diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index a776a9d86..4211f910c 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -20,22 +20,22 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "apiwrap.h" -#include "data/data_drafts.h" -#include "observer_peer.h" -#include "lang/lang_keys.h" #include "application.h" -#include "mainwindow.h" -#include "messenger.h" -#include "mainwidget.h" -#include "history/history_widget.h" -#include "storage/localstorage.h" #include "auth_session.h" +#include "base/algorithm.h" // for_each_apply #include "boxes/confirm_box.h" -#include "window/themes/window_theme.h" -#include "window/notifications_manager.h" #include "chat_helpers/message_field.h" #include "chat_helpers/stickers.h" -#include "base/algorithm.h" // for_each_apply +#include "data/data_drafts.h" +#include "history/history_widget.h" +#include "lang/lang_keys.h" +#include "mainwidget.h" +#include "mainwindow.h" +#include "messenger.h" +#include "observer_peer.h" +#include "storage/localstorage.h" +#include "window/notifications_manager.h" +#include "window/themes/window_theme.h" namespace { @@ -50,12 +50,11 @@ constexpr auto kUnreadMentionsNextRequestLimit = 100; } // namespace -ApiWrap::ApiWrap(not_null session) -: _session(session) -, _messageDataResolveDelayed([this] { resolveMessageDatas(); }) -, _webPagesTimer([this] { resolveWebPages(); }) -, _draftsSaveTimer([this] { saveDraftsToCloud(); }) { -} +ApiWrap::ApiWrap(not_null session) + : _session(session) + , _messageDataResolveDelayed([this] { resolveMessageDatas(); }) + , _webPagesTimer([this] { resolveWebPages(); }) + , _draftsSaveTimer([this] { saveDraftsToCloud(); }) {} void ApiWrap::start() { Window::Theme::Background()->start(); @@ -66,24 +65,29 @@ void ApiWrap::requestAppChangelogs() { auto oldAppVersion = Local::oldMapVersion(); if (oldAppVersion > 0 && oldAppVersion < AppVersion) { _changelogSubscription = subscribe(_session->data().moreChatsLoaded(), [this, oldAppVersion] { - auto oldVersionString = qsl("%1.%2.%3").arg(oldAppVersion / 1000000).arg((oldAppVersion % 1000000) / 1000).arg(oldAppVersion % 1000); - request(MTPhelp_GetAppChangelog(MTP_string(oldVersionString))).done([this, oldAppVersion](const MTPUpdates &result) { - applyUpdates(result); + auto oldVersionString = qsl("%1.%2.%3") + .arg(oldAppVersion / 1000000) + .arg((oldAppVersion % 1000000) / 1000) + .arg(oldAppVersion % 1000); + request(MTPhelp_GetAppChangelog(MTP_string(oldVersionString))) + .done([this, oldAppVersion](const MTPUpdates &result) { + applyUpdates(result); - auto resultEmpty = true; - switch (result.type()) { - case mtpc_updateShortMessage: - case mtpc_updateShortChatMessage: - case mtpc_updateShort: resultEmpty = false; break; - case mtpc_updatesCombined: resultEmpty = result.c_updatesCombined().vupdates.v.isEmpty(); break; - case mtpc_updates: resultEmpty = result.c_updates().vupdates.v.isEmpty(); break; - case mtpc_updatesTooLong: - case mtpc_updateShortSentMessage: LOG(("API Error: Bad updates type in app changelog.")); break; - } - if (resultEmpty) { - addLocalChangelogs(oldAppVersion); - } - }).send(); + auto resultEmpty = true; + switch (result.type()) { + case mtpc_updateShortMessage: + case mtpc_updateShortChatMessage: + case mtpc_updateShort: resultEmpty = false; break; + case mtpc_updatesCombined: resultEmpty = result.c_updatesCombined().vupdates.v.isEmpty(); break; + case mtpc_updates: resultEmpty = result.c_updates().vupdates.v.isEmpty(); break; + case mtpc_updatesTooLong: + case mtpc_updateShortSentMessage: LOG(("API Error: Bad updates type in app changelog.")); break; + } + if (resultEmpty) { + addLocalChangelogs(oldAppVersion); + } + }) + .send(); unsubscribe(base::take(_changelogSubscription)); }); } @@ -92,13 +96,14 @@ void ApiWrap::requestAppChangelogs() { void ApiWrap::addLocalChangelogs(int oldAppVersion) { auto addedSome = false; auto addLocalChangelog = [this, &addedSome](const QString &text) { - auto textWithEntities = TextWithEntities { text }; + auto textWithEntities = TextWithEntities{text}; TextUtilities::ParseEntities(textWithEntities, TextParseLinks); App::wnd()->serviceNotification(textWithEntities, MTP_messageMediaEmpty(), unixtime()); addedSome = true; }; auto text = lng_new_version_wrap(lt_version, str_const_toString(AppVersionStr), lt_changes, - lang(lng_new_version_minor), lt_link, lang(lng_url_changelog)).trimmed(); + lang(lng_new_version_minor), lt_link, lang(lng_url_changelog)) + .trimmed(); addLocalChangelog(text); } @@ -141,9 +146,12 @@ void ApiWrap::resolveMessageDatas() { auto ids = collectMessageIds(_messageDataRequests); if (!ids.isEmpty()) { - auto requestId = request(MTPmessages_GetMessages(MTP_vector(ids))).done([this](const MTPmessages_Messages &result, mtpRequestId requestId) { - gotMessageDatas(nullptr, result, requestId); - }).after(kSmallDelayMs).send(); + auto requestId = request(MTPmessages_GetMessages(MTP_vector(ids))) + .done([this](const MTPmessages_Messages &result, mtpRequestId requestId) { + gotMessageDatas(nullptr, result, requestId); + }) + .after(kSmallDelayMs) + .send(); for (auto &request : _messageDataRequests) { if (request.requestId > 0) continue; request.requestId = requestId; @@ -156,9 +164,13 @@ void ApiWrap::resolveMessageDatas() { } auto ids = collectMessageIds(j.value()); if (!ids.isEmpty()) { - auto requestId = request(MTPchannels_GetMessages(j.key()->inputChannel, MTP_vector(ids))).done([this, channel = j.key()](const MTPmessages_Messages &result, mtpRequestId requestId) { - gotMessageDatas(channel, result, requestId); - }).after(kSmallDelayMs).send(); + auto requestId = + request(MTPchannels_GetMessages(j.key()->inputChannel, MTP_vector(ids))) + .done([this, channel = j.key()](const MTPmessages_Messages &result, mtpRequestId requestId) { + gotMessageDatas(channel, result, requestId); + }) + .after(kSmallDelayMs) + .send(); for (auto &request : *j) { if (request.requestId > 0) continue; @@ -190,7 +202,9 @@ void ApiWrap::gotMessageDatas(ChannelData *channel, const MTPmessages_Messages & if (channel) { channel->ptsReceived(d.vpts.v); } else { - LOG(("App Error: received messages.channelMessages when no channel was passed! (ApiWrap::gotDependencyItem)")); + LOG( + ("App Error: received messages.channelMessages when no channel was passed! " + "(ApiWrap::gotDependencyItem)")); } App::feedUsers(d.vusers); App::feedChats(d.vchats); @@ -201,9 +215,7 @@ void ApiWrap::gotMessageDatas(ChannelData *channel, const MTPmessages_Messages & if (requests) { for (auto i = requests->begin(); i != requests->cend();) { if (i.value().requestId == requestId) { - for_const (auto &callback, i.value().callbacks) { - callback(channel, i.key()); - } + for_const (auto &callback, i.value().callbacks) { callback(channel, i.key()); } i = requests->erase(i); } else { ++i; @@ -219,21 +231,28 @@ void ApiWrap::requestFullPeer(PeerData *peer) { if (!peer || _fullPeerRequests.contains(peer)) return; auto sendRequest = [this, peer] { - auto failHandler = [this, peer](const RPCError &error) { - _fullPeerRequests.remove(peer); - }; + auto failHandler = [this, peer](const RPCError &error) { _fullPeerRequests.remove(peer); }; if (auto user = peer->asUser()) { - return request(MTPusers_GetFullUser(user->inputUser)).done([this, user](const MTPUserFull &result, mtpRequestId requestId) { - gotUserFull(user, result, requestId); - }).fail(failHandler).send(); + return request(MTPusers_GetFullUser(user->inputUser)) + .done([this, user](const MTPUserFull &result, mtpRequestId requestId) { + gotUserFull(user, result, requestId); + }) + .fail(failHandler) + .send(); } else if (auto chat = peer->asChat()) { - return request(MTPmessages_GetFullChat(chat->inputChat)).done([this, peer](const MTPmessages_ChatFull &result, mtpRequestId requestId) { - gotChatFull(peer, result, requestId); - }).fail(failHandler).send(); + return request(MTPmessages_GetFullChat(chat->inputChat)) + .done([this, peer](const MTPmessages_ChatFull &result, mtpRequestId requestId) { + gotChatFull(peer, result, requestId); + }) + .fail(failHandler) + .send(); } else if (auto channel = peer->asChannel()) { - return request(MTPchannels_GetFullChannel(channel->inputChannel)).done([this, peer](const MTPmessages_ChatFull &result, mtpRequestId requestId) { - gotChatFull(peer, result, requestId); - }).fail(failHandler).send(); + return request(MTPchannels_GetFullChannel(channel->inputChannel)) + .done([this, peer](const MTPmessages_ChatFull &result, mtpRequestId requestId) { + gotChatFull(peer, result, requestId); + }) + .fail(failHandler) + .send(); } return 0; }; @@ -255,9 +274,11 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt auto &vc = d.vchats.v; auto badVersion = false; if (peer->isChat()) { - badVersion = (!vc.isEmpty() && vc[0].type() == mtpc_chat && vc[0].c_chat().vversion.v < peer->asChat()->version); + badVersion = + (!vc.isEmpty() && vc[0].type() == mtpc_chat && vc[0].c_chat().vversion.v < peer->asChat()->version); } else if (peer->isChannel()) { - badVersion = (!vc.isEmpty() && vc[0].type() == mtpc_channel && vc[0].c_channel().vversion.v < peer->asChannel()->version); + badVersion = (!vc.isEmpty() && vc[0].type() == mtpc_channel && + vc[0].c_channel().vversion.v < peer->asChannel()->version); } App::feedUsers(d.vusers); @@ -288,7 +309,9 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt } else { chat->photoId = 0; } - chat->setInviteLink((f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString()); + chat->setInviteLink((f.vexported_invite.type() == mtpc_chatInviteExported) ? + qs(f.vexported_invite.c_chatInviteExported().vlink) : + QString()); chat->fullUpdated(); notifySettingReceived(MTP_inputNotifyPeer(peer->input), f.vnotify_settings); @@ -355,7 +378,9 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt channel->setAdminsCount(f.has_admins_count() ? f.vadmins_count.v : 0); channel->setRestrictedCount(f.has_banned_count() ? f.vbanned_count.v : 0); channel->setKickedCount(f.has_kicked_count() ? f.vkicked_count.v : 0); - channel->setInviteLink((f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString()); + channel->setInviteLink((f.vexported_invite.type() == mtpc_chatInviteExported) ? + qs(f.vexported_invite.c_chatInviteExported().vlink) : + QString()); if (auto h = App::historyLoaded(channel->id)) { if (h->inboxReadBefore < f.vread_inbox_max_id.v + 1) { h->setUnreadCount(f.vunread_count.v); @@ -373,9 +398,13 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt auto stickersChanged = (canEditStickers != channel->canEditStickers()); auto stickerSet = (f.has_stickerset() ? &f.vstickerset.c_stickerSet() : nullptr); auto newSetId = (stickerSet ? stickerSet->vid.v : 0); - auto oldSetId = (channel->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) ? channel->mgInfo->stickerSet.c_inputStickerSetID().vid.v : 0; + auto oldSetId = (channel->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) ? + channel->mgInfo->stickerSet.c_inputStickerSetID().vid.v : + 0; if (oldSetId != newSetId) { - channel->mgInfo->stickerSet = stickerSet ? MTP_inputStickerSetID(stickerSet->vid, stickerSet->vaccess_hash) : MTP_inputStickerSetEmpty(); + channel->mgInfo->stickerSet = stickerSet ? + MTP_inputStickerSetID(stickerSet->vid, stickerSet->vaccess_hash) : + MTP_inputStickerSetEmpty(); stickersChanged = true; } if (stickersChanged) { @@ -384,8 +413,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt } channel->fullUpdated(); - if (canViewAdmins != channel->canViewAdmins() - || canViewMembers != channel->canViewMembers()) { + if (canViewAdmins != channel->canViewAdmins() || canViewMembers != channel->canViewMembers()) { Notify::peerUpdatedDelayed(channel, Notify::PeerUpdate::Flag::ChannelRightsChanged); } @@ -415,7 +443,8 @@ void ApiWrap::gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestI if (d.has_profile_photo()) { App::feedPhoto(d.vprofile_photo); } - App::feedUserLink(MTP_int(peerToUser(user->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link); + App::feedUserLink(MTP_int(peerToUser(user->id)), d.vlink.c_contacts_link().vmy_link, + d.vlink.c_contacts_link().vforeign_link); if (App::main()) { notifySettingReceived(MTP_inputNotifyPeer(user->input), d.vnotify_settings); } @@ -426,7 +455,9 @@ void ApiWrap::gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestI user->setBotInfoVersion(-1); } user->setBlockStatus(d.is_blocked() ? UserData::BlockStatus::Blocked : UserData::BlockStatus::NotBlocked); - user->setCallsStatus(d.is_phone_calls_private() ? UserData::CallsStatus::Private : d.is_phone_calls_available() ? UserData::CallsStatus::Enabled : UserData::CallsStatus::Disabled); + user->setCallsStatus(d.is_phone_calls_private() ? UserData::CallsStatus::Private : + d.is_phone_calls_available() ? UserData::CallsStatus::Enabled : + UserData::CallsStatus::Disabled); user->setAbout(d.has_about() ? qs(d.vabout) : QString()); user->setCommonChatsCount(d.vcommon_chats_count.v); user->fullUpdated(); @@ -444,9 +475,7 @@ void ApiWrap::requestPeer(PeerData *peer) { if (!peer || _fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) return; auto sendRequest = [this, peer] { - auto failHandler = [this, peer](const RPCError &error) { - _peerRequests.remove(peer); - }; + auto failHandler = [this, peer](const RPCError &error) { _peerRequests.remove(peer); }; auto chatHandler = [this, peer](const MTPmessages_Chats &result) { _peerRequests.remove(peer); @@ -456,7 +485,8 @@ void ApiWrap::requestPeer(PeerData *peer) { if (auto chat = peer->asChat()) { badVersion = (!v.isEmpty() && v[0].type() == mtpc_chat && v[0].c_chat().vversion.v < chat->version); } else if (auto channel = peer->asChannel()) { - badVersion = (!v.isEmpty() && v[0].type() == mtpc_channel && v[0].c_channel().vversion.v < channel->version); + badVersion = + (!v.isEmpty() && v[0].type() == mtpc_channel && v[0].c_channel().vversion.v < channel->version); } auto chat = App::feedChats(*chats); if (chat == peer) { @@ -472,14 +502,23 @@ void ApiWrap::requestPeer(PeerData *peer) { } }; if (auto user = peer->asUser()) { - return request(MTPusers_GetUsers(MTP_vector(1, user->inputUser))).done([this, user](const MTPVector &result) { - _peerRequests.remove(user); - App::feedUsers(result); - }).fail(failHandler).send(); + return request(MTPusers_GetUsers(MTP_vector(1, user->inputUser))) + .done([this, user](const MTPVector &result) { + _peerRequests.remove(user); + App::feedUsers(result); + }) + .fail(failHandler) + .send(); } else if (auto chat = peer->asChat()) { - return request(MTPmessages_GetChats(MTP_vector(1, chat->inputChat))).done(chatHandler).fail(failHandler).send(); + return request(MTPmessages_GetChats(MTP_vector(1, chat->inputChat))) + .done(chatHandler) + .fail(failHandler) + .send(); } else if (auto channel = peer->asChannel()) { - return request(MTPchannels_GetChannels(MTP_vector(1, channel->inputChannel))).done(chatHandler).fail(failHandler).send(); + return request(MTPchannels_GetChannels(MTP_vector(1, channel->inputChannel))) + .done(chatHandler) + .fail(failHandler) + .send(); } return 0; }; @@ -488,14 +527,14 @@ void ApiWrap::requestPeer(PeerData *peer) { } } -void ApiWrap::requestPeers(const QList &peers) { +void ApiWrap::requestPeers(const QList &peers) { QVector chats; QVector channels; QVector users; chats.reserve(peers.size()); channels.reserve(peers.size()); users.reserve(peers.size()); - for (QList::const_iterator i = peers.cbegin(), e = peers.cend(); i != e; ++i) { + for (QList::const_iterator i = peers.cbegin(), e = peers.cend(); i != e; ++i) { if (!*i || _fullPeerRequests.contains(*i) || _peerRequests.contains(*i)) continue; if ((*i)->isUser()) { users.push_back((*i)->asUser()->inputUser); @@ -517,9 +556,9 @@ void ApiWrap::requestPeers(const QList &peers) { request(MTPchannels_GetChannels(MTP_vector(channels))).done(handleChats).send(); } if (!users.isEmpty()) { - request(MTPusers_GetUsers(MTP_vector(users))).done([this](const MTPVector &result) { - App::feedUsers(result); - }).send(); + request(MTPusers_GetUsers(MTP_vector(users))) + .done([this](const MTPVector &result) { App::feedUsers(result); }) + .send(); } } @@ -529,7 +568,8 @@ void ApiWrap::requestLastParticipants(ChannelData *channel, bool fromStart) { } auto needAdmins = channel->canViewAdmins(); - auto adminsOutdated = (channel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) != 0; + auto adminsOutdated = + (channel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) != 0; if ((needAdmins && adminsOutdated) || channel->lastParticipantsCountOutdated()) { fromStart = true; } @@ -542,13 +582,20 @@ void ApiWrap::requestLastParticipants(ChannelData *channel, bool fromStart) { } } - auto requestId = request(MTPchannels_GetParticipants(channel->inputChannel, MTP_channelParticipantsRecent(), MTP_int(fromStart ? 0 : channel->mgInfo->lastParticipants.size()), MTP_int(Global::ChatSizeMax()))).done([this, channel](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { - lastParticipantsDone(channel, result, requestId); - }).fail([this, channel](const RPCError &error, mtpRequestId requestId) { - if (_participantsRequests.value(channel) == requestId || _participantsRequests.value(channel) == -requestId) { - _participantsRequests.remove(channel); - } - }).send(); + auto requestId = + request(MTPchannels_GetParticipants(channel->inputChannel, MTP_channelParticipantsRecent(), + MTP_int(fromStart ? 0 : channel->mgInfo->lastParticipants.size()), + MTP_int(Global::ChatSizeMax()))) + .done([this, channel](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { + lastParticipantsDone(channel, result, requestId); + }) + .fail([this, channel](const RPCError &error, mtpRequestId requestId) { + if (_participantsRequests.value(channel) == requestId || + _participantsRequests.value(channel) == -requestId) { + _participantsRequests.remove(channel); + } + }) + .send(); _participantsRequests.insert(channel, fromStart ? requestId : -requestId); } @@ -558,18 +605,23 @@ void ApiWrap::requestBots(ChannelData *channel) { return; } - auto requestId = request(MTPchannels_GetParticipants(channel->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(Global::ChatSizeMax()))).done([this, channel](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { - lastParticipantsDone(channel, result, requestId); - }).fail([this, channel](const RPCError &error, mtpRequestId requestId) { - if (_botsRequests.value(channel) == requestId) { - _botsRequests.remove(channel); - } - }).send(); + auto requestId = request(MTPchannels_GetParticipants(channel->inputChannel, MTP_channelParticipantsBots(), + MTP_int(0), MTP_int(Global::ChatSizeMax()))) + .done([this, channel](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { + lastParticipantsDone(channel, result, requestId); + }) + .fail([this, channel](const RPCError &error, mtpRequestId requestId) { + if (_botsRequests.value(channel) == requestId) { + _botsRequests.remove(channel); + } + }) + .send(); _botsRequests.insert(channel, requestId); } -void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { +void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, + mtpRequestId requestId) { bool bots = (_botsRequests.value(peer) == requestId), fromStart = false; if (bots) { _botsRequests.remove(peer); @@ -618,11 +670,11 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP userId = participant.c_channelParticipantAdmin().vuser_id.v; adminCanEdit = participant.c_channelParticipantAdmin().is_can_edit(); adminRights = participant.c_channelParticipantAdmin().vadmin_rights; - break; + break; case mtpc_channelParticipantBanned: userId = participant.c_channelParticipantBanned().vuser_id.v; restrictedRights = participant.c_channelParticipantBanned().vbanned_rights; - break; + break; case mtpc_channelParticipantCreator: userId = participant.c_channelParticipantCreator().vuser_id.v; break; } if (!userId) { @@ -636,7 +688,7 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP if (bots) { if (u->botInfo) { peer->mgInfo->bots.insert(u); - botStatus = 2;// (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1; + botStatus = 2; // (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1; if (!u->botInfo->inited) { needBotsInfos = true; } @@ -648,9 +700,9 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP if (peer->mgInfo->lastParticipants.indexOf(u) < 0) { peer->mgInfo->lastParticipants.push_back(u); if (adminRights.c_channelAdminRights().vflags.v) { - peer->mgInfo->lastAdmins.insert(u, MegagroupInfo::Admin { adminRights, adminCanEdit }); + peer->mgInfo->lastAdmins.insert(u, MegagroupInfo::Admin{adminRights, adminCanEdit}); } else if (restrictedRights.c_channelBannedRights().vflags.v != 0) { - peer->mgInfo->lastRestricted.insert(u, MegagroupInfo::Restricted { restrictedRights }); + peer->mgInfo->lastRestricted.insert(u, MegagroupInfo::Restricted{restrictedRights}); } if (u->botInfo) { peer->mgInfo->bots.insert(u); @@ -690,46 +742,50 @@ void ApiWrap::requestSelfParticipant(ChannelData *channel) { return; } - auto requestId = request(MTPchannels_GetParticipant(channel->inputChannel, MTP_inputUserSelf())).done([this, channel](const MTPchannels_ChannelParticipant &result) { - _selfParticipantRequests.remove(channel); - if (result.type() != mtpc_channels_channelParticipant) { - LOG(("API Error: unknown type in gotSelfParticipant (%1)").arg(result.type())); - channel->inviter = -1; - if (App::main()) App::main()->onSelfParticipantUpdated(channel); - return; - } + auto requestId = request(MTPchannels_GetParticipant(channel->inputChannel, MTP_inputUserSelf())) + .done([this, channel](const MTPchannels_ChannelParticipant &result) { + _selfParticipantRequests.remove(channel); + if (result.type() != mtpc_channels_channelParticipant) { + LOG(("API Error: unknown type in gotSelfParticipant (%1)").arg(result.type())); + channel->inviter = -1; + if (App::main()) App::main()->onSelfParticipantUpdated(channel); + return; + } - auto &p = result.c_channels_channelParticipant(); - App::feedUsers(p.vusers); + auto &p = result.c_channels_channelParticipant(); + App::feedUsers(p.vusers); - switch (p.vparticipant.type()) { - case mtpc_channelParticipantSelf: { - auto &d = p.vparticipant.c_channelParticipantSelf(); - channel->inviter = d.vinviter_id.v; - channel->inviteDate = date(d.vdate); - } break; - case mtpc_channelParticipantCreator: { - auto &d = p.vparticipant.c_channelParticipantCreator(); - channel->inviter = _session->userId(); - channel->inviteDate = date(MTP_int(channel->date)); - if (channel->mgInfo) { - channel->mgInfo->creator = App::self(); - } - } break; - case mtpc_channelParticipantAdmin: { - auto &d = p.vparticipant.c_channelParticipantAdmin(); - channel->inviter = d.vinviter_id.v; - channel->inviteDate = date(d.vdate); - } break; - } + switch (p.vparticipant.type()) { + case mtpc_channelParticipantSelf: { + auto &d = p.vparticipant.c_channelParticipantSelf(); + channel->inviter = d.vinviter_id.v; + channel->inviteDate = date(d.vdate); + } break; + case mtpc_channelParticipantCreator: { + auto &d = p.vparticipant.c_channelParticipantCreator(); + channel->inviter = _session->userId(); + channel->inviteDate = date(MTP_int(channel->date)); + if (channel->mgInfo) { + channel->mgInfo->creator = App::self(); + } + } break; + case mtpc_channelParticipantAdmin: { + auto &d = p.vparticipant.c_channelParticipantAdmin(); + channel->inviter = d.vinviter_id.v; + channel->inviteDate = date(d.vdate); + } break; + } - if (App::main()) App::main()->onSelfParticipantUpdated(channel); - }).fail([this, channel](const RPCError &error) { - _selfParticipantRequests.remove(channel); - if (error.type() == qstr("USER_NOT_PARTICIPANT")) { - channel->inviter = -1; - } - }).after(kSmallDelayMs).send(); + if (App::main()) App::main()->onSelfParticipantUpdated(channel); + }) + .fail([this, channel](const RPCError &error) { + _selfParticipantRequests.remove(channel); + if (error.type() == qstr("USER_NOT_PARTICIPANT")) { + channel->inviter = -1; + } + }) + .after(kSmallDelayMs) + .send(); _selfParticipantRequests.insert(channel, requestId); } @@ -740,14 +796,15 @@ void ApiWrap::kickParticipant(PeerData *peer, UserData *user, const MTPChannelBa if (auto channel = peer->asChannel()) { auto rights = ChannelData::KickedRestrictedRights(); - auto requestId = request(MTPchannels_EditBanned(channel->inputChannel, user->inputUser, rights)).done([this, channel, user, currentRights, rights](const MTPUpdates &result) { - applyUpdates(result); + auto requestId = request(MTPchannels_EditBanned(channel->inputChannel, user->inputUser, rights)) + .done([this, channel, user, currentRights, rights](const MTPUpdates &result) { + applyUpdates(result); - _kickRequests.remove(KickRequest(channel, user)); - channel->applyEditBanned(user, currentRights, rights); - }).fail([this, kick](const RPCError &error) { - _kickRequests.remove(kick); - }).send(); + _kickRequests.remove(KickRequest(channel, user)); + channel->applyEditBanned(user, currentRights, rights); + }) + .fail([this, kick](const RPCError &error) { _kickRequests.remove(kick); }) + .send(); _kickRequests.insert(kick, requestId); } @@ -758,20 +815,22 @@ void ApiWrap::unblockParticipant(PeerData *peer, UserData *user) { if (_kickRequests.contains(kick)) return; if (auto channel = peer->asChannel()) { - auto requestId = request(MTPchannels_EditBanned(channel->inputChannel, user->inputUser, MTP_channelBannedRights(MTP_flags(0), MTP_int(0)))).done([this, peer, user](const MTPUpdates &result) { - applyUpdates(result); + auto requestId = request(MTPchannels_EditBanned(channel->inputChannel, user->inputUser, + MTP_channelBannedRights(MTP_flags(0), MTP_int(0)))) + .done([this, peer, user](const MTPUpdates &result) { + applyUpdates(result); - _kickRequests.remove(KickRequest(peer, user)); - if (auto channel = peer->asMegagroup()) { - if (channel->kickedCount() > 0) { - channel->setKickedCount(channel->kickedCount() - 1); - } else { - channel->updateFullForced(); - } - } - }).fail([this, kick](const RPCError &error) { - _kickRequests.remove(kick); - }).send(); + _kickRequests.remove(KickRequest(peer, user)); + if (auto channel = peer->asMegagroup()) { + if (channel->kickedCount() > 0) { + channel->setKickedCount(channel->kickedCount() - 1); + } else { + channel->updateFullForced(); + } + } + }) + .fail([this, kick](const RPCError &error) { _kickRequests.remove(kick); }) + .send(); _kickRequests.insert(kick, requestId); } @@ -789,11 +848,12 @@ void ApiWrap::requestStickerSets() { if (i.value().second) continue; auto waitMs = (j == e) ? 0 : kSmallDelayMs; - i.value().second = request(MTPmessages_GetStickerSet(MTP_inputStickerSetID(MTP_long(i.key()), MTP_long(i.value().first)))).done([this, setId = i.key()](const MTPmessages_StickerSet &result) { - gotStickerSet(setId, result); - }).fail([this, setId = i.key()](const RPCError &error) { - _stickerSetRequests.remove(setId); - }).after(waitMs).send(); + i.value().second = + request(MTPmessages_GetStickerSet(MTP_inputStickerSetID(MTP_long(i.key()), MTP_long(i.value().first)))) + .done([this, setId = i.key()](const MTPmessages_StickerSet &result) { gotStickerSet(setId, result); }) + .fail([this, setId = i.key()](const RPCError &error) { _stickerSetRequests.remove(setId); }) + .after(waitMs) + .send(); } } @@ -804,7 +864,8 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers: request(base::take(_stickersReorderRequestId)).cancel(); request(base::take(_stickersClearRecentRequestId)).cancel(); - auto writeInstalled = true, writeRecent = false, writeCloudRecent = false, writeFaved = false, writeArchived = false; + auto writeInstalled = true, writeRecent = false, writeCloudRecent = false, writeFaved = false, + writeArchived = false; auto &recent = cGetRecentStickers(); auto &sets = Global::RefStickerSets(); @@ -822,11 +883,11 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers: writeRecent = true; } - _stickersClearRecentRequestId = request(MTPmessages_ClearRecentStickers(MTP_flags(0))).done([this](const MTPBool &result) { - _stickersClearRecentRequestId = 0; - }).fail([this](const RPCError &error) { - _stickersClearRecentRequestId = 0; - }).send(); + _stickersClearRecentRequestId = + request(MTPmessages_ClearRecentStickers(MTP_flags(0))) + .done([this](const MTPBool &result) { _stickersClearRecentRequestId = 0; }) + .fail([this](const RPCError &error) { _stickersClearRecentRequestId = 0; }) + .send(); continue; } @@ -841,19 +902,26 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers: } } if (!(it->flags & MTPDstickerSet::Flag::f_archived)) { - MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName)); + MTPInputStickerSet setId = (it->id && it->access) ? + MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : + MTP_inputStickerSetShortName(MTP_string(it->shortName)); - auto requestId = request(MTPmessages_UninstallStickerSet(setId)).done([this](const MTPBool &result, mtpRequestId requestId) { - stickerSetDisenabled(requestId); - }).fail([this](const RPCError &error, mtpRequestId requestId) { - stickerSetDisenabled(requestId); - }).after(kSmallDelayMs).send(); + auto requestId = request(MTPmessages_UninstallStickerSet(setId)) + .done([this](const MTPBool &result, mtpRequestId requestId) { + stickerSetDisenabled(requestId); + }) + .fail([this](const RPCError &error, mtpRequestId requestId) { + stickerSetDisenabled(requestId); + }) + .after(kSmallDelayMs) + .send(); _stickerSetDisenableRequests.insert(requestId); int removeIndex = Global::StickerSetsOrder().indexOf(it->id); if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex); - if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured) && !(it->flags & MTPDstickerSet_ClientFlag::f_special)) { + if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured) && + !(it->flags & MTPDstickerSet_ClientFlag::f_special)) { sets.erase(it); } else { if (it->flags & MTPDstickerSet::Flag::f_archived) { @@ -878,13 +946,18 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers: auto it = sets.find(setId); if (it != sets.cend()) { if ((it->flags & MTPDstickerSet::Flag::f_archived) && !localRemoved.contains(it->id)) { - MTPInputStickerSet mtpSetId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName)); + MTPInputStickerSet mtpSetId = (it->id && it->access) ? + MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : + MTP_inputStickerSetShortName(MTP_string(it->shortName)); - auto requestId = request(MTPmessages_InstallStickerSet(mtpSetId, MTP_boolFalse())).done([this](const MTPmessages_StickerSetInstallResult &result, mtpRequestId requestId) { - stickerSetDisenabled(requestId); - }).fail([this](const RPCError &error, mtpRequestId requestId) { - stickerSetDisenabled(requestId); - }).after(kSmallDelayMs).send(); + auto requestId = request(MTPmessages_InstallStickerSet(mtpSetId, MTP_boolFalse())) + .done([this](const MTPmessages_StickerSetInstallResult &result, + mtpRequestId requestId) { stickerSetDisenabled(requestId); }) + .fail([this](const RPCError &error, mtpRequestId requestId) { + stickerSetDisenabled(requestId); + }) + .after(kSmallDelayMs) + .send(); _stickerSetDisenableRequests.insert(requestId); @@ -896,10 +969,8 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers: } } for (auto it = sets.begin(); it != sets.cend();) { - if ((it->flags & MTPDstickerSet_ClientFlag::f_featured) - || (it->flags & MTPDstickerSet::Flag::f_installed) - || (it->flags & MTPDstickerSet::Flag::f_archived) - || (it->flags & MTPDstickerSet_ClientFlag::f_special)) { + if ((it->flags & MTPDstickerSet_ClientFlag::f_featured) || (it->flags & MTPDstickerSet::Flag::f_installed) || + (it->flags & MTPDstickerSet::Flag::f_archived) || (it->flags & MTPDstickerSet_ClientFlag::f_special)) { ++it; } else { it = sets.erase(it); @@ -931,15 +1002,18 @@ void ApiWrap::joinChannel(ChannelData *channel) { if (channel->amIn()) { Notify::peerUpdatedDelayed(channel, Notify::PeerUpdate::Flag::ChannelAmIn); } else if (!_channelAmInRequests.contains(channel)) { - auto requestId = request(MTPchannels_JoinChannel(channel->inputChannel)).done([this, channel](const MTPUpdates &result) { - _channelAmInRequests.remove(channel); - applyUpdates(result); - }).fail([this, channel](const RPCError &error) { - if (error.type() == qstr("CHANNELS_TOO_MUCH")) { - Ui::show(Box(lang(lng_join_channel_error))); - } - _channelAmInRequests.remove(channel); - }).send(); + auto requestId = request(MTPchannels_JoinChannel(channel->inputChannel)) + .done([this, channel](const MTPUpdates &result) { + _channelAmInRequests.remove(channel); + applyUpdates(result); + }) + .fail([this, channel](const RPCError &error) { + if (error.type() == qstr("CHANNELS_TOO_MUCH")) { + Ui::show(Box(lang(lng_join_channel_error))); + } + _channelAmInRequests.remove(channel); + }) + .send(); _channelAmInRequests.insert(channel, requestId); } @@ -949,12 +1023,13 @@ void ApiWrap::leaveChannel(ChannelData *channel) { if (!channel->amIn()) { Notify::peerUpdatedDelayed(channel, Notify::PeerUpdate::Flag::ChannelAmIn); } else if (!_channelAmInRequests.contains(channel)) { - auto requestId = request(MTPchannels_LeaveChannel(channel->inputChannel)).done([this, channel](const MTPUpdates &result) { - _channelAmInRequests.remove(channel); - applyUpdates(result); - }).fail([this, channel](const RPCError &error) { - _channelAmInRequests.remove(channel); - }).send(); + auto requestId = request(MTPchannels_LeaveChannel(channel->inputChannel)) + .done([this, channel](const MTPUpdates &result) { + _channelAmInRequests.remove(channel); + applyUpdates(result); + }) + .fail([this, channel](const RPCError &error) { _channelAmInRequests.remove(channel); }) + .send(); _channelAmInRequests.insert(channel, requestId); } @@ -964,12 +1039,13 @@ void ApiWrap::blockUser(UserData *user) { if (user->isBlocked()) { Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserIsBlocked); } else if (!_blockRequests.contains(user)) { - auto requestId = request(MTPcontacts_Block(user->inputUser)).done([this, user](const MTPBool &result) { - _blockRequests.remove(user); - user->setBlockStatus(UserData::BlockStatus::Blocked); - }).fail([this, user](const RPCError &error) { - _blockRequests.remove(user); - }).send(); + auto requestId = request(MTPcontacts_Block(user->inputUser)) + .done([this, user](const MTPBool &result) { + _blockRequests.remove(user); + user->setBlockStatus(UserData::BlockStatus::Blocked); + }) + .fail([this, user](const RPCError &error) { _blockRequests.remove(user); }) + .send(); _blockRequests.insert(user, requestId); } @@ -979,12 +1055,13 @@ void ApiWrap::unblockUser(UserData *user) { if (!user->isBlocked()) { Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserIsBlocked); } else if (!_blockRequests.contains(user)) { - auto requestId = request(MTPcontacts_Unblock(user->inputUser)).done([this, user](const MTPBool &result) { - _blockRequests.remove(user); - user->setBlockStatus(UserData::BlockStatus::NotBlocked); - }).fail([this, user](const RPCError &error) { - _blockRequests.remove(user); - }).send(); + auto requestId = request(MTPcontacts_Unblock(user->inputUser)) + .done([this, user](const MTPBool &result) { + _blockRequests.remove(user); + user->setBlockStatus(UserData::BlockStatus::NotBlocked); + }) + .fail([this, user](const RPCError &error) { _blockRequests.remove(user); }) + .send(); _blockRequests.insert(user, requestId); } @@ -996,19 +1073,27 @@ void ApiWrap::exportInviteLink(PeerData *peer) { } auto sendRequest = [this, peer] { - auto exportFail = [this, peer](const RPCError &error) { - _exportInviteRequests.remove(peer); - }; + auto exportFail = [this, peer](const RPCError &error) { _exportInviteRequests.remove(peer); }; if (auto chat = peer->asChat()) { - return request(MTPmessages_ExportChatInvite(chat->inputChat)).done([this, chat](const MTPExportedChatInvite &result) { - _exportInviteRequests.remove(chat); - chat->setInviteLink((result.type() == mtpc_chatInviteExported) ? qs(result.c_chatInviteExported().vlink) : QString()); - }).fail(exportFail).send(); + return request(MTPmessages_ExportChatInvite(chat->inputChat)) + .done([this, chat](const MTPExportedChatInvite &result) { + _exportInviteRequests.remove(chat); + chat->setInviteLink((result.type() == mtpc_chatInviteExported) ? + qs(result.c_chatInviteExported().vlink) : + QString()); + }) + .fail(exportFail) + .send(); } else if (auto channel = peer->asChannel()) { - return request(MTPchannels_ExportInvite(channel->inputChannel)).done([this, channel](const MTPExportedChatInvite &result) { - _exportInviteRequests.remove(channel); - channel->setInviteLink((result.type() == mtpc_chatInviteExported) ? qs(result.c_chatInviteExported().vlink) : QString()); - }).fail(exportFail).send(); + return request(MTPchannels_ExportInvite(channel->inputChannel)) + .done([this, channel](const MTPExportedChatInvite &result) { + _exportInviteRequests.remove(channel); + channel->setInviteLink((result.type() == mtpc_chatInviteExported) ? + qs(result.c_chatInviteExported().vlink) : + QString()); + }) + .fail(exportFail) + .send(); } return 0; }; @@ -1021,13 +1106,16 @@ void ApiWrap::requestNotifySetting(PeerData *peer) { if (_notifySettingRequests.contains(peer)) return; auto notifyPeer = MTP_inputNotifyPeer(peer->input); - auto requestId = request(MTPaccount_GetNotifySettings(notifyPeer)).done([this, notifyPeer, peer](const MTPPeerNotifySettings &result) { - notifySettingReceived(notifyPeer, result); - _notifySettingRequests.remove(peer); - }).fail([this, notifyPeer, peer](const RPCError &error) { - notifySettingReceived(notifyPeer, MTP_peerNotifySettingsEmpty()); - _notifySettingRequests.remove(peer); - }).send(); + auto requestId = request(MTPaccount_GetNotifySettings(notifyPeer)) + .done([this, notifyPeer, peer](const MTPPeerNotifySettings &result) { + notifySettingReceived(notifyPeer, result); + _notifySettingRequests.remove(peer); + }) + .fail([this, notifyPeer, peer](const RPCError &error) { + notifySettingReceived(notifyPeer, MTP_peerNotifySettingsEmpty()); + _notifySettingRequests.remove(peer); + }) + .send(); _notifySettingRequests.insert(peer, requestId); } @@ -1047,15 +1135,16 @@ void ApiWrap::savePrivacy(const MTPInputPrivacyKey &key, QVector(std::move(rules)))).done([this, keyTypeId](const MTPaccount_PrivacyRules &result) { - Expects(result.type() == mtpc_account_privacyRules); - auto &rules = result.c_account_privacyRules(); - App::feedUsers(rules.vusers); - _privacySaveRequests.remove(keyTypeId); - handlePrivacyChange(keyTypeId, rules.vrules); - }).fail([this, keyTypeId](const RPCError &error) { - _privacySaveRequests.remove(keyTypeId); - }).send(); + auto requestId = request(MTPaccount_SetPrivacy(key, MTP_vector(std::move(rules)))) + .done([this, keyTypeId](const MTPaccount_PrivacyRules &result) { + Expects(result.type() == mtpc_account_privacyRules); + auto &rules = result.c_account_privacyRules(); + App::feedUsers(rules.vusers); + _privacySaveRequests.remove(keyTypeId); + handlePrivacyChange(keyTypeId, rules.vrules); + }) + .fail([this, keyTypeId](const RPCError &error) { _privacySaveRequests.remove(keyTypeId); }) + .send(); _privacySaveRequests.insert(keyTypeId, requestId); } @@ -1072,7 +1161,8 @@ void ApiWrap::handlePrivacyChange(mtpTypeId keyTypeId, const MTPVector &result) { - _contactsStatusesRequestId = 0; - for_const (auto &item, result.v) { - Assert(item.type() == mtpc_contactStatus); - auto &data = item.c_contactStatus(); - if (auto user = App::userLoaded(data.vuser_id.v)) { - auto oldOnlineTill = user->onlineTill; - auto newOnlineTill = onlineTillFromStatus(data.vstatus, oldOnlineTill); - if (oldOnlineTill != newOnlineTill) { - user->onlineTill = newOnlineTill; - Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserOnlineChanged); - } - } - } - }).fail([this](const RPCError &error) { - _contactsStatusesRequestId = 0; - }).send(); + _contactsStatusesRequestId = + request(MTPcontacts_GetStatuses()) + .done([this](const MTPVector &result) { + _contactsStatusesRequestId = 0; + for_const (auto &item, result.v) { + Assert(item.type() == mtpc_contactStatus); + auto &data = item.c_contactStatus(); + if (auto user = App::userLoaded(data.vuser_id.v)) { + auto oldOnlineTill = user->onlineTill; + auto newOnlineTill = onlineTillFromStatus(data.vstatus, oldOnlineTill); + if (oldOnlineTill != newOnlineTill) { + user->onlineTill = newOnlineTill; + Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserOnlineChanged); + } + } + } + }) + .fail([this](const RPCError &error) { _contactsStatusesRequestId = 0; }) + .send(); } } int ApiWrap::onlineTillFromStatus(const MTPUserStatus &status, int currentOnlineTill) { switch (status.type()) { case mtpc_userStatusEmpty: return 0; - case mtpc_userStatusRecently: return (currentOnlineTill > -10) ? -2 : currentOnlineTill; // don't modify pseudo-online + case mtpc_userStatusRecently: + return (currentOnlineTill > -10) ? -2 : currentOnlineTill; // don't modify pseudo-online case mtpc_userStatusLastWeek: return -3; case mtpc_userStatusLastMonth: return -4; case mtpc_userStatusOffline: return status.c_userStatusOffline().vwas_online.v; @@ -1182,32 +1275,38 @@ void ApiWrap::saveDraftsToCloud() { if (!textWithTags.tags.isEmpty()) { flags |= MTPmessages_SaveDraft::Flag::f_entities; } - auto entities = TextUtilities::EntitiesToMTP(ConvertTextTagsToEntities(textWithTags.tags), TextUtilities::ConvertOption::SkipLocal); + auto entities = TextUtilities::EntitiesToMTP(ConvertTextTagsToEntities(textWithTags.tags), + TextUtilities::ConvertOption::SkipLocal); - cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(MTP_flags(flags), MTP_int(cloudDraft->msgId), history->peer->input, MTP_string(textWithTags.text), entities)).done([this, history](const MTPBool &result, mtpRequestId requestId) { - if (auto cloudDraft = history->cloudDraft()) { - if (cloudDraft->saveRequestId == requestId) { - cloudDraft->saveRequestId = 0; - history->draftSavedToCloud(); - } - } - auto i = _draftsSaveRequestIds.find(history); - if (i != _draftsSaveRequestIds.cend() && i.value() == requestId) { - _draftsSaveRequestIds.remove(history); - checkQuitPreventFinished(); - } - }).fail([this, history](const RPCError &error, mtpRequestId requestId) { - if (auto cloudDraft = history->cloudDraft()) { - if (cloudDraft->saveRequestId == requestId) { - history->clearCloudDraft(); - } - } - auto i = _draftsSaveRequestIds.find(history); - if (i != _draftsSaveRequestIds.cend() && i.value() == requestId) { - _draftsSaveRequestIds.remove(history); - checkQuitPreventFinished(); - } - }).send(); + cloudDraft->saveRequestId = + request(MTPmessages_SaveDraft(MTP_flags(flags), MTP_int(cloudDraft->msgId), history->peer->input, + MTP_string(textWithTags.text), entities)) + .done([this, history](const MTPBool &result, mtpRequestId requestId) { + if (auto cloudDraft = history->cloudDraft()) { + if (cloudDraft->saveRequestId == requestId) { + cloudDraft->saveRequestId = 0; + history->draftSavedToCloud(); + } + } + auto i = _draftsSaveRequestIds.find(history); + if (i != _draftsSaveRequestIds.cend() && i.value() == requestId) { + _draftsSaveRequestIds.remove(history); + checkQuitPreventFinished(); + } + }) + .fail([this, history](const RPCError &error, mtpRequestId requestId) { + if (auto cloudDraft = history->cloudDraft()) { + if (cloudDraft->saveRequestId == requestId) { + history->clearCloudDraft(); + } + } + auto i = _draftsSaveRequestIds.find(history); + if (i != _draftsSaveRequestIds.cend() && i.value() == requestId) { + _draftsSaveRequestIds.remove(history); + checkQuitPreventFinished(); + } + }) + .send(); i.value() = cloudDraft->saveRequestId; } @@ -1240,11 +1339,15 @@ PeerData *ApiWrap::notifySettingReceived(MTPInputNotifyPeer notifyPeer, const MT case mtpc_inputNotifyPeer: { auto &peer = notifyPeer.c_inputNotifyPeer().vpeer; switch (peer.type()) { - case mtpc_inputPeerEmpty: App::main()->applyNotifySetting(MTP_notifyPeer(MTP_peerUser(MTP_int(0))), settings); break; + case mtpc_inputPeerEmpty: + App::main()->applyNotifySetting(MTP_notifyPeer(MTP_peerUser(MTP_int(0))), settings); + break; case mtpc_inputPeerSelf: requestedPeer = App::self(); break; case mtpc_inputPeerUser: requestedPeer = App::user(peerFromUser(peer.c_inputPeerUser().vuser_id)); break; case mtpc_inputPeerChat: requestedPeer = App::chat(peerFromChat(peer.c_inputPeerChat().vchat_id)); break; - case mtpc_inputPeerChannel: requestedPeer = App::channel(peerFromChannel(peer.c_inputPeerChannel().vchannel_id)); break; + case mtpc_inputPeerChannel: + requestedPeer = App::channel(peerFromChannel(peer.c_inputPeerChannel().vchannel_id)); + break; } if (requestedPeer) { App::main()->applyNotifySetting(MTP_notifyPeer(peerToMTP(requestedPeer->id)), settings); @@ -1284,7 +1387,7 @@ void ApiWrap::clearWebPageRequests() { void ApiWrap::resolveWebPages() { auto ids = QVector(); // temp_req_id = -1 using IndexAndMessageIds = QPair>; - using MessageIdsByChannel = QMap; + using MessageIdsByChannel = QMap; MessageIdsByChannel idsByChannel; // temp_req_id = -index - 2 auto &items = App::webPageItems(); @@ -1304,7 +1407,9 @@ void ApiWrap::resolveWebPages() { auto channel = item->history()->peer->asChannel(); auto channelMap = idsByChannel.find(channel); if (channelMap == idsByChannel.cend()) { - channelMap = idsByChannel.insert(channel, IndexAndMessageIds(idsByChannel.size(), QVector(1, MTP_int(item->id)))); + channelMap = idsByChannel.insert( + channel, + IndexAndMessageIds(idsByChannel.size(), QVector(1, MTP_int(item->id)))); } else { channelMap.value().second.push_back(MTP_int(item->id)); } @@ -1321,15 +1426,22 @@ void ApiWrap::resolveWebPages() { auto requestId = mtpRequestId(0); if (!ids.isEmpty()) { - requestId = request(MTPmessages_GetMessages(MTP_vector(ids))).done([this](const MTPmessages_Messages &result, mtpRequestId requestId) { - gotWebPages(nullptr, result, requestId); - }).after(kSmallDelayMs).send(); + requestId = request(MTPmessages_GetMessages(MTP_vector(ids))) + .done([this](const MTPmessages_Messages &result, mtpRequestId requestId) { + gotWebPages(nullptr, result, requestId); + }) + .after(kSmallDelayMs) + .send(); } QVector reqsByIndex(idsByChannel.size(), 0); for (auto i = idsByChannel.cbegin(), e = idsByChannel.cend(); i != e; ++i) { - reqsByIndex[i.value().first] = request(MTPchannels_GetMessages(i.key()->inputChannel, MTP_vector(i.value().second))).done([this, channel = i.key()](const MTPmessages_Messages &result, mtpRequestId requestId) { - gotWebPages(channel, result, requestId); - }).after(kSmallDelayMs).send(); + reqsByIndex[i.value().first] = + request(MTPchannels_GetMessages(i.key()->inputChannel, MTP_vector(i.value().second))) + .done([this, channel = i.key()](const MTPmessages_Messages &result, mtpRequestId requestId) { + gotWebPages(channel, result, requestId); + }) + .after(kSmallDelayMs) + .send(); } if (requestId || !reqsByIndex.isEmpty()) { for (auto &pendingRequestId : _webPagesPending) { @@ -1350,9 +1462,7 @@ void ApiWrap::resolveWebPages() { } void ApiWrap::requestParticipantsCountDelayed(ChannelData *channel) { - _participantsCountRequestTimer.call(kReloadChannelMembersTimeout, [this, channel] { - channel->updateFullForced(); - }); + _participantsCountRequestTimer.call(kReloadChannelMembersTimeout, [this, channel] { channel->updateFullForced(); }); } void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs, mtpRequestId req) { @@ -1391,8 +1501,12 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs const auto &msg(v->at(i)); switch (msg.type()) { case mtpc_message: msgsIds.insert((quint64(quint32(msg.c_message().vid.v)) << 32) | quint64(i), i); break; - case mtpc_messageEmpty: msgsIds.insert((quint64(quint32(msg.c_messageEmpty().vid.v)) << 32) | quint64(i), i); break; - case mtpc_messageService: msgsIds.insert((quint64(quint32(msg.c_messageService().vid.v)) << 32) | quint64(i), i); break; + case mtpc_messageEmpty: + msgsIds.insert((quint64(quint32(msg.c_messageEmpty().vid.v)) << 32) | quint64(i), i); + break; + case mtpc_messageService: + msgsIds.insert((quint64(quint32(msg.c_messageService().vid.v)) << 32) | quint64(i), i); + break; } } @@ -1409,9 +1523,7 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs i.key()->pendingTill = -1; auto j = items.constFind(i.key()); if (j != items.cend()) { - for_const (auto item, j.value()) { - item->setPendingInitDimensions(); - } + for_const (auto item, j.value()) { item->setPendingInitDimensions(); } } } i = _webPagesPending.erase(i); @@ -1425,17 +1537,16 @@ void ApiWrap::stickersSaveOrder() { if (_stickersOrder.size() > 1) { QVector mtpOrder; mtpOrder.reserve(_stickersOrder.size()); - for_const (auto setId, _stickersOrder) { - mtpOrder.push_back(MTP_long(setId)); - } + for_const (auto setId, _stickersOrder) { mtpOrder.push_back(MTP_long(setId)); } - _stickersReorderRequestId = request(MTPmessages_ReorderStickerSets(MTP_flags(0), MTP_vector(mtpOrder))).done([this](const MTPBool &result) { - _stickersReorderRequestId = 0; - }).fail([this](const RPCError &error) { - _stickersReorderRequestId = 0; - Global::SetLastStickersUpdate(0); - updateStickers(); - }).send(); + _stickersReorderRequestId = request(MTPmessages_ReorderStickerSets(MTP_flags(0), MTP_vector(mtpOrder))) + .done([this](const MTPBool &result) { _stickersReorderRequestId = 0; }) + .fail([this](const RPCError &error) { + _stickersReorderRequestId = 0; + Global::SetLastStickersUpdate(0); + updateStickers(); + }) + .send(); } } @@ -1448,7 +1559,7 @@ void ApiWrap::updateStickers() { requestSavedGifs(now); } -void ApiWrap::setGroupStickerSet(not_null megagroup, const MTPInputStickerSet &set) { +void ApiWrap::setGroupStickerSet(not_null megagroup, const MTPInputStickerSet &set) { Expects(megagroup->mgInfo != nullptr); megagroup->mgInfo->stickerSet = set; request(MTPchannels_SetStickers(megagroup->inputChannel, set)).send(); @@ -1471,14 +1582,18 @@ void ApiWrap::requestStickers(TimeId now) { case mtpc_messages_allStickers: { auto &d = result.c_messages_allStickers(); Stickers::SetsReceived(d.vsets.v, d.vhash.v); - } return; + } + return; default: Unexpected("Type in ApiWrap::stickersDone()"); } }; - _stickersUpdateRequest = request(MTPmessages_GetAllStickers(MTP_int(Local::countStickersHash(true)))).done(onDone).fail([this, onDone](const RPCError &error) { - LOG(("App Fail: Failed to get stickers!")); - onDone(MTP_messages_allStickersNotModified()); - }).send(); + _stickersUpdateRequest = request(MTPmessages_GetAllStickers(MTP_int(Local::countStickersHash(true)))) + .done(onDone) + .fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get stickers!")); + onDone(MTP_messages_allStickersNotModified()); + }) + .send(); } void ApiWrap::requestRecentStickers(TimeId now) { @@ -1496,15 +1611,21 @@ void ApiWrap::requestRecentStickers(TimeId now) { case mtpc_messages_recentStickersNotModified: return; case mtpc_messages_recentStickers: { auto &d = result.c_messages_recentStickers(); - Stickers::SpecialSetReceived(Stickers::CloudRecentSetId, lang(lng_recent_stickers), d.vstickers.v, d.vhash.v); - } return; + Stickers::SpecialSetReceived(Stickers::CloudRecentSetId, lang(lng_recent_stickers), d.vstickers.v, + d.vhash.v); + } + return; default: Unexpected("Type in ApiWrap::recentStickersDone()"); } }; - _recentStickersUpdateRequest = request(MTPmessages_GetRecentStickers(MTP_flags(0), MTP_int(Local::countRecentStickersHash()))).done(onDone).fail([this, onDone](const RPCError &error) { - LOG(("App Fail: Failed to get recent stickers!")); - onDone(MTP_messages_recentStickersNotModified()); - }).send(); + _recentStickersUpdateRequest = + request(MTPmessages_GetRecentStickers(MTP_flags(0), MTP_int(Local::countRecentStickersHash()))) + .done(onDone) + .fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get recent stickers!")); + onDone(MTP_messages_recentStickersNotModified()); + }) + .send(); } void ApiWrap::requestFavedStickers(TimeId now) { @@ -1522,19 +1643,25 @@ void ApiWrap::requestFavedStickers(TimeId now) { case mtpc_messages_favedStickersNotModified: return; case mtpc_messages_favedStickers: { auto &d = result.c_messages_favedStickers(); - Stickers::SpecialSetReceived(Stickers::FavedSetId, lang(lng_faved_stickers), d.vstickers.v, d.vhash.v, d.vpacks.v); - } return; + Stickers::SpecialSetReceived(Stickers::FavedSetId, lang(lng_faved_stickers), d.vstickers.v, d.vhash.v, + d.vpacks.v); + } + return; default: Unexpected("Type in ApiWrap::favedStickersDone()"); } }; - _favedStickersUpdateRequest = request(MTPmessages_GetFavedStickers(MTP_int(Local::countFavedStickersHash()))).done(onDone).fail([this, onDone](const RPCError &error) { - LOG(("App Fail: Failed to get faved stickers!")); - onDone(MTP_messages_favedStickersNotModified()); - }).send(); + _favedStickersUpdateRequest = request(MTPmessages_GetFavedStickers(MTP_int(Local::countFavedStickersHash()))) + .done(onDone) + .fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get faved stickers!")); + onDone(MTP_messages_favedStickersNotModified()); + }) + .send(); } void ApiWrap::requestFeaturedStickers(TimeId now) { - if (Global::LastFeaturedStickersUpdate() != 0 && now < Global::LastFeaturedStickersUpdate() + kStickersUpdateTimeout) { + if (Global::LastFeaturedStickersUpdate() != 0 && + now < Global::LastFeaturedStickersUpdate() + kStickersUpdateTimeout) { return; } if (_featuredStickersUpdateRequest) { @@ -1549,14 +1676,19 @@ void ApiWrap::requestFeaturedStickers(TimeId now) { case mtpc_messages_featuredStickers: { auto &d = result.c_messages_featuredStickers(); Stickers::FeaturedSetsReceived(d.vsets.v, d.vunread.v, d.vhash.v); - } return; + } + return; default: Unexpected("Type in ApiWrap::featuredStickersDone()"); } }; - _featuredStickersUpdateRequest = request(MTPmessages_GetFeaturedStickers(MTP_int(Local::countFeaturedStickersHash()))).done(onDone).fail([this, onDone](const RPCError &error) { - LOG(("App Fail: Failed to get featured stickers!")); - onDone(MTP_messages_featuredStickersNotModified()); - }).send(); + _featuredStickersUpdateRequest = + request(MTPmessages_GetFeaturedStickers(MTP_int(Local::countFeaturedStickersHash()))) + .done(onDone) + .fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get featured stickers!")); + onDone(MTP_messages_featuredStickersNotModified()); + }) + .send(); } void ApiWrap::requestSavedGifs(TimeId now) { @@ -1575,14 +1707,18 @@ void ApiWrap::requestSavedGifs(TimeId now) { case mtpc_messages_savedGifs: { auto &d = result.c_messages_savedGifs(); Stickers::GifsReceived(d.vgifs.v, d.vhash.v); - } return; + } + return; default: Unexpected("Type in ApiWrap::savedGifsDone()"); } }; - _savedGifsUpdateRequest = request(MTPmessages_GetSavedGifs(MTP_int(Local::countSavedGifsHash()))).done(onDone).fail([this, onDone](const RPCError &error) { - LOG(("App Fail: Failed to get saved gifs!")); - onDone(MTP_messages_savedGifsNotModified()); - }).send(); + _savedGifsUpdateRequest = request(MTPmessages_GetSavedGifs(MTP_int(Local::countSavedGifsHash()))) + .done(onDone) + .fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get saved gifs!")); + onDone(MTP_messages_savedGifsNotModified()); + }) + .send(); } void ApiWrap::applyUpdatesNoPtsCheck(const MTPUpdates &updates) { @@ -1590,13 +1726,22 @@ void ApiWrap::applyUpdatesNoPtsCheck(const MTPUpdates &updates) { case mtpc_updateShortMessage: { auto &d = updates.c_updateShortMessage(); auto flags = mtpCastFlags(d.vflags.v) | MTPDmessage::Flag::f_from_id; - App::histories().addNewMessage(MTP_message(MTP_flags(flags), d.vid, d.is_out() ? MTP_int(Auth().userId()) : d.vuser_id, MTP_peerUser(d.is_out() ? d.vuser_id : MTP_int(Auth().userId())), d.vfwd_from, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint(), MTPint(), MTPstring()), NewMessageUnread); + App::histories().addNewMessage( + MTP_message(MTP_flags(flags), d.vid, d.is_out() ? MTP_int(Auth().userId()) : d.vuser_id, + MTP_peerUser(d.is_out() ? d.vuser_id : MTP_int(Auth().userId())), d.vfwd_from, d.vvia_bot_id, + d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, + d.has_entities() ? d.ventities : MTPnullEntities, MTPint(), MTPint(), MTPstring()), + NewMessageUnread); } break; case mtpc_updateShortChatMessage: { auto &d = updates.c_updateShortChatMessage(); auto flags = mtpCastFlags(d.vflags.v) | MTPDmessage::Flag::f_from_id; - App::histories().addNewMessage(MTP_message(MTP_flags(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint(), MTPint(), MTPstring()), NewMessageUnread); + App::histories().addNewMessage( + MTP_message(MTP_flags(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from, d.vvia_bot_id, + d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, + d.has_entities() ? d.ventities : MTPnullEntities, MTPint(), MTPint(), MTPstring()), + NewMessageUnread); } break; case mtpc_updateShortSentMessage: { @@ -1706,49 +1851,54 @@ void ApiWrap::applyUpdateNoPtsCheck(const MTPUpdate &update) { } } -void ApiWrap::jumpToDate(not_null peer, const QDate &date) { +void ApiWrap::jumpToDate(not_null peer, const QDate &date) { // API returns a message with date <= offset_date. // So we request a message with offset_date = desired_date - 1 and add_offset = -1. // This should give us the first message with date >= desired_date. auto offset_date = static_cast(QDateTime(date).toTime_t()) - 1; auto add_offset = -1; auto limit = 1; - request(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(offset_date), MTP_int(add_offset), MTP_int(limit), MTP_int(0), MTP_int(0))).done([peer](const MTPmessages_Messages &result) { - auto getMessagesList = [&result, peer]() -> const QVector* { - auto handleMessages = [](auto &messages) { - App::feedUsers(messages.vusers); - App::feedChats(messages.vchats); - return &messages.vmessages.v; - }; - switch (result.type()) { - case mtpc_messages_messages: return handleMessages(result.c_messages_messages()); - case mtpc_messages_messagesSlice: return handleMessages(result.c_messages_messagesSlice()); - case mtpc_messages_channelMessages: { - auto &messages = result.c_messages_channelMessages(); - if (peer && peer->isChannel()) { - peer->asChannel()->ptsReceived(messages.vpts.v); - } else { - LOG(("API Error: received messages.channelMessages when no channel was passed! (MainWidget::showJumpToDate)")); - } - return handleMessages(messages); - } break; - } - return nullptr; - }; + request(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(offset_date), MTP_int(add_offset), MTP_int(limit), + MTP_int(0), MTP_int(0))) + .done([peer](const MTPmessages_Messages &result) { + auto getMessagesList = [&result, peer]() -> const QVector * { + auto handleMessages = [](auto &messages) { + App::feedUsers(messages.vusers); + App::feedChats(messages.vchats); + return &messages.vmessages.v; + }; + switch (result.type()) { + case mtpc_messages_messages: return handleMessages(result.c_messages_messages()); + case mtpc_messages_messagesSlice: return handleMessages(result.c_messages_messagesSlice()); + case mtpc_messages_channelMessages: { + auto &messages = result.c_messages_channelMessages(); + if (peer && peer->isChannel()) { + peer->asChannel()->ptsReceived(messages.vpts.v); + } else { + LOG( + ("API Error: received messages.channelMessages when no channel was passed! " + "(MainWidget::showJumpToDate)")); + } + return handleMessages(messages); + } break; + } + return nullptr; + }; - if (auto list = getMessagesList()) { - App::feedMsgs(*list, NewMessageExisting); - for (auto &message : *list) { - auto id = idFromMessage(message); - Ui::showPeerHistory(peer, id); - return; - } - } - Ui::showPeerHistory(peer, ShowAtUnreadMsgId); - }).send(); + if (auto list = getMessagesList()) { + App::feedMsgs(*list, NewMessageExisting); + for (auto &message : *list) { + auto id = idFromMessage(message); + Ui::showPeerHistory(peer, id); + return; + } + } + Ui::showPeerHistory(peer, ShowAtUnreadMsgId); + }) + .send(); } -void ApiWrap::preloadEnoughUnreadMentions(not_null history) { +void ApiWrap::preloadEnoughUnreadMentions(not_null history) { auto fullCount = history->getUnreadMentionsCount(); auto loadedCount = history->getUnreadMentionsLoadedCount(); auto allLoaded = (fullCount >= 0) ? (loadedCount >= fullCount) : false; @@ -1763,12 +1913,14 @@ void ApiWrap::preloadEnoughUnreadMentions(not_null history) { auto addOffset = loadedCount ? -(limit + 1) : -limit; auto maxId = 0; auto minId = 0; - auto requestId = request(MTPmessages_GetUnreadMentions(history->peer->input, MTP_int(offsetId), MTP_int(addOffset), MTP_int(limit), MTP_int(maxId), MTP_int(minId))).done([this, history](const MTPmessages_Messages &result) { - _unreadMentionsRequests.remove(history); - history->addUnreadMentionsSlice(result); - }).fail([this, history](const RPCError &error) { - _unreadMentionsRequests.remove(history); - }).send(); + auto requestId = request(MTPmessages_GetUnreadMentions(history->peer->input, MTP_int(offsetId), MTP_int(addOffset), + MTP_int(limit), MTP_int(maxId), MTP_int(minId))) + .done([this, history](const MTPmessages_Messages &result) { + _unreadMentionsRequests.remove(history); + history->addUnreadMentionsSlice(result); + }) + .fail([this, history](const RPCError &error) { _unreadMentionsRequests.remove(history); }) + .send(); _unreadMentionsRequests.emplace(history, requestId); } @@ -1784,90 +1936,88 @@ void ApiWrap::checkForUnreadMentions(const base::flat_set &possiblyReadMe } } -void ApiWrap::cancelEditChatAdmins(not_null chat) { - _chatAdminsEnabledRequests.take(chat) - | requestCanceller(); +void ApiWrap::cancelEditChatAdmins(not_null chat) { + _chatAdminsEnabledRequests.take(chat) | requestCanceller(); - _chatAdminsSaveRequests.take(chat) - | base::for_each_apply(requestCanceller()); + _chatAdminsSaveRequests.take(chat) | base::for_each_apply(requestCanceller()); _chatAdminsToSave.remove(chat); } -void ApiWrap::editChatAdmins( - not_null chat, - bool adminsEnabled, - base::flat_set> &&admins) { +void ApiWrap::editChatAdmins(not_null chat, bool adminsEnabled, + base::flat_set> &&admins) { cancelEditChatAdmins(chat); if (adminsEnabled) { _chatAdminsToSave.emplace(chat, std::move(admins)); } - auto requestId = request(MTPmessages_ToggleChatAdmins(chat->inputChat, MTP_bool(adminsEnabled))).done([this, chat](const MTPUpdates &updates) { - _chatAdminsEnabledRequests.remove(chat); - applyUpdates(updates); - saveChatAdmins(chat); - }).fail([this, chat](const RPCError &error) { - _chatAdminsEnabledRequests.remove(chat); - if (error.type() == qstr("CHAT_NOT_MODIFIED")) { - saveChatAdmins(chat); - } - }).send(); + auto requestId = request(MTPmessages_ToggleChatAdmins(chat->inputChat, MTP_bool(adminsEnabled))) + .done([this, chat](const MTPUpdates &updates) { + _chatAdminsEnabledRequests.remove(chat); + applyUpdates(updates); + saveChatAdmins(chat); + }) + .fail([this, chat](const RPCError &error) { + _chatAdminsEnabledRequests.remove(chat); + if (error.type() == qstr("CHAT_NOT_MODIFIED")) { + saveChatAdmins(chat); + } + }) + .send(); _chatAdminsEnabledRequests.emplace(chat, requestId); } -void ApiWrap::saveChatAdmins(not_null chat) { +void ApiWrap::saveChatAdmins(not_null chat) { if (!_chatAdminsToSave.contains(chat)) { return; } - auto requestId = request(MTPmessages_GetFullChat(chat->inputChat)).done([this, chat](const MTPmessages_ChatFull &result) { - _chatAdminsEnabledRequests.remove(chat); - processFullPeer(chat, result); - sendSaveChatAdminsRequests(chat); - }).fail([this, chat](const RPCError &error) { - _chatAdminsEnabledRequests.remove(chat); - _chatAdminsToSave.remove(chat); - }).send(); + auto requestId = request(MTPmessages_GetFullChat(chat->inputChat)) + .done([this, chat](const MTPmessages_ChatFull &result) { + _chatAdminsEnabledRequests.remove(chat); + processFullPeer(chat, result); + sendSaveChatAdminsRequests(chat); + }) + .fail([this, chat](const RPCError &error) { + _chatAdminsEnabledRequests.remove(chat); + _chatAdminsToSave.remove(chat); + }) + .send(); _chatAdminsEnabledRequests.emplace(chat, requestId); } -void ApiWrap::sendSaveChatAdminsRequests(not_null chat) { - auto editOne = [this, chat](not_null user, bool admin) { - auto requestId = request(MTPmessages_EditChatAdmin( - chat->inputChat, - user->inputUser, - MTP_bool(admin))) - .done([this, chat, user, admin]( - const MTPBool &result, - mtpRequestId requestId) { - _chatAdminsSaveRequests[chat].remove(requestId); - if (_chatAdminsSaveRequests[chat].empty()) { - _chatAdminsSaveRequests.remove(chat); - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::AdminsChanged); - } - if (mtpIsTrue(result)) { - if (admin) { - if (chat->noParticipantInfo()) { - requestFullPeer(chat); - } else { - chat->admins.insert(user); - } - } else { - chat->admins.remove(user); - } - } - }).fail([this, chat]( - const RPCError &error, - mtpRequestId requestId) { - _chatAdminsSaveRequests[chat].remove(requestId); - if (_chatAdminsSaveRequests[chat].empty()) { - _chatAdminsSaveRequests.remove(chat); - } - chat->invalidateParticipants(); - if (error.type() == qstr("USER_RESTRICTED")) { - Ui::show(Box(lang(lng_cant_do_this))); - } - }).canWait(5).send(); +void ApiWrap::sendSaveChatAdminsRequests(not_null chat) { + auto editOne = [this, chat](not_null user, bool admin) { + auto requestId = request(MTPmessages_EditChatAdmin(chat->inputChat, user->inputUser, MTP_bool(admin))) + .done([this, chat, user, admin](const MTPBool &result, mtpRequestId requestId) { + _chatAdminsSaveRequests[chat].remove(requestId); + if (_chatAdminsSaveRequests[chat].empty()) { + _chatAdminsSaveRequests.remove(chat); + Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::AdminsChanged); + } + if (mtpIsTrue(result)) { + if (admin) { + if (chat->noParticipantInfo()) { + requestFullPeer(chat); + } else { + chat->admins.insert(user); + } + } else { + chat->admins.remove(user); + } + } + }) + .fail([this, chat](const RPCError &error, mtpRequestId requestId) { + _chatAdminsSaveRequests[chat].remove(requestId); + if (_chatAdminsSaveRequests[chat].empty()) { + _chatAdminsSaveRequests.remove(chat); + } + chat->invalidateParticipants(); + if (error.type() == qstr("USER_RESTRICTED")) { + Ui::show(Box(lang(lng_cant_do_this))); + } + }) + .canWait(5) + .send(); _chatAdminsSaveRequests[chat].insert(requestId); }; @@ -1878,7 +2028,7 @@ void ApiWrap::sendSaveChatAdminsRequests(not_null chat) { Assert(!!admins); auto toRemove = chat->admins; - auto toAppoint = std::vector>(); + auto toAppoint = std::vector>(); if (!admins->empty()) { toAppoint.reserve(admins->size()); for (auto user : *admins) { diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index f0d23a5ee..8050d69d4 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -20,16 +20,16 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include "base/timer.h" -#include -#include "mtproto/rpc_sender.h" -#include "mtproto/core_types.h" -#include "core/single_timer.h" -#include "mtproto/sender.h" #include "base/flat_map.h" #include "base/flat_set.h" -#include "structs.h" +#include "base/timer.h" +#include "core/single_timer.h" #include "facades.h" +#include "mtproto/core_types.h" +#include "mtproto/rpc_sender.h" +#include "mtproto/sender.h" +#include "structs.h" +#include class AuthSession; @@ -49,17 +49,17 @@ class History; class ApiWrap : private MTP::Sender, private base::Subscriber { public: - ApiWrap(not_null session); + ApiWrap(not_null session); void start(); void applyUpdates(const MTPUpdates &updates, quint64 sentMessageRandomId = 0); - using RequestMessageDataCallback = base::lambda; + using RequestMessageDataCallback = base::lambda; void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback); void requestFullPeer(PeerData *peer); void requestPeer(PeerData *peer); - void requestPeers(const QList &peers); + void requestPeers(const QList &peers); void requestLastParticipants(ChannelData *channel, bool fromStart = true); void requestBots(ChannelData *channel); void requestParticipantsCountDelayed(ChannelData *channel); @@ -79,7 +79,7 @@ public: void requestStickerSets(); void saveStickerSets(const Stickers::Order &localOrder, const Stickers::Order &localRemoved); void updateStickers(); - void setGroupStickerSet(not_null megagroup, const MTPInputStickerSet &set); + void setGroupStickerSet(not_null megagroup, const MTPInputStickerSet &set); void joinChannel(ChannelData *channel); void leaveChannel(ChannelData *channel); @@ -96,7 +96,7 @@ public: void handlePrivacyChange(mtpTypeId keyTypeId, const MTPVector &rules); int onlineTillFromStatus(const MTPUserStatus &status, int currentOnlineTill); - base::Observable &fullPeerUpdated() { + base::Observable &fullPeerUpdated() { return _fullPeerUpdated; } @@ -105,15 +105,12 @@ public: void applyUpdatesNoPtsCheck(const MTPUpdates &updates); void applyUpdateNoPtsCheck(const MTPUpdate &update); - void jumpToDate(not_null peer, const QDate &date); + void jumpToDate(not_null peer, const QDate &date); - void preloadEnoughUnreadMentions(not_null history); + void preloadEnoughUnreadMentions(not_null history); void checkForUnreadMentions(const base::flat_set &possiblyReadMentions, ChannelData *channel = nullptr); - void editChatAdmins( - not_null chat, - bool adminsEnabled, - base::flat_set> &&admins); + void editChatAdmins(not_null chat, bool adminsEnabled, base::flat_set> &&admins); ~ApiWrap(); @@ -156,18 +153,18 @@ private: void requestFeaturedStickers(TimeId now); void requestSavedGifs(TimeId now); - void cancelEditChatAdmins(not_null chat); - void saveChatAdmins(not_null chat); - void sendSaveChatAdminsRequests(not_null chat); + void cancelEditChatAdmins(not_null chat); + void saveChatAdmins(not_null chat); + void sendSaveChatAdminsRequests(not_null chat); - not_null _session; + not_null _session; mtpRequestId _changelogSubscription = 0; MessageDataRequests _messageDataRequests; - QMap _channelMessageDataRequests; + QMap _channelMessageDataRequests; SingleQueuedInvokation _messageDataResolveDelayed; - using PeerRequests = QMap; + using PeerRequests = QMap; PeerRequests _fullPeerRequests; PeerRequests _peerRequests; @@ -175,24 +172,24 @@ private: PeerRequests _botsRequests; base::DelayedCallTimer _participantsCountRequestTimer; - typedef QPair KickRequest; + typedef QPair KickRequest; typedef QMap KickRequests; KickRequests _kickRequests; - QMap _selfParticipantRequests; + QMap _selfParticipantRequests; - QMap _webPagesPending; + QMap _webPagesPending; base::Timer _webPagesTimer; - QMap > _stickerSetRequests; + QMap> _stickerSetRequests; - QMap _channelAmInRequests; - QMap _blockRequests; - QMap _exportInviteRequests; + QMap _channelAmInRequests; + QMap _blockRequests; + QMap _exportInviteRequests; - QMap _notifySettingRequests; + QMap _notifySettingRequests; - QMap _draftsSaveRequestIds; + QMap _draftsSaveRequestIds; base::Timer _draftsSaveTimer; OrderedSet _stickerSetDisenableRequests; @@ -210,12 +207,11 @@ private: mtpRequestId _contactsStatusesRequestId = 0; - base::flat_map, mtpRequestId> _unreadMentionsRequests; + base::flat_map, mtpRequestId> _unreadMentionsRequests; - base::flat_map, mtpRequestId> _chatAdminsEnabledRequests; - base::flat_map, base::flat_set>> _chatAdminsToSave; - base::flat_map, base::flat_set> _chatAdminsSaveRequests; - - base::Observable _fullPeerUpdated; + base::flat_map, mtpRequestId> _chatAdminsEnabledRequests; + base::flat_map, base::flat_set>> _chatAdminsToSave; + base::flat_map, base::flat_set> _chatAdminsSaveRequests; + base::Observable _fullPeerUpdated; }; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 4d49df8be..c4801e018 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -24,2759 +24,2865 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include #endif // OS_MAC_OLD -#include "styles/style_overview.h" -#include "styles/style_mediaview.h" -#include "styles/style_chat_helpers.h" -#include "styles/style_history.h" -#include "styles/style_boxes.h" -#include "lang/lang_keys.h" +#include "apiwrap.h" +#include "application.h" +#include "auth_session.h" #include "data/data_abstract_structure.h" -#include "history/history_service_layout.h" #include "history/history_location_manager.h" #include "history/history_media_types.h" -#include "media/media_audio.h" +#include "history/history_service_layout.h" #include "inline_bots/inline_bot_layout_item.h" -#include "messenger.h" -#include "application.h" -#include "storage/file_upload.h" -#include "mainwindow.h" +#include "lang/lang_keys.h" #include "mainwidget.h" -#include "storage/localstorage.h" -#include "apiwrap.h" +#include "mainwindow.h" +#include "media/media_audio.h" +#include "messenger.h" #include "numbers.h" #include "observer_peer.h" -#include "auth_session.h" -#include "window/themes/window_theme.h" -#include "window/notifications_manager.h" #include "platform/platform_notifications_manager.h" +#include "storage/file_upload.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" +#include "styles/style_chat_helpers.h" +#include "styles/style_history.h" +#include "styles/style_mediaview.h" +#include "styles/style_overview.h" +#include "window/notifications_manager.h" +#include "window/themes/window_theme.h" -#include // used in list of PhotosData -#include #include +#include #include +#include // used in list of PhotosData namespace { - App::LaunchState _launchState = App::Launched; +App::LaunchState _launchState = App::Launched; - UserData *self = nullptr; +UserData *self = nullptr; - using PeersData = QHash; - PeersData peersData; +using PeersData = QHash; +PeersData peersData; - using MutedPeers = QMap; - MutedPeers mutedPeers; +using MutedPeers = QMap; +MutedPeers mutedPeers; - PhotosData photosData; - DocumentsData documentsData; +PhotosData photosData; +DocumentsData documentsData; - using LocationsData = QHash; - LocationsData locationsData; +using LocationsData = QHash; +LocationsData locationsData; - using WebPagesData = QHash; - WebPagesData webPagesData; +using WebPagesData = QHash; +WebPagesData webPagesData; - using GamesData = QHash; - GamesData gamesData; +using GamesData = QHash; +GamesData gamesData; - PhotoItems photoItems; - DocumentItems documentItems; - WebPageItems webPageItems; - GameItems gameItems; - SharedContactItems sharedContactItems; - GifItems gifItems; +PhotoItems photoItems; +DocumentItems documentItems; +WebPageItems webPageItems; +GameItems gameItems; +SharedContactItems sharedContactItems; +GifItems gifItems; - using DependentItemsSet = OrderedSet; - using DependentItems = QMap; - DependentItems dependentItems; +using DependentItemsSet = OrderedSet; +using DependentItems = QMap; +DependentItems dependentItems; - Histories histories; +Histories histories; - using MsgsData = QHash; - MsgsData msgsData; - using ChannelMsgsData = QMap; - ChannelMsgsData channelMsgsData; +using MsgsData = QHash; +MsgsData msgsData; +using ChannelMsgsData = QMap; +ChannelMsgsData channelMsgsData; - using RandomData = QMap; - RandomData randomData; +using RandomData = QMap; +RandomData randomData; - using SentData = QMap>; - SentData sentData; +using SentData = QMap>; +SentData sentData; - HistoryItem *hoveredItem = nullptr, - *pressedItem = nullptr, - *hoveredLinkItem = nullptr, - *pressedLinkItem = nullptr, - *contextItem = nullptr, - *mousedItem = nullptr; +HistoryItem *hoveredItem = nullptr, *pressedItem = nullptr, *hoveredLinkItem = nullptr, *pressedLinkItem = nullptr, + *contextItem = nullptr, *mousedItem = nullptr; - QPixmap *emoji = nullptr, *emojiLarge = nullptr; - style::font monofont; +QPixmap *emoji = nullptr, *emojiLarge = nullptr; +style::font monofont; - struct CornersPixmaps { - QPixmap p[4]; - }; - QVector corners; - using CornersMap = QMap; - CornersMap cornersMap; - QImage cornersMaskLarge[4], cornersMaskSmall[4]; +struct CornersPixmaps { + QPixmap p[4]; +}; +QVector corners; +using CornersMap = QMap; +CornersMap cornersMap; +QImage cornersMaskLarge[4], cornersMaskSmall[4]; - using EmojiImagesMap = QMap; - EmojiImagesMap MainEmojiMap; - QMap OtherEmojiMap; +using EmojiImagesMap = QMap; +EmojiImagesMap MainEmojiMap; +QMap OtherEmojiMap; - qint32 serviceImageCacheSize = 0; +qint32 serviceImageCacheSize = 0; - using LastPhotosList = QLinkedList; - LastPhotosList lastPhotos; - using LastPhotosMap = QHash; - LastPhotosMap lastPhotosMap; -} +using LastPhotosList = QLinkedList; +LastPhotosList lastPhotos; +using LastPhotosMap = QHash; +LastPhotosMap lastPhotosMap; +} // namespace namespace App { - QString formatPhone(QString phone) { - if (phone.isEmpty()) return QString(); - if (phone.at(0) == '0') return phone; +QString formatPhone(QString phone) { + if (phone.isEmpty()) return QString(); + if (phone.at(0) == '0') return phone; - QString number = phone; - for (const QChar *ch = phone.constData(), *e = ch + phone.size(); ch != e; ++ch) { - if (ch->unicode() < '0' || ch->unicode() > '9') { - number = phone.replace(QRegularExpression(qsl("[^\\d]")), QString()); - } + QString number = phone; + for (const QChar *ch = phone.constData(), *e = ch + phone.size(); ch != e; ++ch) { + if (ch->unicode() < '0' || ch->unicode() > '9') { + number = phone.replace(QRegularExpression(qsl("[^\\d]")), QString()); } - QVector groups = phoneNumberParse(number); - if (groups.isEmpty()) return '+' + number; - - QString result; - result.reserve(number.size() + groups.size() + 1); - result.append('+'); - qint32 sum = 0; - for (qint32 i = 0, l = groups.size(); i < l; ++i) { - result.append(number.midRef(sum, groups.at(i))); - sum += groups.at(i); - if (sum < number.size()) result.append(' '); - } - if (sum < number.size()) result.append(number.midRef(sum)); - return result; } + QVector groups = phoneNumberParse(number); + if (groups.isEmpty()) return '+' + number; - MainWindow *wnd() { - if (auto instance = Messenger::InstancePointer()) { - return instance->getActiveWindow(); - } - return nullptr; + QString result; + result.reserve(number.size() + groups.size() + 1); + result.append('+'); + qint32 sum = 0; + for (qint32 i = 0, l = groups.size(); i < l; ++i) { + result.append(number.midRef(sum, groups.at(i))); + sum += groups.at(i); + if (sum < number.size()) result.append(' '); } + if (sum < number.size()) result.append(number.midRef(sum)); + return result; +} - MainWidget *main() { - if (auto window = wnd()) { - return window->mainWidget(); - } - return nullptr; +MainWindow *wnd() { + if (auto instance = Messenger::InstancePointer()) { + return instance->getActiveWindow(); } + return nullptr; +} - bool passcoded() { - if (auto window = wnd()) { - return window->passcodeWidget(); - } - return false; +MainWidget *main() { + if (auto window = wnd()) { + return window->mainWidget(); } + return nullptr; +} + +bool passcoded() { + if (auto window = wnd()) { + return window->passcodeWidget(); + } + return false; +} namespace { - bool loggedOut() { - if (Global::LocalPasscode()) { - Global::SetLocalPasscode(false); - Global::RefLocalPasscodeChanged().notify(); - } - Media::Player::mixer()->stopAndClear(); - if (auto w = wnd()) { - w->tempDirDelete(Local::ClearManagerAll); - w->setupIntro(); - } - histories().clear(); - Messenger::Instance().authSessionDestroy(); - Local::reset(); - Window::Theme::Background()->reset(); - - cSetOtherOnline(0); - globalNotifyAllPtr = UnknownNotifySettings; - globalNotifyUsersPtr = UnknownNotifySettings; - globalNotifyChatsPtr = UnknownNotifySettings; - clearStorageImages(); - if (auto w = wnd()) { - w->updateConnectingStatus(); - } - return true; +bool loggedOut() { + if (Global::LocalPasscode()) { + Global::SetLocalPasscode(false); + Global::RefLocalPasscodeChanged().notify(); } + Media::Player::mixer()->stopAndClear(); + if (auto w = wnd()) { + w->tempDirDelete(Local::ClearManagerAll); + w->setupIntro(); + } + histories().clear(); + Messenger::Instance().authSessionDestroy(); + Local::reset(); + Window::Theme::Background()->reset(); + + cSetOtherOnline(0); + globalNotifyAllPtr = UnknownNotifySettings; + globalNotifyUsersPtr = UnknownNotifySettings; + globalNotifyChatsPtr = UnknownNotifySettings; + clearStorageImages(); + if (auto w = wnd()) { + w->updateConnectingStatus(); + } + return true; +} } // namespace - void logOut() { - if (auto mtproto = Messenger::Instance().mtp()) { - mtproto->logout(rpcDone(&loggedOut), rpcFail(&loggedOut)); - } else { - // We log out because we've forgotten passcode. - // So we just start mtproto from scratch. - Messenger::Instance().startMtp(); - loggedOut(); - } +void logOut() { + if (auto mtproto = Messenger::Instance().mtp()) { + mtproto->logout(rpcDone(&loggedOut), rpcFail(&loggedOut)); + } else { + // We log out because we've forgotten passcode. + // So we just start mtproto from scratch. + Messenger::Instance().startMtp(); + loggedOut(); } +} - TimeId onlineForSort(UserData *user, TimeId now) { - if (isServiceUser(user->id) || user->botInfo) { - return -1; - } - TimeId online = user->onlineTill; - if (online <= 0) { - switch (online) { - case 0: - case -1: return online; - - case -2: { - QDate yesterday(date(now).date()); - return qint32(QDateTime(yesterday.addDays(-3)).toTime_t()) + (unixtime() - myunixtime()); - } break; - - case -3: { - QDate weekago(date(now).date()); - return qint32(QDateTime(weekago.addDays(-7)).toTime_t()) + (unixtime() - myunixtime()); - } break; - - case -4: { - QDate monthago(date(now).date()); - return qint32(QDateTime(monthago.addDays(-30)).toTime_t()) + (unixtime() - myunixtime()); - } break; - } - return -online; - } - return online; +TimeId onlineForSort(UserData *user, TimeId now) { + if (isServiceUser(user->id) || user->botInfo) { + return -1; } + TimeId online = user->onlineTill; + if (online <= 0) { + switch (online) { + case 0: + case -1: return online; - qint32 onlineWillChangeIn(UserData *user, TimeId now) { - if (isServiceUser(user->id) || user->botInfo) { - return 86400; + case -2: { + QDate yesterday(date(now).date()); + return qint32(QDateTime(yesterday.addDays(-3)).toTime_t()) + (unixtime() - myunixtime()); + } break; + + case -3: { + QDate weekago(date(now).date()); + return qint32(QDateTime(weekago.addDays(-7)).toTime_t()) + (unixtime() - myunixtime()); + } break; + + case -4: { + QDate monthago(date(now).date()); + return qint32(QDateTime(monthago.addDays(-30)).toTime_t()) + (unixtime() - myunixtime()); + } break; } - return onlineWillChangeIn(user->onlineTill, now); + return -online; } + return online; +} - qint32 onlineWillChangeIn(TimeId online, TimeId now) { - if (online <= 0) { - if (-online > now) return -online - now; - return 86400; - } - if (online > now) { - return online - now; - } - qint32 minutes = (now - online) / 60; - if (minutes < 60) { - return (minutes + 1) * 60 - (now - online); - } - qint32 hours = (now - online) / 3600; - if (hours < 12) { - return (hours + 1) * 3600 - (now - online); - } - QDateTime dNow(date(now)), dTomorrow(dNow.date().addDays(1)); - return dNow.secsTo(dTomorrow); +qint32 onlineWillChangeIn(UserData *user, TimeId now) { + if (isServiceUser(user->id) || user->botInfo) { + return 86400; } + return onlineWillChangeIn(user->onlineTill, now); +} - QString onlineText(UserData *user, TimeId now, bool precise) { - if (isNotificationsUser(user->id)) { - return lang(lng_status_service_notifications); - } else if (user->botInfo) { - return lang(lng_status_bot); - } else if (isServiceUser(user->id)) { - return lang(lng_status_support); - } - return onlineText(user->onlineTill, now, precise); +qint32 onlineWillChangeIn(TimeId online, TimeId now) { + if (online <= 0) { + if (-online > now) return -online - now; + return 86400; } + if (online > now) { + return online - now; + } + qint32 minutes = (now - online) / 60; + if (minutes < 60) { + return (minutes + 1) * 60 - (now - online); + } + qint32 hours = (now - online) / 3600; + if (hours < 12) { + return (hours + 1) * 3600 - (now - online); + } + QDateTime dNow(date(now)), dTomorrow(dNow.date().addDays(1)); + return dNow.secsTo(dTomorrow); +} - QString onlineText(TimeId online, TimeId now, bool precise) { - if (online <= 0) { - switch (online) { - case 0: - case -1: return lang(lng_status_offline); - case -2: return lang(lng_status_recently); - case -3: return lang(lng_status_last_week); - case -4: return lang(lng_status_last_month); - } - return (-online > now) ? lang(lng_status_online) : lang(lng_status_recently); - } - if (online > now) { - return lang(lng_status_online); - } - QString when; - if (precise) { - QDateTime dOnline(date(online)), dNow(date(now)); - if (dOnline.date() == dNow.date()) { - return lng_status_lastseen_today(lt_time, dOnline.time().toString(cTimeFormat())); - } else if (dOnline.date().addDays(1) == dNow.date()) { - return lng_status_lastseen_yesterday(lt_time, dOnline.time().toString(cTimeFormat())); - } - return lng_status_lastseen_date_time(lt_date, dOnline.date().toString(qsl("dd.MM.yy")), lt_time, dOnline.time().toString(cTimeFormat())); - } - qint32 minutes = (now - online) / 60; - if (!minutes) { - return lang(lng_status_lastseen_now); - } else if (minutes < 60) { - return lng_status_lastseen_minutes(lt_count, minutes); - } - qint32 hours = (now - online) / 3600; - if (hours < 12) { - return lng_status_lastseen_hours(lt_count, hours); +QString onlineText(UserData *user, TimeId now, bool precise) { + if (isNotificationsUser(user->id)) { + return lang(lng_status_service_notifications); + } else if (user->botInfo) { + return lang(lng_status_bot); + } else if (isServiceUser(user->id)) { + return lang(lng_status_support); + } + return onlineText(user->onlineTill, now, precise); +} + +QString onlineText(TimeId online, TimeId now, bool precise) { + if (online <= 0) { + switch (online) { + case 0: + case -1: return lang(lng_status_offline); + case -2: return lang(lng_status_recently); + case -3: return lang(lng_status_last_week); + case -4: return lang(lng_status_last_month); } + return (-online > now) ? lang(lng_status_online) : lang(lng_status_recently); + } + if (online > now) { + return lang(lng_status_online); + } + QString when; + if (precise) { QDateTime dOnline(date(online)), dNow(date(now)); if (dOnline.date() == dNow.date()) { return lng_status_lastseen_today(lt_time, dOnline.time().toString(cTimeFormat())); } else if (dOnline.date().addDays(1) == dNow.date()) { return lng_status_lastseen_yesterday(lt_time, dOnline.time().toString(cTimeFormat())); } - return lng_status_lastseen_date(lt_date, dOnline.date().toString(qsl("dd.MM.yy"))); + return lng_status_lastseen_date_time(lt_date, dOnline.date().toString(qsl("dd.MM.yy")), lt_time, + dOnline.time().toString(cTimeFormat())); + } + qint32 minutes = (now - online) / 60; + if (!minutes) { + return lang(lng_status_lastseen_now); + } else if (minutes < 60) { + return lng_status_lastseen_minutes(lt_count, minutes); + } + qint32 hours = (now - online) / 3600; + if (hours < 12) { + return lng_status_lastseen_hours(lt_count, hours); + } + QDateTime dOnline(date(online)), dNow(date(now)); + if (dOnline.date() == dNow.date()) { + return lng_status_lastseen_today(lt_time, dOnline.time().toString(cTimeFormat())); + } else if (dOnline.date().addDays(1) == dNow.date()) { + return lng_status_lastseen_yesterday(lt_time, dOnline.time().toString(cTimeFormat())); + } + return lng_status_lastseen_date(lt_date, dOnline.date().toString(qsl("dd.MM.yy"))); +} + +namespace { +// we should get a full restriction in "{fulltype}: {reason}" format and we +// need to find a "-all" tag in {fulltype}, otherwise ignore this restriction +QString extractRestrictionReason(const QString &fullRestriction) { + int fullTypeEnd = fullRestriction.indexOf(':'); + if (fullTypeEnd <= 0) { + return QString(); } - namespace { - // we should get a full restriction in "{fulltype}: {reason}" format and we - // need to find a "-all" tag in {fulltype}, otherwise ignore this restriction - QString extractRestrictionReason(const QString &fullRestriction) { - int fullTypeEnd = fullRestriction.indexOf(':'); - if (fullTypeEnd <= 0) { - return QString(); - } - - // {fulltype} is in "{type}-{tag}-{tag}-{tag}" format - // if we find "all" tag we return the restriction string - auto typeTags = fullRestriction.mid(0, fullTypeEnd).split('-').mid(1); + // {fulltype} is in "{type}-{tag}-{tag}-{tag}" format + // if we find "all" tag we return the restriction string + auto typeTags = fullRestriction.mid(0, fullTypeEnd).split('-').mid(1); #ifndef OS_MAC_STORE - auto restrictionApplies = typeTags.contains(qsl("all")); + auto restrictionApplies = typeTags.contains(qsl("all")); #else // OS_MAC_STORE - auto restrictionApplies = typeTags.contains(qsl("all")) || typeTags.contains(qsl("ios")); + auto restrictionApplies = typeTags.contains(qsl("all")) || typeTags.contains(qsl("ios")); #endif // OS_MAC_STORE - if (restrictionApplies) { - return fullRestriction.midRef(fullTypeEnd + 1).trimmed().toString(); + if (restrictionApplies) { + return fullRestriction.midRef(fullTypeEnd + 1).trimmed().toString(); + } + return QString(); +} +} // namespace + +bool onlineColorUse(UserData *user, TimeId now) { + if (isServiceUser(user->id) || user->botInfo) { + return false; + } + return onlineColorUse(user->onlineTill, now); +} + +bool onlineColorUse(TimeId online, TimeId now) { + if (online <= 0) { + switch (online) { + case 0: + case -1: + case -2: + case -3: + case -4: return false; + } + return (-online > now); + } + return (online > now); +} + +UserData *feedUser(const MTPUser &user) { + UserData *data = nullptr; + bool wasContact = false, minimal = false; + const MTPUserStatus *status = 0, emptyStatus = MTP_userStatusEmpty(); + + Notify::PeerUpdate update; + using UpdateFlag = Notify::PeerUpdate::Flag; + + switch (user.type()) { + case mtpc_userEmpty: { + auto &d = user.c_userEmpty(); + + auto peer = peerFromUser(d.vid.v); + data = App::user(peer); + auto canShareThisContact = data->canShareThisContactFast(); + wasContact = data->isContact(); + + data->input = MTP_inputPeerUser(d.vid, MTP_long(0)); + data->inputUser = MTP_inputUser(d.vid, MTP_long(0)); + data->setName(lang(lng_deleted), QString(), QString(), QString()); + data->setPhoto(MTP_userProfilePhotoEmpty()); + data->setIsInaccessible(); + data->flags = 0; + data->setBotInfoVersion(-1); + status = &emptyStatus; + data->contact = -1; + + if (canShareThisContact != data->canShareThisContactFast()) update.flags |= UpdateFlag::UserCanShareContact; + if (wasContact != data->isContact()) update.flags |= UpdateFlag::UserIsContact; + } break; + case mtpc_user: { + auto &d = user.c_user(); + minimal = d.is_min(); + + auto peer = peerFromUser(d.vid.v); + data = App::user(peer); + auto canShareThisContact = data->canShareThisContactFast(); + wasContact = data->isContact(); + if (!minimal) { + data->flags = d.vflags.v; + if (d.is_self()) { + data->input = MTP_inputPeerSelf(); + data->inputUser = MTP_inputUserSelf(); + } else if (!d.has_access_hash()) { + data->input = MTP_inputPeerUser(d.vid, MTP_long(data->isInaccessible() ? 0 : data->access)); + data->inputUser = MTP_inputUser(d.vid, MTP_long(data->isInaccessible() ? 0 : data->access)); + } else { + data->input = MTP_inputPeerUser(d.vid, d.vaccess_hash); + data->inputUser = MTP_inputUser(d.vid, d.vaccess_hash); } - return QString(); - } - } - - bool onlineColorUse(UserData *user, TimeId now) { - if (isServiceUser(user->id) || user->botInfo) { - return false; - } - return onlineColorUse(user->onlineTill, now); - } - - bool onlineColorUse(TimeId online, TimeId now) { - if (online <= 0) { - switch (online) { - case 0: - case -1: - case -2: - case -3: - case -4: return false; + if (d.is_restricted()) { + data->setRestrictionReason(extractRestrictionReason(qs(d.vrestriction_reason))); + } else { + data->setRestrictionReason(QString()); } - return (-online > now); } - return (online > now); - } - - UserData *feedUser(const MTPUser &user) { - UserData *data = nullptr; - bool wasContact = false, minimal = false; - const MTPUserStatus *status = 0, emptyStatus = MTP_userStatusEmpty(); - - Notify::PeerUpdate update; - using UpdateFlag = Notify::PeerUpdate::Flag; - - switch (user.type()) { - case mtpc_userEmpty: { - auto &d = user.c_userEmpty(); - - auto peer = peerFromUser(d.vid.v); - data = App::user(peer); - auto canShareThisContact = data->canShareThisContactFast(); - wasContact = data->isContact(); - - data->input = MTP_inputPeerUser(d.vid, MTP_long(0)); - data->inputUser = MTP_inputUser(d.vid, MTP_long(0)); + if (d.is_deleted()) { + if (!data->phone().isEmpty()) { + data->setPhone(QString()); + update.flags |= UpdateFlag::UserPhoneChanged; + } data->setName(lang(lng_deleted), QString(), QString(), QString()); data->setPhoto(MTP_userProfilePhotoEmpty()); data->setIsInaccessible(); - data->flags = 0; - data->setBotInfoVersion(-1); status = &emptyStatus; - data->contact = -1; + } else { + // apply first_name and last_name from minimal user only if we don't have + // local values for first name and last name already, otherwise skip + bool noLocalName = data->firstName.isEmpty() && data->lastName.isEmpty(); + QString fname = (!minimal || noLocalName) ? + (d.has_first_name() ? TextUtilities::SingleLine(qs(d.vfirst_name)) : QString()) : + data->firstName; + QString lname = (!minimal || noLocalName) ? + (d.has_last_name() ? TextUtilities::SingleLine(qs(d.vlast_name)) : QString()) : + data->lastName; - if (canShareThisContact != data->canShareThisContactFast()) update.flags |= UpdateFlag::UserCanShareContact; - if (wasContact != data->isContact()) update.flags |= UpdateFlag::UserIsContact; - } break; - case mtpc_user: { - auto &d = user.c_user(); - minimal = d.is_min(); + QString phone = minimal ? data->phone() : (d.has_phone() ? qs(d.vphone) : QString()); + QString uname = + minimal ? data->username : (d.has_username() ? TextUtilities::SingleLine(qs(d.vusername)) : QString()); - auto peer = peerFromUser(d.vid.v); - data = App::user(peer); - auto canShareThisContact = data->canShareThisContactFast(); - wasContact = data->isContact(); - if (!minimal) { - data->flags = d.vflags.v; - if (d.is_self()) { - data->input = MTP_inputPeerSelf(); - data->inputUser = MTP_inputUserSelf(); - } else if (!d.has_access_hash()) { - data->input = MTP_inputPeerUser(d.vid, MTP_long(data->isInaccessible() ? 0 : data->access)); - data->inputUser = MTP_inputUser(d.vid, MTP_long(data->isInaccessible() ? 0 : data->access)); - } else { - data->input = MTP_inputPeerUser(d.vid, d.vaccess_hash); - data->inputUser = MTP_inputUser(d.vid, d.vaccess_hash); - } - if (d.is_restricted()) { - data->setRestrictionReason(extractRestrictionReason(qs(d.vrestriction_reason))); - } else { - data->setRestrictionReason(QString()); - } + bool phoneChanged = (data->phone() != phone); + if (phoneChanged) { + data->setPhone(phone); + update.flags |= UpdateFlag::UserPhoneChanged; } - if (d.is_deleted()) { - if (!data->phone().isEmpty()) { - data->setPhone(QString()); - update.flags |= UpdateFlag::UserPhoneChanged; - } - data->setName(lang(lng_deleted), QString(), QString(), QString()); + bool nameChanged = (data->firstName != fname) || (data->lastName != lname); + + bool showPhone = !isServiceUser(data->id) && !d.is_self() && !d.is_contact() && !d.is_mutual_contact(); + bool showPhoneChanged = !isServiceUser(data->id) && !d.is_self() && + ((showPhone && data->contact) || (!showPhone && !data->contact)); + if (minimal) { + showPhoneChanged = false; + showPhone = !isServiceUser(data->id) && (data->id != Auth().userPeerId()) && !data->contact; + } + + // see also Local::readPeer + + QString pname = (showPhoneChanged || phoneChanged || nameChanged) ? + ((showPhone && !phone.isEmpty()) ? formatPhone(phone) : QString()) : + data->nameOrPhone; + + if (!minimal && d.is_self() && uname != data->username) { + SignalHandlers::setCrashAnnotation("Username", uname); + } + data->setName(fname, lname, pname, uname); + if (d.has_photo()) { + data->setPhoto(d.vphoto); + } else { data->setPhoto(MTP_userProfilePhotoEmpty()); - data->setIsInaccessible(); - status = &emptyStatus; + } + if (d.has_access_hash()) data->access = d.vaccess_hash.v; + status = d.has_status() ? &d.vstatus : &emptyStatus; + } + if (!minimal) { + if (d.has_bot_info_version()) { + data->setBotInfoVersion(d.vbot_info_version.v); + data->botInfo->readsAllHistory = d.is_bot_chat_history(); + if (data->botInfo->cantJoinGroups != d.is_bot_nochats()) { + data->botInfo->cantJoinGroups = d.is_bot_nochats(); + update.flags |= UpdateFlag::BotCanAddToGroups; + } + data->botInfo->inlinePlaceholder = + d.has_bot_inline_placeholder() ? '_' + qs(d.vbot_inline_placeholder) : QString(); } else { - // apply first_name and last_name from minimal user only if we don't have - // local values for first name and last name already, otherwise skip - bool noLocalName = data->firstName.isEmpty() && data->lastName.isEmpty(); - QString fname = (!minimal || noLocalName) ? (d.has_first_name() ? TextUtilities::SingleLine(qs(d.vfirst_name)) : QString()) : data->firstName; - QString lname = (!minimal || noLocalName) ? (d.has_last_name() ? TextUtilities::SingleLine(qs(d.vlast_name)) : QString()) : data->lastName; - - QString phone = minimal ? data->phone() : (d.has_phone() ? qs(d.vphone) : QString()); - QString uname = minimal ? data->username : (d.has_username() ? TextUtilities::SingleLine(qs(d.vusername)) : QString()); - - bool phoneChanged = (data->phone() != phone); - if (phoneChanged) { - data->setPhone(phone); - update.flags |= UpdateFlag::UserPhoneChanged; - } - bool nameChanged = (data->firstName != fname) || (data->lastName != lname); - - bool showPhone = !isServiceUser(data->id) && !d.is_self() && !d.is_contact() && !d.is_mutual_contact(); - bool showPhoneChanged = !isServiceUser(data->id) && !d.is_self() && ((showPhone && data->contact) || (!showPhone && !data->contact)); - if (minimal) { - showPhoneChanged = false; - showPhone = !isServiceUser(data->id) && (data->id != Auth().userPeerId()) && !data->contact; - } - - // see also Local::readPeer - - QString pname = (showPhoneChanged || phoneChanged || nameChanged) ? ((showPhone && !phone.isEmpty()) ? formatPhone(phone) : QString()) : data->nameOrPhone; - - if (!minimal && d.is_self() && uname != data->username) { - SignalHandlers::setCrashAnnotation("Username", uname); - } - data->setName(fname, lname, pname, uname); - if (d.has_photo()) { - data->setPhoto(d.vphoto); - } else { - data->setPhoto(MTP_userProfilePhotoEmpty()); - } - if (d.has_access_hash()) data->access = d.vaccess_hash.v; - status = d.has_status() ? &d.vstatus : &emptyStatus; + data->setBotInfoVersion(-1); } - if (!minimal) { - if (d.has_bot_info_version()) { - data->setBotInfoVersion(d.vbot_info_version.v); - data->botInfo->readsAllHistory = d.is_bot_chat_history(); - if (data->botInfo->cantJoinGroups != d.is_bot_nochats()) { - data->botInfo->cantJoinGroups = d.is_bot_nochats(); - update.flags |= UpdateFlag::BotCanAddToGroups; - } - data->botInfo->inlinePlaceholder = d.has_bot_inline_placeholder() ? '_' + qs(d.vbot_inline_placeholder) : QString(); - } else { - data->setBotInfoVersion(-1); - } - data->contact = (d.is_contact() || d.is_mutual_contact()) ? 1 : (data->phone().isEmpty() ? -1 : 0); - if (data->contact == 1 && cReportSpamStatuses().value(data->id, dbiprsHidden) != dbiprsHidden) { - cRefReportSpamStatuses().insert(data->id, dbiprsHidden); - Local::writeReportSpamStatuses(); - } - if (d.is_self() && ::self != data) { - ::self = data; - Global::RefSelfChanged().notify(); - } + data->contact = (d.is_contact() || d.is_mutual_contact()) ? 1 : (data->phone().isEmpty() ? -1 : 0); + if (data->contact == 1 && cReportSpamStatuses().value(data->id, dbiprsHidden) != dbiprsHidden) { + cRefReportSpamStatuses().insert(data->id, dbiprsHidden); + Local::writeReportSpamStatuses(); } - - if (canShareThisContact != data->canShareThisContactFast()) update.flags |= UpdateFlag::UserCanShareContact; - if (wasContact != data->isContact()) update.flags |= UpdateFlag::UserIsContact; - } break; - } - - if (!data) { - return nullptr; - } - - if (minimal) { - if (data->loadedStatus == PeerData::NotLoaded) { - data->loadedStatus = PeerData::MinimalLoaded; - } - } else if (data->loadedStatus != PeerData::FullLoaded) { - data->loadedStatus = PeerData::FullLoaded; - } - - if (status && !minimal) { - auto oldOnlineTill = data->onlineTill; - auto newOnlineTill = Auth().api().onlineTillFromStatus(*status, oldOnlineTill); - if (oldOnlineTill != newOnlineTill) { - data->onlineTill = newOnlineTill; - update.flags |= UpdateFlag::UserOnlineChanged; + if (d.is_self() && ::self != data) { + ::self = data; + Global::RefSelfChanged().notify(); } } - if (data->contact < 0 && !data->phone().isEmpty() && data->id != Auth().userPeerId()) { - data->contact = 0; - } - if (App::main()) { - if ((data->contact > 0 && !wasContact) || (wasContact && data->contact < 1)) { - Notify::userIsContactChanged(data); - } - if (update.flags) { - update.peer = data; - Notify::peerUpdatedDelayed(update); - } - } - return data; + if (canShareThisContact != data->canShareThisContactFast()) update.flags |= UpdateFlag::UserCanShareContact; + if (wasContact != data->isContact()) update.flags |= UpdateFlag::UserIsContact; + } break; } - UserData *feedUsers(const MTPVector &users) { - UserData *result = nullptr; - for_const (auto &user, users.v) { - if (auto feededUser = feedUser(user)) { - result = feededUser; - } - } - - return result; + if (!data) { + return nullptr; } - PeerData *feedChat(const MTPChat &chat) { - PeerData *data = nullptr; - bool minimal = false; - - Notify::PeerUpdate update; - using UpdateFlag = Notify::PeerUpdate::Flag; - - switch (chat.type()) { - case mtpc_chat: { - auto &d(chat.c_chat()); - - data = App::chat(peerFromChat(d.vid.v)); - auto cdata = data->asChat(); - auto canEdit = cdata->canEdit(); - - if (cdata->version < d.vversion.v) { - cdata->version = d.vversion.v; - cdata->invalidateParticipants(); - } - - data->input = MTP_inputPeerChat(d.vid); - cdata->setName(qs(d.vtitle)); - cdata->setPhoto(d.vphoto); - cdata->date = d.vdate.v; - - if (d.has_migrated_to() && d.vmigrated_to.type() == mtpc_inputChannel) { - const auto &c(d.vmigrated_to.c_inputChannel()); - ChannelData *channel = App::channel(peerFromChannel(c.vchannel_id)); - if (!channel->mgInfo) { - channel->flags |= MTPDchannel::Flag::f_megagroup; - channel->flagsUpdated(); - } - if (!channel->access) { - channel->input = MTP_inputPeerChannel(c.vchannel_id, c.vaccess_hash); - channel->inputChannel = d.vmigrated_to; - channel->access = d.vmigrated_to.c_inputChannel().vaccess_hash.v; - } - bool updatedTo = (cdata->migrateToPtr != channel), updatedFrom = (channel->mgInfo->migrateFromPtr != cdata); - if (updatedTo) { - cdata->migrateToPtr = channel; - } - if (updatedFrom) { - channel->mgInfo->migrateFromPtr = cdata; - if (History *h = App::historyLoaded(cdata->id)) { - if (History *hto = App::historyLoaded(channel->id)) { - if (!h->isEmpty()) { - h->clear(true); - } - if (hto->inChatList(Dialogs::Mode::All) && h->inChatList(Dialogs::Mode::All)) { - App::removeDialog(h); - } - } - } - Notify::migrateUpdated(channel); - update.flags |= UpdateFlag::MigrationChanged; - } - if (updatedTo) { - Notify::migrateUpdated(cdata); - update.flags |= UpdateFlag::MigrationChanged; - } - } - - if (!(cdata->flags & MTPDchat::Flag::f_admins_enabled) && (d.vflags.v & MTPDchat::Flag::f_admins_enabled)) { - cdata->invalidateParticipants(); - } - cdata->flags = d.vflags.v; - - cdata->count = d.vparticipants_count.v; - cdata->setIsForbidden(false); - if (canEdit != cdata->canEdit()) { - update.flags |= UpdateFlag::ChatCanEdit; - } - } break; - case mtpc_chatForbidden: { - auto &d(chat.c_chatForbidden()); - - data = App::chat(peerFromChat(d.vid.v)); - auto cdata = data->asChat(); - auto canEdit = cdata->canEdit(); - - data->input = MTP_inputPeerChat(d.vid); - cdata->setName(qs(d.vtitle)); - cdata->setPhoto(MTP_chatPhotoEmpty()); - cdata->date = 0; - cdata->count = -1; - cdata->invalidateParticipants(); - cdata->flags = 0; - cdata->setIsForbidden(true); - if (canEdit != cdata->canEdit()) { - update.flags |= UpdateFlag::ChatCanEdit; - } - } break; - case mtpc_channel: { - auto &d = chat.c_channel(); - - auto peerId = peerFromChannel(d.vid.v); - minimal = d.is_min(); - if (minimal) { - data = App::channelLoaded(peerId); - if (!data) { - return nullptr; // minimal is not loaded, need to make getDifference - } - } else { - data = App::channel(peerId); - data->input = MTP_inputPeerChannel(d.vid, d.has_access_hash() ? d.vaccess_hash : MTP_long(0)); - } - - auto cdata = data->asChannel(); - auto wasInChannel = cdata->amIn(); - auto canViewAdmins = cdata->canViewAdmins(); - auto canViewMembers = cdata->canViewMembers(); - auto canAddMembers = cdata->canAddMembers(); - - if (minimal) { - auto mask = MTPDchannel::Flag::f_broadcast | MTPDchannel::Flag::f_verified | MTPDchannel::Flag::f_megagroup | MTPDchannel::Flag::f_democracy; - cdata->flags = (cdata->flags & ~mask) | (d.vflags.v & mask); - } else { - if (d.has_admin_rights()) { - cdata->setAdminRights(d.vadmin_rights); - } else if (cdata->hasAdminRights()) { - cdata->setAdminRights(MTP_channelAdminRights(MTP_flags(0))); - } - if (d.has_banned_rights()) { - cdata->setRestrictedRights(d.vbanned_rights); - } else if (cdata->hasRestrictedRights()) { - cdata->setRestrictedRights(MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); - } - cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash); - cdata->access = d.vaccess_hash.v; - cdata->date = d.vdate.v; - if (cdata->version < d.vversion.v) { - cdata->version = d.vversion.v; - } - if (d.is_restricted()) { - cdata->setRestrictionReason(extractRestrictionReason(qs(d.vrestriction_reason))); - } else { - cdata->setRestrictionReason(QString()); - } - cdata->flags = d.vflags.v; - } - cdata->flagsUpdated(); - - QString uname = d.has_username() ? TextUtilities::SingleLine(qs(d.vusername)) : QString(); - cdata->setName(qs(d.vtitle), uname); - - cdata->setIsForbidden(false); - cdata->setPhoto(d.vphoto); - - if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn; - if (canViewAdmins != cdata->canViewAdmins() - || canViewMembers != cdata->canViewMembers() - || canAddMembers != cdata->canAddMembers()) update.flags |= UpdateFlag::ChannelRightsChanged; - } break; - case mtpc_channelForbidden: { - auto &d(chat.c_channelForbidden()); - - auto peerId = peerFromChannel(d.vid.v); - data = App::channel(peerId); - data->input = MTP_inputPeerChannel(d.vid, d.vaccess_hash); - - auto cdata = data->asChannel(); - auto wasInChannel = cdata->amIn(); - auto canViewAdmins = cdata->canViewAdmins(); - auto canViewMembers = cdata->canViewMembers(); - auto canAddMembers = cdata->canAddMembers(); - - cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash); - - auto mask = mtpCastFlags(MTPDchannelForbidden::Flag::f_broadcast | MTPDchannelForbidden::Flag::f_megagroup); - cdata->flags = (cdata->flags & ~mask) | (mtpCastFlags(d.vflags) & mask); - cdata->flagsUpdated(); - - if (cdata->hasAdminRights()) { - cdata->setAdminRights(MTP_channelAdminRights(MTP_flags(0))); - } - if (cdata->hasRestrictedRights()) { - cdata->setRestrictedRights(MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); - } - - cdata->setName(qs(d.vtitle), QString()); - - cdata->access = d.vaccess_hash.v; - cdata->setPhoto(MTP_chatPhotoEmpty()); - cdata->date = 0; - cdata->setMembersCount(0); - cdata->setIsForbidden(true); - - if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn; - if (canViewAdmins != cdata->canViewAdmins() - || canViewMembers != cdata->canViewMembers() - || canAddMembers != cdata->canAddMembers()) update.flags |= UpdateFlag::ChannelRightsChanged; - } break; - } - if (!data) { - return nullptr; + if (minimal) { + if (data->loadedStatus == PeerData::NotLoaded) { + data->loadedStatus = PeerData::MinimalLoaded; } + } else if (data->loadedStatus != PeerData::FullLoaded) { + data->loadedStatus = PeerData::FullLoaded; + } - if (minimal) { - if (data->loadedStatus == PeerData::NotLoaded) { - data->loadedStatus = PeerData::MinimalLoaded; - } - } else if (data->loadedStatus != PeerData::FullLoaded) { - data->loadedStatus = PeerData::FullLoaded; + if (status && !minimal) { + auto oldOnlineTill = data->onlineTill; + auto newOnlineTill = Auth().api().onlineTillFromStatus(*status, oldOnlineTill); + if (oldOnlineTill != newOnlineTill) { + data->onlineTill = newOnlineTill; + update.flags |= UpdateFlag::UserOnlineChanged; + } + } + + if (data->contact < 0 && !data->phone().isEmpty() && data->id != Auth().userPeerId()) { + data->contact = 0; + } + if (App::main()) { + if ((data->contact > 0 && !wasContact) || (wasContact && data->contact < 1)) { + Notify::userIsContactChanged(data); } if (update.flags) { update.peer = data; Notify::peerUpdatedDelayed(update); } - return data; } + return data; +} - PeerData *feedChats(const MTPVector &chats) { - PeerData *result = nullptr; - for_const (auto &chat, chats.v) { - if (auto feededChat = feedChat(chat)) { - result = feededChat; - } +UserData *feedUsers(const MTPVector &users) { + UserData *result = nullptr; + for_const (auto &user, users.v) { + if (auto feededUser = feedUser(user)) { + result = feededUser; } - return result; } - void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos) { - ChatData *chat = 0; - switch (p.type()) { - case mtpc_chatParticipantsForbidden: { - const auto &d(p.c_chatParticipantsForbidden()); - chat = App::chat(d.vchat_id.v); - chat->count = -1; - chat->invalidateParticipants(); - } break; + return result; +} - case mtpc_chatParticipants: { - const auto &d(p.c_chatParticipants()); - chat = App::chat(d.vchat_id.v); - auto canEdit = chat->canEdit(); - if (!requestBotInfos || chat->version <= d.vversion.v) { // !requestBotInfos is true on getFullChat result - chat->version = d.vversion.v; - auto &v = d.vparticipants.v; - chat->count = v.size(); - qint32 pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1); - chat->invitedByMe.clear(); - chat->admins.clear(); - chat->flags &= ~MTPDchat::Flag::f_admin; - for (auto i = v.cbegin(), e = v.cend(); i != e; ++i) { - qint32 uid = 0, inviter = 0; - switch (i->type()) { - case mtpc_chatParticipantCreator: { - const auto &p(i->c_chatParticipantCreator()); - uid = p.vuser_id.v; - chat->creator = uid; - } break; - case mtpc_chatParticipantAdmin: { - const auto &p(i->c_chatParticipantAdmin()); - uid = p.vuser_id.v; - inviter = p.vinviter_id.v; - } break; - case mtpc_chatParticipant: { - const auto &p(i->c_chatParticipant()); - uid = p.vuser_id.v; - inviter = p.vinviter_id.v; - } break; - } - if (!uid) continue; +PeerData *feedChat(const MTPChat &chat) { + PeerData *data = nullptr; + bool minimal = false; - UserData *user = App::userLoaded(uid); - if (user) { - chat->participants[user] = pversion; - if (inviter == Auth().userId()) { - chat->invitedByMe.insert(user); + Notify::PeerUpdate update; + using UpdateFlag = Notify::PeerUpdate::Flag; + + switch (chat.type()) { + case mtpc_chat: { + auto &d(chat.c_chat()); + + data = App::chat(peerFromChat(d.vid.v)); + auto cdata = data->asChat(); + auto canEdit = cdata->canEdit(); + + if (cdata->version < d.vversion.v) { + cdata->version = d.vversion.v; + cdata->invalidateParticipants(); + } + + data->input = MTP_inputPeerChat(d.vid); + cdata->setName(qs(d.vtitle)); + cdata->setPhoto(d.vphoto); + cdata->date = d.vdate.v; + + if (d.has_migrated_to() && d.vmigrated_to.type() == mtpc_inputChannel) { + const auto &c(d.vmigrated_to.c_inputChannel()); + ChannelData *channel = App::channel(peerFromChannel(c.vchannel_id)); + if (!channel->mgInfo) { + channel->flags |= MTPDchannel::Flag::f_megagroup; + channel->flagsUpdated(); + } + if (!channel->access) { + channel->input = MTP_inputPeerChannel(c.vchannel_id, c.vaccess_hash); + channel->inputChannel = d.vmigrated_to; + channel->access = d.vmigrated_to.c_inputChannel().vaccess_hash.v; + } + bool updatedTo = (cdata->migrateToPtr != channel), updatedFrom = (channel->mgInfo->migrateFromPtr != cdata); + if (updatedTo) { + cdata->migrateToPtr = channel; + } + if (updatedFrom) { + channel->mgInfo->migrateFromPtr = cdata; + if (History *h = App::historyLoaded(cdata->id)) { + if (History *hto = App::historyLoaded(channel->id)) { + if (!h->isEmpty()) { + h->clear(true); } - if (i->type() == mtpc_chatParticipantAdmin) { - chat->admins.insert(user); - if (user->isSelf()) { - chat->flags |= MTPDchat::Flag::f_admin; - } + if (hto->inChatList(Dialogs::Mode::All) && h->inChatList(Dialogs::Mode::All)) { + App::removeDialog(h); } - } else { - chat->invalidateParticipants(); - break; - } - } - if (!chat->participants.isEmpty()) { - History *h = App::historyLoaded(chat->id); - bool found = !h || !h->lastKeyboardFrom; - qint32 botStatus = -1; - for (auto i = chat->participants.begin(), e = chat->participants.end(); i != e;) { - if (i.value() < pversion) { - i = chat->participants.erase(i); - } else { - if (i.key()->botInfo) { - botStatus = 2;// (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1; - if (requestBotInfos && !i.key()->botInfo->inited) { - Auth().api().requestFullPeer(i.key()); - } - } - if (!found && i.key()->id == h->lastKeyboardFrom) { - found = true; - } - ++i; - } - } - chat->botStatus = botStatus; - if (!found) { - h->clearLastKeyboard(); } } + Notify::migrateUpdated(channel); + update.flags |= UpdateFlag::MigrationChanged; } - if (canEdit != chat->canEdit()) { - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::ChatCanEdit); + if (updatedTo) { + Notify::migrateUpdated(cdata); + update.flags |= UpdateFlag::MigrationChanged; } - } break; } - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::MembersChanged | Notify::PeerUpdate::Flag::AdminsChanged); + + if (!(cdata->flags & MTPDchat::Flag::f_admins_enabled) && (d.vflags.v & MTPDchat::Flag::f_admins_enabled)) { + cdata->invalidateParticipants(); + } + cdata->flags = d.vflags.v; + + cdata->count = d.vparticipants_count.v; + cdata->setIsForbidden(false); + if (canEdit != cdata->canEdit()) { + update.flags |= UpdateFlag::ChatCanEdit; + } + } break; + case mtpc_chatForbidden: { + auto &d(chat.c_chatForbidden()); + + data = App::chat(peerFromChat(d.vid.v)); + auto cdata = data->asChat(); + auto canEdit = cdata->canEdit(); + + data->input = MTP_inputPeerChat(d.vid); + cdata->setName(qs(d.vtitle)); + cdata->setPhoto(MTP_chatPhotoEmpty()); + cdata->date = 0; + cdata->count = -1; + cdata->invalidateParticipants(); + cdata->flags = 0; + cdata->setIsForbidden(true); + if (canEdit != cdata->canEdit()) { + update.flags |= UpdateFlag::ChatCanEdit; + } + } break; + case mtpc_channel: { + auto &d = chat.c_channel(); + + auto peerId = peerFromChannel(d.vid.v); + minimal = d.is_min(); + if (minimal) { + data = App::channelLoaded(peerId); + if (!data) { + return nullptr; // minimal is not loaded, need to make getDifference + } + } else { + data = App::channel(peerId); + data->input = MTP_inputPeerChannel(d.vid, d.has_access_hash() ? d.vaccess_hash : MTP_long(0)); + } + + auto cdata = data->asChannel(); + auto wasInChannel = cdata->amIn(); + auto canViewAdmins = cdata->canViewAdmins(); + auto canViewMembers = cdata->canViewMembers(); + auto canAddMembers = cdata->canAddMembers(); + + if (minimal) { + auto mask = MTPDchannel::Flag::f_broadcast | MTPDchannel::Flag::f_verified | + MTPDchannel::Flag::f_megagroup | MTPDchannel::Flag::f_democracy; + cdata->flags = (cdata->flags & ~mask) | (d.vflags.v & mask); + } else { + if (d.has_admin_rights()) { + cdata->setAdminRights(d.vadmin_rights); + } else if (cdata->hasAdminRights()) { + cdata->setAdminRights(MTP_channelAdminRights(MTP_flags(0))); + } + if (d.has_banned_rights()) { + cdata->setRestrictedRights(d.vbanned_rights); + } else if (cdata->hasRestrictedRights()) { + cdata->setRestrictedRights(MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); + } + cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash); + cdata->access = d.vaccess_hash.v; + cdata->date = d.vdate.v; + if (cdata->version < d.vversion.v) { + cdata->version = d.vversion.v; + } + if (d.is_restricted()) { + cdata->setRestrictionReason(extractRestrictionReason(qs(d.vrestriction_reason))); + } else { + cdata->setRestrictionReason(QString()); + } + cdata->flags = d.vflags.v; + } + cdata->flagsUpdated(); + + QString uname = d.has_username() ? TextUtilities::SingleLine(qs(d.vusername)) : QString(); + cdata->setName(qs(d.vtitle), uname); + + cdata->setIsForbidden(false); + cdata->setPhoto(d.vphoto); + + if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn; + if (canViewAdmins != cdata->canViewAdmins() || canViewMembers != cdata->canViewMembers() || + canAddMembers != cdata->canAddMembers()) + update.flags |= UpdateFlag::ChannelRightsChanged; + } break; + case mtpc_channelForbidden: { + auto &d(chat.c_channelForbidden()); + + auto peerId = peerFromChannel(d.vid.v); + data = App::channel(peerId); + data->input = MTP_inputPeerChannel(d.vid, d.vaccess_hash); + + auto cdata = data->asChannel(); + auto wasInChannel = cdata->amIn(); + auto canViewAdmins = cdata->canViewAdmins(); + auto canViewMembers = cdata->canViewMembers(); + auto canAddMembers = cdata->canAddMembers(); + + cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash); + + auto mask = mtpCastFlags(MTPDchannelForbidden::Flag::f_broadcast | MTPDchannelForbidden::Flag::f_megagroup); + cdata->flags = (cdata->flags & ~mask) | (mtpCastFlags(d.vflags) & mask); + cdata->flagsUpdated(); + + if (cdata->hasAdminRights()) { + cdata->setAdminRights(MTP_channelAdminRights(MTP_flags(0))); + } + if (cdata->hasRestrictedRights()) { + cdata->setRestrictedRights(MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); + } + + cdata->setName(qs(d.vtitle), QString()); + + cdata->access = d.vaccess_hash.v; + cdata->setPhoto(MTP_chatPhotoEmpty()); + cdata->date = 0; + cdata->setMembersCount(0); + cdata->setIsForbidden(true); + + if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn; + if (canViewAdmins != cdata->canViewAdmins() || canViewMembers != cdata->canViewMembers() || + canAddMembers != cdata->canAddMembers()) + update.flags |= UpdateFlag::ChannelRightsChanged; + } break; + } + if (!data) { + return nullptr; } - void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d) { - ChatData *chat = App::chat(d.vchat_id.v); - if (chat->version + 1 < d.vversion.v) { + if (minimal) { + if (data->loadedStatus == PeerData::NotLoaded) { + data->loadedStatus = PeerData::MinimalLoaded; + } + } else if (data->loadedStatus != PeerData::FullLoaded) { + data->loadedStatus = PeerData::FullLoaded; + } + if (update.flags) { + update.peer = data; + Notify::peerUpdatedDelayed(update); + } + return data; +} + +PeerData *feedChats(const MTPVector &chats) { + PeerData *result = nullptr; + for_const (auto &chat, chats.v) { + if (auto feededChat = feedChat(chat)) { + result = feededChat; + } + } + return result; +} + +void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos) { + ChatData *chat = 0; + switch (p.type()) { + case mtpc_chatParticipantsForbidden: { + const auto &d(p.c_chatParticipantsForbidden()); + chat = App::chat(d.vchat_id.v); + chat->count = -1; + chat->invalidateParticipants(); + } break; + + case mtpc_chatParticipants: { + const auto &d(p.c_chatParticipants()); + chat = App::chat(d.vchat_id.v); + auto canEdit = chat->canEdit(); + if (!requestBotInfos || chat->version <= d.vversion.v) { // !requestBotInfos is true on getFullChat result chat->version = d.vversion.v; - chat->invalidateParticipants(); - Auth().api().requestPeer(chat); - } else if (chat->version <= d.vversion.v && chat->count >= 0) { - chat->version = d.vversion.v; - UserData *user = App::userLoaded(d.vuser_id.v); - if (user) { - if (chat->participants.isEmpty() && chat->count) { - chat->count++; - chat->botStatus = 0; - } else if (chat->participants.find(user) == chat->participants.end()) { - chat->participants[user] = (chat->participants.isEmpty() ? 1 : chat->participants.begin().value()); - if (d.vinviter_id.v == Auth().userId()) { + auto &v = d.vparticipants.v; + chat->count = v.size(); + qint32 pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1); + chat->invitedByMe.clear(); + chat->admins.clear(); + chat->flags &= ~MTPDchat::Flag::f_admin; + for (auto i = v.cbegin(), e = v.cend(); i != e; ++i) { + qint32 uid = 0, inviter = 0; + switch (i->type()) { + case mtpc_chatParticipantCreator: { + const auto &p(i->c_chatParticipantCreator()); + uid = p.vuser_id.v; + chat->creator = uid; + } break; + case mtpc_chatParticipantAdmin: { + const auto &p(i->c_chatParticipantAdmin()); + uid = p.vuser_id.v; + inviter = p.vinviter_id.v; + } break; + case mtpc_chatParticipant: { + const auto &p(i->c_chatParticipant()); + uid = p.vuser_id.v; + inviter = p.vinviter_id.v; + } break; + } + if (!uid) continue; + + UserData *user = App::userLoaded(uid); + if (user) { + chat->participants[user] = pversion; + if (inviter == Auth().userId()) { chat->invitedByMe.insert(user); - } else { - chat->invitedByMe.remove(user); } - chat->count++; - if (user->botInfo) { - chat->botStatus = 2;// (chat->botStatus > 0/* || !user->botInfo->readsAllHistory*/) ? 2 : 1; - if (!user->botInfo->inited) { - Auth().api().requestFullPeer(user); + if (i->type() == mtpc_chatParticipantAdmin) { + chat->admins.insert(user); + if (user->isSelf()) { + chat->flags |= MTPDchat::Flag::f_admin; } } - } - } else { - chat->invalidateParticipants(); - chat->count++; - } - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::MembersChanged); - } - } - - void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d) { - ChatData *chat = App::chat(d.vchat_id.v); - if (chat->version + 1 < d.vversion.v) { - chat->version = d.vversion.v; - chat->invalidateParticipants(); - Auth().api().requestPeer(chat); - } else if (chat->version <= d.vversion.v && chat->count > 0) { - chat->version = d.vversion.v; - auto canEdit = chat->canEdit(); - UserData *user = App::userLoaded(d.vuser_id.v); - if (user) { - if (chat->participants.isEmpty()) { - if (chat->count > 0) { - chat->count--; - } } else { - auto i = chat->participants.find(user); - if (i != chat->participants.end()) { - chat->participants.erase(i); - chat->count--; - chat->invitedByMe.remove(user); - chat->admins.remove(user); - if (user->isSelf()) { - chat->flags &= ~MTPDchat::Flag::f_admin; - } - - History *h = App::historyLoaded(chat->id); - if (h && h->lastKeyboardFrom == user->id) { - h->clearLastKeyboard(); - } - } - if (chat->botStatus > 0 && user->botInfo) { - qint32 botStatus = -1; - for (auto j = chat->participants.cbegin(), e = chat->participants.cend(); j != e; ++j) { - if (j.key()->botInfo) { - if (true || botStatus > 0/* || !j.key()->botInfo->readsAllHistory*/) { - botStatus = 2; - break; - } - botStatus = 1; + chat->invalidateParticipants(); + break; + } + } + if (!chat->participants.isEmpty()) { + History *h = App::historyLoaded(chat->id); + bool found = !h || !h->lastKeyboardFrom; + qint32 botStatus = -1; + for (auto i = chat->participants.begin(), e = chat->participants.end(); i != e;) { + if (i.value() < pversion) { + i = chat->participants.erase(i); + } else { + if (i.key()->botInfo) { + botStatus = 2; // (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1; + if (requestBotInfos && !i.key()->botInfo->inited) { + Auth().api().requestFullPeer(i.key()); } } - chat->botStatus = botStatus; + if (!found && i.key()->id == h->lastKeyboardFrom) { + found = true; + } + ++i; } } - } else { - chat->invalidateParticipants(); - chat->count--; - } - if (canEdit != chat->canEdit()) { - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::ChatCanEdit); - } - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::MembersChanged); - } - } - - void feedChatAdmins(const MTPDupdateChatAdmins &d) { - ChatData *chat = App::chat(d.vchat_id.v); - if (chat->version <= d.vversion.v) { - bool badVersion = (chat->version + 1 < d.vversion.v); - if (badVersion) { - chat->invalidateParticipants(); - Auth().api().requestPeer(chat); - } - chat->version = d.vversion.v; - if (mtpIsTrue(d.venabled)) { - if (!badVersion) { - chat->invalidateParticipants(); + chat->botStatus = botStatus; + if (!found) { + h->clearLastKeyboard(); } - chat->flags |= MTPDchat::Flag::f_admins_enabled; - } else { - chat->flags &= ~MTPDchat::Flag::f_admins_enabled; } - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::AdminsChanged); } + if (canEdit != chat->canEdit()) { + Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::ChatCanEdit); + } + } break; } + Notify::peerUpdatedDelayed(chat, + Notify::PeerUpdate::Flag::MembersChanged | Notify::PeerUpdate::Flag::AdminsChanged); +} - void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d) { - ChatData *chat = App::chat(d.vchat_id.v); - if (chat->version + 1 < d.vversion.v) { - chat->version = d.vversion.v; - chat->invalidateParticipants(); - Auth().api().requestPeer(chat); - } else if (chat->version <= d.vversion.v && chat->count > 0) { - chat->version = d.vversion.v; - auto canEdit = chat->canEdit(); - UserData *user = App::userLoaded(d.vuser_id.v); - if (user) { - if (mtpIsTrue(d.vis_admin)) { - if (user->isSelf()) { - chat->flags |= MTPDchat::Flag::f_admin; - } - if (chat->noParticipantInfo()) { - Auth().api().requestFullPeer(chat); - } else { - chat->admins.insert(user); - } +void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d) { + ChatData *chat = App::chat(d.vchat_id.v); + if (chat->version + 1 < d.vversion.v) { + chat->version = d.vversion.v; + chat->invalidateParticipants(); + Auth().api().requestPeer(chat); + } else if (chat->version <= d.vversion.v && chat->count >= 0) { + chat->version = d.vversion.v; + UserData *user = App::userLoaded(d.vuser_id.v); + if (user) { + if (chat->participants.isEmpty() && chat->count) { + chat->count++; + chat->botStatus = 0; + } else if (chat->participants.find(user) == chat->participants.end()) { + chat->participants[user] = (chat->participants.isEmpty() ? 1 : chat->participants.begin().value()); + if (d.vinviter_id.v == Auth().userId()) { + chat->invitedByMe.insert(user); } else { + chat->invitedByMe.remove(user); + } + chat->count++; + if (user->botInfo) { + chat->botStatus = 2; // (chat->botStatus > 0/* || !user->botInfo->readsAllHistory*/) ? 2 : 1; + if (!user->botInfo->inited) { + Auth().api().requestFullPeer(user); + } + } + } + } else { + chat->invalidateParticipants(); + chat->count++; + } + Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::MembersChanged); + } +} + +void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d) { + ChatData *chat = App::chat(d.vchat_id.v); + if (chat->version + 1 < d.vversion.v) { + chat->version = d.vversion.v; + chat->invalidateParticipants(); + Auth().api().requestPeer(chat); + } else if (chat->version <= d.vversion.v && chat->count > 0) { + chat->version = d.vversion.v; + auto canEdit = chat->canEdit(); + UserData *user = App::userLoaded(d.vuser_id.v); + if (user) { + if (chat->participants.isEmpty()) { + if (chat->count > 0) { + chat->count--; + } + } else { + auto i = chat->participants.find(user); + if (i != chat->participants.end()) { + chat->participants.erase(i); + chat->count--; + chat->invitedByMe.remove(user); + chat->admins.remove(user); if (user->isSelf()) { chat->flags &= ~MTPDchat::Flag::f_admin; } - chat->admins.remove(user); + + History *h = App::historyLoaded(chat->id); + if (h && h->lastKeyboardFrom == user->id) { + h->clearLastKeyboard(); + } } - } else { + if (chat->botStatus > 0 && user->botInfo) { + qint32 botStatus = -1; + for (auto j = chat->participants.cbegin(), e = chat->participants.cend(); j != e; ++j) { + if (j.key()->botInfo) { + if (true || botStatus > 0 /* || !j.key()->botInfo->readsAllHistory*/) { + botStatus = 2; + break; + } + botStatus = 1; + } + } + chat->botStatus = botStatus; + } + } + } else { + chat->invalidateParticipants(); + chat->count--; + } + if (canEdit != chat->canEdit()) { + Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::ChatCanEdit); + } + Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::MembersChanged); + } +} + +void feedChatAdmins(const MTPDupdateChatAdmins &d) { + ChatData *chat = App::chat(d.vchat_id.v); + if (chat->version <= d.vversion.v) { + bool badVersion = (chat->version + 1 < d.vversion.v); + if (badVersion) { + chat->invalidateParticipants(); + Auth().api().requestPeer(chat); + } + chat->version = d.vversion.v; + if (mtpIsTrue(d.venabled)) { + if (!badVersion) { chat->invalidateParticipants(); } - if (canEdit != chat->canEdit()) { - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::ChatCanEdit); - } - Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::AdminsChanged); + chat->flags |= MTPDchat::Flag::f_admins_enabled; + } else { + chat->flags &= ~MTPDchat::Flag::f_admins_enabled; } + Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::AdminsChanged); } +} - bool checkEntitiesAndViewsUpdate(const MTPDmessage &m) { - auto peerId = peerFromMTP(m.vto_id); - if (m.has_from_id() && peerId == Auth().userPeerId()) { - peerId = peerFromUser(m.vfrom_id); - } - if (auto existing = App::histItemById(peerToChannel(peerId), m.vid.v)) { - auto text = qs(m.vmessage); - auto entities = m.has_entities() ? TextUtilities::EntitiesFromMTP(m.ventities.v) : EntitiesInText(); - existing->setText({ text, entities }); - existing->updateMedia(m.has_media() ? (&m.vmedia) : nullptr); - existing->updateReplyMarkup(m.has_reply_markup() ? (&m.vreply_markup) : nullptr); - existing->setViewsCount(m.has_views() ? m.vviews.v : -1); - existing->addToOverview(AddToOverviewNew); - - if (!existing->detached()) { - App::checkSavedGif(existing); - return true; +void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d) { + ChatData *chat = App::chat(d.vchat_id.v); + if (chat->version + 1 < d.vversion.v) { + chat->version = d.vversion.v; + chat->invalidateParticipants(); + Auth().api().requestPeer(chat); + } else if (chat->version <= d.vversion.v && chat->count > 0) { + chat->version = d.vversion.v; + auto canEdit = chat->canEdit(); + UserData *user = App::userLoaded(d.vuser_id.v); + if (user) { + if (mtpIsTrue(d.vis_admin)) { + if (user->isSelf()) { + chat->flags |= MTPDchat::Flag::f_admin; + } + if (chat->noParticipantInfo()) { + Auth().api().requestFullPeer(chat); + } else { + chat->admins.insert(user); + } + } else { + if (user->isSelf()) { + chat->flags &= ~MTPDchat::Flag::f_admin; + } + chat->admins.remove(user); } - - return false; + } else { + chat->invalidateParticipants(); } + if (canEdit != chat->canEdit()) { + Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::ChatCanEdit); + } + Notify::peerUpdatedDelayed(chat, Notify::PeerUpdate::Flag::AdminsChanged); + } +} + +bool checkEntitiesAndViewsUpdate(const MTPDmessage &m) { + auto peerId = peerFromMTP(m.vto_id); + if (m.has_from_id() && peerId == Auth().userPeerId()) { + peerId = peerFromUser(m.vfrom_id); + } + if (auto existing = App::histItemById(peerToChannel(peerId), m.vid.v)) { + auto text = qs(m.vmessage); + auto entities = m.has_entities() ? TextUtilities::EntitiesFromMTP(m.ventities.v) : EntitiesInText(); + existing->setText({text, entities}); + existing->updateMedia(m.has_media() ? (&m.vmedia) : nullptr); + existing->updateReplyMarkup(m.has_reply_markup() ? (&m.vreply_markup) : nullptr); + existing->setViewsCount(m.has_views() ? m.vviews.v : -1); + existing->addToOverview(AddToOverviewNew); + + if (!existing->detached()) { + App::checkSavedGif(existing); + return true; + } + return false; } + return false; +} - template - void updateEditedMessage(const TMTPDclass &m) { - auto peerId = peerFromMTP(m.vto_id); - if (m.has_from_id() && peerId == Auth().userPeerId()) { - peerId = peerFromUser(m.vfrom_id); - } - if (auto existing = App::histItemById(peerToChannel(peerId), m.vid.v)) { - existing->applyEdition(m); - } +template void updateEditedMessage(const TMTPDclass &m) { + auto peerId = peerFromMTP(m.vto_id); + if (m.has_from_id() && peerId == Auth().userPeerId()) { + peerId = peerFromUser(m.vfrom_id); } - - void updateEditedMessage(const MTPMessage &m) { - if (m.type() == mtpc_message) { // apply message edit - App::updateEditedMessage(m.c_message()); - } else if (m.type() == mtpc_messageService) { - App::updateEditedMessage(m.c_messageService()); - } + if (auto existing = App::histItemById(peerToChannel(peerId), m.vid.v)) { + existing->applyEdition(m); } +} - void addSavedGif(DocumentData *doc) { - SavedGifs &saved(cRefSavedGifs()); - qint32 index = saved.indexOf(doc); - if (index) { - if (index > 0) saved.remove(index); - saved.push_front(doc); - if (saved.size() > Global::SavedGifsLimit()) saved.pop_back(); - Local::writeSavedGifs(); - - Auth().data().savedGifsUpdated().notify(); - cSetLastSavedGifsUpdate(0); - Auth().api().updateStickers(); - } +void updateEditedMessage(const MTPMessage &m) { + if (m.type() == mtpc_message) { // apply message edit + App::updateEditedMessage(m.c_message()); + } else if (m.type() == mtpc_messageService) { + App::updateEditedMessage(m.c_messageService()); } +} - void checkSavedGif(HistoryItem *item) { - if (!item->Has() && (item->out() || item->history()->peer == App::self())) { - if (auto media = item->getMedia()) { - if (auto doc = media->getDocument()) { - if (doc->isGifv()) { - addSavedGif(doc); - } +void addSavedGif(DocumentData *doc) { + SavedGifs &saved(cRefSavedGifs()); + qint32 index = saved.indexOf(doc); + if (index) { + if (index > 0) saved.remove(index); + saved.push_front(doc); + if (saved.size() > Global::SavedGifsLimit()) saved.pop_back(); + Local::writeSavedGifs(); + + Auth().data().savedGifsUpdated().notify(); + cSetLastSavedGifsUpdate(0); + Auth().api().updateStickers(); + } +} + +void checkSavedGif(HistoryItem *item) { + if (!item->Has() && (item->out() || item->history()->peer == App::self())) { + if (auto media = item->getMedia()) { + if (auto doc = media->getDocument()) { + if (doc->isGifv()) { + addSavedGif(doc); } } } } +} - void feedMsgs(const QVector &msgs, NewMessageType type) { - QMap msgsIds; - for (qint32 i = 0, l = msgs.size(); i < l; ++i) { - const auto &msg(msgs.at(i)); - switch (msg.type()) { - case mtpc_message: { - const auto &d(msg.c_message()); - bool needToAdd = true; - if (type == NewMessageUnread) { // new message, index my forwarded messages to links overview - if (checkEntitiesAndViewsUpdate(d)) { // already in blocks - LOG(("Skipping message, because it is already in blocks!")); - needToAdd = false; - } +void feedMsgs(const QVector &msgs, NewMessageType type) { + QMap msgsIds; + for (qint32 i = 0, l = msgs.size(); i < l; ++i) { + const auto &msg(msgs.at(i)); + switch (msg.type()) { + case mtpc_message: { + const auto &d(msg.c_message()); + bool needToAdd = true; + if (type == NewMessageUnread) { // new message, index my forwarded messages to links overview + if (checkEntitiesAndViewsUpdate(d)) { // already in blocks + LOG(("Skipping message, because it is already in blocks!")); + needToAdd = false; } - if (needToAdd) { - msgsIds.insert((quint64(quint32(d.vid.v)) << 32) | quint64(i), i); - } - } break; - case mtpc_messageEmpty: msgsIds.insert((quint64(quint32(msg.c_messageEmpty().vid.v)) << 32) | quint64(i), i); break; - case mtpc_messageService: msgsIds.insert((quint64(quint32(msg.c_messageService().vid.v)) << 32) | quint64(i), i); break; } - } - for (QMap::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { - histories().addNewMessage(msgs.at(i.value()), type); - } - } - - void feedMsgs(const MTPVector &msgs, NewMessageType type) { - return feedMsgs(msgs.v, type); - } - - ImagePtr image(const MTPPhotoSize &size) { - switch (size.type()) { - case mtpc_photoSize: { - auto &d = size.c_photoSize(); - if (d.vlocation.type() == mtpc_fileLocation) { - auto &l = d.vlocation.c_fileLocation(); - return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), d.vsize.v); + if (needToAdd) { + msgsIds.insert((quint64(quint32(d.vid.v)) << 32) | quint64(i), i); } } break; - case mtpc_photoCachedSize: { - auto &d = size.c_photoCachedSize(); - if (d.vlocation.type() == mtpc_fileLocation) { - auto &l = d.vlocation.c_fileLocation(); - auto bytes = qba(d.vbytes); - return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), bytes); - } else if (d.vlocation.type() == mtpc_fileLocationUnavailable) { - auto bytes = qba(d.vbytes); - return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, 0, 0, 0, 0), bytes); - } - } break; - } - return ImagePtr(); - } - - StorageImageLocation imageLocation(qint32 w, qint32 h, const MTPFileLocation &loc) { - if (loc.type() == mtpc_fileLocation) { - const auto &l(loc.c_fileLocation()); - return StorageImageLocation(w, h, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v); - } - return StorageImageLocation(w, h, 0, 0, 0, 0); - } - - StorageImageLocation imageLocation(const MTPPhotoSize &size) { - switch (size.type()) { - case mtpc_photoSize: { - const auto &d(size.c_photoSize()); - return imageLocation(d.vw.v, d.vh.v, d.vlocation); - } break; - case mtpc_photoCachedSize: { - const auto &d(size.c_photoCachedSize()); - return imageLocation(d.vw.v, d.vh.v, d.vlocation); - } break; - } - return StorageImageLocation(); - } - - void feedInboxRead(const PeerId &peer, MsgId upTo) { - if (auto history = App::historyLoaded(peer)) { - history->inboxRead(upTo); - } - } - - void feedOutboxRead(const PeerId &peer, MsgId upTo, TimeId when) { - if (auto history = App::historyLoaded(peer)) { - history->outboxRead(upTo); - if (history->lastMsg && history->lastMsg->out() && history->lastMsg->id <= upTo) { - if (App::main()) App::main()->dlgUpdated(history->peer, history->lastMsg->id); - } - history->updateChatListEntry(); - - if (history->peer->isUser()) { - history->peer->asUser()->madeAction(when); - } - } - } - - inline MsgsData *fetchMsgsData(ChannelId channelId, bool insert = true) { - if (channelId == NoChannel) return &msgsData; - ChannelMsgsData::iterator i = channelMsgsData.find(channelId); - if (i == channelMsgsData.cend()) { - if (insert) { - i = channelMsgsData.insert(channelId, MsgsData()); - } else { - return 0; - } - } - return &(*i); - } - - void feedWereDeleted(ChannelId channelId, const QVector &msgsIds) { - MsgsData *data = fetchMsgsData(channelId, false); - if (!data) return; - - ChannelHistory *channelHistory = (channelId == NoChannel) ? 0 : App::historyLoaded(peerFromChannel(channelId))->asChannelHistory(); - - QMap historiesToCheck; - for (QVector::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { - MsgsData::const_iterator j = data->constFind(i->v); - if (j != data->cend()) { - History *h = (*j)->history(); - (*j)->destroy(); - if (!h->lastMsg) historiesToCheck.insert(h, true); - } else { - if (channelHistory) { - if (channelHistory->unreadCount() > 0 && i->v >= channelHistory->inboxReadBefore) { - channelHistory->setUnreadCount(channelHistory->unreadCount() - 1); - } - } - } - } - if (main()) { - for (QMap::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; ++i) { - main()->checkPeerHistory(i.key()->peer); - } - } - } - - void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink) { - UserData *user = userLoaded(userId.v); - if (user) { - auto wasContact = user->isContact(); - bool wasShowPhone = !user->contact; - switch (myLink.type()) { - case mtpc_contactLinkContact: - user->contact = 1; - if (user->contact == 1 && cReportSpamStatuses().value(user->id, dbiprsHidden) != dbiprsHidden) { - cRefReportSpamStatuses().insert(user->id, dbiprsHidden); - Local::writeReportSpamStatuses(); - } + case mtpc_messageEmpty: + msgsIds.insert((quint64(quint32(msg.c_messageEmpty().vid.v)) << 32) | quint64(i), i); break; - case mtpc_contactLinkHasPhone: + case mtpc_messageService: + msgsIds.insert((quint64(quint32(msg.c_messageService().vid.v)) << 32) | quint64(i), i); + break; + } + } + for (QMap::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { + histories().addNewMessage(msgs.at(i.value()), type); + } +} + +void feedMsgs(const MTPVector &msgs, NewMessageType type) { + return feedMsgs(msgs.v, type); +} + +ImagePtr image(const MTPPhotoSize &size) { + switch (size.type()) { + case mtpc_photoSize: { + auto &d = size.c_photoSize(); + if (d.vlocation.type() == mtpc_fileLocation) { + auto &l = d.vlocation.c_fileLocation(); + return ImagePtr( + StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), + d.vsize.v); + } + } break; + case mtpc_photoCachedSize: { + auto &d = size.c_photoCachedSize(); + if (d.vlocation.type() == mtpc_fileLocation) { + auto &l = d.vlocation.c_fileLocation(); + auto bytes = qba(d.vbytes); + return ImagePtr( + StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), bytes); + } else if (d.vlocation.type() == mtpc_fileLocationUnavailable) { + auto bytes = qba(d.vbytes); + return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, 0, 0, 0, 0), bytes); + } + } break; + } + return ImagePtr(); +} + +StorageImageLocation imageLocation(qint32 w, qint32 h, const MTPFileLocation &loc) { + if (loc.type() == mtpc_fileLocation) { + const auto &l(loc.c_fileLocation()); + return StorageImageLocation(w, h, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v); + } + return StorageImageLocation(w, h, 0, 0, 0, 0); +} + +StorageImageLocation imageLocation(const MTPPhotoSize &size) { + switch (size.type()) { + case mtpc_photoSize: { + const auto &d(size.c_photoSize()); + return imageLocation(d.vw.v, d.vh.v, d.vlocation); + } break; + case mtpc_photoCachedSize: { + const auto &d(size.c_photoCachedSize()); + return imageLocation(d.vw.v, d.vh.v, d.vlocation); + } break; + } + return StorageImageLocation(); +} + +void feedInboxRead(const PeerId &peer, MsgId upTo) { + if (auto history = App::historyLoaded(peer)) { + history->inboxRead(upTo); + } +} + +void feedOutboxRead(const PeerId &peer, MsgId upTo, TimeId when) { + if (auto history = App::historyLoaded(peer)) { + history->outboxRead(upTo); + if (history->lastMsg && history->lastMsg->out() && history->lastMsg->id <= upTo) { + if (App::main()) App::main()->dlgUpdated(history->peer, history->lastMsg->id); + } + history->updateChatListEntry(); + + if (history->peer->isUser()) { + history->peer->asUser()->madeAction(when); + } + } +} + +inline MsgsData *fetchMsgsData(ChannelId channelId, bool insert = true) { + if (channelId == NoChannel) return &msgsData; + ChannelMsgsData::iterator i = channelMsgsData.find(channelId); + if (i == channelMsgsData.cend()) { + if (insert) { + i = channelMsgsData.insert(channelId, MsgsData()); + } else { + return 0; + } + } + return &(*i); +} + +void feedWereDeleted(ChannelId channelId, const QVector &msgsIds) { + MsgsData *data = fetchMsgsData(channelId, false); + if (!data) return; + + ChannelHistory *channelHistory = + (channelId == NoChannel) ? 0 : App::historyLoaded(peerFromChannel(channelId))->asChannelHistory(); + + QMap historiesToCheck; + for (QVector::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { + MsgsData::const_iterator j = data->constFind(i->v); + if (j != data->cend()) { + History *h = (*j)->history(); + (*j)->destroy(); + if (!h->lastMsg) historiesToCheck.insert(h, true); + } else { + if (channelHistory) { + if (channelHistory->unreadCount() > 0 && i->v >= channelHistory->inboxReadBefore) { + channelHistory->setUnreadCount(channelHistory->unreadCount() - 1); + } + } + } + } + if (main()) { + for (QMap::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; + ++i) { + main()->checkPeerHistory(i.key()->peer); + } + } +} + +void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink) { + UserData *user = userLoaded(userId.v); + if (user) { + auto wasContact = user->isContact(); + bool wasShowPhone = !user->contact; + switch (myLink.type()) { + case mtpc_contactLinkContact: + user->contact = 1; + if (user->contact == 1 && cReportSpamStatuses().value(user->id, dbiprsHidden) != dbiprsHidden) { + cRefReportSpamStatuses().insert(user->id, dbiprsHidden); + Local::writeReportSpamStatuses(); + } + break; + case mtpc_contactLinkHasPhone: user->contact = 0; break; + case mtpc_contactLinkNone: + case mtpc_contactLinkUnknown: user->contact = -1; break; + } + if (user->contact < 1) { + if (user->contact < 0 && !user->phone().isEmpty() && user->id != Auth().userPeerId()) { user->contact = 0; - break; - case mtpc_contactLinkNone: - case mtpc_contactLinkUnknown: - user->contact = -1; - break; - } - if (user->contact < 1) { - if (user->contact < 0 && !user->phone().isEmpty() && user->id != Auth().userPeerId()) { - user->contact = 0; - } } + } - if (wasContact != user->isContact()) { - Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserIsContact); - } - if ((user->contact > 0 && !wasContact) || (wasContact && user->contact < 1)) { - Notify::userIsContactChanged(user); - } + if (wasContact != user->isContact()) { + Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserIsContact); + } + if ((user->contact > 0 && !wasContact) || (wasContact && user->contact < 1)) { + Notify::userIsContactChanged(user); + } - bool showPhone = !isServiceUser(user->id) && !user->isSelf() && !user->contact; - bool showPhoneChanged = !isServiceUser(user->id) && !user->isSelf() && ((showPhone && !wasShowPhone) || (!showPhone && wasShowPhone)); - if (showPhoneChanged) { - user->setName(TextUtilities::SingleLine(user->firstName), TextUtilities::SingleLine(user->lastName), showPhone ? App::formatPhone(user->phone()) : QString(), TextUtilities::SingleLine(user->username)); - } + bool showPhone = !isServiceUser(user->id) && !user->isSelf() && !user->contact; + bool showPhoneChanged = !isServiceUser(user->id) && !user->isSelf() && + ((showPhone && !wasShowPhone) || (!showPhone && wasShowPhone)); + if (showPhoneChanged) { + user->setName(TextUtilities::SingleLine(user->firstName), TextUtilities::SingleLine(user->lastName), + showPhone ? App::formatPhone(user->phone()) : QString(), + TextUtilities::SingleLine(user->username)); } } +} - PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert) { - switch (photo.type()) { - case mtpc_photo: { - return feedPhoto(photo.c_photo(), convert); - } break; - case mtpc_photoEmpty: { - return App::photoSet(photo.c_photoEmpty().vid.v, convert, 0, 0, ImagePtr(), ImagePtr(), ImagePtr()); - } break; +PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert) { + switch (photo.type()) { + case mtpc_photo: { + return feedPhoto(photo.c_photo(), convert); + } break; + case mtpc_photoEmpty: { + return App::photoSet(photo.c_photoEmpty().vid.v, convert, 0, 0, ImagePtr(), ImagePtr(), ImagePtr()); + } break; + } + return App::photo(0); +} + +PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs) { + const QPixmap *thumb = 0, *medium = 0, *full = 0; + qint32 thumbLevel = -1, mediumLevel = -1, fullLevel = -1; + for (PreparedPhotoThumbs::const_iterator i = thumbs.cbegin(), e = thumbs.cend(); i != e; ++i) { + qint32 newThumbLevel = -1, newMediumLevel = -1, newFullLevel = -1; + switch (i.key()) { + case 's': + newThumbLevel = 0; + newMediumLevel = 5; + newFullLevel = 4; + break; // box 100x100 + case 'm': + newThumbLevel = 2; + newMediumLevel = 0; + newFullLevel = 3; + break; // box 320x320 + case 'x': + newThumbLevel = 5; + newMediumLevel = 3; + newFullLevel = 1; + break; // box 800x800 + case 'y': + newThumbLevel = 6; + newMediumLevel = 6; + newFullLevel = 0; + break; // box 1280x1280 + case 'w': + newThumbLevel = 8; + newMediumLevel = 8; + newFullLevel = 2; + break; // box 2560x2560 // if loading this fix HistoryPhoto::updateFrom + case 'a': + newThumbLevel = 1; + newMediumLevel = 4; + newFullLevel = 8; + break; // crop 160x160 + case 'b': + newThumbLevel = 3; + newMediumLevel = 1; + newFullLevel = 7; + break; // crop 320x320 + case 'c': + newThumbLevel = 4; + newMediumLevel = 2; + newFullLevel = 6; + break; // crop 640x640 + case 'd': + newThumbLevel = 7; + newMediumLevel = 7; + newFullLevel = 5; + break; // crop 1280x1280 } + if (newThumbLevel < 0 || newMediumLevel < 0 || newFullLevel < 0) { + continue; + } + if (thumbLevel < 0 || newThumbLevel < thumbLevel) { + thumbLevel = newThumbLevel; + thumb = &i.value(); + } + if (mediumLevel < 0 || newMediumLevel < mediumLevel) { + mediumLevel = newMediumLevel; + medium = &i.value(); + } + if (fullLevel < 0 || newFullLevel < fullLevel) { + fullLevel = newFullLevel; + full = &i.value(); + } + } + if (!thumb || !medium || !full) { return App::photo(0); } - - PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs) { - const QPixmap *thumb = 0, *medium = 0, *full = 0; - qint32 thumbLevel = -1, mediumLevel = -1, fullLevel = -1; - for (PreparedPhotoThumbs::const_iterator i = thumbs.cbegin(), e = thumbs.cend(); i != e; ++i) { - qint32 newThumbLevel = -1, newMediumLevel = -1, newFullLevel = -1; - switch (i.key()) { - case 's': newThumbLevel = 0; newMediumLevel = 5; newFullLevel = 4; break; // box 100x100 - case 'm': newThumbLevel = 2; newMediumLevel = 0; newFullLevel = 3; break; // box 320x320 - case 'x': newThumbLevel = 5; newMediumLevel = 3; newFullLevel = 1; break; // box 800x800 - case 'y': newThumbLevel = 6; newMediumLevel = 6; newFullLevel = 0; break; // box 1280x1280 - case 'w': newThumbLevel = 8; newMediumLevel = 8; newFullLevel = 2; break; // box 2560x2560 // if loading this fix HistoryPhoto::updateFrom - case 'a': newThumbLevel = 1; newMediumLevel = 4; newFullLevel = 8; break; // crop 160x160 - case 'b': newThumbLevel = 3; newMediumLevel = 1; newFullLevel = 7; break; // crop 320x320 - case 'c': newThumbLevel = 4; newMediumLevel = 2; newFullLevel = 6; break; // crop 640x640 - case 'd': newThumbLevel = 7; newMediumLevel = 7; newFullLevel = 5; break; // crop 1280x1280 - } - if (newThumbLevel < 0 || newMediumLevel < 0 || newFullLevel < 0) { - continue; - } - if (thumbLevel < 0 || newThumbLevel < thumbLevel) { - thumbLevel = newThumbLevel; - thumb = &i.value(); - } - if (mediumLevel < 0 || newMediumLevel < mediumLevel) { - mediumLevel = newMediumLevel; - medium = &i.value(); - } - if (fullLevel < 0 || newFullLevel < fullLevel) { - fullLevel = newFullLevel; - full = &i.value(); - } - } - if (!thumb || !medium || !full) { - return App::photo(0); - } - switch (photo.type()) { - case mtpc_photo: { - const auto &ph(photo.c_photo()); - return App::photoSet(ph.vid.v, 0, ph.vaccess_hash.v, ph.vdate.v, ImagePtr(*thumb, "JPG"), ImagePtr(*medium, "JPG"), ImagePtr(*full, "JPG")); - } break; - case mtpc_photoEmpty: return App::photo(photo.c_photoEmpty().vid.v); - } - return App::photo(0); + switch (photo.type()) { + case mtpc_photo: { + const auto &ph(photo.c_photo()); + return App::photoSet(ph.vid.v, 0, ph.vaccess_hash.v, ph.vdate.v, ImagePtr(*thumb, "JPG"), + ImagePtr(*medium, "JPG"), ImagePtr(*full, "JPG")); + } break; + case mtpc_photoEmpty: return App::photo(photo.c_photoEmpty().vid.v); } + return App::photo(0); +} - PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert) { - auto &sizes = photo.vsizes.v; - const MTPPhotoSize *thumb = 0, *medium = 0, *full = 0; - qint32 thumbLevel = -1, mediumLevel = -1, fullLevel = -1; - for (QVector::const_iterator i = sizes.cbegin(), e = sizes.cend(); i != e; ++i) { - char size = 0; - switch (i->type()) { - case mtpc_photoSize: { - auto &s = i->c_photoSize().vtype.v; - if (s.size()) size = s[0]; - } break; - - case mtpc_photoCachedSize: { - auto &s = i->c_photoCachedSize().vtype.v; - if (s.size()) size = s[0]; - } break; - } - if (!size) continue; - - qint32 newThumbLevel = -1, newMediumLevel = -1, newFullLevel = -1; - switch (size) { - case 's': newThumbLevel = 0; newMediumLevel = 5; newFullLevel = 4; break; // box 100x100 - case 'm': newThumbLevel = 2; newMediumLevel = 0; newFullLevel = 3; break; // box 320x320 - case 'x': newThumbLevel = 5; newMediumLevel = 3; newFullLevel = 1; break; // box 800x800 - case 'y': newThumbLevel = 6; newMediumLevel = 6; newFullLevel = 0; break; // box 1280x1280 - case 'w': newThumbLevel = 8; newMediumLevel = 8; newFullLevel = 2; break; // box 2560x2560 - case 'a': newThumbLevel = 1; newMediumLevel = 4; newFullLevel = 8; break; // crop 160x160 - case 'b': newThumbLevel = 3; newMediumLevel = 1; newFullLevel = 7; break; // crop 320x320 - case 'c': newThumbLevel = 4; newMediumLevel = 2; newFullLevel = 6; break; // crop 640x640 - case 'd': newThumbLevel = 7; newMediumLevel = 7; newFullLevel = 5; break; // crop 1280x1280 - } - if (newThumbLevel < 0 || newMediumLevel < 0 || newFullLevel < 0) { - continue; - } - if (thumbLevel < 0 || newThumbLevel < thumbLevel) { - thumbLevel = newThumbLevel; - thumb = &(*i); - } - if (mediumLevel < 0 || newMediumLevel < mediumLevel) { - mediumLevel = newMediumLevel; - medium = &(*i); - } - if (fullLevel < 0 || newFullLevel < fullLevel) { - fullLevel = newFullLevel; - full = &(*i); - } - } - if (thumb && medium && full) { - return App::photoSet(photo.vid.v, convert, photo.vaccess_hash.v, photo.vdate.v, App::image(*thumb), App::image(*medium), App::image(*full)); - } - return App::photoSet(photo.vid.v, convert, 0, 0, ImagePtr(), ImagePtr(), ImagePtr()); - } - - DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb) { - switch (document.type()) { - case mtpc_document: { - auto &d = document.c_document(); - return App::documentSet(d.vid.v, 0, d.vaccess_hash.v, d.vversion.v, d.vdate.v, d.vattributes.v, qs(d.vmime_type), ImagePtr(thumb, "JPG"), d.vdc_id.v, d.vsize.v, StorageImageLocation()); +PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert) { + auto &sizes = photo.vsizes.v; + const MTPPhotoSize *thumb = 0, *medium = 0, *full = 0; + qint32 thumbLevel = -1, mediumLevel = -1, fullLevel = -1; + for (QVector::const_iterator i = sizes.cbegin(), e = sizes.cend(); i != e; ++i) { + char size = 0; + switch (i->type()) { + case mtpc_photoSize: { + auto &s = i->c_photoSize().vtype.v; + if (s.size()) size = s[0]; } break; - case mtpc_documentEmpty: return App::document(document.c_documentEmpty().vid.v); - } - return App::document(0); - } - DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert) { - switch (document.type()) { - case mtpc_document: { - return feedDocument(document.c_document(), convert); - } break; - case mtpc_documentEmpty: { - return App::documentSet(document.c_documentEmpty().vid.v, convert, 0, 0, 0, QVector(), QString(), ImagePtr(), 0, 0, StorageImageLocation()); + case mtpc_photoCachedSize: { + auto &s = i->c_photoCachedSize().vtype.v; + if (s.size()) size = s[0]; } break; } - return App::document(0); - } + if (!size) continue; - DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert) { - return App::documentSet(document.vid.v, convert, document.vaccess_hash.v, document.vversion.v, document.vdate.v, document.vattributes.v, qs(document.vmime_type), App::image(document.vthumb), document.vdc_id.v, document.vsize.v, App::imageLocation(document.vthumb)); - } - - WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert) { - auto description = TextWithEntities { webpage.has_description() ? TextUtilities::Clean(qs(webpage.vdescription)) : QString() }; - auto siteName = webpage.has_site_name() ? qs(webpage.vsite_name) : QString(); - auto parseFlags = TextParseLinks | TextParseMultiline | TextParseRichText; - if (siteName == qstr("Twitter") || siteName == qstr("Instagram")) { - parseFlags |= TextParseHashtags | TextParseMentions; + qint32 newThumbLevel = -1, newMediumLevel = -1, newFullLevel = -1; + switch (size) { + case 's': + newThumbLevel = 0; + newMediumLevel = 5; + newFullLevel = 4; + break; // box 100x100 + case 'm': + newThumbLevel = 2; + newMediumLevel = 0; + newFullLevel = 3; + break; // box 320x320 + case 'x': + newThumbLevel = 5; + newMediumLevel = 3; + newFullLevel = 1; + break; // box 800x800 + case 'y': + newThumbLevel = 6; + newMediumLevel = 6; + newFullLevel = 0; + break; // box 1280x1280 + case 'w': + newThumbLevel = 8; + newMediumLevel = 8; + newFullLevel = 2; + break; // box 2560x2560 + case 'a': + newThumbLevel = 1; + newMediumLevel = 4; + newFullLevel = 8; + break; // crop 160x160 + case 'b': + newThumbLevel = 3; + newMediumLevel = 1; + newFullLevel = 7; + break; // crop 320x320 + case 'c': + newThumbLevel = 4; + newMediumLevel = 2; + newFullLevel = 6; + break; // crop 640x640 + case 'd': + newThumbLevel = 7; + newMediumLevel = 7; + newFullLevel = 5; + break; // crop 1280x1280 } - TextUtilities::ParseEntities(description, parseFlags); - return App::webPageSet(webpage.vid.v, convert, webpage.has_type() ? qs(webpage.vtype) : qsl("article"), qs(webpage.vurl), qs(webpage.vdisplay_url), siteName, webpage.has_title() ? qs(webpage.vtitle) : QString(), description, webpage.has_photo() ? App::feedPhoto(webpage.vphoto) : nullptr, webpage.has_document() ? App::feedDocument(webpage.vdocument) : nullptr, webpage.has_duration() ? webpage.vduration.v : 0, webpage.has_author() ? qs(webpage.vauthor) : QString(), 0); - } - - WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert) { - return App::webPageSet(webpage.vid.v, convert, QString(), QString(), QString(), QString(), QString(), TextWithEntities(), nullptr, nullptr, 0, QString(), webpage.vdate.v); - } - - WebPageData *feedWebPage(const MTPWebPage &webpage) { - switch (webpage.type()) { - case mtpc_webPage: return App::feedWebPage(webpage.c_webPage()); - case mtpc_webPageEmpty: { - WebPageData *page = App::webPage(webpage.c_webPageEmpty().vid.v); - if (page->pendingTill > 0) page->pendingTill = -1; // failed - return page; - } break; - case mtpc_webPagePending: return App::feedWebPage(webpage.c_webPagePending()); - case mtpc_webPageNotModified: LOG(("API Error: webPageNotModified is unexpected in feedWebPage().")); break; + if (newThumbLevel < 0 || newMediumLevel < 0 || newFullLevel < 0) { + continue; + } + if (thumbLevel < 0 || newThumbLevel < thumbLevel) { + thumbLevel = newThumbLevel; + thumb = &(*i); + } + if (mediumLevel < 0 || newMediumLevel < mediumLevel) { + mediumLevel = newMediumLevel; + medium = &(*i); + } + if (fullLevel < 0 || newFullLevel < fullLevel) { + fullLevel = newFullLevel; + full = &(*i); } - return nullptr; } - - WebPageData *feedWebPage(WebPageId webPageId, const QString &siteName, const TextWithEntities &content) { - return App::webPageSet(webPageId, nullptr, qsl("article"), QString(), QString(), siteName, QString(), content, nullptr, nullptr, 0, QString(), 0); + if (thumb && medium && full) { + return App::photoSet(photo.vid.v, convert, photo.vaccess_hash.v, photo.vdate.v, App::image(*thumb), + App::image(*medium), App::image(*full)); } + return App::photoSet(photo.vid.v, convert, 0, 0, ImagePtr(), ImagePtr(), ImagePtr()); +} - GameData *feedGame(const MTPDgame &game, GameData *convert) { - return App::gameSet(game.vid.v, convert, game.vaccess_hash.v, qs(game.vshort_name), qs(game.vtitle), qs(game.vdescription), App::feedPhoto(game.vphoto), game.has_document() ? App::feedDocument(game.vdocument) : nullptr); +DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb) { + switch (document.type()) { + case mtpc_document: { + auto &d = document.c_document(); + return App::documentSet(d.vid.v, 0, d.vaccess_hash.v, d.vversion.v, d.vdate.v, d.vattributes.v, + qs(d.vmime_type), ImagePtr(thumb, "JPG"), d.vdc_id.v, d.vsize.v, + StorageImageLocation()); + } break; + case mtpc_documentEmpty: return App::document(document.c_documentEmpty().vid.v); } + return App::document(0); +} - PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction) { - if (!id) return nullptr; +DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert) { + switch (document.type()) { + case mtpc_document: { + return feedDocument(document.c_document(), convert); + } break; + case mtpc_documentEmpty: { + return App::documentSet(document.c_documentEmpty().vid.v, convert, 0, 0, 0, QVector(), + QString(), ImagePtr(), 0, 0, StorageImageLocation()); + } break; + } + return App::document(0); +} - auto i = peersData.constFind(id); - if (i == peersData.cend()) { - PeerData *newData = nullptr; - if (peerIsUser(id)) { - newData = new UserData(id); - } else if (peerIsChat(id)) { - newData = new ChatData(id); - } else if (peerIsChannel(id)) { - newData = new ChannelData(id); +DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert) { + return App::documentSet(document.vid.v, convert, document.vaccess_hash.v, document.vversion.v, document.vdate.v, + document.vattributes.v, qs(document.vmime_type), App::image(document.vthumb), + document.vdc_id.v, document.vsize.v, App::imageLocation(document.vthumb)); +} + +WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert) { + auto description = + TextWithEntities{webpage.has_description() ? TextUtilities::Clean(qs(webpage.vdescription)) : QString()}; + auto siteName = webpage.has_site_name() ? qs(webpage.vsite_name) : QString(); + auto parseFlags = TextParseLinks | TextParseMultiline | TextParseRichText; + if (siteName == qstr("Twitter") || siteName == qstr("Instagram")) { + parseFlags |= TextParseHashtags | TextParseMentions; + } + TextUtilities::ParseEntities(description, parseFlags); + return App::webPageSet( + webpage.vid.v, convert, webpage.has_type() ? qs(webpage.vtype) : qsl("article"), qs(webpage.vurl), + qs(webpage.vdisplay_url), siteName, webpage.has_title() ? qs(webpage.vtitle) : QString(), description, + webpage.has_photo() ? App::feedPhoto(webpage.vphoto) : nullptr, + webpage.has_document() ? App::feedDocument(webpage.vdocument) : nullptr, + webpage.has_duration() ? webpage.vduration.v : 0, webpage.has_author() ? qs(webpage.vauthor) : QString(), 0); +} + +WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert) { + return App::webPageSet(webpage.vid.v, convert, QString(), QString(), QString(), QString(), QString(), + TextWithEntities(), nullptr, nullptr, 0, QString(), webpage.vdate.v); +} + +WebPageData *feedWebPage(const MTPWebPage &webpage) { + switch (webpage.type()) { + case mtpc_webPage: return App::feedWebPage(webpage.c_webPage()); + case mtpc_webPageEmpty: { + WebPageData *page = App::webPage(webpage.c_webPageEmpty().vid.v); + if (page->pendingTill > 0) page->pendingTill = -1; // failed + return page; + } break; + case mtpc_webPagePending: return App::feedWebPage(webpage.c_webPagePending()); + case mtpc_webPageNotModified: LOG(("API Error: webPageNotModified is unexpected in feedWebPage().")); break; + } + return nullptr; +} + +WebPageData *feedWebPage(WebPageId webPageId, const QString &siteName, const TextWithEntities &content) { + return App::webPageSet(webPageId, nullptr, qsl("article"), QString(), QString(), siteName, QString(), content, + nullptr, nullptr, 0, QString(), 0); +} + +GameData *feedGame(const MTPDgame &game, GameData *convert) { + return App::gameSet(game.vid.v, convert, game.vaccess_hash.v, qs(game.vshort_name), qs(game.vtitle), + qs(game.vdescription), App::feedPhoto(game.vphoto), + game.has_document() ? App::feedDocument(game.vdocument) : nullptr); +} + +PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction) { + if (!id) return nullptr; + + auto i = peersData.constFind(id); + if (i == peersData.cend()) { + PeerData *newData = nullptr; + if (peerIsUser(id)) { + newData = new UserData(id); + } else if (peerIsChat(id)) { + newData = new ChatData(id); + } else if (peerIsChannel(id)) { + newData = new ChannelData(id); + } + Assert(newData != nullptr); + + newData->input = MTPinputPeer(MTP_inputPeerEmpty()); + i = peersData.insert(id, newData); + } + switch (restriction) { + case PeerData::MinimalLoaded: { + if (i.value()->loadedStatus == PeerData::NotLoaded) { + return nullptr; + } + } break; + case PeerData::FullLoaded: { + if (i.value()->loadedStatus != PeerData::FullLoaded) { + return nullptr; + } + } break; + case PeerData::NotLoaded: break; + } + return i.value(); +} + +void enumerateUsers(base::lambda action) { + for_const (auto peer, peersData) { + if (auto user = peer->asUser()) { + action(user); + } + } +} + +UserData *self() { + return ::self; +} + +PeerData *peerByName(const QString &username) { + QString uname(username.trimmed()); + for_const (PeerData *peer, peersData) { + if (!peer->userName().compare(uname, Qt::CaseInsensitive)) { + return peer; + } + } + return nullptr; +} + +void updateImage(ImagePtr &old, ImagePtr now) { + if (now->isNull()) return; + if (old->isNull()) { + old = now; + } else if (DelayedStorageImage *img = old->toDelayedStorageImage()) { + StorageImageLocation loc = now->location(); + if (!loc.isNull()) { + img->setStorageLocation(loc); + } + } +} + +PhotoData *photo(const PhotoId &photo) { + PhotosData::const_iterator i = ::photosData.constFind(photo); + if (i == ::photosData.cend()) { + i = ::photosData.insert(photo, new PhotoData(photo)); + } + return i.value(); +} + +PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const quint64 &access, qint32 date, const ImagePtr &thumb, + const ImagePtr &medium, const ImagePtr &full) { + if (convert) { + if (convert->id != photo) { + PhotosData::iterator i = ::photosData.find(convert->id); + if (i != ::photosData.cend() && i.value() == convert) { + ::photosData.erase(i); } - Assert(newData != nullptr); - - newData->input = MTPinputPeer(MTP_inputPeerEmpty()); - i = peersData.insert(id, newData); + convert->id = photo; + convert->uploadingData.reset(); } - switch (restriction) { - case PeerData::MinimalLoaded: { - if (i.value()->loadedStatus == PeerData::NotLoaded) { - return nullptr; - } - } break; - case PeerData::FullLoaded: { - if (i.value()->loadedStatus != PeerData::FullLoaded) { - return nullptr; - } - } break; - case PeerData::NotLoaded: break; - } - return i.value(); - } - - void enumerateUsers(base::lambda action) { - for_const (auto peer, peersData) { - if (auto user = peer->asUser()) { - action(user); - } + if (date) { + convert->access = access; + convert->date = date; + updateImage(convert->thumb, thumb); + updateImage(convert->medium, medium); + updateImage(convert->full, full); } } - - UserData *self() { - return ::self; - } - - PeerData *peerByName(const QString &username) { - QString uname(username.trimmed()); - for_const (PeerData *peer, peersData) { - if (!peer->userName().compare(uname, Qt::CaseInsensitive)) { - return peer; - } - } - return nullptr; - } - - void updateImage(ImagePtr &old, ImagePtr now) { - if (now->isNull()) return; - if (old->isNull()) { - old = now; - } else if (DelayedStorageImage *img = old->toDelayedStorageImage()) { - StorageImageLocation loc = now->location(); - if (!loc.isNull()) { - img->setStorageLocation(loc); - } - } - } - - PhotoData *photo(const PhotoId &photo) { - PhotosData::const_iterator i = ::photosData.constFind(photo); - if (i == ::photosData.cend()) { - i = ::photosData.insert(photo, new PhotoData(photo)); - } - return i.value(); - } - - PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const quint64 &access, qint32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full) { + PhotosData::const_iterator i = ::photosData.constFind(photo); + PhotoData *result; + LastPhotosMap::iterator inLastIter = lastPhotosMap.end(); + if (i == ::photosData.cend()) { if (convert) { - if (convert->id != photo) { - PhotosData::iterator i = ::photosData.find(convert->id); - if (i != ::photosData.cend() && i.value() == convert) { - ::photosData.erase(i); - } - convert->id = photo; - convert->uploadingData.reset(); + result = convert; + } else { + result = new PhotoData(photo, access, date, thumb, medium, full); + } + ::photosData.insert(photo, result); + } else { + result = i.value(); + if (result != convert && date) { + result->access = access; + result->date = date; + updateImage(result->thumb, thumb); + updateImage(result->medium, medium); + updateImage(result->full, full); + } + inLastIter = lastPhotosMap.find(result); + } + if (inLastIter == lastPhotosMap.end()) { // insert new one + if (lastPhotos.size() == MaxPhotosInMemory) { + lastPhotos.front()->forget(); + lastPhotosMap.remove(lastPhotos.front()); + lastPhotos.pop_front(); + } + lastPhotosMap.insert(result, lastPhotos.insert(lastPhotos.end(), result)); + } else { + lastPhotos.erase(inLastIter.value()); // move to back + (*inLastIter) = lastPhotos.insert(lastPhotos.end(), result); + } + return result; +} + +DocumentData *document(const DocumentId &document) { + DocumentsData::const_iterator i = ::documentsData.constFind(document); + if (i == ::documentsData.cend()) { + i = ::documentsData.insert(document, DocumentData::create(document)); + } + return i.value(); +} + +DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const quint64 &access, qint32 version, + qint32 date, const QVector &attributes, const QString &mime, + const ImagePtr &thumb, qint32 dc, qint32 size, const StorageImageLocation &thumbLocation) { + bool versionChanged = false; + bool sentSticker = false; + if (convert) { + MediaKey oldKey = convert->mediaKey(); + bool idChanged = (convert->id != document); + if (idChanged) { + DocumentsData::iterator i = ::documentsData.find(convert->id); + if (i != ::documentsData.cend() && i.value() == convert) { + ::documentsData.erase(i); } - if (date) { - convert->access = access; - convert->date = date; + + convert->id = document; + convert->status = FileReady; + sentSticker = (convert->sticker() != 0); + } + if (date) { + convert->setattributes(attributes); + versionChanged = convert->setRemoteVersion(version); + convert->setRemoteLocation(dc, access); + convert->date = date; + convert->mime = mime; + if (!thumb->isNull() && (convert->thumb->isNull() || convert->thumb->width() < thumb->width() || + convert->thumb->height() < thumb->height() || versionChanged)) { updateImage(convert->thumb, thumb); - updateImage(convert->medium, medium); - updateImage(convert->full, full); } - } - PhotosData::const_iterator i = ::photosData.constFind(photo); - PhotoData *result; - LastPhotosMap::iterator inLastIter = lastPhotosMap.end(); - if (i == ::photosData.cend()) { - if (convert) { - result = convert; - } else { - result = new PhotoData(photo, access, date, thumb, medium, full); + convert->size = size; + convert->recountIsImage(); + if (convert->sticker() && convert->sticker()->loc.isNull() && !thumbLocation.isNull()) { + convert->sticker()->loc = thumbLocation; } - ::photosData.insert(photo, result); - } else { - result = i.value(); - if (result != convert && date) { - result->access = access; - result->date = date; - updateImage(result->thumb, thumb); - updateImage(result->medium, medium); - updateImage(result->full, full); - } - inLastIter = lastPhotosMap.find(result); - } - if (inLastIter == lastPhotosMap.end()) { // insert new one - if (lastPhotos.size() == MaxPhotosInMemory) { - lastPhotos.front()->forget(); - lastPhotosMap.remove(lastPhotos.front()); - lastPhotos.pop_front(); - } - lastPhotosMap.insert(result, lastPhotos.insert(lastPhotos.end(), result)); - } else { - lastPhotos.erase(inLastIter.value()); // move to back - (*inLastIter) = lastPhotos.insert(lastPhotos.end(), result); - } - return result; - } - DocumentData *document(const DocumentId &document) { - DocumentsData::const_iterator i = ::documentsData.constFind(document); - if (i == ::documentsData.cend()) { - i = ::documentsData.insert(document, DocumentData::create(document)); - } - return i.value(); - } - - DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const quint64 &access, qint32 version, qint32 date, const QVector &attributes, const QString &mime, const ImagePtr &thumb, qint32 dc, qint32 size, const StorageImageLocation &thumbLocation) { - bool versionChanged = false; - bool sentSticker = false; - if (convert) { - MediaKey oldKey = convert->mediaKey(); - bool idChanged = (convert->id != document); + MediaKey newKey = convert->mediaKey(); if (idChanged) { - DocumentsData::iterator i = ::documentsData.find(convert->id); - if (i != ::documentsData.cend() && i.value() == convert) { - ::documentsData.erase(i); + if (convert->voice()) { + Local::copyAudio(oldKey, newKey); + } else if (convert->sticker() || convert->isAnimation()) { + Local::copyStickerImage(oldKey, newKey); } - - convert->id = document; - convert->status = FileReady; - sentSticker = (convert->sticker() != 0); - } - if (date) { - convert->setattributes(attributes); - versionChanged = convert->setRemoteVersion(version); - convert->setRemoteLocation(dc, access); - convert->date = date; - convert->mime = mime; - if (!thumb->isNull() && (convert->thumb->isNull() || convert->thumb->width() < thumb->width() || convert->thumb->height() < thumb->height() || versionChanged)) { - updateImage(convert->thumb, thumb); - } - convert->size = size; - convert->recountIsImage(); - if (convert->sticker() && convert->sticker()->loc.isNull() && !thumbLocation.isNull()) { - convert->sticker()->loc = thumbLocation; - } - - MediaKey newKey = convert->mediaKey(); - if (idChanged) { - if (convert->voice()) { - Local::copyAudio(oldKey, newKey); - } else if (convert->sticker() || convert->isAnimation()) { - Local::copyStickerImage(oldKey, newKey); - } - } - } - - if (cSavedGifs().indexOf(convert) >= 0) { // id changed - Local::writeSavedGifs(); } } - DocumentsData::const_iterator i = ::documentsData.constFind(document); - DocumentData *result; - if (i == ::documentsData.cend()) { - if (convert) { - result = convert; - } else { - result = DocumentData::create(document, dc, access, version, attributes); - result->date = date; - result->mime = mime; + + if (cSavedGifs().indexOf(convert) >= 0) { // id changed + Local::writeSavedGifs(); + } + } + DocumentsData::const_iterator i = ::documentsData.constFind(document); + DocumentData *result; + if (i == ::documentsData.cend()) { + if (convert) { + result = convert; + } else { + result = DocumentData::create(document, dc, access, version, attributes); + result->date = date; + result->mime = mime; + result->thumb = thumb; + result->size = size; + result->recountIsImage(); + if (result->sticker()) { + result->sticker()->loc = thumbLocation; + } + } + ::documentsData.insert(document, result); + } else { + result = i.value(); + if (result != convert && date) { + result->setattributes(attributes); + versionChanged = result->setRemoteVersion(version); + if (!result->isValid()) { + result->setRemoteLocation(dc, access); + } + result->date = date; + result->mime = mime; + if (!thumb->isNull() && (result->thumb->isNull() || result->thumb->width() < thumb->width() || + result->thumb->height() < thumb->height() || versionChanged)) { result->thumb = thumb; - result->size = size; - result->recountIsImage(); - if (result->sticker()) { - result->sticker()->loc = thumbLocation; - } } - ::documentsData.insert(document, result); - } else { - result = i.value(); - if (result != convert && date) { - result->setattributes(attributes); - versionChanged = result->setRemoteVersion(version); - if (!result->isValid()) { - result->setRemoteLocation(dc, access); - } - result->date = date; - result->mime = mime; - if (!thumb->isNull() && (result->thumb->isNull() || result->thumb->width() < thumb->width() || result->thumb->height() < thumb->height() || versionChanged)) { - result->thumb = thumb; - } - result->size = size; - result->recountIsImage(); - if (result->sticker() && result->sticker()->loc.isNull() && !thumbLocation.isNull()) { - result->sticker()->loc = thumbLocation; - } + result->size = size; + result->recountIsImage(); + if (result->sticker() && result->sticker()->loc.isNull() && !thumbLocation.isNull()) { + result->sticker()->loc = thumbLocation; } } - if (sentSticker && App::main()) { - App::main()->incrementSticker(result); - } - if (versionChanged) { - if (result->sticker() && result->sticker()->set.type() == mtpc_inputStickerSetID) { - auto it = Global::StickerSets().constFind(result->sticker()->set.c_inputStickerSetID().vid.v); - if (it != Global::StickerSets().cend()) { - if (it->id == Stickers::CloudRecentSetId) { - Local::writeRecentStickers(); - } else if (it->id == Stickers::FavedSetId) { - Local::writeFavedStickers(); - } else if (it->flags & MTPDstickerSet::Flag::f_archived) { - Local::writeArchivedStickers(); - } else if (it->flags & MTPDstickerSet::Flag::f_installed) { - Local::writeInstalledStickers(); - } - if (it->flags & MTPDstickerSet_ClientFlag::f_featured) { - Local::writeFeaturedStickers(); - } - } - } - auto &items = App::documentItems(); - auto i = items.constFind(result); - if (i != items.cend()) { - for_const (auto item, i.value()) { - item->setPendingInitDimensions(); - } - } - } - return result; } - - WebPageData *webPage(const WebPageId &webPage) { - auto i = webPagesData.constFind(webPage); - if (i == webPagesData.cend()) { - i = webPagesData.insert(webPage, new WebPageData(webPage)); - } - return i.value(); + if (sentSticker && App::main()) { + App::main()->incrementSticker(result); } + if (versionChanged) { + if (result->sticker() && result->sticker()->set.type() == mtpc_inputStickerSetID) { + auto it = Global::StickerSets().constFind(result->sticker()->set.c_inputStickerSetID().vid.v); + if (it != Global::StickerSets().cend()) { + if (it->id == Stickers::CloudRecentSetId) { + Local::writeRecentStickers(); + } else if (it->id == Stickers::FavedSetId) { + Local::writeFavedStickers(); + } else if (it->flags & MTPDstickerSet::Flag::f_archived) { + Local::writeArchivedStickers(); + } else if (it->flags & MTPDstickerSet::Flag::f_installed) { + Local::writeInstalledStickers(); + } + if (it->flags & MTPDstickerSet_ClientFlag::f_featured) { + Local::writeFeaturedStickers(); + } + } + } + auto &items = App::documentItems(); + auto i = items.constFind(result); + if (i != items.cend()) { + for_const (auto item, i.value()) { item->setPendingInitDimensions(); } + } + } + return result; +} - WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *document, qint32 duration, const QString &author, qint32 pendingTill) { +WebPageData *webPage(const WebPageId &webPage) { + auto i = webPagesData.constFind(webPage); + if (i == webPagesData.cend()) { + i = webPagesData.insert(webPage, new WebPageData(webPage)); + } + return i.value(); +} + +WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, + const QString &displayUrl, const QString &siteName, const QString &title, + const TextWithEntities &description, PhotoData *photo, DocumentData *document, qint32 duration, + const QString &author, qint32 pendingTill) { + if (convert) { + if (convert->id != webPage) { + auto i = webPagesData.find(convert->id); + if (i != webPagesData.cend() && i.value() == convert) { + webPagesData.erase(i); + } + convert->id = webPage; + } + if ((convert->url.isEmpty() && !url.isEmpty()) || + (convert->pendingTill && convert->pendingTill != pendingTill && pendingTill >= -1)) { + convert->type = toWebPageType(type); + convert->url = TextUtilities::Clean(url); + convert->displayUrl = TextUtilities::Clean(displayUrl); + convert->siteName = TextUtilities::Clean(siteName); + convert->title = TextUtilities::SingleLine(title); + convert->description = description; + convert->photo = photo; + convert->document = document; + convert->duration = duration; + convert->author = TextUtilities::Clean(author); + if (convert->pendingTill > 0 && pendingTill <= 0) { + Auth().api().clearWebPageRequest(convert); + } + convert->pendingTill = pendingTill; + if (App::main()) App::main()->webPageUpdated(convert); + } + } + auto i = webPagesData.constFind(webPage); + WebPageData *result; + if (i == webPagesData.cend()) { if (convert) { - if (convert->id != webPage) { - auto i = webPagesData.find(convert->id); - if (i != webPagesData.cend() && i.value() == convert) { - webPagesData.erase(i); - } - convert->id = webPage; - } - if ((convert->url.isEmpty() && !url.isEmpty()) || (convert->pendingTill && convert->pendingTill != pendingTill && pendingTill >= -1)) { - convert->type = toWebPageType(type); - convert->url = TextUtilities::Clean(url); - convert->displayUrl = TextUtilities::Clean(displayUrl); - convert->siteName = TextUtilities::Clean(siteName); - convert->title = TextUtilities::SingleLine(title); - convert->description = description; - convert->photo = photo; - convert->document = document; - convert->duration = duration; - convert->author = TextUtilities::Clean(author); - if (convert->pendingTill > 0 && pendingTill <= 0) { - Auth().api().clearWebPageRequest(convert); - } - convert->pendingTill = pendingTill; - if (App::main()) App::main()->webPageUpdated(convert); - } - } - auto i = webPagesData.constFind(webPage); - WebPageData *result; - if (i == webPagesData.cend()) { - if (convert) { - result = convert; - } else { - result = new WebPageData(webPage, toWebPageType(type), url, displayUrl, siteName, title, description, document, photo, duration, author, (pendingTill >= -1) ? pendingTill : -1); - if (pendingTill > 0) { - Auth().api().requestWebPageDelayed(result); - } - } - webPagesData.insert(webPage, result); + result = convert; } else { - result = i.value(); - if (result != convert) { - if ((result->url.isEmpty() && !url.isEmpty()) || (result->pendingTill && result->pendingTill != pendingTill && pendingTill >= -1)) { - result->type = toWebPageType(type); - result->url = TextUtilities::Clean(url); - result->displayUrl = TextUtilities::Clean(displayUrl); - result->siteName = TextUtilities::Clean(siteName); - result->title = TextUtilities::SingleLine(title); - result->description = description; - result->photo = photo; - result->document = document; - result->duration = duration; - result->author = TextUtilities::Clean(author); - if (result->pendingTill > 0 && pendingTill <= 0) { - Auth().api().clearWebPageRequest(result); - } - result->pendingTill = pendingTill; - if (App::main()) App::main()->webPageUpdated(result); - } + result = new WebPageData(webPage, toWebPageType(type), url, displayUrl, siteName, title, description, + document, photo, duration, author, (pendingTill >= -1) ? pendingTill : -1); + if (pendingTill > 0) { + Auth().api().requestWebPageDelayed(result); } } - return result; - } - - GameData *game(const GameId &game) { - auto i = gamesData.constFind(game); - if (i == gamesData.cend()) { - i = gamesData.insert(game, new GameData(game)); + webPagesData.insert(webPage, result); + } else { + result = i.value(); + if (result != convert) { + if ((result->url.isEmpty() && !url.isEmpty()) || + (result->pendingTill && result->pendingTill != pendingTill && pendingTill >= -1)) { + result->type = toWebPageType(type); + result->url = TextUtilities::Clean(url); + result->displayUrl = TextUtilities::Clean(displayUrl); + result->siteName = TextUtilities::Clean(siteName); + result->title = TextUtilities::SingleLine(title); + result->description = description; + result->photo = photo; + result->document = document; + result->duration = duration; + result->author = TextUtilities::Clean(author); + if (result->pendingTill > 0 && pendingTill <= 0) { + Auth().api().clearWebPageRequest(result); + } + result->pendingTill = pendingTill; + if (App::main()) App::main()->webPageUpdated(result); + } } - return i.value(); } + return result; +} - GameData *gameSet(const GameId &game, GameData *convert, const quint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *document) { +GameData *game(const GameId &game) { + auto i = gamesData.constFind(game); + if (i == gamesData.cend()) { + i = gamesData.insert(game, new GameData(game)); + } + return i.value(); +} + +GameData *gameSet(const GameId &game, GameData *convert, const quint64 &accessHash, const QString &shortName, + const QString &title, const QString &description, PhotoData *photo, DocumentData *document) { + if (convert) { + if (convert->id != game) { + auto i = gamesData.find(convert->id); + if (i != gamesData.cend() && i.value() == convert) { + gamesData.erase(i); + } + convert->id = game; + convert->accessHash = 0; + } + if (!convert->accessHash && accessHash) { + convert->accessHash = accessHash; + convert->shortName = TextUtilities::Clean(shortName); + convert->title = TextUtilities::SingleLine(title); + convert->description = TextUtilities::Clean(description); + convert->photo = photo; + convert->document = document; + if (App::main()) App::main()->gameUpdated(convert); + } + } + auto i = gamesData.constFind(game); + GameData *result; + if (i == gamesData.cend()) { if (convert) { - if (convert->id != game) { - auto i = gamesData.find(convert->id); - if (i != gamesData.cend() && i.value() == convert) { - gamesData.erase(i); - } - convert->id = game; - convert->accessHash = 0; - } - if (!convert->accessHash && accessHash) { - convert->accessHash = accessHash; - convert->shortName = TextUtilities::Clean(shortName); - convert->title = TextUtilities::SingleLine(title); - convert->description = TextUtilities::Clean(description); - convert->photo = photo; - convert->document = document; - if (App::main()) App::main()->gameUpdated(convert); - } - } - auto i = gamesData.constFind(game); - GameData *result; - if (i == gamesData.cend()) { - if (convert) { - result = convert; - } else { - result = new GameData(game, accessHash, shortName, title, description, photo, document); - } - gamesData.insert(game, result); + result = convert; } else { - result = i.value(); - if (result != convert) { - if (!result->accessHash && accessHash) { - result->accessHash = accessHash; - result->shortName = TextUtilities::Clean(shortName); - result->title = TextUtilities::SingleLine(title); - result->description = TextUtilities::Clean(description); - result->photo = photo; - result->document = document; - if (App::main()) App::main()->gameUpdated(result); - } + result = new GameData(game, accessHash, shortName, title, description, photo, document); + } + gamesData.insert(game, result); + } else { + result = i.value(); + if (result != convert) { + if (!result->accessHash && accessHash) { + result->accessHash = accessHash; + result->shortName = TextUtilities::Clean(shortName); + result->title = TextUtilities::SingleLine(title); + result->description = TextUtilities::Clean(description); + result->photo = photo; + result->document = document; + if (App::main()) App::main()->gameUpdated(result); } } - return result; } + return result; +} - LocationData *location(const LocationCoords &coords) { - auto i = locationsData.constFind(coords); - if (i == locationsData.cend()) { - i = locationsData.insert(coords, new LocationData(coords)); - } +LocationData *location(const LocationCoords &coords) { + auto i = locationsData.constFind(coords); + if (i == locationsData.cend()) { + i = locationsData.insert(coords, new LocationData(coords)); + } + return i.value(); +} + +void forgetMedia() { + lastPhotos.clear(); + lastPhotosMap.clear(); + for_const (auto photo, ::photosData) { photo->forget(); } + for_const (auto document, ::documentsData) { document->forget(); } + for_const (auto location, ::locationsData) { location->thumb->forget(); } +} + +MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo) { + if (photo.type() == mtpc_userProfilePhoto) { + const auto &uphoto(photo.c_userProfilePhoto()); + + QVector photoSizes; + photoSizes.push_back( + MTP_photoSize(MTP_string("a"), uphoto.vphoto_small, MTP_int(160), MTP_int(160), MTP_int(0))); + photoSizes.push_back(MTP_photoSize(MTP_string("c"), uphoto.vphoto_big, MTP_int(640), MTP_int(640), MTP_int(0))); + + return MTP_photo(MTP_flags(0), uphoto.vphoto_id, MTP_long(0), date, MTP_vector(photoSizes)); + } + return MTP_photoEmpty(MTP_long(0)); +} + +QString peerName(const PeerData *peer, bool forDialogs) { + return peer ? + ((forDialogs && peer->isUser() && !peer->asUser()->nameOrPhone.isEmpty()) ? peer->asUser()->nameOrPhone : + peer->name) : + lang(lng_deleted); +} + +Histories &histories() { + return ::histories; +} + +not_null history(const PeerId &peer) { + return ::histories.findOrInsert(peer); +} + +History *historyFromDialog(const PeerId &peer, qint32 unreadCnt, qint32 maxInboxRead, qint32 maxOutboxRead) { + return ::histories.findOrInsert(peer, unreadCnt, maxInboxRead, maxOutboxRead); +} + +History *historyLoaded(const PeerId &peer) { + return ::histories.find(peer); +} + +HistoryItem *histItemById(ChannelId channelId, MsgId itemId) { + if (!itemId) return nullptr; + + auto data = fetchMsgsData(channelId, false); + if (!data) return nullptr; + + auto i = data->constFind(itemId); + if (i != data->cend()) { return i.value(); } + return nullptr; +} - void forgetMedia() { - lastPhotos.clear(); - lastPhotosMap.clear(); - for_const (auto photo, ::photosData) { - photo->forget(); - } - for_const (auto document, ::documentsData) { - document->forget(); - } - for_const (auto location, ::locationsData) { - location->thumb->forget(); +void historyRegItem(HistoryItem *item) { + MsgsData *data = fetchMsgsData(item->channelId()); + MsgsData::const_iterator i = data->constFind(item->id); + if (i == data->cend()) { + data->insert(item->id, item); + } else if (i.value() != item) { + LOG(("App Error: trying to historyRegItem() an already registered item")); + i.value()->destroy(); + data->insert(item->id, item); + } +} + +void historyItemDetached(HistoryItem *item) { + if (::hoveredItem == item) { + hoveredItem(nullptr); + } + if (::pressedItem == item) { + pressedItem(nullptr); + } + if (::hoveredLinkItem == item) { + hoveredLinkItem(nullptr); + } + if (::pressedLinkItem == item) { + pressedLinkItem(nullptr); + } + if (::contextItem == item) { + contextItem(nullptr); + } + if (::mousedItem == item) { + mousedItem(nullptr); + } +} + +void historyUnregItem(HistoryItem *item) { + auto data = fetchMsgsData(item->channelId(), false); + if (!data) return; + + auto i = data->find(item->id); + if (i != data->cend()) { + if (i.value() == item) { + data->erase(i); } } + historyItemDetached(item); + auto j = ::dependentItems.find(item); + if (j != ::dependentItems.cend()) { + DependentItemsSet items; + std::swap(items, j.value()); + ::dependentItems.erase(j); - MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo) { - if (photo.type() == mtpc_userProfilePhoto) { - const auto &uphoto(photo.c_userProfilePhoto()); - - QVector photoSizes; - photoSizes.push_back(MTP_photoSize(MTP_string("a"), uphoto.vphoto_small, MTP_int(160), MTP_int(160), MTP_int(0))); - photoSizes.push_back(MTP_photoSize(MTP_string("c"), uphoto.vphoto_big, MTP_int(640), MTP_int(640), MTP_int(0))); - - return MTP_photo(MTP_flags(0), uphoto.vphoto_id, MTP_long(0), date, MTP_vector(photoSizes)); - } - return MTP_photoEmpty(MTP_long(0)); + for_const (auto dependent, items) { dependent->dependencyItemRemoved(item); } } - - QString peerName(const PeerData *peer, bool forDialogs) { - return peer ? ((forDialogs && peer->isUser() && !peer->asUser()->nameOrPhone.isEmpty()) ? peer->asUser()->nameOrPhone : peer->name) : lang(lng_deleted); + Auth().notifications().clearFromItem(item); + if (Global::started() && !App::quitting()) { + Global::RefItemRemoved().notify(item, true); } +} - Histories &histories() { - return ::histories; +void historyUpdateDependent(HistoryItem *item) { + DependentItems::iterator j = ::dependentItems.find(item); + if (j != ::dependentItems.cend()) { + for_const (HistoryItem *dependent, j.value()) { dependent->updateDependencyItem(); } } - - not_null history(const PeerId &peer) { - return ::histories.findOrInsert(peer); + if (App::main()) { + App::main()->itemEdited(item); } +} - History *historyFromDialog(const PeerId &peer, qint32 unreadCnt, qint32 maxInboxRead, qint32 maxOutboxRead) { - return ::histories.findOrInsert(peer, unreadCnt, maxInboxRead, maxOutboxRead); - } +void historyClearMsgs() { + ::dependentItems.clear(); - History *historyLoaded(const PeerId &peer) { - return ::histories.find(peer); - } - - HistoryItem *histItemById(ChannelId channelId, MsgId itemId) { - if (!itemId) return nullptr; - - auto data = fetchMsgsData(channelId, false); - if (!data) return nullptr; - - auto i = data->constFind(itemId); - if (i != data->cend()) { - return i.value(); - } - return nullptr; - } - - void historyRegItem(HistoryItem *item) { - MsgsData *data = fetchMsgsData(item->channelId()); - MsgsData::const_iterator i = data->constFind(item->id); - if (i == data->cend()) { - data->insert(item->id, item); - } else if (i.value() != item) { - LOG(("App Error: trying to historyRegItem() an already registered item")); - i.value()->destroy(); - data->insert(item->id, item); + QVector toDelete; + for_const (auto item, msgsData) { + if (item->detached()) { + toDelete.push_back(item); } } - - void historyItemDetached(HistoryItem *item) { - if (::hoveredItem == item) { - hoveredItem(nullptr); - } - if (::pressedItem == item) { - pressedItem(nullptr); - } - if (::hoveredLinkItem == item) { - hoveredLinkItem(nullptr); - } - if (::pressedLinkItem == item) { - pressedLinkItem(nullptr); - } - if (::contextItem == item) { - contextItem(nullptr); - } - if (::mousedItem == item) { - mousedItem(nullptr); - } - } - - void historyUnregItem(HistoryItem *item) { - auto data = fetchMsgsData(item->channelId(), false); - if (!data) return; - - auto i = data->find(item->id); - if (i != data->cend()) { - if (i.value() == item) { - data->erase(i); - } - } - historyItemDetached(item); - auto j = ::dependentItems.find(item); - if (j != ::dependentItems.cend()) { - DependentItemsSet items; - std::swap(items, j.value()); - ::dependentItems.erase(j); - - for_const (auto dependent, items) { - dependent->dependencyItemRemoved(item); - } - } - Auth().notifications().clearFromItem(item); - if (Global::started() && !App::quitting()) { - Global::RefItemRemoved().notify(item, true); - } - } - - void historyUpdateDependent(HistoryItem *item) { - DependentItems::iterator j = ::dependentItems.find(item); - if (j != ::dependentItems.cend()) { - for_const (HistoryItem *dependent, j.value()) { - dependent->updateDependencyItem(); - } - } - if (App::main()) { - App::main()->itemEdited(item); - } - } - - void historyClearMsgs() { - ::dependentItems.clear(); - - QVector toDelete; - for_const (auto item, msgsData) { + for_const (auto &chMsgsData, channelMsgsData) { + for_const (auto item, chMsgsData) { if (item->detached()) { toDelete.push_back(item); } } - for_const (auto &chMsgsData, channelMsgsData) { - for_const (auto item, chMsgsData) { - if (item->detached()) { - toDelete.push_back(item); - } - } - } - msgsData.clear(); - channelMsgsData.clear(); - for_const (auto item, toDelete) { - delete item; - } - - clearMousedItems(); } + msgsData.clear(); + channelMsgsData.clear(); + for_const (auto item, toDelete) { delete item; } - void historyClearItems() { - randomData.clear(); - sentData.clear(); - mutedPeers.clear(); - cSetSavedPeers(SavedPeers()); - cSetSavedPeersByTime(SavedPeersByTime()); - cSetRecentInlineBots(RecentInlineBots()); + clearMousedItems(); +} - for_const (auto peer, ::peersData) { - delete peer; - } - ::peersData.clear(); - for_const (auto game, ::gamesData) { - delete game; - } - ::gamesData.clear(); - for_const (auto webpage, ::webPagesData) { - delete webpage; - } - ::webPagesData.clear(); - for_const (auto photo, ::photosData) { - delete photo; - } - ::photosData.clear(); - for_const (auto document, ::documentsData) { - delete document; - } - ::documentsData.clear(); +void historyClearItems() { + randomData.clear(); + sentData.clear(); + mutedPeers.clear(); + cSetSavedPeers(SavedPeers()); + cSetSavedPeersByTime(SavedPeersByTime()); + cSetRecentInlineBots(RecentInlineBots()); - if (AuthSession::Exists()) { - Auth().api().clearWebPageRequests(); - } - cSetRecentStickers(RecentStickerPack()); - Global::SetStickerSets(Stickers::Sets()); - Global::SetStickerSetsOrder(Stickers::Order()); - Global::SetLastStickersUpdate(0); - Global::SetLastRecentStickersUpdate(0); - Global::SetFeaturedStickerSetsOrder(Stickers::Order()); - if (Global::FeaturedStickerSetsUnreadCount() != 0) { - Global::SetFeaturedStickerSetsUnreadCount(0); - Global::RefFeaturedStickerSetsUnreadCountChanged().notify(); - } - Global::SetLastFeaturedStickersUpdate(0); - Global::SetArchivedStickerSetsOrder(Stickers::Order()); - cSetSavedGifs(SavedGifs()); - cSetLastSavedGifsUpdate(0); - cSetReportSpamStatuses(ReportSpamStatuses()); - cSetAutoDownloadPhoto(0); - cSetAutoDownloadAudio(0); - cSetAutoDownloadGif(0); - ::photoItems.clear(); - ::documentItems.clear(); - ::webPageItems.clear(); - ::gameItems.clear(); - ::sharedContactItems.clear(); - ::gifItems.clear(); - lastPhotos.clear(); - lastPhotosMap.clear(); - ::self = nullptr; - Global::RefSelfChanged().notify(true); + for_const (auto peer, ::peersData) { delete peer; } + ::peersData.clear(); + for_const (auto game, ::gamesData) { delete game; } + ::gamesData.clear(); + for_const (auto webpage, ::webPagesData) { delete webpage; } + ::webPagesData.clear(); + for_const (auto photo, ::photosData) { delete photo; } + ::photosData.clear(); + for_const (auto document, ::documentsData) { delete document; } + ::documentsData.clear(); + + if (AuthSession::Exists()) { + Auth().api().clearWebPageRequests(); } - - void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency) { - ::dependentItems[dependency].insert(dependent); + cSetRecentStickers(RecentStickerPack()); + Global::SetStickerSets(Stickers::Sets()); + Global::SetStickerSetsOrder(Stickers::Order()); + Global::SetLastStickersUpdate(0); + Global::SetLastRecentStickersUpdate(0); + Global::SetFeaturedStickerSetsOrder(Stickers::Order()); + if (Global::FeaturedStickerSetsUnreadCount() != 0) { + Global::SetFeaturedStickerSetsUnreadCount(0); + Global::RefFeaturedStickerSetsUnreadCountChanged().notify(); } + Global::SetLastFeaturedStickersUpdate(0); + Global::SetArchivedStickerSetsOrder(Stickers::Order()); + cSetSavedGifs(SavedGifs()); + cSetLastSavedGifsUpdate(0); + cSetReportSpamStatuses(ReportSpamStatuses()); + cSetAutoDownloadPhoto(0); + cSetAutoDownloadAudio(0); + cSetAutoDownloadGif(0); + ::photoItems.clear(); + ::documentItems.clear(); + ::webPageItems.clear(); + ::gameItems.clear(); + ::sharedContactItems.clear(); + ::gifItems.clear(); + lastPhotos.clear(); + lastPhotosMap.clear(); + ::self = nullptr; + Global::RefSelfChanged().notify(true); +} - void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency) { - auto i = ::dependentItems.find(dependency); - if (i != ::dependentItems.cend()) { - i.value().remove(dependent); - if (i.value().isEmpty()) { - ::dependentItems.erase(i); - } +void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency) { + ::dependentItems[dependency].insert(dependent); +} + +void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency) { + auto i = ::dependentItems.find(dependency); + if (i != ::dependentItems.cend()) { + i.value().remove(dependent); + if (i.value().isEmpty()) { + ::dependentItems.erase(i); } } +} - void historyRegRandom(quint64 randomId, const FullMsgId &itemId) { - randomData.insert(randomId, itemId); - } +void historyRegRandom(quint64 randomId, const FullMsgId &itemId) { + randomData.insert(randomId, itemId); +} - void historyUnregRandom(quint64 randomId) { - randomData.remove(randomId); - } +void historyUnregRandom(quint64 randomId) { + randomData.remove(randomId); +} - FullMsgId histItemByRandom(quint64 randomId) { - RandomData::const_iterator i = randomData.constFind(randomId); - if (i != randomData.cend()) { - return i.value(); - } - return FullMsgId(); - } - - void historyRegSentData(quint64 randomId, const PeerId &peerId, const QString &text) { - sentData.insert(randomId, qMakePair(peerId, text)); - } - - void historyUnregSentData(quint64 randomId) { - sentData.remove(randomId); - } - - void histSentDataByItem(quint64 randomId, PeerId &peerId, QString &text) { - QPair d = sentData.value(randomId); - peerId = d.first; - text = d.second; - } - - void prepareCorners(RoundCorners index, qint32 radius, const QBrush &brush, const style::color *shadow = nullptr, QImage *cors = nullptr) { - Expects(::corners.size() > index); - qint32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor(); - QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4]; - { - Painter p(&rect); - PainterHighQualityEnabler hq(p); - - p.setCompositionMode(QPainter::CompositionMode_Source); - p.fillRect(QRect(0, 0, rect.width(), rect.height()), Qt::transparent); - p.setCompositionMode(QPainter::CompositionMode_SourceOver); - p.setPen(Qt::NoPen); - if (shadow) { - p.setBrush((*shadow)->b); - p.drawRoundedRect(0, s, r * 3, r * 3, r, r); - } - p.setBrush(brush); - p.drawRoundedRect(0, 0, r * 3, r * 3, r, r); - } - if (!cors) cors = localCors; - cors[0] = rect.copy(0, 0, r, r); - cors[1] = rect.copy(r * 2, 0, r, r); - cors[2] = rect.copy(0, r * 2, r, r + (shadow ? s : 0)); - cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0)); - if (index != SmallMaskCorners && index != LargeMaskCorners) { - for (int i = 0; i < 4; ++i) { - ::corners[index].p[i] = pixmapFromImageInPlace(std::move(cors[i])); - ::corners[index].p[i].setDevicePixelRatio(cRetinaFactor()); - } - } - } - - void tryFontFamily(QString &family, const QString &tryFamily) { - if (family.isEmpty()) { - if (!QFontInfo(QFont(tryFamily)).family().trimmed().compare(tryFamily, Qt::CaseInsensitive)) { - family = tryFamily; - } - } - } - - int msgRadius() { - static int MsgRadius = ([]() { - return st::historyMessageRadius; - auto minMsgHeight = (st::msgPadding.top() + st::msgFont->height + st::msgPadding.bottom()); - return minMsgHeight / 2; - })(); - return MsgRadius; - } - - void createMaskCorners() { - QImage mask[4]; - prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask); - for (int i = 0; i < 4; ++i) { - ::cornersMaskSmall[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied); - ::cornersMaskSmall[i].setDevicePixelRatio(cRetinaFactor()); - } - prepareCorners(LargeMaskCorners, msgRadius(), QColor(255, 255, 255), nullptr, mask); - for (int i = 0; i < 4; ++i) { - ::cornersMaskLarge[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied); - ::cornersMaskLarge[i].setDevicePixelRatio(cRetinaFactor()); - } - } - - void createPaletteCorners() { - prepareCorners(MenuCorners, st::buttonRadius, st::menuBg); - prepareCorners(BoxCorners, st::boxRadius, st::boxBg); - prepareCorners(BotKbOverCorners, st::dateRadius, st::msgBotKbOverBgAdd); - prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg); - prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected); - prepareCorners(SelectedOverlaySmallCorners, st::buttonRadius, st::msgSelectOverlay); - prepareCorners(SelectedOverlayLargeCorners, msgRadius(), st::msgSelectOverlay); - prepareCorners(DateCorners, st::dateRadius, st::msgDateImgBg); - prepareCorners(DateSelectedCorners, st::dateRadius, st::msgDateImgBgSelected); - prepareCorners(InShadowCorners, msgRadius(), st::msgInShadow); - prepareCorners(InSelectedShadowCorners, msgRadius(), st::msgInShadowSelected); - prepareCorners(ForwardCorners, msgRadius(), st::historyForwardChooseBg); - prepareCorners(MediaviewSaveCorners, st::mediaviewControllerRadius, st::mediaviewSaveMsgBg); - prepareCorners(EmojiHoverCorners, st::buttonRadius, st::emojiPanHover); - prepareCorners(StickerHoverCorners, st::buttonRadius, st::emojiPanHover); - prepareCorners(BotKeyboardCorners, st::buttonRadius, st::botKbBg); - prepareCorners(PhotoSelectOverlayCorners, st::buttonRadius, st::overviewPhotoSelectOverlay); - - prepareCorners(Doc1Corners, st::buttonRadius, st::msgFile1Bg); - prepareCorners(Doc2Corners, st::buttonRadius, st::msgFile2Bg); - prepareCorners(Doc3Corners, st::buttonRadius, st::msgFile3Bg); - prepareCorners(Doc4Corners, st::buttonRadius, st::msgFile4Bg); - - prepareCorners(MessageInCorners, msgRadius(), st::msgInBg, &st::msgInShadow); - prepareCorners(MessageInSelectedCorners, msgRadius(), st::msgInBgSelected, &st::msgInShadowSelected); - prepareCorners(MessageOutCorners, msgRadius(), st::msgOutBg, &st::msgOutShadow); - prepareCorners(MessageOutSelectedCorners, msgRadius(), st::msgOutBgSelected, &st::msgOutShadowSelected); - } - - void createCorners() { - ::corners.resize(RoundCornersCount); - createMaskCorners(); - createPaletteCorners(); - } - - void clearCorners() { - ::corners.clear(); - ::cornersMap.clear(); - } - - void initMedia() { - if (!::monofont) { - QString family; - tryFontFamily(family, qsl("Consolas")); - tryFontFamily(family, qsl("Liberation Mono")); - tryFontFamily(family, qsl("Menlo")); - tryFontFamily(family, qsl("Courier")); - if (family.isEmpty()) family = QFontDatabase::systemFont(QFontDatabase::FixedFont).family(); - ::monofont = style::font(st::normalFont->f.pixelSize(), 0, family); - } - Ui::Emoji::Init(); - if (!::emoji) { - ::emoji = new QPixmap(Ui::Emoji::Filename(Ui::Emoji::Index())); - if (cRetina()) ::emoji->setDevicePixelRatio(cRetinaFactor()); - } - if (!::emojiLarge) { - ::emojiLarge = new QPixmap(Ui::Emoji::Filename(Ui::Emoji::Index() + 1)); - if (cRetina()) ::emojiLarge->setDevicePixelRatio(cRetinaFactor()); - } - - createCorners(); - - using Update = Window::Theme::BackgroundUpdate; - static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) { - if (update.paletteChanged()) { - createPaletteCorners(); - - if (App::main()) { - App::main()->updateScrollColors(); - } - HistoryLayout::serviceColorsUpdated(); - } else if (update.type == Update::Type::New) { - prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg); - prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected); - - if (App::main()) { - App::main()->updateScrollColors(); - } - HistoryLayout::serviceColorsUpdated(); - } - }); - } - - void clearHistories() { - ClickHandler::clearActive(); - ClickHandler::unpressed(); - - if (AuthSession::Exists()) { - // Clear notifications to prevent any showNotification() calls while destroying items. - Auth().notifications().clearAllFast(); - } - - histories().clear(); - - clearStorageImages(); - cSetServerBackgrounds(WallPapers()); - - serviceImageCacheSize = imageCacheSize(); - } - - void deinitMedia() { - delete ::emoji; - ::emoji = nullptr; - delete ::emojiLarge; - ::emojiLarge = nullptr; - - clearCorners(); - - MainEmojiMap.clear(); - OtherEmojiMap.clear(); - - Data::clearGlobalStructures(); - - clearAllImages(); - } - - void hoveredItem(HistoryItem *item) { - ::hoveredItem = item; - } - - HistoryItem *hoveredItem() { - return ::hoveredItem; - } - - void pressedItem(HistoryItem *item) { - ::pressedItem = item; - } - - HistoryItem *pressedItem() { - return ::pressedItem; - } - - void hoveredLinkItem(HistoryItem *item) { - ::hoveredLinkItem = item; - } - - HistoryItem *hoveredLinkItem() { - return ::hoveredLinkItem; - } - - void pressedLinkItem(HistoryItem *item) { - ::pressedLinkItem = item; - } - - HistoryItem *pressedLinkItem() { - return ::pressedLinkItem; - } - - void contextItem(HistoryItem *item) { - ::contextItem = item; - } - - HistoryItem *contextItem() { - return ::contextItem; - } - - void mousedItem(HistoryItem *item) { - ::mousedItem = item; - } - - HistoryItem *mousedItem() { - return ::mousedItem; - } - - void clearMousedItems() { - hoveredItem(nullptr); - pressedItem(nullptr); - hoveredLinkItem(nullptr); - pressedLinkItem(nullptr); - contextItem(nullptr); - mousedItem(nullptr); - } - - const style::font &monofont() { - return ::monofont; - } - - const QPixmap &emoji() { - return *::emoji; - } - - const QPixmap &emojiLarge() { - return *::emojiLarge; - } - - const QPixmap &emojiSingle(EmojiPtr emoji, qint32 fontHeight) { - auto &map = (fontHeight == st::msgFont->height) ? MainEmojiMap : OtherEmojiMap[fontHeight]; - auto i = map.constFind(emoji->index()); - if (i == map.cend()) { - auto image = QImage(Ui::Emoji::Size() + st::emojiPadding * cIntRetinaFactor() * 2, fontHeight * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); - if (cRetina()) image.setDevicePixelRatio(cRetinaFactor()); - image.fill(Qt::transparent); - { - QPainter p(&image); - emojiDraw(p, emoji, st::emojiPadding * cIntRetinaFactor(), (fontHeight * cIntRetinaFactor() - Ui::Emoji::Size()) / 2); - } - i = map.insert(emoji->index(), App::pixmapFromImageInPlace(std::move(image))); - } +FullMsgId histItemByRandom(quint64 randomId) { + RandomData::const_iterator i = randomData.constFind(randomId); + if (i != randomData.cend()) { return i.value(); } + return FullMsgId(); +} - void checkImageCacheSize() { - qint64 nowImageCacheSize = imageCacheSize(); - if (nowImageCacheSize > serviceImageCacheSize + MemoryForImageCache) { - App::forgetMedia(); - serviceImageCacheSize = imageCacheSize(); +void historyRegSentData(quint64 randomId, const PeerId &peerId, const QString &text) { + sentData.insert(randomId, qMakePair(peerId, text)); +} + +void historyUnregSentData(quint64 randomId) { + sentData.remove(randomId); +} + +void histSentDataByItem(quint64 randomId, PeerId &peerId, QString &text) { + QPair d = sentData.value(randomId); + peerId = d.first; + text = d.second; +} + +void prepareCorners(RoundCorners index, qint32 radius, const QBrush &brush, const style::color *shadow = nullptr, + QImage *cors = nullptr) { + Expects(::corners.size() > index); + qint32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor(); + QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4]; + { + Painter p(&rect); + PainterHighQualityEnabler hq(p); + + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(QRect(0, 0, rect.width(), rect.height()), Qt::transparent); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); + p.setPen(Qt::NoPen); + if (shadow) { + p.setBrush((*shadow)->b); + p.drawRoundedRect(0, s, r * 3, r * 3, r, r); + } + p.setBrush(brush); + p.drawRoundedRect(0, 0, r * 3, r * 3, r, r); + } + if (!cors) cors = localCors; + cors[0] = rect.copy(0, 0, r, r); + cors[1] = rect.copy(r * 2, 0, r, r); + cors[2] = rect.copy(0, r * 2, r, r + (shadow ? s : 0)); + cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0)); + if (index != SmallMaskCorners && index != LargeMaskCorners) { + for (int i = 0; i < 4; ++i) { + ::corners[index].p[i] = pixmapFromImageInPlace(std::move(cors[i])); + ::corners[index].p[i].setDevicePixelRatio(cRetinaFactor()); } } +} - bool isValidPhone(QString phone) { - phone = phone.replace(QRegularExpression(qsl("[^\\d]")), QString()); - return phone.length() >= 8 || phone == qsl("777") || phone == qsl("333") || phone == qsl("111") || (phone.startsWith(qsl("42")) && (phone.length() == 2 || phone.length() == 5 || phone == qsl("4242"))); +void tryFontFamily(QString &family, const QString &tryFamily) { + if (family.isEmpty()) { + if (!QFontInfo(QFont(tryFamily)).family().trimmed().compare(tryFamily, Qt::CaseInsensitive)) { + family = tryFamily; + } + } +} + +int msgRadius() { + static int MsgRadius = ([]() { + return st::historyMessageRadius; + auto minMsgHeight = (st::msgPadding.top() + st::msgFont->height + st::msgPadding.bottom()); + return minMsgHeight / 2; + })(); + return MsgRadius; +} + +void createMaskCorners() { + QImage mask[4]; + prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask); + for (int i = 0; i < 4; ++i) { + ::cornersMaskSmall[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied); + ::cornersMaskSmall[i].setDevicePixelRatio(cRetinaFactor()); + } + prepareCorners(LargeMaskCorners, msgRadius(), QColor(255, 255, 255), nullptr, mask); + for (int i = 0; i < 4; ++i) { + ::cornersMaskLarge[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied); + ::cornersMaskLarge[i].setDevicePixelRatio(cRetinaFactor()); + } +} + +void createPaletteCorners() { + prepareCorners(MenuCorners, st::buttonRadius, st::menuBg); + prepareCorners(BoxCorners, st::boxRadius, st::boxBg); + prepareCorners(BotKbOverCorners, st::dateRadius, st::msgBotKbOverBgAdd); + prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg); + prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected); + prepareCorners(SelectedOverlaySmallCorners, st::buttonRadius, st::msgSelectOverlay); + prepareCorners(SelectedOverlayLargeCorners, msgRadius(), st::msgSelectOverlay); + prepareCorners(DateCorners, st::dateRadius, st::msgDateImgBg); + prepareCorners(DateSelectedCorners, st::dateRadius, st::msgDateImgBgSelected); + prepareCorners(InShadowCorners, msgRadius(), st::msgInShadow); + prepareCorners(InSelectedShadowCorners, msgRadius(), st::msgInShadowSelected); + prepareCorners(ForwardCorners, msgRadius(), st::historyForwardChooseBg); + prepareCorners(MediaviewSaveCorners, st::mediaviewControllerRadius, st::mediaviewSaveMsgBg); + prepareCorners(EmojiHoverCorners, st::buttonRadius, st::emojiPanHover); + prepareCorners(StickerHoverCorners, st::buttonRadius, st::emojiPanHover); + prepareCorners(BotKeyboardCorners, st::buttonRadius, st::botKbBg); + prepareCorners(PhotoSelectOverlayCorners, st::buttonRadius, st::overviewPhotoSelectOverlay); + + prepareCorners(Doc1Corners, st::buttonRadius, st::msgFile1Bg); + prepareCorners(Doc2Corners, st::buttonRadius, st::msgFile2Bg); + prepareCorners(Doc3Corners, st::buttonRadius, st::msgFile3Bg); + prepareCorners(Doc4Corners, st::buttonRadius, st::msgFile4Bg); + + prepareCorners(MessageInCorners, msgRadius(), st::msgInBg, &st::msgInShadow); + prepareCorners(MessageInSelectedCorners, msgRadius(), st::msgInBgSelected, &st::msgInShadowSelected); + prepareCorners(MessageOutCorners, msgRadius(), st::msgOutBg, &st::msgOutShadow); + prepareCorners(MessageOutSelectedCorners, msgRadius(), st::msgOutBgSelected, &st::msgOutShadowSelected); +} + +void createCorners() { + ::corners.resize(RoundCornersCount); + createMaskCorners(); + createPaletteCorners(); +} + +void clearCorners() { + ::corners.clear(); + ::cornersMap.clear(); +} + +void initMedia() { + if (!::monofont) { + QString family; + tryFontFamily(family, qsl("Consolas")); + tryFontFamily(family, qsl("Liberation Mono")); + tryFontFamily(family, qsl("Menlo")); + tryFontFamily(family, qsl("Courier")); + if (family.isEmpty()) family = QFontDatabase::systemFont(QFontDatabase::FixedFont).family(); + ::monofont = style::font(st::normalFont->f.pixelSize(), 0, family); + } + Ui::Emoji::Init(); + if (!::emoji) { + ::emoji = new QPixmap(Ui::Emoji::Filename(Ui::Emoji::Index())); + if (cRetina()) ::emoji->setDevicePixelRatio(cRetinaFactor()); + } + if (!::emojiLarge) { + ::emojiLarge = new QPixmap(Ui::Emoji::Filename(Ui::Emoji::Index() + 1)); + if (cRetina()) ::emojiLarge->setDevicePixelRatio(cRetinaFactor()); } - void quit() { - if (quitting()) return; - setLaunchState(QuitRequested); + createCorners(); - if (auto window = wnd()) { - if (!Sandbox::isSavingSession()) { - window->hide(); + using Update = Window::Theme::BackgroundUpdate; + static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) { + if (update.paletteChanged()) { + createPaletteCorners(); + + if (App::main()) { + App::main()->updateScrollColors(); } + HistoryLayout::serviceColorsUpdated(); + } else if (update.type == Update::Type::New) { + prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg); + prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected); + + if (App::main()) { + App::main()->updateScrollColors(); + } + HistoryLayout::serviceColorsUpdated(); } - if (auto mainwidget = main()) { - mainwidget->saveDraftToCloud(); - } - Messenger::QuitAttempt(); + }); +} + +void clearHistories() { + ClickHandler::clearActive(); + ClickHandler::unpressed(); + + if (AuthSession::Exists()) { + // Clear notifications to prevent any showNotification() calls while destroying items. + Auth().notifications().clearAllFast(); } - bool quitting() { - return _launchState != Launched; - } + histories().clear(); - LaunchState launchState() { - return _launchState; - } + clearStorageImages(); + cSetServerBackgrounds(WallPapers()); - void setLaunchState(LaunchState state) { - _launchState = state; - } + serviceImageCacheSize = imageCacheSize(); +} - void restart() { - cSetRestarting(true); - cSetRestartingToSettings(true); - App::quit(); - } +void deinitMedia() { + delete ::emoji; + ::emoji = nullptr; + delete ::emojiLarge; + ::emojiLarge = nullptr; - QImage readImage(QByteArray data, QByteArray *format, bool opaque, bool *animated) { - QByteArray tmpFormat; - QImage result; - QBuffer buffer(&data); - if (!format) { - format = &tmpFormat; - } + clearCorners(); + + MainEmojiMap.clear(); + OtherEmojiMap.clear(); + + Data::clearGlobalStructures(); + + clearAllImages(); +} + +void hoveredItem(HistoryItem *item) { + ::hoveredItem = item; +} + +HistoryItem *hoveredItem() { + return ::hoveredItem; +} + +void pressedItem(HistoryItem *item) { + ::pressedItem = item; +} + +HistoryItem *pressedItem() { + return ::pressedItem; +} + +void hoveredLinkItem(HistoryItem *item) { + ::hoveredLinkItem = item; +} + +HistoryItem *hoveredLinkItem() { + return ::hoveredLinkItem; +} + +void pressedLinkItem(HistoryItem *item) { + ::pressedLinkItem = item; +} + +HistoryItem *pressedLinkItem() { + return ::pressedLinkItem; +} + +void contextItem(HistoryItem *item) { + ::contextItem = item; +} + +HistoryItem *contextItem() { + return ::contextItem; +} + +void mousedItem(HistoryItem *item) { + ::mousedItem = item; +} + +HistoryItem *mousedItem() { + return ::mousedItem; +} + +void clearMousedItems() { + hoveredItem(nullptr); + pressedItem(nullptr); + hoveredLinkItem(nullptr); + pressedLinkItem(nullptr); + contextItem(nullptr); + mousedItem(nullptr); +} + +const style::font &monofont() { + return ::monofont; +} + +const QPixmap &emoji() { + return *::emoji; +} + +const QPixmap &emojiLarge() { + return *::emojiLarge; +} + +const QPixmap &emojiSingle(EmojiPtr emoji, qint32 fontHeight) { + auto &map = (fontHeight == st::msgFont->height) ? MainEmojiMap : OtherEmojiMap[fontHeight]; + auto i = map.constFind(emoji->index()); + if (i == map.cend()) { + auto image = QImage(Ui::Emoji::Size() + st::emojiPadding * cIntRetinaFactor() * 2, + fontHeight * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + if (cRetina()) image.setDevicePixelRatio(cRetinaFactor()); + image.fill(Qt::transparent); { - QImageReader reader(&buffer, *format); -#ifndef OS_MAC_OLD - reader.setAutoTransform(true); -#endif // OS_MAC_OLD - if (animated) *animated = reader.supportsAnimation() && reader.imageCount() > 1; - QByteArray fmt = reader.format(); - if (!fmt.isEmpty()) *format = fmt; - if (!reader.read(&result)) { - return QImage(); - } - fmt = reader.format(); - if (!fmt.isEmpty()) *format = fmt; + QPainter p(&image); + emojiDraw(p, emoji, st::emojiPadding * cIntRetinaFactor(), + (fontHeight * cIntRetinaFactor() - Ui::Emoji::Size()) / 2); } - buffer.seek(0); - auto fmt = QString::fromUtf8(*format).toLower(); - if (fmt == "jpg" || fmt == "jpeg") { -#ifdef OS_MAC_OLD - if (auto exifData = exif_data_new_from_data((const uchar*)(data.constData()), data.size())) { - auto byteOrder = exif_data_get_byte_order(exifData); - if (auto exifEntry = exif_data_get_entry(exifData, EXIF_TAG_ORIENTATION)) { - auto orientationFix = [exifEntry, byteOrder] { - auto orientation = exif_get_short(exifEntry->data, byteOrder); - switch (orientation) { - case 2: return QTransform(-1, 0, 0, 1, 0, 0); - case 3: return QTransform(-1, 0, 0, -1, 0, 0); - case 4: return QTransform(1, 0, 0, -1, 0, 0); - case 5: return QTransform(0, -1, -1, 0, 0, 0); - case 6: return QTransform(0, 1, -1, 0, 0, 0); - case 7: return QTransform(0, 1, 1, 0, 0, 0); - case 8: return QTransform(0, -1, 1, 0, 0, 0); - } - return QTransform(); - }; - result = result.transformed(orientationFix()); - } - exif_data_free(exifData); - } -#endif // OS_MAC_OLD - } else if (opaque) { - result = Images::prepareOpaque(std::move(result)); - } - return result; + i = map.insert(emoji->index(), App::pixmapFromImageInPlace(std::move(image))); } + return i.value(); +} - QImage readImage(const QString &file, QByteArray *format, bool opaque, bool *animated, QByteArray *content) { - QFile f(file); - if (f.size() > kImageSizeLimit || !f.open(QIODevice::ReadOnly)) { - if (animated) *animated = false; +void checkImageCacheSize() { + qint64 nowImageCacheSize = imageCacheSize(); + if (nowImageCacheSize > serviceImageCacheSize + MemoryForImageCache) { + App::forgetMedia(); + serviceImageCacheSize = imageCacheSize(); + } +} + +bool isValidPhone(QString phone) { + phone = phone.replace(QRegularExpression(qsl("[^\\d]")), QString()); + return phone.length() >= 8 || phone == qsl("777") || phone == qsl("333") || phone == qsl("111") || + (phone.startsWith(qsl("42")) && (phone.length() == 2 || phone.length() == 5 || phone == qsl("4242"))); +} + +void quit() { + if (quitting()) return; + setLaunchState(QuitRequested); + + if (auto window = wnd()) { + if (!Sandbox::isSavingSession()) { + window->hide(); + } + } + if (auto mainwidget = main()) { + mainwidget->saveDraftToCloud(); + } + Messenger::QuitAttempt(); +} + +bool quitting() { + return _launchState != Launched; +} + +LaunchState launchState() { + return _launchState; +} + +void setLaunchState(LaunchState state) { + _launchState = state; +} + +void restart() { + cSetRestarting(true); + cSetRestartingToSettings(true); + App::quit(); +} + +QImage readImage(QByteArray data, QByteArray *format, bool opaque, bool *animated) { + QByteArray tmpFormat; + QImage result; + QBuffer buffer(&data); + if (!format) { + format = &tmpFormat; + } + { + QImageReader reader(&buffer, *format); +#ifndef OS_MAC_OLD + reader.setAutoTransform(true); +#endif // OS_MAC_OLD + if (animated) *animated = reader.supportsAnimation() && reader.imageCount() > 1; + QByteArray fmt = reader.format(); + if (!fmt.isEmpty()) *format = fmt; + if (!reader.read(&result)) { return QImage(); } - auto imageBytes = f.readAll(); - auto result = readImage(imageBytes, format, opaque, animated); - if (content && !result.isNull()) { - *content = imageBytes; - } - return result; + fmt = reader.format(); + if (!fmt.isEmpty()) *format = fmt; } - - QPixmap pixmapFromImageInPlace(QImage &&image) { - return QPixmap::fromImage(std::move(image), Qt::ColorOnly); - } - - void regPhotoItem(PhotoData *data, HistoryItem *item) { - ::photoItems[data].insert(item); - } - - void unregPhotoItem(PhotoData *data, HistoryItem *item) { - ::photoItems[data].remove(item); - } - - const PhotoItems &photoItems() { - return ::photoItems; - } - - const PhotosData &photosData() { - return ::photosData; - } - - void regDocumentItem(DocumentData *data, HistoryItem *item) { - ::documentItems[data].insert(item); - } - - void unregDocumentItem(DocumentData *data, HistoryItem *item) { - ::documentItems[data].remove(item); - } - - const DocumentItems &documentItems() { - return ::documentItems; - } - - const DocumentsData &documentsData() { - return ::documentsData; - } - - void regWebPageItem(WebPageData *data, HistoryItem *item) { - ::webPageItems[data].insert(item); - } - - void unregWebPageItem(WebPageData *data, HistoryItem *item) { - ::webPageItems[data].remove(item); - } - - const WebPageItems &webPageItems() { - return ::webPageItems; - } - - void regGameItem(GameData *data, HistoryItem *item) { - ::gameItems[data].insert(item); - } - - void unregGameItem(GameData *data, HistoryItem *item) { - ::gameItems[data].remove(item); - } - - const GameItems &gameItems() { - return ::gameItems; - } - - void regSharedContactItem(qint32 userId, HistoryItem *item) { - auto user = App::userLoaded(userId); - auto canShareThisContact = user ? user->canShareThisContact() : false; - ::sharedContactItems[userId].insert(item); - if (canShareThisContact != (user ? user->canShareThisContact() : false)) { - Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserCanShareContact); - } - } - - void unregSharedContactItem(qint32 userId, HistoryItem *item) { - auto user = App::userLoaded(userId); - auto canShareThisContact = user ? user->canShareThisContact() : false; - ::sharedContactItems[userId].remove(item); - if (canShareThisContact != (user ? user->canShareThisContact() : false)) { - Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserCanShareContact); - } - } - - const SharedContactItems &sharedContactItems() { - return ::sharedContactItems; - } - - void regGifItem(Media::Clip::Reader *reader, HistoryItem *item) { - ::gifItems.insert(reader, item); - } - - void unregGifItem(Media::Clip::Reader *reader) { - ::gifItems.remove(reader); - } - - void stopGifItems() { - if (!::gifItems.isEmpty()) { - auto gifs = ::gifItems; - for_const (auto item, gifs) { - if (auto media = item->getMedia()) { - if (!media->isRoundVideoPlaying()) { - media->stopInline(); + buffer.seek(0); + auto fmt = QString::fromUtf8(*format).toLower(); + if (fmt == "jpg" || fmt == "jpeg") { +#ifdef OS_MAC_OLD + if (auto exifData = exif_data_new_from_data((const uchar *)(data.constData()), data.size())) { + auto byteOrder = exif_data_get_byte_order(exifData); + if (auto exifEntry = exif_data_get_entry(exifData, EXIF_TAG_ORIENTATION)) { + auto orientationFix = [exifEntry, byteOrder] { + auto orientation = exif_get_short(exifEntry->data, byteOrder); + switch (orientation) { + case 2: return QTransform(-1, 0, 0, 1, 0, 0); + case 3: return QTransform(-1, 0, 0, -1, 0, 0); + case 4: return QTransform(1, 0, 0, -1, 0, 0); + case 5: return QTransform(0, -1, -1, 0, 0, 0); + case 6: return QTransform(0, 1, -1, 0, 0, 0); + case 7: return QTransform(0, 1, 1, 0, 0, 0); + case 8: return QTransform(0, -1, 1, 0, 0, 0); } + return QTransform(); + }; + result = result.transformed(orientationFix()); + } + exif_data_free(exifData); + } +#endif // OS_MAC_OLD + } else if (opaque) { + result = Images::prepareOpaque(std::move(result)); + } + return result; +} + +QImage readImage(const QString &file, QByteArray *format, bool opaque, bool *animated, QByteArray *content) { + QFile f(file); + if (f.size() > kImageSizeLimit || !f.open(QIODevice::ReadOnly)) { + if (animated) *animated = false; + return QImage(); + } + auto imageBytes = f.readAll(); + auto result = readImage(imageBytes, format, opaque, animated); + if (content && !result.isNull()) { + *content = imageBytes; + } + return result; +} + +QPixmap pixmapFromImageInPlace(QImage &&image) { + return QPixmap::fromImage(std::move(image), Qt::ColorOnly); +} + +void regPhotoItem(PhotoData *data, HistoryItem *item) { + ::photoItems[data].insert(item); +} + +void unregPhotoItem(PhotoData *data, HistoryItem *item) { + ::photoItems[data].remove(item); +} + +const PhotoItems &photoItems() { + return ::photoItems; +} + +const PhotosData &photosData() { + return ::photosData; +} + +void regDocumentItem(DocumentData *data, HistoryItem *item) { + ::documentItems[data].insert(item); +} + +void unregDocumentItem(DocumentData *data, HistoryItem *item) { + ::documentItems[data].remove(item); +} + +const DocumentItems &documentItems() { + return ::documentItems; +} + +const DocumentsData &documentsData() { + return ::documentsData; +} + +void regWebPageItem(WebPageData *data, HistoryItem *item) { + ::webPageItems[data].insert(item); +} + +void unregWebPageItem(WebPageData *data, HistoryItem *item) { + ::webPageItems[data].remove(item); +} + +const WebPageItems &webPageItems() { + return ::webPageItems; +} + +void regGameItem(GameData *data, HistoryItem *item) { + ::gameItems[data].insert(item); +} + +void unregGameItem(GameData *data, HistoryItem *item) { + ::gameItems[data].remove(item); +} + +const GameItems &gameItems() { + return ::gameItems; +} + +void regSharedContactItem(qint32 userId, HistoryItem *item) { + auto user = App::userLoaded(userId); + auto canShareThisContact = user ? user->canShareThisContact() : false; + ::sharedContactItems[userId].insert(item); + if (canShareThisContact != (user ? user->canShareThisContact() : false)) { + Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserCanShareContact); + } +} + +void unregSharedContactItem(qint32 userId, HistoryItem *item) { + auto user = App::userLoaded(userId); + auto canShareThisContact = user ? user->canShareThisContact() : false; + ::sharedContactItems[userId].remove(item); + if (canShareThisContact != (user ? user->canShareThisContact() : false)) { + Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserCanShareContact); + } +} + +const SharedContactItems &sharedContactItems() { + return ::sharedContactItems; +} + +void regGifItem(Media::Clip::Reader *reader, HistoryItem *item) { + ::gifItems.insert(reader, item); +} + +void unregGifItem(Media::Clip::Reader *reader) { + ::gifItems.remove(reader); +} + +void stopGifItems() { + if (!::gifItems.isEmpty()) { + auto gifs = ::gifItems; + for_const (auto item, gifs) { + if (auto media = item->getMedia()) { + if (!media->isRoundVideoPlaying()) { + media->stopInline(); } } } } +} - QString phoneFromSharedContact(qint32 userId) { - auto i = ::sharedContactItems.constFind(userId); - if (i != ::sharedContactItems.cend() && !i->isEmpty()) { - if (auto media = (*i->cbegin())->getMedia()) { - if (media->type() == MediaTypeContact) { - return static_cast(media)->phone(); - } +QString phoneFromSharedContact(qint32 userId) { + auto i = ::sharedContactItems.constFind(userId); + if (i != ::sharedContactItems.cend() && !i->isEmpty()) { + if (auto media = (*i->cbegin())->getMedia()) { + if (media->type() == MediaTypeContact) { + return static_cast(media)->phone(); } } - return QString(); } + return QString(); +} - void regMuted(PeerData *peer, qint32 changeIn) { - ::mutedPeers.insert(peer, true); - if (App::main()) App::main()->updateMutedIn(changeIn); - } +void regMuted(PeerData *peer, qint32 changeIn) { + ::mutedPeers.insert(peer, true); + if (App::main()) App::main()->updateMutedIn(changeIn); +} - void unregMuted(PeerData *peer) { - ::mutedPeers.remove(peer); - } +void unregMuted(PeerData *peer) { + ::mutedPeers.remove(peer); +} - void updateMuted() { - qint32 changeInMin = 0; - for (MutedPeers::iterator i = ::mutedPeers.begin(); i != ::mutedPeers.end();) { - qint32 changeIn = 0; - History *h = App::history(i.key()->id); - if (isNotifyMuted(i.key()->notify, &changeIn)) { - h->setMute(true); - if (changeIn && (!changeInMin || changeIn < changeInMin)) { - changeInMin = changeIn; - } - ++i; - } else { - h->setMute(false); - i = ::mutedPeers.erase(i); +void updateMuted() { + qint32 changeInMin = 0; + for (MutedPeers::iterator i = ::mutedPeers.begin(); i != ::mutedPeers.end();) { + qint32 changeIn = 0; + History *h = App::history(i.key()->id); + if (isNotifyMuted(i.key()->notify, &changeIn)) { + h->setMute(true); + if (changeIn && (!changeInMin || changeIn < changeInMin)) { + changeInMin = changeIn; } + ++i; + } else { + h->setMute(false); + i = ::mutedPeers.erase(i); } - if (changeInMin) App::main()->updateMutedIn(changeInMin); } + if (changeInMin) App::main()->updateMutedIn(changeInMin); +} - void setProxySettings(QNetworkAccessManager &manager) { +void setProxySettings(QNetworkAccessManager &manager) { #ifndef TDESKTOP_DISABLE_NETWORK_PROXY - manager.setProxy(getHttpProxySettings()); + manager.setProxy(getHttpProxySettings()); #endif // !TDESKTOP_DISABLE_NETWORK_PROXY - } +} #ifndef TDESKTOP_DISABLE_NETWORK_PROXY - QNetworkProxy getHttpProxySettings() { - const ProxyData *proxy = nullptr; - if (Global::started()) { - proxy = (Global::ConnectionType() == dbictHttpProxy) ? (&Global::ConnectionProxy()) : nullptr; - } else { - proxy = Sandbox::PreLaunchProxy().host.isEmpty() ? nullptr : (&Sandbox::PreLaunchProxy()); - } - if (proxy) { - return QNetworkProxy(QNetworkProxy::HttpProxy, proxy->host, proxy->port, proxy->user, proxy->password); - } - return QNetworkProxy(QNetworkProxy::DefaultProxy); +QNetworkProxy getHttpProxySettings() { + const ProxyData *proxy = nullptr; + if (Global::started()) { + proxy = (Global::ConnectionType() == dbictHttpProxy) ? (&Global::ConnectionProxy()) : nullptr; + } else { + proxy = Sandbox::PreLaunchProxy().host.isEmpty() ? nullptr : (&Sandbox::PreLaunchProxy()); } + if (proxy) { + return QNetworkProxy(QNetworkProxy::HttpProxy, proxy->host, proxy->port, proxy->user, proxy->password); + } + return QNetworkProxy(QNetworkProxy::DefaultProxy); +} #endif // !TDESKTOP_DISABLE_NETWORK_PROXY - void setProxySettings(QTcpSocket &socket) { +void setProxySettings(QTcpSocket &socket) { #ifndef TDESKTOP_DISABLE_NETWORK_PROXY - if (Global::ConnectionType() == dbictTcpProxy) { - auto &p = Global::ConnectionProxy(); - socket.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, p.host, p.port, p.user, p.password)); - } else { - socket.setProxy(QNetworkProxy(QNetworkProxy::NoProxy)); - } -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY + if (Global::ConnectionType() == dbictTcpProxy) { + auto &p = Global::ConnectionProxy(); + socket.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, p.host, p.port, p.user, p.password)); + } else { + socket.setProxy(QNetworkProxy(QNetworkProxy::NoProxy)); } +#endif // !TDESKTOP_DISABLE_NETWORK_PROXY +} - void complexAdjustRect(ImageRoundCorners corners, QRect &rect, RectParts &parts) { - if (corners & ImageRoundCorner::TopLeft) { - if (!(corners & ImageRoundCorner::BottomLeft)) { - parts = RectPart::NoTopBottom | RectPart::FullTop; - rect.setHeight(rect.height() + msgRadius()); - } - } else if (corners & ImageRoundCorner::BottomLeft) { - parts = RectPart::NoTopBottom | RectPart::FullBottom; - rect.setTop(rect.y() - msgRadius()); - } else { - parts = RectPart::NoTopBottom; - rect.setTop(rect.y() - msgRadius()); +void complexAdjustRect(ImageRoundCorners corners, QRect &rect, RectParts &parts) { + if (corners & ImageRoundCorner::TopLeft) { + if (!(corners & ImageRoundCorner::BottomLeft)) { + parts = RectPart::NoTopBottom | RectPart::FullTop; rect.setHeight(rect.height() + msgRadius()); } + } else if (corners & ImageRoundCorner::BottomLeft) { + parts = RectPart::NoTopBottom | RectPart::FullBottom; + rect.setTop(rect.y() - msgRadius()); + } else { + parts = RectPart::NoTopBottom; + rect.setTop(rect.y() - msgRadius()); + rect.setHeight(rect.height() + msgRadius()); } - - void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners) { - if (radius == ImageRoundRadius::Ellipse) { - PainterHighQualityEnabler hq(p); - p.setPen(Qt::NoPen); - p.setBrush(p.textPalette().selectOverlay); - p.drawEllipse(rect); - } else { - auto overlayCorners = (radius == ImageRoundRadius::Small) ? SelectedOverlaySmallCorners : SelectedOverlayLargeCorners; - auto overlayParts = RectPart::Full | RectPart::None; - if (radius == ImageRoundRadius::Large) { - complexAdjustRect(corners, rect, overlayParts); - } - roundRect(p, rect, p.textPalette().selectOverlay, overlayCorners, nullptr, overlayParts); - } - } - - void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners) { - auto parts = RectPart::Full | RectPart::None; - complexAdjustRect(corners, rect, parts); - roundRect(p, rect, st::msgInBg, MessageInCorners, nullptr, parts); - } - - QImage *cornersMask(ImageRoundRadius radius) { - switch (radius) { - case ImageRoundRadius::Large: return ::cornersMaskLarge; - case ImageRoundRadius::Small: - default: break; - } - return ::cornersMaskSmall; - } - - void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) { - auto cornerWidth = corner.p[0].width() / cIntRetinaFactor(); - auto cornerHeight = corner.p[0].height() / cIntRetinaFactor(); - if (w < 2 * cornerWidth || h < 2 * cornerHeight) return; - if (w > 2 * cornerWidth) { - if (parts & RectPart::Top) { - p.fillRect(x + cornerWidth, y, w - 2 * cornerWidth, cornerHeight, bg); - } - if (parts & RectPart::Bottom) { - p.fillRect(x + cornerWidth, y + h - cornerHeight, w - 2 * cornerWidth, cornerHeight, bg); - if (shadow) { - p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, *shadow); - } - } - } - if (h > 2 * cornerHeight) { - if ((parts & RectPart::NoTopBottom) == RectPart::NoTopBottom) { - p.fillRect(x, y + cornerHeight, w, h - 2 * cornerHeight, bg); - } else { - if (parts & RectPart::Left) { - p.fillRect(x, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg); - } - if ((parts & RectPart::Center) && w > 2 * cornerWidth) { - p.fillRect(x + cornerWidth, y + cornerHeight, w - 2 * cornerWidth, h - 2 * cornerHeight, bg); - } - if (parts & RectPart::Right) { - p.fillRect(x + w - cornerWidth, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg); - } - } - } - if (parts & RectPart::TopLeft) { - p.drawPixmap(x, y, corner.p[0]); - } - if (parts & RectPart::TopRight) { - p.drawPixmap(x + w - cornerWidth, y, corner.p[1]); - } - if (parts & RectPart::BottomLeft) { - p.drawPixmap(x, y + h - cornerHeight, corner.p[2]); - } - if (parts & RectPart::BottomRight) { - p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight, corner.p[3]); - } - } - - void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, RoundCorners index, const style::color *shadow, RectParts parts) { - roundRect(p, x, y, w, h, bg, ::corners[index], shadow, parts); - } - - void roundShadow(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color shadow, RoundCorners index, RectParts parts) { - auto &corner = ::corners[index]; - auto cornerWidth = corner.p[0].width() / cIntRetinaFactor(); - auto cornerHeight = corner.p[0].height() / cIntRetinaFactor(); - if (parts & RectPart::Bottom) { - p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, shadow); - } - if (parts & RectPart::BottomLeft) { - p.fillRect(x, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow); - p.drawPixmap(x, y + h - cornerHeight + st::msgShadow, corner.p[2]); - } - if (parts & RectPart::BottomRight) { - p.fillRect(x + w - cornerWidth, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow); - p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight + st::msgShadow, corner.p[3]); - } - } - - void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, ImageRoundRadius radius, RectParts parts) { - auto colorKey = ((quint32(bg->c.alpha()) & 0xFF) << 24) | ((quint32(bg->c.red()) & 0xFF) << 16) | ((quint32(bg->c.green()) & 0xFF) << 8) | ((quint32(bg->c.blue()) & 0xFF) << 24); - auto i = cornersMap.find(colorKey); - if (i == cornersMap.cend()) { - QImage images[4]; - switch (radius) { - case ImageRoundRadius::Small: prepareCorners(SmallMaskCorners, st::buttonRadius, bg, nullptr, images); break; - case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, msgRadius(), bg, nullptr, images); break; - default: p.fillRect(x, y, w, h, bg); return; - } - - CornersPixmaps pixmaps; - for (int j = 0; j < 4; ++j) { - pixmaps.p[j] = pixmapFromImageInPlace(std::move(images[j])); - pixmaps.p[j].setDevicePixelRatio(cRetinaFactor()); - } - i = cornersMap.insert(colorKey, pixmaps); - } - roundRect(p, x, y, w, h, bg, i.value(), nullptr, parts); - } - - WallPapers gServerBackgrounds; - } + +void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners) { + if (radius == ImageRoundRadius::Ellipse) { + PainterHighQualityEnabler hq(p); + p.setPen(Qt::NoPen); + p.setBrush(p.textPalette().selectOverlay); + p.drawEllipse(rect); + } else { + auto overlayCorners = + (radius == ImageRoundRadius::Small) ? SelectedOverlaySmallCorners : SelectedOverlayLargeCorners; + auto overlayParts = RectPart::Full | RectPart::None; + if (radius == ImageRoundRadius::Large) { + complexAdjustRect(corners, rect, overlayParts); + } + roundRect(p, rect, p.textPalette().selectOverlay, overlayCorners, nullptr, overlayParts); + } +} + +void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners) { + auto parts = RectPart::Full | RectPart::None; + complexAdjustRect(corners, rect, parts); + roundRect(p, rect, st::msgInBg, MessageInCorners, nullptr, parts); +} + +QImage *cornersMask(ImageRoundRadius radius) { + switch (radius) { + case ImageRoundRadius::Large: return ::cornersMaskLarge; + case ImageRoundRadius::Small: + default: break; + } + return ::cornersMaskSmall; +} + +void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, const CornersPixmaps &corner, + const style::color *shadow, RectParts parts) { + auto cornerWidth = corner.p[0].width() / cIntRetinaFactor(); + auto cornerHeight = corner.p[0].height() / cIntRetinaFactor(); + if (w < 2 * cornerWidth || h < 2 * cornerHeight) return; + if (w > 2 * cornerWidth) { + if (parts & RectPart::Top) { + p.fillRect(x + cornerWidth, y, w - 2 * cornerWidth, cornerHeight, bg); + } + if (parts & RectPart::Bottom) { + p.fillRect(x + cornerWidth, y + h - cornerHeight, w - 2 * cornerWidth, cornerHeight, bg); + if (shadow) { + p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, *shadow); + } + } + } + if (h > 2 * cornerHeight) { + if ((parts & RectPart::NoTopBottom) == RectPart::NoTopBottom) { + p.fillRect(x, y + cornerHeight, w, h - 2 * cornerHeight, bg); + } else { + if (parts & RectPart::Left) { + p.fillRect(x, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg); + } + if ((parts & RectPart::Center) && w > 2 * cornerWidth) { + p.fillRect(x + cornerWidth, y + cornerHeight, w - 2 * cornerWidth, h - 2 * cornerHeight, bg); + } + if (parts & RectPart::Right) { + p.fillRect(x + w - cornerWidth, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg); + } + } + } + if (parts & RectPart::TopLeft) { + p.drawPixmap(x, y, corner.p[0]); + } + if (parts & RectPart::TopRight) { + p.drawPixmap(x + w - cornerWidth, y, corner.p[1]); + } + if (parts & RectPart::BottomLeft) { + p.drawPixmap(x, y + h - cornerHeight, corner.p[2]); + } + if (parts & RectPart::BottomRight) { + p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight, corner.p[3]); + } +} + +void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, RoundCorners index, + const style::color *shadow, RectParts parts) { + roundRect(p, x, y, w, h, bg, ::corners[index], shadow, parts); +} + +void roundShadow(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color shadow, RoundCorners index, + RectParts parts) { + auto &corner = ::corners[index]; + auto cornerWidth = corner.p[0].width() / cIntRetinaFactor(); + auto cornerHeight = corner.p[0].height() / cIntRetinaFactor(); + if (parts & RectPart::Bottom) { + p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, shadow); + } + if (parts & RectPart::BottomLeft) { + p.fillRect(x, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow); + p.drawPixmap(x, y + h - cornerHeight + st::msgShadow, corner.p[2]); + } + if (parts & RectPart::BottomRight) { + p.fillRect(x + w - cornerWidth, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow); + p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight + st::msgShadow, corner.p[3]); + } +} + +void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, ImageRoundRadius radius, + RectParts parts) { + auto colorKey = ((quint32(bg->c.alpha()) & 0xFF) << 24) | ((quint32(bg->c.red()) & 0xFF) << 16) | + ((quint32(bg->c.green()) & 0xFF) << 8) | ((quint32(bg->c.blue()) & 0xFF) << 24); + auto i = cornersMap.find(colorKey); + if (i == cornersMap.cend()) { + QImage images[4]; + switch (radius) { + case ImageRoundRadius::Small: prepareCorners(SmallMaskCorners, st::buttonRadius, bg, nullptr, images); break; + case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, msgRadius(), bg, nullptr, images); break; + default: p.fillRect(x, y, w, h, bg); return; + } + + CornersPixmaps pixmaps; + for (int j = 0; j < 4; ++j) { + pixmaps.p[j] = pixmapFromImageInPlace(std::move(images[j])); + pixmaps.p[j].setDevicePixelRatio(cRetinaFactor()); + } + i = cornersMap.insert(colorKey, pixmaps); + } + roundRect(p, x, y, w, h, bg, i.value(), nullptr, parts); +} + +WallPapers gServerBackgrounds; + +} // namespace App diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 4a1516610..86b042575 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -20,288 +20,304 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include #include +#include -#include "ui/animation.h" #include "core/basic_types.h" #include "history/history.h" #include "history/history_item.h" #include "layout.h" #include "media/media_clip_reader.h" +#include "ui/animation.h" class Messenger; class MainWindow; class MainWidget; -using HistoryItemsMap = OrderedSet; -using PhotoItems = QHash; -using DocumentItems = QHash; -using WebPageItems = QHash; -using GameItems = QHash; +using HistoryItemsMap = OrderedSet; +using PhotoItems = QHash; +using DocumentItems = QHash; +using WebPageItems = QHash; +using GameItems = QHash; using SharedContactItems = QHash; -using GifItems = QHash; +using GifItems = QHash; -using PhotosData = QHash; -using DocumentsData = QHash; +using PhotosData = QHash; +using DocumentsData = QHash; class LocationCoords; struct LocationData; namespace App { - MainWindow *wnd(); - MainWidget *main(); - bool passcoded(); +MainWindow *wnd(); +MainWidget *main(); +bool passcoded(); - void logOut(); +void logOut(); - QString formatPhone(QString phone); +QString formatPhone(QString phone); - TimeId onlineForSort(UserData *user, TimeId now); - qint32 onlineWillChangeIn(UserData *user, TimeId now); - qint32 onlineWillChangeIn(TimeId online, TimeId now); - QString onlineText(UserData *user, TimeId now, bool precise = false); - QString onlineText(TimeId online, TimeId now, bool precise = false); - bool onlineColorUse(UserData *user, TimeId now); - bool onlineColorUse(TimeId online, TimeId now); +TimeId onlineForSort(UserData *user, TimeId now); +qint32 onlineWillChangeIn(UserData *user, TimeId now); +qint32 onlineWillChangeIn(TimeId online, TimeId now); +QString onlineText(UserData *user, TimeId now, bool precise = false); +QString onlineText(TimeId online, TimeId now, bool precise = false); +bool onlineColorUse(UserData *user, TimeId now); +bool onlineColorUse(TimeId online, TimeId now); - UserData *feedUser(const MTPUser &user); - UserData *feedUsers(const MTPVector &users); // returns last user - PeerData *feedChat(const MTPChat &chat); - PeerData *feedChats(const MTPVector &chats); // returns last chat +UserData *feedUser(const MTPUser &user); +UserData *feedUsers(const MTPVector &users); // returns last user +PeerData *feedChat(const MTPChat &chat); +PeerData *feedChats(const MTPVector &chats); // returns last chat - void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos); - void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d); - void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d); - void feedChatAdmins(const MTPDupdateChatAdmins &d); - void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d); - bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached - void updateEditedMessage(const MTPMessage &m); - void addSavedGif(DocumentData *doc); - void checkSavedGif(HistoryItem *item); - void feedMsgs(const QVector &msgs, NewMessageType type); - void feedMsgs(const MTPVector &msgs, NewMessageType type); - void feedInboxRead(const PeerId &peer, MsgId upTo); - void feedOutboxRead(const PeerId &peer, MsgId upTo, TimeId when); - void feedWereDeleted(ChannelId channelId, const QVector &msgsIds); - void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink); +void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos); +void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d); +void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d); +void feedChatAdmins(const MTPDupdateChatAdmins &d); +void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d); +bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached +void updateEditedMessage(const MTPMessage &m); +void addSavedGif(DocumentData *doc); +void checkSavedGif(HistoryItem *item); +void feedMsgs(const QVector &msgs, NewMessageType type); +void feedMsgs(const MTPVector &msgs, NewMessageType type); +void feedInboxRead(const PeerId &peer, MsgId upTo); +void feedOutboxRead(const PeerId &peer, MsgId upTo, TimeId when); +void feedWereDeleted(ChannelId channelId, const QVector &msgsIds); +void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink); - ImagePtr image(const MTPPhotoSize &size); - StorageImageLocation imageLocation(qint32 w, qint32 h, const MTPFileLocation &loc); - StorageImageLocation imageLocation(const MTPPhotoSize &size); +ImagePtr image(const MTPPhotoSize &size); +StorageImageLocation imageLocation(qint32 w, qint32 h, const MTPFileLocation &loc); +StorageImageLocation imageLocation(const MTPPhotoSize &size); - PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs); - PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = nullptr); - PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = nullptr); - DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb); - DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = nullptr); - DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = nullptr); - WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert = nullptr); - WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = nullptr); - WebPageData *feedWebPage(const MTPWebPage &webpage); - WebPageData *feedWebPage(WebPageId webPageId, const QString &siteName, const TextWithEntities &content); - GameData *feedGame(const MTPDgame &game, GameData *convert = nullptr); +PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs); +PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = nullptr); +PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = nullptr); +DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb); +DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = nullptr); +DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = nullptr); +WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert = nullptr); +WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = nullptr); +WebPageData *feedWebPage(const MTPWebPage &webpage); +WebPageData *feedWebPage(WebPageId webPageId, const QString &siteName, const TextWithEntities &content); +GameData *feedGame(const MTPDgame &game, GameData *convert = nullptr); - PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded); - inline UserData *user(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asUser(peer(id, restriction)); - } - inline ChatData *chat(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asChat(peer(id, restriction)); - } - inline ChannelData *channel(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asChannel(peer(id, restriction)); - } - inline UserData *user(UserId userId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asUser(peer(peerFromUser(userId), restriction)); - } - inline ChatData *chat(ChatId chatId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asChat(peer(peerFromChat(chatId), restriction)); - } - inline ChannelData *channel(ChannelId channelId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asChannel(peer(peerFromChannel(channelId), restriction)); - } - inline PeerData *peerLoaded(const PeerId &id) { - return peer(id, PeerData::FullLoaded); - } - inline UserData *userLoaded(const PeerId &id) { - return user(id, PeerData::FullLoaded); - } - inline ChatData *chatLoaded(const PeerId &id) { - return chat(id, PeerData::FullLoaded); - } - inline ChannelData *channelLoaded(const PeerId &id) { - return channel(id, PeerData::FullLoaded); - } - inline UserData *userLoaded(UserId userId) { - return user(userId, PeerData::FullLoaded); - } - inline ChatData *chatLoaded(ChatId chatId) { - return chat(chatId, PeerData::FullLoaded); - } - inline ChannelData *channelLoaded(ChannelId channelId) { - return channel(channelId, PeerData::FullLoaded); - } - void enumerateUsers(base::lambda action); +PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded); +inline UserData *user(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { + return asUser(peer(id, restriction)); +} +inline ChatData *chat(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { + return asChat(peer(id, restriction)); +} +inline ChannelData *channel(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { + return asChannel(peer(id, restriction)); +} +inline UserData *user(UserId userId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { + return asUser(peer(peerFromUser(userId), restriction)); +} +inline ChatData *chat(ChatId chatId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { + return asChat(peer(peerFromChat(chatId), restriction)); +} +inline ChannelData *channel(ChannelId channelId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { + return asChannel(peer(peerFromChannel(channelId), restriction)); +} +inline PeerData *peerLoaded(const PeerId &id) { + return peer(id, PeerData::FullLoaded); +} +inline UserData *userLoaded(const PeerId &id) { + return user(id, PeerData::FullLoaded); +} +inline ChatData *chatLoaded(const PeerId &id) { + return chat(id, PeerData::FullLoaded); +} +inline ChannelData *channelLoaded(const PeerId &id) { + return channel(id, PeerData::FullLoaded); +} +inline UserData *userLoaded(UserId userId) { + return user(userId, PeerData::FullLoaded); +} +inline ChatData *chatLoaded(ChatId chatId) { + return chat(chatId, PeerData::FullLoaded); +} +inline ChannelData *channelLoaded(ChannelId channelId) { + return channel(channelId, PeerData::FullLoaded); +} +void enumerateUsers(base::lambda action); - UserData *self(); - PeerData *peerByName(const QString &username); - QString peerName(const PeerData *peer, bool forDialogs = false); - PhotoData *photo(const PhotoId &photo); - PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const quint64 &access, qint32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full); - DocumentData *document(const DocumentId &document); - DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const quint64 &access, qint32 version, qint32 date, const QVector &attributes, const QString &mime, const ImagePtr &thumb, qint32 dc, qint32 size, const StorageImageLocation &thumbLocation); - WebPageData *webPage(const WebPageId &webPage); - WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *doc, qint32 duration, const QString &author, qint32 pendingTill); - GameData *game(const GameId &game); - GameData *gameSet(const GameId &game, GameData *convert, const quint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc); - LocationData *location(const LocationCoords &coords); - void forgetMedia(); +UserData *self(); +PeerData *peerByName(const QString &username); +QString peerName(const PeerData *peer, bool forDialogs = false); +PhotoData *photo(const PhotoId &photo); +PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const quint64 &access, qint32 date, const ImagePtr &thumb, + const ImagePtr &medium, const ImagePtr &full); +DocumentData *document(const DocumentId &document); +DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const quint64 &access, qint32 version, + qint32 date, const QVector &attributes, const QString &mime, + const ImagePtr &thumb, qint32 dc, qint32 size, const StorageImageLocation &thumbLocation); +WebPageData *webPage(const WebPageId &webPage); +WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, + const QString &displayUrl, const QString &siteName, const QString &title, + const TextWithEntities &description, PhotoData *photo, DocumentData *doc, qint32 duration, + const QString &author, qint32 pendingTill); +GameData *game(const GameId &game); +GameData *gameSet(const GameId &game, GameData *convert, const quint64 &accessHash, const QString &shortName, + const QString &title, const QString &description, PhotoData *photo, DocumentData *doc); +LocationData *location(const LocationCoords &coords); +void forgetMedia(); - MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo); +MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo); - Histories &histories(); - not_null history(const PeerId &peer); - History *historyFromDialog(const PeerId &peer, qint32 unreadCnt, qint32 maxInboxRead, qint32 maxOutboxRead); - History *historyLoaded(const PeerId &peer); - HistoryItem *histItemById(ChannelId channelId, MsgId itemId); - inline not_null history(const PeerData *peer) { - Assert(peer != nullptr); - return history(peer->id); - } - inline History *historyLoaded(const PeerData *peer) { - return peer ? historyLoaded(peer->id) : nullptr; - } - inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) { - return histItemById(channel ? peerToChannel(channel->id) : 0, itemId); - } - inline HistoryItem *histItemById(const FullMsgId &msgId) { - return histItemById(msgId.channel, msgId.msg); - } - void historyRegItem(HistoryItem *item); - void historyItemDetached(HistoryItem *item); - void historyUnregItem(HistoryItem *item); - void historyUpdateDependent(HistoryItem *item); - void historyClearMsgs(); - void historyClearItems(); - void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency); - void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency); +Histories &histories(); +not_null history(const PeerId &peer); +History *historyFromDialog(const PeerId &peer, qint32 unreadCnt, qint32 maxInboxRead, qint32 maxOutboxRead); +History *historyLoaded(const PeerId &peer); +HistoryItem *histItemById(ChannelId channelId, MsgId itemId); +inline not_null history(const PeerData *peer) { + Assert(peer != nullptr); + return history(peer->id); +} +inline History *historyLoaded(const PeerData *peer) { + return peer ? historyLoaded(peer->id) : nullptr; +} +inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) { + return histItemById(channel ? peerToChannel(channel->id) : 0, itemId); +} +inline HistoryItem *histItemById(const FullMsgId &msgId) { + return histItemById(msgId.channel, msgId.msg); +} +void historyRegItem(HistoryItem *item); +void historyItemDetached(HistoryItem *item); +void historyUnregItem(HistoryItem *item); +void historyUpdateDependent(HistoryItem *item); +void historyClearMsgs(); +void historyClearItems(); +void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency); +void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency); - void historyRegRandom(quint64 randomId, const FullMsgId &itemId); - void historyUnregRandom(quint64 randomId); - FullMsgId histItemByRandom(quint64 randomId); - void historyRegSentData(quint64 randomId, const PeerId &peerId, const QString &text); - void historyUnregSentData(quint64 randomId); - void histSentDataByItem(quint64 randomId, PeerId &peerId, QString &text); +void historyRegRandom(quint64 randomId, const FullMsgId &itemId); +void historyUnregRandom(quint64 randomId); +FullMsgId histItemByRandom(quint64 randomId); +void historyRegSentData(quint64 randomId, const PeerId &peerId, const QString &text); +void historyUnregSentData(quint64 randomId); +void histSentDataByItem(quint64 randomId, PeerId &peerId, QString &text); - void hoveredItem(HistoryItem *item); - HistoryItem *hoveredItem(); - void pressedItem(HistoryItem *item); - HistoryItem *pressedItem(); - void hoveredLinkItem(HistoryItem *item); - HistoryItem *hoveredLinkItem(); - void pressedLinkItem(HistoryItem *item); - HistoryItem *pressedLinkItem(); - void contextItem(HistoryItem *item); - HistoryItem *contextItem(); - void mousedItem(HistoryItem *item); - HistoryItem *mousedItem(); - void clearMousedItems(); +void hoveredItem(HistoryItem *item); +HistoryItem *hoveredItem(); +void pressedItem(HistoryItem *item); +HistoryItem *pressedItem(); +void hoveredLinkItem(HistoryItem *item); +HistoryItem *hoveredLinkItem(); +void pressedLinkItem(HistoryItem *item); +HistoryItem *pressedLinkItem(); +void contextItem(HistoryItem *item); +HistoryItem *contextItem(); +void mousedItem(HistoryItem *item); +HistoryItem *mousedItem(); +void clearMousedItems(); - const style::font &monofont(); - const QPixmap &emoji(); - const QPixmap &emojiLarge(); - const QPixmap &emojiSingle(EmojiPtr emoji, qint32 fontHeight); +const style::font &monofont(); +const QPixmap &emoji(); +const QPixmap &emojiLarge(); +const QPixmap &emojiSingle(EmojiPtr emoji, qint32 fontHeight); - void clearHistories(); +void clearHistories(); - void initMedia(); - void deinitMedia(); +void initMedia(); +void deinitMedia(); - void checkImageCacheSize(); +void checkImageCacheSize(); - bool isValidPhone(QString phone); - - enum LaunchState { - Launched = 0, - QuitRequested = 1, - QuitProcessed = 2, - }; - void quit(); - bool quitting(); - LaunchState launchState(); - void setLaunchState(LaunchState state); - void restart(); - - constexpr auto kFileSizeLimit = 1500 * 1024 * 1024; // Load files up to 1500mb - constexpr auto kImageSizeLimit = 64 * 1024 * 1024; // Open images up to 64mb jpg/png/gif - QImage readImage(QByteArray data, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr); - QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, QByteArray *content = 0); - QPixmap pixmapFromImageInPlace(QImage &&image); - - void regPhotoItem(PhotoData *data, HistoryItem *item); - void unregPhotoItem(PhotoData *data, HistoryItem *item); - const PhotoItems &photoItems(); - const PhotosData &photosData(); - - void regDocumentItem(DocumentData *data, HistoryItem *item); - void unregDocumentItem(DocumentData *data, HistoryItem *item); - const DocumentItems &documentItems(); - const DocumentsData &documentsData(); - - void regWebPageItem(WebPageData *data, HistoryItem *item); - void unregWebPageItem(WebPageData *data, HistoryItem *item); - const WebPageItems &webPageItems(); - - void regGameItem(GameData *data, HistoryItem *item); - void unregGameItem(GameData *data, HistoryItem *item); - const GameItems &gameItems(); - - void regSharedContactItem(qint32 userId, HistoryItem *item); - void unregSharedContactItem(qint32 userId, HistoryItem *item); - const SharedContactItems &sharedContactItems(); - QString phoneFromSharedContact(qint32 userId); - - void regGifItem(Media::Clip::Reader *reader, HistoryItem *item); - void unregGifItem(Media::Clip::Reader *reader); - void stopRoundVideoPlayback(); - void stopGifItems(); - - void regMuted(PeerData *peer, qint32 changeIn); - void unregMuted(PeerData *peer); - void updateMuted(); - - void setProxySettings(QNetworkAccessManager &manager); -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - QNetworkProxy getHttpProxySettings(); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY - void setProxySettings(QTcpSocket &socket); - - void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners); - void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners); - - QImage *cornersMask(ImageRoundRadius radius); - void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full); - inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) { - return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts); - } - void roundShadow(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full); - inline void roundShadow(Painter &p, const QRect &rect, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full) { - return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts); - } - void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full); - inline void roundRect(Painter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) { - return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts); - } - - struct WallPaper { - WallPaper(qint32 id, ImagePtr thumb, ImagePtr full) : id(id), thumb(thumb), full(full) { - } - qint32 id; - ImagePtr thumb; - ImagePtr full; - }; - typedef QList WallPapers; - DeclareSetting(WallPapers, ServerBackgrounds); +bool isValidPhone(QString phone); +enum LaunchState { + Launched = 0, + QuitRequested = 1, + QuitProcessed = 2, }; +void quit(); +bool quitting(); +LaunchState launchState(); +void setLaunchState(LaunchState state); +void restart(); + +constexpr auto kFileSizeLimit = 1500 * 1024 * 1024; // Load files up to 1500mb +constexpr auto kImageSizeLimit = 64 * 1024 * 1024; // Open images up to 64mb jpg/png/gif +QImage readImage(QByteArray data, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr); +QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, + QByteArray *content = 0); +QPixmap pixmapFromImageInPlace(QImage &&image); + +void regPhotoItem(PhotoData *data, HistoryItem *item); +void unregPhotoItem(PhotoData *data, HistoryItem *item); +const PhotoItems &photoItems(); +const PhotosData &photosData(); + +void regDocumentItem(DocumentData *data, HistoryItem *item); +void unregDocumentItem(DocumentData *data, HistoryItem *item); +const DocumentItems &documentItems(); +const DocumentsData &documentsData(); + +void regWebPageItem(WebPageData *data, HistoryItem *item); +void unregWebPageItem(WebPageData *data, HistoryItem *item); +const WebPageItems &webPageItems(); + +void regGameItem(GameData *data, HistoryItem *item); +void unregGameItem(GameData *data, HistoryItem *item); +const GameItems &gameItems(); + +void regSharedContactItem(qint32 userId, HistoryItem *item); +void unregSharedContactItem(qint32 userId, HistoryItem *item); +const SharedContactItems &sharedContactItems(); +QString phoneFromSharedContact(qint32 userId); + +void regGifItem(Media::Clip::Reader *reader, HistoryItem *item); +void unregGifItem(Media::Clip::Reader *reader); +void stopRoundVideoPlayback(); +void stopGifItems(); + +void regMuted(PeerData *peer, qint32 changeIn); +void unregMuted(PeerData *peer); +void updateMuted(); + +void setProxySettings(QNetworkAccessManager &manager); +#ifndef TDESKTOP_DISABLE_NETWORK_PROXY +QNetworkProxy getHttpProxySettings(); +#endif // !TDESKTOP_DISABLE_NETWORK_PROXY +void setProxySettings(QTcpSocket &socket); + +void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners); +void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners); + +QImage *cornersMask(ImageRoundRadius radius); +void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, RoundCorners index, + const style::color *shadow = nullptr, RectParts parts = RectPart::Full); +inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, + const style::color *shadow = nullptr, RectParts parts = RectPart::Full) { + return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts); +} +void roundShadow(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color shadow, RoundCorners index, + RectParts parts = RectPart::Full); +inline void roundShadow(Painter &p, const QRect &rect, style::color shadow, RoundCorners index, + RectParts parts = RectPart::Full) { + return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts); +} +void roundRect(Painter &p, qint32 x, qint32 y, qint32 w, qint32 h, style::color bg, ImageRoundRadius radius, + RectParts parts = RectPart::Full); +inline void roundRect(Painter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, + RectParts parts = RectPart::Full) { + return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts); +} + +struct WallPaper { + WallPaper(qint32 id, ImagePtr thumb, ImagePtr full) + : id(id) + , thumb(thumb) + , full(full) {} + qint32 id; + ImagePtr thumb; + ImagePtr full; +}; +typedef QList WallPapers; +DeclareSetting(WallPapers, ServerBackgrounds); + +}; // namespace App diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index fceb20319..a66a2e83f 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -20,13 +20,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "application.h" -#include "platform/platform_specific.h" +#include "base/timer.h" #include "mainwidget.h" #include "mainwindow.h" +#include "messenger.h" +#include "platform/platform_specific.h" #include "storage/localstorage.h" #include "window/notifications_manager.h" -#include "messenger.h" -#include "base/timer.h" #include #include @@ -50,7 +50,11 @@ QString _escapeTo7bit(const QString &str) { QChar ch(str.at(i)); ushort uch(ch.unicode()); if (uch < 32 || uch > 127 || uch == ushort(uchar('%'))) { - result.append('%').append(_toHex(uch >> 12)).append(_toHex(uch >> 8)).append(_toHex(uch >> 4)).append(_toHex(uch)); + result.append('%') + .append(_toHex(uch >> 12)) + .append(_toHex(uch >> 8)) + .append(_toHex(uch >> 4)) + .append(_toHex(uch)); } else { result.append(ch); } @@ -64,7 +68,8 @@ QString _escapeFrom7bit(const QString &str) { for (int i = 0, l = str.size(); i != l; ++i) { QChar ch(str.at(i)); if (ch == QChar::fromLatin1('%') && i + 4 < l) { - result.append(QChar(ushort((_fromHex(str.at(i + 1)) << 12) | (_fromHex(str.at(i + 2)) << 8) | (_fromHex(str.at(i + 3)) << 4) | _fromHex(str.at(i + 4))))); + result.append(QChar(ushort((_fromHex(str.at(i + 1)) << 12) | (_fromHex(str.at(i + 2)) << 8) | + (_fromHex(str.at(i + 3)) << 4) | _fromHex(str.at(i + 4))))); i += 4; } else { result.append(ch); @@ -75,9 +80,10 @@ QString _escapeFrom7bit(const QString &str) { } // namespace -Application::Application(int &argc, char **argv) : QApplication(argc, argv) { +Application::Application(int &argc, char **argv) + : QApplication(argc, argv) { QByteArray d(QFile::encodeName(QDir(cWorkingDir()).absolutePath())); - char h[33] = { 0 }; + char h[33] = {0}; hashMd5Hex(d.constData(), d.size(), h); #ifndef OS_MAC_STORE _localServerName = psServerPrefix() + h + '-' + cGUIDStr(); @@ -88,7 +94,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) { connect(&_localSocket, SIGNAL(connected()), this, SLOT(socketConnected())); connect(&_localSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); - connect(&_localSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(socketError(QLocalSocket::LocalSocketError))); + connect(&_localSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, + SLOT(socketError(QLocalSocket::LocalSocketError))); connect(&_localSocket, SIGNAL(bytesWritten(qint64)), this, SLOT(socketWritten(qint64))); connect(&_localSocket, SIGNAL(readyRead()), this, SLOT(socketReading())); connect(&_localServer, SIGNAL(newConnection()), this, SLOT(newInstanceConnected())); @@ -100,7 +107,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) { LOG(("Many instance allowed, starting...")); singleInstanceChecked(); } else { - LOG(("Connecting local socket to %1...").arg(_localServerName)); + LOG(("Connecting local socket to %1...").arg(_localServerName)); _localSocket.connectToServer(_localServerName); } } @@ -132,7 +139,7 @@ void Application::socketConnected() { _localSocket.write(commands.toLatin1()); } -void Application::socketWritten(qint64/* bytes*/) { +void Application::socketWritten(qint64 /* bytes*/) { if (_localSocket.state() != QLocalSocket::ConnectedState) { LOG(("Socket is not connected %1").arg(_localSocket.state())); return; @@ -177,7 +184,9 @@ void Application::socketError(QLocalSocket::LocalSocketError e) { psCheckLocalSocket(_localServerName); if (!_localServer.listen(_localServerName)) { - LOG(("Failed to start listening to %1 server, error %2").arg(_localServerName).arg(int(_localServer.serverError()))); + LOG(("Failed to start listening to %1 server, error %2") + .arg(_localServerName) + .arg(int(_localServer.serverError()))); return App::quit(); } #endif // !Q_OS_WINRT @@ -223,7 +232,8 @@ void Application::socketDisconnected() { void Application::newInstanceConnected() { DEBUG_LOG(("Application Info: new local socket connected")); - for (QLocalSocket *client = _localServer.nextPendingConnection(); client; client = _localServer.nextPendingConnection()) { + for (QLocalSocket *client = _localServer.nextPendingConnection(); client; + client = _localServer.nextPendingConnection()) { _localClients.push_back(LocalClient(client, QByteArray())); connect(client, SIGNAL(readyRead()), this, SLOT(readClients())); connect(client, SIGNAL(disconnected()), this, SLOT(removeClients())); @@ -239,7 +249,8 @@ void Application::readClients() { if (i->second.size()) { QString cmds(QString::fromLatin1(i->second)); qint32 from = 0, l = cmds.length(); - for (qint32 to = cmds.indexOf(QChar(';'), from); to >= from; to = (from < l) ? cmds.indexOf(QChar(';'), from) : -1) { + for (qint32 to = cmds.indexOf(QChar(';'), from); to >= from; + to = (from < l) ? cmds.indexOf(QChar(';'), from) : -1) { QStringRef cmd(&cmds, from, to - from); if (cmd.startsWith(qsl("CMD:"))) { Sandbox::execExternal(cmds.mid(from + 4, to - from - 4)); @@ -254,7 +265,8 @@ void Application::readClients() { startUrl = _escapeFrom7bit(cmds.mid(from + 5, to - from - 5)).mid(0, 8192); } } else { - LOG(("Application Error: unknown command %1 passed in local socket").arg(QString(cmd.constData(), cmd.length()))); + LOG(("Application Error: unknown command %1 passed in local socket") + .arg(QString(cmd.constData(), cmd.length()))); } from = to + 1; } @@ -324,7 +336,7 @@ void Application::closeApplication() { } inline Application *application() { - return qobject_cast(QApplication::instance()); + return qobject_cast(QApplication::instance()); } namespace Sandbox { @@ -398,10 +410,13 @@ void launch() { if (devicePixelRatio > 1.) { if ((cPlatform() != dbipMac && cPlatform() != dbipMacOld) || (devicePixelRatio != 2.)) { LOG(("Found non-trivial Device Pixel Ratio: %1").arg(devicePixelRatio)); - LOG(("Environmental variables: QT_DEVICE_PIXEL_RATIO='%1'").arg(QString::fromLatin1(qgetenv("QT_DEVICE_PIXEL_RATIO")))); + LOG(("Environmental variables: QT_DEVICE_PIXEL_RATIO='%1'") + .arg(QString::fromLatin1(qgetenv("QT_DEVICE_PIXEL_RATIO")))); LOG(("Environmental variables: QT_SCALE_FACTOR='%1'").arg(QString::fromLatin1(qgetenv("QT_SCALE_FACTOR")))); - LOG(("Environmental variables: QT_AUTO_SCREEN_SCALE_FACTOR='%1'").arg(QString::fromLatin1(qgetenv("QT_AUTO_SCREEN_SCALE_FACTOR")))); - LOG(("Environmental variables: QT_SCREEN_SCALE_FACTORS='%1'").arg(QString::fromLatin1(qgetenv("QT_SCREEN_SCALE_FACTORS")))); + LOG(("Environmental variables: QT_AUTO_SCREEN_SCALE_FACTOR='%1'") + .arg(QString::fromLatin1(qgetenv("QT_AUTO_SCREEN_SCALE_FACTOR")))); + LOG(("Environmental variables: QT_SCREEN_SCALE_FACTORS='%1'") + .arg(QString::fromLatin1(qgetenv("QT_SCREEN_SCALE_FACTORS")))); } cSetRetina(true); cSetRetinaFactor(devicePixelRatio); diff --git a/Telegram/SourceFiles/application.h b/Telegram/SourceFiles/application.h index 268d55562..c61812563 100644 --- a/Telegram/SourceFiles/application.h +++ b/Telegram/SourceFiles/application.h @@ -23,8 +23,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include #include -#include #include +#include class Messenger; @@ -43,7 +43,7 @@ public: signals: void adjustSingleTimers(); -// Single instance application + // Single instance application public slots: void socketConnected(); void socketError(QLocalSocket::LocalSocketError e); @@ -59,7 +59,7 @@ public slots: void closeApplication(); // will be done in aboutToQuit() private: - typedef QPair LocalClient; + typedef QPair LocalClient; typedef QList LocalClients; std::unique_ptr _messengerInstance; diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index baa06dd49..b5b11b410 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -21,16 +21,16 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "auth_session.h" #include "apiwrap.h" +#include "calls/calls_instance.h" +#include "chat_helpers/tabbed_selector.h" #include "messenger.h" +#include "platform/platform_specific.h" #include "storage/file_download.h" #include "storage/file_upload.h" #include "storage/localstorage.h" #include "storage/serialize_common.h" #include "window/notifications_manager.h" -#include "platform/platform_specific.h" -#include "calls/calls_instance.h" #include "window/section_widget.h" -#include "chat_helpers/tabbed_selector.h" #include "app.h" // App::user @@ -41,10 +41,9 @@ constexpr auto kAutoLockTimeoutLateMs = TimeMs(3000); } // namespace AuthSessionData::Variables::Variables() -: selectorTab(ChatHelpers::SelectorTab::Emoji) -, floatPlayerColumn(Window::Column::Second) -, floatPlayerCorner(RectPart::TopRight) { -} + : selectorTab(ChatHelpers::SelectorTab::Emoji) + , floatPlayerColumn(Window::Column::Second) + , floatPlayerCorner(RectPart::TopRight) {} QByteArray AuthSessionData::serialize() const { auto size = sizeof(qint32) * 8; @@ -170,17 +169,15 @@ AuthSession &Auth() { } AuthSession::AuthSession(UserId userId) -: _userId(userId) -, _autoLockTimer([this] { checkAutoLock(); }) -, _api(std::make_unique(this)) -, _calls(std::make_unique()) -, _downloader(std::make_unique()) -, _uploader(std::make_unique()) -, _notifications(std::make_unique(this)) { + : _userId(userId) + , _autoLockTimer([this] { checkAutoLock(); }) + , _api(std::make_unique(this)) + , _calls(std::make_unique()) + , _downloader(std::make_unique()) + , _uploader(std::make_unique()) + , _notifications(std::make_unique(this)) { Expects(_userId != 0); - _saveDataTimer.setCallback([this] { - Local::writeUserSettings(); - }); + _saveDataTimer.setCallback([this] { Local::writeUserSettings(); }); subscribe(Messenger::Instance().passcodedChanged(), [this] { _shouldLockAt = 0; notifications().updateAll(); diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h index 412de760a..0a47ef8b3 100644 --- a/Telegram/SourceFiles/auth_session.h +++ b/Telegram/SourceFiles/auth_session.h @@ -64,18 +64,18 @@ public: base::Observable &savedGifsUpdated() { return _savedGifsUpdated; } - base::Observable> &historyCleared() { + base::Observable> &historyCleared() { return _historyCleared; } - base::Observable> &repaintLogEntry() { + base::Observable> &repaintLogEntry() { return _repaintLogEntry; } base::Observable &pendingHistoryResize() { return _pendingHistoryResize; } struct ItemVisibilityQuery { - not_null item; - not_null isVisible; + not_null item; + not_null isVisible; }; base::Observable &queryItemVisibility() { return _queryItemVisibility; @@ -160,18 +160,17 @@ private: OrderedSet groupStickersSectionHidden; }; - base::Variable _contactsLoaded = { false }; - base::Variable _allChatsLoaded = { false }; + base::Variable _contactsLoaded = {false}; + base::Variable _allChatsLoaded = {false}; base::Observable _moreChatsLoaded; base::Observable _stickersUpdated; base::Observable _savedGifsUpdated; - base::Observable> _historyCleared; - base::Observable> _repaintLogEntry; + base::Observable> _historyCleared; + base::Observable> _repaintLogEntry; base::Observable _pendingHistoryResize; base::Observable _queryItemVisibility; Variables _variables; TimeMs _lastTimeVideoPlayedAt = 0; - }; // One per Messenger. @@ -225,8 +224,8 @@ public: void checkAutoLock(); void checkAutoLockIn(TimeMs time); - base::Observable documentUpdated; - base::Observable> messageIdChanging; + base::Observable documentUpdated; + base::Observable> messageIdChanging; ~AuthSession(); @@ -243,5 +242,4 @@ private: const std::unique_ptr _downloader; const std::unique_ptr _uploader; const std::unique_ptr _notifications; - }; diff --git a/Telegram/SourceFiles/base/algorithm.h b/Telegram/SourceFiles/base/algorithm.h index 0b03ec674..292fa1ecb 100644 --- a/Telegram/SourceFiles/base/algorithm.h +++ b/Telegram/SourceFiles/base/algorithm.h @@ -20,22 +20,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include #include +#include namespace base { // @todo use ranges-v3 here -template -decltype(auto) for_each(Range &&range, Method &&method) { - return std::for_each( - std::begin(std::forward(range)), - std::end(std::forward(range)), - std::forward(method)); +template decltype(auto) for_each(Range &&range, Method &&method) { + return std::for_each(std::begin(std::forward(range)), std::end(std::forward(range)), + std::forward(method)); } -template -decltype(auto) for_each_apply(Method &&method) { +template decltype(auto) for_each_apply(Method &&method) { return [&method](auto &&range) { return for_each(std::forward(range), std::forward(method)); }; diff --git a/Telegram/SourceFiles/base/assertion.h b/Telegram/SourceFiles/base/assertion.h index 2d0ea39a5..8479b8fb3 100644 --- a/Telegram/SourceFiles/base/assertion.h +++ b/Telegram/SourceFiles/base/assertion.h @@ -31,15 +31,15 @@ void log(const char *message, const char *file, int line); // Release build assertions. inline constexpr void noop() { - // MSVC2015 requires return to suppress warning: a constexpr function must contain exactly one return statement - return void(); + // MSVC2015 requires return to suppress warning: a constexpr function must contain exactly one return statement + return void(); } [[noreturn]] inline void fail(const char *message, const char *file, int line) { log(message, file, line); // Crash with access violation and generate crash report. - volatile auto nullptr_value = (int*)nullptr; + volatile auto nullptr_value = (int *)nullptr; *nullptr_value = 0; // Silent the possible failure to comply noreturn warning. @@ -47,8 +47,8 @@ inline constexpr void noop() { } inline constexpr void validate(bool condition, const char *message, const char *file, int line) { - // MSVC2015 requires return to suppress error C3249: illegal statement or sub-expression for 'constexpr' function - return (GSL_UNLIKELY(!(condition))) ? fail(message, file, line) : noop(); + // MSVC2015 requires return to suppress error C3249: illegal statement or sub-expression for 'constexpr' function + return (GSL_UNLIKELY(!(condition))) ? fail(message, file, line) : noop(); } diff --git a/Telegram/SourceFiles/base/flags.h b/Telegram/SourceFiles/base/flags.h index d51e84f1a..17d7c2623 100644 --- a/Telegram/SourceFiles/base/flags.h +++ b/Telegram/SourceFiles/base/flags.h @@ -30,49 +30,41 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace base { -template -class flags; +template class flags; -template -struct extended_flags; +template struct extended_flags; -template -using extended_flags_t = typename extended_flags::type; +template using extended_flags_t = typename extended_flags::type; namespace details { -struct flags_zero_helper_struct { -}; +struct flags_zero_helper_struct {}; -using flags_zero_helper = void(base::details::flags_zero_helper_struct::*)(); +using flags_zero_helper = void (base::details::flags_zero_helper_struct::*)(); -template ::type> +template ::type> inline constexpr auto extended_flag_convert(ExtendedEnum value) { return static_cast(value); } -template ::type> +template ::type> inline constexpr auto extended_flags_convert(ExtendedEnum value) { return flags(extended_flag_convert(value)); } } // namespace details -template -class flags { +template class flags { public: using Enum = EnumType; using Type = std::underlying_type_t; constexpr flags() = default; - constexpr flags(details::flags_zero_helper) noexcept { - } - constexpr flags(Enum value) noexcept : _value(static_cast(value)) { - } - explicit constexpr flags(Type value) noexcept : _value(value) { - } + constexpr flags(details::flags_zero_helper) noexcept {} + constexpr flags(Enum value) noexcept + : _value(static_cast(value)) {} + explicit constexpr flags(Type value) noexcept + : _value(value) {} constexpr auto value() const noexcept { return _value; @@ -139,157 +131,131 @@ public: private: Type _value = 0; - }; -template -constexpr auto make_flags(Enum value) noexcept { +template constexpr auto make_flags(Enum value) noexcept { return flags(value); } -template ::value>, - typename = std::enable_if_t> +template ::value>, + typename = std::enable_if_t> inline constexpr auto operator|(Enum a, flags b) noexcept { return b | a; } -template ::value>, - typename = std::enable_if_t> +template ::value>, + typename = std::enable_if_t> inline constexpr auto operator&(Enum a, flags b) noexcept { return b & a; } -template ::value>, - typename = std::enable_if_t> +template ::value>, + typename = std::enable_if_t> inline constexpr auto operator^(Enum a, flags b) noexcept { return b ^ a; } -template ::type> +template ::type> inline constexpr auto operator|(flags> a, ExtendedEnum b) { return a | details::extended_flags_convert(b); } -template ::type> +template ::type> inline constexpr auto operator|(ExtendedEnum a, flags> b) { return b | a; } -template > +template > inline constexpr auto operator&(flags> a, ExtendedEnum b) { return a & details::extended_flags_convert(b); } -template ::type> +template ::type> inline constexpr auto operator&(ExtendedEnum a, flags> b) { return b & a; } -template > +template > inline constexpr auto operator^(flags> a, ExtendedEnum b) { return a ^ details::extended_flags_convert(b); } -template ::type> +template ::type> inline constexpr auto operator^(ExtendedEnum a, flags> b) { return b ^ a; } -template ::type> +template ::type> inline constexpr auto &operator&=(flags> &a, ExtendedEnum b) { return (a &= details::extended_flags_convert(b)); } -template ::type> +template ::type> inline constexpr auto &operator|=(flags> &a, ExtendedEnum b) { return (a |= details::extended_flags_convert(b)); } -template ::type> +template ::type> inline constexpr auto &operator^=(flags> &a, ExtendedEnum b) { return (a ^= details::extended_flags_convert(b)); } -template ::type> +template ::type> inline constexpr auto operator==(flags> a, ExtendedEnum b) { return a == details::extended_flags_convert(b); } -template ::type> +template ::type> inline constexpr auto operator==(ExtendedEnum a, flags> b) { return (b == a); } -template ::type> +template ::type> inline constexpr auto operator!=(flags> a, ExtendedEnum b) { return !(a == b); } -template ::type> +template ::type> inline constexpr auto operator!=(ExtendedEnum a, flags> b) { return !(a == b); } -template ::type> +template ::type> inline constexpr auto operator<(flags> a, ExtendedEnum b) { return a < details::extended_flags_convert(b); } -template ::type> +template ::type> inline constexpr auto operator<(ExtendedEnum a, flags> b) { return details::extended_flags_convert(a) < b; } -template ::type> +template ::type> inline constexpr auto operator>(flags> a, ExtendedEnum b) { return (b < a); } -template ::type> +template ::type> inline constexpr auto operator>(ExtendedEnum a, flags> b) { return (b < a); } -template ::type> +template ::type> inline constexpr auto operator<=(flags> a, ExtendedEnum b) { return !(b < a); } -template ::type> +template ::type> inline constexpr auto operator<=(ExtendedEnum a, flags> b) { return !(b < a); } -template ::type> +template ::type> inline constexpr auto operator>=(flags> a, ExtendedEnum b) { return !(a < b); } -template ::type> +template ::type> inline constexpr auto operator>=(ExtendedEnum a, flags> b) { return !(a < b); } @@ -298,73 +264,62 @@ inline constexpr auto operator>=(ExtendedEnum a, flags::value>, - typename = std::enable_if_t> +template ::value>, + typename = std::enable_if_t> inline constexpr auto operator!(Enum a) noexcept { return !base::make_flags(a); } -template ::value>, - typename = std::enable_if_t> +template ::value>, + typename = std::enable_if_t> inline constexpr auto operator~(Enum a) noexcept { return ~base::make_flags(a); } -template ::value>, - typename = std::enable_if_t> +template ::value>, + typename = std::enable_if_t> inline constexpr auto operator|(Enum a, Enum b) noexcept { return base::make_flags(a) | b; } -template ::value>, - typename = std::enable_if_t> +template ::value>, + typename = std::enable_if_t> inline constexpr auto operator|(Enum a, base::details::flags_zero_helper) noexcept { return base::make_flags(a); } -template ::value>, - typename = std::enable_if_t> +template ::value>, + typename = std::enable_if_t> inline constexpr auto operator|(base::details::flags_zero_helper, Enum b) noexcept { return base::make_flags(b); } -template ::type> +template ::type> inline constexpr auto operator|(ExtendedEnum a, ExtendedEnum b) { return base::details::extended_flags_convert(a) | b; } -template ::type> +template ::type> inline constexpr auto operator|(ExtendedEnum a, typename base::extended_flags::type b) { return base::details::extended_flags_convert(a) | b; } -template ::type> +template ::type> inline constexpr auto operator|(typename base::extended_flags::type a, ExtendedEnum b) { return b | a; } -template ::type> +template ::type> inline constexpr auto operator|(base::details::flags_zero_helper, ExtendedEnum b) { return 0 | base::details::extended_flag_convert(b); } -template ::type> +template ::type> inline constexpr auto operator|(ExtendedEnum a, base::details::flags_zero_helper) { return base::details::extended_flag_convert(a) | 0; } -template ::type> +template ::type> inline constexpr auto operator~(ExtendedEnum b) { return ~base::details::extended_flags_convert(b); } diff --git a/Telegram/SourceFiles/base/flat_map.h b/Telegram/SourceFiles/base/flat_map.h index 4f90b5e63..1c8813a47 100644 --- a/Telegram/SourceFiles/base/flat_map.h +++ b/Telegram/SourceFiles/base/flat_map.h @@ -20,17 +20,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include -#include #include "base/optional.h" +#include +#include namespace base { -template -class flat_map; +template class flat_map; -template -class flat_multi_map; +template class flat_multi_map; template class flat_multi_map_iterator_base_impl; @@ -47,8 +45,8 @@ public: using reference = reference_impl; using const_reference = typename flat_multi_map::const_reference; - flat_multi_map_iterator_base_impl(iterator_impl impl = iterator_impl()) : _impl(impl) { - } + flat_multi_map_iterator_base_impl(iterator_impl impl = iterator_impl()) + : _impl(impl) {} reference operator*() { return *_impl; @@ -113,89 +111,87 @@ public: private: iterator_impl _impl; friend class flat_multi_map; - }; -template -class flat_multi_map { +template class flat_multi_map { using self = flat_multi_map; class key_const_wrap { public: - key_const_wrap(const Key &value) : _value(value) { - } - key_const_wrap(Key &&value) : _value(std::move(value)) { - } - inline operator const Key&() const { + key_const_wrap(const Key &value) + : _value(value) {} + key_const_wrap(Key &&value) + : _value(std::move(value)) {} + inline operator const Key &() const { return _value; } friend inline bool operator<(const Key &a, const key_const_wrap &b) { - return a < ((const Key&)b); + return a < ((const Key &)b); } friend inline bool operator<(const key_const_wrap &a, const Key &b) { - return ((const Key&)a) < b; + return ((const Key &)a) < b; } friend inline bool operator<(const key_const_wrap &a, const key_const_wrap &b) { - return ((const Key&)a) < ((const Key&)b); + return ((const Key &)a) < ((const Key &)b); } private: Key _value; - }; using pair_type = std::pair; using impl = std::deque; - using iterator_base = flat_multi_map_iterator_base_impl; - using const_iterator_base = flat_multi_map_iterator_base_impl; - using reverse_iterator_base = flat_multi_map_iterator_base_impl; - using const_reverse_iterator_base = flat_multi_map_iterator_base_impl; + using iterator_base = + flat_multi_map_iterator_base_impl; + using const_iterator_base = flat_multi_map_iterator_base_impl; + using reverse_iterator_base = + flat_multi_map_iterator_base_impl; + using const_reverse_iterator_base = + flat_multi_map_iterator_base_impl; public: using value_type = pair_type; using size_type = typename impl::size_type; using difference_type = typename impl::difference_type; - using pointer = pair_type*; - using const_pointer = const pair_type*; - using reference = pair_type&; - using const_reference = const pair_type&; + using pointer = pair_type *; + using const_pointer = const pair_type *; + using reference = pair_type &; + using const_reference = const pair_type &; class const_iterator; class iterator : public iterator_base { public: using iterator_base::iterator_base; - iterator(const iterator_base &other) : iterator_base(other) { - } + iterator(const iterator_base &other) + : iterator_base(other) {} friend class const_iterator; - }; class const_iterator : public const_iterator_base { public: using const_iterator_base::const_iterator_base; - const_iterator(const_iterator_base other) : const_iterator_base(other) { - } - const_iterator(const iterator &other) : const_iterator_base(other._impl) { - } - + const_iterator(const_iterator_base other) + : const_iterator_base(other) {} + const_iterator(const iterator &other) + : const_iterator_base(other._impl) {} }; class const_reverse_iterator; class reverse_iterator : public reverse_iterator_base { public: using reverse_iterator_base::reverse_iterator_base; - reverse_iterator(reverse_iterator_base other) : reverse_iterator_base(other) { - } + reverse_iterator(reverse_iterator_base other) + : reverse_iterator_base(other) {} friend class const_reverse_iterator; - }; class const_reverse_iterator : public const_reverse_iterator_base { public: using const_reverse_iterator_base::const_reverse_iterator_base; - const_reverse_iterator(const_reverse_iterator_base other) : const_reverse_iterator_base(other) { - } - const_reverse_iterator(const reverse_iterator &other) : const_reverse_iterator_base(other._impl) { - } - + const_reverse_iterator(const_reverse_iterator_base other) + : const_reverse_iterator_base(other) {} + const_reverse_iterator(const reverse_iterator &other) + : const_reverse_iterator_base(other._impl) {} }; size_type size() const { @@ -280,8 +276,7 @@ public: auto where = getUpperBound(value.first); return _impl.insert(where, std::move(value)); } - template - iterator emplace(Args&&... args) { + template iterator emplace(Args &&... args) { return insert(value_type(std::forward(args)...)); } @@ -372,11 +367,9 @@ private: std::pair getEqualRange(const Key &key) const { return std::equal_range(_impl.begin(), _impl.end(), key, Comparator()); } - }; -template -class flat_map : public flat_multi_map { +template class flat_map : public flat_multi_map { using parent = flat_multi_map; using pair_type = typename parent::pair_type; @@ -414,8 +407,7 @@ public: } return this->end(); } - template - iterator emplace(Args&&... args) { + template iterator emplace(Args &&... args) { return this->insert(value_type(std::forward(args)...)); } @@ -432,15 +424,15 @@ public: Type &operator[](const Key &key) { if (this->empty() || (key < this->front().first)) { - this->_impl.push_front({ key, Type() }); + this->_impl.push_front({key, Type()}); return this->front().second; } else if (this->back().first < key) { - this->_impl.push_back({ key, Type() }); + this->_impl.push_back({key, Type()}); return this->back().second; } auto where = this->getLowerBound(key); if (key < where->first) { - return this->_impl.insert(where, { key, Type() })->second; + return this->_impl.insert(where, {key, Type()})->second; } return where->second; } @@ -454,7 +446,6 @@ public: this->erase(it); return std::move(result); } - }; } // namespace base diff --git a/Telegram/SourceFiles/base/flat_set.h b/Telegram/SourceFiles/base/flat_set.h index 449b680fe..ebf3f8d36 100644 --- a/Telegram/SourceFiles/base/flat_set.h +++ b/Telegram/SourceFiles/base/flat_set.h @@ -20,22 +20,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include #include +#include namespace base { -template -class flat_set; +template class flat_set; -template -class flat_multi_set; +template class flat_multi_set; -template -class flat_multi_set_iterator_base_impl; +template class flat_multi_set_iterator_base_impl; -template -class flat_multi_set_iterator_base_impl { +template class flat_multi_set_iterator_base_impl { public: using iterator_category = typename iterator_impl::iterator_category; @@ -44,8 +40,8 @@ public: using pointer = typename flat_multi_set::pointer; using reference = typename flat_multi_set::reference; - flat_multi_set_iterator_base_impl(iterator_impl impl = iterator_impl()) : _impl(impl) { - } + flat_multi_set_iterator_base_impl(iterator_impl impl = iterator_impl()) + : _impl(impl) {} reference operator*() const { return *_impl; @@ -101,35 +97,32 @@ public: private: iterator_impl _impl; friend class flat_multi_set; - }; -template -class flat_multi_set { +template class flat_multi_set { using self = flat_multi_set; class const_wrap { public: - const_wrap(const Type &value) : _value(value) { - } - const_wrap(Type &&value) : _value(std::move(value)) { - } - inline operator const Type&() const { + const_wrap(const Type &value) + : _value(value) {} + const_wrap(Type &&value) + : _value(std::move(value)) {} + inline operator const Type &() const { return _value; } friend inline bool operator<(const Type &a, const const_wrap &b) { - return a < ((const Type&)b); + return a < ((const Type &)b); } friend inline bool operator<(const const_wrap &a, const Type &b) { - return ((const Type&)a) < b; + return ((const Type &)a) < b; } friend inline bool operator<(const const_wrap &a, const const_wrap &b) { - return ((const Type&)a) < ((const Type&)b); + return ((const Type &)a) < ((const Type &)b); } private: Type _value; - }; using impl = std::deque; @@ -143,50 +136,47 @@ public: using value_type = Type; using size_type = typename impl::size_type; using difference_type = typename impl::difference_type; - using pointer = const Type*; - using reference = const Type&; + using pointer = const Type *; + using reference = const Type &; class const_iterator; class iterator : public iterator_base { public: using iterator_base::iterator_base; - iterator(const iterator_base &other) : iterator_base(other) { - } + iterator(const iterator_base &other) + : iterator_base(other) {} friend class const_iterator; - }; class const_iterator : public const_iterator_base { public: using const_iterator_base::const_iterator_base; - const_iterator(const_iterator_base other) : const_iterator_base(other) { - } - const_iterator(const iterator &other) : const_iterator_base(other._impl) { - } - + const_iterator(const_iterator_base other) + : const_iterator_base(other) {} + const_iterator(const iterator &other) + : const_iterator_base(other._impl) {} }; class const_reverse_iterator; class reverse_iterator : public reverse_iterator_base { public: using reverse_iterator_base::reverse_iterator_base; - reverse_iterator(reverse_iterator_base other) : reverse_iterator_base(other) { - } + reverse_iterator(reverse_iterator_base other) + : reverse_iterator_base(other) {} friend class const_reverse_iterator; - }; class const_reverse_iterator : public const_reverse_iterator_base { public: using const_reverse_iterator_base::const_reverse_iterator_base; - const_reverse_iterator(const_reverse_iterator_base other) : const_reverse_iterator_base(other) { - } - const_reverse_iterator(const reverse_iterator &other) : const_reverse_iterator_base(other._impl) { - } - + const_reverse_iterator(const_reverse_iterator_base other) + : const_reverse_iterator_base(other) {} + const_reverse_iterator(const reverse_iterator &other) + : const_reverse_iterator_base(other._impl) {} }; flat_multi_set() = default; template ::iterator_category> - flat_multi_set(Iterator first, Iterator last) : _impl(first, last) { + flat_multi_set(Iterator first, Iterator last) + : _impl(first, last) { std::sort(_impl.begin(), _impl.end()); } @@ -266,8 +256,7 @@ public: auto where = getUpperBound(value); return _impl.insert(where, std::move(value)); } - template - iterator emplace(Args&&... args) { + template iterator emplace(Args &&... args) { return insert(Type(std::forward(args)...)); } @@ -350,11 +339,9 @@ private: std::pair getEqualRange(const Type &value) const { return std::equal_range(_impl.begin(), _impl.end(), value); } - }; -template -class flat_set : public flat_multi_set { +template class flat_set : public flat_multi_set { using parent = flat_multi_set; public: @@ -365,10 +352,11 @@ public: flat_set() = default; template ::iterator_category> - flat_set(Iterator first, Iterator last) : parent(first, last) { - this->_impl.erase(std::unique(this->_impl.begin(), this->_impl.end(), [](auto &&a, auto &&b) { - return !(a < b); - }), this->_impl.end()); + flat_set(Iterator first, Iterator last) + : parent(first, last) { + this->_impl.erase( + std::unique(this->_impl.begin(), this->_impl.end(), [](auto &&a, auto &&b) { return !(a < b); }), + this->_impl.end()); } iterator insert(const Type &value) { @@ -399,8 +387,7 @@ public: } return this->end(); } - template - iterator emplace(Args&&... args) { + template iterator emplace(Args &&... args) { return this->insert(Type(std::forward(args)...)); } @@ -414,7 +401,6 @@ public: const_iterator find(const Type &value) const { return this->findFirst(value); } - }; } // namespace base diff --git a/Telegram/SourceFiles/base/functors.h b/Telegram/SourceFiles/base/functors.h index 72f161b7c..b95da28b3 100644 --- a/Telegram/SourceFiles/base/functors.h +++ b/Telegram/SourceFiles/base/functors.h @@ -26,17 +26,14 @@ namespace base { namespace functors { struct abs_helper { - template ()), - typename = decltype(-std::declval())> - constexpr Type operator()(Type value) const { + template ()), typename = decltype(-std::declval())> + constexpr Type operator()(Type value) const { return (0 < value) ? value : (-value); } }; -constexpr auto abs = abs_helper {}; +constexpr auto abs = abs_helper{}; -template -inline auto add(Type a) { +template inline auto add(Type a) { return [a](auto b) { return a + b; }; }; diff --git a/Telegram/SourceFiles/base/lambda.h b/Telegram/SourceFiles/base/lambda.h index 115aea9c0..016039352 100644 --- a/Telegram/SourceFiles/base/lambda.h +++ b/Telegram/SourceFiles/base/lambda.h @@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include #include // std::max_align_t +#include #ifndef Assert #define LambdaAssertDefined @@ -42,31 +42,26 @@ template class lambda; namespace lambda_internal { -template -struct type_resolver; +template struct type_resolver; -template -struct type_resolver { +template struct type_resolver { using type = lambda; static constexpr auto is_mutable = false; }; -template -struct type_resolver { +template struct type_resolver { using type = lambda_once; static constexpr auto is_mutable = true; }; -template -struct type_helper { +template struct type_helper { using type = typename type_resolver::type; static constexpr auto is_mutable = type_resolver::is_mutable; }; } // namespace lambda_internal -template -using lambda_type = typename lambda_internal::type_helper>::type; +template using lambda_type = typename lambda_internal::type_helper>::type; template constexpr bool lambda_is_mutable = lambda_internal::type_helper>::is_mutable; @@ -74,205 +69,165 @@ constexpr bool lambda_is_mutable = lambda_internal::type_helper -constexpr bool is_large = (sizeof(std::decay_t) > kStorageSize); +template constexpr bool is_large = (sizeof(std::decay_t) > kStorageSize); [[noreturn]] inline void bad_construct_copy(void *lambda, const void *source) { Unexpected("base::lambda bad_construct_copy() called!"); } -template -[[noreturn]] Return bad_const_call(const void *lambda, Args...) { - Unexpected("base::lambda bad_const_call() called!"); -} +template +[[noreturn]] Return bad_const_call(const void *lambda, Args...) { Unexpected("base::lambda bad_const_call() called!"); } -template +template struct vtable_base { - using construct_copy_other_type = void(*)(void *, const void *); // dst, src - using construct_move_other_type = void(*)(void *, void *); // dst, src - using const_call_type = Return(*)(const void *, Args...); - using call_type = Return(*)(void *, Args...); - using destruct_type = void(*)(const void *); + using construct_copy_other_type = void (*)(void *, const void *); // dst, src + using construct_move_other_type = void (*)(void *, void *); // dst, src + using const_call_type = Return (*)(const void *, Args...); + using call_type = Return (*)(void *, Args...); + using destruct_type = void (*)(const void *); vtable_base() = delete; vtable_base(const vtable_base &other) = delete; vtable_base &operator=(const vtable_base &other) = delete; - vtable_base( - construct_copy_other_type construct_copy_other, - construct_move_other_type construct_move_other, - const_call_type const_call, - call_type call, - destruct_type destruct) - : construct_copy_other(construct_copy_other) - , construct_move_other(construct_move_other) - , const_call(const_call) - , call(call) - , destruct(destruct) { - } + vtable_base(construct_copy_other_type construct_copy_other, construct_move_other_type construct_move_other, + const_call_type const_call, call_type call, destruct_type destruct) + : construct_copy_other(construct_copy_other) + , construct_move_other(construct_move_other) + , const_call(const_call) + , call(call) + , destruct(destruct) {} const construct_copy_other_type construct_copy_other; const construct_move_other_type construct_move_other; const const_call_type const_call; const call_type call; const destruct_type destruct; - }; -template struct vtable_once_impl; +template struct vtable_once_impl; -template +template struct vtable_once_impl : public vtable_base { using JustLambda = std::decay_t; using LambdaPtr = std::unique_ptr; using Parent = vtable_base; static void construct_move_other_method(void *storage, void *source) { - auto source_lambda_ptr = static_cast(source); + auto source_lambda_ptr = static_cast(source); new (storage) LambdaPtr(std::move(*source_lambda_ptr)); } static Return call_method(void *storage, Args... args) { - return (**static_cast(storage))(std::forward(args)...); + return (**static_cast(storage))(std::forward(args)...); } static void destruct_method(const void *storage) { - static_cast(storage)->~LambdaPtr(); - } - vtable_once_impl() : Parent( - &bad_construct_copy, - &vtable_once_impl::construct_move_other_method, - &bad_const_call, - &vtable_once_impl::call_method, - &vtable_once_impl::destruct_method) { + static_cast(storage)->~LambdaPtr(); } + vtable_once_impl() + : Parent(&bad_construct_copy, &vtable_once_impl::construct_move_other_method, &bad_const_call, + &vtable_once_impl::call_method, &vtable_once_impl::destruct_method) {} // Used directly. static void construct_move_lambda_method(void *storage, void *source) { - auto source_lambda = static_cast(source); - new (storage) LambdaPtr(std::make_unique(static_cast(*source_lambda))); + auto source_lambda = static_cast(source); + new (storage) LambdaPtr(std::make_unique(static_cast(*source_lambda))); } protected: - vtable_once_impl( - typename Parent::construct_copy_other_type construct_copy_other, - typename Parent::const_call_type const_call - ) : Parent( - construct_copy_other, - &vtable_once_impl::construct_move_other_method, - const_call, - &vtable_once_impl::call_method, - &vtable_once_impl::destruct_method) { - } - + vtable_once_impl(typename Parent::construct_copy_other_type construct_copy_other, + typename Parent::const_call_type const_call) + : Parent(construct_copy_other, &vtable_once_impl::construct_move_other_method, const_call, + &vtable_once_impl::call_method, &vtable_once_impl::destruct_method) {} }; -template +template struct vtable_once_impl : public vtable_base { using JustLambda = std::decay_t; using Parent = vtable_base; static void construct_move_other_method(void *storage, void *source) { - auto source_lambda = static_cast(source); - new (storage) JustLambda(static_cast(*source_lambda)); + auto source_lambda = static_cast(source); + new (storage) JustLambda(static_cast(*source_lambda)); } static Return call_method(void *storage, Args... args) { - return (*static_cast(storage))(std::forward(args)...); + return (*static_cast(storage))(std::forward(args)...); } static void destruct_method(const void *storage) { - static_cast(storage)->~JustLambda(); - } - vtable_once_impl() : Parent( - &bad_construct_copy, - &vtable_once_impl::construct_move_other_method, - &bad_const_call, - &vtable_once_impl::call_method, - &vtable_once_impl::destruct_method) { + static_cast(storage)->~JustLambda(); } + vtable_once_impl() + : Parent(&bad_construct_copy, &vtable_once_impl::construct_move_other_method, &bad_const_call, + &vtable_once_impl::call_method, &vtable_once_impl::destruct_method) {} // Used directly. static void construct_move_lambda_method(void *storage, void *source) { - auto source_lambda = static_cast(source); - new (storage) JustLambda(static_cast(*source_lambda)); + auto source_lambda = static_cast(source); + new (storage) JustLambda(static_cast(*source_lambda)); } protected: - vtable_once_impl( - typename Parent::construct_copy_other_type construct_copy_other, - typename Parent::const_call_type const_call - ) : Parent( - construct_copy_other, - &vtable_once_impl::construct_move_other_method, - const_call, - &vtable_once_impl::call_method, - &vtable_once_impl::destruct_method) { - } - + vtable_once_impl(typename Parent::construct_copy_other_type construct_copy_other, + typename Parent::const_call_type const_call) + : Parent(construct_copy_other, &vtable_once_impl::construct_move_other_method, const_call, + &vtable_once_impl::call_method, &vtable_once_impl::destruct_method) {} }; -template +template struct vtable_once : public vtable_once_impl, Return, Args...> { static const vtable_once instance; }; -template +template const vtable_once vtable_once::instance = {}; -template struct vtable_impl; +template struct vtable_impl; -template +template struct vtable_impl : public vtable_once_impl { using JustLambda = std::decay_t; using LambdaPtr = std::unique_ptr; using Parent = vtable_once_impl; static void construct_copy_other_method(void *storage, const void *source) { - auto source_lambda = static_cast(source); + auto source_lambda = static_cast(source); new (storage) LambdaPtr(std::make_unique(*source_lambda->get())); } static Return const_call_method(const void *storage, Args... args) { - auto lambda_ptr = static_cast(storage)->get(); - return (*static_cast(lambda_ptr))(std::forward(args)...); + auto lambda_ptr = static_cast(storage)->get(); + return (*static_cast(lambda_ptr))(std::forward(args)...); } - vtable_impl() : Parent( - &vtable_impl::construct_copy_other_method, - &vtable_impl::const_call_method - ) { - } - + vtable_impl() + : Parent(&vtable_impl::construct_copy_other_method, &vtable_impl::const_call_method) {} }; -template +template struct vtable_impl : public vtable_once_impl { using JustLambda = std::decay_t; using Parent = vtable_once_impl; static void construct_copy_other_method(void *storage, const void *source) { - auto source_lambda = static_cast(source); + auto source_lambda = static_cast(source); new (storage) JustLambda(static_cast(*source_lambda)); } static Return const_call_method(const void *storage, Args... args) { - return (*static_cast(storage))(std::forward(args)...); + return (*static_cast(storage))(std::forward(args)...); } - vtable_impl() : Parent( - &vtable_impl::construct_copy_other_method, - &vtable_impl::const_call_method - ) { - } - + vtable_impl() + : Parent(&vtable_impl::construct_copy_other_method, &vtable_impl::const_call_method) {} }; -template +template struct vtable : public vtable_impl, Return, Args...> { static const vtable instance; }; -template +template const vtable vtable::instance = {}; } // namespace lambda_internal -template -class lambda_once { +template class lambda_once { using VTable = lambda_internal::vtable_base; public: @@ -345,12 +300,14 @@ public: } // Copy / move construct / assign from an arbitrary type. - template ()(std::declval()...)),Return>::value>> + template ()(std::declval()...)), Return>::value>> lambda_once(Lambda other) { data_.vtable = &lambda_internal::vtable_once::instance; lambda_internal::vtable_once::construct_move_lambda_method(data_.storage, &other); } - template ()(std::declval()...)),Return>::value>> + template ()(std::declval()...)), Return>::value>> lambda_once &operator=(Lambda other) { if (data_.vtable) { data_.vtable->destruct(data_.storage); @@ -382,8 +339,7 @@ public: } protected: - struct Private { - }; + struct Private {}; lambda_once(const VTable *vtable, const Private &) { data_.vtable = vtable; } @@ -397,38 +353,39 @@ protected: char raw_[lambda_internal::kFullStorageSize]; Data data_; }; - }; -template -class lambda final : public lambda_once { +template class lambda final : public lambda_once { using Parent = lambda_once; public: lambda() = default; // Move construct / assign from the same type. - lambda(lambda &&other) : Parent(std::move(other)) { - } + lambda(lambda &&other) + : Parent(std::move(other)) {} lambda &operator=(lambda &&other) { Parent::operator=(std::move(other)); return *this; } // Copy construct / assign from the same type. - lambda(const lambda &other) : Parent(other) { - } + lambda(const lambda &other) + : Parent(other) {} lambda &operator=(const lambda &other) { Parent::operator=(other); return *this; } // Copy / move construct / assign from an arbitrary type. - template ()(std::declval()...)),Return>::value>> - lambda(Lambda other) : Parent(&lambda_internal::vtable::instance, typename Parent::Private()) { + template ()(std::declval()...)), Return>::value>> + lambda(Lambda other) + : Parent(&lambda_internal::vtable::instance, typename Parent::Private()) { lambda_internal::vtable::construct_move_lambda_method(this->data_.storage, &other); } - template ()(std::declval()...)),Return>::value>> + template ()(std::declval()...)), Return>::value>> lambda &operator=(Lambda other) { if (this->data_.vtable) { this->data_.vtable->destruct(this->data_.storage); @@ -448,7 +405,6 @@ public: std::swap(*this, other); } } - }; } // namespace base diff --git a/Telegram/SourceFiles/base/lambda_guard.h b/Telegram/SourceFiles/base/lambda_guard.h index c28a5ed40..7b38d3d9a 100644 --- a/Telegram/SourceFiles/base/lambda_guard.h +++ b/Telegram/SourceFiles/base/lambda_guard.h @@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include #include "base/lambda.h" +#include namespace base { @@ -29,23 +29,22 @@ namespace base { namespace lambda_internal { -template -class guard_data { +template class guard_data { public: using return_type = typename lambda_type::return_type; - template - inline guard_data(PointersAndLambda&&... qobjectsAndLambda) : _lambda(init(_pointers, std::forward(qobjectsAndLambda)...)) { - } + template + inline guard_data(PointersAndLambda &&... qobjectsAndLambda) + : _lambda(init(_pointers, std::forward(qobjectsAndLambda)...)) {} - inline guard_data(const guard_data &other) : _lambda(other._lambda) { + inline guard_data(const guard_data &other) + : _lambda(other._lambda) { for (auto i = 0; i != N; ++i) { _pointers[i] = other._pointers[i]; } } - template - inline return_type operator()(Args&&... args) { + template inline return_type operator()(Args &&... args) { for (int i = 0; i != N; ++i) { if (!_pointers[i]) { return return_type(); @@ -54,8 +53,7 @@ public: return _lambda(std::forward(args)...); } - template - inline return_type operator()(Args&&... args) const { + template inline return_type operator()(Args &&... args) const { for (int i = 0; i != N; ++i) { if (!_pointers[i]) { return return_type(); @@ -65,8 +63,8 @@ public: } private: - template - Lambda init(QPointer *pointers, QObject *qobject, PointersAndLambda&&... qobjectsAndLambda) { + template + Lambda init(QPointer *pointers, QObject *qobject, PointersAndLambda &&... qobjectsAndLambda) { *pointers = qobject; return init(++pointers, std::forward(qobjectsAndLambda)...); } @@ -76,24 +74,24 @@ private: QPointer _pointers[N]; Lambda _lambda; - }; -template -class guard { +template class guard { public: using return_type = typename lambda_type::return_type; - template - inline guard(Pointer &&qobject, Other &&other, PointersAndLambda&&... qobjectsAndLambda) : _data(std::make_unique>(std::forward(qobject), std::forward(other), std::forward(qobjectsAndLambda)...)) { + template + inline guard(Pointer &&qobject, Other &&other, PointersAndLambda &&... qobjectsAndLambda) + : _data(std::make_unique>(std::forward(qobject), std::forward(other), + std::forward(qobjectsAndLambda)...)) { static_assert(1 + 1 + sizeof...(PointersAndLambda) == N + 1, "Wrong argument count!"); } - inline guard(const guard &other) : _data(std::make_unique>(static_cast &>(*other._data))) { - } + inline guard(const guard &other) + : _data(std::make_unique>(static_cast &>(*other._data))) {} - inline guard(guard &&other) : _data(std::move(other._data)) { - } + inline guard(guard &&other) + : _data(std::move(other._data)) {} inline guard &operator=(const guard &&other) { _data = std::move(other._data); @@ -105,13 +103,11 @@ public: return *this; } - template - inline return_type operator()(Args&&... args) { + template inline return_type operator()(Args &&... args) { return (*_data)(std::forward(args)...); } - template - inline return_type operator()(Args&&... args) const { + template inline return_type operator()(Args &&... args) const { return (*_data)(std::forward(args)...); } @@ -121,41 +117,33 @@ public: private: mutable std::unique_ptr> _data; - }; -template -struct guard_type; +template struct guard_type; -template +template struct guard_type { using type = typename guard_type::type; }; -template -struct guard_type { - using type = guard; -}; +template struct guard_type { using type = guard; }; -template -struct guard_type_helper { +template struct guard_type_helper { static constexpr int N = sizeof...(PointersAndLambda); using type = typename guard_type::type; }; -template -using guard_t = typename guard_type_helper::type; +template using guard_t = typename guard_type_helper::type; -template -struct type_helper> { +template struct type_helper> { using type = typename type_helper::type; static constexpr auto is_mutable = type_helper::is_mutable; }; } // namespace lambda_internal -template -inline lambda_internal::guard_t lambda_guarded(PointersAndLambda&&... qobjectsAndLambda) { +template +inline lambda_internal::guard_t lambda_guarded(PointersAndLambda &&... qobjectsAndLambda) { static_assert(sizeof...(PointersAndLambda) > 0, "Lambda should be passed here."); return lambda_internal::guard_t(std::forward(qobjectsAndLambda)...); } diff --git a/Telegram/SourceFiles/base/object_ptr.h b/Telegram/SourceFiles/base/object_ptr.h index ad04c7ddc..a0bd000ae 100644 --- a/Telegram/SourceFiles/base/object_ptr.h +++ b/Telegram/SourceFiles/base/object_ptr.h @@ -20,27 +20,25 @@ Copyright (c) 2018 pro.cxx Community */ #pragma once +#include "core/utils.h" // @todo used for base::take #include #include -#include "core/utils.h" // @todo used for base::take // Smart pointer for QObject*, has move semantics, destroys object if it doesn't have a parent. -template -class object_ptr { +template class object_ptr { public: - object_ptr(std::nullptr_t) { - } + object_ptr(std::nullptr_t) {} // No default constructor, but constructors with at least // one argument are simply make functions. template - explicit object_ptr(Parent &&parent, Args&&... args) : _object(new Object(std::forward(parent), std::forward(args)...)) { - } + explicit object_ptr(Parent &&parent, Args &&... args) + : _object(new Object(std::forward(parent), std::forward(args)...)) {} object_ptr(const object_ptr &other) = delete; object_ptr &operator=(const object_ptr &other) = delete; - object_ptr(object_ptr &&other) : _object(base::take(other._object)) { - } + object_ptr(object_ptr &&other) + : _object(base::take(other._object)) {} object_ptr &operator=(object_ptr &&other) { auto temp = std::move(other); destroy(); @@ -49,8 +47,8 @@ public: } template ::value>> - object_ptr(object_ptr &&other) : _object(base::take(other._object)) { - } + object_ptr(object_ptr &&other) + : _object(base::take(other._object)) {} template ::value>> object_ptr &operator=(object_ptr &&other) { @@ -65,9 +63,9 @@ public: // So we can pass this pointer to methods like connect(). Object *data() const { - return static_cast(_object.data()); + return static_cast(_object.data()); } - operator Object*() const { + operator Object *() const { return data(); } @@ -83,8 +81,7 @@ public: } // Use that instead "= new Object(parent, ...)" - template - void create(Parent &&parent, Args&&... args) { + template void create(Parent &&parent, Args &&... args) { destroy(); _object = new Object(std::forward(parent), std::forward(args)...); } @@ -93,7 +90,7 @@ public: } void destroyDelayed() { if (_object) { - if (auto widget = base::up_cast(data())) { + if (auto widget = base::up_cast(data())) { widget->hide(); } base::take(_object)->deleteLater(); @@ -112,16 +109,14 @@ public: friend object_ptr static_object_cast(object_ptr source); private: - template - friend class object_ptr; + template friend class object_ptr; QPointer _object; - }; template inline object_ptr static_object_cast(object_ptr source) { auto result = object_ptr(nullptr); - result._object = static_cast(base::take(source._object).data()); + result._object = static_cast(base::take(source._object).data()); return std::move(result); } diff --git a/Telegram/SourceFiles/base/observer.cpp b/Telegram/SourceFiles/base/observer.cpp index 377ef0101..9705713b5 100644 --- a/Telegram/SourceFiles/base/observer.cpp +++ b/Telegram/SourceFiles/base/observer.cpp @@ -31,7 +31,7 @@ struct ObservableListWrap { ~ObservableListWrap() { CantUseObservables = true; } - OrderedSet list; + OrderedSet list; }; ObservableListWrap &PendingObservables() { diff --git a/Telegram/SourceFiles/base/observer.h b/Telegram/SourceFiles/base/observer.h index c0d6cf0cb..52ddd4204 100644 --- a/Telegram/SourceFiles/base/observer.h +++ b/Telegram/SourceFiles/base/observer.h @@ -20,13 +20,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include -#include -#include #include "base/assertion.h" #include "base/lambda.h" #include "base/type_traits.h" #include "core/utils.h" +#include +#include +#include namespace base { namespace internal { @@ -36,28 +36,20 @@ void RegisterPendingObservable(ObservableCallHandlers *handlers); void UnregisterActiveObservable(ObservableCallHandlers *handlers); void UnregisterObservable(ObservableCallHandlers *handlers); -template -struct SubscriptionHandlerHelper { +template struct SubscriptionHandlerHelper { using type = base::lambda)>; }; -template <> -struct SubscriptionHandlerHelper { - using type = base::lambda; -}; +template <> struct SubscriptionHandlerHelper { using type = base::lambda; }; -template -using SubscriptionHandler = typename SubscriptionHandlerHelper::type; +template using SubscriptionHandler = typename SubscriptionHandlerHelper::type; // Required because QShared/WeakPointer can't point to void. -class BaseObservableData { -}; +class BaseObservableData {}; -template -class CommonObservableData; +template class CommonObservableData; -template -class ObservableData; +template class ObservableData; } // namespace internal @@ -66,8 +58,9 @@ public: Subscription() = default; Subscription(const Subscription &) = delete; Subscription &operator=(const Subscription &) = delete; - Subscription(Subscription &&other) : _node(base::take(other._node)), _removeAndDestroyMethod(other._removeAndDestroyMethod) { - } + Subscription(Subscription &&other) + : _node(base::take(other._node)) + , _removeAndDestroyMethod(other._removeAndDestroyMethod) {} Subscription &operator=(Subscription &&other) { qSwap(_node, other._node); qSwap(_removeAndDestroyMethod, other._removeAndDestroyMethod); @@ -87,34 +80,30 @@ public: private: struct Node { - Node(const QSharedPointer &observable) : observable(observable) { - } + Node(const QSharedPointer &observable) + : observable(observable) {} Node *next = nullptr; Node *prev = nullptr; QWeakPointer observable; }; - using RemoveAndDestroyMethod = void(*)(Node*); - Subscription(Node *node, RemoveAndDestroyMethod removeAndDestroyMethod) : _node(node), _removeAndDestroyMethod(removeAndDestroyMethod) { - } + using RemoveAndDestroyMethod = void (*)(Node *); + Subscription(Node *node, RemoveAndDestroyMethod removeAndDestroyMethod) + : _node(node) + , _removeAndDestroyMethod(removeAndDestroyMethod) {} Node *_node = nullptr; RemoveAndDestroyMethod _removeAndDestroyMethod; - template - friend class internal::CommonObservableData; - - template - friend class internal::ObservableData; + template friend class internal::CommonObservableData; + template friend class internal::ObservableData; }; namespace internal { -template -class BaseObservable; +template class BaseObservable; -template -class CommonObservable { +template class CommonObservable { public: Subscription add_subscription(Handler &&handler) { if (!_data) { @@ -128,7 +117,6 @@ private: friend class CommonObservableData; friend class BaseObservable::is_fast_copy_type::value>; - }; template @@ -139,7 +127,6 @@ public: this->_data->notify(std::move(event), sync); } } - }; template @@ -156,18 +143,16 @@ public: this->_data->notify(std::move(event_copy), sync); } } - }; } // namespace internal namespace internal { -template -class CommonObservableData : public BaseObservableData { +template class CommonObservableData : public BaseObservableData { public: - CommonObservableData(CommonObservable *observable) : _observable(observable) { - } + CommonObservableData(CommonObservable *observable) + : _observable(observable) {} Subscription append(Handler &&handler) { auto node = new Node(_observable->_data, std::move(handler)); @@ -178,7 +163,7 @@ public: } else { _begin = _end = node; } - return { _end, &CommonObservableData::removeAndDestroyNode }; + return {_end, &CommonObservableData::removeAndDestroyNode}; } bool empty() const { @@ -187,8 +172,9 @@ public: private: struct Node : public Subscription::Node { - Node(const QSharedPointer &observer, Handler &&handler) : Subscription::Node(observer), handler(std::move(handler)) { - } + Node(const QSharedPointer &observer, Handler &&handler) + : Subscription::Node(observer) + , handler(std::move(handler)) {} Handler handler; }; @@ -200,13 +186,13 @@ private: node->next->prev = node->prev; } if (_begin == node) { - _begin = static_cast(node->next); + _begin = static_cast(node->next); } if (_end == node) { - _end = static_cast(node->prev); + _end = static_cast(node->prev); } if (_current == node) { - _current = static_cast(node->prev); + _current = static_cast(node->prev); } else if (!_begin) { _observable->_data.reset(); } @@ -214,18 +200,17 @@ private: static void removeAndDestroyNode(Subscription::Node *node) { if (auto that = node->observable.toStrongRef()) { - static_cast(that.data())->remove(node); + static_cast(that.data())->remove(node); } - delete static_cast(node); + delete static_cast(node); } - template - void notifyEnumerate(CallCurrent callCurrent) { + template void notifyEnumerate(CallCurrent callCurrent) { _current = _begin; do { callCurrent(); if (_current) { - _current = static_cast(_current->next); + _current = static_cast(_current->next); } else if (_begin) { _current = _begin; } else { @@ -249,11 +234,9 @@ private: ObservableCallHandlers _callHandlers; friend class ObservableData; - }; -template -class ObservableData : public CommonObservableData { +template class ObservableData : public CommonObservableData { public: using CommonObservableData::CommonObservableData; @@ -266,9 +249,7 @@ public: callHandlers(); } else { if (!this->_callHandlers) { - this->_callHandlers = [this]() { - callHandlers(); - }; + this->_callHandlers = [this]() { callHandlers(); }; } if (_events.empty()) { RegisterPendingObservable(&this->_callHandlers); @@ -286,9 +267,7 @@ private: _handling = true; auto events = base::take(_events); for (auto &event : events) { - this->notifyEnumerate([this, &event]() { - this->_current->handler(event); - }); + this->notifyEnumerate([this, &event]() { this->_current->handler(event); }); if (this->destroyMeIfEmpty()) { return; } @@ -299,11 +278,9 @@ private: std::deque _events; bool _handling = false; - }; -template -class ObservableData : public CommonObservableData { +template class ObservableData : public CommonObservableData { public: using CommonObservableData::CommonObservableData; @@ -316,9 +293,7 @@ public: callHandlers(); } else { if (!this->_callHandlers) { - this->_callHandlers = [this]() { - callHandlers(); - }; + this->_callHandlers = [this]() { callHandlers(); }; } if (!_eventsCount) { RegisterPendingObservable(&this->_callHandlers); @@ -336,9 +311,7 @@ private: _handling = true; auto eventsCount = base::take(_eventsCount); for (int i = 0; i != eventsCount; ++i) { - this->notifyEnumerate([this]() { - this->_current->handler(); - }); + this->notifyEnumerate([this]() { this->_current->handler(); }); if (this->destroyMeIfEmpty()) { return; } @@ -349,38 +322,36 @@ private: int _eventsCount = 0; bool _handling = false; - }; template -class BaseObservable::is_fast_copy_type::value> : public internal::CommonObservable { +class BaseObservable::is_fast_copy_type::value> + : public internal::CommonObservable { public: void notify(bool sync = false) { if (this->_data) { this->_data->notify(sync); } } - }; } // namespace internal template > -class Observable : public internal::BaseObservable::is_fast_copy_type::value> { +class Observable + : public internal::BaseObservable::is_fast_copy_type::value> { public: Observable() = default; Observable(const Observable &other) = delete; Observable(Observable &&other) = delete; Observable &operator=(const Observable &other) = delete; Observable &operator=(Observable &&other) = delete; - }; -template -class Variable { +template class Variable { public: - Variable(parameter_type startValue = Type()) : _value(startValue) { - } + Variable(parameter_type startValue = Type()) + : _value(startValue) {} Variable(Variable &&other) = default; Variable &operator=(Variable &&other) = default; @@ -399,8 +370,7 @@ public: } } - template - void process(Callback callback, bool sync = false) { + template void process(Callback callback, bool sync = false) { callback(_value); changed().notify(_value, sync); } @@ -412,7 +382,6 @@ public: private: Type _value; mutable Observable _changed; - }; class Subscriber { @@ -428,13 +397,11 @@ protected: return subscribe(*observable, std::forward(handler)); } - template - size_t subscribe(const base::Variable &variable, Lambda &&handler) { + template size_t subscribe(const base::Variable &variable, Lambda &&handler) { return subscribe(variable.changed(), std::forward(handler)); } - template - size_t subscribe(const base::Variable *variable, Lambda &&handler) { + template size_t subscribe(const base::Variable *variable, Lambda &&handler) { return subscribe(variable->changed(), std::forward(handler)); } @@ -459,7 +426,6 @@ protected: private: std::vector _subscriptions; - }; void HandleObservables(); diff --git a/Telegram/SourceFiles/base/openssl_help.h b/Telegram/SourceFiles/base/openssl_help.h index d00af74ea..c8020906c 100644 --- a/Telegram/SourceFiles/base/openssl_help.h +++ b/Telegram/SourceFiles/base/openssl_help.h @@ -21,8 +21,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #pragma once #include -#include #include +#include #include "base/assertion.h" #include "core/utils.h" @@ -30,11 +30,11 @@ namespace openssl { class Context { public: - Context() : _data(BN_CTX_new()) { - } + Context() + : _data(BN_CTX_new()) {} Context(const Context &other) = delete; - Context(Context &&other) : _data(base::take(other._data)) { - } + Context(Context &&other) + : _data(base::take(other._data)) {} Context &operator=(const Context &other) = delete; Context &operator=(Context &&other) { _data = base::take(other._data); @@ -52,14 +52,14 @@ public: private: BN_CTX *_data = nullptr; - }; class BigNum { public: - BigNum() : _data(BN_new()) { - } - BigNum(const BigNum &other) : BigNum() { + BigNum() + : _data(BN_new()) {} + BigNum(const BigNum &other) + : BigNum() { *this = other; } BigNum &operator=(const BigNum &other) { @@ -72,10 +72,12 @@ public: BN_clear_free(raw()); } - explicit BigNum(unsigned int word) : BigNum() { + explicit BigNum(unsigned int word) + : BigNum() { setWord(word); } - explicit BigNum(base::const_byte_span bytes) : BigNum() { + explicit BigNum(base::const_byte_span bytes) + : BigNum() { setBytes(bytes); } @@ -85,18 +87,11 @@ public: } } void setBytes(base::const_byte_span bytes) { - if (!BN_bin2bn( - reinterpret_cast(bytes.data()), - bytes.size(), - raw())) { + if (!BN_bin2bn(reinterpret_cast(bytes.data()), bytes.size(), raw())) { _failed = true; } } - void setModExp( - const BigNum &a, - const BigNum &p, - const BigNum &m, - const Context &context = Context()) { + void setModExp(const BigNum &a, const BigNum &p, const BigNum &m, const Context &context = Context()) { if (a.failed() || p.failed() || m.failed()) { _failed = true; } else if (a.isNegative() || p.isNegative() || m.isNegative()) { @@ -143,11 +138,7 @@ public: return false; } constexpr auto kMillerRabinIterationCount = 30; - auto result = BN_is_prime_ex( - raw(), - kMillerRabinIterationCount, - context.raw(), - NULL); + auto result = BN_is_prime_ex(raw(), kMillerRabinIterationCount, context.raw(), NULL); if (result == 1) { return true; } else if (result != 0) { @@ -182,9 +173,7 @@ public: } auto length = BN_num_bytes(raw()); auto result = base::byte_vector(length, gsl::byte()); - auto resultSize = BN_bn2bin( - raw(), - reinterpret_cast(result.data())); + auto resultSize = BN_bn2bin(raw(), reinterpret_cast(result.data())); Assert(resultSize == length); return result; } @@ -212,7 +201,6 @@ public: private: BIGNUM *_data = nullptr; mutable bool _failed = false; - }; inline BigNum operator-(const BigNum &a, const BigNum &b) { @@ -223,18 +211,20 @@ inline BigNum operator-(const BigNum &a, const BigNum &b) { inline base::byte_array Sha256(base::const_byte_span bytes) { auto result = base::byte_array(); - SHA256(reinterpret_cast(bytes.data()), bytes.size(), reinterpret_cast(result.data())); + SHA256(reinterpret_cast(bytes.data()), bytes.size(), + reinterpret_cast(result.data())); return result; } inline base::byte_array Sha1(base::const_byte_span bytes) { auto result = base::byte_array(); - SHA1(reinterpret_cast(bytes.data()), bytes.size(), reinterpret_cast(result.data())); + SHA1(reinterpret_cast(bytes.data()), bytes.size(), + reinterpret_cast(result.data())); return result; } inline int FillRandom(base::byte_span bytes) { - return RAND_bytes(reinterpret_cast(bytes.data()), bytes.size()); + return RAND_bytes(reinterpret_cast(bytes.data()), bytes.size()); } } // namespace openssl diff --git a/Telegram/SourceFiles/base/optional.h b/Telegram/SourceFiles/base/optional.h index 6f5ed9e1f..e04ef1a3c 100644 --- a/Telegram/SourceFiles/base/optional.h +++ b/Telegram/SourceFiles/base/optional.h @@ -44,23 +44,21 @@ struct none_type { bool operator>=(none_type other) const { return true; } - }; constexpr none_type none = {}; -template -class optional_variant { +template class optional_variant { public: - optional_variant() : _impl(none) { - } - optional_variant(const optional_variant &other) : _impl(other._impl) { - } - optional_variant(optional_variant &&other) : _impl(std::move(other._impl)) { - } + optional_variant() + : _impl(none) {} + optional_variant(const optional_variant &other) + : _impl(other._impl) {} + optional_variant(optional_variant &&other) + : _impl(std::move(other._impl)) {} template >::value>> - optional_variant(T &&value) : _impl(std::forward(value)) { - } + optional_variant(T &&value) + : _impl(std::forward(value)) {} optional_variant &operator=(const optional_variant &other) { _impl = other._impl; return *this; @@ -97,65 +95,43 @@ public: return _impl >= other._impl; } - template - decltype(auto) is() const { + template decltype(auto) is() const { return _impl.template is(); } - template - decltype(auto) get_unchecked() { + template decltype(auto) get_unchecked() { return _impl.template get_unchecked(); } - template - decltype(auto) get_unchecked() const { + template decltype(auto) get_unchecked() const { return _impl.template get_unchecked(); } private: variant _impl; - }; -template -inline T *get_if(optional_variant *v) { +template inline T *get_if(optional_variant *v) { return (v && v->template is()) ? &v->template get_unchecked() : nullptr; } -template -inline const T *get_if(const optional_variant *v) { +template inline const T *get_if(const optional_variant *v) { return (v && v->template is()) ? &v->template get_unchecked() : nullptr; } -template -class optional; +template class optional; -template -struct optional_wrap_once { - using type = optional; -}; +template struct optional_wrap_once { using type = optional; }; -template -struct optional_wrap_once> { - using type = optional; -}; +template struct optional_wrap_once> { using type = optional; }; -template -using optional_wrap_once_t = typename optional_wrap_once>::type; +template using optional_wrap_once_t = typename optional_wrap_once>::type; -template -struct optional_chain_result { - using type = optional_wrap_once_t; -}; +template struct optional_chain_result { using type = optional_wrap_once_t; }; -template <> -struct optional_chain_result { - using type = bool; -}; +template <> struct optional_chain_result { using type = bool; }; -template -using optional_chain_result_t = typename optional_chain_result::type; +template using optional_chain_result_t = typename optional_chain_result::type; -template -class optional : public optional_variant { +template class optional : public optional_variant { public: using optional_variant::optional_variant; @@ -179,37 +155,28 @@ public: Expects(result != nullptr); return result; } - }; -template -optional_wrap_once_t make_optional(Type &&value) { - return optional_wrap_once_t { std::forward(value) }; +template optional_wrap_once_t make_optional(Type &&value) { + return optional_wrap_once_t{std::forward(value)}; } template -inline auto optional_chain( - const optional &value, - Method &method, - std::false_type) --> optional_chain_result_t { +inline auto optional_chain(const optional &value, Method &method, std::false_type) + -> optional_chain_result_t { return value ? make_optional(method(*value)) : none; } template -inline auto optional_chain( - const optional &value, - Method &method, - std::true_type) --> optional_chain_result_t { +inline auto optional_chain(const optional &value, Method &method, std::true_type) + -> optional_chain_result_t { return value ? (method(*value), true) : false; } template -inline auto operator|(const optional &value, Method method) --> optional_chain_result_t { +inline auto operator|(const optional &value, Method method) -> optional_chain_result_t { using is_void_return = std::is_same; - return optional_chain(value, method, is_void_return {}); + return optional_chain(value, method, is_void_return{}); } } // namespace base diff --git a/Telegram/SourceFiles/base/ordered_set.h b/Telegram/SourceFiles/base/ordered_set.h index 51c02c8ff..a643d916c 100644 --- a/Telegram/SourceFiles/base/ordered_set.h +++ b/Telegram/SourceFiles/base/ordered_set.h @@ -23,10 +23,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include // ordered set template based on QMap -template -class OrderedSet { - struct NullType { - }; +template class OrderedSet { + struct NullType {}; using Self = OrderedSet; using Impl = QMap; using IteratorImpl = typename Impl::iterator; @@ -41,16 +39,36 @@ public: OrderedSet &operator=(OrderedSet &&other) = default; ~OrderedSet() = default; - inline bool operator==(const Self &other) const { return impl_ == other.impl_; } - inline bool operator!=(const Self &other) const { return impl_ != other.impl_; } - inline int size() const { return impl_.size(); } - inline bool isEmpty() const { return impl_.isEmpty(); } - inline void detach() { return impl_.detach(); } - inline bool isDetached() const { return impl_.isDetached(); } - inline void clear() { return impl_.clear(); } - inline QList values() const { return impl_.keys(); } - inline const T &first() const { return impl_.firstKey(); } - inline const T &last() const { return impl_.lastKey(); } + inline bool operator==(const Self &other) const { + return impl_ == other.impl_; + } + inline bool operator!=(const Self &other) const { + return impl_ != other.impl_; + } + inline int size() const { + return impl_.size(); + } + inline bool isEmpty() const { + return impl_.isEmpty(); + } + inline void detach() { + return impl_.detach(); + } + inline bool isDetached() const { + return impl_.isDetached(); + } + inline void clear() { + return impl_.clear(); + } + inline QList values() const { + return impl_.keys(); + } + inline const T &first() const { + return impl_.firstKey(); + } + inline const T &last() const { + return impl_.lastKey(); + } class const_iterator; class iterator { @@ -64,29 +82,60 @@ public: iterator() = default; iterator(const iterator &other) = default; iterator &operator=(const iterator &other) = default; - inline const T &operator*() const { return impl_.key(); } - inline const T *operator->() const { return &impl_.key(); } - inline bool operator==(const iterator &other) const { return impl_ == other.impl_; } - inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; } - inline iterator &operator++() { ++impl_; return *this; } - inline iterator operator++(int) { return iterator(impl_++); } - inline iterator &operator--() { --impl_; return *this; } - inline iterator operator--(int) { return iterator(impl_--); } - inline iterator operator+(int j) const { return iterator(impl_ + j); } - inline iterator operator-(int j) const { return iterator(impl_ - j); } - inline iterator &operator+=(int j) { impl_ += j; return *this; } - inline iterator &operator-=(int j) { impl_ -= j; return *this; } + inline const T &operator*() const { + return impl_.key(); + } + inline const T *operator->() const { + return &impl_.key(); + } + inline bool operator==(const iterator &other) const { + return impl_ == other.impl_; + } + inline bool operator!=(const iterator &other) const { + return impl_ != other.impl_; + } + inline iterator &operator++() { + ++impl_; + return *this; + } + inline iterator operator++(int) { + return iterator(impl_++); + } + inline iterator &operator--() { + --impl_; + return *this; + } + inline iterator operator--(int) { + return iterator(impl_--); + } + inline iterator operator+(int j) const { + return iterator(impl_ + j); + } + inline iterator operator-(int j) const { + return iterator(impl_ - j); + } + inline iterator &operator+=(int j) { + impl_ += j; + return *this; + } + inline iterator &operator-=(int j) { + impl_ -= j; + return *this; + } friend class const_iterator; - inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; } - inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; } + inline bool operator==(const const_iterator &other) const { + return impl_ == other.impl_; + } + inline bool operator!=(const const_iterator &other) const { + return impl_ != other.impl_; + } private: - explicit iterator(const IteratorImpl &impl) : impl_(impl) { - } + explicit iterator(const IteratorImpl &impl) + : impl_(impl) {} IteratorImpl impl_; friend class OrderedSet; - }; friend class iterator; @@ -101,66 +150,136 @@ public: const_iterator() = default; const_iterator(const const_iterator &other) = default; const_iterator &operator=(const const_iterator &other) = default; - const_iterator(const iterator &other) : impl_(other.impl_) { - } + const_iterator(const iterator &other) + : impl_(other.impl_) {} const_iterator &operator=(const iterator &other) { impl_ = other.impl_; return *this; } - inline const T &operator*() const { return impl_.key(); } - inline const T *operator->() const { return &impl_.key(); } - inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; } - inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; } - inline const_iterator &operator++() { ++impl_; return *this; } - inline const_iterator operator++(int) { return const_iterator(impl_++); } - inline const_iterator &operator--() { --impl_; return *this; } - inline const_iterator operator--(int) { return const_iterator(impl_--); } - inline const_iterator operator+(int j) const { return const_iterator(impl_ + j); } - inline const_iterator operator-(int j) const { return const_iterator(impl_ - j); } - inline const_iterator &operator+=(int j) { impl_ += j; return *this; } - inline const_iterator &operator-=(int j) { impl_ -= j; return *this; } + inline const T &operator*() const { + return impl_.key(); + } + inline const T *operator->() const { + return &impl_.key(); + } + inline bool operator==(const const_iterator &other) const { + return impl_ == other.impl_; + } + inline bool operator!=(const const_iterator &other) const { + return impl_ != other.impl_; + } + inline const_iterator &operator++() { + ++impl_; + return *this; + } + inline const_iterator operator++(int) { + return const_iterator(impl_++); + } + inline const_iterator &operator--() { + --impl_; + return *this; + } + inline const_iterator operator--(int) { + return const_iterator(impl_--); + } + inline const_iterator operator+(int j) const { + return const_iterator(impl_ + j); + } + inline const_iterator operator-(int j) const { + return const_iterator(impl_ - j); + } + inline const_iterator &operator+=(int j) { + impl_ += j; + return *this; + } + inline const_iterator &operator-=(int j) { + impl_ -= j; + return *this; + } friend class iterator; - inline bool operator==(const iterator &other) const { return impl_ == other.impl_; } - inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; } + inline bool operator==(const iterator &other) const { + return impl_ == other.impl_; + } + inline bool operator!=(const iterator &other) const { + return impl_ != other.impl_; + } private: - explicit const_iterator(const ConstIteratorImpl &impl) : impl_(impl) { - } + explicit const_iterator(const ConstIteratorImpl &impl) + : impl_(impl) {} ConstIteratorImpl impl_; friend class OrderedSet; - }; friend class const_iterator; // STL style - inline iterator begin() { return iterator(impl_.begin()); } - inline const_iterator begin() const { return const_iterator(impl_.cbegin()); } - inline const_iterator constBegin() const { return const_iterator(impl_.cbegin()); } - inline const_iterator cbegin() const { return const_iterator(impl_.cbegin()); } - inline iterator end() { detach(); return iterator(impl_.end()); } - inline const_iterator end() const { return const_iterator(impl_.cend()); } - inline const_iterator constEnd() const { return const_iterator(impl_.cend()); } - inline const_iterator cend() const { return const_iterator(impl_.cend()); } - inline iterator erase(iterator it) { return iterator(impl_.erase(it.impl_)); } + inline iterator begin() { + return iterator(impl_.begin()); + } + inline const_iterator begin() const { + return const_iterator(impl_.cbegin()); + } + inline const_iterator constBegin() const { + return const_iterator(impl_.cbegin()); + } + inline const_iterator cbegin() const { + return const_iterator(impl_.cbegin()); + } + inline iterator end() { + detach(); + return iterator(impl_.end()); + } + inline const_iterator end() const { + return const_iterator(impl_.cend()); + } + inline const_iterator constEnd() const { + return const_iterator(impl_.cend()); + } + inline const_iterator cend() const { + return const_iterator(impl_.cend()); + } + inline iterator erase(iterator it) { + return iterator(impl_.erase(it.impl_)); + } - inline iterator insert(const T &value) { return iterator(impl_.insert(value, NullType())); } - inline iterator insert(const_iterator pos, const T &value) { return iterator(impl_.insert(pos.impl_, value, NullType())); } - inline int remove(const T &value) { return impl_.remove(value); } - inline bool contains(const T &value) const { return impl_.contains(value); } + inline iterator insert(const T &value) { + return iterator(impl_.insert(value, NullType())); + } + inline iterator insert(const_iterator pos, const T &value) { + return iterator(impl_.insert(pos.impl_, value, NullType())); + } + inline int remove(const T &value) { + return impl_.remove(value); + } + inline bool contains(const T &value) const { + return impl_.contains(value); + } // more Qt typedef iterator Iterator; typedef const_iterator ConstIterator; - inline int count() const { return impl_.count(); } - inline iterator find(const T &value) { return iterator(impl_.find(value)); } - inline const_iterator find(const T &value) const { return const_iterator(impl_.constFind(value)); } - inline const_iterator constFind(const T &value) const { return const_iterator(impl_.constFind(value)); } - inline Self &unite(const Self &other) { impl_.unite(other.impl_); return *this; } + inline int count() const { + return impl_.count(); + } + inline iterator find(const T &value) { + return iterator(impl_.find(value)); + } + inline const_iterator find(const T &value) const { + return const_iterator(impl_.constFind(value)); + } + inline const_iterator constFind(const T &value) const { + return const_iterator(impl_.constFind(value)); + } + inline Self &unite(const Self &other) { + impl_.unite(other.impl_); + return *this; + } // STL compatibility typedef typename Impl::difference_type difference_type; typedef typename Impl::size_type size_type; - inline bool empty() const { return impl_.empty(); } - + inline bool empty() const { + return impl_.empty(); + } }; diff --git a/Telegram/SourceFiles/base/parse_helper.h b/Telegram/SourceFiles/base/parse_helper.h index 7b1b553a9..5e7bb9c84 100644 --- a/Telegram/SourceFiles/base/parse_helper.h +++ b/Telegram/SourceFiles/base/parse_helper.h @@ -20,9 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once +#include "base/assertion.h" #include #include -#include "base/assertion.h" namespace base { @@ -33,11 +33,7 @@ QByteArray stripComments(const QByteArray &content); inline bool skipWhitespaces(const char *&from, const char *end) { Assert(from <= end); - while (from != end && ( - (*from == ' ') || - (*from == '\n') || - (*from == '\t') || - (*from == '\r'))) { + while (from != end && ((*from == ' ') || (*from == '\n') || (*from == '\t') || (*from == '\r'))) { ++from; } return (from != end); @@ -46,11 +42,8 @@ inline bool skipWhitespaces(const char *&from, const char *end) { inline QLatin1String readName(const char *&from, const char *end) { Assert(from <= end); auto start = from; - while (from != end && ( - (*from >= 'a' && *from <= 'z') || - (*from >= 'A' && *from <= 'Z') || - (*from >= '0' && *from <= '9') || - (*from == '_'))) { + while (from != end && ((*from >= 'a' && *from <= 'z') || (*from >= 'A' && *from <= 'Z') || + (*from >= '0' && *from <= '9') || (*from == '_'))) { ++from; } return QLatin1String(start, from - start); diff --git a/Telegram/SourceFiles/base/qthelp_regex.h b/Telegram/SourceFiles/base/qthelp_regex.h index 398503483..e47ebff81 100644 --- a/Telegram/SourceFiles/base/qthelp_regex.h +++ b/Telegram/SourceFiles/base/qthelp_regex.h @@ -30,10 +30,10 @@ class RegularExpressionMatch { public: RegularExpressionMatch(const QRegularExpressionMatch &other) = delete; RegularExpressionMatch(const RegularExpressionMatch &other) = delete; - RegularExpressionMatch(QRegularExpressionMatch &&match) : data_(std::move(match)) { - } - RegularExpressionMatch(RegularExpressionMatch &&other) : data_(std::move(other.data_)) { - } + RegularExpressionMatch(QRegularExpressionMatch &&match) + : data_(std::move(match)) {} + RegularExpressionMatch(RegularExpressionMatch &&other) + : data_(std::move(other.data_)) {} RegularExpressionMatch &operator=(const QRegularExpressionMatch &match) = delete; RegularExpressionMatch &operator=(const RegularExpressionMatch &other) = delete; RegularExpressionMatch &operator=(QRegularExpressionMatch &&match) { @@ -56,7 +56,6 @@ public: private: QRegularExpressionMatch data_; - }; enum class RegExOption { @@ -74,14 +73,17 @@ enum class RegExOption { #endif // OS_MAC_OLD }; using RegExOptions = base::flags; -inline constexpr auto is_flag_type(RegExOption) { return true; }; +inline constexpr auto is_flag_type(RegExOption) { + return true; +}; inline RegularExpressionMatch regex_match(const QString &string, const QString &subject, RegExOptions options = 0) { auto qtOptions = QRegularExpression::PatternOptions(static_cast(options)); return RegularExpressionMatch(QRegularExpression(string, qtOptions).match(subject)); } -inline RegularExpressionMatch regex_match(const QString &string, const QStringRef &subjectRef, RegExOptions options = 0) { +inline RegularExpressionMatch regex_match(const QString &string, const QStringRef &subjectRef, + RegExOptions options = 0) { auto qtOptions = QRegularExpression::PatternOptions(static_cast(options)); #ifndef OS_MAC_OLD return RegularExpressionMatch(QRegularExpression(string, qtOptions).match(subjectRef)); diff --git a/Telegram/SourceFiles/base/qthelp_url.cpp b/Telegram/SourceFiles/base/qthelp_url.cpp index 4f04c013a..8db9ab5ef 100644 --- a/Telegram/SourceFiles/base/qthelp_url.cpp +++ b/Telegram/SourceFiles/base/qthelp_url.cpp @@ -18,9 +18,9 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include -#include "core/utils.h" #include "base/qthelp_url.h" +#include "core/utils.h" +#include namespace qthelp { @@ -34,7 +34,7 @@ QMap url_parse_params(const QString ¶ms, UrlParamNameTrans return name; }; - auto paramsList = params.split('&'); + auto paramsList = params.split('&'); for_const (auto ¶m, paramsList) { // Skip params without a name (starting with '='). if (auto separatorPosition = param.indexOf('=')) { diff --git a/Telegram/SourceFiles/base/qthelp_url.h b/Telegram/SourceFiles/base/qthelp_url.h index de86b77f3..33fbcaf39 100644 --- a/Telegram/SourceFiles/base/qthelp_url.h +++ b/Telegram/SourceFiles/base/qthelp_url.h @@ -20,9 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once +#include #include #include -#include namespace qthelp { @@ -39,6 +39,7 @@ enum class UrlParamNameTransform { ToLower, }; // Parses a string like "p1=v1&p2=v2&..&pn=vn" to a map. -QMap url_parse_params(const QString ¶ms, UrlParamNameTransform transform = UrlParamNameTransform::NoTransform); +QMap url_parse_params(const QString ¶ms, + UrlParamNameTransform transform = UrlParamNameTransform::NoTransform); } // namespace qthelp diff --git a/Telegram/SourceFiles/base/runtime_composer.cpp b/Telegram/SourceFiles/base/runtime_composer.cpp index 2abbe86d6..5a5a3c933 100644 --- a/Telegram/SourceFiles/base/runtime_composer.cpp +++ b/Telegram/SourceFiles/base/runtime_composer.cpp @@ -18,15 +18,13 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include #include "base/runtime_composer.h" +#include struct RuntimeComposerMetadatasMap { - QMap data; + QMap data; ~RuntimeComposerMetadatasMap() { - for_const (const RuntimeComposerMetadata *p, data) { - delete p; - } + for_const (const RuntimeComposerMetadata *p, data) { delete p; } } }; diff --git a/Telegram/SourceFiles/base/runtime_composer.h b/Telegram/SourceFiles/base/runtime_composer.h index 4af9ba0cd..b209be614 100644 --- a/Telegram/SourceFiles/base/runtime_composer.h +++ b/Telegram/SourceFiles/base/runtime_composer.h @@ -19,28 +19,28 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include #include +#include #include "base/assertion.h" #include "core/utils.h" class RuntimeComposer; -typedef void(*RuntimeComponentConstruct)(void *location, RuntimeComposer *composer); -typedef void(*RuntimeComponentDestruct)(void *location); -typedef void(*RuntimeComponentMove)(void *location, void *waslocation); +typedef void (*RuntimeComponentConstruct)(void *location, RuntimeComposer *composer); +typedef void (*RuntimeComponentDestruct)(void *location); +typedef void (*RuntimeComponentMove)(void *location, void *waslocation); struct RuntimeComponentWrapStruct { // Don't init any fields, because it is only created in // global scope, so it will be filled by zeros from the start. RuntimeComponentWrapStruct() = default; - RuntimeComponentWrapStruct(std::size_t size, std::size_t align, RuntimeComponentConstruct construct, RuntimeComponentDestruct destruct, RuntimeComponentMove move) - : Size(size) - , Align(align) - , Construct(construct) - , Destruct(destruct) - , Move(move) { - } + RuntimeComponentWrapStruct(std::size_t size, std::size_t align, RuntimeComponentConstruct construct, + RuntimeComponentDestruct destruct, RuntimeComponentMove move) + : Size(size) + , Align(align) + , Construct(construct) + , Destruct(destruct) + , Move(move) {} std::size_t Size; std::size_t Align; RuntimeComponentConstruct Construct; @@ -48,16 +48,14 @@ struct RuntimeComponentWrapStruct { RuntimeComponentMove Move; }; -template -struct CeilDivideMinimumOne { +template struct CeilDivideMinimumOne { static constexpr int Result = ((Value / Denominator) + ((!Value || (Value % Denominator)) ? 1 : 0)); }; extern RuntimeComponentWrapStruct RuntimeComponentWraps[64]; extern QAtomicInt RuntimeComponentIndexLast; -template -struct RuntimeComponent { +template struct RuntimeComponent { RuntimeComponent() { // While there is no std::aligned_alloc(). static_assert(alignof(Type) <= alignof(std::max_align_t), "Components should align to std::max_align_t!"); @@ -77,12 +75,9 @@ struct RuntimeComponent { if (RuntimeComponentIndexLast.testAndSetOrdered(last, last + 1)) { Assert(last < 64); if (MyIndex.testAndSetOrdered(0, last + 1)) { - RuntimeComponentWraps[last] = RuntimeComponentWrapStruct( - sizeof(Type), - alignof(Type), - Type::RuntimeComponentConstruct, - Type::RuntimeComponentDestruct, - Type::RuntimeComponentMove); + RuntimeComponentWraps[last] = + RuntimeComponentWrapStruct(sizeof(Type), alignof(Type), Type::RuntimeComponentConstruct, + Type::RuntimeComponentDestruct, Type::RuntimeComponentMove); } break; } @@ -98,17 +93,17 @@ protected: new (location) Type(); } static void RuntimeComponentDestruct(void *location) { - ((Type*)location)->~Type(); + ((Type *)location)->~Type(); } static void RuntimeComponentMove(void *location, void *waslocation) { - *(Type*)location = std::move(*(Type*)waslocation); + *(Type *)location = std::move(*(Type *)waslocation); } - }; class RuntimeComposerMetadata { public: - RuntimeComposerMetadata(quint64 mask) : _mask(mask) { + RuntimeComposerMetadata(quint64 mask) + : _mask(mask) { for (int i = 0; i != 64; ++i) { auto componentBit = (1ULL << i); if (_mask & componentBit) { @@ -130,9 +125,9 @@ public: } // Meta pointer in the start. - std::size_t size = sizeof(const RuntimeComposerMetadata*); - std::size_t align = alignof(const RuntimeComposerMetadata*); - std::size_t offsets[64] = { 0 }; + std::size_t size = sizeof(const RuntimeComposerMetadata *); + std::size_t align = alignof(const RuntimeComposerMetadata *); + std::size_t offsets[64] = {0}; int last = 64; bool equals(quint64 mask) const { @@ -147,14 +142,14 @@ public: private: quint64 _mask; - }; const RuntimeComposerMetadata *GetRuntimeComposerMetadata(quint64 mask); class RuntimeComposer { public: - RuntimeComposer(quint64 mask = 0) : _data(zerodata()) { + RuntimeComposer(quint64 mask = 0) + : _data(zerodata()) { if (mask) { auto meta = GetRuntimeComposerMetadata(mask); @@ -202,18 +197,15 @@ public: } } - template - bool Has() const { + template bool Has() const { return (_meta()->offsets[Type::Index()] >= sizeof(_meta())); } - template - Type *Get() { - return static_cast(_dataptr(_meta()->offsets[Type::Index()])); + template Type *Get() { + return static_cast(_dataptr(_meta()->offsets[Type::Index()])); } - template - const Type *Get() const { - return static_cast(_dataptr(_meta()->offsets[Type::Index()])); + template const Type *Get() const { + return static_cast(_dataptr(_meta()->offsets[Type::Index()])); } protected: @@ -247,18 +239,17 @@ private: } void *_dataptrunsafe(size_t skip) const { - return (char*)_data + skip; + return (char *)_data + skip; } void *_dataptr(size_t skip) const { return (skip >= sizeof(_meta())) ? _dataptrunsafe(skip) : nullptr; } const RuntimeComposerMetadata *&_meta() const { - return *static_cast(_data); + return *static_cast(_data); } void *_data = nullptr; void swap(RuntimeComposer &other) { std::swap(_data, other._data); } - }; diff --git a/Telegram/SourceFiles/base/task_queue.cpp b/Telegram/SourceFiles/base/task_queue.cpp index c54ae16db..a9d73583f 100644 --- a/Telegram/SourceFiles/base/task_queue.cpp +++ b/Telegram/SourceFiles/base/task_queue.cpp @@ -19,14 +19,14 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include -#include -#include +#include "base/task_queue.h" +#include "base/assertion.h" +#include "facades.h" #include #include -#include "base/assertion.h" -#include "base/task_queue.h" -#include "facades.h" +#include +#include +#include namespace base { namespace { @@ -51,20 +51,22 @@ private: void Insert(TaskQueue *queue, int list_index_); void Remove(TaskQueue *queue, int list_index_); - TaskQueue *Tail() { return &tail_; } - const TaskQueue *Tail() const { return &tail_; } + TaskQueue *Tail() { + return &tail_; + } + const TaskQueue *Tail() const { + return &tail_; + } - TaskQueue tail_ = { Type::Special, Priority::Normal }; + TaskQueue tail_ = {Type::Special, Priority::Normal}; TaskQueue *(lists_[kQueuesListsCount]); - }; class TaskQueue::TaskThreadPool { - struct Private { - }; + struct Private {}; public: - TaskThreadPool(const Private &) { } + TaskThreadPool(const Private &) {} static const std::shared_ptr &Instance(); void AddQueueTask(TaskQueue *queue, Task &&task); @@ -85,7 +87,6 @@ private: bool stopped_ = false; int tasks_in_process_ = 0; int background_tasks_in_process_ = 0; - }; TaskQueue::TaskQueueList::TaskQueueList() { @@ -175,7 +176,7 @@ TaskQueue *TaskQueue::TaskQueueList::TakeFirst(int list_index_) { auto queue = lists_[list_index_]; Unregister(queue); -// log_msgs.push_back("Unregistered from list in TakeFirst"); + // log_msgs.push_back("Unregistered from list in TakeFirst"); return queue; } @@ -195,9 +196,7 @@ void TaskQueue::TaskThreadPool::AddQueueTask(TaskQueue *queue, Task &&task) { } } if (will_create_thread) { - threads_.emplace_back([this]() { - ThreadFunction(); - }); + threads_.emplace_back([this]() { ThreadFunction(); }); } else if (some_threads_are_vacant) { Assert(threads_count > tasks_in_process_); thread_condition_.wakeOne(); @@ -309,8 +308,8 @@ void TaskQueue::TaskThreadPool::ThreadFunction() { } TaskQueue::TaskQueue(Type type, Priority priority) -: type_(type) -, priority_(priority) { + : type_(type) + , priority_(priority) { if (type_ != Type::Main && type_ != Type::Special) { weak_thread_pool_ = TaskThreadPool::Instance(); } @@ -381,17 +380,17 @@ bool TaskQueue::IsMyThread() const { // Default queues. TaskQueue &TaskQueue::Main() { // static - static TaskQueue MainQueue { Type::Main, Priority::Normal }; + static TaskQueue MainQueue{Type::Main, Priority::Normal}; return MainQueue; } TaskQueue &TaskQueue::Normal() { // static - static TaskQueue NormalQueue { Type::Concurrent, Priority::Normal }; + static TaskQueue NormalQueue{Type::Concurrent, Priority::Normal}; return NormalQueue; } TaskQueue &TaskQueue::Background() { // static - static TaskQueue BackgroundQueue { Type::Concurrent, Priority::Background }; + static TaskQueue BackgroundQueue{Type::Concurrent, Priority::Background}; return BackgroundQueue; } diff --git a/Telegram/SourceFiles/base/task_queue.h b/Telegram/SourceFiles/base/task_queue.h index 00425b9ad..7699fee99 100644 --- a/Telegram/SourceFiles/base/task_queue.h +++ b/Telegram/SourceFiles/base/task_queue.h @@ -20,11 +20,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include -#include -#include #include "base/lambda.h" #include "base/timer.h" +#include +#include +#include namespace base { @@ -47,8 +47,8 @@ public: }; // Creating custom serial queues. - TaskQueue(Priority priority) : TaskQueue(Type::Serial, priority) { - } + TaskQueue(Priority priority) + : TaskQueue(Type::Serial, priority) {} // Default main and two concurrent queues. static TaskQueue &Main(); @@ -100,7 +100,6 @@ private: // Only for Serial queues: non-null value means a task is currently processed. bool *destroyed_flag_ = nullptr; - }; } // namespace base diff --git a/Telegram/SourceFiles/base/tests/flags_tests.cpp b/Telegram/SourceFiles/base/tests/flags_tests.cpp index bed795d2e..a9d596580 100644 --- a/Telegram/SourceFiles/base/tests/flags_tests.cpp +++ b/Telegram/SourceFiles/base/tests/flags_tests.cpp @@ -25,8 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace MethodNamespace { -template -void TestFlags(Enum a, Enum b, Enum c) { +template void TestFlags(Enum a, Enum b, Enum c) { auto abc = a | b; abc |= c; auto test = abc != a; @@ -66,7 +65,9 @@ enum class Flag : int { two = (1 << 1), three = (1 << 2), }; -inline constexpr auto is_flag_type(Flag) { return true; } +inline constexpr auto is_flag_type(Flag) { + return true; +} class Class { public: @@ -75,7 +76,9 @@ public: two = (1 << 1), three = (1 << 0), }; - friend inline constexpr auto is_flag_type(Public) { return true; } + friend inline constexpr auto is_flag_type(Public) { + return true; + } static void TestPrivate(); @@ -85,8 +88,9 @@ private: two = (1 << 1), three = (1 << 2), }; - friend inline constexpr auto is_flag_type(Private) { return true; } - + friend inline constexpr auto is_flag_type(Private) { + return true; + } }; void Class::TestPrivate() { @@ -107,34 +111,24 @@ enum class Flag : int { namespace base { -template<> -struct extended_flags { - using type = FlagsNamespace::Flag; -}; +template <> struct extended_flags { using type = FlagsNamespace::Flag; }; } // namespace base TEST_CASE("flags operators on scoped enums", "[flags]") { SECTION("testing non-member flags") { - MethodNamespace::TestFlags( - FlagsNamespace::Flag::one, - FlagsNamespace::Flag::two, - FlagsNamespace::Flag::three); + MethodNamespace::TestFlags(FlagsNamespace::Flag::one, FlagsNamespace::Flag::two, FlagsNamespace::Flag::three); } SECTION("testing public member flags") { - MethodNamespace::TestFlags( - FlagsNamespace::Class::Public::one, - FlagsNamespace::Class::Public::two, - FlagsNamespace::Class::Public::three); + MethodNamespace::TestFlags(FlagsNamespace::Class::Public::one, FlagsNamespace::Class::Public::two, + FlagsNamespace::Class::Public::three); } SECTION("testing private member flags") { FlagsNamespace::Class::TestPrivate(); } SECTION("testing extended flags") { - MethodNamespace::TestFlags( - ExtendedNamespace::Flag::one, - ExtendedNamespace::Flag::two, - ExtendedNamespace::Flag::three); + MethodNamespace::TestFlags(ExtendedNamespace::Flag::one, ExtendedNamespace::Flag::two, + ExtendedNamespace::Flag::three); auto onetwo = FlagsNamespace::Flag::one | ExtendedNamespace::Flag::two; auto twoone = ExtendedNamespace::Flag::two | FlagsNamespace::Flag::one; diff --git a/Telegram/SourceFiles/base/timer.cpp b/Telegram/SourceFiles/base/timer.cpp index c590c5c78..7798a93d1 100644 --- a/Telegram/SourceFiles/base/timer.cpp +++ b/Telegram/SourceFiles/base/timer.cpp @@ -18,8 +18,8 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include #include "base/timer.h" +#include namespace base { namespace { @@ -31,10 +31,11 @@ QObject *TimersAdjuster() { } // namespace -Timer::Timer(base::lambda callback) : QObject(nullptr) -, _callback(std::move(callback)) -, _type(Qt::PreciseTimer) -, _adjusted(false) { +Timer::Timer(base::lambda callback) + : QObject(nullptr) + , _callback(std::move(callback)) + , _type(Qt::PreciseTimer) + , _adjusted(false) { setRepeat(Repeat::Interval); connect(TimersAdjuster(), &QObject::destroyed, this, [this] { adjust(); }, Qt::QueuedConnection); } diff --git a/Telegram/SourceFiles/base/timer.h b/Telegram/SourceFiles/base/timer.h index c4882cd38..489f045f6 100644 --- a/Telegram/SourceFiles/base/timer.h +++ b/Telegram/SourceFiles/base/timer.h @@ -70,7 +70,7 @@ protected: private: enum class Repeat : unsigned { - Interval = 0, + Interval = 0, SingleShot = 1, }; void start(TimeMs timeout, Qt::TimerType type, Repeat repeat); @@ -94,7 +94,6 @@ private: Qt::TimerType _type : 2; bool _adjusted : 1; unsigned _repeat : 1; - }; class DelayedCallTimer final : private QObject { @@ -111,7 +110,6 @@ protected: private: std::map> _callbacks; // Better to use flatmap. - }; } // namespace base diff --git a/Telegram/SourceFiles/base/type_traits.h b/Telegram/SourceFiles/base/type_traits.h index b2c779686..9271403c7 100644 --- a/Telegram/SourceFiles/base/type_traits.h +++ b/Telegram/SourceFiles/base/type_traits.h @@ -24,9 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace base { -template -struct custom_is_fast_copy_type : public std::false_type { -}; +template struct custom_is_fast_copy_type : public std::false_type {}; // To make your own type a fast copy type just write: // template <> // struct base::custom_is_fast_copy_type : public std::true_type { @@ -34,28 +32,24 @@ struct custom_is_fast_copy_type : public std::false_type { namespace internal { -template -struct type_list_contains; +template struct type_list_contains; -template -struct type_list_contains : public std::false_type { -}; +template struct type_list_contains : public std::false_type {}; -template -struct type_list_contains : public std::integral_constant::value || type_list_contains::value> { -}; +template +struct type_list_contains + : public std::integral_constant::value || type_list_contains::value> {}; template using is_std_unsigned_int = type_list_contains; -template -using is_std_signed_int = type_list_contains; +template using is_std_signed_int = type_list_contains; template -using is_std_integral = std::integral_constant::value || is_std_signed_int::value || type_list_contains::value>; +using is_std_integral = std::integral_constant::value || is_std_signed_int::value || + type_list_contains::value>; -template -using is_std_float = type_list_contains; +template using is_std_float = type_list_contains; template using is_std_arith = std::integral_constant::value || is_std_float::value>; @@ -63,55 +57,34 @@ using is_std_arith = std::integral_constant::value || i template using is_std_fundamental = std::integral_constant::value || std::is_same::value>; -template -struct is_pointer : public std::false_type { -}; +template struct is_pointer : public std::false_type {}; + +template struct is_pointer : public std::true_type {}; + +template struct is_member_pointer : public std::false_type {}; + +template struct is_member_pointer : public std::true_type {}; template -struct is_pointer : public std::true_type { -}; +using is_fast_copy_type = + std::integral_constant::value || is_pointer::value || is_member_pointer::value || + custom_is_fast_copy_type::value>; -template -struct is_member_pointer : public std::false_type { -}; +template struct add_const_reference { using type = const T &; }; -template -struct is_member_pointer : public std::true_type { -}; +template <> struct add_const_reference { using type = void; }; -template -using is_fast_copy_type = std::integral_constant::value || is_pointer::value || is_member_pointer::value || custom_is_fast_copy_type::value>; +template using add_const_reference_t = typename add_const_reference::type; -template -struct add_const_reference { - using type = const T &; -}; +template struct remove_pointer { using type = T; }; -template <> -struct add_const_reference { - using type = void; -}; +template struct remove_pointer { using type = T; }; -template -using add_const_reference_t = typename add_const_reference::type; - -template -struct remove_pointer { - using type = T; -}; - -template -struct remove_pointer { - using type = T; -}; - -template -using remove_pointer_t = typename remove_pointer::type; +template using remove_pointer_t = typename remove_pointer::type; } // namespace internal -template -struct type_traits { +template struct type_traits { using is_std_unsigned_int = internal::is_std_unsigned_int; using is_std_signed_int = internal::is_std_signed_int; using is_std_integral = internal::is_std_integral; @@ -126,7 +99,6 @@ struct type_traits { using pointed_type = internal::remove_pointer_t; }; -template -using parameter_type = typename type_traits::parameter_type; +template using parameter_type = typename type_traits::parameter_type; } // namespace base diff --git a/Telegram/SourceFiles/base/variant.h b/Telegram/SourceFiles/base/variant.h index 02a005c19..4ec1a0e55 100644 --- a/Telegram/SourceFiles/base/variant.h +++ b/Telegram/SourceFiles/base/variant.h @@ -25,16 +25,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org // We use base::variant<> alias and base::get_if() helper while we don't have std::variant<>. namespace base { -template -using variant = mapbox::util::variant; +template using variant = mapbox::util::variant; -template -inline T *get_if(variant *v) { +template inline T *get_if(variant *v) { return (v && v->template is()) ? &v->template get_unchecked() : nullptr; } -template -inline const T *get_if(const variant *v) { +template inline const T *get_if(const variant *v) { return (v && v->template is()) ? &v->template get_unchecked() : nullptr; } diff --git a/Telegram/SourceFiles/base/weak_unique_ptr.h b/Telegram/SourceFiles/base/weak_unique_ptr.h index 0bdf7f69d..5347d95ab 100644 --- a/Telegram/SourceFiles/base/weak_unique_ptr.h +++ b/Telegram/SourceFiles/base/weak_unique_ptr.h @@ -22,23 +22,20 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include // @todo replace this with std::experimental::observer_ptr -#include #include +#include namespace base { class enable_weak_from_this; -template -class weak_unique_ptr; +template class weak_unique_ptr; class enable_weak_from_this { public: enable_weak_from_this() = default; - enable_weak_from_this(const enable_weak_from_this &other) noexcept { - } - enable_weak_from_this(enable_weak_from_this &&other) noexcept { - } + enable_weak_from_this(const enable_weak_from_this &other) noexcept {} + enable_weak_from_this(enable_weak_from_this &&other) noexcept {} enable_weak_from_this &operator=(const enable_weak_from_this &other) noexcept { return *this; } @@ -47,31 +44,28 @@ public: } private: - template - friend class weak_unique_ptr; + template friend class weak_unique_ptr; - std::shared_ptr getGuarded() { + std::shared_ptr getGuarded() { if (!_guarded) { - _guarded = std::make_shared(static_cast(this)); + _guarded = std::make_shared(static_cast(this)); } return _guarded; } - std::shared_ptr _guarded; - + std::shared_ptr _guarded; }; -template -class weak_unique_ptr { +template class weak_unique_ptr { public: weak_unique_ptr() = default; - weak_unique_ptr(T *value) : _guarded(value ? value->getGuarded() : std::shared_ptr()) { - } - weak_unique_ptr(const std::unique_ptr &value) : weak_unique_ptr(value.get()) { - } + weak_unique_ptr(T *value) + : _guarded(value ? value->getGuarded() : std::shared_ptr()) {} + weak_unique_ptr(const std::unique_ptr &value) + : weak_unique_ptr(value.get()) {} weak_unique_ptr &operator=(T *value) { - _guarded = value ? value->getGuarded() : std::shared_ptr(); + _guarded = value ? value->getGuarded() : std::shared_ptr(); return *this; } weak_unique_ptr &operator=(const std::unique_ptr &value) { @@ -80,7 +74,7 @@ public: T *get() const noexcept { if (auto shared = _guarded.lock()) { - return static_cast(*shared); + return static_cast(*shared); } return nullptr; } @@ -95,50 +89,44 @@ public: } private: - std::weak_ptr _guarded; - + std::weak_ptr _guarded; }; -template -inline bool operator==(const weak_unique_ptr &pointer, std::nullptr_t) { +template inline bool operator==(const weak_unique_ptr &pointer, std::nullptr_t) { return (pointer.get() == nullptr); } -template -inline bool operator==(std::nullptr_t, const weak_unique_ptr &pointer) { +template inline bool operator==(std::nullptr_t, const weak_unique_ptr &pointer) { return (pointer == nullptr); } -template -inline bool operator!=(const weak_unique_ptr &pointer, std::nullptr_t) { +template inline bool operator!=(const weak_unique_ptr &pointer, std::nullptr_t) { return !(pointer == nullptr); } -template -inline bool operator!=(std::nullptr_t, const weak_unique_ptr &pointer) { +template inline bool operator!=(std::nullptr_t, const weak_unique_ptr &pointer) { return !(pointer == nullptr); } -template -weak_unique_ptr make_weak_unique(T *value) { +template weak_unique_ptr make_weak_unique(T *value) { return weak_unique_ptr(value); } -template -weak_unique_ptr make_weak_unique(const std::unique_ptr &value) { +template weak_unique_ptr make_weak_unique(const std::unique_ptr &value) { return weak_unique_ptr(value); } } // namespace base #ifdef QT_VERSION -template -inline void InvokeQueued(base::enable_weak_from_this *context, Lambda &&lambda) { - QObject proxy; - QObject::connect(&proxy, &QObject::destroyed, QCoreApplication::instance(), [guard = base::make_weak_unique(context), lambda = std::forward(lambda)] { - if (guard) { - lambda(); - } - }, Qt::QueuedConnection); +template inline void InvokeQueued(base::enable_weak_from_this *context, Lambda &&lambda) { + QObject proxy; + QObject::connect(&proxy, &QObject::destroyed, QCoreApplication::instance(), + [guard = base::make_weak_unique(context), lambda = std::forward(lambda)] { + if (guard) { + lambda(); + } + }, + Qt::QueuedConnection); } #endif // QT_VERSION diff --git a/Telegram/SourceFiles/base/zlib_help.h b/Telegram/SourceFiles/base/zlib_help.h index 6873142b1..7a20a0057 100644 --- a/Telegram/SourceFiles/base/zlib_help.h +++ b/Telegram/SourceFiles/base/zlib_help.h @@ -25,8 +25,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include -#include "minizip/zip.h" #include "minizip/unzip.h" +#include "minizip/zip.h" #include "logs.h" @@ -35,8 +35,8 @@ namespace internal { class InMemoryFile { public: - InMemoryFile(const QByteArray &data = QByteArray()) : _data(data) { - } + InMemoryFile(const QByteArray &data = QByteArray()) + : _data(data) {} zlib_filefunc_def funcs() { zlib_filefunc_def result; @@ -74,7 +74,7 @@ private: return this; } - uLong read(voidpf stream, void* buf, uLong size) { + uLong read(voidpf stream, void *buf, uLong size) { uLong toRead = 0; if (!_error) { if (_data.size() > int(_position)) { @@ -89,7 +89,7 @@ private: return toRead; } - uLong write(voidpf stream, const void* buf, uLong size) { + uLong write(voidpf stream, const void *buf, uLong size) { if (_data.size() < int(_position + size)) { _data.resize(_position + size); } @@ -127,38 +127,37 @@ private: return _error; } - static voidpf Open(voidpf opaque, const char* filename, int mode) { - return static_cast(opaque)->open(filename, mode); + static voidpf Open(voidpf opaque, const char *filename, int mode) { + return static_cast(opaque)->open(filename, mode); } - static uLong Read(voidpf opaque, voidpf stream, void* buf, uLong size) { - return static_cast(opaque)->read(stream, buf, size); + static uLong Read(voidpf opaque, voidpf stream, void *buf, uLong size) { + return static_cast(opaque)->read(stream, buf, size); } - static uLong Write(voidpf opaque, voidpf stream, const void* buf, uLong size) { - return static_cast(opaque)->write(stream, buf, size); + static uLong Write(voidpf opaque, voidpf stream, const void *buf, uLong size) { + return static_cast(opaque)->write(stream, buf, size); } static int Close(voidpf opaque, voidpf stream) { - return static_cast(opaque)->close(stream); + return static_cast(opaque)->close(stream); } static int Error(voidpf opaque, voidpf stream) { - return static_cast(opaque)->error(stream); + return static_cast(opaque)->error(stream); } static long Tell(voidpf opaque, voidpf stream) { - return static_cast(opaque)->tell(stream); + return static_cast(opaque)->tell(stream); } static long Seek(voidpf opaque, voidpf stream, uLong offset, int origin) { - return static_cast(opaque)->seek(stream, offset, origin); + return static_cast(opaque)->seek(stream, offset, origin); } uLong _position = 0; int _error = 0; QByteArray _data; - }; } // namespace internal @@ -168,7 +167,8 @@ constexpr int kCaseInsensitive = 2; class FileToRead { public: - FileToRead(const QByteArray &content) : _data(content) { + FileToRead(const QByteArray &content) + : _data(content) { auto funcs = _data.funcs(); if (!(_handle = unzOpen2(nullptr, &funcs))) { _error = -1; @@ -189,26 +189,12 @@ public: return error(); } - int getCurrentFileInfo( - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize - ) { + int getCurrentFileInfo(unz_file_info *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, + uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize) { if (error() == UNZ_OK) { - _error = _handle ? unzGetCurrentFileInfo( - _handle, - pfile_info, - szFileName, - fileNameBufferSize, - extraField, - extraFieldBufferSize, - szComment, - commentBufferSize - ) : -1; + _error = _handle ? unzGetCurrentFileInfo(_handle, pfile_info, szFileName, fileNameBufferSize, extraField, + extraFieldBufferSize, szComment, commentBufferSize) : + -1; } return error(); } @@ -240,7 +226,7 @@ public: } QByteArray readCurrentFileContent(int fileSizeLimit) { - unz_file_info fileInfo = { 0 }; + unz_file_info fileInfo = {0}; if (getCurrentFileInfo(&fileInfo, nullptr, 0, nullptr, 0, nullptr, 0) != UNZ_OK) { LOG(("Error: could not get current file info in a zip file.")); return QByteArray(); @@ -249,7 +235,9 @@ public: auto size = fileInfo.uncompressed_size; if (size > static_cast(fileSizeLimit)) { if (_error == UNZ_OK) _error = -1; - LOG(("Error: current file is too large (should be less than %1, got %2) in a zip file.").arg(fileSizeLimit).arg(size)); + LOG(("Error: current file is too large (should be less than %1, got %2) in a zip file.") + .arg(fileSizeLimit) + .arg(size)); return QByteArray(); } if (openCurrentFile() != UNZ_OK) { @@ -308,7 +296,6 @@ private: internal::InMemoryFile _data; unzFile _handle = nullptr; int _error = 0; - }; class FileToWrite { @@ -320,35 +307,18 @@ public: } } - int openNewFile( - const char *filename, - const zip_fileinfo *zipfi, - const void *extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level - ) { + int openNewFile(const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, + uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, + const char *comment, int method, int level) { if (error() == ZIP_OK) { - _error = _handle ? zipOpenNewFileInZip( - _handle, - filename, - zipfi, - extrafield_local, - size_extrafield_local, - extrafield_global, - size_extrafield_global, - comment, - method, - level - ) : -1; + _error = _handle ? zipOpenNewFileInZip(_handle, filename, zipfi, extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, comment, method, level) : + -1; } return error(); } - int writeInFile(const void* buf, unsigned len) { + int writeInFile(const void *buf, unsigned len) { if (error() == ZIP_OK) { _error = _handle ? zipWriteInFileInZip(_handle, buf, len) : -1; } @@ -388,7 +358,6 @@ private: internal::InMemoryFile _data; zipFile _handle = nullptr; int _error = 0; - }; } // namespace zlib diff --git a/Telegram/SourceFiles/boxes/about_box.cpp b/Telegram/SourceFiles/boxes/about_box.cpp index 5b395bd5b..620e6b4bb 100644 --- a/Telegram/SourceFiles/boxes/about_box.cpp +++ b/Telegram/SourceFiles/boxes/about_box.cpp @@ -18,38 +18,43 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include #include "boxes/about_box.h" +#include +#include "application.h" +#include "boxes/confirm_box.h" #include "config.h" #include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" -#include "boxes/confirm_box.h" -#include "application.h" +#include "platform/platform_file_utilities.h" +#include "styles/style_boxes.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" -#include "styles/style_boxes.h" -#include "platform/platform_file_utilities.h" AboutBox::AboutBox(QWidget *parent) -: _version(this, lng_about_version(lt_version, QString::fromLatin1(AppVersionStr.c_str()) + (cAlphaVersion() ? " alpha" : "") + (cBetaVersion() ? qsl(" beta %1").arg(cBetaVersion()) : QString())), st::aboutVersionLink) -, _text1(this, lang(lng_about_text_1), Ui::FlatLabel::InitType::Rich, st::aboutLabel) -, _text2(this, lang(lng_about_text_2), Ui::FlatLabel::InitType::Rich, st::aboutLabel) -, _text3(this, st::aboutLabel) { -} + : _version(this, + lng_about_version(lt_version, QString::fromLatin1(AppVersionStr.c_str()) + + (cAlphaVersion() ? " alpha" : "") + + (cBetaVersion() ? qsl(" beta %1").arg(cBetaVersion()) : QString())), + st::aboutVersionLink) + , _text1(this, lang(lng_about_text_1), Ui::FlatLabel::InitType::Rich, st::aboutLabel) + , _text2(this, lang(lng_about_text_2), Ui::FlatLabel::InitType::Rich, st::aboutLabel) + , _text3(this, st::aboutLabel) {} void AboutBox::prepare() { - constexpr auto test = std::is_convertible::value; + constexpr auto test = std::is_convertible::value; setTitle([] { return str_const_toString(AppName); }); addButton(langFactory(lng_close), [this] { closeBox(); }); - _text3->setRichText(lng_about_text_3(lt_faq_open, qsl("[a href=\"%1\"]").arg(telegramFaqLink()), lt_faq_close, qsl("[/a]"))); + _text3->setRichText( + lng_about_text_3(lt_faq_open, qsl("[a href=\"%1\"]").arg(telegramFaqLink()), lt_faq_close, qsl("[/a]"))); _version->setClickedCallback([this] { showVersionHistory(); }); - setDimensions(st::aboutWidth, st::aboutTextTop + _text1->height() + st::aboutSkip + _text2->height() + st::aboutSkip + _text3->height()); + setDimensions(st::aboutWidth, st::aboutTextTop + _text1->height() + st::aboutSkip + _text2->height() + + st::aboutSkip + _text3->height()); } void AboutBox::resizeEvent(QResizeEvent *e) { @@ -76,7 +81,7 @@ void AboutBox::keyPressEvent(QKeyEvent *e) { QString telegramFaqLink() { auto result = qsl("https://telegram.org/faq"); auto language = Lang::Current().id(); - for (auto faqLanguage : { "de", "es", "it", "ko", "br" }) { + for (auto faqLanguage : {"de", "es", "it", "ko", "br"}) { if (language.startsWith(QLatin1String(faqLanguage))) { result.append('/').append(faqLanguage); } diff --git a/Telegram/SourceFiles/boxes/about_box.h b/Telegram/SourceFiles/boxes/about_box.h index 624eab40c..4a2937a0a 100644 --- a/Telegram/SourceFiles/boxes/about_box.h +++ b/Telegram/SourceFiles/boxes/about_box.h @@ -29,7 +29,7 @@ class FlatLabel; class AboutBox : public BoxContent { public: - AboutBox(QWidget*); + AboutBox(QWidget *); protected: void prepare() override; @@ -44,7 +44,6 @@ private: object_ptr _text1; object_ptr _text2; object_ptr _text3; - }; QString telegramFaqLink(); diff --git a/Telegram/SourceFiles/boxes/abstract_box.cpp b/Telegram/SourceFiles/boxes/abstract_box.cpp index 6a69446a6..e368e5497 100644 --- a/Telegram/SourceFiles/boxes/abstract_box.cpp +++ b/Telegram/SourceFiles/boxes/abstract_box.cpp @@ -18,25 +18,27 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include #include "boxes/abstract_box.h" +#include -#include "styles/style_boxes.h" -#include "styles/style_profile.h" -#include "storage/localstorage.h" #include "lang/lang_keys.h" -#include "ui/effects/widget_fade_wrap.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/scroll_area.h" -#include "ui/widgets/labels.h" #include "mainwidget.h" #include "mainwindow.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" +#include "styles/style_profile.h" +#include "ui/effects/widget_fade_wrap.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/labels.h" +#include "ui/widgets/scroll_area.h" -QPointer BoxContent::addButton(base::lambda textFactory, base::lambda clickCallback) { +QPointer BoxContent::addButton(base::lambda textFactory, + base::lambda clickCallback) { return addButton(std::move(textFactory), std::move(clickCallback), st::defaultBoxButton); } -QPointer BoxContent::addLeftButton(base::lambda textFactory, base::lambda clickCallback) { +QPointer BoxContent::addLeftButton(base::lambda textFactory, + base::lambda clickCallback) { return getDelegate()->addLeftButton(std::move(textFactory), std::move(clickCallback), st::defaultBoxButton); } @@ -105,12 +107,13 @@ void BoxContent::onDraggingScrollDelta(int delta) { } void BoxContent::onDraggingScrollTimer() { - auto delta = (_draggingScrollDelta > 0) ? std::min(_draggingScrollDelta * 3 / 20 + 1, qint32(MaxScrollSpeed)) : std::max(_draggingScrollDelta * 3 / 20 - 1, -qint32(MaxScrollSpeed)); + auto delta = (_draggingScrollDelta > 0) ? std::min(_draggingScrollDelta * 3 / 20 + 1, qint32(MaxScrollSpeed)) : + std::max(_draggingScrollDelta * 3 / 20 - 1, -qint32(MaxScrollSpeed)); _scroll->scrollToY(_scroll->scrollTop() + delta); } void BoxContent::updateInnerVisibleTopBottom() { - if (auto widget = static_cast(_scroll ? _scroll->widget() : nullptr)) { + if (auto widget = static_cast(_scroll ? _scroll->widget() : nullptr)) { auto top = _scroll->scrollTop(); widget->setVisibleTopBottom(top, top + _scroll->height()); } @@ -210,9 +213,10 @@ void BoxContent::paintEvent(QPaintEvent *e) { } } -AbstractBox::AbstractBox(QWidget *parent, Window::Controller *controller, object_ptr content) : LayerWidget(parent) -, _controller(controller) -, _content(std::move(content)) { +AbstractBox::AbstractBox(QWidget *parent, Window::Controller *controller, object_ptr content) + : LayerWidget(parent) + , _controller(controller) + , _content(std::move(content)) { subscribe(Lang::Current().updated(), [this] { refreshLang(); }); _content->setParent(this); _content->setDelegate(this); @@ -263,7 +267,9 @@ void AbstractBox::paintEvent(QPaintEvent *e) { void AbstractBox::paintAdditionalTitle(Painter &p) { p.setFont(st::boxLayerTitleAdditionalFont); p.setPen(st::boxTitleAdditionalFg); - p.drawTextLeft(_titleLeft + (_title ? _title->width() : 0) + st::boxLayerTitleAdditionalSkip, _titleTop + st::boxTitleFont->ascent - st::boxLayerTitleAdditionalFont->ascent, width(), _additionalTitle); + p.drawTextLeft(_titleLeft + (_title ? _title->width() : 0) + st::boxLayerTitleAdditionalSkip, + _titleTop + st::boxTitleFont->ascent - st::boxLayerTitleAdditionalFont->ascent, width(), + _additionalTitle); } void AbstractBox::parentResized() { @@ -349,7 +355,8 @@ void AbstractBox::clearButtons() { _leftButton.destroy(); } -QPointer AbstractBox::addButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) { +QPointer AbstractBox::addButton(base::lambda textFactory, + base::lambda clickCallback, const style::RoundButton &st) { _buttons.push_back(object_ptr(this, std::move(textFactory), st)); auto result = QPointer(_buttons.back()); result->setClickedCallback(std::move(clickCallback)); @@ -358,7 +365,8 @@ QPointer AbstractBox::addButton(base::lambda textFac return result; } -QPointer AbstractBox::addLeftButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) { +QPointer AbstractBox::addLeftButton(base::lambda textFactory, + base::lambda clickCallback, const style::RoundButton &st) { _leftButton = object_ptr(this, std::move(textFactory), st); auto result = QPointer(_leftButton); result->setClickedCallback(std::move(clickCallback)); @@ -379,7 +387,8 @@ void AbstractBox::setDimensions(int newWidth, int maxHeight) { auto newGeometry = geometry(); auto parentHeight = parentWidget()->height(); if (newGeometry.top() + newGeometry.height() + st::boxVerticalMargin > parentHeight) { - auto newTop = std::max(parentHeight - int(st::boxVerticalMargin) - newGeometry.height(), (parentHeight - newGeometry.height()) / 2); + auto newTop = std::max(parentHeight - int(st::boxVerticalMargin) - newGeometry.height(), + (parentHeight - newGeometry.height()) / 2); if (newTop != newGeometry.top()) { move(newGeometry.left(), newTop); } @@ -422,11 +431,11 @@ void AbstractBox::keyPressEvent(QKeyEvent *e) { } } -BoxLayerTitleShadow::BoxLayerTitleShadow(QWidget *parent) : Ui::PlainShadow(parent, st::boxLayerTitleShadow) { -} +BoxLayerTitleShadow::BoxLayerTitleShadow(QWidget *parent) + : Ui::PlainShadow(parent, st::boxLayerTitleShadow) {} -BoxContentDivider::BoxContentDivider(QWidget *parent) : TWidget(parent) { -} +BoxContentDivider::BoxContentDivider(QWidget *parent) + : TWidget(parent) {} int BoxContentDivider::resizeGetHeight(int newWidth) { return st::rightsDividerHeight; @@ -437,6 +446,7 @@ void BoxContentDivider::paintEvent(QPaintEvent *e) { p.fillRect(e->rect(), st::contactsAboutBg); auto dividerFillTop = myrtlrect(0, 0, width(), st::profileDividerTop.height()); st::profileDividerTop.fill(p, dividerFillTop); - auto dividerFillBottom = myrtlrect(0, height() - st::profileDividerBottom.height(), width(), st::profileDividerBottom.height()); + auto dividerFillBottom = + myrtlrect(0, height() - st::profileDividerBottom.height(), width(), st::profileDividerBottom.height()); st::profileDividerBottom.fill(p, dividerFillBottom); } diff --git a/Telegram/SourceFiles/boxes/abstract_box.h b/Telegram/SourceFiles/boxes/abstract_box.h index 4bc14265d..e2ff7e808 100644 --- a/Telegram/SourceFiles/boxes/abstract_box.h +++ b/Telegram/SourceFiles/boxes/abstract_box.h @@ -22,18 +22,17 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "base/lambda.h" #include "base/observer.h" -#include "ui/text/text_entity.h" -#include "ui/widgets/shadow.h" -#include "ui/twidget.h" #include "layerwidget.h" +#include "ui/text/text_entity.h" +#include "ui/twidget.h" +#include "ui/widgets/shadow.h" namespace Ui { class RoundButton; class IconButton; class ScrollArea; class FlatLabel; -template -class WidgetFadeWrap; +template class WidgetFadeWrap; } // namespace Ui namespace Window { @@ -51,15 +50,17 @@ public: virtual void setAdditionalTitle(base::lambda additionalFactory) = 0; virtual void clearButtons() = 0; - virtual QPointer addButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) = 0; - virtual QPointer addLeftButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) = 0; + virtual QPointer addButton(base::lambda textFactory, base::lambda clickCallback, + const style::RoundButton &st) = 0; + virtual QPointer addLeftButton(base::lambda textFactory, + base::lambda clickCallback, + const style::RoundButton &st) = 0; virtual void updateButtonsPositions() = 0; virtual void setDimensions(int newWidth, int maxHeight) = 0; virtual void setNoContentMargin(bool noContentMargin) = 0; virtual bool isBoxShown() const = 0; virtual void closeBox() = 0; - }; class BoxContent : public TWidget, protected base::Subscriber { @@ -79,7 +80,7 @@ public: void setTitle(base::lambda titleFactory) { if (titleFactory) { - getDelegate()->setTitle([titleFactory] { return TextWithEntities { titleFactory(), EntitiesInText() }; }); + getDelegate()->setTitle([titleFactory] { return TextWithEntities{titleFactory(), EntitiesInText()}; }); } else { getDelegate()->setTitle(base::lambda()); } @@ -96,7 +97,8 @@ public: } QPointer addButton(base::lambda textFactory, base::lambda clickCallback); QPointer addLeftButton(base::lambda textFactory, base::lambda clickCallback); - QPointer addButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) { + QPointer addButton(base::lambda textFactory, base::lambda clickCallback, + const style::RoundButton &st) { return getDelegate()->addButton(std::move(textFactory), std::move(clickCallback), st); } void updateButtonsGeometry() { @@ -152,16 +154,14 @@ protected: return result; } - template - QPointer setInnerWidget(object_ptr inner, int topSkip = 0) { + template QPointer setInnerWidget(object_ptr inner, int topSkip = 0) { auto result = QPointer(inner.data()); setInnerTopSkip(topSkip); setInner(std::move(inner)); return result; } - template - object_ptr takeInnerWidget() { + template object_ptr takeInnerWidget() { return static_object_cast(doTakeInnerWidget()); } @@ -196,13 +196,12 @@ private: bool _preparing = false; bool _noContentMargin = false; int _innerTopSkip = 0; - object_ptr _scroll = { nullptr }; - object_ptr> _topShadow = { nullptr }; - object_ptr> _bottomShadow = { nullptr }; + object_ptr _scroll = {nullptr}; + object_ptr> _topShadow = {nullptr}; + object_ptr> _bottomShadow = {nullptr}; - object_ptr _draggingScrollTimer = { nullptr }; + object_ptr _draggingScrollTimer = {nullptr}; int _draggingScrollDelta = 0; - }; class AbstractBox : public LayerWidget, public BoxContentDelegate, protected base::Subscriber { @@ -219,8 +218,10 @@ public: void setAdditionalTitle(base::lambda additionalFactory) override; void clearButtons() override; - QPointer addButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) override; - QPointer addLeftButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) override; + QPointer addButton(base::lambda textFactory, base::lambda clickCallback, + const style::RoundButton &st) override; + QPointer addLeftButton(base::lambda textFactory, base::lambda clickCallback, + const style::RoundButton &st) override; void updateButtonsPositions() override; void setDimensions(int newWidth, int maxHeight) override; @@ -274,7 +275,7 @@ private: int _maxContentHeight = 0; object_ptr _content; - object_ptr _title = { nullptr }; + object_ptr _title = {nullptr}; base::lambda _titleFactory; QString _additionalTitle; base::lambda _additionalTitleFactory; @@ -283,14 +284,12 @@ private: bool _layerType = false; std::vector> _buttons; - object_ptr _leftButton = { nullptr }; - + object_ptr _leftButton = {nullptr}; }; class BoxLayerTitleShadow : public Ui::PlainShadow { public: BoxLayerTitleShadow(QWidget *parent); - }; class BoxContentDivider : public TWidget { @@ -300,7 +299,6 @@ public: protected: int resizeGetHeight(int newWidth) override; void paintEvent(QPaintEvent *e) override; - }; enum CreatingGroupType { diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index a17636701..00caade87 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -20,29 +20,29 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/add_contact_box.h" -#include "styles/style_boxes.h" -#include "styles/style_dialogs.h" -#include "lang/lang_keys.h" -#include "messenger.h" -#include "mtproto/sender.h" +#include "apiwrap.h" +#include "auth_session.h" #include "base/flat_set.h" #include "boxes/confirm_box.h" -#include "boxes/photo_crop_box.h" #include "boxes/peer_list_controllers.h" +#include "boxes/photo_crop_box.h" #include "core/file_utilities.h" -#include "ui/widgets/checkbox.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/input_fields.h" -#include "ui/widgets/labels.h" -#include "ui/toast/toast.h" -#include "ui/special_buttons.h" +#include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" -#include "apiwrap.h" +#include "messenger.h" +#include "mtproto/sender.h" #include "observer_peer.h" -#include "auth_session.h" -#include +#include "styles/style_boxes.h" +#include "styles/style_dialogs.h" +#include "ui/special_buttons.h" +#include "ui/toast/toast.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/input_fields.h" +#include "ui/widgets/labels.h" #include +#include namespace { @@ -59,9 +59,7 @@ style::InputField CreateBioFieldStyle() { } // namespace QString PeerFloodErrorText(PeerFloodType type) { - auto link = textcmdLink( - Messenger::Instance().createInternalLinkFull(qsl("spambot")), - lang(lng_cant_more_info)); + auto link = textcmdLink(Messenger::Instance().createInternalLinkFull(qsl("spambot")), lang(lng_cant_more_info)); if (type == PeerFloodType::InviteGroup) { return lng_cant_invite_not_contact(lt_more_info, link); } @@ -80,10 +78,10 @@ protected: private: struct ChatRow { - ChatRow(not_null peer) : peer(peer) { - } + ChatRow(not_null peer) + : peer(peer) {} - not_null peer; + not_null peer; Text name, status; }; void paintChat(Painter &p, const ChatRow &row, bool selected) const; @@ -101,25 +99,24 @@ private: base::lambda _revokeCallback; mtpRequestId _revokeRequestId = 0; QPointer _weakRevokeConfirmBox; - }; -AddContactBox::AddContactBox(QWidget*, QString fname, QString lname, QString phone) -: _first(this, st::defaultInputField, langFactory(lng_signup_firstname), fname) -, _last(this, st::defaultInputField, langFactory(lng_signup_lastname), lname) -, _phone(this, st::defaultInputField, langFactory(lng_contact_phone), phone) -, _invertOrder(langFirstNameGoesSecond()) { +AddContactBox::AddContactBox(QWidget *, QString fname, QString lname, QString phone) + : _first(this, st::defaultInputField, langFactory(lng_signup_firstname), fname) + , _last(this, st::defaultInputField, langFactory(lng_signup_lastname), lname) + , _phone(this, st::defaultInputField, langFactory(lng_contact_phone), phone) + , _invertOrder(langFirstNameGoesSecond()) { if (!phone.isEmpty()) { _phone->setDisabled(true); } } -AddContactBox::AddContactBox(QWidget*, UserData *user) -: _user(user) -, _first(this, st::defaultInputField, langFactory(lng_signup_firstname), user->firstName) -, _last(this, st::defaultInputField, langFactory(lng_signup_lastname), user->lastName) -, _phone(this, st::defaultInputField, langFactory(lng_contact_phone), user->phone()) -, _invertOrder(langFirstNameGoesSecond()) { +AddContactBox::AddContactBox(QWidget *, UserData *user) + : _user(user) + , _first(this, st::defaultInputField, langFactory(lng_signup_firstname), user->firstName) + , _last(this, st::defaultInputField, langFactory(lng_signup_lastname), user->lastName) + , _phone(this, st::defaultInputField, langFactory(lng_contact_phone), user->phone()) + , _invertOrder(langFirstNameGoesSecond()) { _phone->setDisabled(true); } @@ -130,7 +127,8 @@ void AddContactBox::prepare() { if (_user) { setTitle(langFactory(lng_edit_contact_title)); } else { - auto readyToAdd = !_phone->getLastText().isEmpty() && (!_first->getLastText().isEmpty() || !_last->getLastText().isEmpty()); + auto readyToAdd = + !_phone->getLastText().isEmpty() && (!_first->getLastText().isEmpty() || !_last->getLastText().isEmpty()); setTitle(langFactory(readyToAdd ? lng_confirm_contact_data : lng_enter_contact_data)); } updateButtons(); @@ -139,7 +137,9 @@ void AddContactBox::prepare() { connect(_last, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); connect(_phone, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); - setDimensions(st::boxWideWidth, st::contactPadding.top() + _first->height() + st::contactSkip + _last->height() + st::contactPhoneSkip + _phone->height() + st::contactPadding.bottom() + st::boxPadding.bottom()); + setDimensions(st::boxWideWidth, st::contactPadding.top() + _first->height() + st::contactSkip + _last->height() + + st::contactPhoneSkip + _phone->height() + st::contactPadding.bottom() + + st::boxPadding.bottom()); } void AddContactBox::setInnerFocus() { @@ -159,7 +159,9 @@ void AddContactBox::paintEvent(QPaintEvent *e) { p.setPen(st::boxTextFg); p.setFont(st::boxTextFont); auto textHeight = height() - st::contactPadding.top() - st::contactPadding.bottom() - st::boxPadding.bottom(); - p.drawText(QRect(st::boxPadding.left(), st::contactPadding.top(), width() - st::boxPadding.left() - st::boxPadding.right(), textHeight), lng_contact_not_joined(lt_name, _sentName), style::al_topleft); + p.drawText(QRect(st::boxPadding.left(), st::contactPadding.top(), + width() - st::boxPadding.left() - st::boxPadding.right(), textHeight), + lng_contact_not_joined(lt_name, _sentName), style::al_topleft); } else { st::contactUserIcon.paint(p, st::boxPadding.left(), _first->y() + st::contactIconTop, width()); st::contactPhoneIcon.paint(p, st::boxPadding.left(), _phone->y() + st::contactIconTop, width()); @@ -169,17 +171,22 @@ void AddContactBox::paintEvent(QPaintEvent *e) { void AddContactBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _first->resize(width() - st::boxPadding.left() - st::contactPadding.left() - st::boxPadding.right(), _first->height()); + _first->resize(width() - st::boxPadding.left() - st::contactPadding.left() - st::boxPadding.right(), + _first->height()); _last->resize(_first->width(), _last->height()); _phone->resize(_first->width(), _last->height()); if (_invertOrder) { _last->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), st::contactPadding.top()); - _first->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), _last->y() + _last->height() + st::contactSkip); - _phone->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), _first->y() + _first->height() + st::contactPhoneSkip); + _first->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), + _last->y() + _last->height() + st::contactSkip); + _phone->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), + _first->y() + _first->height() + st::contactPhoneSkip); } else { _first->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), st::contactPadding.top()); - _last->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), _first->y() + _first->height() + st::contactSkip); - _phone->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), _last->y() + _last->height() + st::contactPhoneSkip); + _last->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), + _first->y() + _first->height() + st::contactSkip); + _phone->moveToLeft(st::boxPadding.left() + st::contactPadding.left(), + _last->y() + _last->height() + st::contactPhoneSkip); } } @@ -224,12 +231,16 @@ void AddContactBox::onSave() { _sentName = firstName; if (_user) { _contactId = rand_value(); - QVector v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_user->phone()), MTP_string(firstName), MTP_string(lastName))); - _addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector(v)), rpcDone(&AddContactBox::onSaveUserDone), rpcFail(&AddContactBox::onSaveUserFail)); + QVector v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_user->phone()), + MTP_string(firstName), MTP_string(lastName))); + _addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector(v)), + rpcDone(&AddContactBox::onSaveUserDone), rpcFail(&AddContactBox::onSaveUserFail)); } else { _contactId = rand_value(); - QVector v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(phone), MTP_string(firstName), MTP_string(lastName))); - _addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector(v)), rpcDone(&AddContactBox::onImportDone)); + QVector v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(phone), + MTP_string(firstName), MTP_string(lastName))); + _addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector(v)), + rpcDone(&AddContactBox::onImportDone)); } } @@ -307,12 +318,12 @@ void AddContactBox::updateButtons() { } } -GroupInfoBox::GroupInfoBox(QWidget*, CreatingGroupType creating, bool fromTypeChoose) -: _creating(creating) -, _fromTypeChoose(fromTypeChoose) -, _photo(this, st::newGroupPhotoSize, st::newGroupPhotoIconPosition) -, _title(this, st::defaultInputField, langFactory(_creating == CreatingGroupChannel ? lng_dlg_new_channel_name : lng_dlg_new_group_name)) { -} +GroupInfoBox::GroupInfoBox(QWidget *, CreatingGroupType creating, bool fromTypeChoose) + : _creating(creating) + , _fromTypeChoose(fromTypeChoose) + , _photo(this, st::newGroupPhotoSize, st::newGroupPhotoIconPosition) + , _title(this, st::defaultInputField, + langFactory(_creating == CreatingGroupChannel ? lng_dlg_new_channel_name : lng_dlg_new_group_name)) {} void GroupInfoBox::prepare() { setMouseTracking(true); @@ -331,7 +342,8 @@ void GroupInfoBox::prepare() { connect(_title, SIGNAL(submitted(bool)), this, SLOT(onNameSubmit())); - addButton(langFactory(_creating == CreatingGroupChannel ? lng_create_group_create : lng_create_group_next), [this] { onNext(); }); + addButton(langFactory(_creating == CreatingGroupChannel ? lng_create_group_create : lng_create_group_next), + [this] { onNext(); }); addButton(langFactory(_fromTypeChoose ? lng_create_group_back : lng_cancel), [this] { closeBox(); }); setupPhotoButton(); @@ -343,23 +355,26 @@ void GroupInfoBox::setupPhotoButton() { _photo->setClickedCallback(App::LambdaDelayed(st::defaultActiveButton.ripple.hideDuration, this, [this] { auto imgExtensions = cImgExtensions(); auto filter = qsl("Image files (*") + imgExtensions.join(qsl(" *")) + qsl(");;") + FileDialog::AllFilesFilter(); - FileDialog::GetOpenPath(lang(lng_choose_image), filter, base::lambda_guarded(this, [this](const FileDialog::OpenResult &result) { - if (result.remoteContent.isEmpty() && result.paths.isEmpty()) { - return; - } + FileDialog::GetOpenPath( + lang(lng_choose_image), filter, base::lambda_guarded(this, [this](const FileDialog::OpenResult &result) { + if (result.remoteContent.isEmpty() && result.paths.isEmpty()) { + return; + } - QImage img; - if (!result.remoteContent.isEmpty()) { - img = App::readImage(result.remoteContent); - } else { - img = App::readImage(result.paths.front()); - } - if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) { - return; - } - auto box = Ui::show(Box(img, (_creating == CreatingGroupChannel) ? peerFromChannel(0) : peerFromChat(0)), KeepOtherLayers); - connect(box, SIGNAL(ready(const QImage&)), this, SLOT(onPhotoReady(const QImage&))); - })); + QImage img; + if (!result.remoteContent.isEmpty()) { + img = App::readImage(result.remoteContent); + } else { + img = App::readImage(result.paths.front()); + } + if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) { + return; + } + auto box = Ui::show( + Box(img, (_creating == CreatingGroupChannel) ? peerFromChannel(0) : peerFromChat(0)), + KeepOtherLayers); + connect(box, SIGNAL(ready(const QImage &)), this, SLOT(onPhotoReady(const QImage &))); + })); })); } @@ -370,14 +385,20 @@ void GroupInfoBox::setInnerFocus() { void GroupInfoBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _photo->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::boxPadding.top() + st::newGroupInfoPadding.top()); + _photo->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + st::boxPadding.top() + st::newGroupInfoPadding.top()); auto nameLeft = st::newGroupPhotoSize + st::newGroupNamePosition.x(); - _title->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right() - nameLeft, _title->height()); - _title->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left() + nameLeft, st::boxPadding.top() + st::newGroupInfoPadding.top() + st::newGroupNamePosition.y()); + _title->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right() - nameLeft, + _title->height()); + _title->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left() + nameLeft, + st::boxPadding.top() + st::newGroupInfoPadding.top() + st::newGroupNamePosition.y()); if (_description) { - _description->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _description->height()); - _description->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::boxPadding.top() + st::newGroupInfoPadding.top() + st::newGroupPhotoSize + st::newGroupDescriptionPadding.top()); + _description->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), + _description->height()); + _description->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + st::boxPadding.top() + st::newGroupInfoPadding.top() + st::newGroupPhotoSize + + st::newGroupDescriptionPadding.top()); } } @@ -392,7 +413,8 @@ void GroupInfoBox::onNameSubmit() { } } -void GroupInfoBox::createGroup(not_null selectUsersBox, const QString &title, const std::vector> &users) { +void GroupInfoBox::createGroup(not_null selectUsersBox, const QString &title, + const std::vector> &users) { if (_creationRequestId) return; auto inputs = QVector(); @@ -404,61 +426,61 @@ void GroupInfoBox::createGroup(not_null selectUsersBox, const QStr inputs.push_back(user->inputUser); } } - _creationRequestId = request(MTPmessages_CreateChat(MTP_vector(inputs), MTP_string(title))).done([this](const MTPUpdates &result) { - Ui::hideLayer(); + _creationRequestId = + request(MTPmessages_CreateChat(MTP_vector(inputs), MTP_string(title))) + .done([this](const MTPUpdates &result) { + Ui::hideLayer(); - App::main()->sentUpdatesReceived(result); + App::main()->sentUpdatesReceived(result); - auto success = base::make_optional(&result) - | [](auto updates) -> base::optional*> { - switch (updates->type()) { - case mtpc_updates: - return &updates->c_updates().vchats.v; - case mtpc_updatesCombined: - return &updates->c_updatesCombined().vchats.v; - } - LOG(("API Error: unexpected update cons %1 (GroupInfoBox::creationDone)").arg(updates->type())); - return base::none; - } - | [](auto chats) { - return (!chats->empty() && chats->front().type() == mtpc_chat) - ? base::make_optional(chats) - : base::none; - } - | [](auto chats) { - return App::chat(chats->front().c_chat().vid.v); - } - | [this](not_null chat) { - if (!_photoImage.isNull()) { - Messenger::Instance().uploadProfilePhoto(_photoImage, chat->id); - } - Ui::showPeerHistory(chat, ShowAtUnreadMsgId); - }; - if (!success) { - LOG(("API Error: chat not found in updates (ContactsBox::creationDone)")); - } - }).fail([this, selectUsersBox](const RPCError &error) { - _creationRequestId = 0; - if (error.type() == qstr("NO_CHAT_TITLE")) { - auto guard = weak(this); - selectUsersBox->closeBox(); - if (guard) { - _title->showError(); - } - } else if (error.type() == qstr("USERS_TOO_FEW")) { - } else if (error.type() == qstr("PEER_FLOOD")) { - Ui::show(Box(PeerFloodErrorText(PeerFloodType::InviteGroup)), KeepOtherLayers); - } else if (error.type() == qstr("USER_RESTRICTED")) { - Ui::show(Box(lang(lng_cant_do_this)), KeepOtherLayers); - } - }).send(); + auto success = + base::make_optional(&result) | [](auto updates) -> base::optional *> { + switch (updates->type()) { + case mtpc_updates: return &updates->c_updates().vchats.v; + case mtpc_updatesCombined: return &updates->c_updatesCombined().vchats.v; + } + LOG(("API Error: unexpected update cons %1 (GroupInfoBox::creationDone)").arg(updates->type())); + return base::none; + } | [](auto chats) { + return (!chats->empty() && chats->front().type() == mtpc_chat) ? base::make_optional(chats) : + base::none; + } | [](auto chats) { + return App::chat(chats->front().c_chat().vid.v); + } | [this](not_null chat) { + if (!_photoImage.isNull()) { + Messenger::Instance().uploadProfilePhoto(_photoImage, chat->id); + } + Ui::showPeerHistory(chat, ShowAtUnreadMsgId); + }; + if (!success) { + LOG(("API Error: chat not found in updates (ContactsBox::creationDone)")); + } + }) + .fail([this, selectUsersBox](const RPCError &error) { + _creationRequestId = 0; + if (error.type() == qstr("NO_CHAT_TITLE")) { + auto guard = weak(this); + selectUsersBox->closeBox(); + if (guard) { + _title->showError(); + } + } else if (error.type() == qstr("USERS_TOO_FEW")) { + } else if (error.type() == qstr("PEER_FLOOD")) { + Ui::show(Box(PeerFloodErrorText(PeerFloodType::InviteGroup)), KeepOtherLayers); + } else if (error.type() == qstr("USER_RESTRICTED")) { + Ui::show(Box(lang(lng_cant_do_this)), KeepOtherLayers); + } + }) + .send(); } void GroupInfoBox::onNext() { if (_creationRequestId) return; auto title = TextUtilities::PrepareForSending(_title->getLastText()); - auto description = _description ? TextUtilities::PrepareForSending(_description->getLastText(), TextUtilities::PrepareTextOption::CheckLinks) : QString(); + auto description = _description ? TextUtilities::PrepareForSending(_description->getLastText(), + TextUtilities::PrepareTextOption::CheckLinks) : + QString(); if (title.isEmpty()) { _title->setFocus(); _title->showError(); @@ -467,7 +489,7 @@ void GroupInfoBox::onNext() { if (_creating != CreatingGroupGroup) { createChannel(title, description); } else { - auto initBox = [title, weak = weak(this)](not_null box) { + auto initBox = [title, weak = weak(this)](not_null box) { box->addButton(langFactory(lng_create_group_create), [box, title, weak] { if (weak) { auto rows = box->peerListCollectSelectedRows(); @@ -478,68 +500,65 @@ void GroupInfoBox::onNext() { }); box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); }); }; - Ui::show(Box(std::make_unique(nullptr), std::move(initBox)), KeepOtherLayers); + Ui::show(Box(std::make_unique(nullptr), std::move(initBox)), + KeepOtherLayers); } } void GroupInfoBox::createChannel(const QString &title, const QString &description) { bool mega = false; auto flags = mega ? MTPchannels_CreateChannel::Flag::f_megagroup : MTPchannels_CreateChannel::Flag::f_broadcast; - _creationRequestId = request(MTPchannels_CreateChannel(MTP_flags(flags), MTP_string(title), MTP_string(description))).done([this](const MTPUpdates &result) { - App::main()->sentUpdatesReceived(result); + _creationRequestId = + request(MTPchannels_CreateChannel(MTP_flags(flags), MTP_string(title), MTP_string(description))) + .done([this](const MTPUpdates &result) { + App::main()->sentUpdatesReceived(result); - auto success = base::make_optional(&result) - | [](auto updates) -> base::optional*> { - switch (updates->type()) { - case mtpc_updates: - return &updates->c_updates().vchats.v; - case mtpc_updatesCombined: - return &updates->c_updatesCombined().vchats.v; - } - LOG(("API Error: unexpected update cons %1 (GroupInfoBox::createChannel)").arg(updates->type())); - return base::none; - } - | [](auto chats) { - return (!chats->empty() && chats->front().type() == mtpc_channel) - ? base::make_optional(chats) - : base::none; - } - | [](auto chats) { - return App::channel(chats->front().c_channel().vid.v); - } - | [this](not_null channel) { - if (!_photoImage.isNull()) { - Messenger::Instance().uploadProfilePhoto( - _photoImage, - channel->id); - } - _createdChannel = channel; - _creationRequestId = request( - MTPchannels_ExportInvite(_createdChannel->inputChannel) - ).done([this](const MTPExportedChatInvite &result) { - _creationRequestId = 0; - if (result.type() == mtpc_chatInviteExported) { - auto link = qs(result.c_chatInviteExported().vlink); - _createdChannel->setInviteLink(link); - } - Ui::show(Box(_createdChannel)); - }).send(); - }; - if (!success) { - LOG(("API Error: channel not found in updates (GroupInfoBox::creationDone)")); - closeBox(); - } - }).fail([this](const RPCError &error) { - _creationRequestId = 0; - if (error.type() == "NO_CHAT_TITLE") { - _title->setFocus(); - _title->showError(); - } else if (error.type() == qstr("USER_RESTRICTED")) { - Ui::show(Box(lang(lng_cant_do_this))); - } else if (error.type() == qstr("CHANNELS_TOO_MUCH")) { - Ui::show(Box(lang(lng_cant_do_this))); // TODO - } - }).send(); + auto success = + base::make_optional(&result) | [](auto updates) -> base::optional *> { + switch (updates->type()) { + case mtpc_updates: return &updates->c_updates().vchats.v; + case mtpc_updatesCombined: return &updates->c_updatesCombined().vchats.v; + } + LOG(("API Error: unexpected update cons %1 (GroupInfoBox::createChannel)").arg(updates->type())); + return base::none; + } | [](auto chats) { + return (!chats->empty() && chats->front().type() == mtpc_channel) ? base::make_optional(chats) : + base::none; + } | [](auto chats) { + return App::channel(chats->front().c_channel().vid.v); + } | [this](not_null channel) { + if (!_photoImage.isNull()) { + Messenger::Instance().uploadProfilePhoto(_photoImage, channel->id); + } + _createdChannel = channel; + _creationRequestId = request(MTPchannels_ExportInvite(_createdChannel->inputChannel)) + .done([this](const MTPExportedChatInvite &result) { + _creationRequestId = 0; + if (result.type() == mtpc_chatInviteExported) { + auto link = qs(result.c_chatInviteExported().vlink); + _createdChannel->setInviteLink(link); + } + Ui::show(Box(_createdChannel)); + }) + .send(); + }; + if (!success) { + LOG(("API Error: channel not found in updates (GroupInfoBox::creationDone)")); + closeBox(); + } + }) + .fail([this](const RPCError &error) { + _creationRequestId = 0; + if (error.type() == "NO_CHAT_TITLE") { + _title->setFocus(); + _title->showError(); + } else if (error.type() == qstr("USER_RESTRICTED")) { + Ui::show(Box(lang(lng_cant_do_this))); + } else if (error.type() == qstr("CHANNELS_TOO_MUCH")) { + Ui::show(Box(lang(lng_cant_do_this))); // TODO + } + }) + .send(); } void GroupInfoBox::onDescriptionResized() { @@ -548,9 +567,11 @@ void GroupInfoBox::onDescriptionResized() { } void GroupInfoBox::updateMaxHeight() { - auto newHeight = st::boxPadding.top() + st::newGroupInfoPadding.top() + st::newGroupPhotoSize + st::boxPadding.bottom() + st::newGroupInfoPadding.bottom(); + auto newHeight = st::boxPadding.top() + st::newGroupInfoPadding.top() + st::newGroupPhotoSize + + st::boxPadding.bottom() + st::newGroupInfoPadding.bottom(); if (_description) { - newHeight += st::newGroupDescriptionPadding.top() + _description->height() + st::newGroupDescriptionPadding.bottom(); + newHeight += + st::newGroupDescriptionPadding.top() + _description->height() + st::newGroupDescriptionPadding.bottom(); } setDimensions(st::boxWideWidth, newHeight); } @@ -560,24 +581,34 @@ void GroupInfoBox::onPhotoReady(const QImage &img) { _photo->setImage(_photoImage); } -SetupChannelBox::SetupChannelBox(QWidget*, ChannelData *channel, bool existing) -: _channel(channel) -, _existing(existing) -, _privacyGroup(std::make_shared>(Privacy::Public)) -, _public(this, _privacyGroup, Privacy::Public, lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), st::defaultBoxCheckbox) -, _private(this, _privacyGroup, Privacy::Private, lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title), st::defaultBoxCheckbox) -, _aboutPublicWidth(st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadio.diameter - st::defaultBoxCheckbox.textPosition.x()) -, _aboutPublic(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth) -, _aboutPrivate(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth) -, _link(this, st::setupChannelLink, base::lambda(), channel->username, true) { -} +SetupChannelBox::SetupChannelBox(QWidget *, ChannelData *channel, bool existing) + : _channel(channel) + , _existing(existing) + , _privacyGroup(std::make_shared>(Privacy::Public)) + , _public(this, _privacyGroup, Privacy::Public, + lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), + st::defaultBoxCheckbox) + , _private(this, _privacyGroup, Privacy::Private, + lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title), + st::defaultBoxCheckbox) + , _aboutPublicWidth(st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right() - + st::newGroupPadding.left() - st::defaultRadio.diameter - + st::defaultBoxCheckbox.textPosition.x()) + , _aboutPublic(st::defaultTextStyle, + lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), + _defaultOptions, _aboutPublicWidth) + , _aboutPrivate(st::defaultTextStyle, + lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), + _defaultOptions, _aboutPublicWidth) + , _link(this, st::setupChannelLink, base::lambda(), channel->username, true) {} void SetupChannelBox::prepare() { _aboutPublicHeight = _aboutPublic.countHeight(_aboutPublicWidth); setMouseTracking(true); - _checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string("preston")), RPCDoneHandlerPtr(), rpcFail(&SetupChannelBox::onFirstCheckFail)); + _checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string("preston")), + RPCDoneHandlerPtr(), rpcFail(&SetupChannelBox::onFirstCheckFail)); addButton(langFactory(lng_settings_save), [this] { onSave(); }); addButton(langFactory(_existing ? lng_cancel : lng_create_group_skip), [this] { closeBox(); }); @@ -589,11 +620,12 @@ void SetupChannelBox::prepare() { connect(&_checkTimer, SIGNAL(timeout()), this, SLOT(onCheck())); _privacyGroup->setChangedCallback([this](Privacy value) { privacyChanged(value); }); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::InviteLinkChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer == _channel) { - rtlupdate(_invitationLink); - } - })); + subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::InviteLinkChanged, + [this](const Notify::PeerUpdate &update) { + if (update.peer == _channel) { + rtlupdate(_invitationLink); + } + })); subscribe(boxClosing, [this] { if (!_existing) { AddParticipantsBoxController::Start(_channel); @@ -612,7 +644,9 @@ void SetupChannelBox::setInnerFocus() { } void SetupChannelBox::updateMaxHeight() { - auto newHeight = st::boxPadding.top() + st::newGroupPadding.top() + _public->heightNoMargins() + _aboutPublicHeight + st::newGroupSkip + _private->heightNoMargins() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom(); + auto newHeight = st::boxPadding.top() + st::newGroupPadding.top() + _public->heightNoMargins() + + _aboutPublicHeight + st::newGroupSkip + _private->heightNoMargins() + + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom(); if (!_channel->isMegagroup() || _privacyGroup->value() == Privacy::Public) { newHeight += st::newGroupLinkPadding.top() + _link->height() + st::newGroupLinkPadding.bottom(); } @@ -640,16 +674,22 @@ void SetupChannelBox::paintEvent(QPaintEvent *e) { p.fillRect(e->rect(), st::boxBg); p.setPen(st::newGroupAboutFg); - QRect aboutPublic(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadio.diameter + st::defaultBoxCheckbox.textPosition.x(), _public->bottomNoMargins(), _aboutPublicWidth, _aboutPublicHeight); + QRect aboutPublic(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadio.diameter + + st::defaultBoxCheckbox.textPosition.x(), + _public->bottomNoMargins(), _aboutPublicWidth, _aboutPublicHeight); _aboutPublic.drawLeft(p, aboutPublic.x(), aboutPublic.y(), aboutPublic.width(), width()); - QRect aboutPrivate(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadio.diameter + st::defaultBoxCheckbox.textPosition.x(), _private->bottomNoMargins(), _aboutPublicWidth, _aboutPublicHeight); + QRect aboutPrivate(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadio.diameter + + st::defaultBoxCheckbox.textPosition.x(), + _private->bottomNoMargins(), _aboutPublicWidth, _aboutPublicHeight); _aboutPrivate.drawLeft(p, aboutPrivate.x(), aboutPrivate.y(), aboutPrivate.width(), width()); if (!_channel->isMegagroup() || !_link->isHidden()) { p.setPen(st::boxTextFg); p.setFont(st::newGroupLinkFont); - p.drawTextLeft(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultInputField.textMargins.left(), _link->y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop, width(), lang(_link->isHidden() ? lng_create_group_invite_link : lng_create_group_link)); + p.drawTextLeft(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultInputField.textMargins.left(), + _link->y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop, width(), + lang(_link->isHidden() ? lng_create_group_invite_link : lng_create_group_link)); } if (_link->isHidden()) { @@ -658,18 +698,25 @@ void SetupChannelBox::paintEvent(QPaintEvent *e) { option.setWrapMode(QTextOption::WrapAnywhere); p.setFont(_linkOver ? st::boxTextFont->underline() : st::boxTextFont); p.setPen(st::defaultLinkButton.color); - auto inviteLinkText = _channel->inviteLink().isEmpty() ? lang(lng_group_invite_create) : _channel->inviteLink(); + auto inviteLinkText = + _channel->inviteLink().isEmpty() ? lang(lng_group_invite_create) : _channel->inviteLink(); p.drawText(_invitationLink, inviteLinkText, option); } } else { if (!_errorText.isEmpty()) { p.setPen(st::boxTextFgError); p.setFont(st::boxTextFont); - p.drawTextRight(st::boxPadding.right(), _link->y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, width(), _errorText); + p.drawTextRight(st::boxPadding.right(), + _link->y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, + width(), _errorText); } else if (!_goodText.isEmpty()) { p.setPen(st::boxTextFgGood); p.setFont(st::boxTextFont); - p.drawTextRight(st::boxPadding.right(), _link->y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, width(), _goodText); + p.drawTextRight(st::boxPadding.right(), + _link->y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, + width(), _goodText); } } } @@ -677,12 +724,18 @@ void SetupChannelBox::paintEvent(QPaintEvent *e) { void SetupChannelBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _public->moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), st::boxPadding.top() + st::newGroupPadding.top()); - _private->moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), _public->bottomNoMargins() + _aboutPublicHeight + st::newGroupSkip); + _public->moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), + st::boxPadding.top() + st::newGroupPadding.top()); + _private->moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), + _public->bottomNoMargins() + _aboutPublicHeight + st::newGroupSkip); - _link->resize(width() - st::boxPadding.left() - st::newGroupLinkPadding.left() - st::boxPadding.right(), _link->height()); - _link->moveToLeft(st::boxPadding.left() + st::newGroupLinkPadding.left(), _private->bottomNoMargins() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top()); - _invitationLink = QRect(_link->x(), _link->y() + (_link->height() / 2) - st::boxTextFont->height, _link->width(), 2 * st::boxTextFont->height); + _link->resize(width() - st::boxPadding.left() - st::newGroupLinkPadding.left() - st::boxPadding.right(), + _link->height()); + _link->moveToLeft(st::boxPadding.left() + st::newGroupLinkPadding.left(), + _private->bottomNoMargins() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top()); + _invitationLink = QRect(_link->x(), _link->y() + (_link->height() / 2) - st::boxTextFont->height, _link->width(), + 2 * st::boxTextFont->height); } void SetupChannelBox::mouseMoveEvent(QMouseEvent *e) { @@ -719,7 +772,9 @@ void SetupChannelBox::onSave() { if (_privacyGroup->value() == Privacy::Private) { if (_existing) { _sentUsername = QString(); - _saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail)); + _saveRequestId = + MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), + rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail)); } else { closeBox(); } @@ -735,7 +790,8 @@ void SetupChannelBox::onSave() { } _sentUsername = link; - _saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail)); + _saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), + rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail)); } void SetupChannelBox::onChange() { @@ -782,7 +838,8 @@ void SetupChannelBox::onCheck() { QString link = _link->text().trimmed(); if (link.size() >= MinUsernameLength) { _checkUsername = link; - _checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string(link)), rpcDone(&SetupChannelBox::onCheckDone), rpcFail(&SetupChannelBox::onCheckFail)); + _checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string(link)), + rpcDone(&SetupChannelBox::onCheckDone), rpcFail(&SetupChannelBox::onCheckFail)); } } @@ -790,11 +847,13 @@ void SetupChannelBox::privacyChanged(Privacy value) { if (value == Privacy::Public) { if (_tooMuchUsernames) { _privacyGroup->setValue(Privacy::Private); - Ui::show(Box(base::lambda_guarded(this, [this] { - _tooMuchUsernames = false; - _privacyGroup->setValue(Privacy::Public); - onCheck(); - })), KeepOtherLayers); + Ui::show(Box(base::lambda_guarded(this, + [this] { + _tooMuchUsernames = false; + _privacyGroup->setValue(Privacy::Public); + onCheck(); + })), + KeepOtherLayers); return; } _link->show(); @@ -843,7 +902,9 @@ bool SetupChannelBox::onUpdateFail(const RPCError &error) { void SetupChannelBox::onCheckDone(const MTPBool &result) { _checkRequestId = 0; - QString newError = (mtpIsTrue(result) || _checkUsername == _channel->username) ? QString() : lang(lng_create_channel_link_occupied); + QString newError = (mtpIsTrue(result) || _checkUsername == _channel->username) ? + QString() : + lang(lng_create_channel_link_occupied); QString newGood = newError.isEmpty() ? lang(lng_create_channel_link_available) : QString(); if (_errorText != newError || _goodText != newGood) { _errorText = newError; @@ -885,8 +946,9 @@ bool SetupChannelBox::onCheckFail(const RPCError &error) { void SetupChannelBox::showRevokePublicLinkBoxForEdit() { closeBox(); Ui::show(Box([channel = _channel, existing = _existing]() { - Ui::show(Box(channel, existing), KeepOtherLayers); - }), KeepOtherLayers); + Ui::show(Box(channel, existing), KeepOtherLayers); + }), + KeepOtherLayers); } bool SetupChannelBox::onFirstCheckFail(const RPCError &error) { @@ -911,12 +973,13 @@ bool SetupChannelBox::onFirstCheckFail(const RPCError &error) { return true; } -EditNameTitleBox::EditNameTitleBox(QWidget*, not_null peer) -: _peer(peer) -, _first(this, st::defaultInputField, langFactory(_peer->isUser() ? lng_signup_firstname : lng_dlg_new_group_name), _peer->isUser() ? _peer->asUser()->firstName : _peer->name) -, _last(this, st::defaultInputField, langFactory(lng_signup_lastname), peer->isUser() ? peer->asUser()->lastName : QString()) -, _invertOrder(!peer->isChat() && langFirstNameGoesSecond()) { -} +EditNameTitleBox::EditNameTitleBox(QWidget *, not_null peer) + : _peer(peer) + , _first(this, st::defaultInputField, langFactory(_peer->isUser() ? lng_signup_firstname : lng_dlg_new_group_name), + _peer->isUser() ? _peer->asUser()->firstName : _peer->name) + , _last(this, st::defaultInputField, langFactory(lng_signup_lastname), + peer->isUser() ? peer->asUser()->lastName : QString()) + , _invertOrder(!peer->isChat() && langFirstNameGoesSecond()) {} void EditNameTitleBox::prepare() { auto newHeight = st::contactPadding.top() + _first->height(); @@ -974,14 +1037,17 @@ void EditNameTitleBox::onSubmit() { void EditNameTitleBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _first->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _first->height()); + _first->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), + _first->height()); _last->resize(_first->size()); if (_invertOrder) { _last->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::contactPadding.top()); - _first->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _last->y() + _last->height() + st::contactSkip); + _first->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _last->y() + _last->height() + st::contactSkip); } else { _first->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::contactPadding.top()); - _last->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _first->y() + _first->height() + st::contactSkip); + _last->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _first->y() + _first->height() + st::contactSkip); } } @@ -1007,9 +1073,12 @@ void EditNameTitleBox::onSave() { _sentName = first; if (_peer == App::self()) { auto flags = MTPaccount_UpdateProfile::Flag::f_first_name | MTPaccount_UpdateProfile::Flag::f_last_name; - _requestId = MTP::send(MTPaccount_UpdateProfile(MTP_flags(flags), MTP_string(first), MTP_string(last), MTPstring()), rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail)); + _requestId = + MTP::send(MTPaccount_UpdateProfile(MTP_flags(flags), MTP_string(first), MTP_string(last), MTPstring()), + rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail)); } else if (_peer->isChat()) { - _requestId = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(first)), rpcDone(&EditNameTitleBox::onSaveChatDone), rpcFail(&EditNameTitleBox::onSaveChatFail)); + _requestId = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(first)), + rpcDone(&EditNameTitleBox::onSaveChatDone), rpcFail(&EditNameTitleBox::onSaveChatFail)); } } @@ -1066,13 +1135,13 @@ void EditNameTitleBox::onSaveChatDone(const MTPUpdates &updates) { closeBox(); } -EditBioBox::EditBioBox(QWidget*, not_null self) : BoxContent() -, _dynamicFieldStyle(CreateBioFieldStyle()) -, _self(self) -, _bio(this, _dynamicFieldStyle, langFactory(lng_bio_placeholder), _self->about()) -, _countdown(this, QString(), Ui::FlatLabel::InitType::Simple, st::editBioCountdownLabel) -, _about(this, lang(lng_bio_about), Ui::FlatLabel::InitType::Simple, st::aboutRevokePublicLabel) { -} +EditBioBox::EditBioBox(QWidget *, not_null self) + : BoxContent() + , _dynamicFieldStyle(CreateBioFieldStyle()) + , _self(self) + , _bio(this, _dynamicFieldStyle, langFactory(lng_bio_placeholder), _self->about()) + , _countdown(this, QString(), Ui::FlatLabel::InitType::Simple, st::editBioCountdownLabel) + , _about(this, lang(lng_bio_about), Ui::FlatLabel::InitType::Simple, st::aboutRevokePublicLabel) {} void EditBioBox::prepare() { setTitle(langFactory(lng_bio_title)); @@ -1092,7 +1161,8 @@ void EditBioBox::prepare() { } void EditBioBox::updateMaxHeight() { - auto newHeight = st::contactPadding.top() + _bio->height() + st::boxLittleSkip + _about->height() + st::boxPadding.bottom() + st::contactPadding.bottom(); + auto newHeight = st::contactPadding.top() + _bio->height() + st::boxLittleSkip + _about->height() + + st::boxPadding.bottom() + st::contactPadding.bottom(); setDimensions(st::boxWideWidth, newHeight); } @@ -1116,7 +1186,8 @@ void EditBioBox::setInnerFocus() { void EditBioBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _bio->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _bio->height()); + _bio->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), + _bio->height()); _bio->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::contactPadding.top()); _countdown->moveToRight(st::boxPadding.right(), _bio->y() + _dynamicFieldStyle.textMargins.top()); _about->moveToLeft(st::boxPadding.left(), _bio->y() + _bio->height() + st::boxLittleSkip); @@ -1129,23 +1200,27 @@ void EditBioBox::save() { _sentBio = text; auto flags = MTPaccount_UpdateProfile::Flag::f_about; - _requestId = request(MTPaccount_UpdateProfile(MTP_flags(flags), MTPstring(), MTPstring(), MTP_string(text))).done([this](const MTPUser &result) { - App::feedUsers(MTP_vector(1, result)); - _self->setAbout(_sentBio); - closeBox(); - }).send(); + _requestId = request(MTPaccount_UpdateProfile(MTP_flags(flags), MTPstring(), MTPstring(), MTP_string(text))) + .done([this](const MTPUser &result) { + App::feedUsers(MTP_vector(1, result)); + _self->setAbout(_sentBio); + closeBox(); + }) + .send(); } -EditChannelBox::EditChannelBox(QWidget*, not_null channel) -: _channel(channel) -, _title(this, st::defaultInputField, langFactory(_channel->isMegagroup() ? lng_dlg_new_group_name : lng_dlg_new_channel_name), _channel->name) -, _description(this, st::newGroupDescription, langFactory(lng_create_group_description), _channel->about()) -, _sign(this, lang(lng_edit_sign_messages), channel->addsSignature(), st::defaultBoxCheckbox) -, _inviteGroup(std::make_shared>(channel->anyoneCanAddMembers() ? Invites::Everybody : Invites::OnlyAdmins)) -, _inviteEverybody(this, _inviteGroup, Invites::Everybody, lang(lng_edit_group_invites_everybody)) -, _inviteOnlyAdmins(this, _inviteGroup, Invites::OnlyAdmins, lang(lng_edit_group_invites_only_admins)) -, _publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link), st::boxLinkButton) { -} +EditChannelBox::EditChannelBox(QWidget *, not_null channel) + : _channel(channel) + , _title(this, st::defaultInputField, + langFactory(_channel->isMegagroup() ? lng_dlg_new_group_name : lng_dlg_new_channel_name), _channel->name) + , _description(this, st::newGroupDescription, langFactory(lng_create_group_description), _channel->about()) + , _sign(this, lang(lng_edit_sign_messages), channel->addsSignature(), st::defaultBoxCheckbox) + , _inviteGroup(std::make_shared>(channel->anyoneCanAddMembers() ? Invites::Everybody : + Invites::OnlyAdmins)) + , _inviteEverybody(this, _inviteGroup, Invites::Everybody, lang(lng_edit_group_invites_everybody)) + , _inviteOnlyAdmins(this, _inviteGroup, Invites::OnlyAdmins, lang(lng_edit_group_invites_only_admins)) + , _publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link), + st::boxLinkButton) {} void EditChannelBox::prepare() { setTitle(langFactory(_channel->isMegagroup() ? lng_edit_group : lng_edit_channel_title)); @@ -1153,11 +1228,12 @@ void EditChannelBox::prepare() { addButton(langFactory(lng_settings_save), [this] { onSave(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer == _channel) { - handleChannelNameChange(); - } - })); + subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, + [this](const Notify::PeerUpdate &update) { + if (update.peer == _channel) { + handleChannelNameChange(); + } + })); setMouseTracking(true); @@ -1211,16 +1287,19 @@ bool EditChannelBox::canEditInvites() const { void EditChannelBox::updateMaxHeight() { auto newHeight = st::newGroupInfoPadding.top() + _title->height(); - newHeight += st::newGroupDescriptionPadding.top() + _description->height() + st::newGroupDescriptionPadding.bottom(); + newHeight += + st::newGroupDescriptionPadding.top() + _description->height() + st::newGroupDescriptionPadding.bottom(); if (canEditSignatures()) { - newHeight += st::newGroupPublicLinkPadding.top() + _sign->heightNoMargins() + st::newGroupPublicLinkPadding.bottom(); + newHeight += + st::newGroupPublicLinkPadding.top() + _sign->heightNoMargins() + st::newGroupPublicLinkPadding.bottom(); } if (canEditInvites()) { newHeight += st::boxTitleHeight + _inviteEverybody->heightNoMargins(); newHeight += st::boxLittleSkip + _inviteOnlyAdmins->heightNoMargins(); } if (_channel->canEditUsername()) { - newHeight += st::newGroupPublicLinkPadding.top() + _publicLink->height() + st::newGroupPublicLinkPadding.bottom(); + newHeight += + st::newGroupPublicLinkPadding.top() + _publicLink->height() + st::newGroupPublicLinkPadding.bottom(); } newHeight += st::boxPadding.bottom() + st::newGroupInfoPadding.bottom(); setDimensions(st::boxWideWidth, newHeight); @@ -1229,23 +1308,37 @@ void EditChannelBox::updateMaxHeight() { void EditChannelBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _title->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _title->height()); - _title->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::newGroupInfoPadding.top() + st::newGroupNamePosition.y()); + _title->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), + _title->height()); + _title->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + st::newGroupInfoPadding.top() + st::newGroupNamePosition.y()); - _description->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _description->height()); - _description->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _title->y() + _title->height() + st::newGroupDescriptionPadding.top()); + _description->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), + _description->height()); + _description->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _title->y() + _title->height() + st::newGroupDescriptionPadding.top()); - _sign->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top()); + _sign->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _description->y() + _description->height() + st::newGroupDescriptionPadding.bottom() + + st::newGroupPublicLinkPadding.top()); - _inviteEverybody->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::boxTitleHeight); - _inviteOnlyAdmins->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _inviteEverybody->bottomNoMargins() + st::boxLittleSkip); + _inviteEverybody->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _description->y() + _description->height() + st::boxTitleHeight); + _inviteOnlyAdmins->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _inviteEverybody->bottomNoMargins() + st::boxLittleSkip); if (canEditSignatures()) { - _publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _sign->bottomNoMargins() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top()); + _publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _sign->bottomNoMargins() + st::newGroupDescriptionPadding.bottom() + + st::newGroupPublicLinkPadding.top()); } else if (canEditInvites()) { - _publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _inviteOnlyAdmins->bottomNoMargins() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top()); + _publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _inviteOnlyAdmins->bottomNoMargins() + st::newGroupDescriptionPadding.bottom() + + st::newGroupPublicLinkPadding.top()); } else { - _publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top()); + _publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), + _description->y() + _description->height() + st::newGroupDescriptionPadding.bottom() + + st::newGroupPublicLinkPadding.top()); } } @@ -1256,7 +1349,8 @@ void EditChannelBox::paintEvent(QPaintEvent *e) { Painter p(this); p.setPen(st::boxTitleFg); p.setFont(st::autoDownloadTitleFont); - p.drawTextLeft(st::boxTitlePosition.x(), _description->y() + _description->height() + st::boxTitlePosition.y(), width(), lang(lng_edit_group_who_invites)); + p.drawTextLeft(st::boxTitlePosition.x(), _description->y() + _description->height() + st::boxTitlePosition.y(), + width(), lang(lng_edit_group_who_invites)); } } @@ -1264,7 +1358,8 @@ void EditChannelBox::onSave() { if (_saveTitleRequestId || _saveDescriptionRequestId || _saveSignRequestId || _saveInvitesRequestId) return; auto title = TextUtilities::PrepareForSending(_title->getLastText()); - auto description = TextUtilities::PrepareForSending(_description->getLastText(), TextUtilities::PrepareTextOption::CheckLinks); + auto description = + TextUtilities::PrepareForSending(_description->getLastText(), TextUtilities::PrepareTextOption::CheckLinks); if (title.isEmpty()) { _title->setFocus(); _title->showError(); @@ -1275,7 +1370,9 @@ void EditChannelBox::onSave() { if (_sentTitle == _channel->name) { saveDescription(); } else { - _saveTitleRequestId = MTP::send(MTPchannels_EditTitle(_channel->inputChannel, MTP_string(_sentTitle)), rpcDone(&EditChannelBox::onSaveTitleDone), rpcFail(&EditChannelBox::onSaveFail)); + _saveTitleRequestId = + MTP::send(MTPchannels_EditTitle(_channel->inputChannel, MTP_string(_sentTitle)), + rpcDone(&EditChannelBox::onSaveTitleDone), rpcFail(&EditChannelBox::onSaveFail)); } } @@ -1287,7 +1384,9 @@ void EditChannelBox::saveDescription() { if (_sentDescription == _channel->about()) { saveSign(); } else { - _saveDescriptionRequestId = MTP::send(MTPchannels_EditAbout(_channel->inputChannel, MTP_string(_sentDescription)), rpcDone(&EditChannelBox::onSaveDescriptionDone), rpcFail(&EditChannelBox::onSaveFail)); + _saveDescriptionRequestId = + MTP::send(MTPchannels_EditAbout(_channel->inputChannel, MTP_string(_sentDescription)), + rpcDone(&EditChannelBox::onSaveDescriptionDone), rpcFail(&EditChannelBox::onSaveFail)); } } @@ -1295,7 +1394,8 @@ void EditChannelBox::saveSign() { if (!canEditSignatures() || _channel->addsSignature() == _sign->checked()) { saveInvites(); } else { - _saveSignRequestId = MTP::send(MTPchannels_ToggleSignatures(_channel->inputChannel, MTP_bool(_sign->checked())), rpcDone(&EditChannelBox::onSaveSignDone), rpcFail(&EditChannelBox::onSaveFail)); + _saveSignRequestId = MTP::send(MTPchannels_ToggleSignatures(_channel->inputChannel, MTP_bool(_sign->checked())), + rpcDone(&EditChannelBox::onSaveSignDone), rpcFail(&EditChannelBox::onSaveFail)); } } @@ -1303,7 +1403,9 @@ void EditChannelBox::saveInvites() { if (!canEditInvites() || _channel->anyoneCanAddMembers() == (_inviteGroup->value() == Invites::Everybody)) { closeBox(); } else { - _saveInvitesRequestId = MTP::send(MTPchannels_ToggleInvites(_channel->inputChannel, MTP_bool(_inviteGroup->value() == Invites::Everybody)), rpcDone(&EditChannelBox::onSaveInvitesDone), rpcFail(&EditChannelBox::onSaveFail)); + _saveInvitesRequestId = MTP::send( + MTPchannels_ToggleInvites(_channel->inputChannel, MTP_bool(_inviteGroup->value() == Invites::Everybody)), + rpcDone(&EditChannelBox::onSaveInvitesDone), rpcFail(&EditChannelBox::onSaveFail)); } } @@ -1377,48 +1479,55 @@ void EditChannelBox::onSaveInvitesDone(const MTPUpdates &result) { closeBox(); } -RevokePublicLinkBox::Inner::Inner(QWidget *parent, base::lambda revokeCallback) : TWidget(parent) -, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) -, _revokeWidth(st::normalFont->width(lang(lng_channels_too_much_public_revoke))) -, _revokeCallback(std::move(revokeCallback)) { +RevokePublicLinkBox::Inner::Inner(QWidget *parent, base::lambda revokeCallback) + : TWidget(parent) + , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) + , _revokeWidth(st::normalFont->width(lang(lng_channels_too_much_public_revoke))) + , _revokeCallback(std::move(revokeCallback)) { setMouseTracking(true); resize(width(), 5 * _rowHeight); - request(MTPchannels_GetAdminedPublicChannels()).done([this](const MTPmessages_Chats &result) { - if (auto chats = Api::getChatsFromMessagesChats(result)) { - for_const (auto &chat, chats->v) { - if (auto peer = App::feedChat(chat)) { - if (!peer->isChannel() || peer->userName().isEmpty()) { - continue; - } + request(MTPchannels_GetAdminedPublicChannels()) + .done([this](const MTPmessages_Chats &result) { + if (auto chats = Api::getChatsFromMessagesChats(result)) { + for_const (auto &chat, chats->v) { + if (auto peer = App::feedChat(chat)) { + if (!peer->isChannel() || peer->userName().isEmpty()) { + continue; + } - auto row = ChatRow(peer); - row.peer = peer; - row.name.setText(st::contactsNameStyle, peer->name, _textNameOptions); - row.status.setText(st::defaultTextStyle, Messenger::Instance().createInternalLink(textcmdLink(1, peer->userName())), _textDlgOptions); - _rows.push_back(std::move(row)); - } - } - } - resize(width(), _rows.size() * _rowHeight); - update(); - }).send(); + auto row = ChatRow(peer); + row.peer = peer; + row.name.setText(st::contactsNameStyle, peer->name, _textNameOptions); + row.status.setText(st::defaultTextStyle, + Messenger::Instance().createInternalLink(textcmdLink(1, peer->userName())), + _textDlgOptions); + _rows.push_back(std::move(row)); + } + } + } + resize(width(), _rows.size() * _rowHeight); + update(); + }) + .send(); } -RevokePublicLinkBox::RevokePublicLinkBox(QWidget*, base::lambda revokeCallback) -: _aboutRevoke(this, lang(lng_channels_too_much_public_about), Ui::FlatLabel::InitType::Simple, st::aboutRevokePublicLabel) -, _revokeCallback(std::move(revokeCallback)) { -} +RevokePublicLinkBox::RevokePublicLinkBox(QWidget *, base::lambda revokeCallback) + : _aboutRevoke(this, lang(lng_channels_too_much_public_about), Ui::FlatLabel::InitType::Simple, + st::aboutRevokePublicLabel) + , _revokeCallback(std::move(revokeCallback)) {} void RevokePublicLinkBox::prepare() { _innerTop = st::boxPadding.top() + _aboutRevoke->height() + st::boxPadding.top(); - _inner = setInnerWidget(object_ptr(this, [this] { - closeBox(); - if (_revokeCallback) { - _revokeCallback(); - } - }), st::boxLayerScroll, _innerTop); + _inner = setInnerWidget(object_ptr(this, + [this] { + closeBox(); + if (_revokeCallback) { + _revokeCallback(); + } + }), + st::boxLayerScroll, _innerTop); addButton(langFactory(lng_cancel), [this] { closeBox(); }); @@ -1437,7 +1546,10 @@ void RevokePublicLinkBox::Inner::updateSelected() { PeerData *selected = nullptr; auto top = _rowsTop; for_const (auto &row, _rows) { - auto revokeLink = rtlrect(width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - _revokeWidth, top + st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, _revokeWidth, st::normalFont->height, width()); + auto revokeLink = + rtlrect(width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - _revokeWidth, + top + st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, + _revokeWidth, st::normalFont->height, width()); if (revokeLink.contains(point)) { selected = row.peer; break; @@ -1462,20 +1574,31 @@ void RevokePublicLinkBox::Inner::mouseReleaseEvent(QMouseEvent *e) { auto pressed = base::take(_pressed); setCursor((_selected || _pressed) ? style::cur_pointer : style::cur_default); if (pressed && pressed == _selected) { - auto text_method = pressed->isMegagroup() ? lng_channels_too_much_public_revoke_confirm_group : lng_channels_too_much_public_revoke_confirm_channel; - auto text = text_method(lt_link, Messenger::Instance().createInternalLink(pressed->userName()), lt_group, pressed->name); + auto text_method = pressed->isMegagroup() ? lng_channels_too_much_public_revoke_confirm_group : + lng_channels_too_much_public_revoke_confirm_channel; + auto text = text_method(lt_link, Messenger::Instance().createInternalLink(pressed->userName()), lt_group, + pressed->name); auto confirmText = lang(lng_channels_too_much_public_revoke); - _weakRevokeConfirmBox = Ui::show(Box(text, confirmText, base::lambda_guarded(this, [this, pressed]() { - if (_revokeRequestId) return; - _revokeRequestId = request(MTPchannels_UpdateUsername(pressed->asChannel()->inputChannel, MTP_string(""))).done([this](const MTPBool &result) { - if (_weakRevokeConfirmBox) { - _weakRevokeConfirmBox->closeBox(); - } - if (_revokeCallback) { - _revokeCallback(); - } - }).send(); - })), KeepOtherLayers); + _weakRevokeConfirmBox = + Ui::show(Box(text, confirmText, + base::lambda_guarded(this, + [this, pressed]() { + if (_revokeRequestId) return; + _revokeRequestId = + request(MTPchannels_UpdateUsername( + pressed->asChannel()->inputChannel, + MTP_string(""))) + .done([this](const MTPBool &result) { + if (_weakRevokeConfirmBox) { + _weakRevokeConfirmBox->closeBox(); + } + if (_revokeCallback) { + _revokeCallback(); + } + }) + .send(); + })), + KeepOtherLayers); } } @@ -1505,13 +1628,16 @@ void RevokePublicLinkBox::Inner::paintChat(Painter &p, const ChatRow &row, bool if (peer->isVerified()) { auto icon = &st::dialogsVerifiedIcon; namew -= icon->width(); - icon->paint(p, namex + std::min(row.name.maxWidth(), namew), st::contactsPadding.top() + st::contactsNameTop, width()); + icon->paint(p, namex + std::min(row.name.maxWidth(), namew), st::contactsPadding.top() + st::contactsNameTop, + width()); } row.name.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsNameTop, namew, width()); p.setFont(selected ? st::linkOverFont : st::linkFont); p.setPen(selected ? st::defaultLinkButton.overColor : st::defaultLinkButton.color); - p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), lang(lng_channels_too_much_public_revoke), _revokeWidth); + p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), + st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), + lang(lng_channels_too_much_public_revoke), _revokeWidth); p.setPen(st::contactsStatusFg); p.setTextPalette(st::revokePublicLinkStatusPalette); diff --git a/Telegram/SourceFiles/boxes/add_contact_box.h b/Telegram/SourceFiles/boxes/add_contact_box.h index 61b93559a..72dd67f1c 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.h +++ b/Telegram/SourceFiles/boxes/add_contact_box.h @@ -33,10 +33,8 @@ class PhoneInput; class InputArea; class UsernameInput; class Checkbox; -template -class RadioenumGroup; -template -class Radioenum; +template class RadioenumGroup; +template class Radioenum; class LinkButton; class NewAvatarButton; } // namespace Ui @@ -52,8 +50,8 @@ class AddContactBox : public BoxContent, public RPCSender { Q_OBJECT public: - AddContactBox(QWidget*, QString fname = QString(), QString lname = QString(), QString phone = QString()); - AddContactBox(QWidget*, UserData *user); + AddContactBox(QWidget *, QString fname = QString(), QString lname = QString(), QString phone = QString()); + AddContactBox(QWidget *, UserData *user); protected: void prepare() override; @@ -88,14 +86,13 @@ private: mtpRequestId _addRequest = 0; QString _sentName; - }; class GroupInfoBox : public BoxContent, private MTP::Sender { Q_OBJECT public: - GroupInfoBox(QWidget*, CreatingGroupType creating, bool fromTypeChoose); + GroupInfoBox(QWidget *, CreatingGroupType creating, bool fromTypeChoose); protected: void prepare() override; @@ -116,7 +113,8 @@ private slots: private: void setupPhotoButton(); void createChannel(const QString &title, const QString &description); - void createGroup(not_null selectUsersBox, const QString &title, const std::vector> &users); + void createGroup(not_null selectUsersBox, const QString &title, + const std::vector> &users); void updateMaxHeight(); void updateSelected(const QPoint &cursorGlobalPosition); @@ -126,21 +124,20 @@ private: object_ptr _photo; object_ptr _title; - object_ptr _description = { nullptr }; + object_ptr _description = {nullptr}; QImage _photoImage; // group / channel creation mtpRequestId _creationRequestId = 0; ChannelData *_createdChannel = nullptr; - }; class SetupChannelBox : public BoxContent, public RPCSender { Q_OBJECT public: - SetupChannelBox(QWidget*, ChannelData *channel, bool existing = false); + SetupChannelBox(QWidget *, ChannelData *channel, bool existing = false); void setInnerFocus() override; @@ -199,14 +196,13 @@ private: QString _sentUsername, _checkUsername, _errorText, _goodText; QTimer _checkTimer; - }; class EditNameTitleBox : public BoxContent, public RPCSender { Q_OBJECT public: - EditNameTitleBox(QWidget*, not_null peer); + EditNameTitleBox(QWidget *, not_null peer); protected: void setInnerFocus() override; @@ -225,7 +221,7 @@ private: void onSaveChatDone(const MTPUpdates &updates); bool onSaveChatFail(const RPCError &e); - not_null _peer; + not_null _peer; object_ptr _first; object_ptr _last; @@ -234,12 +230,11 @@ private: mtpRequestId _requestId = 0; QString _sentName; - }; class EditBioBox : public BoxContent, private MTP::Sender { public: - EditBioBox(QWidget*, not_null self); + EditBioBox(QWidget *, not_null self); protected: void setInnerFocus() override; @@ -253,21 +248,20 @@ private: void save(); style::InputField _dynamicFieldStyle; - not_null _self; + not_null _self; object_ptr _bio; object_ptr _countdown; object_ptr _about; mtpRequestId _requestId = 0; QString _sentBio; - }; class EditChannelBox : public BoxContent, public RPCSender { Q_OBJECT public: - EditChannelBox(QWidget*, not_null channel); + EditChannelBox(QWidget *, not_null channel); protected: void prepare() override; @@ -301,7 +295,7 @@ private: void saveSign(); void saveInvites(); - not_null _channel; + not_null _channel; object_ptr _title; object_ptr _description; @@ -323,12 +317,11 @@ private: mtpRequestId _saveInvitesRequestId = 0; QString _sentTitle, _sentDescription; - }; class RevokePublicLinkBox : public BoxContent, public RPCSender { public: - RevokePublicLinkBox(QWidget*, base::lambda revokeCallback); + RevokePublicLinkBox(QWidget *, base::lambda revokeCallback); protected: void prepare() override; @@ -343,5 +336,4 @@ private: int _innerTop = 0; base::lambda _revokeCallback; - }; diff --git a/Telegram/SourceFiles/boxes/autolock_box.cpp b/Telegram/SourceFiles/boxes/autolock_box.cpp index 9c9f9b91a..fbc57e98f 100644 --- a/Telegram/SourceFiles/boxes/autolock_box.cpp +++ b/Telegram/SourceFiles/boxes/autolock_box.cpp @@ -20,31 +20,36 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/autolock_box.h" -#include "lang/lang_keys.h" -#include "storage/localstorage.h" -#include "mainwindow.h" -#include "ui/widgets/checkbox.h" -#include "styles/style_boxes.h" #include "facades.h" +#include "lang/lang_keys.h" +#include "mainwindow.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" +#include "ui/widgets/checkbox.h" void AutoLockBox::prepare() { setTitle(langFactory(lng_passcode_autolock)); addButton(langFactory(lng_box_ok), [this] { closeBox(); }); - auto options = { 60, 300, 3600, 18000 }; + auto options = {60, 300, 3600, 18000}; auto group = std::make_shared(Global::AutoLock()); auto y = st::boxOptionListPadding.top() + st::langsButton.margin.top(); auto count = int(options.size()); _options.reserve(count); for (auto seconds : options) { - _options.emplace_back(this, group, seconds, (seconds % 3600) ? lng_passcode_autolock_minutes(lt_count, seconds / 60) : lng_passcode_autolock_hours(lt_count, seconds / 3600), st::langsButton); + _options.emplace_back(this, group, seconds, + (seconds % 3600) ? lng_passcode_autolock_minutes(lt_count, seconds / 60) : + lng_passcode_autolock_hours(lt_count, seconds / 3600), + st::langsButton); _options.back()->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), y); y += _options.back()->heightNoMargins() + st::boxOptionListSkip; } group->setChangedCallback([this](int value) { durationChanged(value); }); - setDimensions(st::langsWidth, st::boxOptionListPadding.top() + count * _options.back()->heightNoMargins() + (count - 1) * st::boxOptionListSkip + st::boxOptionListPadding.bottom() + st::boxPadding.bottom()); + setDimensions(st::langsWidth, st::boxOptionListPadding.top() + count * _options.back()->heightNoMargins() + + (count - 1) * st::boxOptionListSkip + st::boxOptionListPadding.bottom() + + st::boxPadding.bottom()); } void AutoLockBox::durationChanged(int seconds) { diff --git a/Telegram/SourceFiles/boxes/autolock_box.h b/Telegram/SourceFiles/boxes/autolock_box.h index 6ec547324..4203a8fec 100644 --- a/Telegram/SourceFiles/boxes/autolock_box.h +++ b/Telegram/SourceFiles/boxes/autolock_box.h @@ -30,8 +30,7 @@ class AutoLockBox : public BoxContent { Q_OBJECT public: - AutoLockBox(QWidget*) { - } + AutoLockBox(QWidget*) {} protected: void prepare() override; @@ -40,5 +39,4 @@ private: void durationChanged(int seconds); std::vector> _options; - }; diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp index 2c9dd890e..e6da96216 100644 --- a/Telegram/SourceFiles/boxes/background_box.cpp +++ b/Telegram/SourceFiles/boxes/background_box.cpp @@ -20,14 +20,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/background_box.h" +#include "auth_session.h" #include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" -#include "window/themes/window_theme.h" -#include "styles/style_overview.h" #include "styles/style_boxes.h" +#include "styles/style_overview.h" #include "ui/effects/round_checkbox.h" -#include "auth_session.h" +#include "window/themes/window_theme.h" class BackgroundBox::Inner : public TWidget, public RPCSender, private base::Subscriber { public: @@ -56,11 +56,9 @@ private: int _over = -1; int _overDown = -1; std::unique_ptr _check; // this is not a widget - }; -BackgroundBox::BackgroundBox(QWidget*) { -} +BackgroundBox::BackgroundBox(QWidget *) {} void BackgroundBox::prepare() { setTitle(langFactory(lng_backgrounds_header)); @@ -84,11 +82,13 @@ void BackgroundBox::backgroundChosen(int index) { closeBox(); } -BackgroundBox::Inner::Inner(QWidget *parent) : TWidget(parent) -, _check(std::make_unique(st::overviewCheck, [this] { update(); })) { +BackgroundBox::Inner::Inner(QWidget *parent) + : TWidget(parent) + , _check(std::make_unique(st::overviewCheck, [this] { update(); })) { _check->setChecked(true, Ui::RoundCheckbox::SetStyle::Fast); if (App::cServerBackgrounds().isEmpty()) { - resize(BackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, 2 * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding); + resize(BackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, + 2 * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding); MTP::send(MTPaccount_GetWallPapers(), rpcDone(&Inner::gotWallpapers)); } else { updateWallpapers(); @@ -136,7 +136,8 @@ void BackgroundBox::Inner::gotWallpapers(const MTPVector &result) } if (!size || !w || !h) continue; - qint32 newThumbLevel = qAbs((st::backgroundSize.width() * cIntRetinaFactor()) - w), newFullLevel = qAbs(2560 - w); + qint32 newThumbLevel = qAbs((st::backgroundSize.width() * cIntRetinaFactor()) - w), + newFullLevel = qAbs(2560 - w); if (thumbLevel < 0 || newThumbLevel < thumbLevel) { thumbLevel = newThumbLevel; thumb = &(*j); @@ -147,7 +148,8 @@ void BackgroundBox::Inner::gotWallpapers(const MTPVector &result) } } if (thumb && full && full->type() != mtpc_photoSizeEmpty) { - wallpapers.push_back(App::WallPaper(d.vid.v ? d.vid.v : INT_MAX, App::image(*thumb), App::image(*full))); + wallpapers.push_back( + App::WallPaper(d.vid.v ? d.vid.v : INT_MAX, App::image(*thumb), App::image(*full))); } } break; @@ -166,7 +168,8 @@ void BackgroundBox::Inner::updateWallpapers() { _rows = _bgCount / BackgroundsInRow; if (_bgCount % BackgroundsInRow) ++_rows; - resize(BackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, _rows * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding); + resize(BackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, + _rows * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding); for (int i = 0; i < BackgroundsInRow * 3; ++i) { if (i >= _bgCount) break; @@ -211,10 +214,14 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) { void BackgroundBox::Inner::mouseMoveEvent(QMouseEvent *e) { int x = e->pos().x(), y = e->pos().y(); int row = int((y - st::backgroundPadding) / (st::backgroundSize.height() + st::backgroundPadding)); - if (y - row * (st::backgroundSize.height() + st::backgroundPadding) > st::backgroundPadding + st::backgroundSize.height()) row = _rows + 1; + if (y - row * (st::backgroundSize.height() + st::backgroundPadding) > + st::backgroundPadding + st::backgroundSize.height()) + row = _rows + 1; int col = int((x - st::backgroundPadding) / (st::backgroundSize.width() + st::backgroundPadding)); - if (x - col * (st::backgroundSize.width() + st::backgroundPadding) > st::backgroundPadding + st::backgroundSize.width()) row = _rows + 1; + if (x - col * (st::backgroundSize.width() + st::backgroundPadding) > + st::backgroundPadding + st::backgroundSize.width()) + row = _rows + 1; int newOver = row * BackgroundsInRow + col; if (newOver >= _bgCount) newOver = -1; diff --git a/Telegram/SourceFiles/boxes/background_box.h b/Telegram/SourceFiles/boxes/background_box.h index f24331dd8..741787616 100644 --- a/Telegram/SourceFiles/boxes/background_box.h +++ b/Telegram/SourceFiles/boxes/background_box.h @@ -38,5 +38,4 @@ private: class Inner; QPointer _inner; - }; diff --git a/Telegram/SourceFiles/boxes/calendar_box.cpp b/Telegram/SourceFiles/boxes/calendar_box.cpp index 8d4af760e..a01af4934 100644 --- a/Telegram/SourceFiles/boxes/calendar_box.cpp +++ b/Telegram/SourceFiles/boxes/calendar_box.cpp @@ -20,11 +20,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/calendar_box.h" -#include "ui/widgets/buttons.h" +#include "lang/lang_keys.h" #include "styles/style_boxes.h" #include "styles/style_dialogs.h" -#include "lang/lang_keys.h" #include "ui/effects/ripple_animation.h" +#include "ui/widgets/buttons.h" namespace { @@ -92,10 +92,10 @@ private: int _daysCount = 0; int _daysShift = 0; int _rowsCount = 0; - }; -CalendarBox::Context::Context(QDate month, QDate highlighted) : _highlighted(highlighted) { +CalendarBox::Context::Context(QDate month, QDate highlighted) + : _highlighted(highlighted) { showMonth(month); } @@ -176,7 +176,8 @@ QDate CalendarBox::Context::dateFromIndex(int index) const { } index += QDate(year, month, 1).daysInMonth(); } - for (auto maxIndex = QDate(year, month, 1).daysInMonth(); index >= maxIndex; maxIndex = QDate(year, month, 1).daysInMonth()) { + for (auto maxIndex = QDate(year, month, 1).daysInMonth(); index >= maxIndex; + maxIndex = QDate(year, month, 1).daysInMonth()) { index -= maxIndex; if (month++ == kMonthsCount) { month -= kMonthsCount; @@ -236,11 +237,11 @@ private: static constexpr auto kEmptySelection = -kDaysInWeek; int _selected = kEmptySelection; int _pressed = kEmptySelection; - }; -CalendarBox::Inner::Inner(QWidget *parent, Context *context) : TWidget(parent) -, _context(context) { +CalendarBox::Inner::Inner(QWidget *parent, Context *context) + : TWidget(parent) + , _context(context) { setMouseTracking(true); subscribe(context->month(), [this](QDate month) { monthChanged(month); }); } @@ -295,11 +296,11 @@ void CalendarBox::Inner::paintRows(Painter &p, QRect clip) { auto y = rowsTop(); auto index = -_context->daysShift(); auto highlightedIndex = _context->highlightedIndex(); - for (auto row = 0, rowsCount = _context->rowsCount(), daysCount = _context->daysCount() - ; row != rowsCount - ; ++row, y += st::calendarCellSize.height()) { + for (auto row = 0, rowsCount = _context->rowsCount(), daysCount = _context->daysCount(); row != rowsCount; + ++row, y += st::calendarCellSize.height()) { auto x = rowsLeft(); - if (!myrtlrect(x, y, st::calendarCellSize.width() * kDaysInWeek, st::calendarCellSize.height()).intersects(clip)) { + if (!myrtlrect(x, y, st::calendarCellSize.width() * kDaysInWeek, st::calendarCellSize.height()) + .intersects(clip)) { index += kDaysInWeek; continue; } @@ -364,14 +365,20 @@ void CalendarBox::Inner::mousePressEvent(QMouseEvent *e) { auto row = index / kDaysInWeek; auto col = index % kDaysInWeek; - auto cell = QRect(rowsLeft() + col * st::calendarCellSize.width(), rowsTop() + row * st::calendarCellSize.height(), st::calendarCellSize.width(), st::calendarCellSize.height()); + auto cell = + QRect(rowsLeft() + col * st::calendarCellSize.width(), rowsTop() + row * st::calendarCellSize.height(), + st::calendarCellSize.width(), st::calendarCellSize.height()); auto it = _ripples.find(_selected); if (it == _ripples.cend()) { auto mask = Ui::RippleAnimation::ellipseMask(QSize(st::calendarCellInner, st::calendarCellInner)); auto update = [this, cell] { rtlupdate(cell); }; - it = _ripples.emplace(_selected, std::make_unique(st::defaultRippleAnimation, std::move(mask), std::move(update))).first; + it = _ripples + .emplace(_selected, std::make_unique(st::defaultRippleAnimation, + std::move(mask), std::move(update))) + .first; } - auto ripplePosition = QPoint(cell.x() + (st::calendarCellSize.width() - st::calendarCellInner) / 2, cell.y() + (st::calendarCellSize.height() - st::calendarCellInner) / 2); + auto ripplePosition = QPoint(cell.x() + (st::calendarCellSize.width() - st::calendarCellInner) / 2, + cell.y() + (st::calendarCellSize.height() - st::calendarCellInner) / 2); it->second->add(e->pos() - ripplePosition); } } @@ -400,7 +407,9 @@ CalendarBox::Inner::~Inner() = default; class CalendarBox::Title : public TWidget, private base::Subscriber { public: - Title(QWidget *parent, Context *context) : TWidget(parent), _context(context) { + Title(QWidget *parent, Context *context) + : TWidget(parent) + , _context(context) { subscribe(_context->month(), [this](QDate date) { monthChanged(date); }); } @@ -414,7 +423,6 @@ private: QString _text; int _textWidth = 0; - }; void CalendarBox::Title::monthChanged(QDate month) { @@ -428,17 +436,17 @@ void CalendarBox::Title::paintEvent(QPaintEvent *e) { p.setFont(st::calendarTitleFont); p.setPen(st::boxTitleFg); - p.drawTextLeft((width() - _textWidth) / 2, (height() - st::calendarTitleFont->height) / 2, width(), _text, _textWidth); + p.drawTextLeft((width() - _textWidth) / 2, (height() - st::calendarTitleFont->height) / 2, width(), _text, + _textWidth); } -CalendarBox::CalendarBox(QWidget*, QDate month, QDate highlighted, base::lambda callback) -: _context(std::make_unique(month, highlighted)) -, _inner(this, _context.get()) -, _title(this, _context.get()) -, _previous(this, st::calendarPrevious) -, _next(this, st::calendarNext) -, _callback(std::move(callback)) { -} +CalendarBox::CalendarBox(QWidget *, QDate month, QDate highlighted, base::lambda callback) + : _context(std::make_unique(month, highlighted)) + , _inner(this, _context.get()) + , _title(this, _context.get()) + , _previous(this, st::calendarPrevious) + , _next(this, st::calendarNext) + , _callback(std::move(callback)) {} void CalendarBox::setMinDate(QDate date) { _context->setMinDate(date); @@ -460,7 +468,7 @@ void CalendarBox::prepare() { } }); -// _inner = setInnerWidget(object_ptr(this, _context.get()), st::calendarScroll, st::calendarTitleHeight); + // _inner = setInnerWidget(object_ptr(this, _context.get()), st::calendarScroll, st::calendarTitleHeight); _inner->setDateChosenCallback(std::move(_callback)); addButton(langFactory(lng_close), [this] { closeBox(); }); @@ -493,7 +501,8 @@ void CalendarBox::monthChanged(QDate month) { void CalendarBox::resizeEvent(QResizeEvent *e) { _previous->moveToLeft(0, 0); _next->moveToRight(0, 0); - _title->setGeometryToLeft(_previous->width(), 0, width() - _previous->width() - _next->width(), st::calendarTitleHeight); + _title->setGeometryToLeft(_previous->width(), 0, width() - _previous->width() - _next->width(), + st::calendarTitleHeight); _inner->setGeometryToLeft(0, st::calendarTitleHeight, width(), height() - st::calendarTitleHeight); BoxContent::resizeEvent(e); } diff --git a/Telegram/SourceFiles/boxes/calendar_box.h b/Telegram/SourceFiles/boxes/calendar_box.h index 1cb326024..841df6092 100644 --- a/Telegram/SourceFiles/boxes/calendar_box.h +++ b/Telegram/SourceFiles/boxes/calendar_box.h @@ -28,7 +28,7 @@ class IconButton; class CalendarBox : public BoxContent { public: - CalendarBox(QWidget*, QDate month, QDate highlighted, base::lambda callback); + CalendarBox(QWidget *, QDate month, QDate highlighted, base::lambda callback); void setMinDate(QDate date); void setMaxDate(QDate date); @@ -58,5 +58,4 @@ private: object_ptr _next; base::lambda _callback; - }; diff --git a/Telegram/SourceFiles/boxes/change_phone_box.cpp b/Telegram/SourceFiles/boxes/change_phone_box.cpp index 6a52fe357..d3dfb39a6 100644 --- a/Telegram/SourceFiles/boxes/change_phone_box.cpp +++ b/Telegram/SourceFiles/boxes/change_phone_box.cpp @@ -18,22 +18,23 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include "base/lambda_guard.h" #include "boxes/change_phone_box.h" +#include "app.h" // For formatPhone +#include "base/lambda_guard.h" +#include "boxes/confirm_box.h" +#include "boxes/confirm_phone_box.h" +#include "facades.h" #include "lang/lang_keys.h" #include "styles/style_boxes.h" -#include "ui/widgets/labels.h" -#include "ui/widgets/input_fields.h" #include "ui/effects/widget_fade_wrap.h" -#include "boxes/confirm_phone_box.h" #include "ui/toast/toast.h" -#include "boxes/confirm_box.h" -#include "facades.h" -#include "app.h" // For formatPhone +#include "ui/widgets/input_fields.h" +#include "ui/widgets/labels.h" namespace { -void createErrorLabel(QWidget *parent, object_ptr> &label, const QString &text, int x, int y) { +void createErrorLabel(QWidget *parent, object_ptr> &label, const QString &text, int x, + int y) { if (label) { auto errorFadeOut = std::move(label); errorFadeOut->setUpdateCallback([label = errorFadeOut.data()] { @@ -44,7 +45,8 @@ void createErrorLabel(QWidget *parent, object_ptrhideAnimated(); } if (!text.isEmpty()) { - label.create(parent, object_ptr(parent, text, Ui::FlatLabel::InitType::Simple, st::changePhoneError)); + label.create(parent, + object_ptr(parent, text, Ui::FlatLabel::InitType::Simple, st::changePhoneError)); label->hideFast(); label->moveToLeft(x, y); label->showAnimated(); @@ -55,8 +57,7 @@ void createErrorLabel(QWidget *parent, object_ptrsetFocusFast(); @@ -74,15 +75,14 @@ private: showError(QString()); } - object_ptr _phone = { nullptr }; - object_ptr> _error = { nullptr }; + object_ptr _phone = {nullptr}; + object_ptr> _error = {nullptr}; mtpRequestId _requestId = 0; - }; class ChangePhoneBox::EnterCode : public BoxContent { public: - EnterCode(QWidget*, const QString &phone, const QString &hash, int codeLength, int callTimeout); + EnterCode(QWidget *, const QString &phone, const QString &hash, int codeLength, int callTimeout); void setInnerFocus() override { _code->setFocusFast(); @@ -106,12 +106,11 @@ private: QString _hash; int _codeLength = 0; int _callTimeout = 0; - object_ptr _code = { nullptr }; - object_ptr> _error = { nullptr }; - object_ptr _callLabel = { nullptr }; + object_ptr _code = {nullptr}; + object_ptr> _error = {nullptr}; + object_ptr _callLabel = {nullptr}; mtpRequestId _requestId = 0; SentCodeCall _call; - }; void ChangePhoneBox::EnterPhone::prepare() { @@ -124,7 +123,8 @@ void ChangePhoneBox::EnterPhone::prepare() { _phone->moveToLeft(st::boxPadding.left(), st::boxLittleSkip); connect(_phone, &Ui::PhoneInput::submitted, this, [this] { submit(); }); - auto description = object_ptr(this, lang(lng_change_phone_new_description), Ui::FlatLabel::InitType::Simple, st::changePhoneLabel); + auto description = object_ptr(this, lang(lng_change_phone_new_description), + Ui::FlatLabel::InitType::Simple, st::changePhoneLabel); auto errorSkip = st::boxLittleSkip + st::changePhoneError.style.font->height; description->moveToLeft(st::boxPadding.left(), _phone->y() + _phone->height() + errorSkip + st::boxLittleSkip); @@ -141,11 +141,12 @@ void ChangePhoneBox::EnterPhone::submit() { hideError(); auto phoneNumber = _phone->getLastText().trimmed(); - _requestId = MTP::send(MTPaccount_SendChangePhoneCode(MTP_flags(0), MTP_string(phoneNumber), MTP_bool(false)), rpcDone(base::lambda_guarded(this, [this, phoneNumber](const MTPauth_SentCode &result) { - return sendPhoneDone(phoneNumber, result); - })), rpcFail(base::lambda_guarded(this, [this, phoneNumber](const RPCError &error) { - return sendPhoneFail(phoneNumber, error); - }))); + _requestId = MTP::send( + MTPaccount_SendChangePhoneCode(MTP_flags(0), MTP_string(phoneNumber), MTP_bool(false)), + rpcDone(base::lambda_guarded( + this, [this, phoneNumber](const MTPauth_SentCode &result) { return sendPhoneDone(phoneNumber, result); })), + rpcFail(base::lambda_guarded( + this, [this, phoneNumber](const RPCError &error) { return sendPhoneFail(phoneNumber, error); }))); } void ChangePhoneBox::EnterPhone::sendPhoneDone(const QString &phoneNumber, const MTPauth_SentCode &result) { @@ -199,19 +200,21 @@ void ChangePhoneBox::EnterPhone::showError(const QString &text) { } } -ChangePhoneBox::EnterCode::EnterCode(QWidget*, const QString &phone, const QString &hash, int codeLength, int callTimeout) -: _phone(phone) -, _hash(hash) -, _codeLength(codeLength) -, _callTimeout(callTimeout) -, _call(this, [this] { sendCall(); }, [this] { updateCall(); }) { -} +ChangePhoneBox::EnterCode::EnterCode(QWidget *, const QString &phone, const QString &hash, int codeLength, + int callTimeout) + : _phone(phone) + , _hash(hash) + , _codeLength(codeLength) + , _callTimeout(callTimeout) + , _call(this, [this] { sendCall(); }, [this] { updateCall(); }) {} void ChangePhoneBox::EnterCode::prepare() { setTitle(langFactory(lng_change_phone_title)); - auto descriptionText = lng_change_phone_code_description(lt_phone, textcmdStartSemibold() + App::formatPhone(_phone) + textcmdStopSemibold()); - auto description = object_ptr(this, descriptionText, Ui::FlatLabel::InitType::Rich, st::changePhoneLabel); + auto descriptionText = lng_change_phone_code_description( + lt_phone, textcmdStartSemibold() + App::formatPhone(_phone) + textcmdStopSemibold()); + auto description = + object_ptr(this, descriptionText, Ui::FlatLabel::InitType::Rich, st::changePhoneLabel); description->moveToLeft(st::boxPadding.left(), 0); auto phoneValue = QString(); @@ -226,7 +229,7 @@ void ChangePhoneBox::EnterCode::prepare() { setDimensions(st::boxWidth, countHeight()); if (_callTimeout > 0) { - _call.setStatus({ SentCodeCall::State::Waiting, _callTimeout }); + _call.setStatus({SentCodeCall::State::Waiting, _callTimeout}); updateCall(); } @@ -246,21 +249,21 @@ void ChangePhoneBox::EnterCode::submit() { hideError(); auto code = _code->getLastText().trimmed(); - _requestId = MTP::send(MTPaccount_ChangePhone(MTP_string(_phone), MTP_string(_hash), MTP_string(code)), rpcDone([weak = weak(this)](const MTPUser &result) { - App::feedUser(result); - if (weak) { - Ui::hideLayer(); - } - Ui::Toast::Show(lang(lng_change_phone_success)); - }), rpcFail(base::lambda_guarded(this, [this](const RPCError &error) { - return sendCodeFail(error); - }))); + _requestId = + MTP::send(MTPaccount_ChangePhone(MTP_string(_phone), MTP_string(_hash), MTP_string(code)), + rpcDone([weak = weak(this)](const MTPUser &result) { + App::feedUser(result); + if (weak) { + Ui::hideLayer(); + } + Ui::Toast::Show(lang(lng_change_phone_success)); + }), + rpcFail(base::lambda_guarded(this, [this](const RPCError &error) { return sendCodeFail(error); }))); } void ChangePhoneBox::EnterCode::sendCall() { - MTP::send(MTPauth_ResendCode(MTP_string(_phone), MTP_string(_hash)), rpcDone(base::lambda_guarded(this, [this] { - _call.callDone(); - }))); + MTP::send(MTPauth_ResendCode(MTP_string(_phone), MTP_string(_hash)), + rpcDone(base::lambda_guarded(this, [this] { _call.callDone(); }))); } void ChangePhoneBox::EnterCode::updateCall() { @@ -305,16 +308,12 @@ bool ChangePhoneBox::EnterCode::sendCodeFail(const RPCError &error) { void ChangePhoneBox::prepare() { setTitle(langFactory(lng_change_phone_title)); - addButton(langFactory(lng_change_phone_button), [] { - Ui::show(Box(lang(lng_change_phone_warning), [] { - Ui::show(Box()); - })); - }); - addButton(langFactory(lng_cancel), [this] { - closeBox(); - }); + addButton(langFactory(lng_change_phone_button), + [] { Ui::show(Box(lang(lng_change_phone_warning), [] { Ui::show(Box()); })); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); - auto label = object_ptr(this, lang(lng_change_phone_description), Ui::FlatLabel::InitType::Rich, st::changePhoneDescription); + auto label = object_ptr(this, lang(lng_change_phone_description), Ui::FlatLabel::InitType::Rich, + st::changePhoneDescription); label->moveToLeft((st::boxWideWidth - label->width()) / 2, st::changePhoneDescriptionTop); setDimensions(st::boxWideWidth, label->bottomNoMargins() + st::boxLittleSkip); diff --git a/Telegram/SourceFiles/boxes/change_phone_box.h b/Telegram/SourceFiles/boxes/change_phone_box.h index 0c64f7e7c..8d18b4fe4 100644 --- a/Telegram/SourceFiles/boxes/change_phone_box.h +++ b/Telegram/SourceFiles/boxes/change_phone_box.h @@ -24,8 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org class ChangePhoneBox : public BoxContent { public: - ChangePhoneBox(QWidget*) { - } + ChangePhoneBox(QWidget *) {} protected: void prepare() override; @@ -35,6 +34,4 @@ protected: private: class EnterPhone; class EnterCode; - }; - diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 791ca403a..eb2243bb0 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -20,85 +20,93 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/confirm_box.h" -#include "styles/style_boxes.h" +#include "apiwrap.h" +#include "application.h" +#include "auth_session.h" +#include "core/click_handler_types.h" #include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" -#include "apiwrap.h" -#include "application.h" -#include "ui/widgets/checkbox.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/labels.h" -#include "ui/toast/toast.h" -#include "core/click_handler_types.h" -#include "storage/localstorage.h" -#include "auth_session.h" #include "observer_peer.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" +#include "ui/toast/toast.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/labels.h" TextParseOptions _confirmBoxTextOptions = { - TextParseLinks | TextParseMultiline | TextParseRichText, // flags - 0, // maxw - 0, // maxh - Qt::LayoutDirectionAuto, // dir + TextParseLinks | TextParseMultiline | TextParseRichText, // flags + 0, // maxw + 0, // maxh + Qt::LayoutDirectionAuto, // dir }; -ConfirmBox::ConfirmBox(QWidget*, const QString &text, base::lambda_once confirmedCallback, base::lambda_once cancelledCallback) -: _confirmText(lang(lng_box_ok)) -, _cancelText(lang(lng_cancel)) -, _confirmStyle(st::defaultBoxButton) -, _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) -, _confirmedCallback(std::move(confirmedCallback)) -, _cancelledCallback(std::move(cancelledCallback)) { +ConfirmBox::ConfirmBox(QWidget *, const QString &text, base::lambda_once confirmedCallback, + base::lambda_once cancelledCallback) + : _confirmText(lang(lng_box_ok)) + , _cancelText(lang(lng_cancel)) + , _confirmStyle(st::defaultBoxButton) + , _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) + , _confirmedCallback(std::move(confirmedCallback)) + , _cancelledCallback(std::move(cancelledCallback)) { init(text); } -ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText, base::lambda_once confirmedCallback, base::lambda_once cancelledCallback) -: _confirmText(confirmText) -, _cancelText(lang(lng_cancel)) -, _confirmStyle(st::defaultBoxButton) -, _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) -, _confirmedCallback(std::move(confirmedCallback)) -, _cancelledCallback(std::move(cancelledCallback)) { +ConfirmBox::ConfirmBox(QWidget *, const QString &text, const QString &confirmText, + base::lambda_once confirmedCallback, base::lambda_once cancelledCallback) + : _confirmText(confirmText) + , _cancelText(lang(lng_cancel)) + , _confirmStyle(st::defaultBoxButton) + , _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) + , _confirmedCallback(std::move(confirmedCallback)) + , _cancelledCallback(std::move(cancelledCallback)) { init(text); } -ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, base::lambda_once confirmedCallback, base::lambda_once cancelledCallback) -: _confirmText(confirmText) -, _cancelText(lang(lng_cancel)) -, _confirmStyle(confirmStyle) -, _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) -, _confirmedCallback(std::move(confirmedCallback)) -, _cancelledCallback(std::move(cancelledCallback)) { +ConfirmBox::ConfirmBox(QWidget *, const QString &text, const QString &confirmText, + const style::RoundButton &confirmStyle, base::lambda_once confirmedCallback, + base::lambda_once cancelledCallback) + : _confirmText(confirmText) + , _cancelText(lang(lng_cancel)) + , _confirmStyle(confirmStyle) + , _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) + , _confirmedCallback(std::move(confirmedCallback)) + , _cancelledCallback(std::move(cancelledCallback)) { init(text); } -ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const QString &cancelText, base::lambda_once confirmedCallback, base::lambda_once cancelledCallback) -: _confirmText(confirmText) -, _cancelText(cancelText) -, _confirmStyle(st::defaultBoxButton) -, _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) -, _confirmedCallback(std::move(confirmedCallback)) -, _cancelledCallback(std::move(cancelledCallback)) { +ConfirmBox::ConfirmBox(QWidget *, const QString &text, const QString &confirmText, const QString &cancelText, + base::lambda_once confirmedCallback, base::lambda_once cancelledCallback) + : _confirmText(confirmText) + , _cancelText(cancelText) + , _confirmStyle(st::defaultBoxButton) + , _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) + , _confirmedCallback(std::move(confirmedCallback)) + , _cancelledCallback(std::move(cancelledCallback)) { init(text); } -ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, const QString &cancelText, base::lambda_once confirmedCallback, base::lambda_once cancelledCallback) -: _confirmText(confirmText) -, _cancelText(cancelText) -, _confirmStyle(st::defaultBoxButton) -, _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) -, _confirmedCallback(std::move(confirmedCallback)) -, _cancelledCallback(std::move(cancelledCallback)) { +ConfirmBox::ConfirmBox(QWidget *, const QString &text, const QString &confirmText, + const style::RoundButton &confirmStyle, const QString &cancelText, + base::lambda_once confirmedCallback, base::lambda_once cancelledCallback) + : _confirmText(confirmText) + , _cancelText(cancelText) + , _confirmStyle(st::defaultBoxButton) + , _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) + , _confirmedCallback(std::move(confirmedCallback)) + , _cancelledCallback(std::move(cancelledCallback)) { init(text); } -ConfirmBox::ConfirmBox(const InformBoxTag &, const QString &text, const QString &doneText, base::lambda closedCallback) -: _confirmText(doneText) -, _confirmStyle(st::defaultBoxButton) -, _informative(true) -, _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) -, _confirmedCallback(generateInformCallback(closedCallback)) -, _cancelledCallback(generateInformCallback(closedCallback)) { +ConfirmBox::ConfirmBox(const InformBoxTag &, const QString &text, const QString &doneText, + base::lambda closedCallback) + : _confirmText(doneText) + , _confirmStyle(st::defaultBoxButton) + , _informative(true) + , _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) + , _confirmedCallback(generateInformCallback(closedCallback)) + , _cancelledCallback(generateInformCallback(closedCallback)) { init(text); } @@ -118,7 +126,11 @@ void ConfirmBox::init(const QString &text) { void ConfirmBox::prepare() { addButton([this] { return _confirmText; }, [this] { confirmed(); }, _confirmStyle); if (!_informative) { - addButton([this] { return _cancelText; }, [this] { _cancelled = true; closeBox(); }); + addButton([this] { return _cancelText; }, + [this] { + _cancelled = true; + closeBox(); + }); } subscribe(boxClosing, [this] { if (!_confirmed && (!_strictCancel || _cancelled) && _cancelledCallback) { @@ -210,16 +222,17 @@ void ConfirmBox::paintEvent(QPaintEvent *e) { _text.drawLeftElided(p, st::boxPadding.left(), st::boxPadding.top(), _textWidth, width(), 16, style::al_left); } -InformBox::InformBox(QWidget*, const QString &text, base::lambda closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, lang(lng_box_ok), std::move(closedCallback)) { -} +InformBox::InformBox(QWidget *, const QString &text, base::lambda closedCallback) + : ConfirmBox(ConfirmBox::InformBoxTag(), text, lang(lng_box_ok), std::move(closedCallback)) {} -InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, base::lambda closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std::move(closedCallback)) { -} +InformBox::InformBox(QWidget *, const QString &text, const QString &doneText, base::lambda closedCallback) + : ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std::move(closedCallback)) {} -MaxInviteBox::MaxInviteBox(QWidget*, not_null channel) : BoxContent() -, _channel(channel) -, _text(st::boxLabelStyle, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) { -} +MaxInviteBox::MaxInviteBox(QWidget *, not_null channel) + : BoxContent() + , _channel(channel) + , _text(st::boxLabelStyle, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, + st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) {} void MaxInviteBox::prepare() { setMouseTracking(true); @@ -228,13 +241,15 @@ void MaxInviteBox::prepare() { _textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right(); _textHeight = std::min(_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()); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::InviteLinkChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer == _channel) { - rtlupdate(_invitationLink); - } - })); + subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::InviteLinkChanged, + [this](const Notify::PeerUpdate &update) { + if (update.peer == _channel) { + rtlupdate(_invitationLink); + } + })); } void MaxInviteBox::mouseMoveEvent(QMouseEvent *e) { @@ -287,14 +302,14 @@ void MaxInviteBox::paintEvent(QPaintEvent *e) { void MaxInviteBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _invitationLink = myrtlrect(st::boxPadding.left(), st::boxPadding.top() + _textHeight + st::boxTextFont->height, width() - st::boxPadding.left() - st::boxPadding.right(), 2 * st::boxTextFont->height); + _invitationLink = myrtlrect(st::boxPadding.left(), st::boxPadding.top() + _textHeight + st::boxTextFont->height, + width() - st::boxPadding.left() - st::boxPadding.right(), 2 * st::boxTextFont->height); } -ConvertToSupergroupBox::ConvertToSupergroupBox(QWidget*, ChatData *chat) -: _chat(chat) -, _text(100) -, _note(100) { -} +ConvertToSupergroupBox::ConvertToSupergroupBox(QWidget *, ChatData *chat) + : _chat(chat) + , _text(100) + , _note(100) {} void ConvertToSupergroupBox::prepare() { QStringList text; @@ -309,14 +324,18 @@ void ConvertToSupergroupBox::prepare() { addButton(langFactory(lng_cancel), [this] { closeBox(); }); _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); + _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)); } void ConvertToSupergroupBox::convertToSupergroup() { - MTP::send(MTPmessages_MigrateChat(_chat->inputChat), rpcDone(&ConvertToSupergroupBox::convertDone), rpcFail(&ConvertToSupergroupBox::convertFail)); + MTP::send(MTPmessages_MigrateChat(_chat->inputChat), rpcDone(&ConvertToSupergroupBox::convertDone), + rpcFail(&ConvertToSupergroupBox::convertFail)); } void ConvertToSupergroupBox::convertDone(const MTPUpdates &updates) { @@ -336,7 +355,9 @@ void ConvertToSupergroupBox::convertDone(const MTPUpdates &updates) { switch (updates.type()) { case mtpc_updates: handleChats(updates.c_updates().vchats); break; case mtpc_updatesCombined: handleChats(updates.c_updatesCombined().vchats); break; - default: LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); break; + default: + LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); + break; } } @@ -365,18 +386,18 @@ void ConvertToSupergroupBox::paintEvent(QPaintEvent *e) { _note.drawLeft(p, st::boxPadding.left(), _textHeight + st::boxPadding.bottom(), _textWidth, width()); } -PinMessageBox::PinMessageBox(QWidget*, ChannelData *channel, MsgId msgId) -: _channel(channel) -, _msgId(msgId) -, _text(this, lang(lng_pinned_pin_sure), Ui::FlatLabel::InitType::Simple, st::boxLabel) -, _notify(this, lang(lng_pinned_notify), true, st::defaultBoxCheckbox) { -} +PinMessageBox::PinMessageBox(QWidget *, ChannelData *channel, MsgId msgId) + : _channel(channel) + , _msgId(msgId) + , _text(this, lang(lng_pinned_pin_sure), Ui::FlatLabel::InitType::Simple, st::boxLabel) + , _notify(this, lang(lng_pinned_notify), true, st::defaultBoxCheckbox) {} void PinMessageBox::prepare() { addButton(langFactory(lng_pinned_pin), [this] { pinMessage(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); - setDimensions(st::boxWidth, st::boxPadding.top() + _text->height() + st::boxMediumSkip + _notify->heightNoMargins() + st::boxPadding.bottom()); + setDimensions(st::boxWidth, st::boxPadding.top() + _text->height() + st::boxMediumSkip + + _notify->heightNoMargins() + st::boxPadding.bottom()); } void PinMessageBox::resizeEvent(QResizeEvent *e) { @@ -400,7 +421,8 @@ void PinMessageBox::pinMessage() { if (!_notify->checked()) { flags |= MTPchannels_UpdatePinnedMessage::Flag::f_silent; } - _requestId = MTP::send(MTPchannels_UpdatePinnedMessage(MTP_flags(flags), _channel->inputChannel, MTP_int(_msgId)), rpcDone(&PinMessageBox::pinDone), rpcFail(&PinMessageBox::pinFail)); + _requestId = MTP::send(MTPchannels_UpdatePinnedMessage(MTP_flags(flags), _channel->inputChannel, MTP_int(_msgId)), + rpcDone(&PinMessageBox::pinDone), rpcFail(&PinMessageBox::pinFail)); } void PinMessageBox::pinDone(const MTPUpdates &updates) { @@ -416,7 +438,8 @@ bool PinMessageBox::pinFail(const RPCError &error) { return true; } -DeleteMessagesBox::DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestModerateActions) : _singleItem(true) { +DeleteMessagesBox::DeleteMessagesBox(QWidget *, HistoryItem *item, bool suggestModerateActions) + : _singleItem(true) { _ids.push_back(item->fullId()); if (suggestModerateActions) { _moderateBan = item->suggestBanReport(); @@ -428,13 +451,11 @@ DeleteMessagesBox::DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestMo } } -DeleteMessagesBox::DeleteMessagesBox(QWidget*, const SelectedItemSet &selected) { +DeleteMessagesBox::DeleteMessagesBox(QWidget *, const SelectedItemSet &selected) { auto count = selected.size(); Assert(count > 0); _ids.reserve(count); - for_const (auto item, selected) { - _ids.push_back(item->fullId()); - } + for_const (auto item, selected) { _ids.push_back(item->fullId()); } } void DeleteMessagesBox::prepare() { @@ -453,8 +474,8 @@ void DeleteMessagesBox::prepare() { 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 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)) { @@ -542,10 +563,12 @@ void DeleteMessagesBox::deleteAndClear() { if (_moderateFrom) { if (_banUser && _banUser->checked()) { - Auth().api().kickParticipant(_moderateInChannel, _moderateFrom, MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); + Auth().api().kickParticipant(_moderateInChannel, _moderateFrom, + MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); } if (_reportSpam->checked()) { - MTP::send(MTPchannels_ReportSpam(_moderateInChannel->inputChannel, _moderateFrom->inputUser, MTP_vector(1, MTP_int(_ids[0].msg)))); + MTP::send(MTPchannels_ReportSpam(_moderateInChannel->inputChannel, _moderateFrom->inputUser, + MTP_vector(1, MTP_int(_ids[0].msg)))); } if (_deleteAll && _deleteAll->checked()) { App::main()->deleteAllFromUser(_moderateInChannel, _moderateFrom); @@ -556,7 +579,7 @@ void DeleteMessagesBox::deleteAndClear() { App::main()->clearSelectedItems(); } - QMap> idsByPeer; + QMap> idsByPeer; for_const (auto fullId, _ids) { if (auto item = App::histItemById(fullId)) { auto history = item->history(); @@ -579,10 +602,11 @@ void DeleteMessagesBox::deleteAndClear() { Ui::hideLayer(); } -ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, bool isChannel, const MTPChatPhoto &photo, int count, const QVector &participants) -: _title(this, st::confirmInviteTitle) -, _status(this, st::confirmInviteStatus) -, _participants(participants) { +ConfirmInviteBox::ConfirmInviteBox(QWidget *, const QString &title, bool isChannel, const MTPChatPhoto &photo, + int count, const QVector &participants) + : _title(this, st::confirmInviteTitle) + , _status(this, st::confirmInviteStatus) + , _participants(participants) { _title->setText(title); QString status; if (_participants.isEmpty() || _participants.size() >= count) { @@ -655,15 +679,18 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) { Painter p(this); if (_photo) { - p.drawPixmap((width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, _photo->pixCircled(st::confirmInvitePhotoSize, st::confirmInvitePhotoSize)); + p.drawPixmap((width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, + _photo->pixCircled(st::confirmInvitePhotoSize, st::confirmInvitePhotoSize)); } else { - _photoEmpty.paint(p, (width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, width(), st::confirmInvitePhotoSize); + _photoEmpty.paint(p, (width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, width(), + st::confirmInvitePhotoSize); } int sumWidth = _participants.size() * _userWidth; int left = (width() - sumWidth) / 2; for_const (auto user, _participants) { - user->paintUserpicLeft(p, left + (_userWidth - st::confirmInviteUserPhotoSize) / 2, st::confirmInviteUserPhotoTop, width(), st::confirmInviteUserPhotoSize); + user->paintUserpicLeft(p, left + (_userWidth - st::confirmInviteUserPhotoSize) / 2, + st::confirmInviteUserPhotoTop, width(), st::confirmInviteUserPhotoSize); left += _userWidth; } } diff --git a/Telegram/SourceFiles/boxes/confirm_box.h b/Telegram/SourceFiles/boxes/confirm_box.h index 09814fe7c..bf9fd888f 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.h +++ b/Telegram/SourceFiles/boxes/confirm_box.h @@ -31,11 +31,21 @@ class FlatLabel; class InformBox; class ConfirmBox : public BoxContent, public ClickHandlerHost { public: - ConfirmBox(QWidget*, const QString &text, base::lambda_once confirmedCallback = base::lambda_once(), base::lambda_once cancelledCallback = base::lambda_once()); - ConfirmBox(QWidget*, const QString &text, const QString &confirmText, base::lambda_once confirmedCallback = base::lambda_once(), base::lambda_once cancelledCallback = base::lambda_once()); - ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, base::lambda_once confirmedCallback = base::lambda_once(), base::lambda_once cancelledCallback = base::lambda_once()); - ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const QString &cancelText, base::lambda_once confirmedCallback = base::lambda_once(), base::lambda_once cancelledCallback = base::lambda_once()); - ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, const QString &cancelText, base::lambda_once confirmedCallback = base::lambda_once(), base::lambda_once cancelledCallback = base::lambda_once()); + ConfirmBox(QWidget *, const QString &text, + base::lambda_once confirmedCallback = base::lambda_once(), + base::lambda_once cancelledCallback = base::lambda_once()); + ConfirmBox(QWidget *, const QString &text, const QString &confirmText, + base::lambda_once confirmedCallback = base::lambda_once(), + base::lambda_once cancelledCallback = base::lambda_once()); + ConfirmBox(QWidget *, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, + base::lambda_once confirmedCallback = base::lambda_once(), + base::lambda_once cancelledCallback = base::lambda_once()); + ConfirmBox(QWidget *, const QString &text, const QString &confirmText, const QString &cancelText, + base::lambda_once confirmedCallback = base::lambda_once(), + base::lambda_once cancelledCallback = base::lambda_once()); + ConfirmBox(QWidget *, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, + const QString &cancelText, base::lambda_once confirmedCallback = base::lambda_once(), + base::lambda_once cancelledCallback = base::lambda_once()); void updateLink(); @@ -59,8 +69,7 @@ protected: void leaveEventHook(QEvent *e) override; private: - struct InformBoxTag { - }; + struct InformBoxTag {}; ConfirmBox(const InformBoxTag &, const QString &text, const QString &doneText, base::lambda closedCallback); base::lambda_once generateInformCallback(base::lambda closedCallback); friend class InformBox; @@ -87,19 +96,18 @@ private: bool _strictCancel = false; base::lambda_once _confirmedCallback; base::lambda_once _cancelledCallback; - }; class InformBox : public ConfirmBox { public: - InformBox(QWidget*, const QString &text, base::lambda closedCallback = base::lambda()); - InformBox(QWidget*, const QString &text, const QString &doneText, base::lambda closedCallback = base::lambda()); - + InformBox(QWidget *, const QString &text, base::lambda closedCallback = base::lambda()); + InformBox(QWidget *, const QString &text, const QString &doneText, + base::lambda closedCallback = base::lambda()); }; class MaxInviteBox : public BoxContent { public: - MaxInviteBox(QWidget*, not_null channel); + MaxInviteBox(QWidget *, not_null channel); protected: void prepare() override; @@ -113,7 +121,7 @@ protected: private: void updateSelected(const QPoint &cursorGlobalPosition); - not_null _channel; + not_null _channel; Text _text; qint32 _textWidth, _textHeight; @@ -122,12 +130,11 @@ private: bool _linkOver = false; QPoint _lastMousePos; - }; class ConvertToSupergroupBox : public BoxContent, public RPCSender { public: - ConvertToSupergroupBox(QWidget*, ChatData *chat); + ConvertToSupergroupBox(QWidget *, ChatData *chat); protected: void prepare() override; @@ -143,12 +150,11 @@ private: ChatData *_chat; Text _text, _note; qint32 _textWidth, _textHeight; - }; class PinMessageBox : public BoxContent, public RPCSender { public: - PinMessageBox(QWidget*, ChannelData *channel, MsgId msgId); + PinMessageBox(QWidget *, ChannelData *channel, MsgId msgId); protected: void prepare() override; @@ -168,13 +174,12 @@ private: object_ptr _notify; mtpRequestId _requestId = 0; - }; class DeleteMessagesBox : public BoxContent, public RPCSender { public: - DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestModerateActions); - DeleteMessagesBox(QWidget*, const SelectedItemSet &selected); + DeleteMessagesBox(QWidget *, HistoryItem *item, bool suggestModerateActions); + DeleteMessagesBox(QWidget *, const SelectedItemSet &selected); protected: void prepare() override; @@ -192,17 +197,17 @@ private: bool _moderateBan = false; bool _moderateDeleteAll = false; - object_ptr _text = { nullptr }; - object_ptr _forEveryone = { nullptr }; - object_ptr _banUser = { nullptr }; - object_ptr _reportSpam = { nullptr }; - object_ptr _deleteAll = { nullptr }; - + object_ptr _text = {nullptr}; + object_ptr _forEveryone = {nullptr}; + object_ptr _banUser = {nullptr}; + object_ptr _reportSpam = {nullptr}; + object_ptr _deleteAll = {nullptr}; }; class ConfirmInviteBox : public BoxContent, public RPCSender { public: - ConfirmInviteBox(QWidget*, const QString &title, bool isChannel, const MTPChatPhoto &photo, int count, const QVector &participants); + ConfirmInviteBox(QWidget *, const QString &title, bool isChannel, const MTPChatPhoto &photo, int count, + const QVector &participants); protected: void prepare() override; @@ -215,8 +220,7 @@ private: object_ptr _status; ImagePtr _photo; EmptyUserpic _photoEmpty; - QVector _participants; + QVector _participants; int _userWidth = 0; - }; diff --git a/Telegram/SourceFiles/boxes/confirm_phone_box.cpp b/Telegram/SourceFiles/boxes/confirm_phone_box.cpp index 1b2724198..d72ddb527 100644 --- a/Telegram/SourceFiles/boxes/confirm_phone_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_phone_box.cpp @@ -20,17 +20,17 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/confirm_phone_box.h" -#include "styles/style_boxes.h" #include "boxes/confirm_box.h" +#include "lang/lang_keys.h" +#include "mainwidget.h" +#include "styles/style_boxes.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" #include "ui/widgets/labels.h" -#include "mainwidget.h" -#include "lang/lang_keys.h" namespace { -object_ptr CurrentConfirmPhoneBox = { nullptr }; +object_ptr CurrentConfirmPhoneBox = {nullptr}; } // namespace @@ -90,9 +90,9 @@ void SentCodeField::fix() { } SentCodeCall::SentCodeCall(QObject *parent, base::lambda_once callCallback, base::lambda updateCallback) -: _timer(parent) -, _call(std::move(callCallback)) -, _update(std::move(updateCallback)) { + : _timer(parent) + , _call(std::move(callCallback)) + , _update(std::move(updateCallback)) { _timer->connect(_timer, &QTimer::timeout, [this] { if (_status.state == State::Waiting) { if (--_status.timeout <= 0) { @@ -120,9 +120,13 @@ QString SentCodeCall::getText() const { switch (_status.state) { case State::Waiting: { if (_status.timeout >= 3600) { - return lng_code_call(lt_minutes, qsl("%1:%2").arg(_status.timeout / 3600).arg((_status.timeout / 60) % 60, 2, 10, QChar('0')), lt_seconds, qsl("%1").arg(_status.timeout % 60, 2, 10, QChar('0'))); + return lng_code_call( + lt_minutes, + qsl("%1:%2").arg(_status.timeout / 3600).arg((_status.timeout / 60) % 60, 2, 10, QChar('0')), + lt_seconds, qsl("%1").arg(_status.timeout % 60, 2, 10, QChar('0'))); } - return lng_code_call(lt_minutes, QString::number(_status.timeout / 60), lt_seconds, qsl("%1").arg(_status.timeout % 60, 2, 10, QChar('0'))); + return lng_code_call(lt_minutes, QString::number(_status.timeout / 60), lt_seconds, + qsl("%1").arg(_status.timeout % 60, 2, 10, QChar('0'))); } break; case State::Calling: return lang(lng_code_calling); case State::Called: return lang(lng_code_called); @@ -140,11 +144,10 @@ void ConfirmPhoneBox::start(const QString &phone, const QString &hash) { CurrentConfirmPhoneBox->checkPhoneAndHash(); } -ConfirmPhoneBox::ConfirmPhoneBox(QWidget*, const QString &phone, const QString &hash) -: _phone(phone) -, _hash(hash) -, _call(this, [this] { sendCall(); }, [this] { update(); }) { -} +ConfirmPhoneBox::ConfirmPhoneBox(QWidget *, const QString &phone, const QString &hash) + : _phone(phone) + , _hash(hash) + , _call(this, [this] { sendCall(); }, [this] { update(); }) {} void ConfirmPhoneBox::sendCall() { MTP::send(MTPauth_ResendCode(MTP_string(_phone), MTP_string(_phoneHash)), rpcDone(&ConfirmPhoneBox::callDone)); @@ -154,7 +157,8 @@ void ConfirmPhoneBox::checkPhoneAndHash() { if (_sendCodeRequestId) { return; } - _sendCodeRequestId = MTP::send(MTPaccount_SendConfirmPhoneCode(MTP_flags(0), MTP_string(_hash), MTPBool()), rpcDone(&ConfirmPhoneBox::sendCodeDone), rpcFail(&ConfirmPhoneBox::sendCodeFail)); + _sendCodeRequestId = MTP::send(MTPaccount_SendConfirmPhoneCode(MTP_flags(0), MTP_string(_hash), MTPBool()), + rpcDone(&ConfirmPhoneBox::sendCodeDone), rpcFail(&ConfirmPhoneBox::sendCodeFail)); } void ConfirmPhoneBox::sendCodeDone(const MTPauth_SentCode &result) { @@ -170,7 +174,7 @@ void ConfirmPhoneBox::sendCodeDone(const MTPauth_SentCode &result) { } _phoneHash = qs(resultInner.vphone_code_hash); if (resultInner.has_next_type() && resultInner.vnext_type.type() == mtpc_auth_codeTypeCall) { - _call.setStatus({ SentCodeCall::State::Waiting, resultInner.has_timeout() ? resultInner.vtimeout.v : 60 }); + _call.setStatus({SentCodeCall::State::Waiting, resultInner.has_timeout() ? resultInner.vtimeout.v : 60}); } launch(); } @@ -219,7 +223,8 @@ void ConfirmPhoneBox::prepare() { addButton(langFactory(lng_confirm_phone_send), [this] { onSendCode(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); - setDimensions(st::boxWidth, st::usernamePadding.top() + _code->height() + st::usernameSkip + _about->height() + st::usernameSkip); + setDimensions(st::boxWidth, + st::usernamePadding.top() + _code->height() + st::usernameSkip + _about->height() + st::usernameSkip); connect(_code, SIGNAL(submitted(bool)), this, SLOT(onSendCode())); @@ -245,7 +250,8 @@ void ConfirmPhoneBox::onSendCode() { showError(QString()); - _sendCodeRequestId = MTP::send(MTPaccount_ConfirmPhone(MTP_string(_phoneHash), MTP_string(_code->getLastText())), rpcDone(&ConfirmPhoneBox::confirmDone), rpcFail(&ConfirmPhoneBox::confirmFail)); + _sendCodeRequestId = MTP::send(MTPaccount_ConfirmPhone(MTP_string(_phoneHash), MTP_string(_code->getLastText())), + rpcDone(&ConfirmPhoneBox::confirmDone), rpcFail(&ConfirmPhoneBox::confirmFail)); } void ConfirmPhoneBox::confirmDone(const MTPBool &result) { diff --git a/Telegram/SourceFiles/boxes/confirm_phone_box.h b/Telegram/SourceFiles/boxes/confirm_phone_box.h index 88554f4de..b72a34c21 100644 --- a/Telegram/SourceFiles/boxes/confirm_phone_box.h +++ b/Telegram/SourceFiles/boxes/confirm_phone_box.h @@ -30,7 +30,10 @@ class FlatLabel; class SentCodeField : public Ui::InputField { public: - SentCodeField(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString()) : Ui::InputField(parent, st, std::move(placeholderFactory), val) { + SentCodeField(QWidget *parent, const style::InputField &st, + base::lambda placeholderFactory = base::lambda(), + const QString &val = QString()) + : Ui::InputField(parent, st, std::move(placeholderFactory), val) { connect(this, &Ui::InputField::changed, [this] { fix(); }); } @@ -51,7 +54,6 @@ private: int _autoSubmitLength = 0; base::lambda _submitCallback; base::lambda _changedCallback; - }; class SentCodeCall { @@ -65,10 +67,10 @@ public: Disabled, }; struct Status { - Status() { - } - Status(State state, int timeout) : state(state), timeout(timeout) { - } + Status() {} + Status(State state, int timeout) + : state(state) + , timeout(timeout) {} State state = State::Disabled; int timeout = 0; @@ -91,7 +93,6 @@ private: object_ptr _timer; base::lambda_once _call; base::lambda _update; - }; class ConfirmPhoneBox : public BoxContent, public RPCSender { @@ -113,7 +114,7 @@ protected: void resizeEvent(QResizeEvent *e) override; private: - ConfirmPhoneBox(QWidget*, const QString &phone, const QString &hash); + ConfirmPhoneBox(QWidget *, const QString &phone, const QString &hash); friend class object_ptr; void sendCall(); @@ -146,10 +147,9 @@ private: mtpRequestId _checkCodeRequestId = 0; - object_ptr _about = { nullptr }; - object_ptr _code = { nullptr }; + object_ptr _about = {nullptr}; + object_ptr _code = {nullptr}; QString _error; SentCodeCall _call; - }; diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index 56aa55b6f..7a7cd3bfb 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -21,52 +21,58 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "boxes/connection_box.h" #include "boxes/confirm_box.h" +#include "history/history_location_manager.h" #include "lang/lang_keys.h" -#include "storage/localstorage.h" #include "mainwidget.h" #include "mainwindow.h" -#include "ui/widgets/checkbox.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/input_fields.h" -#include "history/history_location_manager.h" +#include "storage/localstorage.h" #include "styles/style_boxes.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/input_fields.h" void ConnectionBox::ShowApplyProxyConfirmation(const QMap &fields) { auto server = fields.value(qsl("server")); auto port = fields.value(qsl("port")).toInt(); if (!server.isEmpty() && port != 0) { auto weakBox = std::make_shared>(nullptr); - auto box = Ui::show(Box(lng_sure_enable_socks(lt_server, server, lt_port, QString::number(port)), lang(lng_sure_enable), [fields, weakBox] { - auto p = ProxyData(); - p.host = fields.value(qsl("server")); - p.user = fields.value(qsl("user")); - p.password = fields.value(qsl("pass")); - p.port = fields.value(qsl("port")).toInt(); - Global::SetConnectionType(dbictTcpProxy); - Global::SetLastProxyType(dbictTcpProxy); - Global::SetConnectionProxy(p); - Local::writeSettings(); - Global::RefConnectionTypeChanged().notify(); - MTP::restart(); - reinitLocationManager(); - reinitWebLoadManager(); - if (*weakBox) (*weakBox)->closeBox(); - }), KeepOtherLayers); + auto box = Ui::show(Box(lng_sure_enable_socks(lt_server, server, lt_port, QString::number(port)), + lang(lng_sure_enable), + [fields, weakBox] { + auto p = ProxyData(); + p.host = fields.value(qsl("server")); + p.user = fields.value(qsl("user")); + p.password = fields.value(qsl("pass")); + p.port = fields.value(qsl("port")).toInt(); + Global::SetConnectionType(dbictTcpProxy); + Global::SetLastProxyType(dbictTcpProxy); + Global::SetConnectionProxy(p); + Local::writeSettings(); + Global::RefConnectionTypeChanged().notify(); + MTP::restart(); + reinitLocationManager(); + reinitWebLoadManager(); + if (*weakBox) (*weakBox)->closeBox(); + }), + KeepOtherLayers); *weakBox = box; } } ConnectionBox::ConnectionBox(QWidget *parent) -: _hostInput(this, st::connectionHostInputField, langFactory(lng_connection_host_ph), Global::ConnectionProxy().host) -, _portInput(this, st::connectionPortInputField, langFactory(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port)) -, _userInput(this, st::connectionUserInputField, langFactory(lng_connection_user_ph), Global::ConnectionProxy().user) -, _passwordInput(this, st::connectionPasswordInputField, langFactory(lng_connection_password_ph), Global::ConnectionProxy().password) -, _typeGroup(std::make_shared>(Global::ConnectionType())) -, _autoRadio(this, _typeGroup, dbictAuto, lang(lng_connection_auto_rb), st::defaultBoxCheckbox) -, _httpProxyRadio(this, _typeGroup, dbictHttpProxy, lang(lng_connection_http_proxy_rb), st::defaultBoxCheckbox) -, _tcpProxyRadio(this, _typeGroup, dbictTcpProxy, lang(lng_connection_tcp_proxy_rb), st::defaultBoxCheckbox) -, _tryIPv6(this, lang(lng_connection_try_ipv6), Global::TryIPv6(), st::defaultBoxCheckbox) { -} + : _hostInput(this, st::connectionHostInputField, langFactory(lng_connection_host_ph), + Global::ConnectionProxy().host) + , _portInput(this, st::connectionPortInputField, langFactory(lng_connection_port_ph), + QString::number(Global::ConnectionProxy().port)) + , _userInput(this, st::connectionUserInputField, langFactory(lng_connection_user_ph), + Global::ConnectionProxy().user) + , _passwordInput(this, st::connectionPasswordInputField, langFactory(lng_connection_password_ph), + Global::ConnectionProxy().password) + , _typeGroup(std::make_shared>(Global::ConnectionType())) + , _autoRadio(this, _typeGroup, dbictAuto, lang(lng_connection_auto_rb), st::defaultBoxCheckbox) + , _httpProxyRadio(this, _typeGroup, dbictHttpProxy, lang(lng_connection_http_proxy_rb), st::defaultBoxCheckbox) + , _tcpProxyRadio(this, _typeGroup, dbictTcpProxy, lang(lng_connection_tcp_proxy_rb), st::defaultBoxCheckbox) + , _tryIPv6(this, lang(lng_connection_try_ipv6), Global::TryIPv6(), st::defaultBoxCheckbox) {} void ConnectionBox::prepare() { setTitle(langFactory(lng_connection_header)); @@ -93,7 +99,10 @@ bool ConnectionBox::badProxyValue() const { } void ConnectionBox::updateControlsVisibility() { - auto newHeight = st::boxOptionListPadding.top() + _autoRadio->heightNoMargins() + st::boxOptionListSkip + _httpProxyRadio->heightNoMargins() + st::boxOptionListSkip + _tcpProxyRadio->heightNoMargins() + st::boxOptionListSkip + st::connectionIPv6Skip + _tryIPv6->heightNoMargins() + st::defaultCheckbox.margin.bottom() + st::boxOptionListPadding.bottom() + st::boxPadding.bottom(); + auto newHeight = st::boxOptionListPadding.top() + _autoRadio->heightNoMargins() + st::boxOptionListSkip + + _httpProxyRadio->heightNoMargins() + st::boxOptionListSkip + _tcpProxyRadio->heightNoMargins() + + st::boxOptionListSkip + st::connectionIPv6Skip + _tryIPv6->heightNoMargins() + + st::defaultCheckbox.margin.bottom() + st::boxOptionListPadding.bottom() + st::boxPadding.bottom(); if (_typeGroup->value() == dbictAuto && badProxyValue()) { _hostInput->hide(); _portInput->hide(); @@ -127,31 +136,42 @@ void ConnectionBox::resizeEvent(QResizeEvent *e) { void ConnectionBox::updateControlsPosition() { auto type = _typeGroup->value(); - _autoRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _autoRadio->getMargins().top() + st::boxOptionListPadding.top()); - _httpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _autoRadio->bottomNoMargins() + st::boxOptionListSkip); + _autoRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + _autoRadio->getMargins().top() + st::boxOptionListPadding.top()); + _httpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + _autoRadio->bottomNoMargins() + st::boxOptionListSkip); auto inputy = 0; auto fieldsVisible = (type != dbictAuto) || (!badProxyValue() && Global::LastProxyType() != dbictAuto); - auto fieldsBelowHttp = fieldsVisible && (type == dbictHttpProxy || (type == dbictAuto && Global::LastProxyType() == dbictHttpProxy)); - auto fieldsBelowTcp = fieldsVisible && (type == dbictTcpProxy || (type == dbictAuto && Global::LastProxyType() == dbictTcpProxy)); + auto fieldsBelowHttp = + fieldsVisible && (type == dbictHttpProxy || (type == dbictAuto && Global::LastProxyType() == dbictHttpProxy)); + auto fieldsBelowTcp = + fieldsVisible && (type == dbictTcpProxy || (type == dbictAuto && Global::LastProxyType() == dbictTcpProxy)); if (fieldsBelowHttp) { inputy = _httpProxyRadio->bottomNoMargins() + st::boxOptionInputSkip; - _tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), inputy + st::boxOptionInputSkip + 2 * _hostInput->height() + st::boxOptionListSkip); + _tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + inputy + st::boxOptionInputSkip + 2 * _hostInput->height() + st::boxOptionListSkip); } else { - _tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _httpProxyRadio->bottomNoMargins() + st::boxOptionListSkip); + _tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + _httpProxyRadio->bottomNoMargins() + st::boxOptionListSkip); if (fieldsBelowTcp) { inputy = _tcpProxyRadio->bottomNoMargins() + st::boxOptionInputSkip; } } if (inputy) { - _hostInput->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left() + st::defaultCheck.diameter + st::defaultBoxCheckbox.textPosition.x() - st::defaultInputField.textMargins.left(), inputy); + _hostInput->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left() + st::defaultCheck.diameter + + st::defaultBoxCheckbox.textPosition.x() - st::defaultInputField.textMargins.left(), + inputy); _portInput->moveToRight(st::boxPadding.right(), inputy); - _userInput->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left() + st::defaultCheck.diameter + st::defaultBoxCheckbox.textPosition.x() - st::defaultInputField.textMargins.left(), _hostInput->y() + _hostInput->height() + st::boxOptionInputSkip); + _userInput->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left() + st::defaultCheck.diameter + + st::defaultBoxCheckbox.textPosition.x() - st::defaultInputField.textMargins.left(), + _hostInput->y() + _hostInput->height() + st::boxOptionInputSkip); _passwordInput->moveToRight(st::boxPadding.right(), _userInput->y()); } - auto tryipv6y = (fieldsBelowTcp ? _userInput->bottomNoMargins() : _tcpProxyRadio->bottomNoMargins()) + st::boxOptionListSkip + st::connectionIPv6Skip; + auto tryipv6y = (fieldsBelowTcp ? _userInput->bottomNoMargins() : _tcpProxyRadio->bottomNoMargins()) + + st::boxOptionListSkip + st::connectionIPv6Skip; _tryIPv6->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), tryipv6y); } @@ -162,7 +182,8 @@ void ConnectionBox::typeChanged(DBIConnectionType type) { updateControlsVisibility(); if (type != dbictAuto) { Global::SetLastProxyType(type); - if (!_hostInput->hasFocus() && !_portInput->hasFocus() && !_userInput->hasFocus() && !_passwordInput->hasFocus()) { + if (!_hostInput->hasFocus() && !_portInput->hasFocus() && !_userInput->hasFocus() && + !_passwordInput->hasFocus()) { _hostInput->setFocusFast(); } if ((type == dbictHttpProxy) && !_portInput->getLastText().toInt()) { @@ -257,21 +278,24 @@ void ConnectionBox::onSave() { } AutoDownloadBox::AutoDownloadBox(QWidget *parent) -: _photoPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadPhoto() & dbiadNoPrivate), st::defaultBoxCheckbox) -, _photoGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadPhoto() & dbiadNoGroups), st::defaultBoxCheckbox) -, _audioPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadAudio() & dbiadNoPrivate), st::defaultBoxCheckbox) -, _audioGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadAudio() & dbiadNoGroups), st::defaultBoxCheckbox) -, _gifPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadGif() & dbiadNoPrivate), st::defaultBoxCheckbox) -, _gifGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadGif() & dbiadNoGroups), st::defaultBoxCheckbox) -, _gifPlay(this, lang(lng_media_auto_play), cAutoPlayGif(), st::defaultBoxCheckbox) -, _sectionHeight(st::boxTitleHeight + 2 * (st::defaultCheck.diameter + st::setLittleSkip)) { -} + : _photoPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadPhoto() & dbiadNoPrivate), + st::defaultBoxCheckbox) + , _photoGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadPhoto() & dbiadNoGroups), st::defaultBoxCheckbox) + , _audioPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadAudio() & dbiadNoPrivate), + st::defaultBoxCheckbox) + , _audioGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadAudio() & dbiadNoGroups), st::defaultBoxCheckbox) + , _gifPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadGif() & dbiadNoPrivate), + st::defaultBoxCheckbox) + , _gifGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadGif() & dbiadNoGroups), st::defaultBoxCheckbox) + , _gifPlay(this, lang(lng_media_auto_play), cAutoPlayGif(), st::defaultBoxCheckbox) + , _sectionHeight(st::boxTitleHeight + 2 * (st::defaultCheck.diameter + st::setLittleSkip)) {} void AutoDownloadBox::prepare() { addButton(langFactory(lng_connection_save), [this] { onSave(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); - setDimensions(st::boxWidth, 3 * _sectionHeight - st::autoDownloadTopDelta + st::setLittleSkip + _gifPlay->heightNoMargins() + st::setLittleSkip); + setDimensions(st::boxWidth, 3 * _sectionHeight - st::autoDownloadTopDelta + st::setLittleSkip + + _gifPlay->heightNoMargins() + st::setLittleSkip); } void AutoDownloadBox::paintEvent(QPaintEvent *e) { @@ -281,9 +305,12 @@ void AutoDownloadBox::paintEvent(QPaintEvent *e) { p.setPen(st::boxTitleFg); p.setFont(st::autoDownloadTitleFont); - p.drawTextLeft(st::autoDownloadTitlePosition.x(), st::autoDownloadTitlePosition.y(), width(), lang(lng_media_auto_photo)); - p.drawTextLeft(st::autoDownloadTitlePosition.x(), _sectionHeight + st::autoDownloadTitlePosition.y(), width(), lang(lng_media_auto_audio)); - p.drawTextLeft(st::autoDownloadTitlePosition.x(), 2 * _sectionHeight + st::autoDownloadTitlePosition.y(), width(), lang(lng_media_auto_gif)); + p.drawTextLeft(st::autoDownloadTitlePosition.x(), st::autoDownloadTitlePosition.y(), width(), + lang(lng_media_auto_photo)); + p.drawTextLeft(st::autoDownloadTitlePosition.x(), _sectionHeight + st::autoDownloadTitlePosition.y(), width(), + lang(lng_media_auto_audio)); + p.drawTextLeft(st::autoDownloadTitlePosition.x(), 2 * _sectionHeight + st::autoDownloadTitlePosition.y(), width(), + lang(lng_media_auto_gif)); } void AutoDownloadBox::resizeEvent(QResizeEvent *e) { @@ -303,7 +330,8 @@ void AutoDownloadBox::resizeEvent(QResizeEvent *e) { void AutoDownloadBox::onSave() { bool changed = false; - qint32 autoDownloadPhoto = (_photoPrivate->checked() ? 0 : dbiadNoPrivate) | (_photoGroups->checked() ? 0 : dbiadNoGroups); + qint32 autoDownloadPhoto = + (_photoPrivate->checked() ? 0 : dbiadNoPrivate) | (_photoGroups->checked() ? 0 : dbiadNoGroups); if (cAutoDownloadPhoto() != autoDownloadPhoto) { bool enabledPrivate = ((cAutoDownloadPhoto() & dbiadNoPrivate) && !(autoDownloadPhoto & dbiadNoPrivate)); bool enabledGroups = ((cAutoDownloadPhoto() & dbiadNoGroups) && !(autoDownloadPhoto & dbiadNoGroups)); @@ -316,7 +344,8 @@ void AutoDownloadBox::onSave() { } changed = true; } - qint32 autoDownloadAudio = (_audioPrivate->checked() ? 0 : dbiadNoPrivate) | (_audioGroups->checked() ? 0 : dbiadNoGroups); + qint32 autoDownloadAudio = + (_audioPrivate->checked() ? 0 : dbiadNoPrivate) | (_audioGroups->checked() ? 0 : dbiadNoGroups); if (cAutoDownloadAudio() != autoDownloadAudio) { bool enabledPrivate = ((cAutoDownloadAudio() & dbiadNoPrivate) && !(autoDownloadAudio & dbiadNoPrivate)); bool enabledGroups = ((cAutoDownloadAudio() & dbiadNoGroups) && !(autoDownloadAudio & dbiadNoGroups)); @@ -330,7 +359,8 @@ void AutoDownloadBox::onSave() { } changed = true; } - qint32 autoDownloadGif = (_gifPrivate->checked() ? 0 : dbiadNoPrivate) | (_gifGroups->checked() ? 0 : dbiadNoGroups); + qint32 autoDownloadGif = + (_gifPrivate->checked() ? 0 : dbiadNoPrivate) | (_gifGroups->checked() ? 0 : dbiadNoGroups); if (cAutoDownloadGif() != autoDownloadGif) { bool enabledPrivate = ((cAutoDownloadGif() & dbiadNoPrivate) && !(autoDownloadGif & dbiadNoPrivate)); bool enabledGroups = ((cAutoDownloadGif() & dbiadNoGroups) && !(autoDownloadGif & dbiadNoGroups)); diff --git a/Telegram/SourceFiles/boxes/connection_box.h b/Telegram/SourceFiles/boxes/connection_box.h index 2256db6fa..d5039c28b 100644 --- a/Telegram/SourceFiles/boxes/connection_box.h +++ b/Telegram/SourceFiles/boxes/connection_box.h @@ -27,10 +27,8 @@ class InputField; class PortInput; class PasswordInput; class Checkbox; -template -class RadioenumGroup; -template -class Radioenum; +template class RadioenumGroup; +template class Radioenum; } // namespace Ui class ConnectionBox : public BoxContent { @@ -67,7 +65,6 @@ private: object_ptr> _httpProxyRadio; object_ptr> _tcpProxyRadio; object_ptr _tryIPv6; - }; class AutoDownloadBox : public BoxContent { @@ -95,5 +92,4 @@ private: object_ptr _gifPlay; int _sectionHeight = 0; - }; diff --git a/Telegram/SourceFiles/boxes/download_path_box.cpp b/Telegram/SourceFiles/boxes/download_path_box.cpp index ade2c5bd7..710ca390b 100644 --- a/Telegram/SourceFiles/boxes/download_path_box.cpp +++ b/Telegram/SourceFiles/boxes/download_path_box.cpp @@ -20,24 +20,23 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/download_path_box.h" -#include "lang/lang_keys.h" -#include "storage/localstorage.h" #include "core/file_utilities.h" -#include "ui/widgets/checkbox.h" -#include "ui/widgets/buttons.h" -#include "platform/platform_specific.h" -#include "styles/style_boxes.h" #include "facades.h" +#include "lang/lang_keys.h" +#include "platform/platform_specific.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" DownloadPathBox::DownloadPathBox(QWidget *parent) -: _path(Global::DownloadPath()) -, _pathBookmark(Global::DownloadPathBookmark()) -, _group(std::make_shared>(typeFromPath(_path))) -, _default(this, _group, Directory::Downloads, lang(lng_download_path_default_radio), st::defaultBoxCheckbox) -, _temp(this, _group, Directory::Temp, lang(lng_download_path_temp_radio), st::defaultBoxCheckbox) -, _dir(this, _group, Directory::Custom, lang(lng_download_path_dir_radio), st::defaultBoxCheckbox) -, _pathLink(this, QString(), st::boxLinkButton) { -} + : _path(Global::DownloadPath()) + , _pathBookmark(Global::DownloadPathBookmark()) + , _group(std::make_shared>(typeFromPath(_path))) + , _default(this, _group, Directory::Downloads, lang(lng_download_path_default_radio), st::defaultBoxCheckbox) + , _temp(this, _group, Directory::Temp, lang(lng_download_path_temp_radio), st::defaultBoxCheckbox) + , _dir(this, _group, Directory::Custom, lang(lng_download_path_dir_radio), st::defaultBoxCheckbox) + , _pathLink(this, QString(), st::boxLinkButton) {} void DownloadPathBox::prepare() { addButton(langFactory(lng_connection_save), [this] { save(); }); @@ -58,7 +57,8 @@ void DownloadPathBox::updateControlsVisibility() { auto custom = (_group->value() == Directory::Custom); _pathLink->setVisible(custom); - auto newHeight = st::boxOptionListPadding.top() + _default->getMargins().top() + _default->heightNoMargins() + st::boxOptionListSkip + _temp->heightNoMargins() + st::boxOptionListSkip + _dir->heightNoMargins(); + auto newHeight = st::boxOptionListPadding.top() + _default->getMargins().top() + _default->heightNoMargins() + + st::boxOptionListSkip + _temp->heightNoMargins() + st::boxOptionListSkip + _dir->heightNoMargins(); if (custom) { newHeight += st::downloadPathSkip + _pathLink->height(); } @@ -70,10 +70,14 @@ void DownloadPathBox::updateControlsVisibility() { void DownloadPathBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _default->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), st::boxOptionListPadding.top() + _default->getMargins().top()); - _temp->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _default->bottomNoMargins() + st::boxOptionListSkip); - _dir->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _temp->bottomNoMargins() + st::boxOptionListSkip); - auto inputx = st::boxPadding.left() + st::boxOptionListPadding.left() + st::defaultCheck.diameter + st::defaultBoxCheckbox.textPosition.x(); + _default->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + st::boxOptionListPadding.top() + _default->getMargins().top()); + _temp->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + _default->bottomNoMargins() + st::boxOptionListSkip); + _dir->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + _temp->bottomNoMargins() + st::boxOptionListSkip); + auto inputx = st::boxPadding.left() + st::boxOptionListPadding.left() + st::defaultCheck.diameter + + st::defaultBoxCheckbox.textPosition.x(); auto inputy = _dir->bottomNoMargins() + st::downloadPathSkip; _pathLink->moveToLeft(inputx, inputy); @@ -99,18 +103,20 @@ void DownloadPathBox::radioChanged(Directory value) { void DownloadPathBox::onEditPath() { auto initialPath = [] { if (!Global::DownloadPath().isEmpty() && Global::DownloadPath() != qstr("tmp")) { - return Global::DownloadPath().left(Global::DownloadPath().size() - (Global::DownloadPath().endsWith('/') ? 1 : 0)); + return Global::DownloadPath().left(Global::DownloadPath().size() - + (Global::DownloadPath().endsWith('/') ? 1 : 0)); } return QString(); }; - FileDialog::GetFolder(lang(lng_download_path_choose), initialPath(), base::lambda_guarded(this, [this](const QString &result) { - if (!result.isEmpty()) { - _path = result + '/'; - _pathBookmark = psDownloadPathBookmark(_path); - setPathText(QDir::toNativeSeparators(_path)); - _group->setValue(Directory::Custom); - } - })); + FileDialog::GetFolder(lang(lng_download_path_choose), initialPath(), + base::lambda_guarded(this, [this](const QString &result) { + if (!result.isEmpty()) { + _path = result + '/'; + _pathBookmark = psDownloadPathBookmark(_path); + setPathText(QDir::toNativeSeparators(_path)); + _group->setValue(Directory::Custom); + } + })); } void DownloadPathBox::save() { @@ -133,6 +139,7 @@ void DownloadPathBox::save() { } void DownloadPathBox::setPathText(const QString &text) { - auto availw = st::boxWideWidth - st::boxPadding.left() - st::defaultCheck.diameter - st::defaultBoxCheckbox.textPosition.x() - st::boxPadding.right(); + auto availw = st::boxWideWidth - st::boxPadding.left() - st::defaultCheck.diameter - + st::defaultBoxCheckbox.textPosition.x() - st::boxPadding.right(); _pathLink->setText(st::boxTextFont->elided(text, availw)); } diff --git a/Telegram/SourceFiles/boxes/download_path_box.h b/Telegram/SourceFiles/boxes/download_path_box.h index d2a52ae10..fbebc5f03 100644 --- a/Telegram/SourceFiles/boxes/download_path_box.h +++ b/Telegram/SourceFiles/boxes/download_path_box.h @@ -20,14 +20,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include "boxes/abstract_box.h" #include "base/observer.h" +#include "boxes/abstract_box.h" namespace Ui { -template -class RadioenumGroup; -template -class Radioenum; +template class RadioenumGroup; +template class Radioenum; class LinkButton; } // namespace Ui @@ -73,5 +71,4 @@ private: object_ptr> _temp; object_ptr> _dir; object_ptr _pathLink; - }; diff --git a/Telegram/SourceFiles/boxes/edit_color_box.cpp b/Telegram/SourceFiles/boxes/edit_color_box.cpp index 35c4eb857..9cfacf9fb 100644 --- a/Telegram/SourceFiles/boxes/edit_color_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_color_box.cpp @@ -20,12 +20,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/edit_color_box.h" +#include "app.h" #include "lang/lang_keys.h" #include "styles/style_boxes.h" -#include "ui/widgets/shadow.h" #include "styles/style_mediaview.h" #include "ui/widgets/input_fields.h" -#include "app.h" +#include "ui/widgets/shadow.h" class EditColorBox::Picker : public TWidget { public: @@ -70,7 +70,6 @@ private: bool _choosing = false; base::Observable _changed; - }; QCursor EditColorBox::Picker::generateCursor() { @@ -97,7 +96,8 @@ QCursor EditColorBox::Picker::generateCursor() { return QCursor(QPixmap::fromImage(cursor)); } -EditColorBox::Picker::Picker(QWidget *parent, QColor color) : TWidget(parent) { +EditColorBox::Picker::Picker(QWidget *parent, QColor color) + : TWidget(parent) { setCursor(generateCursor()); auto size = QSize(st::colorPickerSize, st::colorPickerSize); @@ -128,7 +128,8 @@ void EditColorBox::Picker::paintEvent(QPaintEvent *e) { auto y = anim::interpolate(0, height() - 1, _y); PainterHighQualityEnabler hq(p); - p.drawEllipse(QRect(x - st::colorPickerMarkRadius, y - st::colorPickerMarkRadius, 2 * st::colorPickerMarkRadius, 2 * st::colorPickerMarkRadius)); + p.drawEllipse(QRect(x - st::colorPickerMarkRadius, y - st::colorPickerMarkRadius, 2 * st::colorPickerMarkRadius, + 2 * st::colorPickerMarkRadius)); } void EditColorBox::Picker::mousePressEvent(QMouseEvent *e) { @@ -151,7 +152,7 @@ void EditColorBox::Picker::preparePalette() { _paletteInvalidated = false; auto size = _palette.width(); - auto ints = reinterpret_cast(_palette.bits()); + auto ints = reinterpret_cast(_palette.bits()); auto intsAddPerLine = (_palette.bytesPerLine() - size * sizeof(quint32)) / sizeof(quint32); constexpr auto Large = 1024 * 1024; @@ -280,15 +281,15 @@ private: bool _choosing = false; base::Observable _changed; - }; -EditColorBox::Slider::Slider(QWidget *parent, Direction direction, Type type, QColor color) : TWidget(parent) -, _direction(direction) -, _type(type) -, _color(color.red(), color.green(), color.blue()) -, _value(valueFromColor(color)) -, _transparent((_type == Type::Hue) ? QBrush() : style::transparentPlaceholderBrush()) { +EditColorBox::Slider::Slider(QWidget *parent, Direction direction, Type type, QColor color) + : TWidget(parent) + , _direction(direction) + , _type(type) + , _color(color.red(), color.green(), color.blue()) + , _value(valueFromColor(color)) + , _transparent((_type == Type::Hue) ? QBrush() : style::transparentPlaceholderBrush()) { prepareMinSize(); } @@ -299,7 +300,8 @@ void EditColorBox::Slider::prepareMinSize() { void EditColorBox::Slider::paintEvent(QPaintEvent *e) { Painter p(this); - auto to = rect().marginsRemoved(QMargins(st::colorSliderSkip, st::colorSliderSkip, st::colorSliderSkip, st::colorSliderSkip)); + auto to = rect().marginsRemoved( + QMargins(st::colorSliderSkip, st::colorSliderSkip, st::colorSliderSkip, st::colorSliderSkip)); Ui::Shadow::paint(p, to, width(), st::defaultRoundShadow); if (_type == Type::Opacity) { p.fillRect(to, _transparent); @@ -308,11 +310,13 @@ void EditColorBox::Slider::paintEvent(QPaintEvent *e) { if (isHorizontal()) { auto x = st::colorSliderSkip + std::round(_value * to.width()); st::colorSliderArrowTop.paint(p, x - st::colorSliderArrowTop.width() / 2, 0, width()); - st::colorSliderArrowBottom.paint(p, x - st::colorSliderArrowBottom.width() / 2, height() - st::colorSliderArrowBottom.height(), width()); + st::colorSliderArrowBottom.paint(p, x - st::colorSliderArrowBottom.width() / 2, + height() - st::colorSliderArrowBottom.height(), width()); } else { auto y = st::colorSliderSkip + std::round(_value * to.height()); st::colorSliderArrowLeft.paint(p, 0, y - st::colorSliderArrowLeft.height() / 2, width()); - st::colorSliderArrowRight.paint(p, width() - st::colorSliderArrowRight.width(), y - st::colorSliderArrowRight.height() / 2, width()); + st::colorSliderArrowRight.paint(p, width() - st::colorSliderArrowRight.width(), + y - st::colorSliderArrowRight.height() / 2, width()); } } @@ -340,7 +344,7 @@ void EditColorBox::Slider::generatePixmap() { auto size = (isHorizontal() ? width() : height()) * cIntRetinaFactor(); auto image = QImage(size, cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); image.setDevicePixelRatio(cRetinaFactor()); - auto ints = reinterpret_cast(image.bits()); + auto ints = reinterpret_cast(image.bits()); auto intsPerLine = image.bytesPerLine() / sizeof(quint32); auto intsPerLineAdded = intsPerLine - size; @@ -441,7 +445,8 @@ void EditColorBox::Slider::updateCurrentPoint(QPoint localPosition) { class EditColorBox::Field : public Ui::MaskedInputField { public: - Field(QWidget *parent, const style::InputField &st, const QString &placeholder, int limit, const QString &units = QString()); + Field(QWidget *parent, const style::InputField &st, const QString &placeholder, int limit, + const QString &units = QString()); int value() const { return getLastText().toInt(); @@ -468,15 +473,15 @@ private: int _limit = 0; int _digitLimit = 1; int _wheelDelta = 0; - }; -EditColorBox::Field::Field(QWidget *parent, const style::InputField &st, const QString &placeholder, int limit, const QString &units) : Ui::MaskedInputField(parent, st) -, _placeholder(placeholder) -, _units(units) -, _limit(limit) -, _digitLimit(QString::number(_limit).size()) { -} +EditColorBox::Field::Field(QWidget *parent, const style::InputField &st, const QString &placeholder, int limit, + const QString &units) + : Ui::MaskedInputField(parent, st) + , _placeholder(placeholder) + , _units(units) + , _limit(limit) + , _digitLimit(QString::number(_limit).size()) {} void EditColorBox::Field::correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) { QString newText; @@ -518,7 +523,8 @@ void EditColorBox::Field::correctValue(const QString &was, int wasCursor, QStrin void EditColorBox::Field::paintAdditionalPlaceholder(Painter &p, TimeMs ms) { p.setFont(_st.font); p.setPen(_st.placeholderFg); - auto inner = QRect(_st.textMargins.right(), _st.textMargins.top(), width() - 2 * _st.textMargins.right(), height() - _st.textMargins.top() - _st.textMargins.bottom()); + auto inner = QRect(_st.textMargins.right(), _st.textMargins.top(), width() - 2 * _st.textMargins.right(), + height() - _st.textMargins.top() - _st.textMargins.bottom()); p.drawText(inner, _placeholder, style::al_topleft); if (!_units.isEmpty()) { p.drawText(inner, _units, style::al_topright); @@ -580,11 +586,10 @@ public: protected: void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override; void paintAdditionalPlaceholder(Painter &p, TimeMs ms) override; - }; -EditColorBox::ResultField::ResultField(QWidget *parent, const style::InputField &st) : Ui::MaskedInputField(parent, st) { -} +EditColorBox::ResultField::ResultField(QWidget *parent, const style::InputField &st) + : Ui::MaskedInputField(parent, st) {} void EditColorBox::ResultField::correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) { QString newText; @@ -623,25 +628,27 @@ void EditColorBox::ResultField::correctValue(const QString &was, int wasCursor, void EditColorBox::ResultField::paintAdditionalPlaceholder(Painter &p, TimeMs ms) { p.setFont(_st.font); p.setPen(_st.placeholderFg); - p.drawText(QRect(_st.textMargins.right(), _st.textMargins.top(), width(), height() - _st.textMargins.top() - _st.textMargins.bottom()), "#", style::al_topleft); + p.drawText(QRect(_st.textMargins.right(), _st.textMargins.top(), width(), + height() - _st.textMargins.top() - _st.textMargins.bottom()), + "#", style::al_topleft); } -EditColorBox::EditColorBox(QWidget*, const QString &title, QColor current) : BoxContent() -, _title(title) -, _picker(this, current) -, _hueSlider(this, Slider::Direction::Vertical, Slider::Type::Hue, current) -, _opacitySlider(this, Slider::Direction::Horizontal, Slider::Type::Opacity, current) -, _hueField(this, st::colorValueInput, "H", 360, QString() + QChar(176)) // degree character -, _saturationField(this, st::colorValueInput, "S", 100, "%") -, _brightnessField(this, st::colorValueInput, "B", 100, "%") -, _redField(this, st::colorValueInput, "R", 255) -, _greenField(this, st::colorValueInput, "G", 255) -, _blueField(this, st::colorValueInput, "B", 255) -, _result(this, st::colorResultInput) -, _transparent(style::transparentPlaceholderBrush()) -, _current(current) -, _new(current) { -} +EditColorBox::EditColorBox(QWidget *, const QString &title, QColor current) + : BoxContent() + , _title(title) + , _picker(this, current) + , _hueSlider(this, Slider::Direction::Vertical, Slider::Type::Hue, current) + , _opacitySlider(this, Slider::Direction::Horizontal, Slider::Type::Opacity, current) + , _hueField(this, st::colorValueInput, "H", 360, QString() + QChar(176)) // degree character + , _saturationField(this, st::colorValueInput, "S", 100, "%") + , _brightnessField(this, st::colorValueInput, "B", 100, "%") + , _redField(this, st::colorValueInput, "R", 255) + , _greenField(this, st::colorValueInput, "G", 255) + , _blueField(this, st::colorValueInput, "B", 255) + , _result(this, st::colorResultInput) + , _transparent(style::transparentPlaceholderBrush()) + , _current(current) + , _new(current) {} void EditColorBox::prepare() { setTitle([this] { return _title; }); @@ -665,7 +672,8 @@ void EditColorBox::prepare() { addButton(langFactory(lng_settings_save), [this] { saveColor(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); - auto height = st::colorEditSkip + st::colorPickerSize + st::colorEditSkip + st::colorSliderWidth + st::colorEditSkip; + auto height = + st::colorEditSkip + st::colorPickerSize + st::colorEditSkip + st::colorSliderWidth + st::colorEditSkip; setDimensions(st::colorEditWidth, height); subscribe(_picker->changed(), [this] { updateFromControls(); }); @@ -708,15 +716,8 @@ void EditColorBox::onFieldChanged() { } void EditColorBox::onFieldSubmitted() { - Ui::MaskedInputField *fields[] = { - _hueField, - _saturationField, - _brightnessField, - _redField, - _greenField, - _blueField, - _result - }; + Ui::MaskedInputField *fields[] = {_hueField, _saturationField, _brightnessField, _redField, + _greenField, _blueField, _result}; for (auto i = 0, count = int(base::array_size(fields)); i + 1 != count; ++i) { if (fields[i]->hasFocus()) { fields[i + 1]->setFocus(); @@ -776,23 +777,33 @@ void EditColorBox::updateResultField() { } void EditColorBox::resizeEvent(QResizeEvent *e) { - auto fullwidth = _picker->width() + 2 * (st::colorEditSkip - st::colorSliderSkip) + _hueSlider->width() + st::colorSampleSize.width(); + auto fullwidth = _picker->width() + 2 * (st::colorEditSkip - st::colorSliderSkip) + _hueSlider->width() + + st::colorSampleSize.width(); auto left = (width() - fullwidth) / 2; _picker->moveToLeft(left, st::colorEditSkip); - _hueSlider->setGeometryToLeft(_picker->x() + _picker->width() + st::colorEditSkip - st::colorSliderSkip, st::colorEditSkip - st::colorSliderSkip, _hueSlider->width(), st::colorPickerSize + 2 * st::colorSliderSkip); - _opacitySlider->setGeometryToLeft(_picker->x() - st::colorSliderSkip, _picker->y() + _picker->height() + st::colorEditSkip - st::colorSliderSkip, _picker->width() + 2 * st::colorSliderSkip, _opacitySlider->height()); + _hueSlider->setGeometryToLeft(_picker->x() + _picker->width() + st::colorEditSkip - st::colorSliderSkip, + st::colorEditSkip - st::colorSliderSkip, _hueSlider->width(), + st::colorPickerSize + 2 * st::colorSliderSkip); + _opacitySlider->setGeometryToLeft(_picker->x() - st::colorSliderSkip, + _picker->y() + _picker->height() + st::colorEditSkip - st::colorSliderSkip, + _picker->width() + 2 * st::colorSliderSkip, _opacitySlider->height()); auto fieldLeft = _hueSlider->x() + _hueSlider->width() - st::colorSliderSkip + st::colorEditSkip; auto fieldWidth = st::colorSampleSize.width(); auto fieldHeight = _hueField->height(); _newRect = QRect(fieldLeft, st::colorEditSkip, fieldWidth, st::colorSampleSize.height()); _currentRect = _newRect.translated(0, st::colorSampleSize.height()); - _hueField->setGeometryToLeft(fieldLeft, _currentRect.y() + _currentRect.height() + st::colorFieldSkip, fieldWidth, fieldHeight); + _hueField->setGeometryToLeft(fieldLeft, _currentRect.y() + _currentRect.height() + st::colorFieldSkip, fieldWidth, + fieldHeight); _saturationField->setGeometryToLeft(fieldLeft, _hueField->y() + _hueField->height(), fieldWidth, fieldHeight); - _brightnessField->setGeometryToLeft(fieldLeft, _saturationField->y() + _saturationField->height(), fieldWidth, fieldHeight); - _redField->setGeometryToLeft(fieldLeft, _brightnessField->y() + _brightnessField->height() + st::colorFieldSkip, fieldWidth, fieldHeight); + _brightnessField->setGeometryToLeft(fieldLeft, _saturationField->y() + _saturationField->height(), fieldWidth, + fieldHeight); + _redField->setGeometryToLeft(fieldLeft, _brightnessField->y() + _brightnessField->height() + st::colorFieldSkip, + fieldWidth, fieldHeight); _greenField->setGeometryToLeft(fieldLeft, _redField->y() + _redField->height(), fieldWidth, fieldHeight); _blueField->setGeometryToLeft(fieldLeft, _greenField->y() + _greenField->height(), fieldWidth, fieldHeight); - _result->setGeometryToLeft(fieldLeft - (st::colorEditSkip + st::colorSliderWidth), _opacitySlider->y() + _opacitySlider->height() - st::colorSliderSkip - _result->height(), fieldWidth + (st::colorEditSkip + st::colorSliderWidth), fieldHeight); + _result->setGeometryToLeft(fieldLeft - (st::colorEditSkip + st::colorSliderWidth), + _opacitySlider->y() + _opacitySlider->height() - st::colorSliderSkip - _result->height(), + fieldWidth + (st::colorEditSkip + st::colorSliderWidth), fieldHeight); } void EditColorBox::paintEvent(QPaintEvent *e) { @@ -801,7 +812,8 @@ void EditColorBox::paintEvent(QPaintEvent *e) { Painter p(this); Ui::Shadow::paint(p, _picker->geometry(), width(), st::defaultRoundShadow); - Ui::Shadow::paint(p, QRect(_newRect.x(), _newRect.y(), _newRect.width(), _newRect.height() + _currentRect.height()), width(), st::defaultRoundShadow); + Ui::Shadow::paint(p, QRect(_newRect.x(), _newRect.y(), _newRect.width(), _newRect.height() + _currentRect.height()), + width(), st::defaultRoundShadow); if (_new.alphaF() < 1.) { p.fillRect(myrtlrect(_newRect), _transparent); } @@ -870,9 +882,7 @@ void EditColorBox::updateFromResultField() { } return code - '0'; }; - auto fromChars = [fromHex](QChar a, QChar b) { - return fromHex(a) * 0x10 + fromHex(b); - }; + auto fromChars = [fromHex](QChar a, QChar b) { return fromHex(a) * 0x10 + fromHex(b); }; auto red = fromChars(text[0], text[1]); auto green = fromChars(text[2], text[3]); auto blue = fromChars(text[4], text[5]); diff --git a/Telegram/SourceFiles/boxes/edit_color_box.h b/Telegram/SourceFiles/boxes/edit_color_box.h index b4aa2a64d..26740b5ab 100644 --- a/Telegram/SourceFiles/boxes/edit_color_box.h +++ b/Telegram/SourceFiles/boxes/edit_color_box.h @@ -26,7 +26,7 @@ class EditColorBox : public BoxContent { Q_OBJECT public: - EditColorBox(QWidget*, const QString &title, QColor current = QColor(255, 255, 255)); + EditColorBox(QWidget *, const QString &title, QColor current = QColor(255, 255, 255)); void setSaveCallback(base::lambda callback) { _saveCallback = std::move(callback); @@ -105,5 +105,4 @@ private: base::lambda _saveCallback; base::lambda _cancelCallback; - }; diff --git a/Telegram/SourceFiles/boxes/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/edit_participant_box.cpp index 5f22a7f6e..caa1a7b09 100644 --- a/Telegram/SourceFiles/boxes/edit_participant_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_participant_box.cpp @@ -20,15 +20,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/edit_participant_box.h" -#include "lang/lang_keys.h" -#include "ui/widgets/checkbox.h" -#include "ui/widgets/labels.h" -#include "ui/widgets/buttons.h" -#include "styles/style_boxes.h" -#include "ui/special_buttons.h" +#include "app.h" // For App::peerName #include "boxes/calendar_box.h" #include "facades.h" -#include "app.h" // For App::peerName +#include "lang/lang_keys.h" +#include "styles/style_boxes.h" +#include "ui/special_buttons.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/labels.h" namespace { @@ -77,12 +77,11 @@ void ApplyDependencies(CheckboxesMap &checkboxes, DependenciesMap &dependencies, class EditParticipantBox::Inner : public TWidget { public: - Inner(QWidget *parent, not_null channel, not_null user, bool hasAdminRights); + Inner(QWidget *parent, not_null channel, not_null user, bool hasAdminRights); - template - QPointer addControl(object_ptr widget, QMargins margin) { + template QPointer addControl(object_ptr widget, QMargins margin) { doAddControl(std::move(widget), margin); - return static_cast(_rows.back().widget.data()); + return static_cast(_rows.back().widget.data()); } void removeControl(QPointer widget); @@ -94,8 +93,8 @@ protected: private: void doAddControl(object_ptr widget, QMargins margin); - not_null _channel; - not_null _user; + not_null _channel; + not_null _user; object_ptr _userPhoto; Text _userName; bool _hasAdminRights = false; @@ -104,22 +103,21 @@ private: QMargins margin; }; std::vector _rows; - }; -EditParticipantBox::Inner::Inner(QWidget *parent, not_null channel, not_null user, bool hasAdminRights) : TWidget(parent) -, _channel(channel) -, _user(user) -, _userPhoto(this, _user, st::rightsPhotoButton) -, _hasAdminRights(hasAdminRights) { +EditParticipantBox::Inner::Inner(QWidget *parent, not_null channel, not_null user, + bool hasAdminRights) + : TWidget(parent) + , _channel(channel) + , _user(user) + , _userPhoto(this, _user, st::rightsPhotoButton) + , _hasAdminRights(hasAdminRights) { _userName.setText(st::rightsNameStyle, App::peerName(_user), _textNameOptions); _userPhoto->setClickedCallback([this] { Ui::showPeerProfile(_user); }); } void EditParticipantBox::Inner::removeControl(QPointer widget) { - auto row = std::find_if(_rows.begin(), _rows.end(), [widget](auto &&row) { - return (row.widget == widget); - }); + auto row = std::find_if(_rows.begin(), _rows.end(), [widget](auto &&row) { return (row.widget == widget); }); Assert(row != _rows.end()); row->widget.destroy(); _rows.erase(row); @@ -127,7 +125,7 @@ void EditParticipantBox::Inner::removeControl(QPointer widget) { void EditParticipantBox::Inner::doAddControl(object_ptr widget, QMargins margin) { widget->setParent(this); - _rows.push_back({ std::move(widget), margin }); + _rows.push_back({std::move(widget), margin}); _rows.back().widget->show(); } @@ -165,18 +163,18 @@ void EditParticipantBox::Inner::paintEvent(QPaintEvent *e) { p.drawTextLeft(namex, st::rightsPhotoMargin.top() + st::rightsStatusTop, width(), statusText()); } -EditParticipantBox::EditParticipantBox(QWidget*, not_null channel, not_null user, bool hasAdminRights) : BoxContent() -, _channel(channel) -, _user(user) -, _hasAdminRights(hasAdminRights) { -} +EditParticipantBox::EditParticipantBox(QWidget *, not_null channel, not_null user, + bool hasAdminRights) + : BoxContent() + , _channel(channel) + , _user(user) + , _hasAdminRights(hasAdminRights) {} void EditParticipantBox::prepare() { _inner = setInnerWidget(object_ptr(this, _channel, _user, hasAdminRights())); } -template -QPointer EditParticipantBox::addControl(object_ptr widget, QMargins margin) { +template QPointer EditParticipantBox::addControl(object_ptr widget, QMargins margin) { Expects(_inner != nullptr); return _inner->addControl(std::move(widget), margin); } @@ -191,8 +189,10 @@ void EditParticipantBox::resizeToContent() { setDimensions(_inner->width(), std::min(_inner->height(), st::boxMaxListHeight)); } -EditAdminBox::EditAdminBox(QWidget*, not_null channel, not_null user, const MTPChannelAdminRights &rights) : EditParticipantBox(nullptr, channel, user, (rights.c_channelAdminRights().vflags.v != 0)) -, _oldRights(rights) { +EditAdminBox::EditAdminBox(QWidget *, not_null channel, not_null user, + const MTPChannelAdminRights &rights) + : EditParticipantBox(nullptr, channel, user, (rights.c_channelAdminRights().vflags.v != 0)) + , _oldRights(rights) { auto dependency = [this](Flag dependent, Flag dependency) { _dependencies.push_back(std::make_pair(dependent, dependency)); }; @@ -200,10 +200,12 @@ EditAdminBox::EditAdminBox(QWidget*, not_null channel, not_null channel) { - auto defaultRights = channel->isMegagroup() - ? (Flag::f_change_info | Flag::f_delete_messages | Flag::f_ban_users | Flag::f_invite_users | Flag::f_invite_link | Flag::f_pin_messages) - : (Flag::f_change_info | Flag::f_post_messages | Flag::f_edit_messages | Flag::f_delete_messages | Flag::f_invite_users | Flag::f_invite_link); +MTPChannelAdminRights EditAdminBox::DefaultRights(not_null channel) { + auto defaultRights = channel->isMegagroup() ? + (Flag::f_change_info | Flag::f_delete_messages | Flag::f_ban_users | Flag::f_invite_users | + Flag::f_invite_link | Flag::f_pin_messages) : + (Flag::f_change_info | Flag::f_post_messages | Flag::f_edit_messages | + Flag::f_delete_messages | Flag::f_invite_users | Flag::f_invite_link); return MTP_channelAdminRights(MTP_flags(defaultRights)); } @@ -214,12 +216,15 @@ void EditAdminBox::prepare() { setTitle(langFactory(hadRights ? lng_rights_edit_admin : lng_channel_add_admin)); addControl(object_ptr(this), QMargins()); - addControl(object_ptr(this, lang(lng_rights_edit_admin_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin); + addControl(object_ptr(this, lang(lng_rights_edit_admin_header), Ui::FlatLabel::InitType::Simple, + st::rightsHeaderLabel), + st::rightsHeaderMargin); auto prepareRights = (hadRights ? _oldRights : DefaultRights(channel())); auto addCheckbox = [this, &prepareRights](Flags flags, const QString &text) { auto checked = (prepareRights.c_channelAdminRights().vflags.v & flags) != 0; - auto control = addControl(object_ptr(this, text, checked, st::rightsCheckbox, st::rightsToggle), st::rightsToggleMargin); + auto control = addControl(object_ptr(this, text, checked, st::rightsCheckbox, st::rightsToggle), + st::rightsToggleMargin); subscribe(control->checkedChanged, [this, control](bool checked) { InvokeQueued(this, [this, control] { applyDependencies(control); }); }); @@ -237,7 +242,8 @@ void EditAdminBox::prepare() { addCheckbox(Flag::f_change_info, lang(lng_rights_group_info)); addCheckbox(Flag::f_delete_messages, lang(lng_rights_group_delete)); addCheckbox(Flag::f_ban_users, lang(lng_rights_group_ban)); - addCheckbox(Flag::f_invite_users | Flag::f_invite_link, lang(channel()->anyoneCanAddMembers() ? lng_rights_group_invite_link : lng_rights_group_invite)); + addCheckbox(Flag::f_invite_users | Flag::f_invite_link, + lang(channel()->anyoneCanAddMembers() ? lng_rights_group_invite_link : lng_rights_group_invite)); addCheckbox(Flag::f_pin_messages, lang(lng_rights_group_pin)); addCheckbox(Flag::f_add_admins, lang(lng_rights_add_admins)); } else { @@ -253,9 +259,7 @@ void EditAdminBox::prepare() { if (addAdmins != _checkboxes.end()) { _aboutAddAdmins = addControl(object_ptr(this, st::boxLabel), st::rightsAboutMargin); Assert(addAdmins != _checkboxes.end()); - subscribe(addAdmins->second->checkedChanged, [this](bool checked) { - refreshAboutAddAdminsText(); - }); + subscribe(addAdmins->second->checkedChanged, [this](bool checked) { refreshAboutAddAdminsText(); }); refreshAboutAddAdminsText(); } @@ -310,8 +314,10 @@ void EditAdminBox::refreshAboutAddAdminsText() { resizeToContent(); } -EditRestrictedBox::EditRestrictedBox(QWidget*, not_null channel, not_null user, bool hasAdminRights, const MTPChannelBannedRights &rights) : EditParticipantBox(nullptr, channel, user, hasAdminRights) -, _oldRights(rights) { +EditRestrictedBox::EditRestrictedBox(QWidget *, not_null channel, not_null user, + bool hasAdminRights, const MTPChannelBannedRights &rights) + : EditParticipantBox(nullptr, channel, user, hasAdminRights) + , _oldRights(rights) { auto dependency = [this](Flag dependent, Flag dependency) { _dependencies.push_back(std::make_pair(dependent, dependency)); }; @@ -333,14 +339,17 @@ void EditRestrictedBox::prepare() { setTitle(langFactory(lng_rights_user_restrictions)); addControl(object_ptr(this), QMargins()); - addControl(object_ptr(this, lang(lng_rights_user_restrictions_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin); + addControl(object_ptr(this, lang(lng_rights_user_restrictions_header), + Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), + st::rightsHeaderMargin); auto prepareRights = (_oldRights.c_channelBannedRights().vflags.v ? _oldRights : DefaultRights(channel())); _until = prepareRights.c_channelBannedRights().vuntil_date.v; auto addCheckbox = [this, &prepareRights](Flags flags, const QString &text) { auto checked = (prepareRights.c_channelBannedRights().vflags.v & flags) == 0; - auto control = addControl(object_ptr(this, text, checked, st::rightsCheckbox, st::rightsToggle), st::rightsToggleMargin); + auto control = addControl(object_ptr(this, text, checked, st::rightsCheckbox, st::rightsToggle), + st::rightsToggleMargin); subscribe(control->checkedChanged, [this, control](bool checked) { InvokeQueued(this, [this, control] { applyDependencies(control); }); }); @@ -352,14 +361,17 @@ void EditRestrictedBox::prepare() { addCheckbox(Flag::f_view_messages, lang(lng_rights_chat_read)); addCheckbox(Flag::f_send_messages, lang(lng_rights_chat_send_text)); addCheckbox(Flag::f_send_media, lang(lng_rights_chat_send_media)); - addCheckbox(Flag::f_send_stickers | Flag::f_send_gifs | Flag::f_send_games | Flag::f_send_inline, lang(lng_rights_chat_send_stickers)); + addCheckbox(Flag::f_send_stickers | Flag::f_send_gifs | Flag::f_send_games | Flag::f_send_inline, + lang(lng_rights_chat_send_stickers)); addCheckbox(Flag::f_embed_links, lang(lng_rights_chat_send_links)); addControl(object_ptr(this), st::rightsUntilMargin); - addControl(object_ptr(this, lang(lng_rights_chat_banned_until_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin); + addControl(object_ptr(this, lang(lng_rights_chat_banned_until_header), + Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), + st::rightsHeaderMargin); setRestrictUntil(_until); - //addControl(object_ptr(this, lang(lng_rights_chat_banned_block), st::boxLinkButton)); + // addControl(object_ptr(this, lang(lng_rights_chat_banned_block), st::boxLinkButton)); if (canSave()) { addButton(langFactory(lng_settings_save), [this] { @@ -393,8 +405,9 @@ void EditRestrictedBox::applyDependencies(QPointer changed) { ApplyDependencies(_checkboxes, _dependencies, changed); } -MTPChannelBannedRights EditRestrictedBox::DefaultRights(not_null channel) { - auto defaultRights = Flag::f_send_messages | Flag::f_send_media | Flag::f_embed_links | Flag::f_send_stickers | Flag::f_send_gifs | Flag::f_send_games | Flag::f_send_inline; +MTPChannelBannedRights EditRestrictedBox::DefaultRights(not_null channel) { + auto defaultRights = Flag::f_send_messages | Flag::f_send_media | Flag::f_embed_links | Flag::f_send_stickers | + Flag::f_send_gifs | Flag::f_send_games | Flag::f_send_inline; return MTP_channelBannedRights(MTP_flags(defaultRights), MTP_int(0)); } @@ -402,7 +415,10 @@ void EditRestrictedBox::showRestrictUntil() { auto tomorrow = QDate::currentDate().addDays(1); auto highlighted = isUntilForever() ? tomorrow : date(getRealUntilValue()).date(); auto month = highlighted; - _restrictUntilBox = Ui::show(Box(month, highlighted, [this](const QDate &date) { setRestrictUntil(static_cast(QDateTime(date).toTime_t())); }), KeepOtherLayers); + _restrictUntilBox = Ui::show( + Box(month, highlighted, + [this](const QDate &date) { setRestrictUntil(static_cast(QDateTime(date).toTime_t())); }), + KeepOtherLayers); _restrictUntilBox->setMaxDate(QDate::currentDate().addDays(kMaxRestrictDelayDays)); _restrictUntilBox->setMinDate(tomorrow); _restrictUntilBox->addLeftButton(langFactory(lng_rights_chat_banned_forever), [this] { setRestrictUntil(0); }); @@ -442,7 +458,9 @@ void EditRestrictedBox::createUntilVariants() { if (!canSave() && _untilGroup->value() != value) { return; } - _untilVariants.push_back(addControl(object_ptr(this, _untilGroup, value, text, st::defaultBoxCheckbox), st::rightsToggleMargin)); + _untilVariants.push_back( + addControl(object_ptr(this, _untilGroup, value, text, st::defaultBoxCheckbox), + st::rightsToggleMargin)); if (!canSave()) { _untilVariants.back()->setDisabled(true); } diff --git a/Telegram/SourceFiles/boxes/edit_participant_box.h b/Telegram/SourceFiles/boxes/edit_participant_box.h index d4496b19b..91107e84c 100644 --- a/Telegram/SourceFiles/boxes/edit_participant_box.h +++ b/Telegram/SourceFiles/boxes/edit_participant_box.h @@ -34,22 +34,21 @@ class CalendarBox; class EditParticipantBox : public BoxContent { public: - EditParticipantBox(QWidget*, not_null channel, not_null user, bool hasAdminRights); + EditParticipantBox(QWidget *, not_null channel, not_null user, bool hasAdminRights); protected: void prepare() override; void resizeToContent(); - not_null user() const { + not_null user() const { return _user; } - not_null channel() const { + not_null channel() const { return _channel; } - template - QPointer addControl(object_ptr widget, QMargins margin); + template QPointer addControl(object_ptr widget, QMargins margin); void removeControl(QPointer widget); @@ -58,18 +57,18 @@ protected: } private: - not_null _channel; - not_null _user; + not_null _channel; + not_null _user; bool _hasAdminRights = false; class Inner; QPointer _inner; - }; class EditAdminBox : public EditParticipantBox { public: - EditAdminBox(QWidget*, not_null channel, not_null user, const MTPChannelAdminRights &rights); + EditAdminBox(QWidget *, not_null channel, not_null user, + const MTPChannelAdminRights &rights); void setSaveCallback(base::lambda callback) { _saveCallback = std::move(callback); @@ -82,7 +81,7 @@ private: using Flag = MTPDchannelAdminRights::Flag; using Flags = MTPDchannelAdminRights::Flags; - static MTPChannelAdminRights DefaultRights(not_null channel); + static MTPChannelAdminRights DefaultRights(not_null channel); bool canSave() const { return !!_saveCallback; @@ -96,7 +95,6 @@ private: std::map> _checkboxes; QPointer _aboutAddAdmins; - }; // Restricted box works with flags in the opposite way. @@ -104,7 +102,8 @@ private: class EditRestrictedBox : public EditParticipantBox { public: - EditRestrictedBox(QWidget*, not_null channel, not_null user, bool hasAdminRights, const MTPChannelBannedRights &rights); + EditRestrictedBox(QWidget *, not_null channel, not_null user, bool hasAdminRights, + const MTPChannelBannedRights &rights); void setSaveCallback(base::lambda callback) { _saveCallback = std::move(callback); @@ -117,7 +116,7 @@ private: using Flag = MTPDchannelBannedRights::Flag; using Flags = MTPDchannelBannedRights::Flags; - static MTPChannelBannedRights DefaultRights(not_null channel); + static MTPChannelBannedRights DefaultRights(not_null channel); bool canSave() const { return !!_saveCallback; @@ -147,5 +146,4 @@ private: static constexpr auto kUntilOneDay = -1; static constexpr auto kUntilOneWeek = -2; static constexpr auto kUntilCustom = -3; - }; diff --git a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp index 5cdcb9649..c06446e48 100644 --- a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp @@ -18,52 +18,52 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include "base/lambda_guard.h" #include "boxes/edit_privacy_box.h" +#include "base/lambda_guard.h" +#include "apiwrap.h" +#include "app.h" // For App::user, App::feedUsers +#include "auth_session.h" +#include "boxes/peer_list_controllers.h" +#include "lang/lang_keys.h" #include "styles/style_boxes.h" +#include "ui/effects/widget_slide_wrap.h" +#include "ui/widgets/buttons.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" -#include "ui/widgets/buttons.h" -#include "ui/effects/widget_slide_wrap.h" -#include "boxes/peer_list_controllers.h" -#include "apiwrap.h" -#include "auth_session.h" -#include "lang/lang_keys.h" -#include "app.h" // For App::user, App::feedUsers namespace { class PrivacyExceptionsBoxController : public ChatsListBoxController { public: - PrivacyExceptionsBoxController(base::lambda titleFactory, const std::vector> &selected); - void rowClicked(not_null row) override; + PrivacyExceptionsBoxController(base::lambda titleFactory, + const std::vector> &selected); + void rowClicked(not_null row) override; - std::vector> getResult() const; + std::vector> getResult() const; protected: void prepareViewHook() override; - std::unique_ptr createRow(not_null history) override; + std::unique_ptr createRow(not_null history) override; private: base::lambda _titleFactory; - std::vector> _selected; - + std::vector> _selected; }; -PrivacyExceptionsBoxController::PrivacyExceptionsBoxController(base::lambda titleFactory, const std::vector> &selected) -: _titleFactory(std::move(titleFactory)) -, _selected(selected) { -} +PrivacyExceptionsBoxController::PrivacyExceptionsBoxController(base::lambda titleFactory, + const std::vector> &selected) + : _titleFactory(std::move(titleFactory)) + , _selected(selected) {} void PrivacyExceptionsBoxController::prepareViewHook() { delegate()->peerListSetTitle(_titleFactory); delegate()->peerListAddSelectedRows(_selected); } -std::vector> PrivacyExceptionsBoxController::getResult() const { +std::vector> PrivacyExceptionsBoxController::getResult() const { auto peers = delegate()->peerListCollectSelectedRows(); - auto users = std::vector>(); + auto users = std::vector>(); if (!peers.empty()) { users.reserve(peers.size()); for_const (auto peer, peers) { @@ -75,11 +75,12 @@ std::vector> PrivacyExceptionsBoxController::getResult() con return users; } -void PrivacyExceptionsBoxController::rowClicked(not_null row) { +void PrivacyExceptionsBoxController::rowClicked(not_null row) { delegate()->peerListSetRowChecked(row, !row->checked()); } -std::unique_ptr PrivacyExceptionsBoxController::createRow(not_null history) { +std::unique_ptr +PrivacyExceptionsBoxController::createRow(not_null history) { if (history->peer->isSelf()) { return nullptr; } @@ -91,10 +92,10 @@ std::unique_ptr PrivacyExceptionsBoxControl } // namespace -EditPrivacyBox::EditPrivacyBox(QWidget*, std::unique_ptr controller) : BoxContent() -, _controller(std::move(controller)) -, _loading(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout) { -} +EditPrivacyBox::EditPrivacyBox(QWidget *, std::unique_ptr controller) + : BoxContent() + , _controller(std::move(controller)) + , _loading(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout) {} void EditPrivacyBox::prepare() { _controller->setView(this); @@ -177,34 +178,34 @@ int EditPrivacyBox::countDefaultHeight(int newWidth) { } void EditPrivacyBox::editExceptionUsers(Exception exception) { - auto controller = std::make_unique(base::lambda_guarded(this, [this, exception] { - return _controller->exceptionBoxTitle(exception); - }), exceptionUsers(exception)); - auto initBox = [this, exception, controller = controller.get()](not_null box) { + auto controller = std::make_unique( + base::lambda_guarded(this, [this, exception] { return _controller->exceptionBoxTitle(exception); }), + exceptionUsers(exception)); + auto initBox = [this, exception, controller = controller.get()](not_null box) { box->addButton(langFactory(lng_settings_save), base::lambda_guarded(this, [this, box, exception, controller] { - exceptionUsers(exception) = controller->getResult(); - exceptionLink(exception)->entity()->setText(exceptionLinkText(exception)); - auto removeFrom = ([exception] { - switch (exception) { - case Exception::Always: return Exception::Never; - case Exception::Never: return Exception::Always; - } - Unexpected("Invalid exception value."); - })(); - auto &removeFromUsers = exceptionUsers(removeFrom); - auto removedSome = false; - for (auto user : exceptionUsers(exception)) { - auto removedStart = std::remove(removeFromUsers.begin(), removeFromUsers.end(), user); - if (removedStart != removeFromUsers.end()) { - removeFromUsers.erase(removedStart, removeFromUsers.end()); - removedSome = true; - } - } - if (removedSome) { - exceptionLink(removeFrom)->entity()->setText(exceptionLinkText(removeFrom)); - } - box->closeBox(); - })); + exceptionUsers(exception) = controller->getResult(); + exceptionLink(exception)->entity()->setText(exceptionLinkText(exception)); + auto removeFrom = ([exception] { + switch (exception) { + case Exception::Always: return Exception::Never; + case Exception::Never: return Exception::Always; + } + Unexpected("Invalid exception value."); + })(); + auto &removeFromUsers = exceptionUsers(removeFrom); + auto removedSome = false; + for (auto user : exceptionUsers(exception)) { + auto removedStart = std::remove(removeFromUsers.begin(), removeFromUsers.end(), user); + if (removedStart != removeFromUsers.end()) { + removeFromUsers.erase(removedStart, removeFromUsers.end()); + removedSome = true; + } + } + if (removedSome) { + exceptionLink(removeFrom)->entity()->setText(exceptionLinkText(removeFrom)); + } + box->closeBox(); + })); box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); }); }; Ui::show(Box(std::move(controller), std::move(initBox)), KeepOtherLayers); @@ -246,7 +247,7 @@ style::margins EditPrivacyBox::exceptionLinkMargins() const { return st::editPrivacyLinkMargin; } -std::vector> &EditPrivacyBox::exceptionUsers(Exception exception) { +std::vector> &EditPrivacyBox::exceptionUsers(Exception exception) { switch (exception) { case Exception::Always: return _alwaysUsers; case Exception::Never: return _neverUsers; @@ -286,9 +287,8 @@ void EditPrivacyBox::createWidgets() { widget.create(this, text, Ui::FlatLabel::InitType::Simple, st); }; auto createExceptionLink = [this](Exception exception) { - exceptionLink(exception).create(this, object_ptr(this, exceptionLinkText(exception)), exceptionLinkMargins(), [this] { - resizeGetHeight(width()); - }); + exceptionLink(exception).create(this, object_ptr(this, exceptionLinkText(exception)), + exceptionLinkMargins(), [this] { resizeGetHeight(width()); }); exceptionLink(exception)->entity()->setClickedCallback([this, exception] { editExceptionUsers(exception); }); }; @@ -306,9 +306,9 @@ void EditPrivacyBox::createWidgets() { addButton(langFactory(lng_settings_save), [this] { auto someAreDisallowed = (_option != Option::Everyone) || !_neverUsers.empty(); _controller->confirmSave(someAreDisallowed, base::lambda_guarded(this, [this] { - Auth().api().savePrivacy(_controller->key(), collectResult()); - closeBox(); - })); + Auth().api().savePrivacy(_controller->key(), collectResult()); + closeBox(); + })); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); @@ -326,53 +326,54 @@ void EditPrivacyBox::createWidgets() { } void EditPrivacyBox::loadData() { - request(MTPaccount_GetPrivacy(_controller->key())).done([this](const MTPaccount_PrivacyRules &result) { - Expects(result.type() == mtpc_account_privacyRules); - auto &rules = result.c_account_privacyRules(); - App::feedUsers(rules.vusers); + request(MTPaccount_GetPrivacy(_controller->key())) + .done([this](const MTPaccount_PrivacyRules &result) { + Expects(result.type() == mtpc_account_privacyRules); + auto &rules = result.c_account_privacyRules(); + App::feedUsers(rules.vusers); - // This is simplified version of privacy rules interpretation. - // But it should be fine for all the apps that use the same subset of features. - auto optionSet = false; - auto setOption = [this, &optionSet](Option option) { - if (optionSet) return; - optionSet = true; - _option = option; - }; - auto feedRule = [this, &setOption](const MTPPrivacyRule &rule) { - switch (rule.type()) { - case mtpc_privacyValueAllowAll: setOption(Option::Everyone); break; - case mtpc_privacyValueAllowContacts: setOption(Option::Contacts); break; - case mtpc_privacyValueAllowUsers: { - auto &users = rule.c_privacyValueAllowUsers().vusers.v; - _alwaysUsers.reserve(_alwaysUsers.size() + users.size()); - for (auto &userId : users) { - auto user = App::user(UserId(userId.v)); - if (!base::contains(_neverUsers, user) && !base::contains(_alwaysUsers, user)) { - _alwaysUsers.push_back(user); - } - } - } break; - case mtpc_privacyValueDisallowContacts: // not supported, fall through - case mtpc_privacyValueDisallowAll: setOption(Option::Nobody); break; - case mtpc_privacyValueDisallowUsers: { - auto &users = rule.c_privacyValueDisallowUsers().vusers.v; - _neverUsers.reserve(_neverUsers.size() + users.size()); - for (auto &userId : users) { - auto user = App::user(UserId(userId.v)); - if (!base::contains(_alwaysUsers, user) && !base::contains(_neverUsers, user)) { - _neverUsers.push_back(user); - } - } - } break; - } - }; - for (auto &rule : rules.vrules.v) { - feedRule(rule); - } - feedRule(MTP_privacyValueDisallowAll()); // disallow by default. + // This is simplified version of privacy rules interpretation. + // But it should be fine for all the apps that use the same subset of features. + auto optionSet = false; + auto setOption = [this, &optionSet](Option option) { + if (optionSet) return; + optionSet = true; + _option = option; + }; + auto feedRule = [this, &setOption](const MTPPrivacyRule &rule) { + switch (rule.type()) { + case mtpc_privacyValueAllowAll: setOption(Option::Everyone); break; + case mtpc_privacyValueAllowContacts: setOption(Option::Contacts); break; + case mtpc_privacyValueAllowUsers: { + auto &users = rule.c_privacyValueAllowUsers().vusers.v; + _alwaysUsers.reserve(_alwaysUsers.size() + users.size()); + for (auto &userId : users) { + auto user = App::user(UserId(userId.v)); + if (!base::contains(_neverUsers, user) && !base::contains(_alwaysUsers, user)) { + _alwaysUsers.push_back(user); + } + } + } break; + case mtpc_privacyValueDisallowContacts: // not supported, fall through + case mtpc_privacyValueDisallowAll: setOption(Option::Nobody); break; + case mtpc_privacyValueDisallowUsers: { + auto &users = rule.c_privacyValueDisallowUsers().vusers.v; + _neverUsers.reserve(_neverUsers.size() + users.size()); + for (auto &userId : users) { + auto user = App::user(UserId(userId.v)); + if (!base::contains(_alwaysUsers, user) && !base::contains(_neverUsers, user)) { + _neverUsers.push_back(user); + } + } + } break; + } + }; + for (auto &rule : rules.vrules.v) { + feedRule(rule); + } + feedRule(MTP_privacyValueDisallowAll()); // disallow by default. - createWidgets(); - }).send(); + createWidgets(); + }) + .send(); } - diff --git a/Telegram/SourceFiles/boxes/edit_privacy_box.h b/Telegram/SourceFiles/boxes/edit_privacy_box.h index 46eaae29f..a6d4d8b7d 100644 --- a/Telegram/SourceFiles/boxes/edit_privacy_box.h +++ b/Telegram/SourceFiles/boxes/edit_privacy_box.h @@ -26,12 +26,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace Ui { class FlatLabel; class LinkButton; -template -class RadioenumGroup; -template -class Radioenum; -template -class WidgetSlideWrap; +template class RadioenumGroup; +template class Radioenum; +template class WidgetSlideWrap; } // namespace Ui class EditPrivacyBox : public BoxContent, private MTP::Sender { @@ -81,10 +78,9 @@ public: EditPrivacyBox *_view = nullptr; friend class EditPrivacyBox; - }; - EditPrivacyBox(QWidget*, std::unique_ptr controller); + EditPrivacyBox(QWidget *, std::unique_ptr controller); protected: void prepare() override; @@ -102,7 +98,7 @@ private: void editExceptionUsers(Exception exception); QString exceptionLinkText(Exception exception); - std::vector> &exceptionUsers(Exception exception); + std::vector> &exceptionUsers(Exception exception); object_ptr> &exceptionLink(Exception exception); std::unique_ptr _controller; @@ -110,17 +106,16 @@ private: std::shared_ptr> _optionGroup; object_ptr _loading; - object_ptr _description = { nullptr }; - object_ptr> _everyone = { nullptr }; - object_ptr> _contacts = { nullptr }; - object_ptr> _nobody = { nullptr }; - object_ptr _warning = { nullptr }; - object_ptr _exceptionsTitle = { nullptr }; - object_ptr> _alwaysLink = { nullptr }; - object_ptr> _neverLink = { nullptr }; - object_ptr _exceptionsDescription = { nullptr }; - - std::vector> _alwaysUsers; - std::vector> _neverUsers; + object_ptr _description = {nullptr}; + object_ptr> _everyone = {nullptr}; + object_ptr> _contacts = {nullptr}; + object_ptr> _nobody = {nullptr}; + object_ptr _warning = {nullptr}; + object_ptr _exceptionsTitle = {nullptr}; + object_ptr> _alwaysLink = {nullptr}; + object_ptr> _neverLink = {nullptr}; + object_ptr _exceptionsDescription = {nullptr}; + std::vector> _alwaysUsers; + std::vector> _neverUsers; }; diff --git a/Telegram/SourceFiles/boxes/language_box.cpp b/Telegram/SourceFiles/boxes/language_box.cpp index 0ce1be712..74a08b8fa 100644 --- a/Telegram/SourceFiles/boxes/language_box.cpp +++ b/Telegram/SourceFiles/boxes/language_box.cpp @@ -19,20 +19,20 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/language_box.h" -#include "lang/lang_keys.h" -#include "ui/widgets/checkbox.h" -#include "ui/widgets/buttons.h" -#include "storage/localstorage.h" #include "boxes/confirm_box.h" +#include "lang/lang_cloud_manager.h" +#include "lang/lang_instance.h" +#include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" -#include "lang/lang_instance.h" -#include "lang/lang_cloud_manager.h" +#include "storage/localstorage.h" #include "styles/style_boxes.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" class LanguageBox::Inner : public TWidget, private base::Subscriber { public: - Inner(QWidget *parent, not_null languages); + Inner(QWidget *parent, not_null languages); void setSelected(int index); void refresh(); @@ -41,14 +41,14 @@ private: void activateCurrent(); void languageChanged(int languageIndex); - not_null _languages; + not_null _languages; std::shared_ptr _group; std::vector> _buttons; - }; -LanguageBox::Inner::Inner(QWidget *parent, not_null languages) : TWidget(parent) -, _languages(languages) { +LanguageBox::Inner::Inner(QWidget *parent, not_null languages) + : TWidget(parent) + , _languages(languages) { _group = std::make_shared(0); _group->setChangedCallback([this](int value) { languageChanged(value); }); subscribe(Lang::Current().updated(), [this] { @@ -107,16 +107,12 @@ void LanguageBox::Inner::activateCurrent() { void LanguageBox::prepare() { refreshLang(); - subscribe(Lang::Current().updated(), [this] { - refreshLang(); - }); + subscribe(Lang::Current().updated(), [this] { refreshLang(); }); _inner = setInnerWidget(object_ptr(this, &_languages), st::boxLayerScroll); refresh(); - subscribe(Lang::CurrentCloudManager().languageListChanged(), [this] { - refresh(); - }); + subscribe(Lang::CurrentCloudManager().languageListChanged(), [this] { refresh(); }); } void LanguageBox::refreshLang() { @@ -141,9 +137,10 @@ void LanguageBox::refreshLanguages() { _languages.reserve(list.size() + 1); auto currentId = Lang::Current().id(); auto currentIndex = -1; - _languages.push_back({ qsl("en"), qsl("English"), qsl("English") }); + _languages.push_back({qsl("en"), qsl("English"), qsl("English")}); for (auto &language : list) { - auto isCurrent = (language.id == currentId) || (language.id == Lang::DefaultLanguageId() && currentId.isEmpty()); + auto isCurrent = + (language.id == currentId) || (language.id == Lang::DefaultLanguageId() && currentId.isEmpty()); if (language.id != qstr("en")) { if (isCurrent) { currentIndex = _languages.size(); @@ -154,11 +151,11 @@ void LanguageBox::refreshLanguages() { } } if (currentId == qstr("custom")) { - _languages.insert(_languages.begin(), { currentId, qsl("Custom LangPack"), qsl("Custom LangPack") }); + _languages.insert(_languages.begin(), {currentId, qsl("Custom LangPack"), qsl("Custom LangPack")}); currentIndex = 0; } else if (currentIndex < 0) { currentIndex = _languages.size(); - _languages.push_back({ currentId, lang(lng_language_name), lang(lng_language_name) }); + _languages.push_back({currentId, lang(lng_language_name), lang(lng_language_name)}); } _inner->setSelected(currentIndex); } diff --git a/Telegram/SourceFiles/boxes/language_box.h b/Telegram/SourceFiles/boxes/language_box.h index a34505ebd..f174fc14e 100644 --- a/Telegram/SourceFiles/boxes/language_box.h +++ b/Telegram/SourceFiles/boxes/language_box.h @@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include "lang/lang_cloud_manager.h" #include "boxes/abstract_box.h" +#include "lang/lang_cloud_manager.h" #include "mtproto/sender.h" namespace Ui { @@ -29,10 +29,9 @@ class RadiobuttonGroup; class Radiobutton; } // namespace Ui -class LanguageBox : public BoxContent, private MTP::Sender { +class LanguageBox : public BoxContent, private MTP::Sender { public: - LanguageBox(QWidget*) { - } + LanguageBox(QWidget*) {} protected: void prepare() override; @@ -48,5 +47,4 @@ private: class Inner; QPointer _inner; - }; diff --git a/Telegram/SourceFiles/boxes/local_storage_box.cpp b/Telegram/SourceFiles/boxes/local_storage_box.cpp index 1b744616c..a1549e0b6 100644 --- a/Telegram/SourceFiles/boxes/local_storage_box.cpp +++ b/Telegram/SourceFiles/boxes/local_storage_box.cpp @@ -20,19 +20,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/local_storage_box.h" -#include "styles/style_boxes.h" -#include "ui/widgets/buttons.h" -#include "storage/localstorage.h" -#include "lang/lang_keys.h" -#include "mainwindow.h" +#include "app.h" // For App::wnd #include "auth_session.h" #include "facades.h" -#include "app.h" // For App::wnd +#include "lang/lang_keys.h" #include "layout.h" // For formatSizeText +#include "mainwindow.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" +#include "ui/widgets/buttons.h" LocalStorageBox::LocalStorageBox(QWidget *parent) -: _clear(this, lang(lng_local_storage_clear), st::boxLinkButton) { -} + : _clear(this, lang(lng_local_storage_clear), st::boxLinkButton) {} void LocalStorageBox::prepare() { setTitle(langFactory(lng_local_storage_title)); @@ -87,12 +86,15 @@ void LocalStorageBox::paintEvent(QPaintEvent *e) { checkLocalStoredCounts(); auto top = st::localStorageBoxSkip; if (_imagesCount > 0) { - auto text = lng_settings_images_cached(lt_count, _imagesCount, lt_size, formatSizeText(Local::storageImagesSize() + Local::storageStickersSize() + Local::storageWebFilesSize())); + auto text = lng_settings_images_cached( + lt_count, _imagesCount, lt_size, + formatSizeText(Local::storageImagesSize() + Local::storageStickersSize() + Local::storageWebFilesSize())); p.drawTextLeft(st::boxPadding.left(), top, width(), text); top += st::boxTextFont->height + st::localStorageBoxSkip; } if (_audiosCount > 0) { - auto text = lng_settings_audios_cached(lt_count, _audiosCount, lt_size, formatSizeText(Local::storageAudiosSize())); + auto text = + lng_settings_audios_cached(lt_count, _audiosCount, lt_size, formatSizeText(Local::storageAudiosSize())); p.drawTextLeft(st::boxPadding.left(), top, width(), text); top += st::boxTextFont->height + st::localStorageBoxSkip; } else if (_imagesCount <= 0) { diff --git a/Telegram/SourceFiles/boxes/local_storage_box.h b/Telegram/SourceFiles/boxes/local_storage_box.h index 0b194d78d..f04771e29 100644 --- a/Telegram/SourceFiles/boxes/local_storage_box.h +++ b/Telegram/SourceFiles/boxes/local_storage_box.h @@ -30,7 +30,7 @@ class LocalStorageBox : public BoxContent { Q_OBJECT public: - LocalStorageBox(QWidget*); + LocalStorageBox(QWidget *); private slots: void onTempDirCleared(int task); @@ -58,5 +58,4 @@ private: int _imagesCount = -1; int _audiosCount = -1; - }; diff --git a/Telegram/SourceFiles/boxes/mute_settings_box.cpp b/Telegram/SourceFiles/boxes/mute_settings_box.cpp index 0a1827142..9f330f5ca 100644 --- a/Telegram/SourceFiles/boxes/mute_settings_box.cpp +++ b/Telegram/SourceFiles/boxes/mute_settings_box.cpp @@ -29,15 +29,14 @@ void MuteSettingsBox::prepare() { object_ptr title(this, st::muteChatTitle); title->setText(App::peerName(_peer, true)); - title->moveToLeft(st::boxPadding.left(), - y + icon->height() / 2 - title->height() / 2); + title->moveToLeft(st::boxPadding.left(), y + icon->height() / 2 - title->height() / 2); // the icon is always higher than this chat title y += icon->height() + st::boxMediumSkip; - const int FOREVER = 8760; // in fact, this is mute only for 1 year + const int FOREVER = 8760; // in fact, this is mute only for 1 year auto group = std::make_shared(FOREVER); y += st::boxOptionListPadding.top(); - for (int value : { 1, 4, 18, 72, FOREVER }) { // periods in hours + for (int value : {1, 4, 18, 72, FOREVER}) { // periods in hours QString text; if (value < 24) { text = lng_mute_duration_hours(lt_count, value); @@ -53,8 +52,7 @@ void MuteSettingsBox::prepare() { y += st::boxOptionListPadding.bottom() - st::boxOptionListSkip + st::defaultCheckbox.margin.bottom(); addButton(langFactory(lng_box_ok), [this, group] { - App::main()->updateNotifySetting(_peer, NotifySettingSetMuted, - SilentNotifiesDontChange, group->value() * 3600); + App::main()->updateNotifySetting(_peer, NotifySettingSetMuted, SilentNotifiesDontChange, group->value() * 3600); closeBox(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); diff --git a/Telegram/SourceFiles/boxes/mute_settings_box.h b/Telegram/SourceFiles/boxes/mute_settings_box.h index dc689b1fb..321bc7622 100644 --- a/Telegram/SourceFiles/boxes/mute_settings_box.h +++ b/Telegram/SourceFiles/boxes/mute_settings_box.h @@ -14,15 +14,14 @@ class MuteSettingsBox : public BoxContent { Q_OBJECT - public: - MuteSettingsBox(QWidget *parent, not_null peer) - : _peer(peer) { - } +public: + MuteSettingsBox(QWidget *parent, not_null peer) + : _peer(peer) {} - protected: +protected: void prepare() override; - private: - not_null _peer; +private: + not_null _peer; }; // vi: ts=4 tw=80 diff --git a/Telegram/SourceFiles/boxes/notifications_box.cpp b/Telegram/SourceFiles/boxes/notifications_box.cpp index b30f464f2..1470a4d60 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.cpp +++ b/Telegram/SourceFiles/boxes/notifications_box.cpp @@ -20,19 +20,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/notifications_box.h" +#include "app.h" // For App::pixmapFromImageInPlace +#include "auth_session.h" #include "config.h" #include "lang/lang_keys.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/discrete_sliders.h" +#include "messenger.h" +#include "platform/platform_specific.h" +#include "storage/localstorage.h" #include "styles/style_boxes.h" #include "styles/style_dialogs.h" #include "styles/style_window.h" -#include "messenger.h" -#include "storage/localstorage.h" -#include "auth_session.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/discrete_sliders.h" #include "window/notifications_manager.h" -#include "platform/platform_specific.h" -#include "app.h" // For App::pixmapFromImageInPlace namespace { @@ -44,12 +44,14 @@ using ChangeType = Window::Notifications::ChangeType; class NotificationsBox::SampleWidget : public QWidget { public: - SampleWidget(NotificationsBox *owner, const QPixmap &cache) : QWidget(nullptr) - , _owner(owner) - , _cache(cache) { + SampleWidget(NotificationsBox *owner, const QPixmap &cache) + : QWidget(nullptr) + , _owner(owner) + , _cache(cache) { resize(cache.width() / cache.devicePixelRatio(), cache.height() / cache.devicePixelRatio()); - setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::WindowStaysOnTopHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint | Qt::Tool); + setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::WindowStaysOnTopHint | + Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint | Qt::Tool); setAttribute(Qt::WA_MacAlwaysShowToolWindow); setAttribute(Qt::WA_TransparentForMouseEvents); setAttribute(Qt::WA_OpaquePaintEvent); @@ -111,14 +113,12 @@ private: Animation _opacity; bool _hiding = false; bool _deleted = false; - }; NotificationsBox::NotificationsBox(QWidget *parent) -: _chosenCorner(Global::NotificationsCorner()) -, _oldCount(snap(Global::NotificationsCount(), 1, kMaxNotificationsCount)) -, _countSlider(this) { -} + : _chosenCorner(Global::NotificationsCorner()) + , _oldCount(snap(Global::NotificationsCount(), 1, kMaxNotificationsCount)) + , _countSlider(this) {} void NotificationsBox::prepare() { addButton(langFactory(lng_close), [this] { closeBox(); }); @@ -151,7 +151,8 @@ void NotificationsBox::paintEvent(QPaintEvent *e) { p.drawTextLeft(contentLeft, st::boxTitlePosition.y(), width(), lang(lng_settings_notifications_position)); auto screenRect = getScreenRect(); - p.fillRect(screenRect.x(), screenRect.y(), st::notificationsBoxScreenSize.width(), st::notificationsBoxScreenSize.height(), st::notificationsBoxScreenBg); + p.fillRect(screenRect.x(), screenRect.y(), st::notificationsBoxScreenSize.width(), + st::notificationsBoxScreenSize.height(), st::notificationsBoxScreenBg); auto monitorTop = st::notificationsBoxMonitorTop; st::notificationsBoxMonitor.paint(p, contentLeft, monitorTop, width()); @@ -160,8 +161,12 @@ void NotificationsBox::paintEvent(QPaintEvent *e) { auto screenCorner = static_cast(corner); auto isLeft = Notify::IsLeftCorner(screenCorner); auto isTop = Notify::IsTopCorner(screenCorner); - auto sampleLeft = isLeft ? (screenRect.x() + st::notificationsSampleSkip) : (screenRect.x() + screenRect.width() - st::notificationsSampleSkip - st::notificationSampleSize.width()); - auto sampleTop = isTop ? (screenRect.y() + st::notificationsSampleTopSkip) : (screenRect.y() + screenRect.height() - st::notificationsSampleBottomSkip - st::notificationSampleSize.height()); + auto sampleLeft = isLeft ? (screenRect.x() + st::notificationsSampleSkip) : + (screenRect.x() + screenRect.width() - st::notificationsSampleSkip - + st::notificationSampleSize.width()); + auto sampleTop = isTop ? (screenRect.y() + st::notificationsSampleTopSkip) : + (screenRect.y() + screenRect.height() - st::notificationsSampleBottomSkip - + st::notificationSampleSize.height()); if (corner == static_cast(_chosenCorner)) { auto count = currentCount(); for (int i = 0; i != kMaxNotificationsCount; ++i) { @@ -209,14 +214,16 @@ int NotificationsBox::getContentLeft() const { QRect NotificationsBox::getScreenRect() const { auto screenLeft = (width() - st::notificationsBoxScreenSize.width()) / 2; auto screenTop = st::notificationsBoxMonitorTop + st::notificationsBoxScreenTop; - return QRect(screenLeft, screenTop, st::notificationsBoxScreenSize.width(), st::notificationsBoxScreenSize.height()); + return QRect(screenLeft, screenTop, st::notificationsBoxScreenSize.width(), + st::notificationsBoxScreenSize.height()); } void NotificationsBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); auto screenRect = getScreenRect(); - auto sliderTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop + st::notificationsBoxCountTop; + auto sliderTop = + screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop + st::notificationsBoxCountTop; auto contentLeft = getContentLeft(); _countSlider->resizeToWidth(width() - 2 * contentLeft); _countSlider->move(contentLeft, sliderTop); @@ -225,7 +232,8 @@ void NotificationsBox::resizeEvent(QResizeEvent *e) { void NotificationsBox::prepareNotificationSampleSmall() { auto width = st::notificationSampleSize.width(); auto height = st::notificationSampleSize.height(); - auto sampleImage = QImage(width * cIntRetinaFactor(), height * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + auto sampleImage = + QImage(width * cIntRetinaFactor(), height * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); sampleImage.setDevicePixelRatio(cRetinaFactor()); sampleImage.fill(st::notificationBg->c); { @@ -262,7 +270,9 @@ void NotificationsBox::prepareNotificationSampleSmall() { void NotificationsBox::prepareNotificationSampleUserpic() { if (_notificationSampleUserpic.isNull()) { - _notificationSampleUserpic = App::pixmapFromImageInPlace(Messenger::Instance().logoNoMargin().scaled(st::notifyPhotoSize * cIntRetinaFactor(), st::notifyPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + _notificationSampleUserpic = App::pixmapFromImageInPlace(Messenger::Instance().logoNoMargin().scaled( + st::notifyPhotoSize * cIntRetinaFactor(), st::notifyPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, + Qt::SmoothTransformation)); _notificationSampleUserpic.setDevicePixelRatio(cRetinaFactor()); } } @@ -276,20 +286,24 @@ void NotificationsBox::prepareNotificationSampleLarge() { Painter p(&sampleImage); p.fillRect(0, 0, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); p.fillRect(w - st::notifyBorderWidth, 0, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); - p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, + st::notifyBorder->b); p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); prepareNotificationSampleUserpic(); p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), _notificationSampleUserpic); - int itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; + int itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - + st::notifyClose.width; - auto rectForName = rtlrect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height, w); + auto rectForName = rtlrect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, + itemWidth, st::msgNameFont->height, w); auto notifyText = st::dialogsTextFont->elided(lang(lng_notification_sample), itemWidth); p.setFont(st::dialogsTextFont); p.setPen(st::dialogsTextFgService); - p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dialogsTextFont->ascent, notifyText); + p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, + st::notifyItemTop + st::msgNameFont->height + st::dialogsTextFont->ascent, notifyText); p.setPen(st::dialogsNameFg); p.setFont(st::msgNameFont); @@ -297,7 +311,9 @@ void NotificationsBox::prepareNotificationSampleLarge() { auto notifyTitle = st::msgNameFont->elided(str_const_toString(AppName), rectForName.width()); p.drawText(rectForName.left(), rectForName.top() + st::msgNameFont->ascent, notifyTitle); - st::notifyClose.icon.paint(p, w - st::notifyClosePos.x() - st::notifyClose.width + st::notifyClose.iconPosition.x(), st::notifyClosePos.y() + st::notifyClose.iconPosition.y(), w); + st::notifyClose.icon.paint( + p, w - st::notifyClosePos.x() - st::notifyClose.width + st::notifyClose.iconPosition.x(), + st::notifyClosePos.y() + st::notifyClose.iconPosition.y(), w); } _notificationSampleLarge = App::pixmapFromImageInPlace(std::move(sampleImage)); @@ -322,9 +338,12 @@ void NotificationsBox::mouseMoveEvent(QMouseEvent *e) { auto cornerWidth = screenRect.width() / 3; auto cornerHeight = screenRect.height() / 3; auto topLeft = rtlrect(screenRect.x(), screenRect.y(), cornerWidth, cornerHeight, width()); - auto topRight = rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y(), cornerWidth, cornerHeight, width()); - auto bottomRight = rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width()); - auto bottomLeft = rtlrect(screenRect.x(), screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width()); + auto topRight = + rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y(), cornerWidth, cornerHeight, width()); + auto bottomRight = rtlrect(screenRect.x() + screenRect.width() - cornerWidth, + screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width()); + auto bottomLeft = rtlrect(screenRect.x(), screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, + cornerHeight, width()); if (topLeft.contains(e->pos())) { setOverCorner(Notify::ScreenCorner::TopLeft); } else if (topRight.contains(e->pos())) { @@ -347,9 +366,7 @@ void NotificationsBox::setOverCorner(Notify::ScreenCorner corner) { if (corner == _overCorner) { return; } - for_const (auto widget, _cornerSamples[static_cast(_overCorner)]) { - widget->hideFast(); - } + for_const (auto widget, _cornerSamples[static_cast(_overCorner)]) { widget->hideFast(); } } else { _isOverCorner = true; setCursor(style::cur_pointer); @@ -369,8 +386,10 @@ void NotificationsBox::setOverCorner(Notify::ScreenCorner corner) { auto r = psDesktopRect(); auto isLeft = Notify::IsLeftCorner(_overCorner); auto isTop = Notify::IsTopCorner(_overCorner); - auto sampleLeft = (isLeft == rtl()) ? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX) : (r.x() + st::notifyDeltaX); - auto sampleTop = isTop ? (r.y() + st::notifyDeltaY) : (r.y() + r.height() - st::notifyDeltaY - st::notifyMinHeight); + auto sampleLeft = + (isLeft == rtl()) ? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX) : (r.x() + st::notifyDeltaX); + auto sampleTop = + isTop ? (r.y() + st::notifyDeltaY) : (r.y() + r.height() - st::notifyDeltaY - st::notifyMinHeight); for (int i = samplesLeave; i != samplesNeeded; ++i) { auto widget = std::make_unique(this, _notificationSampleLarge); widget->move(sampleLeft, sampleTop + (isTop ? 1 : -1) * i * (st::notifyMinHeight + st::notifyDeltaY)); @@ -392,9 +411,7 @@ void NotificationsBox::clearOverCorner() { Auth().notifications().settingsChanged().notify(ChangeType::DemoIsShown); for_const (auto &samples, _cornerSamples) { - for_const (auto widget, samples) { - widget->hideFast(); - } + for_const (auto widget, samples) { widget->hideFast(); } } } } @@ -424,9 +441,7 @@ void NotificationsBox::mouseReleaseEvent(QMouseEvent *e) { NotificationsBox::~NotificationsBox() { for_const (auto &samples, _cornerSamples) { - for_const (auto widget, samples) { - widget->detach(); - } + for_const (auto widget, samples) { widget->detach(); } } clearOverCorner(); } diff --git a/Telegram/SourceFiles/boxes/notifications_box.h b/Telegram/SourceFiles/boxes/notifications_box.h index 1149ce481..52cc3d57f 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.h +++ b/Telegram/SourceFiles/boxes/notifications_box.h @@ -30,7 +30,7 @@ class SettingsSlider; class NotificationsBox : public BoxContent { public: - NotificationsBox(QWidget*); + NotificationsBox(QWidget *); ~NotificationsBox(); protected: @@ -74,6 +74,5 @@ private: int _oldCount; object_ptr _countSlider; - QVector _cornerSamples[4]; - + QVector _cornerSamples[4]; }; diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp index 91494147e..963aba772 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.cpp +++ b/Telegram/SourceFiles/boxes/passcode_box.cpp @@ -20,39 +20,42 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/passcode_box.h" -#include "lang/lang_keys.h" #include "boxes/confirm_box.h" +#include "facades.h" +#include "lang/lang_keys.h" #include "mainwindow.h" #include "storage/localstorage.h" #include "styles/style_boxes.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" -#include "facades.h" -PasscodeBox::PasscodeBox(QWidget*, bool turningOff) -: _turningOff(turningOff) -, _about(st::boxWidth - st::boxPadding.left() * 1.5) -, _oldPasscode(this, st::defaultInputField, langFactory(lng_passcode_enter_old)) -, _newPasscode(this, st::defaultInputField, langFactory(Global::LocalPasscode() ? lng_passcode_enter_new : lng_passcode_enter_first)) -, _reenterPasscode(this, st::defaultInputField, langFactory(lng_passcode_confirm_new)) -, _passwordHint(this, st::defaultInputField, langFactory(lng_cloud_password_hint)) -, _recoverEmail(this, st::defaultInputField, langFactory(lng_cloud_password_email)) -, _recover(this, lang(lng_signin_recover)) { -} +PasscodeBox::PasscodeBox(QWidget *, bool turningOff) + : _turningOff(turningOff) + , _about(st::boxWidth - st::boxPadding.left() * 1.5) + , _oldPasscode(this, st::defaultInputField, langFactory(lng_passcode_enter_old)) + , _newPasscode(this, st::defaultInputField, + langFactory(Global::LocalPasscode() ? lng_passcode_enter_new : lng_passcode_enter_first)) + , _reenterPasscode(this, st::defaultInputField, langFactory(lng_passcode_confirm_new)) + , _passwordHint(this, st::defaultInputField, langFactory(lng_cloud_password_hint)) + , _recoverEmail(this, st::defaultInputField, langFactory(lng_cloud_password_email)) + , _recover(this, lang(lng_signin_recover)) {} -PasscodeBox::PasscodeBox(QWidget*, const QByteArray &newSalt, const QByteArray &curSalt, bool hasRecovery, const QString &hint, bool turningOff) -: _turningOff(turningOff) -, _cloudPwd(true) -, _newSalt(newSalt) -, _curSalt(curSalt) -, _hasRecovery(hasRecovery) -, _about(st::boxWidth - st::boxPadding.left() * 1.5) -, _oldPasscode(this, st::defaultInputField, langFactory(lng_cloud_password_enter_old)) -, _newPasscode(this, st::defaultInputField, langFactory(curSalt.isEmpty() ? lng_cloud_password_enter_first : lng_cloud_password_enter_new)) -, _reenterPasscode(this, st::defaultInputField, langFactory(lng_cloud_password_confirm_new)) -, _passwordHint(this, st::defaultInputField, langFactory(curSalt.isEmpty() ? lng_cloud_password_hint : lng_cloud_password_change_hint)) -, _recoverEmail(this, st::defaultInputField, langFactory(lng_cloud_password_email)) -, _recover(this, lang(lng_signin_recover)) { +PasscodeBox::PasscodeBox(QWidget *, const QByteArray &newSalt, const QByteArray &curSalt, bool hasRecovery, + const QString &hint, bool turningOff) + : _turningOff(turningOff) + , _cloudPwd(true) + , _newSalt(newSalt) + , _curSalt(curSalt) + , _hasRecovery(hasRecovery) + , _about(st::boxWidth - st::boxPadding.left() * 1.5) + , _oldPasscode(this, st::defaultInputField, langFactory(lng_cloud_password_enter_old)) + , _newPasscode(this, st::defaultInputField, + langFactory(curSalt.isEmpty() ? lng_cloud_password_enter_first : lng_cloud_password_enter_new)) + , _reenterPasscode(this, st::defaultInputField, langFactory(lng_cloud_password_confirm_new)) + , _passwordHint(this, st::defaultInputField, + langFactory(curSalt.isEmpty() ? lng_cloud_password_hint : lng_cloud_password_change_hint)) + , _recoverEmail(this, st::defaultInputField, langFactory(lng_cloud_password_email)) + , _recover(this, lang(lng_signin_recover)) { if (!hint.isEmpty()) _hintText.setText(st::passcodeTextStyle, lng_signin_hint(lt_password_hint, hint)); } @@ -65,17 +68,30 @@ void PasscodeBox::prepare() { if (_turningOff) { _oldPasscode->show(); setTitle(langFactory(_cloudPwd ? lng_cloud_password_remove : lng_passcode_remove)); - setDimensions(st::boxWidth, st::passcodePadding.top() + _oldPasscode->height() + st::passcodeTextLine + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeTextLine : 0) + st::passcodeAboutSkip + _aboutHeight + st::passcodePadding.bottom()); + setDimensions(st::boxWidth, st::passcodePadding.top() + _oldPasscode->height() + st::passcodeTextLine + + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeTextLine : 0) + + st::passcodeAboutSkip + _aboutHeight + st::passcodePadding.bottom()); } else { auto has = _cloudPwd ? (!_curSalt.isEmpty()) : Global::LocalPasscode(); if (has) { _oldPasscode->show(); setTitle(langFactory(_cloudPwd ? lng_cloud_password_change : lng_passcode_change)); - setDimensions(st::boxWidth, st::passcodePadding.top() + _oldPasscode->height() + st::passcodeTextLine + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeTextLine : 0) + _newPasscode->height() + st::passcodeLittleSkip + _reenterPasscode->height() + st::passcodeSkip + (_cloudPwd ? _passwordHint->height() + st::passcodeLittleSkip : 0) + st::passcodeAboutSkip + _aboutHeight + st::passcodePadding.bottom()); + setDimensions(st::boxWidth, st::passcodePadding.top() + _oldPasscode->height() + st::passcodeTextLine + + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeTextLine : 0) + + _newPasscode->height() + st::passcodeLittleSkip + + _reenterPasscode->height() + st::passcodeSkip + + (_cloudPwd ? _passwordHint->height() + st::passcodeLittleSkip : 0) + + st::passcodeAboutSkip + _aboutHeight + st::passcodePadding.bottom()); } else { _oldPasscode->hide(); setTitle(langFactory(_cloudPwd ? lng_cloud_password_create : lng_passcode_create)); - setDimensions(st::boxWidth, st::passcodePadding.top() + _newPasscode->height() + st::passcodeLittleSkip + _reenterPasscode->height() + st::passcodeSkip + (_cloudPwd ? _passwordHint->height() + st::passcodeLittleSkip : 0) + st::passcodeAboutSkip + _aboutHeight + (_cloudPwd ? (st::passcodeLittleSkip + _recoverEmail->height() + st::passcodeSkip) : st::passcodePadding.bottom())); + setDimensions(st::boxWidth, + st::passcodePadding.top() + _newPasscode->height() + st::passcodeLittleSkip + + _reenterPasscode->height() + st::passcodeSkip + + (_cloudPwd ? _passwordHint->height() + st::passcodeLittleSkip : 0) + + st::passcodeAboutSkip + _aboutHeight + + (_cloudPwd ? (st::passcodeLittleSkip + _recoverEmail->height() + st::passcodeSkip) : + st::passcodePadding.bottom())); } } @@ -143,27 +159,40 @@ void PasscodeBox::paintEvent(QPaintEvent *e) { Painter p(this); qint32 w = st::boxWidth - st::boxPadding.left() * 1.5; - qint32 abouty = (_passwordHint->isHidden() ? ((_reenterPasscode->isHidden() ? (_oldPasscode->y() + (_hasRecovery && !_hintText.isEmpty() ? st::passcodeTextLine : 0)) : _reenterPasscode->y()) + st::passcodeSkip) : _passwordHint->y()) + _oldPasscode->height() + st::passcodeLittleSkip + st::passcodeAboutSkip; + qint32 abouty = (_passwordHint->isHidden() ? + ((_reenterPasscode->isHidden() ? + (_oldPasscode->y() + (_hasRecovery && !_hintText.isEmpty() ? st::passcodeTextLine : 0)) : + _reenterPasscode->y()) + + st::passcodeSkip) : + _passwordHint->y()) + + _oldPasscode->height() + st::passcodeLittleSkip + st::passcodeAboutSkip; p.setPen(st::boxTextFg); _about.drawLeft(p, st::boxPadding.left(), abouty, w, width()); if (!_hintText.isEmpty() && _oldError.isEmpty()) { - _hintText.drawLeftElided(p, st::boxPadding.left(), _oldPasscode->y() + _oldPasscode->height() + ((st::passcodeTextLine - st::normalFont->height) / 2), w, width(), 1, style::al_topleft); + _hintText.drawLeftElided(p, st::boxPadding.left(), + _oldPasscode->y() + _oldPasscode->height() + + ((st::passcodeTextLine - st::normalFont->height) / 2), + w, width(), 1, style::al_topleft); } if (!_oldError.isEmpty()) { p.setPen(st::boxTextFgError); - p.drawText(QRect(st::boxPadding.left(), _oldPasscode->y() + _oldPasscode->height(), w, st::passcodeTextLine), _oldError, style::al_left); + p.drawText(QRect(st::boxPadding.left(), _oldPasscode->y() + _oldPasscode->height(), w, st::passcodeTextLine), + _oldError, style::al_left); } if (!_newError.isEmpty()) { p.setPen(st::boxTextFgError); - p.drawText(QRect(st::boxPadding.left(), _reenterPasscode->y() + _reenterPasscode->height(), w, st::passcodeTextLine), _newError, style::al_left); + p.drawText( + QRect(st::boxPadding.left(), _reenterPasscode->y() + _reenterPasscode->height(), w, st::passcodeTextLine), + _newError, style::al_left); } if (!_emailError.isEmpty()) { p.setPen(st::boxTextFgError); - p.drawText(QRect(st::boxPadding.left(), _recoverEmail->y() + _recoverEmail->height(), w, st::passcodeTextLine), _emailError, style::al_left); + p.drawText(QRect(st::boxPadding.left(), _recoverEmail->y() + _recoverEmail->height(), w, st::passcodeTextLine), + _emailError, style::al_left); } } @@ -175,16 +204,28 @@ void PasscodeBox::resizeEvent(QResizeEvent *e) { _oldPasscode->resize(w, _oldPasscode->height()); _oldPasscode->moveToLeft(st::boxPadding.left(), st::passcodePadding.top()); _newPasscode->resize(w, _newPasscode->height()); - _newPasscode->moveToLeft(st::boxPadding.left(), _oldPasscode->y() + ((_turningOff || has) ? (_oldPasscode->height() + st::passcodeTextLine + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeTextLine : 0)) : 0)); + _newPasscode->moveToLeft(st::boxPadding.left(), + _oldPasscode->y() + + ((_turningOff || has) ? + (_oldPasscode->height() + st::passcodeTextLine + + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeTextLine : 0)) : + 0)); _reenterPasscode->resize(w, _reenterPasscode->height()); - _reenterPasscode->moveToLeft(st::boxPadding.left(), _newPasscode->y() + _newPasscode->height() + st::passcodeLittleSkip); + _reenterPasscode->moveToLeft(st::boxPadding.left(), + _newPasscode->y() + _newPasscode->height() + st::passcodeLittleSkip); _passwordHint->resize(w, _passwordHint->height()); - _passwordHint->moveToLeft(st::boxPadding.left(), _reenterPasscode->y() + _reenterPasscode->height() + st::passcodeSkip); + _passwordHint->moveToLeft(st::boxPadding.left(), + _reenterPasscode->y() + _reenterPasscode->height() + st::passcodeSkip); _recoverEmail->resize(w, _passwordHint->height()); - _recoverEmail->moveToLeft(st::boxPadding.left(), _passwordHint->y() + _passwordHint->height() + st::passcodeLittleSkip + _aboutHeight + st::passcodeLittleSkip); + _recoverEmail->moveToLeft(st::boxPadding.left(), _passwordHint->y() + _passwordHint->height() + + st::passcodeLittleSkip + _aboutHeight + + st::passcodeLittleSkip); if (!_recover->isHidden()) { - _recover->moveToLeft(st::boxPadding.left(), _oldPasscode->y() + _oldPasscode->height() + (_hintText.isEmpty() ? ((st::passcodeTextLine - _recover->height()) / 2) : st::passcodeTextLine)); + _recover->moveToLeft( + st::boxPadding.left(), + _oldPasscode->y() + _oldPasscode->height() + + (_hintText.isEmpty() ? ((st::passcodeTextLine - _recover->height()) / 2) : st::passcodeTextLine)); } } @@ -201,7 +242,9 @@ void PasscodeBox::setInnerFocus() { void PasscodeBox::setPasswordDone(const MTPBool &result) { _setRequest = 0; emit reloadPassword(); - auto text = lang(_reenterPasscode->isHidden() ? lng_cloud_password_removed : (_oldPasscode->isHidden() ? lng_cloud_password_was_set : lng_cloud_password_updated)); + auto text = lang(_reenterPasscode->isHidden() ? + lng_cloud_password_removed : + (_oldPasscode->isHidden() ? lng_cloud_password_was_set : lng_cloud_password_updated)); Ui::show(Box(text)); } @@ -319,9 +362,10 @@ void PasscodeBox::onSave(bool force) { } if (!_recoverEmail->isHidden() && email.isEmpty() && !force) { _skipEmailWarning = true; - _replacedBy = Ui::show(Box(lang(lng_cloud_password_about_recover), lang(lng_cloud_password_skip_email), st::attentionBoxButton, base::lambda_guarded(this, [this] { - onSave(true); - })), KeepOtherLayers); + _replacedBy = + Ui::show(Box(lang(lng_cloud_password_about_recover), lang(lng_cloud_password_skip_email), + st::attentionBoxButton, base::lambda_guarded(this, [this] { onSave(true); })), + KeepOtherLayers); } else { QByteArray newPasswordData = pwd.isEmpty() ? QByteArray() : (_newSalt + pwd.toUtf8() + _newSalt); QByteArray newPasswordHash = pwd.isEmpty() ? QByteArray() : QByteArray(32, Qt::Uninitialized); @@ -336,12 +380,17 @@ void PasscodeBox::onSave(bool force) { if (!_oldPasscode->isHidden()) { hashSha256(oldPasswordData.constData(), oldPasswordData.size(), oldPasswordHash.data()); } - auto flags = MTPDaccount_passwordInputSettings::Flag::f_new_salt | MTPDaccount_passwordInputSettings::Flag::f_new_password_hash | MTPDaccount_passwordInputSettings::Flag::f_hint; + auto flags = MTPDaccount_passwordInputSettings::Flag::f_new_salt | + MTPDaccount_passwordInputSettings::Flag::f_new_password_hash | + MTPDaccount_passwordInputSettings::Flag::f_hint; if (_oldPasscode->isHidden() || _newPasscode->isHidden()) { flags |= MTPDaccount_passwordInputSettings::Flag::f_email; } - MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_flags(flags), MTP_bytes(_newSalt), MTP_bytes(newPasswordHash), MTP_string(hint), MTP_string(email))); - _setRequest = MTP::send(MTPaccount_UpdatePasswordSettings(MTP_bytes(oldPasswordHash), settings), rpcDone(&PasscodeBox::setPasswordDone), rpcFail(&PasscodeBox::setPasswordFail)); + MTPaccount_PasswordInputSettings settings( + MTP_account_passwordInputSettings(MTP_flags(flags), MTP_bytes(_newSalt), MTP_bytes(newPasswordHash), + MTP_string(hint), MTP_string(email))); + _setRequest = MTP::send(MTPaccount_UpdatePasswordSettings(MTP_bytes(oldPasswordHash), settings), + rpcDone(&PasscodeBox::setPasswordDone), rpcFail(&PasscodeBox::setPasswordFail)); } } else { cSetPasscodeBadTries(0); @@ -389,7 +438,8 @@ void PasscodeBox::onEmailChanged() { void PasscodeBox::onRecoverByEmail() { if (_pattern.isEmpty()) { _pattern = "-"; - MTP::send(MTPauth_RequestPasswordRecovery(), rpcDone(&PasscodeBox::recoverStarted), rpcFail(&PasscodeBox::recoverStartFail)); + MTP::send(MTPauth_RequestPasswordRecovery(), rpcDone(&PasscodeBox::recoverStarted), + rpcFail(&PasscodeBox::recoverStartFail)); } else { recover(); } @@ -420,10 +470,10 @@ bool PasscodeBox::recoverStartFail(const RPCError &error) { return true; } -RecoverBox::RecoverBox(QWidget*, const QString &pattern) -: _pattern(st::normalFont->elided(lng_signin_recover_hint(lt_recover_email, pattern), st::boxWidth - st::boxPadding.left() * 1.5)) -, _recoverCode(this, st::defaultInputField, langFactory(lng_signin_code)) { -} +RecoverBox::RecoverBox(QWidget *, const QString &pattern) + : _pattern(st::normalFont->elided(lng_signin_recover_hint(lt_recover_email, pattern), + st::boxWidth - st::boxPadding.left() * 1.5)) + , _recoverCode(this, st::defaultInputField, langFactory(lng_signin_code)) {} void RecoverBox::prepare() { setTitle(langFactory(lng_signin_recover_title)); @@ -431,7 +481,8 @@ void RecoverBox::prepare() { addButton(langFactory(lng_passcode_submit), [this] { onSubmit(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); - setDimensions(st::boxWidth, st::passcodePadding.top() + st::passcodePadding.bottom() + st::passcodeTextLine + _recoverCode->height() + st::passcodeTextLine); + setDimensions(st::boxWidth, st::passcodePadding.top() + st::passcodePadding.bottom() + st::passcodeTextLine + + _recoverCode->height() + st::passcodeTextLine); connect(_recoverCode, SIGNAL(changed()), this, SLOT(onCodeChanged())); connect(_recoverCode, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); @@ -445,11 +496,14 @@ void RecoverBox::paintEvent(QPaintEvent *e) { p.setFont(st::normalFont); p.setPen(st::boxTextFg); qint32 w = st::boxWidth - st::boxPadding.left() * 1.5; - p.drawText(QRect(st::boxPadding.left(), _recoverCode->y() - st::passcodeTextLine - st::passcodePadding.top(), w, st::passcodePadding.top() + st::passcodeTextLine), _pattern, style::al_left); + p.drawText(QRect(st::boxPadding.left(), _recoverCode->y() - st::passcodeTextLine - st::passcodePadding.top(), w, + st::passcodePadding.top() + st::passcodeTextLine), + _pattern, style::al_left); if (!_error.isEmpty()) { p.setPen(st::boxTextFgError); - p.drawText(QRect(st::boxPadding.left(), _recoverCode->y() + _recoverCode->height(), w, st::passcodeTextLine), _error, style::al_left); + p.drawText(QRect(st::boxPadding.left(), _recoverCode->y() + _recoverCode->height(), w, st::passcodeTextLine), + _error, style::al_left); } } @@ -457,7 +511,8 @@ void RecoverBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); _recoverCode->resize(st::boxWidth - st::boxPadding.left() - st::boxPadding.right(), _recoverCode->height()); - _recoverCode->moveToLeft(st::boxPadding.left(), st::passcodePadding.top() + st::passcodePadding.bottom() + st::passcodeTextLine); + _recoverCode->moveToLeft(st::boxPadding.left(), + st::passcodePadding.top() + st::passcodePadding.bottom() + st::passcodeTextLine); } void RecoverBox::setInnerFocus() { @@ -474,7 +529,8 @@ void RecoverBox::onSubmit() { return; } - _submitRequest = MTP::send(MTPauth_RecoverPassword(MTP_string(code)), rpcDone(&RecoverBox::codeSubmitDone, true), rpcFail(&RecoverBox::codeSubmitFail)); + _submitRequest = MTP::send(MTPauth_RecoverPassword(MTP_string(code)), rpcDone(&RecoverBox::codeSubmitDone, true), + rpcFail(&RecoverBox::codeSubmitFail)); } void RecoverBox::onCodeChanged() { @@ -522,7 +578,7 @@ bool RecoverBox::codeSubmitFail(const RPCError &error) { return true; } if (cDebug()) { // internal server error - _error = err + ": " + error.description(); + _error = err + ": " + error.description(); } else { _error = lang(lng_server_error); } diff --git a/Telegram/SourceFiles/boxes/passcode_box.h b/Telegram/SourceFiles/boxes/passcode_box.h index bb09b75c0..374852e93 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.h +++ b/Telegram/SourceFiles/boxes/passcode_box.h @@ -32,8 +32,9 @@ class PasscodeBox : public BoxContent, public RPCSender { Q_OBJECT public: - PasscodeBox(QWidget*, bool turningOff); - PasscodeBox(QWidget*, const QByteArray &newSalt, const QByteArray &curSalt, bool hasRecovery, const QString &hint, bool turningOff = false); + PasscodeBox(QWidget *, bool turningOff); + PasscodeBox(QWidget *, const QByteArray &newSalt, const QByteArray &curSalt, bool hasRecovery, const QString &hint, + bool turningOff = false); private slots: void onSave(bool force = false); @@ -88,14 +89,13 @@ private: object_ptr _recover; QString _oldError, _newError, _emailError; - }; class RecoverBox : public BoxContent, public RPCSender { Q_OBJECT public: - RecoverBox(QWidget*, const QString &pattern); + RecoverBox(QWidget *, const QString &pattern); public slots: void onSubmit(); @@ -123,5 +123,4 @@ private: object_ptr _recoverCode; QString _error; - }; diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index 60dbd798d..4b371b75e 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -18,29 +18,27 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include "base/algorithm.h" #include "boxes/peer_list_box.h" +#include "base/algorithm.h" -#include "styles/style_boxes.h" -#include "styles/style_dialogs.h" #include "auth_session.h" -#include "mainwidget.h" -#include "ui/widgets/multi_select.h" -#include "ui/widgets/labels.h" -#include "ui/effects/round_checkbox.h" -#include "ui/effects/ripple_animation.h" -#include "ui/effects/widget_slide_wrap.h" #include "lang/lang_keys.h" +#include "mainwidget.h" #include "observer_peer.h" #include "storage/file_download.h" +#include "styles/style_boxes.h" +#include "styles/style_dialogs.h" +#include "ui/effects/ripple_animation.h" +#include "ui/effects/round_checkbox.h" +#include "ui/effects/widget_slide_wrap.h" +#include "ui/widgets/labels.h" +#include "ui/widgets/multi_select.h" #include "window/themes/window_theme.h" -PeerListBox::PeerListBox(QWidget* - , std::unique_ptr controller - , base::lambda)> init) - : _controller(std::move(controller)) - , _init(std::move(init)) -{ +PeerListBox::PeerListBox(QWidget *, std::unique_ptr controller, + base::lambda)> init) + : _controller(std::move(controller)) + , _init(std::move(init)) { Expects(_controller != nullptr); } @@ -159,7 +157,7 @@ void PeerListBox::peerListAppendSearchRow(std::unique_ptr row) { _inner->appendSearchRow(std::move(row)); } -void PeerListBox::peerListAppendFoundRow(not_null row) { +void PeerListBox::peerListAppendFoundRow(not_null row) { _inner->appendFoundRow(row); } @@ -167,7 +165,7 @@ void PeerListBox::peerListPrependRow(std::unique_ptr row) { _inner->prependRow(std::move(row)); } -void PeerListBox::peerListPrependRowFromSearchResult(not_null row) { +void PeerListBox::peerListPrependRowFromSearchResult(not_null row) { _inner->prependRowFromSearchResult(row); } @@ -175,19 +173,19 @@ PeerListRow *PeerListBox::peerListFindRow(PeerListRowId id) { return _inner->findRow(id); } -void PeerListBox::peerListUpdateRow(not_null row) { +void PeerListBox::peerListUpdateRow(not_null row) { _inner->updateRow(row); } -void PeerListBox::peerListRemoveRow(not_null row) { +void PeerListBox::peerListRemoveRow(not_null row) { _inner->removeRow(row); } -void PeerListBox::peerListConvertRowToSearchResult(not_null row) { +void PeerListBox::peerListConvertRowToSearchResult(not_null row) { _inner->convertRowToSearchResult(row); } -void PeerListBox::peerListSetRowChecked(not_null row, bool checked) { +void PeerListBox::peerListSetRowChecked(not_null row, bool checked) { auto peer = row->peer(); if (checked) { addSelectItem(peer, PeerListRow::SetStyle::Animated); @@ -207,7 +205,7 @@ int PeerListBox::peerListFullRowsCount() { return _inner->fullRowsCount(); } -not_null PeerListBox::peerListRowAt(int index) { +not_null PeerListBox::peerListRowAt(int index) { return _inner->rowAt(index); } @@ -251,21 +249,18 @@ void PeerListBox::peerListSetSearchMode(PeerListSearchMode mode) { void PeerListBox::peerListSortRows(base::lambda compare) { _inner->reorderRows([compare = std::move(compare)](auto &&begin, auto &&end) { - std::sort(begin, end, [compare](auto &&a, auto &&b) { - return compare(*a, *b); - }); + std::sort(begin, end, [compare](auto &&a, auto &&b) { return compare(*a, *b); }); }); } void PeerListBox::peerListPartitionRows(base::lambda border) { _inner->reorderRows([border = std::move(border)](auto &&begin, auto &&end) { - std::stable_partition(begin, end, [border](auto &¤t) { - return border(*current); - }); + std::stable_partition(begin, end, [border](auto &¤t) { return border(*current); }); }); } -PeerListController::PeerListController(std::unique_ptr searchController) : _searchController(std::move(searchController)) { +PeerListController::PeerListController(std::unique_ptr searchController) + : _searchController(std::move(searchController)) { if (_searchController) { _searchController->setDelegate(this); } @@ -280,7 +275,7 @@ void PeerListController::search(const QString &query) { _searchController->searchQuery(query); } -void PeerListController::peerListSearchAddRow(not_null peer) { +void PeerListController::peerListSearchAddRow(not_null peer) { if (auto row = delegate()->peerListFindRow(peer->id)) { Assert(row->id() == row->peer()->id); delegate()->peerListAppendFoundRow(row); @@ -318,7 +313,7 @@ void PeerListController::setSearchNoResultsText(const QString &text) { } } -void PeerListBox::addSelectItem(not_null peer, PeerListRow::SetStyle style) { +void PeerListBox::addSelectItem(not_null peer, PeerListRow::SetStyle style) { if (!_select) { createMultiSelect(); _select->toggleFast(false); @@ -326,7 +321,8 @@ void PeerListBox::addSelectItem(not_null peer, PeerListRow::SetStyle if (style == PeerListRow::SetStyle::Fast) { _select->entity()->addItemInBunch(peer->id, peer->shortName(), st::activeButtonBg, PaintUserpicCallback(peer)); } else { - _select->entity()->addItem(peer->id, peer->shortName(), st::activeButtonBg, PaintUserpicCallback(peer), Ui::MultiSelect::AddItemWay::Default); + _select->entity()->addItem(peer->id, peer->shortName(), st::activeButtonBg, PaintUserpicCallback(peer), + Ui::MultiSelect::AddItemWay::Default); } } @@ -335,7 +331,7 @@ void PeerListBox::peerListFinishSelectedRowsBunch() { _select->entity()->finishItemsBunch(); } -bool PeerListBox::peerListIsRowSelected(not_null peer) { +bool PeerListBox::peerListIsRowSelected(not_null peer) { return _select ? _select->entity()->hasItem(peer->id) : false; } @@ -343,27 +339,24 @@ int PeerListBox::peerListSelectedRowsCount() { return _select ? _select->entity()->getItemsCount() : 0; } -std::vector> PeerListBox::peerListCollectSelectedRows() { - auto result = std::vector> {}; - auto items = _select ? _select->entity()->getItems() : QVector {}; +std::vector> PeerListBox::peerListCollectSelectedRows() { + auto result = std::vector>{}; + auto items = _select ? _select->entity()->getItems() : QVector{}; if (!items.empty()) { result.reserve(items.size()); - for_const (auto itemId, items) { - result.push_back(App::peer(itemId)); - } + for_const (auto itemId, items) { result.push_back(App::peer(itemId)); } } return result; } -PeerListRow::PeerListRow(not_null peer) : PeerListRow(peer, peer->id) { -} +PeerListRow::PeerListRow(not_null peer) + : PeerListRow(peer, peer->id) {} -PeerListRow::PeerListRow(not_null peer, PeerListRowId id) -: _id(id) -, _peer(peer) -, _initialized(false) -, _isSearchResult(false) { -} +PeerListRow::PeerListRow(not_null peer, PeerListRowId id) + : _id(id) + , _peer(peer) + , _initialized(false) + , _isSearchResult(false) {} bool PeerListRow::checked() const { return _checkbox && _checkbox->checked(); @@ -423,7 +416,8 @@ void PeerListRow::invalidatePixmapsCache() { void PeerListRow::paintStatusText(Painter &p, int x, int y, int availableWidth, int outerWidth, bool selected) { auto statusHasOnlineColor = (_statusType == PeerListRow::StatusType::Online); p.setFont(st::contactsStatusFont); - p.setPen(statusHasOnlineColor ? st::contactsStatusFgOnline : (selected ? st::contactsStatusFgOver : st::contactsStatusFg)); + p.setPen(statusHasOnlineColor ? st::contactsStatusFgOnline : + (selected ? st::contactsStatusFgOver : st::contactsStatusFg)); _status.drawLeftElided(p, x, y, availableWidth, outerWidth); } @@ -514,7 +508,8 @@ void PeerListRow::lazyInitialize() { } void PeerListRow::createCheckbox(base::lambda updateCallback) { - _checkbox = std::make_unique(st::contactsPhotoCheckbox, std::move(updateCallback), PaintUserpicCallback(_peer)); + _checkbox = std::make_unique(st::contactsPhotoCheckbox, std::move(updateCallback), + PaintUserpicCallback(_peer)); } void PeerListRow::setCheckedInternal(bool checked, SetStyle style) { @@ -524,20 +519,21 @@ void PeerListRow::setCheckedInternal(bool checked, SetStyle style) { _checkbox->setChecked(checked, speed); } -PeerListBox::Inner::Inner(QWidget *parent, not_null controller) : TWidget(parent) -, _controller(controller) -, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) { +PeerListBox::Inner::Inner(QWidget *parent, not_null controller) + : TWidget(parent) + , _controller(controller) + , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) { subscribe(Auth().downloaderTaskFinished(), [this] { update(); }); using UpdateFlag = Notify::PeerUpdate::Flag; auto changes = UpdateFlag::NameChanged | UpdateFlag::PhotoChanged; subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(changes, [this](const Notify::PeerUpdate &update) { - if (update.flags & UpdateFlag::PhotoChanged) { - this->update(); - } else if (update.flags & UpdateFlag::NameChanged) { - handleNameChanged(update); - } - })); + if (update.flags & UpdateFlag::PhotoChanged) { + this->update(); + } else if (update.flags & UpdateFlag::NameChanged) { + handleNameChanged(update); + } + })); subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.paletteChanged()) { invalidatePixmapsCache(); @@ -566,7 +562,7 @@ void PeerListBox::Inner::appendSearchRow(std::unique_ptr row) { } } -void PeerListBox::Inner::appendFoundRow(not_null row) { +void PeerListBox::Inner::appendFoundRow(not_null row) { Expects(showingSearch()); auto index = findRowIndex(row); if (index.value < 0) { @@ -574,13 +570,11 @@ void PeerListBox::Inner::appendFoundRow(not_null row) { } } -void PeerListBox::Inner::changeCheckState(not_null row, bool checked, PeerListRow::SetStyle style) { - row->setChecked(checked, style, [this, row] { - updateRow(row); - }); +void PeerListBox::Inner::changeCheckState(not_null row, bool checked, PeerListRow::SetStyle style) { + row->setChecked(checked, style, [this, row] { updateRow(row); }); } -void PeerListBox::Inner::addRowEntry(not_null row) { +void PeerListBox::Inner::addRowEntry(not_null row) { _rowsById.emplace(row->id(), row); _rowsByPeer[row->peer()].push_back(row); if (addingToSearchIndex()) { @@ -603,19 +597,17 @@ bool PeerListBox::Inner::addingToSearchIndex() const { return (_searchMode != PeerListSearchMode::Disabled) || !_searchIndex.empty(); } -void PeerListBox::Inner::addToSearchIndex(not_null row) { +void PeerListBox::Inner::addToSearchIndex(not_null row) { if (row->isSearchResult()) { return; } removeFromSearchIndex(row); row->setNameFirstChars(row->peer()->chars); - for_const (auto ch, row->nameFirstChars()) { - _searchIndex[ch].push_back(row); - } + for_const (auto ch, row->nameFirstChars()) { _searchIndex[ch].push_back(row); } } -void PeerListBox::Inner::removeFromSearchIndex(not_null row) { +void PeerListBox::Inner::removeFromSearchIndex(not_null row) { auto &nameFirstChars = row->nameFirstChars(); if (!nameFirstChars.empty()) { for_const (auto ch, row->nameFirstChars()) { @@ -641,7 +633,7 @@ void PeerListBox::Inner::prependRow(std::unique_ptr row) { } } -void PeerListBox::Inner::prependRowFromSearchResult(not_null row) { +void PeerListBox::Inner::prependRowFromSearchResult(not_null row) { if (!row->isSearchResult()) { return; } @@ -679,7 +671,7 @@ PeerListRow *PeerListBox::Inner::findRow(PeerListRowId id) { return (it == _rowsById.cend()) ? nullptr : it->second.get(); } -void PeerListBox::Inner::removeRow(not_null row) { +void PeerListBox::Inner::removeRow(not_null row) { auto index = row->absoluteIndex(); auto isSearchResult = row->isSearchResult(); auto &eraseFrom = isSearchResult ? _searchRows : _rows; @@ -700,7 +692,7 @@ void PeerListBox::Inner::removeRow(not_null row) { restoreSelection(); } -void PeerListBox::Inner::convertRowToSearchResult(not_null row) { +void PeerListBox::Inner::convertRowToSearchResult(not_null row) { if (row->isSearchResult()) { return; } else if (!showingSearch() || !_controller->hasComplexSearch()) { @@ -721,7 +713,7 @@ int PeerListBox::Inner::fullRowsCount() const { return _rows.size(); } -not_null PeerListBox::Inner::rowAt(int index) const { +not_null PeerListBox::Inner::rowAt(int index) const { Expects(index >= 0 && index < _rows.size()); return _rows[index].get(); } @@ -785,14 +777,13 @@ void PeerListBox::Inner::refreshRows() { void PeerListBox::Inner::setSearchMode(PeerListSearchMode mode) { if (_searchMode != mode) { if (!addingToSearchIndex()) { - for_const (auto &row, _rows) { - addToSearchIndex(row.get()); - } + for_const (auto &row, _rows) { addToSearchIndex(row.get()); } } _searchMode = mode; if (_controller->hasComplexSearch()) { if (!_searchLoading) { - setSearchLoading(object_ptr(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout)); + setSearchLoading(object_ptr(this, lang(lng_contacts_loading), + Ui::FlatLabel::InitType::Simple, st::membersAbout)); } } else { clearSearchRows(); @@ -847,7 +838,8 @@ int PeerListBox::Inner::resizeGetHeight(int newWidth) { _description->setVisible(!showingSearch()); } if (_searchNoResults) { - _searchNoResults->moveToLeft(st::contactsPadding.left(), labelTop + st::membersAboutLimitPadding.top(), newWidth); + _searchNoResults->moveToLeft(st::contactsPadding.left(), labelTop + st::membersAboutLimitPadding.top(), + newWidth); _searchNoResults->setVisible(showingSearch() && _filterResults.empty() && !_controller->isSearchLoading()); } if (_searchLoading) { @@ -883,9 +875,7 @@ void PeerListBox::Inner::mousePressEvent(QMouseEvent *e) { setPressed(_selected); if (auto row = getRow(_selected.index)) { - auto updateCallback = [this, row, hint = _selected.index] { - updateRow(row, hint); - }; + auto updateCallback = [this, row, hint = _selected.index] { updateRow(row, hint); }; if (_selected.action) { auto actionRect = getActionRect(row, _selected.index); if (!actionRect.isEmpty()) { @@ -954,7 +944,8 @@ void PeerListBox::Inner::paintRow(Painter &p, TimeMs ms, RowIndex index) { if (row->needsVerifiedIcon()) { auto icon = &st::dialogsVerifiedIcon; namew -= icon->width(); - icon->paint(p, namex + std::min(name.maxWidth(), namew), st::contactsPadding.top() + st::contactsNameTop, width()); + icon->paint(p, namex + std::min(name.maxWidth(), namew), st::contactsPadding.top() + st::contactsNameTop, + width()); } auto nameCheckedRatio = row->disabled() ? 0. : row->checkedRatio(); p.setPen(anim::pen(st::contactsNameFg, st::contactsNameCheckedFg, nameCheckedRatio)); @@ -967,7 +958,8 @@ void PeerListBox::Inner::paintRow(Painter &p, TimeMs ms, RowIndex index) { } p.setFont(st::contactsStatusFont); - if (row->isSearchResult() && !_mentionHighlight.isEmpty() && peer->userName().startsWith(_mentionHighlight, Qt::CaseInsensitive)) { + if (row->isSearchResult() && !_mentionHighlight.isEmpty() && + peer->userName().startsWith(_mentionHighlight, Qt::CaseInsensitive)) { auto username = peer->userName(); auto availableWidth = statusw; auto highlightedPart = '@' + username.mid(0, _mentionHighlight.size()); @@ -985,7 +977,8 @@ void PeerListBox::Inner::paintRow(Painter &p, TimeMs ms, RowIndex index) { p.setPen(st::contactsStatusFgOnline); p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), highlightedPart); p.setPen(selected ? st::contactsStatusFgOver : st::contactsStatusFg); - p.drawTextLeft(namex + highlightedWidth, st::contactsPadding.top() + st::contactsStatusTop, width(), grayedPart); + p.drawTextLeft(namex + highlightedWidth, st::contactsPadding.top() + st::contactsStatusTop, width(), + grayedPart); } } else { row->paintStatusText(p, namex, st::contactsPadding.top() + st::contactsStatusTop, statusw, width(), selected); @@ -1003,7 +996,7 @@ void PeerListBox::Inner::selectSkip(int direction) { auto rowsCount = shownRowsCount(); auto index = 0; auto firstEnabled = -1, lastEnabled = -1; - enumerateShownRows([&firstEnabled, &lastEnabled, &index](not_null row) { + enumerateShownRows([&firstEnabled, &lastEnabled, &index](not_null row) { if (!row->disabled()) { if (firstEnabled < 0) { firstEnabled = index; @@ -1022,8 +1015,8 @@ void PeerListBox::Inner::selectSkip(int direction) { Assert(firstEnabled - 1 <= lastEnabled); // Always pass through the first enabled item when changing from / to none selected. - if ((_selected.index.value > firstEnabled && newSelectedIndex < firstEnabled) - || (_selected.index.value < firstEnabled && newSelectedIndex > firstEnabled)) { + if ((_selected.index.value > firstEnabled && newSelectedIndex < firstEnabled) || + (_selected.index.value < firstEnabled && newSelectedIndex > firstEnabled)) { newSelectedIndex = firstEnabled; } @@ -1037,7 +1030,7 @@ void PeerListBox::Inner::selectSkip(int direction) { newSelectedIndex = lastEnabled; } else if (getRow(RowIndex(newSelectedIndex))->disabled()) { auto delta = (direction > 0) ? 1 : -1; - for (newSelectedIndex += delta; ; newSelectedIndex += delta) { + for (newSelectedIndex += delta;; newSelectedIndex += delta) { // We must find an enabled row, firstEnabled <= us <= lastEnabled. Assert(newSelectedIndex >= 0 && newSelectedIndex < rowsCount); if (!getRow(RowIndex(newSelectedIndex))->disabled()) { @@ -1100,7 +1093,7 @@ void PeerListBox::Inner::searchQueryChanged(QString query) { if (_normalizedSearchQuery != normalizedQuery) { setSearchQuery(query, normalizedQuery); if (_controller->searchInLocal() && !searchWordsList.isEmpty()) { - auto minimalList = (const std::vector>*)nullptr; + auto minimalList = (const std::vector> *)nullptr; for_const (auto &searchWord, searchWordsList) { auto searchWordStart = searchWord[0].toLower(); auto it = _searchIndex.find(searchWordStart); @@ -1190,7 +1183,8 @@ void PeerListBox::Inner::updateSelection() { auto in = parentWidget()->rect().contains(parentWidget()->mapFromGlobal(_lastMousePosition)); auto selected = Selected(); auto rowsPointY = point.y() - rowsTop(); - selected.index.value = (in && rowsPointY >= 0 && rowsPointY < shownRowsCount() * _rowHeight) ? (rowsPointY / _rowHeight) : -1; + selected.index.value = + (in && rowsPointY >= 0 && rowsPointY < shownRowsCount() * _rowHeight) ? (rowsPointY / _rowHeight) : -1; if (selected.index.value >= 0) { auto row = getRow(selected.index); if (row->disabled()) { @@ -1204,7 +1198,7 @@ void PeerListBox::Inner::updateSelection() { setSelected(selected); } -QRect PeerListBox::Inner::getActionRect(not_null row, RowIndex index) const { +QRect PeerListBox::Inner::getActionRect(not_null row, RowIndex index) const { auto actionSize = row->actionSize(); if (actionSize.isEmpty()) { return QRect(); @@ -1228,7 +1222,7 @@ int PeerListBox::Inner::getRowTop(RowIndex index) const { return -1; } -void PeerListBox::Inner::updateRow(not_null row, RowIndex hint) { +void PeerListBox::Inner::updateRow(not_null row, RowIndex hint) { updateRow(findRowIndex(row, hint)); } @@ -1248,13 +1242,11 @@ void PeerListBox::Inner::updateRow(RowIndex index) { update(0, getRowTop(index), width(), _rowHeight); } -template -bool PeerListBox::Inner::enumerateShownRows(Callback callback) { +template bool PeerListBox::Inner::enumerateShownRows(Callback callback) { return enumerateShownRows(0, shownRowsCount(), std::move(callback)); } -template -bool PeerListBox::Inner::enumerateShownRows(int from, int to, Callback callback) { +template bool PeerListBox::Inner::enumerateShownRows(int from, int to, Callback callback) { Assert(0 <= from); Assert(from <= to); if (showingSearch()) { @@ -1288,7 +1280,7 @@ PeerListRow *PeerListBox::Inner::getRow(RowIndex index) { return nullptr; } -PeerListBox::Inner::RowIndex PeerListBox::Inner::findRowIndex(not_null row, RowIndex hint) { +PeerListBox::Inner::RowIndex PeerListBox::Inner::findRowIndex(not_null row, RowIndex hint) { if (!showingSearch()) { Assert(!row->isSearchResult()); return RowIndex(row->absoluteIndex()); diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index 2a952feef..e2c60bc12 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -20,16 +20,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once +#include "base/timer.h" #include "boxes/abstract_box.h" #include "mtproto/sender.h" -#include "base/timer.h" namespace Ui { class RippleAnimation; class RoundImageCheckbox; class MultiSelect; -template -class WidgetSlideWrap; +template class WidgetSlideWrap; class FlatLabel; } // namespace Ui @@ -46,8 +45,8 @@ inline auto PaintUserpicCallback(PeerData *peer) { using PeerListRowId = quint64; class PeerListRow { public: - PeerListRow(not_null peer); - PeerListRow(not_null peer, PeerListRowId id); + PeerListRow(not_null peer); + PeerListRow(not_null peer, PeerListRowId id); enum class State { Active, @@ -64,7 +63,7 @@ public: // added to the box it is always false. bool checked() const; - not_null peer() const { + not_null peer() const { return _peer; } PeerListRowId id() const { @@ -86,12 +85,9 @@ public: virtual QMargins actionMargins() const { return QMargins(); } - virtual void addActionRipple(QPoint point, base::lambda updateCallback) { - } - virtual void stopLastActionRipple() { - } - virtual void paintAction(Painter &p, TimeMs ms, int x, int y, int outerWidth, bool actionSelected) { - } + virtual void addActionRipple(QPoint point, base::lambda updateCallback) {} + virtual void stopLastActionRipple() {} + virtual void paintAction(Painter &p, TimeMs ms, int x, int y, int outerWidth, bool actionSelected) {} void refreshName(); const Text &name() const { @@ -125,8 +121,7 @@ public: Animated, Fast, }; - template - void setChecked(bool checked, SetStyle style, UpdateCallback callback) { + template void setChecked(bool checked, SetStyle style, UpdateCallback callback) { if (checked && !_checkbox) { createCheckbox(std::move(callback)); } @@ -134,8 +129,7 @@ public: } void invalidatePixmapsCache(); - template - void addRipple(QSize size, QPoint point, UpdateCallback updateCallback); + template void addRipple(QSize size, QPoint point, UpdateCallback updateCallback); void stopLastRipple(); void paintRipple(Painter &p, TimeMs ms, int x, int y, int outerWidth); void paintUserpic(Painter &p, TimeMs ms, int x, int y, int outerWidth); @@ -163,7 +157,7 @@ private: void setStatusText(const QString &text); PeerListRowId _id = 0; - not_null _peer; + not_null _peer; std::unique_ptr _ripple; std::unique_ptr _checkbox; Text _name; @@ -174,7 +168,6 @@ private: State _disabledState = State::Active; bool _initialized : 1; bool _isSearchResult : 1; - }; enum class PeerListSearchMode { @@ -193,15 +186,15 @@ public: virtual void peerListSetSearchMode(PeerListSearchMode mode) = 0; virtual void peerListAppendRow(std::unique_ptr row) = 0; virtual void peerListAppendSearchRow(std::unique_ptr row) = 0; - virtual void peerListAppendFoundRow(not_null row) = 0; + virtual void peerListAppendFoundRow(not_null row) = 0; virtual void peerListPrependRow(std::unique_ptr row) = 0; - virtual void peerListPrependRowFromSearchResult(not_null row) = 0; - virtual void peerListUpdateRow(not_null row) = 0; - virtual void peerListRemoveRow(not_null row) = 0; - virtual void peerListConvertRowToSearchResult(not_null row) = 0; - virtual bool peerListIsRowSelected(not_null peer) = 0; - virtual void peerListSetRowChecked(not_null row, bool checked) = 0; - virtual not_null peerListRowAt(int index) = 0; + virtual void peerListPrependRowFromSearchResult(not_null row) = 0; + virtual void peerListUpdateRow(not_null row) = 0; + virtual void peerListRemoveRow(not_null row) = 0; + virtual void peerListConvertRowToSearchResult(not_null row) = 0; + virtual bool peerListIsRowSelected(not_null peer) = 0; + virtual void peerListSetRowChecked(not_null row, bool checked) = 0; + virtual not_null peerListRowAt(int index) = 0; virtual void peerListRefreshRows() = 0; virtual void peerListScrollToTop() = 0; virtual int peerListFullRowsCount() = 0; @@ -209,8 +202,7 @@ public: virtual void peerListSortRows(base::lambda compare) = 0; virtual void peerListPartitionRows(base::lambda border) = 0; - template - void peerListAddSelectedRows(PeerDataRange &&range) { + template void peerListAddSelectedRows(PeerDataRange &&range) { for (auto peer : range) { peerListAddSelectedRowInBunch(peer); } @@ -218,21 +210,19 @@ public: } virtual int peerListSelectedRowsCount() = 0; - virtual std::vector> peerListCollectSelectedRows() = 0; + virtual std::vector> peerListCollectSelectedRows() = 0; virtual ~PeerListDelegate() = default; private: - virtual void peerListAddSelectedRowInBunch(not_null peer) = 0; + virtual void peerListAddSelectedRowInBunch(not_null peer) = 0; virtual void peerListFinishSelectedRowsBunch() = 0; - }; class PeerListSearchDelegate { public: - virtual void peerListSearchAddRow(not_null peer) = 0; + virtual void peerListSearchAddRow(not_null peer) = 0; virtual void peerListSearchRefreshRows() = 0; virtual ~PeerListSearchDelegate() = default; - }; class PeerListSearchController { @@ -242,18 +232,17 @@ public: virtual bool loadMoreRows() = 0; virtual ~PeerListSearchController() = default; - void setDelegate(not_null delegate) { + void setDelegate(not_null delegate) { _delegate = delegate; } protected: - not_null delegate() const { + not_null delegate() const { return _delegate; } private: PeerListSearchDelegate *_delegate = nullptr; - }; class PeerListController : public PeerListSearchDelegate { @@ -261,27 +250,24 @@ public: // Search works only with RowId == peer->id. PeerListController(std::unique_ptr searchController = nullptr); - void setDelegate(not_null delegate) { + void setDelegate(not_null delegate) { _delegate = delegate; prepare(); } virtual void prepare() = 0; - virtual void rowClicked(not_null row) = 0; - virtual void rowActionClicked(not_null row) { - } - virtual void loadMoreRows() { - } - virtual void itemDeselectedHook(not_null peer) { - } + virtual void rowClicked(not_null row) = 0; + virtual void rowActionClicked(not_null row) {} + virtual void loadMoreRows() {} + virtual void itemDeselectedHook(not_null peer) {} bool isSearchLoading() const { return _searchController ? _searchController->isLoading() : false; } - virtual std::unique_ptr createSearchRow(not_null peer) { + virtual std::unique_ptr createSearchRow(not_null peer) { return nullptr; } - bool isRowSelected(not_null peer) { + bool isRowSelected(not_null peer) { return delegate()->peerListIsRowSelected(peer); } @@ -291,13 +277,13 @@ public: bool hasComplexSearch() const; void search(const QString &query); - void peerListSearchAddRow(not_null peer) override; + void peerListSearchAddRow(not_null peer) override; void peerListSearchRefreshRows() override; virtual ~PeerListController() = default; protected: - not_null delegate() const { + not_null delegate() const { return _delegate; } PeerListSearchController *searchController() const { @@ -320,12 +306,12 @@ protected: private: PeerListDelegate *_delegate = nullptr; std::unique_ptr _searchController = nullptr; - }; class PeerListBox : public BoxContent, public PeerListDelegate { public: - PeerListBox(QWidget*, std::unique_ptr controller, base::lambda)> init); + PeerListBox(QWidget *, std::unique_ptr controller, + base::lambda)> init); void peerListSetTitle(base::lambda title) override { setTitle(std::move(title)); @@ -340,17 +326,17 @@ public: void peerListSetSearchMode(PeerListSearchMode mode) override; void peerListAppendRow(std::unique_ptr row) override; void peerListAppendSearchRow(std::unique_ptr row) override; - void peerListAppendFoundRow(not_null row) override; + void peerListAppendFoundRow(not_null row) override; void peerListPrependRow(std::unique_ptr row) override; - void peerListPrependRowFromSearchResult(not_null row) override; - void peerListUpdateRow(not_null row) override; - void peerListRemoveRow(not_null row) override; - void peerListConvertRowToSearchResult(not_null row) override; - void peerListSetRowChecked(not_null row, bool checked) override; - not_null peerListRowAt(int index) override; - bool peerListIsRowSelected(not_null peer) override; + void peerListPrependRowFromSearchResult(not_null row) override; + void peerListUpdateRow(not_null row) override; + void peerListRemoveRow(not_null row) override; + void peerListConvertRowToSearchResult(not_null row) override; + void peerListSetRowChecked(not_null row, bool checked) override; + not_null peerListRowAt(int index) override; + bool peerListIsRowSelected(not_null peer) override; int peerListSelectedRowsCount() override; - std::vector> peerListCollectSelectedRows() override; + std::vector> peerListCollectSelectedRows() override; void peerListRefreshRows() override; void peerListScrollToTop() override; int peerListFullRowsCount() override; @@ -367,26 +353,25 @@ protected: void paintEvent(QPaintEvent *e) override; private: - void peerListAddSelectedRowInBunch(not_null peer) override { + void peerListAddSelectedRowInBunch(not_null peer) override { addSelectItem(peer, PeerListRow::SetStyle::Fast); } void peerListFinishSelectedRowsBunch() override; - void addSelectItem(not_null peer, PeerListRow::SetStyle style); + void addSelectItem(not_null peer, PeerListRow::SetStyle style); void createMultiSelect(); int getTopScrollSkip() const; void updateScrollSkips(); void searchQueryChanged(const QString &query); - object_ptr> _select = { nullptr }; + object_ptr> _select = {nullptr}; class Inner; QPointer _inner; std::unique_ptr _controller; - base::lambda _init; + base::lambda _init; bool _scrollBottomFixed = true; - }; // This class is hold in header because it requires Qt preprocessing. @@ -394,7 +379,7 @@ class PeerListBox::Inner : public TWidget, private base::Subscriber { Q_OBJECT public: - Inner(QWidget *parent, not_null controller); + Inner(QWidget *parent, not_null controller); void selectSkip(int direction); void selectSkipPage(int height, int direction); @@ -409,17 +394,17 @@ public: // Interface for the controller. void appendRow(std::unique_ptr row); void appendSearchRow(std::unique_ptr row); - void appendFoundRow(not_null row); + void appendFoundRow(not_null row); void prependRow(std::unique_ptr row); - void prependRowFromSearchResult(not_null row); + void prependRowFromSearchResult(not_null row); PeerListRow *findRow(PeerListRowId id); - void updateRow(not_null row) { + void updateRow(not_null row) { updateRow(row, RowIndex()); } - void removeRow(not_null row); - void convertRowToSearchResult(not_null row); + void removeRow(not_null row); + void convertRowToSearchResult(not_null row); int fullRowsCount() const; - not_null rowAt(int index) const; + not_null rowAt(int index) const; void setDescription(object_ptr description); void setSearchLoading(object_ptr loading); void setSearchNoResults(object_ptr noResults); @@ -427,10 +412,9 @@ public: void refreshRows(); void setSearchMode(PeerListSearchMode mode); - void changeCheckState(not_null row, bool checked, PeerListRow::SetStyle style); + void changeCheckState(not_null row, bool checked, PeerListRow::SetStyle style); - template - void reorderRows(ReorderCallback &&callback) { + template void reorderRows(ReorderCallback &&callback) { callback(_rows.begin(), _rows.end()); for (auto &searchEntity : _searchIndex) { callback(searchEntity.second.begin(), searchEntity.second.end()); @@ -461,10 +445,9 @@ private: void invalidatePixmapsCache(); struct RowIndex { - RowIndex() { - } - explicit RowIndex(int value) : value(value) { - } + RowIndex() {} + explicit RowIndex(int value) + : value(value) {} int value = -1; }; friend inline bool operator==(RowIndex a, RowIndex b) { @@ -475,12 +458,13 @@ private: } struct Selected { - Selected() { - } - Selected(RowIndex index, bool action) : index(index), action(action) { - } - Selected(int index, bool action) : index(index), action(action) { - } + Selected() {} + Selected(RowIndex index, bool action) + : index(index) + , action(action) {} + Selected(int index, bool action) + : index(index) + , action(action) {} RowIndex index; bool action = false; }; @@ -499,19 +483,19 @@ private: void loadProfilePhotos(); void checkScrollForPreload(); - void updateRow(not_null row, RowIndex hint); + void updateRow(not_null row, RowIndex hint); void updateRow(RowIndex row); int getRowTop(RowIndex row) const; PeerListRow *getRow(RowIndex element); - RowIndex findRowIndex(not_null row, RowIndex hint = RowIndex()); - QRect getActionRect(not_null row, RowIndex index) const; + RowIndex findRowIndex(not_null row, RowIndex hint = RowIndex()); + QRect getActionRect(not_null row, RowIndex index) const; void paintRow(Painter &p, TimeMs ms, RowIndex index); - void addRowEntry(not_null row); - void addToSearchIndex(not_null row); + void addRowEntry(not_null row); + void addToSearchIndex(not_null row); bool addingToSearchIndex() const; - void removeFromSearchIndex(not_null row); + void removeFromSearchIndex(not_null row); void setSearchQuery(const QString &query, const QString &normalizedQuery); bool showingSearch() const { return !_searchQuery.isEmpty(); @@ -519,17 +503,15 @@ private: int shownRowsCount() const { return showingSearch() ? _filterResults.size() : _rows.size(); } - template - bool enumerateShownRows(Callback callback); - template - bool enumerateShownRows(int from, int to, Callback callback); + template bool enumerateShownRows(Callback callback); + template bool enumerateShownRows(int from, int to, Callback callback); int rowsTop() const; int labelHeight() const; void clearSearchRows(); - not_null _controller; + not_null _controller; PeerListSearchMode _searchMode = PeerListSearchMode::Disabled; int _rowHeight = 0; @@ -541,23 +523,22 @@ private: bool _mouseSelection = false; std::vector> _rows; - std::map> _rowsById; - std::map>> _rowsByPeer; + std::map> _rowsById; + std::map>> _rowsByPeer; - std::map>> _searchIndex; + std::map>> _searchIndex; QString _searchQuery; QString _normalizedSearchQuery; QString _mentionHighlight; - std::vector> _filterResults; + std::vector> _filterResults; int _aboveHeight = 0; - object_ptr _aboveWidget = { nullptr }; - object_ptr _description = { nullptr }; - object_ptr _searchNoResults = { nullptr }; - object_ptr _searchLoading = { nullptr }; + object_ptr _aboveWidget = {nullptr}; + object_ptr _description = {nullptr}; + object_ptr _searchNoResults = {nullptr}; + object_ptr _searchLoading = {nullptr}; QPoint _lastMousePosition; std::vector> _searchRows; - }; diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 2e30ff4d8..426b14e64 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -18,32 +18,32 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include "base/algorithm.h" #include "boxes/peer_list_controllers.h" +#include "apiwrap.h" +#include "auth_session.h" +#include "base/algorithm.h" +#include "boxes/confirm_box.h" +#include "dialogs/dialogs_indexed_list.h" +#include "lang/lang_keys.h" +#include "mainwidget.h" +#include "observer_peer.h" #include "styles/style_boxes.h" #include "styles/style_profile.h" -#include "boxes/confirm_box.h" -#include "observer_peer.h" #include "ui/widgets/checkbox.h" -#include "auth_session.h" -#include "apiwrap.h" -#include "mainwidget.h" -#include "lang/lang_keys.h" -#include "dialogs/dialogs_indexed_list.h" namespace { -base::flat_set> GetAlreadyInFromPeer(PeerData *peer) { +base::flat_set> GetAlreadyInFromPeer(PeerData *peer) { if (!peer) { return {}; } if (auto chat = peer->asChat()) { auto participants = chat->participants.keys(); - return { participants.cbegin(), participants.cend() }; + return {participants.cbegin(), participants.cend()}; } else if (auto channel = peer->asChannel()) { if (channel->isMegagroup()) { auto &participants = channel->mgInfo->lastParticipants; - return { participants.cbegin(), participants.cend() }; + return {participants.cbegin(), participants.cend()}; } } return {}; @@ -53,13 +53,13 @@ base::flat_set> GetAlreadyInFromPeer(PeerData *peer) { // Not used for now. // -//MembersAddButton::MembersAddButton(QWidget *parent, const style::TwoIconButton &st) : RippleButton(parent, st.ripple) +// MembersAddButton::MembersAddButton(QWidget *parent, const style::TwoIconButton &st) : RippleButton(parent, st.ripple) //, _st(st) { // resize(_st.width, _st.height); // setCursor(style::cur_pointer); //} // -//void MembersAddButton::paintEvent(QPaintEvent *e) { +// void MembersAddButton::paintEvent(QPaintEvent *e) { // Painter p(this); // // auto ms = getms(); @@ -71,17 +71,18 @@ base::flat_set> GetAlreadyInFromPeer(PeerData *peer) { // ((over || down) ? _st.iconAboveOver : _st.iconAbove).paint(p, _st.iconPosition, width()); //} // -//QImage MembersAddButton::prepareRippleMask() const { +// QImage MembersAddButton::prepareRippleMask() const { // return Ui::RippleAnimation::ellipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize)); //} // -//QPoint MembersAddButton::prepareRippleStartPosition() const { +// QPoint MembersAddButton::prepareRippleStartPosition() const { // return mapFromGlobal(QCursor::pos()) - _st.rippleAreaPosition; //} class EditChatAdminsBoxController::LabeledCheckbox : public TWidget, private base::Subscriber { public: - LabeledCheckbox(QWidget *parent, const QString &text, bool checked = false, const style::Checkbox &st = st::defaultCheckbox, const style::Check &checkSt = st::defaultCheck); + LabeledCheckbox(QWidget *parent, const QString &text, bool checked = false, + const style::Checkbox &st = st::defaultCheckbox, const style::Check &checkSt = st::defaultCheck); base::Observable checkedChanged; @@ -89,12 +90,8 @@ public: return _checkbox->checked(); } - void setLabelText( - bool checked, - const style::TextStyle &st, - const QString &text, - const TextParseOptions &options = _defaultOptions, - int minResizeWidth = QFIXED_MAX); + void setLabelText(bool checked, const style::TextStyle &st, const QString &text, + const TextParseOptions &options = _defaultOptions, int minResizeWidth = QFIXED_MAX); protected: int resizeGetHeight(int newWidth) override; @@ -105,7 +102,6 @@ private: Text _labelUnchecked; Text _labelChecked; int _labelWidth = 0; - }; void PeerListRowWithLink::setActionLink(const QString &action) { @@ -128,7 +124,10 @@ QSize PeerListRowWithLink::actionSize() const { } QMargins PeerListRowWithLink::actionMargins() const { - return QMargins(st::contactsCheckPosition.x(), (st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom() - st::normalFont->height) / 2, st::contactsCheckPosition.x(), 0); + return QMargins( + st::contactsCheckPosition.x(), + (st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom() - st::normalFont->height) / 2, + st::contactsCheckPosition.x(), 0); } void PeerListRowWithLink::paintAction(Painter &p, TimeMs ms, int x, int y, int outerWidth, bool actionSelected) { @@ -164,14 +163,16 @@ bool PeerListGlobalSearchController::searchInCache() { } void PeerListGlobalSearchController::searchOnServer() { - _requestId = request(MTPcontacts_Search(MTP_string(_query), MTP_int(SearchPeopleLimit))).done([this](const MTPcontacts_Found &result, mtpRequestId requestId) { - searchDone(result, requestId); - }).fail([this](const RPCError &error, mtpRequestId requestId) { - if (_requestId == requestId) { - _requestId = 0; - delegate()->peerListSearchRefreshRows(); - } - }).send(); + _requestId = + request(MTPcontacts_Search(MTP_string(_query), MTP_int(SearchPeopleLimit))) + .done([this](const MTPcontacts_Found &result, mtpRequestId requestId) { searchDone(result, requestId); }) + .fail([this](const RPCError &error, mtpRequestId requestId) { + if (_requestId == requestId) { + _requestId = 0; + delegate()->peerListSearchRefreshRows(); + } + }) + .send(); _queries.emplace(_requestId, _query); } @@ -205,8 +206,8 @@ bool PeerListGlobalSearchController::isLoading() { return _timer.isActive() || _requestId; } -ChatsListBoxController::ChatsListBoxController(std::unique_ptr searchController) : PeerListController(std::move(searchController)) { -} +ChatsListBoxController::ChatsListBoxController(std::unique_ptr searchController) + : PeerListController(std::move(searchController)) {} void ChatsListBoxController::prepare() { setSearchNoResultsText(lang(lng_blocked_list_not_found)); @@ -217,15 +218,9 @@ void ChatsListBoxController::prepare() { rebuildRows(); auto &sessionData = Auth().data(); - subscribe(sessionData.contactsLoaded(), [this](bool loaded) { - rebuildRows(); - }); - subscribe(sessionData.moreChatsLoaded(), [this] { - rebuildRows(); - }); - subscribe(sessionData.allChatsLoaded(), [this](bool loaded) { - checkForEmptyRows(); - }); + subscribe(sessionData.contactsLoaded(), [this](bool loaded) { rebuildRows(); }); + subscribe(sessionData.moreChatsLoaded(), [this] { rebuildRows(); }); + subscribe(sessionData.allChatsLoaded(), [this](bool loaded) { checkForEmptyRows(); }); } void ChatsListBoxController::rebuildRows() { @@ -244,7 +239,7 @@ void ChatsListBoxController::rebuildRows() { if (!wasEmpty && added > 0) { // Place dialogs list before contactsNoDialogs list. delegate()->peerListPartitionRows([](PeerListRow &a) { - auto history = static_cast(a).history(); + auto history = static_cast(a).history(); return history->inChatList(Dialogs::Mode::All); }); } @@ -266,13 +261,13 @@ QString ChatsListBoxController::emptyBoxText() const { return lang(lng_contacts_not_found); } -std::unique_ptr ChatsListBoxController::createSearchRow(not_null peer) { +std::unique_ptr ChatsListBoxController::createSearchRow(not_null peer) { return createRow(App::history(peer)); } -bool ChatsListBoxController::appendRow(not_null history) { +bool ChatsListBoxController::appendRow(not_null history) { if (auto row = delegate()->peerListFindRow(history->peer->id)) { - updateRowHook(static_cast(row)); + updateRowHook(static_cast(row)); return false; } if (auto row = createRow(history)) { @@ -282,8 +277,8 @@ bool ChatsListBoxController::appendRow(not_null history) { return false; } -ContactsBoxController::ContactsBoxController(std::unique_ptr searchController) : PeerListController(std::move(searchController)) { -} +ContactsBoxController::ContactsBoxController(std::unique_ptr searchController) + : PeerListController(std::move(searchController)) {} void ContactsBoxController::prepare() { setSearchNoResultsText(lang(lng_blocked_list_not_found)); @@ -295,9 +290,7 @@ void ContactsBoxController::prepare() { rebuildRows(); auto &sessionData = Auth().data(); - subscribe(sessionData.contactsLoaded(), [this](bool loaded) { - rebuildRows(); - }); + subscribe(sessionData.contactsLoaded(), [this](bool loaded) { rebuildRows(); }); } void ContactsBoxController::rebuildRows() { @@ -328,18 +321,18 @@ void ContactsBoxController::checkForEmptyRows() { } } -std::unique_ptr ContactsBoxController::createSearchRow(not_null peer) { +std::unique_ptr ContactsBoxController::createSearchRow(not_null peer) { if (auto user = peer->asUser()) { return createRow(user); } return nullptr; } -void ContactsBoxController::rowClicked(not_null row) { +void ContactsBoxController::rowClicked(not_null row) { Ui::showPeerHistory(row->peer(), ShowAtUnreadMsgId); } -bool ContactsBoxController::appendRow(not_null user) { +bool ContactsBoxController::appendRow(not_null user) { if (auto row = delegate()->peerListFindRow(user->id)) { updateRowHook(row); return false; @@ -351,25 +344,22 @@ bool ContactsBoxController::appendRow(not_null user) { return false; } -std::unique_ptr ContactsBoxController::createRow(not_null user) { +std::unique_ptr ContactsBoxController::createRow(not_null user) { return std::make_unique(user); } AddParticipantsBoxController::AddParticipantsBoxController(PeerData *peer) -: ContactsBoxController(std::make_unique()) -, _peer(peer) -, _alreadyIn(GetAlreadyInFromPeer(peer)) { -} + : ContactsBoxController(std::make_unique()) + , _peer(peer) + , _alreadyIn(GetAlreadyInFromPeer(peer)) {} -AddParticipantsBoxController::AddParticipantsBoxController( - not_null channel, - base::flat_set> &&alreadyIn) -: ContactsBoxController(std::make_unique()) -, _peer(channel) -, _alreadyIn(std::move(alreadyIn)) { -} +AddParticipantsBoxController::AddParticipantsBoxController(not_null channel, + base::flat_set> &&alreadyIn) + : ContactsBoxController(std::make_unique()) + , _peer(channel) + , _alreadyIn(std::move(alreadyIn)) {} -void AddParticipantsBoxController::rowClicked(not_null row) { +void AddParticipantsBoxController::rowClicked(not_null row) { auto count = fullCount(); auto limit = (_peer && _peer->isMegagroup()) ? Global::MegagroupSizeMax() : Global::ChatSizeMax(); if (count < limit || row->checked()) { @@ -380,11 +370,12 @@ void AddParticipantsBoxController::rowClicked(not_null row) { Ui::show(Box(_peer->asChannel()), KeepOtherLayers); } } else if (count >= Global::ChatSizeMax() && count < Global::MegagroupSizeMax()) { - Ui::show(Box(lng_profile_add_more_after_upgrade(lt_count, Global::MegagroupSizeMax())), KeepOtherLayers); + Ui::show(Box(lng_profile_add_more_after_upgrade(lt_count, Global::MegagroupSizeMax())), + KeepOtherLayers); } } -void AddParticipantsBoxController::itemDeselectedHook(not_null peer) { +void AddParticipantsBoxController::itemDeselectedHook(not_null peer) { updateTitle(); } @@ -404,15 +395,15 @@ int AddParticipantsBoxController::alreadyInCount() const { Unexpected("User in AddParticipantsBoxController::alreadyInCount"); } -bool AddParticipantsBoxController::isAlreadyIn(not_null user) const { +bool AddParticipantsBoxController::isAlreadyIn(not_null user) const { if (!_peer) { return false; } if (auto chat = _peer->asChat()) { return chat->participants.contains(user); } else if (auto channel = _peer->asChannel()) { - return _alreadyIn.contains(user) - || (channel->isMegagroup() && channel->mgInfo->lastParticipants.contains(user)); + return _alreadyIn.contains(user) || + (channel->isMegagroup() && channel->mgInfo->lastParticipants.contains(user)); } Unexpected("User in AddParticipantsBoxController::isAlreadyIn"); } @@ -421,7 +412,7 @@ int AddParticipantsBoxController::fullCount() const { return alreadyInCount() + delegate()->peerListSelectedRowsCount(); } -std::unique_ptr AddParticipantsBoxController::createRow(not_null user) { +std::unique_ptr AddParticipantsBoxController::createRow(not_null user) { if (user->isSelf()) { return nullptr; } @@ -433,19 +424,19 @@ std::unique_ptr AddParticipantsBoxController::createRow(not_nullisChannel() && !_peer->isMegagroup()) - ? QString() : - QString("%1 / %2").arg(fullCount()).arg(Global::MegagroupSizeMax()); + auto additional = (_peer && _peer->isChannel() && !_peer->isMegagroup()) ? + QString() : + QString("%1 / %2").arg(fullCount()).arg(Global::MegagroupSizeMax()); delegate()->peerListSetTitle(langFactory(lng_profile_add_participant)); delegate()->peerListSetAdditionalTitle([additional] { return additional; }); } -void AddParticipantsBoxController::Start(not_null chat) { - auto initBox = [chat](not_null box) { +void AddParticipantsBoxController::Start(not_null chat) { + auto initBox = [chat](not_null box) { box->addButton(langFactory(lng_participant_invite), [box, chat] { auto rows = box->peerListCollectSelectedRows(); if (!rows.empty()) { - auto users = std::vector>(); + auto users = std::vector>(); for (auto peer : rows) { auto user = peer->asUser(); Assert(user != nullptr); @@ -461,16 +452,14 @@ void AddParticipantsBoxController::Start(not_null chat) { Ui::show(Box(std::make_unique(chat), std::move(initBox))); } -void AddParticipantsBoxController::Start( - not_null channel, - base::flat_set> &&alreadyIn, - bool justCreated) { - auto initBox = [channel, justCreated](not_null box) { +void AddParticipantsBoxController::Start(not_null channel, + base::flat_set> &&alreadyIn, bool justCreated) { + auto initBox = [channel, justCreated](not_null box) { auto subscription = std::make_shared(); box->addButton(langFactory(lng_participant_invite), [box, channel, subscription] { auto rows = box->peerListCollectSelectedRows(); if (!rows.empty()) { - auto users = std::vector>(); + auto users = std::vector>(); for (auto peer : rows) { auto user = peer->asUser(); Assert(user != nullptr); @@ -487,41 +476,33 @@ void AddParticipantsBoxController::Start( }); box->addButton(langFactory(justCreated ? lng_create_group_skip : lng_cancel), [box] { box->closeBox(); }); if (justCreated) { - *subscription = box->boxClosing.add_subscription([channel] { - Ui::showPeerHistory(channel, ShowAtTheEndMsgId); - }); + *subscription = + box->boxClosing.add_subscription([channel] { Ui::showPeerHistory(channel, ShowAtTheEndMsgId); }); } }; - Ui::show(Box(std::make_unique(channel, std::move(alreadyIn)), std::move(initBox))); + Ui::show(Box(std::make_unique(channel, std::move(alreadyIn)), + std::move(initBox))); } -void AddParticipantsBoxController::Start( - not_null channel, - base::flat_set> &&alreadyIn) { +void AddParticipantsBoxController::Start(not_null channel, + base::flat_set> &&alreadyIn) { Start(channel, std::move(alreadyIn), false); } -void AddParticipantsBoxController::Start(not_null channel) { +void AddParticipantsBoxController::Start(not_null channel) { Start(channel, {}, true); } -EditChatAdminsBoxController::LabeledCheckbox::LabeledCheckbox( - QWidget *parent, - const QString &text, - bool checked, - const style::Checkbox &st, - const style::Check &checkSt) -: TWidget(parent) -, _checkbox(this, text, checked, st, checkSt) { +EditChatAdminsBoxController::LabeledCheckbox::LabeledCheckbox(QWidget *parent, const QString &text, bool checked, + const style::Checkbox &st, const style::Check &checkSt) + : TWidget(parent) + , _checkbox(this, text, checked, st, checkSt) { subscribe(_checkbox->checkedChanged, [this](bool value) { checkedChanged.notify(value, true); }); } -void EditChatAdminsBoxController::LabeledCheckbox::setLabelText( - bool checked, - const style::TextStyle &st, - const QString &text, - const TextParseOptions &options, - int minResizeWidth) { +void EditChatAdminsBoxController::LabeledCheckbox::setLabelText(bool checked, const style::TextStyle &st, + const QString &text, const TextParseOptions &options, + int minResizeWidth) { auto &label = (checked ? _labelChecked : _labelUnchecked); label = Text(st, text, options, minResizeWidth); } @@ -530,9 +511,7 @@ int EditChatAdminsBoxController::LabeledCheckbox::resizeGetHeight(int newWidth) _labelWidth = newWidth - st::contactsPadding.left() - st::contactsPadding.right(); _checkbox->resizeToNaturalWidth(_labelWidth); _checkbox->moveToLeft(st::contactsPadding.left(), st::contactsAllAdminsTop); - auto labelHeight = std::max( - _labelChecked.countHeight(_labelWidth), - _labelUnchecked.countHeight(_labelWidth)); + auto labelHeight = std::max(_labelChecked.countHeight(_labelWidth), _labelUnchecked.countHeight(_labelWidth)); return st::contactsAboutTop + labelHeight + st::contactsAboutBottom; } @@ -544,17 +523,18 @@ void EditChatAdminsBoxController::LabeledCheckbox::paintEvent(QPaintEvent *e) { p.fillRect(infoRect, st::contactsAboutBg); auto dividerFillTop = rtlrect(0, infoRect.y(), width(), st::profileDividerTop.height(), width()); st::profileDividerTop.fill(p, dividerFillTop); - auto dividerFillBottom = rtlrect(0, infoRect.y() + infoRect.height() - st::profileDividerBottom.height(), width(), st::profileDividerBottom.height(), width()); + auto dividerFillBottom = rtlrect(0, infoRect.y() + infoRect.height() - st::profileDividerBottom.height(), width(), + st::profileDividerBottom.height(), width()); st::profileDividerBottom.fill(p, dividerFillBottom); p.setPen(st::contactsAboutFg); - (checked() ? _labelChecked : _labelUnchecked).draw(p, st::contactsPadding.left(), st::contactsAboutTop, _labelWidth); + (checked() ? _labelChecked : _labelUnchecked) + .draw(p, st::contactsPadding.left(), st::contactsAboutTop, _labelWidth); } -EditChatAdminsBoxController::EditChatAdminsBoxController(not_null chat) -: PeerListController() -, _chat(chat) { -} +EditChatAdminsBoxController::EditChatAdminsBoxController(not_null chat) + : PeerListController() + , _chat(chat) {} bool EditChatAdminsBoxController::allAreAdmins() const { return _allAdmins->checked(); @@ -570,16 +550,16 @@ void EditChatAdminsBoxController::prepare() { rebuildRows(); if (!delegate()->peerListFullRowsCount()) { Auth().api().requestFullPeer(_chat); - _adminsUpdatedSubscription = subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler( - Notify::PeerUpdate::Flag::AdminsChanged, [this]( - const Notify::PeerUpdate &update) { - if (update.peer == _chat) { - rebuildRows(); - if (delegate()->peerListFullRowsCount()) { - unsubscribe(_adminsUpdatedSubscription); - } - } - })); + _adminsUpdatedSubscription = subscribe( + Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::AdminsChanged, + [this](const Notify::PeerUpdate &update) { + if (update.peer == _chat) { + rebuildRows(); + if (delegate()->peerListFullRowsCount()) { + unsubscribe(_adminsUpdatedSubscription); + } + } + })); } subscribe(_allAdmins->checkedChanged, [this](bool checked) { @@ -598,7 +578,8 @@ void EditChatAdminsBoxController::prepare() { void EditChatAdminsBoxController::createAllAdminsCheckbox() { auto labelWidth = st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right(); - auto checkbox = object_ptr(nullptr, lang(lng_chat_all_members_admins), !_chat->adminsEnabled(), st::defaultBoxCheckbox); + auto checkbox = object_ptr(nullptr, lang(lng_chat_all_members_admins), !_chat->adminsEnabled(), + st::defaultBoxCheckbox); checkbox->setLabelText(true, st::defaultTextStyle, lang(lng_chat_about_all_admins), _defaultOptions, labelWidth); checkbox->setLabelText(false, st::defaultTextStyle, lang(lng_chat_about_admins), _defaultOptions, labelWidth); _allAdmins = checkbox; @@ -612,7 +593,7 @@ void EditChatAdminsBoxController::rebuildRows() { auto allAdmins = allAreAdmins(); - auto admins = std::vector>(); + auto admins = std::vector>(); auto others = admins; admins.reserve(allAdmins ? _chat->participants.size() : _chat->admins.size()); others.reserve(_chat->participants.size()); @@ -633,13 +614,11 @@ void EditChatAdminsBoxController::rebuildRows() { admins.insert(admins.end(), others.begin(), others.end()); others.clear(); } - auto sortByName = [](auto a, auto b) { - return (a->name.compare(b->name, Qt::CaseInsensitive) < 0); - }; + auto sortByName = [](auto a, auto b) { return (a->name.compare(b->name, Qt::CaseInsensitive) < 0); }; std::sort(admins.begin(), admins.end(), sortByName); std::sort(others.begin(), others.end(), sortByName); - auto addOne = [this](not_null user) { + auto addOne = [this](not_null user) { if (auto row = createRow(user)) { delegate()->peerListAppendRow(std::move(row)); } @@ -655,7 +634,7 @@ void EditChatAdminsBoxController::rebuildRows() { delegate()->peerListRefreshRows(); } -std::unique_ptr EditChatAdminsBoxController::createRow(not_null user) { +std::unique_ptr EditChatAdminsBoxController::createRow(not_null user) { auto result = std::make_unique(user); if (allAreAdmins() || user->id == peerFromUser(_chat->creator)) { result->setDisabledState(PeerListRow::State::DisabledChecked); @@ -663,23 +642,23 @@ std::unique_ptr EditChatAdminsBoxController::createRow(not_null row) { +void EditChatAdminsBoxController::rowClicked(not_null row) { delegate()->peerListSetRowChecked(row, !row->checked()); } -void EditChatAdminsBoxController::Start(not_null chat) { +void EditChatAdminsBoxController::Start(not_null chat) { auto controller = std::make_unique(chat); - auto initBox = [chat, controller = controller.get()](not_null box) { + auto initBox = [chat, controller = controller.get()](not_null box) { box->addButton(langFactory(lng_settings_save), [box, chat, controller] { auto rows = box->peerListCollectSelectedRows(); - auto users = std::vector>(); + auto users = std::vector>(); for (auto peer : rows) { auto user = peer->asUser(); Assert(user != nullptr); Assert(!user->isSelf()); users.push_back(peer->asUser()); } - Auth().api().editChatAdmins(chat, !controller->allAreAdmins(), { users.cbegin(), users.cend() }); + Auth().api().editChatAdmins(chat, !controller->allAreAdmins(), {users.cbegin(), users.cend()}); box->closeBox(); }); box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); }); @@ -687,21 +666,18 @@ void EditChatAdminsBoxController::Start(not_null chat) { Ui::show(Box(std::move(controller), std::move(initBox))); } -void AddBotToGroupBoxController::Start(not_null bot) { - auto initBox = [bot](not_null box) { +void AddBotToGroupBoxController::Start(not_null bot) { + auto initBox = [bot](not_null box) { box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); }); }; Ui::show(Box(std::make_unique(bot), std::move(initBox))); } -AddBotToGroupBoxController::AddBotToGroupBoxController(not_null bot) -: ChatsListBoxController(SharingBotGame(bot) - ? std::make_unique() - : nullptr) -, _bot(bot) { -} +AddBotToGroupBoxController::AddBotToGroupBoxController(not_null bot) + : ChatsListBoxController(SharingBotGame(bot) ? std::make_unique() : nullptr) + , _bot(bot) {} -void AddBotToGroupBoxController::rowClicked(not_null row) { +void AddBotToGroupBoxController::rowClicked(not_null row) { if (sharingBotGame()) { shareBotGame(row->peer()); } else { @@ -709,7 +685,7 @@ void AddBotToGroupBoxController::rowClicked(not_null row) { } } -void AddBotToGroupBoxController::shareBotGame(not_null chat) { +void AddBotToGroupBoxController::shareBotGame(not_null chat) { auto weak = base::make_weak_unique(this); auto send = [weak, bot = _bot, chat] { if (!weak) { @@ -719,16 +695,9 @@ void AddBotToGroupBoxController::shareBotGame(not_null chat) { auto afterRequestId = history ? history->sendRequestId : 0; auto randomId = rand_value(); auto gameShortName = bot->botInfo->shareGameShortName; - auto inputGame = MTP_inputGameShortName( - bot->inputUser, - MTP_string(gameShortName)); - auto request = MTPmessages_SendMedia( - MTP_flags(0), - chat->input, - MTP_int(0), - MTP_inputMediaGame(inputGame), - MTP_long(randomId), - MTPnullMarkup); + auto inputGame = MTP_inputGameShortName(bot->inputUser, MTP_string(gameShortName)); + auto request = MTPmessages_SendMedia(MTP_flags(0), chat->input, MTP_int(0), MTP_inputMediaGame(inputGame), + MTP_long(randomId), MTPnullMarkup); auto done = App::main()->rpcDone(&MainWidget::sentUpdatesReceived); auto fail = App::main()->rpcFail(&MainWidget::sendMessageFail); auto requestId = MTP::send(request, done, fail, 0, 0, afterRequestId); @@ -747,7 +716,7 @@ void AddBotToGroupBoxController::shareBotGame(not_null chat) { Ui::show(Box(confirmText(), send), KeepOtherLayers); } -void AddBotToGroupBoxController::addBotToGroup(not_null chat) { +void AddBotToGroupBoxController::addBotToGroup(not_null chat) { if (auto megagroup = chat->asMegagroup()) { if (!megagroup->canAddMembers()) { Ui::show(Box(lang(lng_error_cant_add_member)), KeepOtherLayers); @@ -761,26 +730,16 @@ void AddBotToGroupBoxController::addBotToGroup(not_null chat) { } if (auto &info = bot->botInfo) { if (!info->startGroupToken.isEmpty()) { - auto request = MTPmessages_StartBot( - bot->inputUser, - chat->input, - MTP_long(rand_value()), - MTP_string(info->startGroupToken)); - auto done = App::main()->rpcDone( - &MainWidget::sentUpdatesReceived); - auto fail = App::main()->rpcFail( - &MainWidget::addParticipantFail, - { bot, chat }); + auto request = MTPmessages_StartBot(bot->inputUser, chat->input, MTP_long(rand_value()), + MTP_string(info->startGroupToken)); + auto done = App::main()->rpcDone(&MainWidget::sentUpdatesReceived); + auto fail = App::main()->rpcFail(&MainWidget::addParticipantFail, {bot, chat}); MTP::send(request, done, fail); } else { - App::main()->addParticipants( - chat, - { 1, bot }); + App::main()->addParticipants(chat, {1, bot}); } } else { - App::main()->addParticipants( - chat, - { 1, bot }); + App::main()->addParticipants(chat, {1, bot}); } Ui::hideLayer(); Ui::showPeerHistory(chat, ShowAtUnreadMsgId); @@ -789,14 +748,14 @@ void AddBotToGroupBoxController::addBotToGroup(not_null chat) { Ui::show(Box(confirmText, send), KeepOtherLayers); } -std::unique_ptr AddBotToGroupBoxController::createRow(not_null history) { +std::unique_ptr AddBotToGroupBoxController::createRow(not_null history) { if (!needToCreateRow(history->peer)) { return nullptr; } return std::make_unique(history); } -bool AddBotToGroupBoxController::needToCreateRow(not_null peer) const { +bool AddBotToGroupBoxController::needToCreateRow(not_null peer) const { if (sharingBotGame()) { if (!peer->canWrite()) { return false; @@ -818,7 +777,7 @@ bool AddBotToGroupBoxController::needToCreateRow(not_null peer) const return false; } -bool AddBotToGroupBoxController::SharingBotGame(not_null bot) { +bool AddBotToGroupBoxController::SharingBotGame(not_null bot) { auto &info = bot->botInfo; return (info && !info->shareGameShortName.isEmpty()); } @@ -828,15 +787,14 @@ bool AddBotToGroupBoxController::sharingBotGame() const { } QString AddBotToGroupBoxController::emptyBoxText() const { - return lang(Auth().data().allChatsLoaded().value() - ? (sharingBotGame() ? lng_bot_no_chats : lng_bot_no_groups) - : lng_contacts_loading); + return lang(Auth().data().allChatsLoaded().value() ? (sharingBotGame() ? lng_bot_no_chats : lng_bot_no_groups) : + lng_contacts_loading); } QString AddBotToGroupBoxController::noResultsText() const { - return lang(Auth().data().allChatsLoaded().value() - ? (sharingBotGame() ? lng_bot_chats_not_found : lng_bot_groups_not_found) - : lng_contacts_loading); + return lang(Auth().data().allChatsLoaded().value() ? + (sharingBotGame() ? lng_bot_chats_not_found : lng_bot_groups_not_found) : + lng_contacts_loading); } void AddBotToGroupBoxController::updateLabels() { @@ -844,9 +802,7 @@ void AddBotToGroupBoxController::updateLabels() { } void AddBotToGroupBoxController::prepareViewHook() { - delegate()->peerListSetTitle(langFactory(sharingBotGame() - ? lng_bot_choose_chat - : lng_bot_choose_group)); + delegate()->peerListSetTitle(langFactory(sharingBotGame() ? lng_bot_choose_chat : lng_bot_choose_group)); updateLabels(); subscribe(Auth().data().allChatsLoaded(), [this](bool) { updateLabels(); }); } diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.h b/Telegram/SourceFiles/boxes/peer_list_controllers.h index 14d2fbcd3..a5fc86a4b 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.h +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.h @@ -20,24 +20,24 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include "boxes/peer_list_box.h" #include "base/flat_set.h" #include "base/weak_unique_ptr.h" +#include "boxes/peer_list_box.h" #include "history/history.h" // Not used for now. // -//class MembersAddButton : public Ui::RippleButton { -//public: +// class MembersAddButton : public Ui::RippleButton { +// public: // MembersAddButton(QWidget *parent, const style::TwoIconButton &st); // -//protected: +// protected: // void paintEvent(QPaintEvent *e) override; // // QImage prepareRippleMask() const override; // QPoint prepareRippleStartPosition() const override; // -//private: +// private: // const style::TwoIconButton &_st; // //}; @@ -58,7 +58,6 @@ private: QString _action; int _actionWidth = 0; - }; class PeerListGlobalSearchController : public PeerListSearchController, private MTP::Sender { @@ -81,151 +80,138 @@ private: mtpRequestId _requestId = 0; std::map _cache; std::map _queries; - }; class ChatsListBoxController : public PeerListController, protected base::Subscriber { public: - ChatsListBoxController(std::unique_ptr searchController = std::make_unique()); + ChatsListBoxController(std::unique_ptr searchController = + std::make_unique()); void prepare() override final; - std::unique_ptr createSearchRow(not_null peer) override final; + std::unique_ptr createSearchRow(not_null peer) override final; protected: class Row : public PeerListRow { public: - Row(not_null history) : PeerListRow(history->peer), _history(history) { - } - not_null history() const { + Row(not_null history) + : PeerListRow(history->peer) + , _history(history) {} + not_null history() const { return _history; } private: - not_null _history; - + not_null _history; }; - virtual std::unique_ptr createRow(not_null history) = 0; + virtual std::unique_ptr createRow(not_null history) = 0; virtual void prepareViewHook() = 0; - virtual void updateRowHook(not_null row) { - } + virtual void updateRowHook(not_null row) {} virtual QString emptyBoxText() const; private: void rebuildRows(); void checkForEmptyRows(); - bool appendRow(not_null history); - + bool appendRow(not_null history); }; class ContactsBoxController : public PeerListController, protected base::Subscriber { public: - ContactsBoxController(std::unique_ptr searchController = std::make_unique()); + ContactsBoxController(std::unique_ptr searchController = + std::make_unique()); void prepare() override final; - std::unique_ptr createSearchRow(not_null peer) override final; - void rowClicked(not_null row) override; + std::unique_ptr createSearchRow(not_null peer) override final; + void rowClicked(not_null row) override; protected: - virtual std::unique_ptr createRow(not_null user); - virtual void prepareViewHook() { - } - virtual void updateRowHook(not_null row) { - } + virtual std::unique_ptr createRow(not_null user); + virtual void prepareViewHook() {} + virtual void updateRowHook(not_null row) {} private: void rebuildRows(); void checkForEmptyRows(); - bool appendRow(not_null user); - + bool appendRow(not_null user); }; class EditChatAdminsBoxController : public PeerListController, private base::Subscriber { public: - static void Start(not_null chat); + static void Start(not_null chat); - EditChatAdminsBoxController(not_null chat); + EditChatAdminsBoxController(not_null chat); bool allAreAdmins() const; void prepare() override; - void rowClicked(not_null row) override; + void rowClicked(not_null row) override; private: void createAllAdminsCheckbox(); void rebuildRows(); - std::unique_ptr createRow(not_null user); + std::unique_ptr createRow(not_null user); - not_null _chat; + not_null _chat; int _adminsUpdatedSubscription = 0; class LabeledCheckbox; QPointer _allAdmins; - }; class AddParticipantsBoxController : public ContactsBoxController { public: - static void Start(not_null chat); - static void Start(not_null channel); - static void Start( - not_null channel, - base::flat_set> &&alreadyIn); + static void Start(not_null chat); + static void Start(not_null channel); + static void Start(not_null channel, base::flat_set> &&alreadyIn); AddParticipantsBoxController(PeerData *peer); - AddParticipantsBoxController( - not_null channel, - base::flat_set> &&alreadyIn); + AddParticipantsBoxController(not_null channel, base::flat_set> &&alreadyIn); using ContactsBoxController::ContactsBoxController; - void rowClicked(not_null row) override; - void itemDeselectedHook(not_null peer) override; + void rowClicked(not_null row) override; + void itemDeselectedHook(not_null peer) override; protected: void prepareViewHook() override; - std::unique_ptr createRow(not_null user) override; + std::unique_ptr createRow(not_null user) override; private: - static void Start( - not_null channel, - base::flat_set> &&alreadyIn, - bool justCreated); + static void Start(not_null channel, base::flat_set> &&alreadyIn, + bool justCreated); int alreadyInCount() const; - bool isAlreadyIn(not_null user) const; + bool isAlreadyIn(not_null user) const; int fullCount() const; void updateTitle(); PeerData *_peer = nullptr; - base::flat_set> _alreadyIn; - + base::flat_set> _alreadyIn; }; class AddBotToGroupBoxController : public ChatsListBoxController, public base::enable_weak_from_this { public: - static void Start(not_null bot); + static void Start(not_null bot); - AddBotToGroupBoxController(not_null bot); + AddBotToGroupBoxController(not_null bot); - void rowClicked(not_null row) override; + void rowClicked(not_null row) override; protected: - std::unique_ptr createRow(not_null history) override; + std::unique_ptr createRow(not_null history) override; void prepareViewHook() override; QString emptyBoxText() const override; private: - static bool SharingBotGame(not_null bot); + static bool SharingBotGame(not_null bot); - bool needToCreateRow(not_null peer) const; + bool needToCreateRow(not_null peer) const; bool sharingBotGame() const; QString noResultsText() const; QString descriptionText() const; void updateLabels(); - void shareBotGame(not_null chat); - void addBotToGroup(not_null chat); - - not_null _bot; + void shareBotGame(not_null chat); + void addBotToGroup(not_null chat); + not_null _bot; }; diff --git a/Telegram/SourceFiles/boxes/photo_crop_box.cpp b/Telegram/SourceFiles/boxes/photo_crop_box.cpp index b38985ce2..e1882ed7f 100644 --- a/Telegram/SourceFiles/boxes/photo_crop_box.cpp +++ b/Telegram/SourceFiles/boxes/photo_crop_box.cpp @@ -21,21 +21,21 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "boxes/photo_crop_box.h" #include "lang/lang_keys.h" -#include "messenger.h" #include "mainwidget.h" +#include "messenger.h" #include "storage/file_upload.h" -#include "ui/widgets/buttons.h" #include "styles/style_boxes.h" +#include "ui/widgets/buttons.h" -PhotoCropBox::PhotoCropBox(QWidget*, const QImage &img, const PeerId &peer) -: _img(img) -, _peerId(peer) { +PhotoCropBox::PhotoCropBox(QWidget *, const QImage &img, const PeerId &peer) + : _img(img) + , _peerId(peer) { init(img, nullptr); } -PhotoCropBox::PhotoCropBox(QWidget*, const QImage &img, PeerData *peer) -: _img(img) -, _peerId(peer->id) { +PhotoCropBox::PhotoCropBox(QWidget *, const QImage &img, PeerData *peer) + : _img(img) + , _peerId(peer->id) { init(img, peer); } @@ -53,11 +53,12 @@ void PhotoCropBox::prepare() { addButton(langFactory(lng_settings_save), [this] { sendPhoto(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); if (peerToBareInt(_peerId)) { - connect(this, SIGNAL(ready(const QImage&)), this, SLOT(onReady(const QImage&))); + connect(this, SIGNAL(ready(const QImage &)), this, SLOT(onReady(const QImage &))); } qint32 s = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(); - _thumb = App::pixmapFromImageInPlace(_img.scaled(s * cIntRetinaFactor(), s * cIntRetinaFactor(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + _thumb = App::pixmapFromImageInPlace( + _img.scaled(s * cIntRetinaFactor(), s * cIntRetinaFactor(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); _thumb.setDevicePixelRatio(cRetinaFactor()); _mask = QImage(_thumb.size(), QImage::Format_ARGB32_Premultiplied); _mask.setDevicePixelRatio(cRetinaFactor()); @@ -77,7 +78,8 @@ void PhotoCropBox::prepare() { _thumby = st::boxPhotoPadding.top(); setMouseTracking(true); - setDimensions(st::boxWideWidth, st::boxPhotoPadding.top() + _thumbh + st::boxPhotoPadding.bottom() + st::boxTextFont->height + st::cropSkip); + setDimensions(st::boxWideWidth, st::boxPhotoPadding.top() + _thumbh + st::boxPhotoPadding.bottom() + + st::boxTextFont->height + st::cropSkip); } void PhotoCropBox::mousePressEvent(QMouseEvent *e) { @@ -231,7 +233,9 @@ void PhotoCropBox::paintEvent(QPaintEvent *e) { p.setFont(st::boxTextFont); p.setPen(st::boxPhotoTextFg); - p.drawText(QRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top() + _thumbh + st::boxPhotoPadding.bottom(), width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), st::boxTextFont->height), _title, style::al_top); + p.drawText(QRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top() + _thumbh + st::boxPhotoPadding.bottom(), + width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), st::boxTextFont->height), + _title, style::al_top); p.translate(_thumbx, _thumby); p.drawPixmap(0, 0, _thumb); diff --git a/Telegram/SourceFiles/boxes/photo_crop_box.h b/Telegram/SourceFiles/boxes/photo_crop_box.h index 6f798860f..6d946443f 100644 --- a/Telegram/SourceFiles/boxes/photo_crop_box.h +++ b/Telegram/SourceFiles/boxes/photo_crop_box.h @@ -26,8 +26,8 @@ class PhotoCropBox : public BoxContent { Q_OBJECT public: - PhotoCropBox(QWidget*, const QImage &img, const PeerId &peer); - PhotoCropBox(QWidget*, const QImage &img, PeerData *peer); + PhotoCropBox(QWidget *, const QImage &img, const PeerId &peer); + PhotoCropBox(QWidget *, const QImage &img, PeerData *peer); qint32 mouseState(QPoint p); @@ -59,5 +59,4 @@ private: QPixmap _thumb; QImage _mask, _fade; PeerId _peerId; - }; diff --git a/Telegram/SourceFiles/boxes/rate_call_box.cpp b/Telegram/SourceFiles/boxes/rate_call_box.cpp index f7c428274..131656766 100644 --- a/Telegram/SourceFiles/boxes/rate_call_box.cpp +++ b/Telegram/SourceFiles/boxes/rate_call_box.cpp @@ -20,15 +20,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/rate_call_box.h" +#include "boxes/confirm_box.h" #include "lang/lang_keys.h" +#include "mainwidget.h" +#include "mainwindow.h" #include "styles/style_boxes.h" #include "styles/style_calls.h" -#include "boxes/confirm_box.h" -#include "ui/widgets/labels.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" -#include "mainwindow.h" -#include "mainwidget.h" +#include "ui/widgets/labels.h" namespace { @@ -36,10 +36,9 @@ constexpr auto kMaxRating = 5; } // namespace -RateCallBox::RateCallBox(QWidget*, quint64 callId, quint64 callAccessHash) -: _callId(callId) -, _callAccessHash(callAccessHash) { -} +RateCallBox::RateCallBox(QWidget *, quint64 callId, quint64 callAccessHash) + : _callId(callId) + , _callAccessHash(callAccessHash) {} void RateCallBox::prepare() { setTitle(langFactory(lng_call_rate_label)); @@ -88,7 +87,8 @@ void RateCallBox::ratingChanged(int value) { _comment->show(); _comment->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); _comment->setMaxLength(MaxPhotoCaption); - _comment->resize(width() - (st::callRatingPadding.left() + st::callRatingPadding.right()), _comment->height()); + _comment->resize(width() - (st::callRatingPadding.left() + st::callRatingPadding.right()), + _comment->height()); updateMaxHeight(); connect(_comment, SIGNAL(resized()), this, SLOT(onCommentResized())); @@ -121,14 +121,19 @@ void RateCallBox::onSend() { return; } auto comment = _comment ? _comment->getLastText().trimmed() : QString(); - _requestId = request(MTPphone_SetCallRating(MTP_inputPhoneCall(MTP_long(_callId), MTP_long(_callAccessHash)), MTP_int(_rating), MTP_string(comment))).done([this](const MTPUpdates &updates) { - App::main()->sentUpdatesReceived(updates); - closeBox(); - }).fail([this](const RPCError &error) { closeBox(); }).send(); + _requestId = request(MTPphone_SetCallRating(MTP_inputPhoneCall(MTP_long(_callId), MTP_long(_callAccessHash)), + MTP_int(_rating), MTP_string(comment))) + .done([this](const MTPUpdates &updates) { + App::main()->sentUpdatesReceived(updates); + closeBox(); + }) + .fail([this](const RPCError &error) { closeBox(); }) + .send(); } void RateCallBox::updateMaxHeight() { - auto newHeight = st::callRatingPadding.top() + st::callRatingStarTop + _stars.back()->heightNoMargins() + st::callRatingPadding.bottom(); + auto newHeight = st::callRatingPadding.top() + st::callRatingStarTop + _stars.back()->heightNoMargins() + + st::callRatingPadding.bottom(); if (_comment) { newHeight += st::callRatingCommentTop + _comment->height(); } diff --git a/Telegram/SourceFiles/boxes/rate_call_box.h b/Telegram/SourceFiles/boxes/rate_call_box.h index b28603c34..e0c661d4c 100644 --- a/Telegram/SourceFiles/boxes/rate_call_box.h +++ b/Telegram/SourceFiles/boxes/rate_call_box.h @@ -33,7 +33,7 @@ class RateCallBox : public BoxContent, private MTP::Sender { Q_OBJECT public: - RateCallBox(QWidget*, quint64 callId, quint64 callAccessHash); + RateCallBox(QWidget *, quint64 callId, quint64 callAccessHash); private slots: void onSend(); @@ -57,8 +57,7 @@ private: int _rating = 0; std::vector> _stars; - object_ptr _comment = { nullptr }; + object_ptr _comment = {nullptr}; mtpRequestId _requestId = 0; - }; diff --git a/Telegram/SourceFiles/boxes/report_box.cpp b/Telegram/SourceFiles/boxes/report_box.cpp index 7f599ceef..3475388dd 100644 --- a/Telegram/SourceFiles/boxes/report_box.cpp +++ b/Telegram/SourceFiles/boxes/report_box.cpp @@ -20,26 +20,28 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/report_box.h" +#include "boxes/confirm_box.h" +#include "facades.h" #include "lang/lang_keys.h" +#include "mainwindow.h" #include "styles/style_boxes.h" #include "styles/style_profile.h" -#include "boxes/confirm_box.h" -#include "ui/widgets/checkbox.h" #include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" #include "ui/widgets/input_fields.h" -#include "mainwindow.h" -#include "facades.h" -ReportBox::ReportBox(QWidget*, PeerData *peer) : _peer(peer) -, _reasonGroup(std::make_shared>(Reason::Spam)) -, _reasonSpam(this, _reasonGroup, Reason::Spam, lang(lng_report_reason_spam), st::defaultBoxCheckbox) -, _reasonViolence(this, _reasonGroup, Reason::Violence, lang(lng_report_reason_violence), st::defaultBoxCheckbox) -, _reasonPornography(this, _reasonGroup, Reason::Pornography, lang(lng_report_reason_pornography), st::defaultBoxCheckbox) -, _reasonOther(this, _reasonGroup, Reason::Other, lang(lng_report_reason_other), st::defaultBoxCheckbox) { -} +ReportBox::ReportBox(QWidget *, PeerData *peer) + : _peer(peer) + , _reasonGroup(std::make_shared>(Reason::Spam)) + , _reasonSpam(this, _reasonGroup, Reason::Spam, lang(lng_report_reason_spam), st::defaultBoxCheckbox) + , _reasonViolence(this, _reasonGroup, Reason::Violence, lang(lng_report_reason_violence), st::defaultBoxCheckbox) + , _reasonPornography(this, _reasonGroup, Reason::Pornography, lang(lng_report_reason_pornography), + st::defaultBoxCheckbox) + , _reasonOther(this, _reasonGroup, Reason::Other, lang(lng_report_reason_other), st::defaultBoxCheckbox) {} void ReportBox::prepare() { - setTitle(langFactory(_peer->isUser() ? lng_report_bot_title : (_peer->isMegagroup() ? lng_report_group_title : lng_report_title))); + setTitle(langFactory(_peer->isUser() ? lng_report_bot_title : + (_peer->isMegagroup() ? lng_report_group_title : lng_report_title))); addButton(langFactory(lng_report_button), [this] { onReport(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); @@ -52,13 +54,19 @@ void ReportBox::prepare() { void ReportBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _reasonSpam->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), st::boxOptionListPadding.top() + _reasonSpam->getMargins().top()); - _reasonViolence->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _reasonSpam->bottomNoMargins() + st::boxOptionListSkip); - _reasonPornography->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _reasonViolence->bottomNoMargins() + st::boxOptionListSkip); - _reasonOther->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _reasonPornography->bottomNoMargins() + st::boxOptionListSkip); + _reasonSpam->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + st::boxOptionListPadding.top() + _reasonSpam->getMargins().top()); + _reasonViolence->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + _reasonSpam->bottomNoMargins() + st::boxOptionListSkip); + _reasonPornography->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + _reasonViolence->bottomNoMargins() + st::boxOptionListSkip); + _reasonOther->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), + _reasonPornography->bottomNoMargins() + st::boxOptionListSkip); if (_reasonOtherText) { - _reasonOtherText->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left() - st::defaultInputField.textMargins.left(), _reasonOther->bottomNoMargins() + st::newGroupDescriptionPadding.top()); + _reasonOtherText->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left() - + st::defaultInputField.textMargins.left(), + _reasonOther->bottomNoMargins() + st::newGroupDescriptionPadding.top()); } } @@ -69,7 +77,9 @@ void ReportBox::reasonChanged(Reason reason) { _reasonOtherText->show(); _reasonOtherText->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); _reasonOtherText->setMaxLength(MaxPhotoCaption); - _reasonOtherText->resize(width() - (st::boxPadding.left() + st::boxOptionListPadding.left() + st::boxPadding.right()), _reasonOtherText->height()); + _reasonOtherText->resize( + width() - (st::boxPadding.left() + st::boxOptionListPadding.left() + st::boxPadding.right()), + _reasonOtherText->height()); updateMaxHeight(); connect(_reasonOtherText, SIGNAL(resized()), this, SLOT(onReasonResized())); @@ -113,7 +123,8 @@ void ReportBox::onReport() { } Unexpected("Bad reason group value."); }; - _requestId = MTP::send(MTPaccount_ReportPeer(_peer->input, getReason()), rpcDone(&ReportBox::reportDone), rpcFail(&ReportBox::reportFail)); + _requestId = MTP::send(MTPaccount_ReportPeer(_peer->input, getReason()), rpcDone(&ReportBox::reportDone), + rpcFail(&ReportBox::reportFail)); } void ReportBox::reportDone(const MTPBool &result) { @@ -132,9 +143,12 @@ bool ReportBox::reportFail(const RPCError &error) { } void ReportBox::updateMaxHeight() { - auto newHeight = st::boxOptionListPadding.top() + _reasonSpam->getMargins().top() + 4 * _reasonSpam->heightNoMargins() + 3 * st::boxOptionListSkip + _reasonSpam->getMargins().bottom() + st::boxOptionListPadding.bottom(); + auto newHeight = st::boxOptionListPadding.top() + _reasonSpam->getMargins().top() + + 4 * _reasonSpam->heightNoMargins() + 3 * st::boxOptionListSkip + + _reasonSpam->getMargins().bottom() + st::boxOptionListPadding.bottom(); if (_reasonOtherText) { - newHeight += st::newGroupDescriptionPadding.top() + _reasonOtherText->height() + st::newGroupDescriptionPadding.bottom(); + newHeight += + st::newGroupDescriptionPadding.top() + _reasonOtherText->height() + st::newGroupDescriptionPadding.bottom(); } setDimensions(st::boxWidth, newHeight); } diff --git a/Telegram/SourceFiles/boxes/report_box.h b/Telegram/SourceFiles/boxes/report_box.h index 9d588179a..cfbb33d83 100644 --- a/Telegram/SourceFiles/boxes/report_box.h +++ b/Telegram/SourceFiles/boxes/report_box.h @@ -23,10 +23,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "boxes/abstract_box.h" namespace Ui { -template -class RadioenumGroup; -template -class Radioenum; +template class RadioenumGroup; +template class Radioenum; class InputArea; } // namespace Ui @@ -34,7 +32,7 @@ class ReportBox : public BoxContent, public RPCSender { Q_OBJECT public: - ReportBox(QWidget*, PeerData *peer); + ReportBox(QWidget *, PeerData *peer); private slots: void onReport(); @@ -69,8 +67,7 @@ private: object_ptr> _reasonViolence; object_ptr> _reasonPornography; object_ptr> _reasonOther; - object_ptr _reasonOtherText = { nullptr }; + object_ptr _reasonOtherText = {nullptr}; mtpRequestId _requestId = 0; - }; diff --git a/Telegram/SourceFiles/boxes/self_destruction_box.cpp b/Telegram/SourceFiles/boxes/self_destruction_box.cpp index 747e270a9..8b7873daf 100644 --- a/Telegram/SourceFiles/boxes/self_destruction_box.cpp +++ b/Telegram/SourceFiles/boxes/self_destruction_box.cpp @@ -21,61 +21,68 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "boxes/self_destruction_box.h" #include "lang/lang_keys.h" +#include "styles/style_boxes.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" -#include "styles/style_boxes.h" void SelfDestructionBox::prepare() { setTitle(langFactory(lng_self_destruct_title)); - _ttlValues = { 30, 90, 180, 365 }; + _ttlValues = {30, 90, 180, 365}; - auto fake = object_ptr(this, lang(lng_self_destruct_description), Ui::FlatLabel::InitType::Simple, st::boxLabel); - auto boxHeight = st::boxOptionListPadding.top() - + fake->height() + st::boxMediumSkip - + _ttlValues.size() * (st::defaultRadio.diameter + st::boxOptionListSkip) - st::boxOptionListSkip - + st::boxOptionListPadding.bottom() + st::boxPadding.bottom(); + auto fake = object_ptr(this, lang(lng_self_destruct_description), Ui::FlatLabel::InitType::Simple, + st::boxLabel); + auto boxHeight = st::boxOptionListPadding.top() + fake->height() + st::boxMediumSkip + + _ttlValues.size() * (st::defaultRadio.diameter + st::boxOptionListSkip) - st::boxOptionListSkip + + st::boxOptionListPadding.bottom() + st::boxPadding.bottom(); fake.destroy(); setDimensions(st::boxWidth, boxHeight); - auto loading = object_ptr(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout); + auto loading = + object_ptr(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout); loading->moveToLeft((st::boxWidth - loading->width()) / 2, boxHeight / 3); addButton(langFactory(lng_cancel), [this] { closeBox(); }); - request(MTPaccount_GetAccountTTL()).done([this, loading = std::move(loading)](const MTPAccountDaysTTL &result) mutable { - Expects(result.type() == mtpc_accountDaysTTL); - Expects(!_ttlValues.empty()); + request(MTPaccount_GetAccountTTL()) + .done([this, loading = std::move(loading)](const MTPAccountDaysTTL &result) mutable { + Expects(result.type() == mtpc_accountDaysTTL); + Expects(!_ttlValues.empty()); - loading.destroy(); - auto y = st::boxOptionListPadding.top(); - _description.create(this, lang(lng_self_destruct_description), Ui::FlatLabel::InitType::Simple, st::boxLabel); - _description->moveToLeft(st::boxPadding.left(), y); - y += _description->height() + st::boxMediumSkip; + loading.destroy(); + auto y = st::boxOptionListPadding.top(); + _description.create(this, lang(lng_self_destruct_description), Ui::FlatLabel::InitType::Simple, + st::boxLabel); + _description->moveToLeft(st::boxPadding.left(), y); + y += _description->height() + st::boxMediumSkip; - auto current = result.c_accountDaysTTL().vdays.v; - auto currentAdjusted = _ttlValues[0]; - for (auto days : _ttlValues) { - if (qAbs(current - days) < qAbs(current - currentAdjusted)) { - currentAdjusted = days; - } - } - auto group = std::make_shared(currentAdjusted); - auto count = int(_ttlValues.size()); - _options.reserve(count); - for (auto days : _ttlValues) { - _options.emplace_back(this, group, days, (days > 364) ? lng_self_destruct_years(lt_count, days / 365) : lng_self_destruct_months(lt_count, std::max(days / 30, 1)), st::langsButton); - _options.back()->moveToLeft(st::boxPadding.left(), y); - y += _options.back()->heightNoMargins() + st::boxOptionListSkip; - } - showChildren(); + auto current = result.c_accountDaysTTL().vdays.v; + auto currentAdjusted = _ttlValues[0]; + for (auto days : _ttlValues) { + if (qAbs(current - days) < qAbs(current - currentAdjusted)) { + currentAdjusted = days; + } + } + auto group = std::make_shared(currentAdjusted); + auto count = int(_ttlValues.size()); + _options.reserve(count); + for (auto days : _ttlValues) { + _options.emplace_back(this, group, days, + (days > 364) ? lng_self_destruct_years(lt_count, days / 365) : + lng_self_destruct_months(lt_count, std::max(days / 30, 1)), + st::langsButton); + _options.back()->moveToLeft(st::boxPadding.left(), y); + y += _options.back()->heightNoMargins() + st::boxOptionListSkip; + } + showChildren(); - clearButtons(); - addButton(langFactory(lng_settings_save), [this, group] { - MTP::send(MTPaccount_SetAccountTTL(MTP_accountDaysTTL(MTP_int(group->value())))); - closeBox(); - }); - addButton(langFactory(lng_cancel), [this] { closeBox(); }); - }).send(); + clearButtons(); + addButton(langFactory(lng_settings_save), [this, group] { + MTP::send(MTPaccount_SetAccountTTL(MTP_accountDaysTTL(MTP_int(group->value())))); + closeBox(); + }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); + }) + .send(); } diff --git a/Telegram/SourceFiles/boxes/self_destruction_box.h b/Telegram/SourceFiles/boxes/self_destruction_box.h index 8b4740164..d8cedc0df 100644 --- a/Telegram/SourceFiles/boxes/self_destruction_box.h +++ b/Telegram/SourceFiles/boxes/self_destruction_box.h @@ -33,16 +33,14 @@ class SelfDestructionBox : public BoxContent, private MTP::Sender { Q_OBJECT public: - SelfDestructionBox(QWidget*) { - } + SelfDestructionBox(QWidget*) {} protected: void prepare() override; private: std::vector _ttlValues; - object_ptr _description = { nullptr }; + object_ptr _description = {nullptr}; std::shared_ptr _ttlGroup; std::vector> _options; - }; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 79e7b2463..923701fb5 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -20,17 +20,17 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/send_files_box.h" -#include "lang/lang_keys.h" -#include "storage/localstorage.h" -#include "mainwidget.h" -#include "history/history_media_types.h" #include "core/file_utilities.h" -#include "ui/widgets/checkbox.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/input_fields.h" -#include "styles/style_history.h" -#include "styles/style_boxes.h" +#include "history/history_media_types.h" +#include "lang/lang_keys.h" +#include "mainwidget.h" #include "media/media_clip_reader.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" +#include "styles/style_history.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/input_fields.h" #include "window/window_controller.h" namespace { @@ -43,18 +43,18 @@ bool ValidatePhotoDimensions(int width, int height) { } // namespace -SendFilesBox::SendFilesBox(QWidget*, QImage image, CompressConfirm compressed) -: _image(image) -, _compressConfirm(compressed) -, _caption(this, st::confirmCaptionArea, langFactory(lng_photo_caption)) { +SendFilesBox::SendFilesBox(QWidget *, QImage image, CompressConfirm compressed) + : _image(image) + , _compressConfirm(compressed) + , _caption(this, st::confirmCaptionArea, langFactory(lng_photo_caption)) { _files.push_back(QString()); prepareSingleFileLayout(); } -SendFilesBox::SendFilesBox(QWidget*, const QStringList &files, CompressConfirm compressed) -: _files(files) -, _compressConfirm(compressed) -, _caption(this, st::confirmCaptionArea, langFactory(_files.size() > 1 ? lng_photos_comment : lng_photo_caption)) { +SendFilesBox::SendFilesBox(QWidget *, const QStringList &files, CompressConfirm compressed) + : _files(files) + , _compressConfirm(compressed) + , _caption(this, st::confirmCaptionArea, langFactory(_files.size() > 1 ? lng_photos_comment : lng_photo_caption)) { if (_files.size() == 1) { prepareSingleFileLayout(); } @@ -79,8 +79,11 @@ void SendFilesBox::prepareSingleFileLayout() { if (originalWidth > originalHeight) { thumbWidth = (originalWidth * st::msgFileThumbSize) / originalHeight; } - auto options = Images::Option::Smooth | Images::Option::RoundedSmall | Images::Option::RoundedTopLeft | Images::Option::RoundedTopRight | Images::Option::RoundedBottomLeft | Images::Option::RoundedBottomRight; - _fileThumb = Images::pixmap(image, thumbWidth * cIntRetinaFactor(), 0, options, st::msgFileThumbSize, st::msgFileThumbSize); + auto options = Images::Option::Smooth | Images::Option::RoundedSmall | Images::Option::RoundedTopLeft | + Images::Option::RoundedTopRight | Images::Option::RoundedBottomLeft | + Images::Option::RoundedBottomRight; + _fileThumb = Images::pixmap(image, thumbWidth * cIntRetinaFactor(), 0, options, st::msgFileThumbSize, + st::msgFileThumbSize); } else { auto maxW = 0; auto maxH = 0; @@ -100,7 +103,8 @@ void SendFilesBox::prepareSingleFileLayout() { maxH = limitH; } } - image = Images::prepare(image, maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth | Images::Option::Blurred, maxW, maxH); + image = Images::prepare(image, maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), + Images::Option::Smooth | Images::Option::Blurred, maxW, maxH); } auto originalWidth = image.width(); auto originalHeight = image.height(); @@ -120,7 +124,8 @@ void SendFilesBox::prepareSingleFileLayout() { } _previewLeft = (st::boxWideWidth - _previewWidth) / 2; - image = std::move(image).scaled(_previewWidth * cIntRetinaFactor(), _previewHeight * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + image = std::move(image).scaled(_previewWidth * cIntRetinaFactor(), _previewHeight * cIntRetinaFactor(), + Qt::IgnoreAspectRatio, Qt::SmoothTransformation); image = Images::prepareOpaque(std::move(image)); _preview = App::pixmapFromImageInPlace(std::move(image)); _preview.setDevicePixelRatio(cRetinaFactor()); @@ -145,9 +150,8 @@ void SendFilesBox::prepareGifPreview() { return _animated; }; if (createGifPreview()) { - _gifPreview = Media::Clip::MakeReader(_files.front(), [this](Media::Clip::Notification notification) { - clipCallback(notification); - }); + _gifPreview = Media::Clip::MakeReader( + _files.front(), [this](Media::Clip::Notification notification) { clipCallback(notification); }); if (_gifPreview) _gifPreview->setAutoplay(); } } @@ -162,7 +166,8 @@ void SendFilesBox::clipCallback(Media::Clip::Notification notification) { if (_gifPreview && _gifPreview->ready() && !_gifPreview->started()) { auto s = QSize(_previewWidth, _previewHeight); - _gifPreview->start(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, ImageRoundCorner::None); + _gifPreview->start(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, + ImageRoundCorner::None); } update(); @@ -219,10 +224,10 @@ void SendFilesBox::tryToReadSingleFile() { } } -SendFilesBox::SendFilesBox(QWidget*, const QString &phone, const QString &firstname, const QString &lastname) -: _contactPhone(phone) -, _contactFirstName(firstname) -, _contactLastName(lastname) { +SendFilesBox::SendFilesBox(QWidget *, const QString &phone, const QString &firstname, const QString &lastname) + : _contactPhone(phone) + , _contactFirstName(firstname) + , _contactLastName(lastname) { auto name = lng_full_name(lt_first_name, _contactFirstName, lt_last_name, _contactLastName); _nameText.setText(st::semiboldTextStyle, name, _textNameOptions); _statusText = _contactPhone; @@ -241,7 +246,8 @@ void SendFilesBox::prepare() { addButton(langFactory(lng_cancel), [this] { closeBox(); }); if (_compressConfirm != CompressConfirm::None) { - auto compressed = (_compressConfirm == CompressConfirm::Auto) ? cCompressPastedImage() : (_compressConfirm == CompressConfirm::Yes); + auto compressed = (_compressConfirm == CompressConfirm::Auto) ? cCompressPastedImage() : + (_compressConfirm == CompressConfirm::Yes); auto text = lng_send_images_compress(lt_count, _files.size()); _compressed.create(this, text, compressed, st::defaultBoxCheckbox); subscribe(_compressed->checkedChanged, [this](bool checked) { onCompressedChange(); }); @@ -286,7 +292,8 @@ void SendFilesBox::onCaptionResized() { } void SendFilesBox::updateTitleText() { - _titleText = (_compressConfirm == CompressConfirm::None) ? lng_send_files_selected(lt_count, _files.size()) : lng_send_images_selected(lt_count, _files.size()); + _titleText = (_compressConfirm == CompressConfirm::None) ? lng_send_files_selected(lt_count, _files.size()) : + lng_send_images_selected(lt_count, _files.size()); update(); } @@ -295,11 +302,13 @@ void SendFilesBox::updateBoxSize() { if (!_preview.isNull()) { newHeight += st::boxPhotoPadding.top() + _previewHeight; } else if (!_fileThumb.isNull()) { - newHeight += st::boxPhotoPadding.top() + st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); + newHeight += st::boxPhotoPadding.top() + st::msgFileThumbPadding.top() + st::msgFileThumbSize + + st::msgFileThumbPadding.bottom(); } else if (_files.size() > 1) { newHeight += 0; } else { - newHeight += st::boxPhotoPadding.top() + st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); + newHeight += + st::boxPhotoPadding.top() + st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); } if (_compressed) { newHeight += st::boxPhotoCompressedSkip + _compressed->heightNoMargins(); @@ -312,7 +321,8 @@ void SendFilesBox::updateBoxSize() { void SendFilesBox::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { - onSend((e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier)) && e->modifiers().testFlag(Qt::ShiftModifier)); + onSend((e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier)) && + e->modifiers().testFlag(Qt::ShiftModifier)); } else { BoxContent::keyPressEvent(e); } @@ -331,21 +341,27 @@ void SendFilesBox::paintEvent(QPaintEvent *e) { if (!_preview.isNull()) { if (_previewLeft > st::boxPhotoPadding.left()) { - p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _previewLeft - st::boxPhotoPadding.left(), _previewHeight, st::confirmBg); + p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _previewLeft - st::boxPhotoPadding.left(), + _previewHeight, st::confirmBg); } if (_previewLeft + _previewWidth < width() - st::boxPhotoPadding.right()) { - p.fillRect(_previewLeft + _previewWidth, st::boxPhotoPadding.top(), width() - st::boxPhotoPadding.right() - _previewLeft - _previewWidth, _previewHeight, st::confirmBg); + p.fillRect(_previewLeft + _previewWidth, st::boxPhotoPadding.top(), + width() - st::boxPhotoPadding.right() - _previewLeft - _previewWidth, _previewHeight, + st::confirmBg); } if (_gifPreview && _gifPreview->started()) { auto s = QSize(_previewWidth, _previewHeight); auto paused = controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Layer); - auto frame = _gifPreview->current(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, ImageRoundCorner::None, paused ? 0 : getms()); + auto frame = _gifPreview->current(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, + ImageRoundCorner::None, paused ? 0 : getms()); p.drawPixmap(_previewLeft, st::boxPhotoPadding.top(), frame); } else { p.drawPixmap(_previewLeft, st::boxPhotoPadding.top(), _preview); } if (_animated && !_gifPreview) { - auto inner = QRect(_previewLeft + (_previewWidth - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (_previewHeight - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + auto inner = QRect(_previewLeft + (_previewWidth - st::msgFileSize) / 2, + st::boxPhotoPadding.top() + (_previewHeight - st::msgFileSize) / 2, st::msgFileSize, + st::msgFileSize); p.setPen(Qt::NoPen); p.setBrush(st::msgDateImgBg); @@ -359,7 +375,9 @@ void SendFilesBox::paintEvent(QPaintEvent *e) { } } else if (_files.size() < 2) { auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(); - auto h = _fileThumb.isNull() ? (st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom()) : (st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom()); + auto h = _fileThumb.isNull() ? + (st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom()) : + (st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom()); auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; if (_fileThumb.isNull()) { nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); @@ -373,14 +391,16 @@ void SendFilesBox::paintEvent(QPaintEvent *e) { statustop = st::msgFileThumbStatusTop; linktop = st::msgFileThumbLinkTop; } - auto namewidth = w - nameleft - (_fileThumb.isNull() ? st::msgFilePadding.left() : st::msgFileThumbPadding.left()); + auto namewidth = + w - nameleft - (_fileThumb.isNull() ? st::msgFilePadding.left() : st::msgFileThumbPadding.left()); qint32 x = (width() - w) / 2, y = st::boxPhotoPadding.top(); App::roundRect(p, x, y, w, h, st::msgOutBg, MessageOutCorners, &st::msgOutShadow); if (_fileThumb.isNull()) { if (_contactPhone.isNull()) { - QRect inner(rtlrect(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width())); + QRect inner(rtlrect(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), st::msgFileSize, + st::msgFileSize, width())); p.setPen(Qt::NoPen); p.setBrush(st::msgFileOutBg); @@ -389,13 +409,16 @@ void SendFilesBox::paintEvent(QPaintEvent *e) { p.drawEllipse(inner); } - auto &icon = _fileIsAudio ? st::historyFileOutPlay : _fileIsImage ? st::historyFileOutImage : st::historyFileOutDocument; + auto &icon = _fileIsAudio ? st::historyFileOutPlay : + _fileIsImage ? st::historyFileOutImage : st::historyFileOutDocument; icon.paintInCenter(p, inner); } else { - _contactPhotoEmpty.paint(p, x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), st::msgFileSize); + _contactPhotoEmpty.paint(p, x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), + st::msgFileSize); } } else { - QRect rthumb(rtlrect(x + st::msgFileThumbPadding.left(), y + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width())); + QRect rthumb(rtlrect(x + st::msgFileThumbPadding.left(), y + st::msgFileThumbPadding.top(), + st::msgFileThumbSize, st::msgFileThumbSize, width())); p.drawPixmap(rthumb.topLeft(), _fileThumb); } p.setFont(st::semiboldFont); @@ -417,7 +440,8 @@ void SendFilesBox::resizeEvent(QResizeEvent *e) { void SendFilesBox::updateControlsGeometry() { auto bottom = height(); if (_caption) { - _caption->resize(st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), _caption->height()); + _caption->resize(st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), + _caption->height()); _caption->moveToLeft(st::boxPhotoPadding.left(), bottom - _caption->height()); bottom -= st::boxPhotoCaptionSkip + _caption->height(); } @@ -443,13 +467,17 @@ void SendFilesBox::onSend(bool ctrlShiftEnter) { _confirmed = true; if (_confirmedCallback) { auto compressed = _compressed ? _compressed->checked() : false; - auto caption = _caption ? TextUtilities::PrepareForSending(_caption->getLastText(), TextUtilities::PrepareTextOption::CheckLinks) : QString(); - _confirmedCallback(_files, _animated ? QImage() : _image, std::move(_information), compressed, caption, ctrlShiftEnter); + auto caption = _caption ? TextUtilities::PrepareForSending(_caption->getLastText(), + TextUtilities::PrepareTextOption::CheckLinks) : + QString(); + _confirmedCallback(_files, _animated ? QImage() : _image, std::move(_information), compressed, caption, + ctrlShiftEnter); } closeBox(); } -EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : _msgId(msgId) { +EditCaptionBox::EditCaptionBox(QWidget *, HistoryMedia *media, FullMsgId msgId) + : _msgId(msgId) { Expects(media->canEditCaption()); QSize dimensions; @@ -460,21 +488,21 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : switch (media->type()) { case MediaTypeGif: { _animated = true; - doc = static_cast(media)->getDocument(); + doc = static_cast(media)->getDocument(); dimensions = doc->dimensions; image = doc->thumb; } break; case MediaTypePhoto: { _photo = true; - auto photo = static_cast(media)->photo(); + auto photo = static_cast(media)->photo(); dimensions = QSize(photo->full->width(), photo->full->height()); image = photo->full; } break; case MediaTypeVideo: { _animated = true; - doc = static_cast(media)->getDocument(); + doc = static_cast(media)->getDocument(); dimensions = doc->dimensions; image = doc->thumb; } break; @@ -483,7 +511,7 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : case MediaTypeMusicFile: case MediaTypeVoiceFile: { _doc = true; - doc = static_cast(media)->getDocument(); + doc = static_cast(media)->getDocument(); image = doc->thumb; } break; } @@ -499,8 +527,11 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : } else { _thumbw = st::msgFileThumbSize; } - auto options = Images::Option::Smooth | Images::Option::RoundedSmall | Images::Option::RoundedTopLeft | Images::Option::RoundedTopRight | Images::Option::RoundedBottomLeft | Images::Option::RoundedBottomRight; - _thumb = Images::pixmap(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, options, st::msgFileThumbSize, st::msgFileThumbSize); + auto options = Images::Option::Smooth | Images::Option::RoundedSmall | Images::Option::RoundedTopLeft | + Images::Option::RoundedTopRight | Images::Option::RoundedBottomLeft | + Images::Option::RoundedBottomRight; + _thumb = Images::pixmap(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, options, + st::msgFileThumbSize, st::msgFileThumbSize); } if (doc) { @@ -532,12 +563,14 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : maxH = limitH; } } - _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth | Images::Option::Blurred, maxW, maxH); + _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), + Images::Option::Smooth | Images::Option::Blurred, maxW, maxH); prepareGifPreview(doc); } else { maxW = dimensions.width(); maxH = dimensions.height(); - _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth, maxW, maxH); + _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth, + maxW, maxH); } qint32 tw = _thumb.width(), th = _thumb.height(); if (!tw || !th) { @@ -558,7 +591,9 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : } _thumbx = (st::boxWideWidth - _thumbw) / 2; - _thumb = App::pixmapFromImageInPlace(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + _thumb = App::pixmapFromImageInPlace(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), + _thumbh * cIntRetinaFactor(), + Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _thumb.setDevicePixelRatio(cRetinaFactor()); } Assert(_animated || _photo || _doc); @@ -569,14 +604,11 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : } void EditCaptionBox::prepareGifPreview(DocumentData *document) { - auto createGifPreview = [document] { - return (document && document->isAnimation()); - }; + auto createGifPreview = [document] { return (document && document->isAnimation()); }; auto createGifPreviewResult = createGifPreview(); // Clang freeze workaround. if (createGifPreviewResult) { - _gifPreview = Media::Clip::MakeReader(document, _msgId, [this](Media::Clip::Notification notification) { - clipCallback(notification); - }); + _gifPreview = Media::Clip::MakeReader( + document, _msgId, [this](Media::Clip::Notification notification) { clipCallback(notification); }); if (_gifPreview) _gifPreview->setAutoplay(); } } @@ -591,7 +623,8 @@ void EditCaptionBox::clipCallback(Media::Clip::Notification notification) { if (_gifPreview && _gifPreview->ready() && !_gifPreview->started()) { auto s = QSize(_thumbw, _thumbh); - _gifPreview->start(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, ImageRoundCorner::None); + _gifPreview->start(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, + ImageRoundCorner::None); } update(); @@ -626,7 +659,8 @@ void EditCaptionBox::onCaptionResized() { } void EditCaptionBox::updateBoxSize() { - auto newHeight = st::boxPhotoPadding.top() + st::boxPhotoCaptionSkip + _field->height() + errorTopSkip() + st::normalFont->height; + auto newHeight = st::boxPhotoPadding.top() + st::boxPhotoCaptionSkip + _field->height() + errorTopSkip() + + st::normalFont->height; if (_photo || _animated) { newHeight += _thumbh; } else if (_thumbw) { @@ -650,21 +684,25 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) { if (_photo || _animated) { if (_thumbx > st::boxPhotoPadding.left()) { - p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _thumbx - st::boxPhotoPadding.left(), _thumbh, st::confirmBg); + p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _thumbx - st::boxPhotoPadding.left(), + _thumbh, st::confirmBg); } if (_thumbx + _thumbw < width() - st::boxPhotoPadding.right()) { - p.fillRect(_thumbx + _thumbw, st::boxPhotoPadding.top(), width() - st::boxPhotoPadding.right() - _thumbx - _thumbw, _thumbh, st::confirmBg); + p.fillRect(_thumbx + _thumbw, st::boxPhotoPadding.top(), + width() - st::boxPhotoPadding.right() - _thumbx - _thumbw, _thumbh, st::confirmBg); } if (_gifPreview && _gifPreview->started()) { auto s = QSize(_thumbw, _thumbh); auto paused = controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Layer); - auto frame = _gifPreview->current(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, ImageRoundCorner::None, paused ? 0 : getms()); + auto frame = _gifPreview->current(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, + ImageRoundCorner::None, paused ? 0 : getms()); p.drawPixmap(_thumbx, st::boxPhotoPadding.top(), frame); } else { p.drawPixmap(_thumbx, st::boxPhotoPadding.top(), _thumb); } if (_animated && !_gifPreview) { - QRect inner(_thumbx + (_thumbw - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (_thumbh - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + QRect inner(_thumbx + (_thumbw - st::msgFileSize) / 2, + st::boxPhotoPadding.top() + (_thumbh - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); p.setPen(Qt::NoPen); p.setBrush(st::msgDateImgBg); @@ -693,12 +731,12 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) { } qint32 namewidth = w - nameleft - 0; if (namewidth > _statusw) { - //w -= (namewidth - _statusw); - //namewidth = _statusw; + // w -= (namewidth - _statusw); + // namewidth = _statusw; } qint32 x = (width() - w) / 2, y = st::boxPhotoPadding.top(); -// App::roundRect(p, x, y, w, h, st::msgInBg, MessageInCorners, &st::msgInShadow); + // App::roundRect(p, x, y, w, h, st::msgInBg, MessageInCorners, &st::msgInShadow); if (_thumbw) { QRect rthumb(rtlrect(x + 0, y + 0, st::msgFileThumbSize, st::msgFileThumbSize, width())); @@ -713,7 +751,8 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) { p.drawEllipse(inner); } - auto icon = &(_isAudio ? st::historyFileInPlay : _isImage ? st::historyFileInImage : st::historyFileInDocument); + auto icon = + &(_isAudio ? st::historyFileInPlay : _isImage ? st::historyFileInImage : st::historyFileInDocument); icon->paintInCenter(p, inner); } p.setFont(st::semiboldFont); @@ -740,7 +779,8 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) { void EditCaptionBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); _field->resize(st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), _field->height()); - _field->moveToLeft(st::boxPhotoPadding.left(), height() - st::normalFont->height - errorTopSkip() - _field->height()); + _field->moveToLeft(st::boxPhotoPadding.left(), + height() - st::normalFont->height - errorTopSkip() - _field->height()); } void EditCaptionBox::setInnerFocus() { @@ -766,7 +806,10 @@ void EditCaptionBox::onSave(bool ctrlShiftEnter) { flags |= MTPmessages_EditMessage::Flag::f_entities; } auto text = TextUtilities::PrepareForSending(_field->getLastText(), TextUtilities::PrepareTextOption::CheckLinks); - _saveRequestId = MTP::send(MTPmessages_EditMessage(MTP_flags(flags), item->history()->peer->input, MTP_int(item->id), MTP_string(text), MTPnullMarkup, sentEntities), rpcDone(&EditCaptionBox::saveDone), rpcFail(&EditCaptionBox::saveFail)); + _saveRequestId = + MTP::send(MTPmessages_EditMessage(MTP_flags(flags), item->history()->peer->input, MTP_int(item->id), + MTP_string(text), MTPnullMarkup, sentEntities), + rpcDone(&EditCaptionBox::saveDone), rpcFail(&EditCaptionBox::saveFail)); } void EditCaptionBox::saveDone(const MTPUpdates &updates) { @@ -782,7 +825,8 @@ bool EditCaptionBox::saveFail(const RPCError &error) { _saveRequestId = 0; QString err = error.type(); - if (err == qstr("MESSAGE_ID_INVALID") || err == qstr("CHAT_ADMIN_REQUIRED") || err == qstr("MESSAGE_EDIT_TIME_EXPIRED")) { + if (err == qstr("MESSAGE_ID_INVALID") || err == qstr("CHAT_ADMIN_REQUIRED") || + err == qstr("MESSAGE_EDIT_TIME_EXPIRED")) { _error = lang(lng_edit_error); } else if (err == qstr("MESSAGE_NOT_MODIFIED")) { closeBox(); diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index 172d858a5..9905764d3 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -21,8 +21,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #pragma once #include "boxes/abstract_box.h" -#include "storage/localimageloader.h" #include "history/history_media.h" +#include "storage/localimageloader.h" namespace Ui { class Checkbox; @@ -34,11 +34,14 @@ class SendFilesBox : public BoxContent { Q_OBJECT public: - SendFilesBox(QWidget*, QImage image, CompressConfirm compressed); - SendFilesBox(QWidget*, const QStringList &files, CompressConfirm compressed); - SendFilesBox(QWidget*, const QString &phone, const QString &firstname, const QString &lastname); + SendFilesBox(QWidget *, QImage image, CompressConfirm compressed); + SendFilesBox(QWidget *, const QStringList &files, CompressConfirm compressed); + SendFilesBox(QWidget *, const QString &phone, const QString &firstname, const QString &lastname); - void setConfirmedCallback(base::lambda information, bool compressed, const QString &caption, bool ctrlShiftEnter)> callback) { + void setConfirmedCallback(base::lambda information, + bool compressed, const QString &caption, bool ctrlShiftEnter)> + callback) { _confirmedCallback = std::move(callback); } void setCancelledCallback(base::lambda callback) { @@ -99,22 +102,24 @@ private: QString _contactLastName; EmptyUserpic _contactPhotoEmpty; - base::lambda information, bool compressed, const QString &caption, bool ctrlShiftEnter)> _confirmedCallback; + base::lambda information, bool compressed, + const QString &caption, bool ctrlShiftEnter)> + _confirmedCallback; base::lambda _cancelledCallback; bool _confirmed = false; - object_ptr _caption = { nullptr }; - object_ptr _compressed = { nullptr }; + object_ptr _caption = {nullptr}; + object_ptr _compressed = {nullptr}; QPointer _send; - }; class EditCaptionBox : public BoxContent, public RPCSender { Q_OBJECT public: - EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId); + EditCaptionBox(QWidget *, HistoryMedia *media, FullMsgId msgId); public slots: void onCaptionResized(); @@ -148,7 +153,7 @@ private: QPixmap _thumb; Media::Clip::ReaderPointer _gifPreview; - object_ptr _field = { nullptr }; + object_ptr _field = {nullptr}; int _thumbx = 0; int _thumby = 0; @@ -164,5 +169,4 @@ private: mtpRequestId _saveRequestId = 0; QString _error; - }; diff --git a/Telegram/SourceFiles/boxes/sessions_box.cpp b/Telegram/SourceFiles/boxes/sessions_box.cpp index 55caef6f8..35414a70c 100644 --- a/Telegram/SourceFiles/boxes/sessions_box.cpp +++ b/Telegram/SourceFiles/boxes/sessions_box.cpp @@ -20,19 +20,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/sessions_box.h" +#include "boxes/confirm_box.h" +#include "countries.h" #include "lang/lang_keys.h" -#include "storage/localstorage.h" #include "mainwidget.h" #include "mainwindow.h" -#include "countries.h" -#include "boxes/confirm_box.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" #include "ui/widgets/buttons.h" #include "ui/widgets/scroll_area.h" -#include "styles/style_boxes.h" -SessionsBox::SessionsBox(QWidget*) -: _shortPollTimer(this) { -} +SessionsBox::SessionsBox(QWidget *) + : _shortPollTimer(this) {} void SessionsBox::prepare() { setTitle(langFactory(lng_sessions_other_header)); @@ -85,7 +84,8 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) { setLoading(false); auto availCurrent = st::boxWideWidth - st::sessionPadding.left() - st::sessionTerminateSkip; - auto availOther = availCurrent - st::sessionTerminate.iconPosition.x();// -st::sessionTerminate.width - st::sessionTerminateSkip; + auto availOther = + availCurrent - st::sessionTerminate.iconPosition.x(); // -st::sessionTerminate.width - st::sessionTerminateSkip; _list.clear(); if (result.type() != mtpc_account_authorizations) { @@ -104,24 +104,26 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) { Data data; data.hash = d.vhash.v; - QString appName, appVer = qs(d.vapp_version), systemVer = qs(d.vsystem_version), deviceModel = qs(d.vdevice_model); + QString appName, appVer = qs(d.vapp_version), systemVer = qs(d.vsystem_version), + deviceModel = qs(d.vdevice_model); if (d.vapi_id.v == 2040 || d.vapi_id.v == 17349) { appName = str_const_toString(AppName); - // if (systemVer == qstr("windows")) { - // deviceModel = qsl("Windows"); - // } else if (systemVer == qstr("os x")) { - // deviceModel = qsl("OS X"); - // } else if (systemVer == qstr("linux")) { - // deviceModel = qsl("Linux"); - // } + // if (systemVer == qstr("windows")) { + // deviceModel = qsl("Windows"); + // } else if (systemVer == qstr("os x")) { + // deviceModel = qsl("OS X"); + // } else if (systemVer == qstr("linux")) { + // deviceModel = qsl("Linux"); + // } if (appVer == QString::number(appVer.toInt())) { qint32 ver = appVer.toInt(); - appVer = QString("%1.%2").arg(ver / 1000000).arg((ver % 1000000) / 1000) + ((ver % 1000) ? ('.' + QString::number(ver % 1000)) : QString()); - //} else { - // appVer = QString(); + appVer = QString("%1.%2").arg(ver / 1000000).arg((ver % 1000000) / 1000) + + ((ver % 1000) ? ('.' + QString::number(ver % 1000)) : QString()); + //} else { + // appVer = QString(); } } else { - appName = qs(d.vapp_name);// +qsl(" for ") + qs(d.vplatform); + appName = qs(d.vapp_name); // +qsl(" for ") + qs(d.vplatform); if (appVer.indexOf('(') >= 0) appVer = appVer.mid(appVer.indexOf('(')); } data.name = appName; @@ -129,13 +131,14 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) { data.nameWidth = st::sessionNameFont->width(data.name); QString country = qs(d.vcountry), platform = qs(d.vplatform); - //CountriesByISO2::const_iterator j = countries.constFind(country); - //if (j != countries.cend()) country = QString::fromUtf8(j.value()->name); + // CountriesByISO2::const_iterator j = countries.constFind(country); + // if (j != countries.cend()) country = QString::fromUtf8(j.value()->name); MTPint active = d.vdate_active.v ? d.vdate_active : d.vdate_created; data.activeTime = active.v; - data.info = qs(d.vdevice_model) + qstr(", ") + (platform.isEmpty() ? QString() : platform + ' ') + qs(d.vsystem_version); + data.info = qs(d.vdevice_model) + qstr(", ") + (platform.isEmpty() ? QString() : platform + ' ') + + qs(d.vsystem_version); data.ip = qs(d.vip) + (country.isEmpty() ? QString() : QString::fromUtf8(" \xe2\x80\x93 ") + country); if (!data.hash || (d.vflags.v & 1)) { data.active = lang(lng_sessions_header); @@ -213,7 +216,7 @@ void SessionsBox::onShortPollAuthorizations() { void SessionsBox::onCheckNewAuthorization() { onShortPollAuthorizations(); -// _shortPollTimer.start(1000); + // _shortPollTimer.start(1000); } void SessionsBox::onAllTerminated() { @@ -228,10 +231,11 @@ void SessionsBox::onTerminateAll() { setLoading(true); } -SessionsBox::Inner::Inner(QWidget *parent, SessionsBox::List *list, SessionsBox::Data *current) : TWidget(parent) -, _list(list) -, _current(current) -, _terminateAll(this, lang(lng_sessions_terminate_all), st::sessionTerminateAllButton) { +SessionsBox::Inner::Inner(QWidget *parent, SessionsBox::List *list, SessionsBox::Data *current) + : TWidget(parent) + , _list(list) + , _current(current) + , _terminateAll(this, lang(lng_sessions_terminate_all), st::sessionTerminateAllButton) { connect(_terminateAll, SIGNAL(clicked()), this, SLOT(onTerminateAll())); _terminateAll->hide(); setAttribute(Qt::WA_OpaquePaintEvent); @@ -242,7 +246,10 @@ void SessionsBox::Inner::paintEvent(QPaintEvent *e) { Painter p(this); p.fillRect(r, st::boxBg); - qint32 x = st::sessionPadding.left(), xact = st::sessionTerminateSkip + st::sessionTerminate.iconPosition.x();// st::sessionTerminateSkip + st::sessionTerminate.width + st::sessionTerminateSkip; + qint32 x = st::sessionPadding.left(), + xact = st::sessionTerminateSkip + + st::sessionTerminate.iconPosition + .x(); // st::sessionTerminateSkip + st::sessionTerminate.width + st::sessionTerminateSkip; qint32 w = width(); if (_current->active.isEmpty() && _list->isEmpty()) { @@ -264,15 +271,19 @@ void SessionsBox::Inner::paintEvent(QPaintEvent *e) { p.setFont(st::sessionInfoFont); p.setPen(st::boxTextFg); - p.drawTextLeft(x, st::sessionPadding.top() + st::sessionNameFont->height, w, _current->info, _current->infoWidth); + p.drawTextLeft(x, st::sessionPadding.top() + st::sessionNameFont->height, w, _current->info, + _current->infoWidth); p.setPen(st::sessionInfoFg); - p.drawTextLeft(x, st::sessionPadding.top() + st::sessionNameFont->height + st::sessionInfoFont->height, w, _current->ip, _current->ipWidth); + p.drawTextLeft(x, st::sessionPadding.top() + st::sessionNameFont->height + st::sessionInfoFont->height, w, + _current->ip, _current->ipWidth); } p.translate(0, st::sessionCurrentHeight - st::sessionCurrentPadding.top()); if (_list->isEmpty()) { p.setFont(st::sessionInfoFont); p.setPen(st::sessionInfoFg); - p.drawText(QRect(st::sessionPadding.left(), 0, width() - st::sessionPadding.left() - st::sessionPadding.right(), st::noContactsHeight), lang(lng_sessions_other_desc), style::al_topleft); + p.drawText(QRect(st::sessionPadding.left(), 0, width() - st::sessionPadding.left() - st::sessionPadding.right(), + st::noContactsHeight), + lang(lng_sessions_other_desc), style::al_topleft); return; } @@ -296,7 +307,8 @@ void SessionsBox::Inner::paintEvent(QPaintEvent *e) { p.setPen(st::boxTextFg); p.drawTextLeft(x, st::sessionPadding.top() + st::sessionNameFont->height, w, auth.info, auth.infoWidth); p.setPen(st::sessionInfoFg); - p.drawTextLeft(x, st::sessionPadding.top() + st::sessionNameFont->height + st::sessionInfoFont->height, w, auth.ip, auth.ipWidth); + p.drawTextLeft(x, st::sessionPadding.top() + st::sessionNameFont->height + st::sessionInfoFont->height, w, + auth.ip, auth.ipWidth); p.translate(0, st::sessionHeight); } @@ -306,32 +318,45 @@ void SessionsBox::Inner::onTerminate() { for (auto i = _terminateButtons.begin(), e = _terminateButtons.end(); i != e; ++i) { if (i.value()->isOver()) { if (_terminateBox) _terminateBox->deleteLater(); - _terminateBox = Ui::show(Box(lang(lng_settings_reset_one_sure), lang(lng_settings_reset_button), st::attentionBoxButton, base::lambda_guarded(this, [this, terminating = i.key()] { - if (_terminateBox) { - _terminateBox->closeBox(); - _terminateBox = nullptr; - } - MTP::send(MTPaccount_ResetAuthorization(MTP_long(terminating)), rpcDone(&Inner::terminateDone, terminating), rpcFail(&Inner::terminateFail, terminating)); - auto i = _terminateButtons.find(terminating); - if (i != _terminateButtons.cend()) { - i.value()->clearState(); - i.value()->hide(); - } - })), KeepOtherLayers); + _terminateBox = + Ui::show(Box( + lang(lng_settings_reset_one_sure), lang(lng_settings_reset_button), st::attentionBoxButton, + base::lambda_guarded(this, + [this, terminating = i.key()] { + if (_terminateBox) { + _terminateBox->closeBox(); + _terminateBox = nullptr; + } + MTP::send(MTPaccount_ResetAuthorization(MTP_long(terminating)), + rpcDone(&Inner::terminateDone, terminating), + rpcFail(&Inner::terminateFail, terminating)); + auto i = _terminateButtons.find(terminating); + if (i != _terminateButtons.cend()) { + i.value()->clearState(); + i.value()->hide(); + } + })), + KeepOtherLayers); } } } void SessionsBox::Inner::onTerminateAll() { if (_terminateBox) _terminateBox->deleteLater(); - _terminateBox = Ui::show(Box(lang(lng_settings_reset_sure), lang(lng_settings_reset_button), st::attentionBoxButton, base::lambda_guarded(this, [this] { - if (_terminateBox) { - _terminateBox->closeBox(); - _terminateBox = nullptr; - } - MTP::send(MTPauth_ResetAuthorizations(), rpcDone(&Inner::terminateAllDone), rpcFail(&Inner::terminateAllFail)); - emit terminateAll(); - })), KeepOtherLayers); + _terminateBox = + Ui::show(Box(lang(lng_settings_reset_sure), lang(lng_settings_reset_button), st::attentionBoxButton, + base::lambda_guarded(this, + [this] { + if (_terminateBox) { + _terminateBox->closeBox(); + _terminateBox = nullptr; + } + MTP::send(MTPauth_ResetAuthorizations(), + rpcDone(&Inner::terminateAllDone), + rpcFail(&Inner::terminateAllFail)); + emit terminateAll(); + })), + KeepOtherLayers); } void SessionsBox::Inner::terminateDone(quint64 hash, const MTPBool &result) { @@ -367,7 +392,8 @@ bool SessionsBox::Inner::terminateAllFail(const RPCError &error) { } void SessionsBox::Inner::resizeEvent(QResizeEvent *e) { - _terminateAll->moveToLeft(st::sessionPadding.left(), st::sessionCurrentPadding.top() + st::sessionHeight + st::sessionCurrentPadding.bottom()); + _terminateAll->moveToLeft(st::sessionPadding.left(), + st::sessionCurrentPadding.top() + st::sessionHeight + st::sessionCurrentPadding.bottom()); } void SessionsBox::Inner::listUpdated() { @@ -385,7 +411,8 @@ void SessionsBox::Inner::listUpdated() { j = _terminateButtons.insert(_list->at(i).hash, new Ui::IconButton(this, st::sessionTerminate)); connect(j.value(), SIGNAL(clicked()), this, SLOT(onTerminate())); } - j.value()->moveToRight(st::sessionTerminateSkip, st::sessionCurrentHeight + i * st::sessionHeight + st::sessionTerminateTop, width()); + j.value()->moveToRight(st::sessionTerminateSkip, + st::sessionCurrentHeight + i * st::sessionHeight + st::sessionTerminateTop, width()); j.value()->show(); } for (TerminateButtons::iterator i = _terminateButtons.begin(); i != _terminateButtons.cend();) { @@ -396,6 +423,7 @@ void SessionsBox::Inner::listUpdated() { i = _terminateButtons.erase(i); } } - resize(width(), _list->isEmpty() ? (st::sessionCurrentHeight + st::noContactsHeight) : (st::sessionCurrentHeight + _list->size() * st::sessionHeight)); + resize(width(), _list->isEmpty() ? (st::sessionCurrentHeight + st::noContactsHeight) : + (st::sessionCurrentHeight + _list->size() * st::sessionHeight)); update(); } diff --git a/Telegram/SourceFiles/boxes/sessions_box.h b/Telegram/SourceFiles/boxes/sessions_box.h index 3a15ba5c1..1a06c340c 100644 --- a/Telegram/SourceFiles/boxes/sessions_box.h +++ b/Telegram/SourceFiles/boxes/sessions_box.h @@ -34,7 +34,7 @@ class SessionsBox : public BoxContent, public RPCSender { Q_OBJECT public: - SessionsBox(QWidget*); + SessionsBox(QWidget *); protected: void prepare() override; @@ -72,7 +72,6 @@ private: object_ptr _shortPollTimer; mtpRequestId _shortPollRequest = 0; - }; // This class is hold in header because it requires Qt preprocessing. @@ -107,10 +106,9 @@ private: SessionsBox::List *_list; SessionsBox::Data *_current; - typedef QMap TerminateButtons; + typedef QMap TerminateButtons; TerminateButtons _terminateButtons; object_ptr _terminateAll; QPointer _terminateBox; - }; diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index a969f483f..d7be573f7 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -20,35 +20,35 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/share_box.h" -#include "dialogs/dialogs_indexed_list.h" -#include "styles/style_boxes.h" -#include "styles/style_history.h" -#include "observer_peer.h" -#include "lang/lang_keys.h" -#include "mainwindow.h" -#include "mainwidget.h" -#include "base/qthelp_url.h" -#include "storage/localstorage.h" -#include "boxes/confirm_box.h" #include "apiwrap.h" -#include "ui/toast/toast.h" -#include "ui/widgets/multi_select.h" +#include "auth_session.h" +#include "base/qthelp_url.h" +#include "boxes/confirm_box.h" +#include "boxes/peer_list_box.h" +#include "dialogs/dialogs_indexed_list.h" #include "history/history_media_types.h" #include "history/history_message.h" +#include "lang/lang_keys.h" +#include "mainwidget.h" +#include "mainwindow.h" +#include "messenger.h" +#include "observer_peer.h" +#include "storage/localstorage.h" +#include "styles/style_boxes.h" +#include "styles/style_history.h" +#include "ui/toast/toast.h" #include "ui/widgets/buttons.h" +#include "ui/widgets/multi_select.h" #include "ui/widgets/scroll_area.h" #include "window/themes/window_theme.h" -#include "boxes/peer_list_box.h" -#include "auth_session.h" -#include "messenger.h" -ShareBox::ShareBox(QWidget*, CopyCallback &©Callback, SubmitCallback &&submitCallback, FilterCallback &&filterCallback) -: _copyCallback(std::move(copyCallback)) -, _submitCallback(std::move(submitCallback)) -, _filterCallback(std::move(filterCallback)) -, _select(this, st::contactsMultiSelect, langFactory(lng_participant_filter)) -, _searchTimer(this) { -} +ShareBox::ShareBox(QWidget *, CopyCallback &©Callback, SubmitCallback &&submitCallback, + FilterCallback &&filterCallback) + : _copyCallback(std::move(copyCallback)) + , _submitCallback(std::move(submitCallback)) + , _filterCallback(std::move(filterCallback)) + , _select(this, st::contactsMultiSelect, langFactory(lng_participant_filter)) + , _searchTimer(this) {} void ShareBox::prepare() { _select->resizeToWidth(st::boxWideWidth); @@ -57,7 +57,7 @@ void ShareBox::prepare() { setTitle(langFactory(lng_share_title)); _inner = setInnerWidget(object_ptr(this, std::move(_filterCallback)), getTopScrollSkip()); - connect(_inner, SIGNAL(mustScrollTo(int,int)), this, SLOT(onMustScrollTo(int,int))); + connect(_inner, SIGNAL(mustScrollTo(int, int)), this, SLOT(onMustScrollTo(int, int))); createButtons(); @@ -74,9 +74,8 @@ void ShareBox::prepare() { _select->setResizedCallback([this] { updateScrollSkips(); }); _select->setSubmittedCallback([this](bool) { _inner->onSelectActive(); }); connect(_inner, SIGNAL(searchByUsername()), this, SLOT(onNeedSearchByUsername())); - _inner->setPeerSelectedChangedCallback([this](PeerData *peer, bool checked) { - onPeerSelectedChanged(peer, checked); - }); + _inner->setPeerSelectedChangedCallback( + [this](PeerData *peer, bool checked) { onPeerSelectedChanged(peer, checked); }); _searchTimer->setSingleShot(true); connect(_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchByUsername())); @@ -116,7 +115,8 @@ bool ShareBox::onSearchByUsername(bool searchCache) { } else if (_peopleQuery != query) { _peopleQuery = query; _peopleFull = false; - _peopleRequest = MTP::send(MTPcontacts_Search(MTP_string(_peopleQuery), MTP_int(SearchPeopleLimit)), rpcDone(&ShareBox::peopleReceived), rpcFail(&ShareBox::peopleFailed)); + _peopleRequest = MTP::send(MTPcontacts_Search(MTP_string(_peopleQuery), MTP_int(SearchPeopleLimit)), + rpcDone(&ShareBox::peopleReceived), rpcFail(&ShareBox::peopleFailed)); _peopleQueries.insert(_peopleRequest, _peopleQuery); } } @@ -274,9 +274,10 @@ void ShareBox::scrollAnimationCallback() { // scrollArea()->scrollToY(scrollTop); } -ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallback) : TWidget(parent) -, _filterCallback(std::move(filterCallback)) -, _chatsIndexed(std::make_unique(Dialogs::SortMode::Add)) { +ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallback) + : TWidget(parent) + , _filterCallback(std::move(filterCallback)) + , _chatsIndexed(std::make_unique(Dialogs::SortMode::Add)) { _rowsTop = st::shareRowsTop; _rowHeight = st::shareRowHeight; setAttribute(Qt::WA_OpaquePaintEvent); @@ -294,9 +295,9 @@ ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallbac using UpdateFlag = Notify::PeerUpdate::Flag; auto observeEvents = UpdateFlag::NameChanged | UpdateFlag::PhotoChanged; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) { - notifyPeerUpdated(update); - })); + subscribe(Notify::PeerUpdated(), + Notify::PeerUpdatedHandler(observeEvents, + [this](const Notify::PeerUpdate &update) { notifyPeerUpdated(update); })); subscribe(Auth().downloaderTaskFinished(), [this] { update(); }); subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { @@ -307,9 +308,7 @@ ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallbac } void ShareBox::Inner::invalidateCache() { - for_const (auto data, _dataMap) { - data->checkbox.invalidateCache(); - } + for_const (auto data, _dataMap) { data->checkbox.invalidateCache(); } } void ShareBox::Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) { @@ -376,12 +375,12 @@ void ShareBox::Inner::repaintChatAtIndex(int index) { ShareBox::Inner::Chat *ShareBox::Inner::getChatAtIndex(int index) { if (index < 0) return nullptr; - auto row = ([this, index]() -> Dialogs::Row* { + auto row = ([this, index]() -> Dialogs::Row * { if (_filter.isEmpty()) return _chatsIndexed->rowAtY(index, 1); return (index < _filtered.size()) ? _filtered[index] : nullptr; })(); if (row) { - return static_cast(row->attached); + return static_cast(row->attached); } if (!_filter.isEmpty()) { @@ -464,7 +463,7 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) { } ShareBox::Inner::Chat *ShareBox::Inner::getChat(Dialogs::Row *row) { - auto data = static_cast(row->attached); + auto data = static_cast(row->attached); if (!data) { auto peer = row->history()->peer; auto i = _dataMap.constFind(peer); @@ -484,9 +483,8 @@ void ShareBox::Inner::setActive(int active) { if (active != _active) { auto changeNameFg = [this](int index, double from, double to) { if (auto chat = getChatAtIndex(index)) { - chat->nameActive.start([this, peer = chat->peer] { - repaintChat(peer); - }, from, to, st::shareActivateDuration); + chat->nameActive.start([this, peer = chat->peer] { repaintChat(peer); }, from, to, + st::shareActivateDuration); } }; changeNameFg(_active, 1., 0.); @@ -516,10 +514,9 @@ void ShareBox::Inner::paintChat(Painter &p, TimeMs ms, Chat *chat, int index) { } ShareBox::Inner::Chat::Chat(PeerData *peer, base::lambda updateCallback) -: peer(peer) -, checkbox(st::sharePhotoCheckbox, updateCallback, PaintUserpicCallback(peer)) -, name(st::sharePhotoCheckbox.imageRadius * 2) { -} + : peer(peer) + , checkbox(st::sharePhotoCheckbox, updateCallback, PaintUserpicCallback(peer)) + , name(st::sharePhotoCheckbox.imageRadius * 2) {} void ShareBox::Inner::paintEvent(QPaintEvent *e) { Painter p(this); @@ -601,7 +598,8 @@ void ShareBox::Inner::updateUpon(const QPoint &pos) { auto left = _rowsLeft + std::floor(column * _rowWidthReal) + st::shareColumnSkip / 2; auto top = _rowsTop + row * _rowHeight + st::sharePhotoTop; auto xupon = (x >= left) && (x < left + (_rowWidth - st::shareColumnSkip)); - auto yupon = (y >= top) && (y < top + st::sharePhotoCheckbox.imageRadius * 2 + st::shareNameTop + st::shareNameStyle.font->height * 2); + auto yupon = (y >= top) && (y < top + st::sharePhotoCheckbox.imageRadius * 2 + st::shareNameTop + + st::shareNameStyle.font->height * 2); auto upon = (xupon && yupon) ? (row * _columnCount + column) : -1; if (upon >= displayedChatsCount()) { upon = -1; @@ -783,13 +781,11 @@ void ShareBox::Inner::refresh() { } ShareBox::Inner::~Inner() { - for_const (auto chat, _dataMap) { - delete chat; - } + for_const (auto chat, _dataMap) { delete chat; } } -QVector ShareBox::Inner::selected() const { - QVector result; +QVector ShareBox::Inner::selected() const { + QVector result; result.reserve(_dataMap.size()); for_const (auto chat, _dataMap) { if (chat->checkbox.checked()) { @@ -801,10 +797,10 @@ QVector ShareBox::Inner::selected() const { QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) { auto shareHashData = QByteArray(0x10, Qt::Uninitialized); - auto shareHashDataInts = reinterpret_cast(shareHashData.data()); - auto channel = fullId.channel ? App::channelLoaded(fullId.channel) : static_cast(nullptr); + auto shareHashDataInts = reinterpret_cast(shareHashData.data()); + auto channel = fullId.channel ? App::channelLoaded(fullId.channel) : static_cast(nullptr); auto channelAccessHash = channel ? channel->access : 0ULL; - auto channelAccessHashInts = reinterpret_cast(&channelAccessHash); + auto channelAccessHashInts = reinterpret_cast(&channelAccessHash); shareHashDataInts[0] = Auth().userId(); shareHashDataInts[1] = fullId.channel; shareHashDataInts[2] = fullId.msg; @@ -816,10 +812,11 @@ QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) { hashSha1(shareHashData.constData(), shareHashData.size(), shareHashEncrypted.data()); // Mix in channel access hash to the first 64 bits of SHA1 of data. - *reinterpret_cast(shareHashEncrypted.data()) ^= *reinterpret_cast(channelAccessHashInts); + *reinterpret_cast(shareHashEncrypted.data()) ^= *reinterpret_cast(channelAccessHashInts); // Encrypt data. - if (!Local::encrypt(shareHashData.constData(), shareHashEncrypted.data() + key128Size, shareHashData.size(), shareHashEncrypted.constData())) { + if (!Local::encrypt(shareHashData.constData(), shareHashEncrypted.data() + key128Size, shareHashData.size(), + shareHashEncrypted.constData())) { return url; } @@ -845,7 +842,8 @@ QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) { void ShareGameScoreByHash(const QString &hash) { auto key128Size = 0x10; - auto hashEncrypted = QByteArray::fromBase64(hash.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); + auto hashEncrypted = + QByteArray::fromBase64(hash.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); if (hashEncrypted.size() <= key128Size || (hashEncrypted.size() % 0x10) != 0) { Ui::show(Box(lang(lng_confirm_phone_link_invalid))); return; @@ -853,16 +851,18 @@ void ShareGameScoreByHash(const QString &hash) { // Decrypt data. auto hashData = QByteArray(hashEncrypted.size() - key128Size, Qt::Uninitialized); - if (!Local::decrypt(hashEncrypted.constData() + key128Size, hashData.data(), hashEncrypted.size() - key128Size, hashEncrypted.constData())) { + if (!Local::decrypt(hashEncrypted.constData() + key128Size, hashData.data(), hashEncrypted.size() - key128Size, + hashEncrypted.constData())) { return; } // Count SHA1() of data. - char dataSha1[20] = { 0 }; + char dataSha1[20] = {0}; hashSha1(hashData.constData(), hashData.size(), dataSha1); // Mix out channel access hash from the first 64 bits of SHA1 of data. - auto channelAccessHash = *reinterpret_cast(hashEncrypted.data()) ^ *reinterpret_cast(dataSha1); + auto channelAccessHash = + *reinterpret_cast(hashEncrypted.data()) ^ *reinterpret_cast(dataSha1); // Check next 64 bits of SHA1() of data. auto skipSha1Part = sizeof(channelAccessHash); @@ -871,14 +871,14 @@ void ShareGameScoreByHash(const QString &hash) { return; } - auto hashDataInts = reinterpret_cast(hashData.data()); + auto hashDataInts = reinterpret_cast(hashData.data()); if (!AuthSession::Exists() || hashDataInts[0] != Auth().userId()) { Ui::show(Box(lang(lng_share_wrong_user))); return; } // Check first 32 bits of channel access hash. - auto channelAccessHashInts = reinterpret_cast(&channelAccessHash); + auto channelAccessHashInts = reinterpret_cast(&channelAccessHash); if (channelAccessHashInts[0] != hashDataInts[3]) { Ui::show(Box(lang(lng_share_wrong_user))); return; @@ -909,16 +909,18 @@ void ShareGameScoreByHash(const QString &hash) { if (channel || !channelId) { resolveMessageAndShareScore(channel); } else { - auto requestChannelIds = MTP_vector(1, MTP_inputChannel(MTP_int(channelId), MTP_long(channelAccessHash))); + auto requestChannelIds = + MTP_vector(1, MTP_inputChannel(MTP_int(channelId), MTP_long(channelAccessHash))); auto requestChannel = MTPchannels_GetChannels(requestChannelIds); - MTP::send(requestChannel, rpcDone([channelId, resolveMessageAndShareScore](const MTPmessages_Chats &result) { - if (auto chats = Api::getChatsFromMessagesChats(result)) { - App::feedChats(*chats); - } - if (auto channel = App::channelLoaded(channelId)) { - resolveMessageAndShareScore(channel); - } - })); + MTP::send(requestChannel, + rpcDone([channelId, resolveMessageAndShareScore](const MTPmessages_Chats &result) { + if (auto chats = Api::getChatsFromMessagesChats(result)) { + App::feedChats(*chats); + } + if (auto channel = App::channelLoaded(channelId)) { + resolveMessageAndShareScore(channel); + } + })); } } } diff --git a/Telegram/SourceFiles/boxes/share_box.h b/Telegram/SourceFiles/boxes/share_box.h index 6caf6cb1d..b9d484cb7 100644 --- a/Telegram/SourceFiles/boxes/share_box.h +++ b/Telegram/SourceFiles/boxes/share_box.h @@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include "boxes/abstract_box.h" #include "base/observer.h" +#include "boxes/abstract_box.h" #include "ui/effects/round_checkbox.h" namespace Dialogs { @@ -45,9 +45,9 @@ class ShareBox : public BoxContent, public RPCSender { public: using CopyCallback = base::lambda; - using SubmitCallback = base::lambda &)>; - using FilterCallback = base::lambda; - ShareBox(QWidget*, CopyCallback &©Callback, SubmitCallback &&submitCallback, FilterCallback &&filterCallback); + using SubmitCallback = base::lambda &)>; + using FilterCallback = base::lambda; + ShareBox(QWidget *, CopyCallback &©Callback, SubmitCallback &&submitCallback, FilterCallback &&filterCallback); protected: void prepare() override; @@ -104,7 +104,6 @@ private: PeopleQueries _peopleQueries; Animation _scrollAnimation; - }; // This class is hold in header because it requires Qt preprocessing. @@ -117,7 +116,7 @@ public: void setPeerSelectedChangedCallback(base::lambda callback); void peerUnselected(PeerData *peer); - QVector selected() const; + QVector selected() const; bool hasSelected() const; void peopleReceived(const QString &query, const QVector &people); @@ -195,12 +194,12 @@ private: ShareBox::FilterCallback _filterCallback; std::unique_ptr _chatsIndexed; QString _filter; - using FilteredDialogs = QVector; + using FilteredDialogs = QVector; FilteredDialogs _filtered; - using DataMap = QMap; + using DataMap = QMap; DataMap _dataMap; - using SelectedChats = OrderedSet; + using SelectedChats = OrderedSet; SelectedChats _selected; base::lambda _peerSelectedChangedCallback; @@ -209,9 +208,8 @@ private: bool _searching = false; QString _lastQuery; - using ByUsernameRows = QVector; - using ByUsernameDatas = QVector; + using ByUsernameRows = QVector; + using ByUsernameDatas = QVector; ByUsernameRows _byUsernameFiltered; ByUsernameDatas d_byUsernameFiltered; - }; diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 5c1d25a3c..d7c4c035c 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -20,20 +20,20 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/sticker_set_box.h" +#include "apiwrap.h" +#include "auth_session.h" +#include "boxes/confirm_box.h" +#include "chat_helpers/stickers.h" +#include "dialogs/dialogs_layout.h" #include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" -#include "chat_helpers/stickers.h" -#include "boxes/confirm_box.h" -#include "apiwrap.h" +#include "messenger.h" #include "storage/localstorage.h" -#include "dialogs/dialogs_layout.h" #include "styles/style_boxes.h" #include "styles/style_chat_helpers.h" #include "ui/widgets/buttons.h" #include "ui/widgets/scroll_area.h" -#include "auth_session.h" -#include "messenger.h" #include #include @@ -43,9 +43,8 @@ constexpr auto kStickersPanelPerRow = Stickers::kPanelPerRow; } // namespace -StickerSetBox::StickerSetBox(QWidget*, const MTPInputStickerSet &set) -: _set(set) { -} +StickerSetBox::StickerSetBox(QWidget *, const MTPInputStickerSet &set) + : _set(set) {} void StickerSetBox::prepare() { setTitle(langFactory(lng_contacts_loading)); @@ -104,10 +103,14 @@ void StickerSetBox::resizeEvent(QResizeEvent *e) { _inner->resize(width(), _inner->height()); } -StickerSetBox::Inner::Inner(QWidget *parent, const MTPInputStickerSet &set) : TWidget(parent) -, _input(set) { +StickerSetBox::Inner::Inner(QWidget *parent, const MTPInputStickerSet &set) + : TWidget(parent) + , _input(set) { switch (set.type()) { - case mtpc_inputStickerSetID: _setId = set.c_inputStickerSetID().vid.v; _setAccess = set.c_inputStickerSetID().vaccess_hash.v; break; + case mtpc_inputStickerSetID: + _setId = set.c_inputStickerSetID().vid.v; + _setAccess = set.c_inputStickerSetID().vaccess_hash.v; + break; case mtpc_inputStickerSetShortName: _setShortName = qs(set.c_inputStickerSetShortName().vshort_name); break; } MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&Inner::gotSet), rpcFail(&Inner::failedSet)); @@ -170,7 +173,9 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) { auto &sets = Global::RefStickerSets(); auto it = sets.find(_setId); if (it != sets.cend()) { - auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded | MTPDstickerSet_ClientFlag::f_unread | MTPDstickerSet_ClientFlag::f_special); + auto clientFlags = + it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded | + MTPDstickerSet_ClientFlag::f_unread | MTPDstickerSet_ClientFlag::f_special); _setFlags |= clientFlags; it->flags = _setFlags; it->stickers = _pack; @@ -183,7 +188,8 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) { Ui::show(Box(lang(lng_stickers_not_found))); } else { qint32 rows = _pack.size() / kStickersPanelPerRow + ((_pack.size() % kStickersPanelPerRow) ? 1 : 0); - resize(st::stickersPadding.left() + kStickersPanelPerRow * st::stickersSize.width(), st::stickersPadding.top() + rows * st::stickersSize.height() + st::stickersPadding.bottom()); + resize(st::stickersPadding.left() + kStickersPanelPerRow * st::stickersSize.width(), + st::stickersPadding.top() + rows * st::stickersSize.height() + st::stickersPadding.bottom()); } _loaded = true; @@ -216,7 +222,8 @@ void StickerSetBox::Inner::installDone(const MTPmessages_StickerSetInstallResult _setFlags |= MTPDstickerSet::Flag::f_installed; auto it = sets.find(_setId); if (it == sets.cend()) { - it = sets.insert(_setId, Stickers::Set(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags)); + it = sets.insert(_setId, + Stickers::Set(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags)); } else { it->flags = _setFlags; } @@ -319,13 +326,15 @@ void StickerSetBox::Inner::setSelected(int selected) { void StickerSetBox::Inner::startOverAnimation(int index, double from, double to) { if (index >= 0 && index < _packOvers.size()) { - _packOvers[index].start([this, index] { - int row = index / kStickersPanelPerRow; - int column = index % kStickersPanelPerRow; - int left = st::stickersPadding.left() + column * st::stickersSize.width(); - int top = st::stickersPadding.top() + row * st::stickersSize.height(); - rtlupdate(left, top, st::stickersSize.width(), st::stickersSize.height()); - }, from, to, st::emojiPanDuration); + _packOvers[index].start( + [this, index] { + int row = index / kStickersPanelPerRow; + int column = index % kStickersPanelPerRow; + int left = st::stickersPadding.left() + column * st::stickersSize.width(); + int top = st::stickersPadding.top() + row * st::stickersSize.height(); + rtlupdate(left, top, st::stickersSize.width(), st::stickersSize.height()); + }, + from, to, st::emojiPanDuration); } } @@ -340,8 +349,12 @@ void StickerSetBox::Inner::onPreview() { qint32 StickerSetBox::Inner::stickerFromGlobalPos(const QPoint &p) const { QPoint l(mapFromGlobal(p)); if (rtl()) l.setX(width() - l.x()); - qint32 row = (l.y() >= st::stickersPadding.top()) ? std::floor((l.y() - st::stickersPadding.top()) / st::stickersSize.height()) : -1; - qint32 col = (l.x() >= st::stickersPadding.left()) ? std::floor((l.x() - st::stickersPadding.left()) / st::stickersSize.width()) : -1; + qint32 row = (l.y() >= st::stickersPadding.top()) ? + std::floor((l.y() - st::stickersPadding.top()) / st::stickersSize.height()) : + -1; + qint32 col = (l.x() >= st::stickersPadding.left()) ? + std::floor((l.x() - st::stickersPadding.left()) / st::stickersSize.width()) : + -1; if (row >= 0 && col >= 0 && col < kStickersPanelPerRow) { qint32 result = row * kStickersPanelPerRow + col; return (result < _pack.size()) ? result : -1; @@ -357,7 +370,8 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) { auto ms = getms(); qint32 rows = _pack.size() / kStickersPanelPerRow + ((_pack.size() % kStickersPanelPerRow) ? 1 : 0); - qint32 from = std::floor(e->rect().top() / st::stickersSize.height()), to = std::floor(e->rect().bottom() / st::stickersSize.height()) + 1; + qint32 from = std::floor(e->rect().top() / st::stickersSize.height()), + to = std::floor(e->rect().bottom() / st::stickersSize.height()) + 1; for (qint32 i = from; i < to; ++i) { for (qint32 j = 0; j < kStickersPanelPerRow; ++j) { @@ -366,7 +380,8 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) { Assert(index < _packOvers.size()); DocumentData *doc = _pack.at(index); - QPoint pos(st::stickersPadding.left() + j * st::stickersSize.width(), st::stickersPadding.top() + i * st::stickersSize.height()); + QPoint pos(st::stickersPadding.left() + j * st::stickersSize.width(), + st::stickersPadding.top() + i * st::stickersSize.height()); if (auto over = _packOvers[index].current(ms, (index == _selected) ? 1. : 0.)) { p.setOpacity(over); @@ -374,7 +389,6 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) { if (rtl()) tl.setX(width() - tl.x() - st::stickersSize.width()); App::roundRect(p, QRect(tl, st::stickersSize), st::emojiPanHover, StickerHoverCorners); p.setOpacity(1); - } bool goodThumb = !doc->thumb->isNull() && ((doc->thumb->width() >= 128) || (doc->thumb->height() >= 128)); if (goodThumb) { @@ -388,7 +402,9 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) { } } - double coef = std::min((st::stickersSize.width() - st::buttonRadius * 2) / double(doc->dimensions.width()), (st::stickersSize.height() - st::buttonRadius * 2) / double(doc->dimensions.height())); + double coef = + std::min((st::stickersSize.width() - st::buttonRadius * 2) / double(doc->dimensions.width()), + (st::stickersSize.height() - st::buttonRadius * 2) / double(doc->dimensions.height())); if (coef > 1) coef = 1; qint32 w = std::round(coef * doc->dimensions.width()), h = std::round(coef * doc->dimensions.height()); if (w < 1) w = 1; @@ -415,7 +431,9 @@ bool StickerSetBox::Inner::loaded() const { qint32 StickerSetBox::Inner::notInstalled() const { if (!_loaded) return 0; auto it = Global::StickerSets().constFind(_setId); - if (it == Global::StickerSets().cend() || !(it->flags & MTPDstickerSet::Flag::f_installed) || (it->flags & MTPDstickerSet::Flag::f_archived)) return _pack.size(); + if (it == Global::StickerSets().cend() || !(it->flags & MTPDstickerSet::Flag::f_installed) || + (it->flags & MTPDstickerSet::Flag::f_archived)) + return _pack.size(); return 0; } @@ -424,15 +442,15 @@ bool StickerSetBox::Inner::official() const { } base::lambda StickerSetBox::Inner::title() const { - auto text = TextWithEntities { _setTitle }; + auto text = TextWithEntities{_setTitle}; if (_loaded) { if (_pack.isEmpty()) { - return [] { return TextWithEntities { lang(lng_attach_failed), EntitiesInText() }; }; + return [] { return TextWithEntities{lang(lng_attach_failed), EntitiesInText()}; }; } else { TextUtilities::ParseEntities(text, TextParseMentions); } } else { - return [] { return TextWithEntities { lang(lng_contacts_loading), EntitiesInText() }; }; + return [] { return TextWithEntities{lang(lng_contacts_loading), EntitiesInText()}; }; } return [text] { return text; }; } @@ -447,8 +465,8 @@ void StickerSetBox::Inner::install() { return; } if (_installRequest) return; - _installRequest = MTP::send(MTPmessages_InstallStickerSet(_input, MTP_bool(false)), rpcDone(&Inner::installDone), rpcFail(&Inner::installFail)); + _installRequest = MTP::send(MTPmessages_InstallStickerSet(_input, MTP_bool(false)), rpcDone(&Inner::installDone), + rpcFail(&Inner::installFail)); } -StickerSetBox::Inner::~Inner() { -} +StickerSetBox::Inner::~Inner() {} diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.h b/Telegram/SourceFiles/boxes/sticker_set_box.h index 406a3f8af..f7675cc66 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.h +++ b/Telegram/SourceFiles/boxes/sticker_set_box.h @@ -33,7 +33,7 @@ class StickerSetBox : public BoxContent, public RPCSender { Q_OBJECT public: - StickerSetBox(QWidget*, const MTPInputStickerSet &set); + StickerSetBox(QWidget *, const MTPInputStickerSet &set); signals: void installed(quint64 id); @@ -57,7 +57,6 @@ private: class Inner; QPointer _inner; - }; // This class is hold in header because it requires Qt preprocessing. @@ -129,5 +128,4 @@ private: QTimer _previewTimer; int _previewShown = -1; - }; diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 422656e07..f3f04498f 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -20,25 +20,25 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "stickers_box.h" -#include "lang/lang_keys.h" -#include "mainwidget.h" -#include "chat_helpers/stickers.h" +#include "apiwrap.h" +#include "auth_session.h" #include "boxes/confirm_box.h" #include "boxes/sticker_set_box.h" -#include "apiwrap.h" -#include "storage/localstorage.h" +#include "chat_helpers/stickers.h" #include "dialogs/dialogs_layout.h" +#include "lang/lang_keys.h" +#include "mainwidget.h" +#include "messenger.h" +#include "storage/localstorage.h" #include "styles/style_boxes.h" #include "styles/style_chat_helpers.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/labels.h" -#include "ui/widgets/scroll_area.h" #include "ui/effects/ripple_animation.h" #include "ui/effects/slide_animation.h" +#include "ui/widgets/buttons.h" #include "ui/widgets/discrete_sliders.h" #include "ui/widgets/input_fields.h" -#include "auth_session.h" -#include "messenger.h" +#include "ui/widgets/labels.h" +#include "ui/widgets/scroll_area.h" namespace { @@ -55,7 +55,8 @@ int stickerPacksCount(bool includeArchivedOfficial) { for (auto i = 0, l = order.size(); i < l; ++i) { auto it = sets.constFind(order.at(i)); if (it != sets.cend()) { - if (!(it->flags & MTPDstickerSet::Flag::f_archived) || ((it->flags & MTPDstickerSet::Flag::f_official) && includeArchivedOfficial)) { + if (!(it->flags & MTPDstickerSet::Flag::f_archived) || + ((it->flags & MTPDstickerSet::Flag::f_official) && includeArchivedOfficial)) { ++result; } } @@ -77,10 +78,10 @@ private: QString _text; Dialogs::Layout::UnreadBadgeStyle _st; - }; -StickersBox::CounterWidget::CounterWidget(QWidget *parent) : TWidget(parent) { +StickersBox::CounterWidget::CounterWidget(QWidget *parent) + : TWidget(parent) { setAttribute(Qt::WA_TransparentForMouseEvents); _st.sizeId = Dialogs::Layout::UnreadBadgeInStickersBox; @@ -119,12 +120,11 @@ void StickersBox::CounterWidget::updateCounter() { update(); } -template -StickersBox::Tab::Tab(int index, Args&&... args) -: _index(index) -, _widget(std::forward(args)...) -, _weak(_widget) { -} +template +StickersBox::Tab::Tab(int index, Args &&... args) + : _index(index) + , _widget(std::forward(args)...) + , _weak(_widget) {} object_ptr StickersBox::Tab::takeWidget() { return std::move(_widget); @@ -139,20 +139,20 @@ void StickersBox::Tab::saveScrollTop() { _scrollTop = widget()->getVisibleTop(); } -StickersBox::StickersBox(QWidget*, Section section) -: _tabs(this, st::stickersTabs) -, _unreadBadge(this) -, _section(section) -, _installed(0, this, Section::Installed) -, _featured(1, this, Section::Featured) -, _archived(2, this, Section::Archived) { +StickersBox::StickersBox(QWidget *, Section section) + : _tabs(this, st::stickersTabs) + , _unreadBadge(this) + , _section(section) + , _installed(0, this, Section::Installed) + , _featured(1, this, Section::Featured) + , _archived(2, this, Section::Archived) { _tabs->setRippleTopRoundRadius(st::boxRadius); } -StickersBox::StickersBox(QWidget*, not_null megagroup) -: _section(Section::Installed) -, _installed(0, this, megagroup) -, _megagroupSet(megagroup) { +StickersBox::StickersBox(QWidget *, not_null megagroup) + : _section(Section::Installed) + , _installed(0, this, megagroup) + , _megagroupSet(megagroup) { subscribe(_installed.widget()->scrollToY, [this](int y) { onScrollToY(y); }); } @@ -243,9 +243,7 @@ void StickersBox::prepare() { preloadArchivedSets(); } setNoContentMargin(true); - _tabs->setSectionActivatedCallback([this] { - switchTab(); - }); + _tabs->setSectionActivatedCallback([this] { switchTab(); }); refreshTabs(); } if (_installed.widget() && _section != Section::Installed) _installed.widget()->hide(); @@ -261,7 +259,10 @@ void StickersBox::prepare() { } if (_megagroupSet) { - addButton(langFactory(lng_settings_save), [this] { _installed.widget()->saveGroupSet(); closeBox(); }); + addButton(langFactory(lng_settings_save), [this] { + _installed.widget()->saveGroupSet(); + closeBox(); + }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); } else { addButton(langFactory(lng_about_done), [this] { closeBox(); }); @@ -310,8 +311,8 @@ void StickersBox::refreshTabs() { _tabIndices.push_back(Section::Archived); } _tabs->setSections(sections); - if ((_tab == &_archived && !_tabIndices.contains(Section::Archived)) - || (_tab == &_featured && !_tabIndices.contains(Section::Featured))) { + if ((_tab == &_archived && !_tabIndices.contains(Section::Archived)) || + (_tab == &_featured && !_tabIndices.contains(Section::Featured))) { switchTab(); } else if (_tab == &_archived) { _tabs->setActiveSectionFast(_tabIndices.indexOf(Section::Archived)); @@ -327,7 +328,8 @@ void StickersBox::loadMoreArchived() { } quint64 lastId = 0; - for (auto setIt = Global::ArchivedStickerSetsOrder().cend(), e = Global::ArchivedStickerSetsOrder().cbegin(); setIt != e;) { + for (auto setIt = Global::ArchivedStickerSetsOrder().cend(), e = Global::ArchivedStickerSetsOrder().cbegin(); + setIt != e;) { --setIt; auto it = Global::StickerSets().constFind(*setIt); if (it != Global::StickerSets().cend()) { @@ -337,7 +339,9 @@ void StickersBox::loadMoreArchived() { } } } - _archivedRequestId = MTP::send(MTPmessages_GetArchivedStickers(MTP_flags(0), MTP_long(lastId), MTP_int(kArchivedLimitPerPage)), rpcDone(&StickersBox::getArchivedDone, lastId)); + _archivedRequestId = + MTP::send(MTPmessages_GetArchivedStickers(MTP_flags(0), MTP_long(lastId), MTP_int(kArchivedLimitPerPage)), + rpcDone(&StickersBox::getArchivedDone, lastId)); } void StickersBox::paintEvent(QPaintEvent *e) { @@ -456,7 +460,8 @@ void StickersBox::installSet(quint64 setId) { _archived.widget()->setRemovedSets(_localRemoved); } if (!(it->flags & MTPDstickerSet::Flag::f_installed) || (it->flags & MTPDstickerSet::Flag::f_archived)) { - MTP::send(MTPmessages_InstallStickerSet(Stickers::inputSetId(*it), MTP_boolFalse()), rpcDone(&StickersBox::installDone), rpcFail(&StickersBox::installFail, setId)); + MTP::send(MTPmessages_InstallStickerSet(Stickers::inputSetId(*it), MTP_boolFalse()), + rpcDone(&StickersBox::installDone), rpcFail(&StickersBox::installFail, setId)); Stickers::InstallLocally(setId); } @@ -486,10 +491,8 @@ void StickersBox::preloadArchivedSets() { if (!_tabs) return; if (!_archivedRequestId) { _archivedRequestId = - MTP::send(MTPmessages_GetArchivedStickers(MTP_flags(0), - MTP_long(0), - MTP_int(kArchivedLimitFirstRequest)), - rpcDone(&StickersBox::getArchivedDone, Q_UINT64_C(0))); + MTP::send(MTPmessages_GetArchivedStickers(MTP_flags(0), MTP_long(0), MTP_int(kArchivedLimitFirstRequest)), + rpcDone(&StickersBox::getArchivedDone, Q_UINT64_C(0))); } } @@ -572,49 +575,57 @@ void StickersBox::setInnerFocus() { StickersBox::~StickersBox() = default; -StickersBox::Inner::Row::Row(quint64 id, DocumentData *sticker, qint32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, qint32 pixw, qint32 pixh) : id(id) -, sticker(sticker) -, count(count) -, title(title) -, titleWidth(titleWidth) -, installed(installed) -, official(official) -, unread(unread) -, archived(archived) -, removed(removed) -, pixw(pixw) -, pixh(pixh) { -} +StickersBox::Inner::Row::Row(quint64 id, DocumentData *sticker, qint32 count, const QString &title, int titleWidth, + bool installed, bool official, bool unread, bool archived, bool removed, qint32 pixw, + qint32 pixh) + : id(id) + , sticker(sticker) + , count(count) + , title(title) + , titleWidth(titleWidth) + , installed(installed) + , official(official) + , unread(unread) + , archived(archived) + , removed(removed) + , pixw(pixw) + , pixh(pixh) {} StickersBox::Inner::Row::~Row() = default; -StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section) : TWidget(parent) -, _section(section) -, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) -, _a_shifting(animation(this, &Inner::step_shifting)) -, _itemsTop(st::membersMarginTop) -, _addText(lang(lng_stickers_featured_add).toUpper()) -, _addWidth(st::stickersTrendingAdd.font->width(_addText)) -, _undoText(lang(lng_stickers_return).toUpper()) -, _undoWidth(st::stickersUndoRemove.font->width(_undoText)) { +StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section) + : TWidget(parent) + , _section(section) + , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) + , _a_shifting(animation(this, &Inner::step_shifting)) + , _itemsTop(st::membersMarginTop) + , _addText(lang(lng_stickers_featured_add).toUpper()) + , _addWidth(st::stickersTrendingAdd.font->width(_addText)) + , _undoText(lang(lng_stickers_return).toUpper()) + , _undoWidth(st::stickersUndoRemove.font->width(_undoText)) { setup(); } -StickersBox::Inner::Inner(QWidget *parent, not_null megagroup) : TWidget(parent) -, _section(StickersBox::Section::Installed) -, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) -, _a_shifting(animation(this, &Inner::step_shifting)) -, _itemsTop(st::membersMarginTop) -, _megagroupSet(megagroup) -, _megagroupSetInput(_megagroupSet->mgInfo->stickerSet) -, _megagroupSetField(this, st::groupStickersField, [] { return qsl("stickerset"); }, QString(), true) -, _megagroupDivider(this) -, _megagroupSubTitle(this, lang(lng_stickers_group_from_your), Ui::FlatLabel::InitType::Simple, st::boxTitle) { +StickersBox::Inner::Inner(QWidget *parent, not_null megagroup) + : TWidget(parent) + , _section(StickersBox::Section::Installed) + , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) + , _a_shifting(animation(this, &Inner::step_shifting)) + , _itemsTop(st::membersMarginTop) + , _megagroupSet(megagroup) + , _megagroupSetInput(_megagroupSet->mgInfo->stickerSet) + , _megagroupSetField(this, st::groupStickersField, [] { return qsl("stickerset"); }, QString(), true) + , _megagroupDivider(this) + , _megagroupSubTitle(this, lang(lng_stickers_group_from_your), Ui::FlatLabel::InitType::Simple, st::boxTitle) { _megagroupSetField->setLinkPlaceholder(Messenger::Instance().createInternalLink(qsl("addstickers/"))); _megagroupSetField->setPlaceholderHidden(false); _megagroupSetAddressChangedTimer.setCallback([this] { handleMegagroupSetAddressChange(); }); - connect(_megagroupSetField, &Ui::MaskedInputField::changed, this, [this] { _megagroupSetAddressChangedTimer.callOnce(kHandleMegagroupSetAddressChangeTimeout); }); - connect(_megagroupSetField, &Ui::MaskedInputField::submitted, this, [this] { _megagroupSetAddressChangedTimer.cancel(); handleMegagroupSetAddressChange(); }); + connect(_megagroupSetField, &Ui::MaskedInputField::changed, this, + [this] { _megagroupSetAddressChangedTimer.callOnce(kHandleMegagroupSetAddressChangeTimeout); }); + connect(_megagroupSetField, &Ui::MaskedInputField::submitted, this, [this] { + _megagroupSetAddressChangedTimer.cancel(); + handleMegagroupSetAddressChange(); + }); setup(); } @@ -683,12 +694,14 @@ void StickersBox::Inner::updateControlsGeometry() { if (_megagroupSet) { auto top = st::groupStickersFieldPadding.top(); auto fieldLeft = st::boxLayerTitlePosition.x(); - _megagroupSetField->setGeometryToLeft(fieldLeft, top, width() - fieldLeft - st::groupStickersFieldPadding.right(), _megagroupSetField->height()); + _megagroupSetField->setGeometryToLeft( + fieldLeft, top, width() - fieldLeft - st::groupStickersFieldPadding.right(), _megagroupSetField->height()); top += _megagroupSetField->height() + st::groupStickersFieldPadding.bottom(); if (_megagroupSelectedRemove) { _megagroupSelectedShadow->setGeometryToLeft(0, top, width(), st::lineWidth); top += st::lineWidth; - _megagroupSelectedRemove->moveToRight(st::groupStickersRemovePosition.x(), top + st::groupStickersRemovePosition.y()); + _megagroupSelectedRemove->moveToRight(st::groupStickersRemovePosition.x(), + top + st::groupStickersRemovePosition.y()); top += _rowHeight; } _megagroupDivider->setGeometryToLeft(0, top, width(), _megagroupDivider->height()); @@ -736,7 +749,10 @@ void StickersBox::Inner::paintRow(Painter &p, Row *set, int index, TimeMs ms) { current = reachedOpacity; } } - auto row = myrtlrect(st::contactsPadding.left() / 2, st::contactsPadding.top() / 2, width() - (st::contactsPadding.left() / 2) - _scrollbar - st::contactsPadding.left() / 2, _rowHeight - ((st::contactsPadding.top() + st::contactsPadding.bottom()) / 2)); + auto row = + myrtlrect(st::contactsPadding.left() / 2, st::contactsPadding.top() / 2, + width() - (st::contactsPadding.left() / 2) - _scrollbar - st::contactsPadding.left() / 2, + _rowHeight - ((st::contactsPadding.top() + st::contactsPadding.bottom()) / 2)); p.setOpacity(current); Ui::Shadow::paint(p, row, width(), st::boxRoundShadow); p.setOpacity(1); @@ -762,14 +778,16 @@ void StickersBox::Inner::paintRow(Painter &p, Row *set, int index, TimeMs ms) { if (!_megagroupSet && _section == Section::Installed) { stickerx += st::stickersReorderIcon.width() + st::stickersReorderSkip; if (!set->isRecentSet()) { - st::stickersReorderIcon.paint(p, st::contactsPadding.left(), (_rowHeight - st::stickersReorderIcon.height()) / 2, width()); + st::stickersReorderIcon.paint(p, st::contactsPadding.left(), + (_rowHeight - st::stickersReorderIcon.height()) / 2, width()); } } if (set->sticker) { set->sticker->thumb->load(); auto pix = set->sticker->thumb->pix(set->pixw, set->pixh); - p.drawPixmapLeft(stickerx + (st::contactsPhotoSize - set->pixw) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - set->pixh) / 2, width(), pix); + p.drawPixmapLeft(stickerx + (st::contactsPhotoSize - set->pixw) / 2, + st::contactsPadding.top() + (st::contactsPhotoSize - set->pixh) / 2, width(), pix); } int namex = stickerx + st::contactsPhotoSize + st::contactsPadding.left(); @@ -788,7 +806,9 @@ void StickersBox::Inner::paintRow(Painter &p, Row *set, int index, TimeMs ms) { { PainterHighQualityEnabler hq(p); - p.drawEllipse(rtlrect(namex + set->titleWidth + st::stickersFeaturedUnreadSkip, namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width())); + p.drawEllipse(rtlrect(namex + set->titleWidth + st::stickersFeaturedUnreadSkip, + namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, + st::stickersFeaturedUnreadSize, width())); } } @@ -807,7 +827,8 @@ void StickersBox::Inner::paintFakeButton(Painter &p, Row *set, int index, TimeMs auto rect = relativeButtonRect(removeButton); if (_section != Section::Installed && set->installed && !set->archived && !set->removed) { // Checkbox after installed from Trending or Archived. - int checkx = width() - (st::contactsPadding.right() + st::contactsCheckPosition.x() + (rect.width() + st::stickersFeaturedInstalled.width()) / 2); + int checkx = width() - (st::contactsPadding.right() + st::contactsCheckPosition.x() + + (rect.width() + st::stickersFeaturedInstalled.width()) / 2); int checky = st::contactsPadding.top() + (st::contactsPhotoSize - st::stickersFeaturedInstalled.height()) / 2; st::stickersFeaturedInstalled.paint(p, QPoint(checkx, checky), width()); } else { @@ -896,7 +917,8 @@ void StickersBox::Inner::setActionDown(int newActionDown) { } if (set->ripple) { auto rect = relativeButtonRect(removeButton); - set->ripple->add(mapFromGlobal(QCursor::pos()) - QPoint(myrtlrect(rect).x(), _itemsTop + _actionDown * _rowHeight + rect.y())); + set->ripple->add(mapFromGlobal(QCursor::pos()) - + QPoint(myrtlrect(rect).x(), _itemsTop + _actionDown * _rowHeight + rect.y())); } } } @@ -931,18 +953,19 @@ void StickersBox::Inner::setPressed(int pressed) { auto &set = _rows[_pressed]; auto rippleMask = Ui::RippleAnimation::rectMask(QSize(width(), _rowHeight)); if (!_rows[_pressed]->ripple) { - _rows[_pressed]->ripple = std::make_unique(st::contactsRipple, std::move(rippleMask), [this, index = _pressed] { - update(0, _itemsTop + index * _rowHeight, width(), _rowHeight); - }); + _rows[_pressed]->ripple = std::make_unique( + st::contactsRipple, std::move(rippleMask), + [this, index = _pressed] { update(0, _itemsTop + index * _rowHeight, width(), _rowHeight); }); } _rows[_pressed]->ripple->add(mapFromGlobal(QCursor::pos()) - QPoint(0, _itemsTop + _pressed * _rowHeight)); } } void StickersBox::Inner::ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton) { - _rows[_actionDown]->ripple = std::make_unique(st, std::move(mask), [this, index = _actionDown, removeButton] { - update(myrtlrect(relativeButtonRect(removeButton).translated(0, _itemsTop + index * _rowHeight))); - }); + _rows[_actionDown]->ripple = + std::make_unique(st, std::move(mask), [this, index = _actionDown, removeButton] { + update(myrtlrect(relativeButtonRect(removeButton).translated(0, _itemsTop + index * _rowHeight))); + }); } void StickersBox::Inner::mouseMoveEvent(QMouseEvent *e) { @@ -960,14 +983,16 @@ void StickersBox::Inner::onUpdateSelected() { ++firstSetIndex; } if (_dragStart.y() > local.y() && _dragging > 0) { - shift = -floorclamp(_dragStart.y() - local.y() + (_rowHeight / 2), _rowHeight, 0, _dragging - firstSetIndex); + shift = + -floorclamp(_dragStart.y() - local.y() + (_rowHeight / 2), _rowHeight, 0, _dragging - firstSetIndex); for (qint32 from = _dragging, to = _dragging + shift; from > to; --from) { qSwap(_rows[from], _rows[from - 1]); _rows[from]->yadd = anim::value(_rows[from]->yadd.current() - _rowHeight, 0); _animStartTimes[from] = ms; } } else if (_dragStart.y() < local.y() && _dragging + 1 < _rows.size()) { - shift = floorclamp(local.y() - _dragStart.y() + (_rowHeight / 2), _rowHeight, 0, _rows.size() - _dragging - 1); + shift = + floorclamp(local.y() - _dragStart.y() + (_rowHeight / 2), _rowHeight, 0, _rows.size() - _dragging - 1); for (qint32 from = _dragging, to = _dragging + shift; from < to; ++from) { qSwap(_rows[from], _rows[from + 1]); _rows[from]->yadd = anim::value(_rows[from]->yadd.current() + _rowHeight, 0); @@ -1005,7 +1030,8 @@ void StickersBox::Inner::onUpdateSelected() { selected = floorclamp(local.y() - _itemsTop, _rowHeight, 0, _rows.size() - 1); local.setY(local.y() - _itemsTop - selected * _rowHeight); auto &set = _rows[selected]; - if (!_megagroupSet && (_section == Section::Installed || !set->installed || set->archived || set->removed)) { + if (!_megagroupSet && + (_section == Section::Installed || !set->installed || set->archived || set->removed)) { auto removeButton = (_section == Section::Installed && !set->removed); auto rect = myrtlrect(relativeButtonRect(removeButton)); actionSel = rect.contains(local) ? selected : -1; @@ -1013,7 +1039,8 @@ void StickersBox::Inner::onUpdateSelected() { actionSel = -1; } if (!_megagroupSet && _section == Section::Installed && !set->isRecentSet()) { - auto dragAreaWidth = st::contactsPadding.left() + st::stickersReorderIcon.width() + st::stickersReorderSkip; + auto dragAreaWidth = + st::contactsPadding.left() + st::stickersReorderIcon.width() + st::stickersReorderSkip; auto dragArea = myrtlrect(0, 0, dragAreaWidth, _rowHeight); inDragArea = dragArea.contains(local); } @@ -1021,7 +1048,8 @@ void StickersBox::Inner::onUpdateSelected() { selected = -1; } if (_selected != selected) { - if ((_megagroupSet || _section != Section::Installed) && ((_selected >= 0 || _pressed >= 0) != (selected >= 0 || _pressed >= 0))) { + if ((_megagroupSet || _section != Section::Installed) && + ((_selected >= 0 || _pressed >= 0) != (selected >= 0 || _pressed >= 0))) { if (!inDragArea) { setCursor((selected >= 0 || _pressed >= 0) ? style::cur_pointer : style::cur_default); } @@ -1030,7 +1058,8 @@ void StickersBox::Inner::onUpdateSelected() { } if (_inDragArea != inDragArea) { _inDragArea = inDragArea; - setCursor(_inDragArea ? style::cur_sizeall : (_selected >= 0 || _pressed >= 0) ? style::cur_pointer : style::cur_default); + setCursor(_inDragArea ? style::cur_sizeall : + (_selected >= 0 || _pressed >= 0) ? style::cur_pointer : style::cur_default); } setActionSel(actionSel); emit draggingScrollDelta(0); @@ -1042,7 +1071,7 @@ double StickersBox::Inner::aboveShadowOpacity() const { auto dx = 0; auto dy = qAbs(_above * _rowHeight + std::round(_rows[_above]->yadd.current()) - _started * _rowHeight); - return std::min((dx + dy) * 2. / _rowHeight, 1.); + return std::min((dx + dy) * 2. / _rowHeight, 1.); } void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) { @@ -1092,8 +1121,11 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) { void StickersBox::Inner::saveGroupSet() { Expects(_megagroupSet != nullptr); - auto oldId = (_megagroupSet->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) ? _megagroupSet->mgInfo->stickerSet.c_inputStickerSetID().vid.v : 0; - auto newId = (_megagroupSetInput.type() == mtpc_inputStickerSetID) ? _megagroupSetInput.c_inputStickerSetID().vid.v : 0; + auto oldId = (_megagroupSet->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) ? + _megagroupSet->mgInfo->stickerSet.c_inputStickerSetID().vid.v : + 0; + auto newId = + (_megagroupSetInput.type() == mtpc_inputStickerSetID) ? _megagroupSetInput.c_inputStickerSetID().vid.v : 0; if (newId != oldId) { Auth().api().setGroupStickerSet(_megagroupSet, _megagroupSetInput); App::main()->onStickersInstalled(Stickers::MegagroupSetId); @@ -1142,7 +1174,8 @@ void StickersBox::Inner::step_shifting(TimeMs ms, bool timer) { if (updateMin < 0 || updateMin > _above) updateMin = _above; if (updateMax < _above) updateMin = _above; if (_aboveShadowFadeStart + st::stickersRowDuration > ms && ms > _aboveShadowFadeStart) { - _aboveShadowFadeOpacity.update(double(ms - _aboveShadowFadeStart) / st::stickersRowDuration, anim::sineInOut); + _aboveShadowFadeOpacity.update(double(ms - _aboveShadowFadeStart) / st::stickersRowDuration, + anim::sineInOut); animating = true; } else { _aboveShadowFadeOpacity.finish(); @@ -1189,7 +1222,8 @@ void StickersBox::Inner::setActionSel(qint32 actionSel) { _actionSel = actionSel; if (_actionSel >= 0) update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight); if (_section == Section::Installed) { - setCursor((_actionSel >= 0 && (_actionDown < 0 || _actionDown == _actionSel)) ? style::cur_pointer : style::cur_default); + setCursor((_actionSel >= 0 && (_actionDown < 0 || _actionDown == _actionSel)) ? style::cur_pointer : + style::cur_default); } } } @@ -1204,14 +1238,18 @@ void StickersBox::Inner::handleMegagroupSetAddressChange() { } } } else if (!_megagroupSetRequestId) { - _megagroupSetRequestId = request(MTPmessages_GetStickerSet(MTP_inputStickerSetShortName(MTP_string(text)))).done([this](const MTPmessages_StickerSet &result) { - _megagroupSetRequestId = 0; - auto set = Stickers::FeedSetFull(result); - setMegagroupSelectedSet(MTP_inputStickerSetID(MTP_long(set->id), MTP_long(set->access))); - }).fail([this](const RPCError &error) { - _megagroupSetRequestId = 0; - setMegagroupSelectedSet(MTP_inputStickerSetEmpty()); - }).send(); + _megagroupSetRequestId = + request(MTPmessages_GetStickerSet(MTP_inputStickerSetShortName(MTP_string(text)))) + .done([this](const MTPmessages_StickerSet &result) { + _megagroupSetRequestId = 0; + auto set = Stickers::FeedSetFull(result); + setMegagroupSelectedSet(MTP_inputStickerSetID(MTP_long(set->id), MTP_long(set->access))); + }) + .fail([this](const RPCError &error) { + _megagroupSetRequestId = 0; + setMegagroupSelectedSet(MTP_inputStickerSetEmpty()); + }) + .send(); } else { _megagroupSetAddressChangedTimer.callOnce(kHandleMegagroupSetAddressChangeTimeout); } @@ -1242,7 +1280,7 @@ void StickersBox::Inner::rebuildMegagroupSet() { auto titleWidth = 0; auto title = fillSetTitle(*it, maxNameWidth, &titleWidth); auto count = fillSetCount(*it); - auto sticker = (DocumentData*)nullptr; + auto sticker = (DocumentData *)nullptr; auto pixw = 0, pixh = 0; fillSetCover(*it, &sticker, &pixw, &pixh); auto installed = true, official = false, unread = false, archived = false, removed = false; @@ -1250,15 +1288,14 @@ void StickersBox::Inner::rebuildMegagroupSet() { _megagroupSetField->setText(it->shortName); _megagroupSetField->finishAnimations(); } - _megagroupSelectedSet = std::make_unique(it->id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh); + _megagroupSelectedSet = std::make_unique(it->id, sticker, count, title, titleWidth, installed, official, + unread, archived, removed, pixw, pixh); _itemsTop += st::lineWidth + _rowHeight; if (!_megagroupSelectedRemove) { _megagroupSelectedRemove.create(this, st::groupStickersRemove); _megagroupSelectedRemove->showFast(); - _megagroupSelectedRemove->setClickedCallback([this] { - setMegagroupSelectedSet(MTP_inputStickerSetEmpty()); - }); + _megagroupSelectedRemove->setClickedCallback([this] { setMegagroupSelectedSet(MTP_inputStickerSetEmpty()); }); _megagroupSelectedShadow.create(this); updateControlsGeometry(); } @@ -1268,7 +1305,8 @@ void StickersBox::Inner::rebuild() { _itemsTop = st::membersMarginTop; if (_megagroupSet) { - _itemsTop += st::groupStickersFieldPadding.top() + _megagroupSetField->height() + st::groupStickersFieldPadding.bottom(); + _itemsTop += + st::groupStickersFieldPadding.top() + _megagroupSetField->height() + st::groupStickersFieldPadding.bottom(); _itemsTop += _megagroupDivider->height() + st::groupStickersSubTitleHeight; rebuildMegagroupSet(); } @@ -1336,7 +1374,7 @@ void StickersBox::Inner::updateRows() { if (it != sets.cend()) { auto &set = it.value(); if (!row->sticker) { - auto sticker = (DocumentData*)nullptr; + auto sticker = (DocumentData *)nullptr; auto pixw = 0, pixh = 0; fillSetCover(set, &sticker, &pixw, &pixh); if (sticker) { @@ -1404,11 +1442,13 @@ void StickersBox::Inner::rebuildAppendSet(const Stickers::Set &set, int maxNameW QString title = fillSetTitle(set, maxNameWidth, &titleWidth); int count = fillSetCount(set); - _rows.push_back(std::make_unique(set.id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh)); + _rows.push_back(std::make_unique(set.id, sticker, count, title, titleWidth, installed, official, unread, + archived, removed, pixw, pixh)); _animStartTimes.push_back(0); } -void StickersBox::Inner::fillSetCover(const Stickers::Set &set, DocumentData **outSticker, int *outWidth, int *outHeight) const { +void StickersBox::Inner::fillSetCover(const Stickers::Set &set, DocumentData **outSticker, int *outWidth, + int *outHeight) const { if (set.stickers.isEmpty()) { *outSticker = nullptr; *outWidth = *outHeight = 0; @@ -1465,7 +1505,8 @@ QString StickersBox::Inner::fillSetTitle(const Stickers::Set &set, int maxNameWi return result; } -void StickersBox::Inner::fillSetFlags(const Stickers::Set &set, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outArchived) { +void StickersBox::Inner::fillSetFlags(const Stickers::Set &set, bool *outInstalled, bool *outOfficial, bool *outUnread, + bool *outArchived) { *outInstalled = (set.flags & MTPDstickerSet::Flag::f_installed); *outOfficial = (set.flags & MTPDstickerSet::Flag::f_official); *outArchived = (set.flags & MTPDstickerSet::Flag::f_archived); @@ -1476,8 +1517,7 @@ void StickersBox::Inner::fillSetFlags(const Stickers::Set &set, bool *outInstall } } -template -Stickers::Order StickersBox::Inner::collectSets(Check check) const { +template Stickers::Order StickersBox::Inner::collectSets(Check check) const { Stickers::Order result; result.reserve(_rows.size()); for_const (auto &row, _rows) { @@ -1489,21 +1529,15 @@ Stickers::Order StickersBox::Inner::collectSets(Check check) const { } Stickers::Order StickersBox::Inner::getOrder() const { - return collectSets([](Row *row) { - return !row->archived && !row->removed && !row->isRecentSet(); - }); + return collectSets([](Row *row) { return !row->archived && !row->removed && !row->isRecentSet(); }); } Stickers::Order StickersBox::Inner::getFullOrder() const { - return collectSets([](Row *row) { - return !row->isRecentSet(); - }); + return collectSets([](Row *row) { return !row->isRecentSet(); }); } Stickers::Order StickersBox::Inner::getRemovedSets() const { - return collectSets([](Row *row) { - return row->removed; - }); + return collectSets([](Row *row) { return row->removed; }); } int StickersBox::Inner::getRowIndex(quint64 setId) const { diff --git a/Telegram/SourceFiles/boxes/stickers_box.h b/Telegram/SourceFiles/boxes/stickers_box.h index 37736c630..695e62196 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.h +++ b/Telegram/SourceFiles/boxes/stickers_box.h @@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include "boxes/abstract_box.h" #include "base/timer.h" +#include "boxes/abstract_box.h" #include "mtproto/sender.h" class ConfirmBox; @@ -46,8 +46,8 @@ public: Featured, Archived, }; - StickersBox(QWidget*, Section section); - StickersBox(QWidget*, not_null megagroup); + StickersBox(QWidget *, Section section); + StickersBox(QWidget *, not_null megagroup); void setInnerFocus() override; @@ -65,8 +65,7 @@ private: public: Tab() = default; - template - Tab(int index, Args&&... args); + template Tab(int index, Args &&... args); object_ptr takeWidget(); void returnWidget(object_ptr widget); @@ -85,10 +84,9 @@ private: private: int _index = 0; - object_ptr _widget = { nullptr }; + object_ptr _widget = {nullptr}; QPointer _weak; int _scrollTop = 0; - }; void handleStickersUpdated(); @@ -110,11 +108,11 @@ private: void loadMoreArchived(); void getArchivedDone(quint64 offsetId, const MTPmessages_ArchivedStickers &result); - object_ptr _tabs = { nullptr }; + object_ptr _tabs = {nullptr}; QList
_tabIndices; class CounterWidget; - object_ptr _unreadBadge = { nullptr }; + object_ptr _unreadBadge = {nullptr}; Section _section; @@ -126,7 +124,7 @@ private: ChannelData *_megagroupSet = nullptr; std::unique_ptr _slideAnimation; - object_ptr _titleShadow = { nullptr }; + object_ptr _titleShadow = {nullptr}; mtpRequestId _archivedRequestId = 0; bool _archivedLoaded = false; @@ -135,7 +133,6 @@ private: Stickers::Order _localOrder; Stickers::Order _localRemoved; - }; int stickerPacksCount(bool includeArchivedOfficial = false); @@ -147,7 +144,7 @@ class StickersBox::Inner : public TWidget, private base::Subscriber, private MTP public: using Section = StickersBox::Section; Inner(QWidget *parent, Section section); - Inner(QWidget *parent, not_null megagroup); + Inner(QWidget *parent, not_null megagroup); base::Observable scrollToY; void setInnerFocus(); @@ -199,7 +196,8 @@ public slots: private: struct Row { - Row(quint64 id, DocumentData *sticker, qint32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, qint32 pixw, qint32 pixh); + Row(quint64 id, DocumentData *sticker, qint32 count, const QString &title, int titleWidth, bool installed, + bool official, bool unread, bool archived, bool removed, qint32 pixw, qint32 pixh); bool isRecentSet() const { return (id == Stickers::CloudRecentSetId); } @@ -221,8 +219,7 @@ private: std::unique_ptr ripple; }; - template - Stickers::Order collectSets(Check check) const; + template Stickers::Order collectSets(Check check) const; void checkLoadMore(); void updateScrollbarWidth(); @@ -250,7 +247,8 @@ private: void fillSetCover(const Stickers::Set &set, DocumentData **outSticker, int *outWidth, int *outHeight) const; int fillSetCount(const Stickers::Set &set) const; QString fillSetTitle(const Stickers::Set &set, int maxNameWidth, int *outTitleWidth) const; - void fillSetFlags(const Stickers::Set &set, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outArchived); + void fillSetFlags(const Stickers::Set &set, bool *outInstalled, bool *outOfficial, bool *outUnread, + bool *outArchived); void rebuildMegagroupSet(); void handleMegagroupSetAddressChange(); void setMegagroupSelectedSet(const MTPInputStickerSet &set); @@ -299,12 +297,11 @@ private: ChannelData *_megagroupSet = nullptr; MTPInputStickerSet _megagroupSetInput = MTP_inputStickerSetEmpty(); std::unique_ptr _megagroupSelectedSet; - object_ptr _megagroupSetField = { nullptr }; - object_ptr _megagroupSelectedShadow = { nullptr }; - object_ptr _megagroupSelectedRemove = { nullptr }; - object_ptr _megagroupDivider = { nullptr }; - object_ptr _megagroupSubTitle = { nullptr }; + object_ptr _megagroupSetField = {nullptr}; + object_ptr _megagroupSelectedShadow = {nullptr}; + object_ptr _megagroupSelectedRemove = {nullptr}; + object_ptr _megagroupDivider = {nullptr}; + object_ptr _megagroupSubTitle = {nullptr}; base::Timer _megagroupSetAddressChangedTimer; mtpRequestId _megagroupSetRequestId = 0; - }; diff --git a/Telegram/SourceFiles/boxes/username_box.cpp b/Telegram/SourceFiles/boxes/username_box.cpp index 32483679f..1fe79fc5b 100644 --- a/Telegram/SourceFiles/boxes/username_box.cpp +++ b/Telegram/SourceFiles/boxes/username_box.cpp @@ -20,24 +20,23 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/username_box.h" -#include "lang/lang_keys.h" #include "application.h" +#include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" +#include "messenger.h" +#include "styles/style_boxes.h" +#include "ui/toast/toast.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" -#include "ui/toast/toast.h" -#include "styles/style_boxes.h" -#include "messenger.h" #include #include -UsernameBox::UsernameBox(QWidget*) -: _username(this, st::defaultInputField, [] { return qsl("@username"); }, App::self()->username, false) -, _link(this, QString(), st::boxLinkButton) -, _about(st::boxWidth - st::usernamePadding.left()) -, _checkTimer(this) { -} +UsernameBox::UsernameBox(QWidget *) + : _username(this, st::defaultInputField, [] { return qsl("@username"); }, App::self()->username, false) + , _link(this, QString(), st::boxLinkButton) + , _about(st::boxWidth - st::usernamePadding.left()) + , _checkTimer(this) {} void UsernameBox::prepare() { _goodText = App::self()->username.isEmpty() ? QString() : lang(lng_username_available); @@ -52,7 +51,9 @@ void UsernameBox::prepare() { connect(_link, SIGNAL(clicked()), this, SLOT(onLinkClick())); _about.setRichText(st::usernameTextStyle, lang(lng_username_about)); - setDimensions(st::boxWidth, st::usernamePadding.top() + _username->height() + st::usernameSkip + _about.countHeight(st::boxWidth - st::usernamePadding.left()) + 3 * st::usernameTextStyle.lineHeight + st::usernamePadding.bottom()); + setDimensions(st::boxWidth, st::usernamePadding.top() + _username->height() + st::usernameSkip + + _about.countHeight(st::boxWidth - st::usernamePadding.left()) + + 3 * st::usernameTextStyle.lineHeight + st::usernamePadding.bottom()); _checkTimer->setSingleShot(true); connect(_checkTimer, SIGNAL(timeout()), this, SLOT(onCheck())); @@ -72,23 +73,34 @@ void UsernameBox::paintEvent(QPaintEvent *e) { p.setFont(st::boxTextFont); if (!_errorText.isEmpty()) { p.setPen(st::boxTextFgError); - p.drawTextLeft(st::usernamePadding.left(), _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _errorText); + p.drawTextLeft(st::usernamePadding.left(), + _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), + width(), _errorText); } else if (!_goodText.isEmpty()) { p.setPen(st::boxTextFgGood); - p.drawTextLeft(st::usernamePadding.left(), _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _goodText); + p.drawTextLeft(st::usernamePadding.left(), + _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), + width(), _goodText); } else { p.setPen(st::usernameDefaultFg); - p.drawTextLeft(st::usernamePadding.left(), _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), lang(lng_username_choose)); + p.drawTextLeft(st::usernamePadding.left(), + _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), + width(), lang(lng_username_choose)); } p.setPen(st::boxTextFg); qint32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw); - _about.drawLeft(p, st::usernamePadding.left(), _username->y() + _username->height() + st::usernameSkip, availw, width()); + _about.drawLeft(p, st::usernamePadding.left(), _username->y() + _username->height() + st::usernameSkip, availw, + width()); - qint32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2); + qint32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2); if (_link->isHidden()) { p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link_willbe)); p.setPen(st::usernameDefaultFg); - p.drawTextLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), width(), Messenger::Instance().createInternalLinkFull(qsl("username"))); + p.drawTextLeft(st::usernamePadding.left(), + linky + st::usernameTextStyle.lineHeight + + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), + width(), Messenger::Instance().createInternalLinkFull(qsl("username"))); } else { p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link)); } @@ -101,15 +113,19 @@ void UsernameBox::resizeEvent(QResizeEvent *e) { _username->moveToLeft(st::usernamePadding.left(), st::usernamePadding.top()); qint32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw); - qint32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2); - _link->moveToLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2)); + qint32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2); + _link->moveToLeft(st::usernamePadding.left(), + linky + st::usernameTextStyle.lineHeight + + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2)); } void UsernameBox::onSave() { if (_saveRequestId) return; _sentUsername = getName(); - _saveRequestId = MTP::send(MTPaccount_UpdateUsername(MTP_string(_sentUsername)), rpcDone(&UsernameBox::onUpdateDone), rpcFail(&UsernameBox::onUpdateFail)); + _saveRequestId = MTP::send(MTPaccount_UpdateUsername(MTP_string(_sentUsername)), + rpcDone(&UsernameBox::onUpdateDone), rpcFail(&UsernameBox::onUpdateFail)); } void UsernameBox::onCheck() { @@ -119,7 +135,8 @@ void UsernameBox::onCheck() { QString name = getName(); if (name.size() >= MinUsernameLength) { _checkUsername = name; - _checkRequestId = MTP::send(MTPaccount_CheckUsername(MTP_string(name)), rpcDone(&UsernameBox::onCheckDone), rpcFail(&UsernameBox::onCheckFail)); + _checkRequestId = MTP::send(MTPaccount_CheckUsername(MTP_string(name)), rpcDone(&UsernameBox::onCheckDone), + rpcFail(&UsernameBox::onCheckFail)); } } @@ -136,7 +153,8 @@ void UsernameBox::onChanged() { qint32 len = name.size(); for (qint32 i = 0; i < len; ++i) { QChar ch = name.at(i); - if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_' && (ch != '@' || i > 0)) { + if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_' && + (ch != '@' || i > 0)) { if (_errorText != lang(lng_username_bad_symbols)) { _errorText = lang(lng_username_bad_symbols); update(); @@ -177,7 +195,9 @@ bool UsernameBox::onUpdateFail(const RPCError &error) { _saveRequestId = 0; QString err(error.type()); if (err == qstr("USERNAME_NOT_MODIFIED") || _sentUsername == App::self()->username) { - App::self()->setName(TextUtilities::SingleLine(App::self()->firstName), TextUtilities::SingleLine(App::self()->lastName), TextUtilities::SingleLine(App::self()->nameOrPhone), TextUtilities::SingleLine(_sentUsername)); + App::self()->setName( + TextUtilities::SingleLine(App::self()->firstName), TextUtilities::SingleLine(App::self()->lastName), + TextUtilities::SingleLine(App::self()->nameOrPhone), TextUtilities::SingleLine(_sentUsername)); closeBox(); return true; } else if (err == qstr("USERNAME_INVALID")) { @@ -199,7 +219,8 @@ bool UsernameBox::onUpdateFail(const RPCError &error) { void UsernameBox::onCheckDone(const MTPBool &result) { _checkRequestId = 0; - QString newError = (mtpIsTrue(result) || _checkUsername == App::self()->username) ? QString() : lang(lng_username_occupied); + QString newError = + (mtpIsTrue(result) || _checkUsername == App::self()->username) ? QString() : lang(lng_username_occupied); QString newGood = newError.isEmpty() ? lang(lng_username_available) : QString(); if (_errorText != newError || _goodText != newGood) { _errorText = newError; @@ -233,7 +254,8 @@ QString UsernameBox::getName() const { void UsernameBox::updateLinkText() { QString uname = getName(); - _link->setText(st::boxTextFont->elided(Messenger::Instance().createInternalLinkFull(uname), st::boxWidth - st::usernamePadding.left() - st::usernamePadding.right())); + _link->setText(st::boxTextFont->elided(Messenger::Instance().createInternalLinkFull(uname), + st::boxWidth - st::usernamePadding.left() - st::usernamePadding.right())); if (uname.isEmpty()) { if (!_link->isHidden()) { _link->hide(); diff --git a/Telegram/SourceFiles/boxes/username_box.h b/Telegram/SourceFiles/boxes/username_box.h index 7eab1bb2d..4239b2d98 100644 --- a/Telegram/SourceFiles/boxes/username_box.h +++ b/Telegram/SourceFiles/boxes/username_box.h @@ -31,7 +31,7 @@ class UsernameBox : public BoxContent, public RPCSender { Q_OBJECT public: - UsernameBox(QWidget*); + UsernameBox(QWidget *); protected: void prepare() override; @@ -67,5 +67,4 @@ private: Text _about; object_ptr _checkTimer; - }; diff --git a/Telegram/SourceFiles/calls/calls_box_controller.cpp b/Telegram/SourceFiles/calls/calls_box_controller.cpp index e1d2c6174..34d272ad7 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.cpp +++ b/Telegram/SourceFiles/calls/calls_box_controller.cpp @@ -20,14 +20,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "calls/calls_box_controller.h" -#include "styles/style_calls.h" -#include "styles/style_boxes.h" -#include "lang/lang_keys.h" -#include "observer_peer.h" -#include "ui/effects/ripple_animation.h" +#include "app.h" #include "calls/calls_instance.h" #include "history/history_media_types.h" -#include "app.h" +#include "lang/lang_keys.h" +#include "observer_peer.h" +#include "styles/style_boxes.h" +#include "styles/style_calls.h" +#include "ui/effects/ripple_animation.h" namespace Calls { namespace { @@ -53,9 +53,7 @@ public: void addItem(HistoryItem *item) { Expects(canAddItem(item)); _items.push_back(item); - std::sort(_items.begin(), _items.end(), [](HistoryItem *a, HistoryItem *b) { - return (a->id > b->id); - }); + std::sort(_items.begin(), _items.end(), [](HistoryItem *a, HistoryItem *b) { return (a->id > b->id); }); refreshStatus(); } void itemRemoved(HistoryItem *item) { @@ -97,18 +95,18 @@ private: void refreshStatus(); static Type ComputeType(HistoryItem *item); - std::vector _items; + std::vector _items; QDate _date; Type _type; std::unique_ptr _actionRipple; - }; -BoxController::Row::Row(HistoryItem *item) : PeerListRow(item->history()->peer, item->id) -, _items(1, item) -, _date(item->date.date()) -, _type(ComputeType(item)) { +BoxController::Row::Row(HistoryItem *item) + : PeerListRow(item->history()->peer, item->id) + , _items(1, item) + , _date(item->date.date()) + , _type(ComputeType(item)) { refreshStatus(); } @@ -132,7 +130,8 @@ void BoxController::Row::paintStatusText(Painter &p, int x, int y, int available void BoxController::Row::paintAction(Painter &p, TimeMs ms, int x, int y, int outerWidth, bool actionSelected) { auto size = actionSize(); if (_actionRipple) { - _actionRipple->paint(p, x + st::callReDial.rippleAreaPosition.x(), y + st::callReDial.rippleAreaPosition.y(), outerWidth, ms); + _actionRipple->paint(p, x + st::callReDial.rippleAreaPosition.x(), y + st::callReDial.rippleAreaPosition.y(), + outerWidth, ms); if (_actionRipple->empty()) { _actionRipple.reset(); } @@ -154,7 +153,9 @@ void BoxController::Row::refreshStatus() { } return lng_call_box_status_date(lt_date, langDayOfMonthFull(_date), lt_time, time); }; - setCustomStatus((_items.size() > 1) ? lng_call_box_status_group(lt_count, QString::number(_items.size()), lt_status, text()) : text()); + setCustomStatus((_items.size() > 1) ? + lng_call_box_status_group(lt_count, QString::number(_items.size()), lt_status, text()) : + text()); } BoxController::Row::Type BoxController::Row::ComputeType(HistoryItem *item) { @@ -162,7 +163,7 @@ BoxController::Row::Type BoxController::Row::ComputeType(HistoryItem *item) { return Type::Out; } else if (auto media = item->getMedia()) { if (media->type() == MediaTypeCall) { - auto reason = static_cast(media)->reason(); + auto reason = static_cast(media)->reason(); if (reason == HistoryCall::FinishReason::Busy || reason == HistoryCall::FinishReason::Missed) { return Type::Missed; } @@ -173,8 +174,10 @@ BoxController::Row::Type BoxController::Row::ComputeType(HistoryItem *item) { void BoxController::Row::addActionRipple(QPoint point, base::lambda updateCallback) { if (!_actionRipple) { - auto mask = Ui::RippleAnimation::ellipseMask(QSize(st::callReDial.rippleAreaSize, st::callReDial.rippleAreaSize)); - _actionRipple = std::make_unique(st::callReDial.ripple, std::move(mask), std::move(updateCallback)); + auto mask = + Ui::RippleAnimation::ellipseMask(QSize(st::callReDial.rippleAreaSize, st::callReDial.rippleAreaSize)); + _actionRipple = + std::make_unique(st::callReDial.ripple, std::move(mask), std::move(updateCallback)); } _actionRipple->add(point - st::callReDial.rippleAreaPosition); } @@ -216,41 +219,49 @@ void BoxController::loadMoreRows() { return; } - _loadRequestId = request(MTPmessages_Search(MTP_flags(0), MTP_inputPeerEmpty(), MTP_string(QString()), MTP_inputUserEmpty(), MTP_inputMessagesFilterPhoneCalls(MTP_flags(0)), MTP_int(0), MTP_int(0), MTP_int(_offsetId), MTP_int(0), MTP_int(_offsetId ? kFirstPageCount : kPerPageCount), MTP_int(0), MTP_int(0))).done([this](const MTPmessages_Messages &result) { - _loadRequestId = 0; + _loadRequestId = + request(MTPmessages_Search(MTP_flags(0), MTP_inputPeerEmpty(), MTP_string(QString()), MTP_inputUserEmpty(), + MTP_inputMessagesFilterPhoneCalls(MTP_flags(0)), MTP_int(0), MTP_int(0), + MTP_int(_offsetId), MTP_int(0), MTP_int(_offsetId ? kFirstPageCount : kPerPageCount), + MTP_int(0), MTP_int(0))) + .done([this](const MTPmessages_Messages &result) { + _loadRequestId = 0; - auto handleResult = [this](auto &data) { - App::feedUsers(data.vusers); - App::feedChats(data.vchats); - receivedCalls(data.vmessages.v); - }; + auto handleResult = [this](auto &data) { + App::feedUsers(data.vusers); + App::feedChats(data.vchats); + receivedCalls(data.vmessages.v); + }; - switch (result.type()) { - case mtpc_messages_messages: handleResult(result.c_messages_messages()); _allLoaded = true; break; - case mtpc_messages_messagesSlice: handleResult(result.c_messages_messagesSlice()); break; - case mtpc_messages_channelMessages: { - LOG(("API Error: received messages.channelMessages! (Calls::BoxController::preloadRows)")); - handleResult(result.c_messages_channelMessages()); - } break; + switch (result.type()) { + case mtpc_messages_messages: + handleResult(result.c_messages_messages()); + _allLoaded = true; + break; + case mtpc_messages_messagesSlice: handleResult(result.c_messages_messagesSlice()); break; + case mtpc_messages_channelMessages: { + LOG(("API Error: received messages.channelMessages! (Calls::BoxController::preloadRows)")); + handleResult(result.c_messages_channelMessages()); + } break; - default: Unexpected("Type of messages.Messages (Calls::BoxController::preloadRows)"); - } - }).fail([this](const RPCError &error) { - _loadRequestId = 0; - }).send(); + default: Unexpected("Type of messages.Messages (Calls::BoxController::preloadRows)"); + } + }) + .fail([this](const RPCError &error) { _loadRequestId = 0; }) + .send(); } void BoxController::refreshAbout() { setDescriptionText(delegate()->peerListFullRowsCount() ? QString() : lang(lng_call_box_about)); } -void BoxController::rowClicked(not_null row) { - auto itemsRow = static_cast(row.get()); +void BoxController::rowClicked(not_null row) { + auto itemsRow = static_cast(row.get()); auto itemId = itemsRow->maxItemId(); Ui::showPeerHistoryAsync(row->peer()->id, itemId); } -void BoxController::rowActionClicked(not_null row) { +void BoxController::rowActionClicked(not_null row) { auto user = row->peer()->asUser(); Assert(user != nullptr); @@ -285,9 +296,10 @@ bool BoxController::insertRow(HistoryItem *item, InsertWay way) { return false; } } - (way == InsertWay::Append) ? delegate()->peerListAppendRow(createRow(item)) : delegate()->peerListPrependRow(createRow(item)); + (way == InsertWay::Append) ? delegate()->peerListAppendRow(createRow(item)) : + delegate()->peerListPrependRow(createRow(item)); delegate()->peerListSortRows([](PeerListRow &a, PeerListRow &b) { - return static_cast(a).maxItemId() > static_cast(b).maxItemId(); + return static_cast(a).maxItemId() > static_cast(b).maxItemId(); }); return true; } @@ -296,11 +308,11 @@ BoxController::Row *BoxController::rowForItem(HistoryItem *item) { auto v = delegate(); if (auto fullRowsCount = v->peerListFullRowsCount()) { auto itemId = item->id; - auto lastRow = static_cast(v->peerListRowAt(fullRowsCount - 1).get()); + auto lastRow = static_cast(v->peerListRowAt(fullRowsCount - 1).get()); if (itemId < lastRow->minItemId()) { return lastRow; } - auto firstRow = static_cast(v->peerListRowAt(0).get()); + auto firstRow = static_cast(v->peerListRowAt(0).get()); if (itemId > firstRow->maxItemId()) { return firstRow; } @@ -312,18 +324,18 @@ BoxController::Row *BoxController::rowForItem(HistoryItem *item) { auto right = fullRowsCount; while (left + 1 < right) { auto middle = (right + left) / 2; - auto middleRow = static_cast(v->peerListRowAt(middle).get()); + auto middleRow = static_cast(v->peerListRowAt(middle).get()); if (middleRow->maxItemId() >= itemId) { left = middle; } else { right = middle; } } - auto result = static_cast(v->peerListRowAt(left).get()); + auto result = static_cast(v->peerListRowAt(left).get()); // Check for rowAt(left)->minItemId > itemId > rowAt(left + 1)->maxItemId. // In that case we sometimes need to return rowAt(left + 1), not rowAt(left). if (result->minItemId() > itemId && left + 1 < fullRowsCount) { - auto possibleResult = static_cast(v->peerListRowAt(left + 1).get()); + auto possibleResult = static_cast(v->peerListRowAt(left + 1).get()); Assert(possibleResult->maxItemId() < itemId); if (possibleResult->canAddItem(item)) { return possibleResult; diff --git a/Telegram/SourceFiles/calls/calls_box_controller.h b/Telegram/SourceFiles/calls/calls_box_controller.h index cbaf79d9d..5ab79b9d7 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.h +++ b/Telegram/SourceFiles/calls/calls_box_controller.h @@ -27,8 +27,8 @@ namespace Calls { class BoxController : public PeerListController, private base::Subscriber, private MTP::Sender { public: void prepare() override; - void rowClicked(not_null row) override; - void rowActionClicked(not_null row) override; + void rowClicked(not_null row) override; + void rowActionClicked(not_null row) override; void loadMoreRows() override; private: @@ -48,7 +48,6 @@ private: MsgId _offsetId = 0; mtpRequestId _loadRequestId = 0; bool _allLoaded = false; - }; } // namespace Calls diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index 4738c3f3e..90a1cfb04 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -19,18 +19,18 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include "core/utils.h" #include "calls/calls_call.h" #include "auth_session.h" -#include "mainwidget.h" -#include "lang/lang_keys.h" +#include "base/openssl_help.h" #include "boxes/confirm_box.h" #include "boxes/rate_call_box.h" #include "calls/calls_instance.h" -#include "base/openssl_help.h" -#include "mtproto/connection.h" -#include "media/media_audio_track.h" #include "calls/calls_panel.h" +#include "core/utils.h" +#include "lang/lang_keys.h" +#include "mainwidget.h" +#include "media/media_audio_track.h" +#include "mtproto/connection.h" #ifdef slots #undef slots @@ -60,28 +60,25 @@ void ConvertEndpoint(std::vector &ep, const MTPDphoneConnectio } auto ipv4 = tgvoip::IPv4Address(std::string(mtc.vip.v.constData(), mtc.vip.v.size())); auto ipv6 = tgvoip::IPv6Address(std::string(mtc.vipv6.v.constData(), mtc.vipv6.v.size())); - ep.push_back(Endpoint((int64_t)mtc.vid.v, (uint16_t)mtc.vport.v, ipv4, ipv6, EP_TYPE_UDP_RELAY, (unsigned char*)mtc.vpeer_tag.v.data())); + ep.push_back(Endpoint((int64_t)mtc.vid.v, (uint16_t)mtc.vport.v, ipv4, ipv6, EP_TYPE_UDP_RELAY, + (unsigned char *)mtc.vpeer_tag.v.data())); } constexpr auto kFingerprintDataSize = 256; quint64 ComputeFingerprint(const std::array &authKey) { auto hash = openssl::Sha1(authKey); - return (gsl::to_integer(hash[19]) << 56) - | (gsl::to_integer(hash[18]) << 48) - | (gsl::to_integer(hash[17]) << 40) - | (gsl::to_integer(hash[16]) << 32) - | (gsl::to_integer(hash[15]) << 24) - | (gsl::to_integer(hash[14]) << 16) - | (gsl::to_integer(hash[13]) << 8) - | (gsl::to_integer(hash[12])); + return (gsl::to_integer(hash[19]) << 56) | (gsl::to_integer(hash[18]) << 48) | + (gsl::to_integer(hash[17]) << 40) | (gsl::to_integer(hash[16]) << 32) | + (gsl::to_integer(hash[15]) << 24) | (gsl::to_integer(hash[14]) << 16) | + (gsl::to_integer(hash[13]) << 8) | (gsl::to_integer(hash[12])); } } // namespace -Call::Call(not_null delegate, not_null user, Type type) -: _delegate(delegate) -, _user(user) -, _type(type) { +Call::Call(not_null delegate, not_null user, Type type) + : _delegate(delegate) + , _user(user) + , _type(type) { _discardByTimeoutTimer.setCallback([this] { hangup(); }); if (_type == Type::Outgoing) { @@ -138,50 +135,55 @@ void Call::startOutgoing() { Expects(_type == Type::Outgoing); Expects(_state == State::Requesting); - request(MTPphone_RequestCall(_user->inputUser, MTP_int(rand_value()), MTP_bytes(_gaHash), MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | MTPDphoneCallProtocol::Flag::f_udp_reflector), MTP_int(kMinLayer), MTP_int(kMaxLayer)))).done([this](const MTPphone_PhoneCall &result) { - Expects(result.type() == mtpc_phone_phoneCall); + request(MTPphone_RequestCall(_user->inputUser, MTP_int(rand_value()), MTP_bytes(_gaHash), + MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | + MTPDphoneCallProtocol::Flag::f_udp_reflector), + MTP_int(kMinLayer), MTP_int(kMaxLayer)))) + .done([this](const MTPphone_PhoneCall &result) { + Expects(result.type() == mtpc_phone_phoneCall); - setState(State::Waiting); + setState(State::Waiting); - auto &call = result.c_phone_phoneCall(); - App::feedUsers(call.vusers); - if (call.vphone_call.type() != mtpc_phoneCallWaiting) { - LOG(("Call Error: Expected phoneCallWaiting in response to phone.requestCall()")); - finish(FinishType::Failed); - return; - } + auto &call = result.c_phone_phoneCall(); + App::feedUsers(call.vusers); + if (call.vphone_call.type() != mtpc_phoneCallWaiting) { + LOG(("Call Error: Expected phoneCallWaiting in response to phone.requestCall()")); + finish(FinishType::Failed); + return; + } - auto &phoneCall = call.vphone_call; - auto &waitingCall = phoneCall.c_phoneCallWaiting(); - _id = waitingCall.vid.v; - _accessHash = waitingCall.vaccess_hash.v; - if (_finishAfterRequestingCall != FinishType::None) { - if (_finishAfterRequestingCall == FinishType::Failed) { - finish(_finishAfterRequestingCall); - } else { - hangup(); - } - return; - } + auto &phoneCall = call.vphone_call; + auto &waitingCall = phoneCall.c_phoneCallWaiting(); + _id = waitingCall.vid.v; + _accessHash = waitingCall.vaccess_hash.v; + if (_finishAfterRequestingCall != FinishType::None) { + if (_finishAfterRequestingCall == FinishType::Failed) { + finish(_finishAfterRequestingCall); + } else { + hangup(); + } + return; + } - _discardByTimeoutTimer.callOnce(Global::CallReceiveTimeoutMs()); - handleUpdate(phoneCall); - }).fail([this](const RPCError &error) { - handleRequestError(error); - }).send(); + _discardByTimeoutTimer.callOnce(Global::CallReceiveTimeoutMs()); + handleUpdate(phoneCall); + }) + .fail([this](const RPCError &error) { handleRequestError(error); }) + .send(); } void Call::startIncoming() { Expects(_type == Type::Incoming); Expects(_state == State::Starting); - request(MTPphone_ReceivedCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)))).done([this](const MTPBool &result) { - if (_state == State::Starting) { - setState(State::WaitingIncoming); - } - }).fail([this](const RPCError &error) { - handleRequestError(error); - }).send(); + request(MTPphone_ReceivedCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)))) + .done([this](const MTPBool &result) { + if (_state == State::Starting) { + setState(State::WaitingIncoming); + } + }) + .fail([this](const RPCError &error) { handleRequestError(error); }) + .send(); } void Call::answer() { @@ -199,20 +201,21 @@ void Call::answer() { } else { _answerAfterDhConfigReceived = false; } - request(MTPphone_AcceptCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_bytes(_gb), _protocol)).done([this](const MTPphone_PhoneCall &result) { - Expects(result.type() == mtpc_phone_phoneCall); - auto &call = result.c_phone_phoneCall(); - App::feedUsers(call.vusers); - if (call.vphone_call.type() != mtpc_phoneCallWaiting) { - LOG(("Call Error: Expected phoneCallWaiting in response to phone.acceptCall()")); - finish(FinishType::Failed); - return; - } + request(MTPphone_AcceptCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_bytes(_gb), _protocol)) + .done([this](const MTPphone_PhoneCall &result) { + Expects(result.type() == mtpc_phone_phoneCall); + auto &call = result.c_phone_phoneCall(); + App::feedUsers(call.vusers); + if (call.vphone_call.type() != mtpc_phoneCallWaiting) { + LOG(("Call Error: Expected phoneCallWaiting in response to phone.acceptCall()")); + finish(FinishType::Failed); + return; + } - handleUpdate(call.vphone_call); - }).fail([this](const RPCError &error) { - handleRequestError(error); - }).send(); + handleUpdate(call.vphone_call); + }) + .fail([this](const RPCError &error) { handleRequestError(error); }) + .send(); } void Call::setMute(bool mute) { @@ -234,7 +237,7 @@ void Call::hangup() { auto missed = (_state == State::Ringing || (_state == State::Waiting && _type == Type::Outgoing)); auto declined = isIncomingWaiting(); auto reason = missed ? MTP_phoneCallDiscardReasonMissed() : - declined ? MTP_phoneCallDiscardReasonBusy() : MTP_phoneCallDiscardReasonHangup(); + declined ? MTP_phoneCallDiscardReasonBusy() : MTP_phoneCallDiscardReasonHangup(); finish(FinishType::Ended, reason); } } @@ -253,16 +256,17 @@ void Call::redial() { QString Call::getDebugLog() const { constexpr auto kDebugLimit = 4096; - auto bytes = base::byte_vector(kDebugLimit, gsl::byte {}); - _controller->GetDebugString(reinterpret_cast(bytes.data()), bytes.size()); - auto end = std::find(bytes.begin(), bytes.end(), gsl::byte {}); + auto bytes = base::byte_vector(kDebugLimit, gsl::byte{}); + _controller->GetDebugString(reinterpret_cast(bytes.data()), bytes.size()); + auto end = std::find(bytes.begin(), bytes.end(), gsl::byte{}); auto size = (end - bytes.begin()); - return QString::fromUtf8(reinterpret_cast(bytes.data()), size); + return QString::fromUtf8(reinterpret_cast(bytes.data()), size); } void Call::startWaitingTrack() { _waitingTrack = Media::Audio::Current().createTrack(); - auto trackFileName = Auth().data().getSoundPath((_type == Type::Outgoing) ? qsl("call_outgoing") : qsl("call_incoming")); + auto trackFileName = + Auth().data().getSoundPath((_type == Type::Outgoing) ? qsl("call_outgoing") : qsl("call_incoming")); _waitingTrack->samplePeakEach(kSoundSampleMs); _waitingTrack->fillFromFile(trackFileName); _waitingTrack->playInLoop(); @@ -283,7 +287,7 @@ bool Call::isKeyShaForFingerprintReady() const { base::byte_array Call::getKeyShaForFingerprint() const { Expects(isKeyShaForFingerprintReady()); Expects(!_ga.empty()); - auto encryptedChatAuthKey = base::byte_vector(_authKey.size() + _ga.size(), gsl::byte {}); + auto encryptedChatAuthKey = base::byte_vector(_authKey.size() + _ga.size(), gsl::byte{}); base::copy_bytes(gsl::make_span(encryptedChatAuthKey).subspan(0, _authKey.size()), _authKey); base::copy_bytes(gsl::make_span(encryptedChatAuthKey).subspan(_authKey.size(), _ga.size()), _ga); return openssl::Sha256(encryptedChatAuthKey); @@ -293,13 +297,13 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { switch (call.type()) { case mtpc_phoneCallRequested: { auto &data = call.c_phoneCallRequested(); - if (_type != Type::Incoming - || _id != 0 - || peerToUser(_user->id) != data.vadmin_id.v) { + if (_type != Type::Incoming || _id != 0 || peerToUser(_user->id) != data.vadmin_id.v) { Unexpected("phoneCallRequested call inside an existing call handleUpdate()"); } if (Auth().userId() != data.vparticipant_id.v) { - LOG(("Call Error: Wrong call participant_id %1, expected %2.").arg(data.vparticipant_id.v).arg(Auth().userId())); + LOG(("Call Error: Wrong call participant_id %1, expected %2.") + .arg(data.vparticipant_id.v) + .arg(Auth().userId())); finish(FinishType::Failed); return true; } @@ -313,7 +317,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { return true; } base::copy_bytes(gsl::make_span(_gaHash), gaHashBytes); - } return true; + } + return true; case mtpc_phoneCallEmpty: { auto &data = call.c_phoneCallEmpty(); @@ -322,7 +327,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { } LOG(("Call Error: phoneCallEmpty received.")); finish(FinishType::Failed); - } return true; + } + return true; case mtpc_phoneCallWaiting: { auto &data = call.c_phoneCallWaiting(); @@ -334,7 +340,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { setState(State::Ringing); startWaitingTrack(); } - } return true; + } + return true; case mtpc_phoneCall: { auto &data = call.c_phoneCall(); @@ -344,7 +351,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { if (_type == Type::Incoming && _state == State::ExchangingKeys) { startConfirmedCall(data); } - } return true; + } + return true; case mtpc_phoneCallDiscarded: { auto &data = call.c_phoneCallDiscarded(); @@ -354,7 +362,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { if (data.is_need_debug()) { auto debugLog = _controller ? _controller->GetDebugLog() : std::string(); if (!debugLog.empty()) { - MTP::send(MTPphone_SaveCallDebug(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_dataJSON(MTP_string(debugLog)))); + MTP::send(MTPphone_SaveCallDebug(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), + MTP_dataJSON(MTP_string(debugLog)))); } } if (data.is_need_rating() && _id && _accessHash) { @@ -370,7 +379,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { } else { setState(State::EndedByOtherDevice); } - } return true; + } + return true; case mtpc_phoneCallAccepted: { auto &data = call.c_phoneCallAccepted(); @@ -383,7 +393,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { } else if (checkCallFields(data)) { confirmAcceptedCall(data); } - } return true; + } + return true; } Unexpected("phoneCall type inside an existing call handleUpdate()"); @@ -404,20 +415,25 @@ void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) { _keyFingerprint = ComputeFingerprint(_authKey); setState(State::ExchangingKeys); - request(MTPphone_ConfirmCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_bytes(_ga), MTP_long(_keyFingerprint), MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | MTPDphoneCallProtocol::Flag::f_udp_reflector), MTP_int(kMinLayer), MTP_int(kMaxLayer)))).done([this](const MTPphone_PhoneCall &result) { - Expects(result.type() == mtpc_phone_phoneCall); - auto &call = result.c_phone_phoneCall(); - App::feedUsers(call.vusers); - if (call.vphone_call.type() != mtpc_phoneCall) { - LOG(("Call Error: Expected phoneCall in response to phone.confirmCall()")); - finish(FinishType::Failed); - return; - } + request(MTPphone_ConfirmCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_bytes(_ga), + MTP_long(_keyFingerprint), + MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | + MTPDphoneCallProtocol::Flag::f_udp_reflector), + MTP_int(kMinLayer), MTP_int(kMaxLayer)))) + .done([this](const MTPphone_PhoneCall &result) { + Expects(result.type() == mtpc_phone_phoneCall); + auto &call = result.c_phone_phoneCall(); + App::feedUsers(call.vusers); + if (call.vphone_call.type() != mtpc_phoneCall) { + LOG(("Call Error: Expected phoneCall in response to phone.confirmCall()")); + finish(FinishType::Failed); + return; + } - createAndStartController(call.vphone_call.c_phoneCall()); - }).fail([this](const RPCError &error) { - handleRequestError(error); - }).send(); + createAndStartController(call.vphone_call.c_phoneCall()); + }) + .fail([this](const RPCError &error) { handleRequestError(error); }) + .send(); } void Call::startConfirmedCall(const MTPDphoneCall &call) { @@ -450,7 +466,7 @@ void Call::createAndStartController(const MTPDphoneCall &call) { return; } - voip_config_t config = { 0 }; + voip_config_t config = {0}; config.data_saving = DATA_SAVING_NEVER; config.enableAEC = true; config.enableNS = true; @@ -480,12 +496,12 @@ void Call::createAndStartController(const MTPDphoneCall &call) { if (_mute) { _controller->SetMicMute(_mute); } - _controller->implData = static_cast(this); + _controller->implData = static_cast(this); _controller->SetRemoteEndpoints(endpoints, true); _controller->SetConfig(&config); - _controller->SetEncryptionKey(reinterpret_cast(_authKey.data()), (_type == Type::Outgoing)); + _controller->SetEncryptionKey(reinterpret_cast(_authKey.data()), (_type == Type::Outgoing)); _controller->SetStateCallback([](tgvoip::VoIPController *controller, int state) { - static_cast(controller->implData)->handleControllerStateChange(controller, state); + static_cast(controller->implData)->handleControllerStateChange(controller, state); }); _controller->Start(); _controller->Connect(); @@ -494,7 +510,7 @@ void Call::createAndStartController(const MTPDphoneCall &call) { void Call::handleControllerStateChange(tgvoip::VoIPController *controller, int state) { // NB! Can be called from an arbitrary thread! // Expects(controller == _controller.get()); This can be called from ~VoIPController()! - Expects(controller->implData == static_cast(this)); + Expects(controller->implData == static_cast(this)); switch (state) { case STATE_WAIT_INIT: { @@ -522,8 +538,7 @@ void Call::handleControllerStateChange(tgvoip::VoIPController *controller, int s } } -template -bool Call::checkCallCommonFields(const T &call) { +template bool Call::checkCallCommonFields(const T &call) { auto checkFailed = [this] { finish(FinishType::Failed); return false; @@ -572,43 +587,28 @@ void Call::setState(State state) { _state = state; _stateChanged.notify(state, true); - if (true - && _state != State::Starting - && _state != State::Requesting - && _state != State::Waiting - && _state != State::WaitingIncoming - && _state != State::Ringing) { + if (true && _state != State::Starting && _state != State::Requesting && _state != State::Waiting && + _state != State::WaitingIncoming && _state != State::Ringing) { _waitingTrack.reset(); } - if (false - || _state == State::Ended - || _state == State::EndedByOtherDevice - || _state == State::Failed - || _state == State::Busy) { + if (false || _state == State::Ended || _state == State::EndedByOtherDevice || _state == State::Failed || + _state == State::Busy) { // Destroy controller before destroying Call Panel, // so that the panel hide animation is smooth. destroyController(); } switch (_state) { - case State::Established: - _startTime = getms(true); - break; - case State::ExchangingKeys: - _delegate->playSound(Delegate::Sound::Connecting); - break; + case State::Established: _startTime = getms(true); break; + case State::ExchangingKeys: _delegate->playSound(Delegate::Sound::Connecting); break; case State::Ended: _delegate->playSound(Delegate::Sound::Ended); // [[fallthrough]] - case State::EndedByOtherDevice: - _delegate->callFinished(this); - break; + case State::EndedByOtherDevice: _delegate->callFinished(this); break; case State::Failed: _delegate->playSound(Delegate::Sound::Ended); _delegate->callFailed(this); break; - case State::Busy: - _delegate->playSound(Delegate::Sound::Busy); - break; + case State::Busy: _delegate->playSound(Delegate::Sound::Busy); break; } } } @@ -622,11 +622,8 @@ void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) { _finishAfterRequestingCall = type; return; } - if (_state == State::HangingUp - || _state == State::FailedHangingUp - || _state == State::EndedByOtherDevice - || _state == State::Ended - || _state == State::Failed) { + if (_state == State::HangingUp || _state == State::FailedHangingUp || _state == State::EndedByOtherDevice || + _state == State::Ended || _state == State::Failed) { return; } if (!_id) { @@ -638,14 +635,16 @@ void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) { auto duration = getDurationMs() / 1000; auto connectionId = _controller ? _controller->GetPreferredRelayID() : 0; _finishByTimeoutTimer.call(kHangupTimeoutMs, [this, finalState] { setState(finalState); }); - request(MTPphone_DiscardCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_int(duration), reason, MTP_long(connectionId))).done([this, finalState](const MTPUpdates &result) { - // This could be destroyed by updates, so we set Ended after - // updates being handled, but in a guarded way. - InvokeQueued(this, [this, finalState] { setState(finalState); }); - App::main()->sentUpdatesReceived(result); - }).fail([this, finalState](const RPCError &error) { - setState(finalState); - }).send(); + request(MTPphone_DiscardCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_int(duration), reason, + MTP_long(connectionId))) + .done([this, finalState](const MTPUpdates &result) { + // This could be destroyed by updates, so we set Ended after + // updates being handled, but in a guarded way. + InvokeQueued(this, [this, finalState] { setState(finalState); }); + App::main()->sentUpdatesReceived(result); + }) + .fail([this, finalState](const RPCError &error) { setState(finalState); }) + .send(); } void Call::setStateQueued(State state) { diff --git a/Telegram/SourceFiles/calls/calls_call.h b/Telegram/SourceFiles/calls/calls_call.h index 8dc8f49f2..e05837884 100644 --- a/Telegram/SourceFiles/calls/calls_call.h +++ b/Telegram/SourceFiles/calls/calls_call.h @@ -20,10 +20,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include "base/weak_unique_ptr.h" #include "base/timer.h" -#include "mtproto/sender.h" +#include "base/weak_unique_ptr.h" #include "mtproto/auth_key.h" +#include "mtproto/sender.h" namespace Media { namespace Audio { @@ -48,9 +48,9 @@ public: class Delegate { public: virtual DhConfig getDhConfig() const = 0; - virtual void callFinished(not_null call) = 0; - virtual void callFailed(not_null call) = 0; - virtual void callRedial(not_null call) = 0; + virtual void callFinished(not_null call) = 0; + virtual void callFailed(not_null call) = 0; + virtual void callRedial(not_null call) = 0; enum class Sound { Connecting, @@ -58,7 +58,6 @@ public: Ended, }; virtual void playSound(Sound sound) = 0; - }; static constexpr auto kRandomPowerSize = 256; @@ -69,12 +68,12 @@ public: Incoming, Outgoing, }; - Call(not_null delegate, not_null user, Type type); + Call(not_null delegate, not_null user, Type type); Type type() const { return _type; } - not_null user() const { + not_null user() const { return _user; } bool isIncomingWaiting() const; @@ -145,8 +144,7 @@ private: void handleControllerStateChange(tgvoip::VoIPController *controller, int state); void createAndStartController(const MTPDphoneCall &call); - template - bool checkCallCommonFields(const T &call); + template bool checkCallCommonFields(const T &call); bool checkCallFields(const MTPDphoneCall &call); bool checkCallFields(const MTPDphoneCallAccepted &call); @@ -157,8 +155,8 @@ private: void setFailedQueued(int error); void destroyController(); - not_null _delegate; - not_null _user; + not_null _delegate; + not_null _user; Type _type = Type::Outgoing; State _state = State::Starting; FinishType _finishAfterRequestingCall = FinishType::None; @@ -186,7 +184,6 @@ private: std::unique_ptr _controller; std::unique_ptr _waitingTrack; - }; void UpdateConfig(const std::map &data); diff --git a/Telegram/SourceFiles/calls/calls_emoji_fingerprint.cpp b/Telegram/SourceFiles/calls/calls_emoji_fingerprint.cpp index ac0871771..adecae91c 100644 --- a/Telegram/SourceFiles/calls/calls_emoji_fingerprint.cpp +++ b/Telegram/SourceFiles/calls/calls_emoji_fingerprint.cpp @@ -26,102 +26,77 @@ namespace Calls { namespace { ushort Data[] = { -0xd83d, 0xde09, 0xd83d, 0xde0d, 0xd83d, 0xde1b, 0xd83d, 0xde2d, 0xd83d, 0xde31, 0xd83d, 0xde21, -0xd83d, 0xde0e, 0xd83d, 0xde34, 0xd83d, 0xde35, 0xd83d, 0xde08, 0xd83d, 0xde2c, 0xd83d, 0xde07, -0xd83d, 0xde0f, 0xd83d, 0xdc6e, 0xd83d, 0xdc77, 0xd83d, 0xdc82, 0xd83d, 0xdc76, 0xd83d, 0xdc68, -0xd83d, 0xdc69, 0xd83d, 0xdc74, 0xd83d, 0xdc75, 0xd83d, 0xde3b, 0xd83d, 0xde3d, 0xd83d, 0xde40, -0xd83d, 0xdc7a, 0xd83d, 0xde48, 0xd83d, 0xde49, 0xd83d, 0xde4a, 0xd83d, 0xdc80, 0xd83d, 0xdc7d, -0xd83d, 0xdca9, 0xd83d, 0xdd25, 0xd83d, 0xdca5, 0xd83d, 0xdca4, 0xd83d, 0xdc42, 0xd83d, 0xdc40, -0xd83d, 0xdc43, 0xd83d, 0xdc45, 0xd83d, 0xdc44, 0xd83d, 0xdc4d, 0xd83d, 0xdc4e, 0xd83d, 0xdc4c, -0xd83d, 0xdc4a, 0x270c, 0x270b, 0xd83d, 0xdc50, 0xd83d, 0xdc46, 0xd83d, 0xdc47, 0xd83d, 0xdc49, -0xd83d, 0xdc48, 0xd83d, 0xde4f, 0xd83d, 0xdc4f, 0xd83d, 0xdcaa, 0xd83d, 0xdeb6, 0xd83c, 0xdfc3, -0xd83d, 0xdc83, 0xd83d, 0xdc6b, 0xd83d, 0xdc6a, 0xd83d, 0xdc6c, 0xd83d, 0xdc6d, 0xd83d, 0xdc85, -0xd83c, 0xdfa9, 0xd83d, 0xdc51, 0xd83d, 0xdc52, 0xd83d, 0xdc5f, 0xd83d, 0xdc5e, 0xd83d, 0xdc60, -0xd83d, 0xdc55, 0xd83d, 0xdc57, 0xd83d, 0xdc56, 0xd83d, 0xdc59, 0xd83d, 0xdc5c, 0xd83d, 0xdc53, -0xd83c, 0xdf80, 0xd83d, 0xdc84, 0xd83d, 0xdc9b, 0xd83d, 0xdc99, 0xd83d, 0xdc9c, 0xd83d, 0xdc9a, -0xd83d, 0xdc8d, 0xd83d, 0xdc8e, 0xd83d, 0xdc36, 0xd83d, 0xdc3a, 0xd83d, 0xdc31, 0xd83d, 0xdc2d, -0xd83d, 0xdc39, 0xd83d, 0xdc30, 0xd83d, 0xdc38, 0xd83d, 0xdc2f, 0xd83d, 0xdc28, 0xd83d, 0xdc3b, -0xd83d, 0xdc37, 0xd83d, 0xdc2e, 0xd83d, 0xdc17, 0xd83d, 0xdc34, 0xd83d, 0xdc11, 0xd83d, 0xdc18, -0xd83d, 0xdc3c, 0xd83d, 0xdc27, 0xd83d, 0xdc25, 0xd83d, 0xdc14, 0xd83d, 0xdc0d, 0xd83d, 0xdc22, -0xd83d, 0xdc1b, 0xd83d, 0xdc1d, 0xd83d, 0xdc1c, 0xd83d, 0xdc1e, 0xd83d, 0xdc0c, 0xd83d, 0xdc19, -0xd83d, 0xdc1a, 0xd83d, 0xdc1f, 0xd83d, 0xdc2c, 0xd83d, 0xdc0b, 0xd83d, 0xdc10, 0xd83d, 0xdc0a, -0xd83d, 0xdc2b, 0xd83c, 0xdf40, 0xd83c, 0xdf39, 0xd83c, 0xdf3b, 0xd83c, 0xdf41, 0xd83c, 0xdf3e, -0xd83c, 0xdf44, 0xd83c, 0xdf35, 0xd83c, 0xdf34, 0xd83c, 0xdf33, 0xd83c, 0xdf1e, 0xd83c, 0xdf1a, -0xd83c, 0xdf19, 0xd83c, 0xdf0e, 0xd83c, 0xdf0b, 0x26a1, 0x2614, 0x2744, 0x26c4, 0xd83c, 0xdf00, -0xd83c, 0xdf08, 0xd83c, 0xdf0a, 0xd83c, 0xdf93, 0xd83c, 0xdf86, 0xd83c, 0xdf83, 0xd83d, 0xdc7b, -0xd83c, 0xdf85, 0xd83c, 0xdf84, 0xd83c, 0xdf81, 0xd83c, 0xdf88, 0xd83d, 0xdd2e, 0xd83c, 0xdfa5, -0xd83d, 0xdcf7, 0xd83d, 0xdcbf, 0xd83d, 0xdcbb, 0x260e, 0xd83d, 0xdce1, 0xd83d, 0xdcfa, 0xd83d, -0xdcfb, 0xd83d, 0xdd09, 0xd83d, 0xdd14, 0x23f3, 0x23f0, 0x231a, 0xd83d, 0xdd12, 0xd83d, 0xdd11, -0xd83d, 0xdd0e, 0xd83d, 0xdca1, 0xd83d, 0xdd26, 0xd83d, 0xdd0c, 0xd83d, 0xdd0b, 0xd83d, 0xdebf, -0xd83d, 0xdebd, 0xd83d, 0xdd27, 0xd83d, 0xdd28, 0xd83d, 0xdeaa, 0xd83d, 0xdeac, 0xd83d, 0xdca3, -0xd83d, 0xdd2b, 0xd83d, 0xdd2a, 0xd83d, 0xdc8a, 0xd83d, 0xdc89, 0xd83d, 0xdcb0, 0xd83d, 0xdcb5, -0xd83d, 0xdcb3, 0x2709, 0xd83d, 0xdceb, 0xd83d, 0xdce6, 0xd83d, 0xdcc5, 0xd83d, 0xdcc1, 0x2702, -0xd83d, 0xdccc, 0xd83d, 0xdcce, 0x2712, 0x270f, 0xd83d, 0xdcd0, 0xd83d, 0xdcda, 0xd83d, 0xdd2c, -0xd83d, 0xdd2d, 0xd83c, 0xdfa8, 0xd83c, 0xdfac, 0xd83c, 0xdfa4, 0xd83c, 0xdfa7, 0xd83c, 0xdfb5, -0xd83c, 0xdfb9, 0xd83c, 0xdfbb, 0xd83c, 0xdfba, 0xd83c, 0xdfb8, 0xd83d, 0xdc7e, 0xd83c, 0xdfae, -0xd83c, 0xdccf, 0xd83c, 0xdfb2, 0xd83c, 0xdfaf, 0xd83c, 0xdfc8, 0xd83c, 0xdfc0, 0x26bd, 0x26be, -0xd83c, 0xdfbe, 0xd83c, 0xdfb1, 0xd83c, 0xdfc9, 0xd83c, 0xdfb3, 0xd83c, 0xdfc1, 0xd83c, 0xdfc7, -0xd83c, 0xdfc6, 0xd83c, 0xdfca, 0xd83c, 0xdfc4, 0x2615, 0xd83c, 0xdf7c, 0xd83c, 0xdf7a, 0xd83c, -0xdf77, 0xd83c, 0xdf74, 0xd83c, 0xdf55, 0xd83c, 0xdf54, 0xd83c, 0xdf5f, 0xd83c, 0xdf57, 0xd83c, -0xdf71, 0xd83c, 0xdf5a, 0xd83c, 0xdf5c, 0xd83c, 0xdf61, 0xd83c, 0xdf73, 0xd83c, 0xdf5e, 0xd83c, -0xdf69, 0xd83c, 0xdf66, 0xd83c, 0xdf82, 0xd83c, 0xdf70, 0xd83c, 0xdf6a, 0xd83c, 0xdf6b, 0xd83c, -0xdf6d, 0xd83c, 0xdf6f, 0xd83c, 0xdf4e, 0xd83c, 0xdf4f, 0xd83c, 0xdf4a, 0xd83c, 0xdf4b, 0xd83c, -0xdf52, 0xd83c, 0xdf47, 0xd83c, 0xdf49, 0xd83c, 0xdf53, 0xd83c, 0xdf51, 0xd83c, 0xdf4c, 0xd83c, -0xdf50, 0xd83c, 0xdf4d, 0xd83c, 0xdf46, 0xd83c, 0xdf45, 0xd83c, 0xdf3d, 0xd83c, 0xdfe1, 0xd83c, -0xdfe5, 0xd83c, 0xdfe6, 0x26ea, 0xd83c, 0xdff0, 0x26fa, 0xd83c, 0xdfed, 0xd83d, 0xddfb, 0xd83d, -0xddfd, 0xd83c, 0xdfa0, 0xd83c, 0xdfa1, 0x26f2, 0xd83c, 0xdfa2, 0xd83d, 0xdea2, 0xd83d, 0xdea4, -0x2693, 0xd83d, 0xde80, 0x2708, 0xd83d, 0xde81, 0xd83d, 0xde82, 0xd83d, 0xde8b, 0xd83d, 0xde8e, -0xd83d, 0xde8c, 0xd83d, 0xde99, 0xd83d, 0xde97, 0xd83d, 0xde95, 0xd83d, 0xde9b, 0xd83d, 0xdea8, -0xd83d, 0xde94, 0xd83d, 0xde92, 0xd83d, 0xde91, 0xd83d, 0xdeb2, 0xd83d, 0xdea0, 0xd83d, 0xde9c, -0xd83d, 0xdea6, 0x26a0, 0xd83d, 0xdea7, 0x26fd, 0xd83c, 0xdfb0, 0xd83d, 0xddff, 0xd83c, 0xdfaa, -0xd83c, 0xdfad, 0xd83c, 0xddef, 0xd83c, 0xddf5, 0xd83c, 0xddf0, 0xd83c, 0xddf7, 0xd83c, 0xdde9, -0xd83c, 0xddea, 0xd83c, 0xdde8, 0xd83c, 0xddf3, 0xd83c, 0xddfa, 0xd83c, 0xddf8, 0xd83c, 0xddeb, -0xd83c, 0xddf7, 0xd83c, 0xddea, 0xd83c, 0xddf8, 0xd83c, 0xddee, 0xd83c, 0xddf9, 0xd83c, 0xddf7, -0xd83c, 0xddfa, 0xd83c, 0xddec, 0xd83c, 0xdde7, 0x0031, 0x20e3, 0x0032, 0x20e3, 0x0033, 0x20e3, -0x0034, 0x20e3, 0x0035, 0x20e3, 0x0036, 0x20e3, 0x0037, 0x20e3, 0x0038, 0x20e3, 0x0039, 0x20e3, -0x0030, 0x20e3, 0xd83d, 0xdd1f, 0x2757, 0x2753, 0x2665, 0x2666, 0xd83d, 0xdcaf, 0xd83d, 0xdd17, -0xd83d, 0xdd31, 0xd83d, 0xdd34, 0xd83d, 0xdd35, 0xd83d, 0xdd36, 0xd83d, 0xdd37 }; + 0xd83d, 0xde09, 0xd83d, 0xde0d, 0xd83d, 0xde1b, 0xd83d, 0xde2d, 0xd83d, 0xde31, 0xd83d, 0xde21, 0xd83d, 0xde0e, + 0xd83d, 0xde34, 0xd83d, 0xde35, 0xd83d, 0xde08, 0xd83d, 0xde2c, 0xd83d, 0xde07, 0xd83d, 0xde0f, 0xd83d, 0xdc6e, + 0xd83d, 0xdc77, 0xd83d, 0xdc82, 0xd83d, 0xdc76, 0xd83d, 0xdc68, 0xd83d, 0xdc69, 0xd83d, 0xdc74, 0xd83d, 0xdc75, + 0xd83d, 0xde3b, 0xd83d, 0xde3d, 0xd83d, 0xde40, 0xd83d, 0xdc7a, 0xd83d, 0xde48, 0xd83d, 0xde49, 0xd83d, 0xde4a, + 0xd83d, 0xdc80, 0xd83d, 0xdc7d, 0xd83d, 0xdca9, 0xd83d, 0xdd25, 0xd83d, 0xdca5, 0xd83d, 0xdca4, 0xd83d, 0xdc42, + 0xd83d, 0xdc40, 0xd83d, 0xdc43, 0xd83d, 0xdc45, 0xd83d, 0xdc44, 0xd83d, 0xdc4d, 0xd83d, 0xdc4e, 0xd83d, 0xdc4c, + 0xd83d, 0xdc4a, 0x270c, 0x270b, 0xd83d, 0xdc50, 0xd83d, 0xdc46, 0xd83d, 0xdc47, 0xd83d, 0xdc49, 0xd83d, 0xdc48, + 0xd83d, 0xde4f, 0xd83d, 0xdc4f, 0xd83d, 0xdcaa, 0xd83d, 0xdeb6, 0xd83c, 0xdfc3, 0xd83d, 0xdc83, 0xd83d, 0xdc6b, + 0xd83d, 0xdc6a, 0xd83d, 0xdc6c, 0xd83d, 0xdc6d, 0xd83d, 0xdc85, 0xd83c, 0xdfa9, 0xd83d, 0xdc51, 0xd83d, 0xdc52, + 0xd83d, 0xdc5f, 0xd83d, 0xdc5e, 0xd83d, 0xdc60, 0xd83d, 0xdc55, 0xd83d, 0xdc57, 0xd83d, 0xdc56, 0xd83d, 0xdc59, + 0xd83d, 0xdc5c, 0xd83d, 0xdc53, 0xd83c, 0xdf80, 0xd83d, 0xdc84, 0xd83d, 0xdc9b, 0xd83d, 0xdc99, 0xd83d, 0xdc9c, + 0xd83d, 0xdc9a, 0xd83d, 0xdc8d, 0xd83d, 0xdc8e, 0xd83d, 0xdc36, 0xd83d, 0xdc3a, 0xd83d, 0xdc31, 0xd83d, 0xdc2d, + 0xd83d, 0xdc39, 0xd83d, 0xdc30, 0xd83d, 0xdc38, 0xd83d, 0xdc2f, 0xd83d, 0xdc28, 0xd83d, 0xdc3b, 0xd83d, 0xdc37, + 0xd83d, 0xdc2e, 0xd83d, 0xdc17, 0xd83d, 0xdc34, 0xd83d, 0xdc11, 0xd83d, 0xdc18, 0xd83d, 0xdc3c, 0xd83d, 0xdc27, + 0xd83d, 0xdc25, 0xd83d, 0xdc14, 0xd83d, 0xdc0d, 0xd83d, 0xdc22, 0xd83d, 0xdc1b, 0xd83d, 0xdc1d, 0xd83d, 0xdc1c, + 0xd83d, 0xdc1e, 0xd83d, 0xdc0c, 0xd83d, 0xdc19, 0xd83d, 0xdc1a, 0xd83d, 0xdc1f, 0xd83d, 0xdc2c, 0xd83d, 0xdc0b, + 0xd83d, 0xdc10, 0xd83d, 0xdc0a, 0xd83d, 0xdc2b, 0xd83c, 0xdf40, 0xd83c, 0xdf39, 0xd83c, 0xdf3b, 0xd83c, 0xdf41, + 0xd83c, 0xdf3e, 0xd83c, 0xdf44, 0xd83c, 0xdf35, 0xd83c, 0xdf34, 0xd83c, 0xdf33, 0xd83c, 0xdf1e, 0xd83c, 0xdf1a, + 0xd83c, 0xdf19, 0xd83c, 0xdf0e, 0xd83c, 0xdf0b, 0x26a1, 0x2614, 0x2744, 0x26c4, 0xd83c, 0xdf00, 0xd83c, 0xdf08, + 0xd83c, 0xdf0a, 0xd83c, 0xdf93, 0xd83c, 0xdf86, 0xd83c, 0xdf83, 0xd83d, 0xdc7b, 0xd83c, 0xdf85, 0xd83c, 0xdf84, + 0xd83c, 0xdf81, 0xd83c, 0xdf88, 0xd83d, 0xdd2e, 0xd83c, 0xdfa5, 0xd83d, 0xdcf7, 0xd83d, 0xdcbf, 0xd83d, 0xdcbb, + 0x260e, 0xd83d, 0xdce1, 0xd83d, 0xdcfa, 0xd83d, 0xdcfb, 0xd83d, 0xdd09, 0xd83d, 0xdd14, 0x23f3, 0x23f0, 0x231a, + 0xd83d, 0xdd12, 0xd83d, 0xdd11, 0xd83d, 0xdd0e, 0xd83d, 0xdca1, 0xd83d, 0xdd26, 0xd83d, 0xdd0c, 0xd83d, 0xdd0b, + 0xd83d, 0xdebf, 0xd83d, 0xdebd, 0xd83d, 0xdd27, 0xd83d, 0xdd28, 0xd83d, 0xdeaa, 0xd83d, 0xdeac, 0xd83d, 0xdca3, + 0xd83d, 0xdd2b, 0xd83d, 0xdd2a, 0xd83d, 0xdc8a, 0xd83d, 0xdc89, 0xd83d, 0xdcb0, 0xd83d, 0xdcb5, 0xd83d, 0xdcb3, + 0x2709, 0xd83d, 0xdceb, 0xd83d, 0xdce6, 0xd83d, 0xdcc5, 0xd83d, 0xdcc1, 0x2702, 0xd83d, 0xdccc, 0xd83d, 0xdcce, + 0x2712, 0x270f, 0xd83d, 0xdcd0, 0xd83d, 0xdcda, 0xd83d, 0xdd2c, 0xd83d, 0xdd2d, 0xd83c, 0xdfa8, 0xd83c, 0xdfac, + 0xd83c, 0xdfa4, 0xd83c, 0xdfa7, 0xd83c, 0xdfb5, 0xd83c, 0xdfb9, 0xd83c, 0xdfbb, 0xd83c, 0xdfba, 0xd83c, 0xdfb8, + 0xd83d, 0xdc7e, 0xd83c, 0xdfae, 0xd83c, 0xdccf, 0xd83c, 0xdfb2, 0xd83c, 0xdfaf, 0xd83c, 0xdfc8, 0xd83c, 0xdfc0, + 0x26bd, 0x26be, 0xd83c, 0xdfbe, 0xd83c, 0xdfb1, 0xd83c, 0xdfc9, 0xd83c, 0xdfb3, 0xd83c, 0xdfc1, 0xd83c, 0xdfc7, + 0xd83c, 0xdfc6, 0xd83c, 0xdfca, 0xd83c, 0xdfc4, 0x2615, 0xd83c, 0xdf7c, 0xd83c, 0xdf7a, 0xd83c, 0xdf77, 0xd83c, + 0xdf74, 0xd83c, 0xdf55, 0xd83c, 0xdf54, 0xd83c, 0xdf5f, 0xd83c, 0xdf57, 0xd83c, 0xdf71, 0xd83c, 0xdf5a, 0xd83c, + 0xdf5c, 0xd83c, 0xdf61, 0xd83c, 0xdf73, 0xd83c, 0xdf5e, 0xd83c, 0xdf69, 0xd83c, 0xdf66, 0xd83c, 0xdf82, 0xd83c, + 0xdf70, 0xd83c, 0xdf6a, 0xd83c, 0xdf6b, 0xd83c, 0xdf6d, 0xd83c, 0xdf6f, 0xd83c, 0xdf4e, 0xd83c, 0xdf4f, 0xd83c, + 0xdf4a, 0xd83c, 0xdf4b, 0xd83c, 0xdf52, 0xd83c, 0xdf47, 0xd83c, 0xdf49, 0xd83c, 0xdf53, 0xd83c, 0xdf51, 0xd83c, + 0xdf4c, 0xd83c, 0xdf50, 0xd83c, 0xdf4d, 0xd83c, 0xdf46, 0xd83c, 0xdf45, 0xd83c, 0xdf3d, 0xd83c, 0xdfe1, 0xd83c, + 0xdfe5, 0xd83c, 0xdfe6, 0x26ea, 0xd83c, 0xdff0, 0x26fa, 0xd83c, 0xdfed, 0xd83d, 0xddfb, 0xd83d, 0xddfd, 0xd83c, + 0xdfa0, 0xd83c, 0xdfa1, 0x26f2, 0xd83c, 0xdfa2, 0xd83d, 0xdea2, 0xd83d, 0xdea4, 0x2693, 0xd83d, 0xde80, 0x2708, + 0xd83d, 0xde81, 0xd83d, 0xde82, 0xd83d, 0xde8b, 0xd83d, 0xde8e, 0xd83d, 0xde8c, 0xd83d, 0xde99, 0xd83d, 0xde97, + 0xd83d, 0xde95, 0xd83d, 0xde9b, 0xd83d, 0xdea8, 0xd83d, 0xde94, 0xd83d, 0xde92, 0xd83d, 0xde91, 0xd83d, 0xdeb2, + 0xd83d, 0xdea0, 0xd83d, 0xde9c, 0xd83d, 0xdea6, 0x26a0, 0xd83d, 0xdea7, 0x26fd, 0xd83c, 0xdfb0, 0xd83d, 0xddff, + 0xd83c, 0xdfaa, 0xd83c, 0xdfad, 0xd83c, 0xddef, 0xd83c, 0xddf5, 0xd83c, 0xddf0, 0xd83c, 0xddf7, 0xd83c, 0xdde9, + 0xd83c, 0xddea, 0xd83c, 0xdde8, 0xd83c, 0xddf3, 0xd83c, 0xddfa, 0xd83c, 0xddf8, 0xd83c, 0xddeb, 0xd83c, 0xddf7, + 0xd83c, 0xddea, 0xd83c, 0xddf8, 0xd83c, 0xddee, 0xd83c, 0xddf9, 0xd83c, 0xddf7, 0xd83c, 0xddfa, 0xd83c, 0xddec, + 0xd83c, 0xdde7, 0x0031, 0x20e3, 0x0032, 0x20e3, 0x0033, 0x20e3, 0x0034, 0x20e3, 0x0035, 0x20e3, 0x0036, 0x20e3, + 0x0037, 0x20e3, 0x0038, 0x20e3, 0x0039, 0x20e3, 0x0030, 0x20e3, 0xd83d, 0xdd1f, 0x2757, 0x2753, 0x2665, 0x2666, + 0xd83d, 0xdcaf, 0xd83d, 0xdd17, 0xd83d, 0xdd31, 0xd83d, 0xdd34, 0xd83d, 0xdd35, 0xd83d, 0xdd36, 0xd83d, 0xdd37}; ushort Offsets[] = { -0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, -24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, -48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, -72, 74, 76, 78, 80, 82, 84, 86, 87, 88, 90, 92, -94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, -118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, -142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, -166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, -190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, -214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, -238, 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 259, -260, 261, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, -282, 284, 286, 288, 290, 292, 294, 295, 297, 299, 301, 303, -305, 306, 307, 308, 310, 312, 314, 316, 318, 320, 322, 324, -326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, -350, 351, 353, 355, 357, 359, 360, 362, 364, 365, 366, 368, -370, 372, 374, 376, 378, 380, 382, 384, 386, 388, 390, 392, -394, 396, 398, 400, 402, 404, 406, 407, 408, 410, 412, 414, -416, 418, 420, 422, 424, 426, 427, 429, 431, 433, 435, 437, -439, 441, 443, 445, 447, 449, 451, 453, 455, 457, 459, 461, -463, 465, 467, 469, 471, 473, 475, 477, 479, 481, 483, 485, -487, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, 508, -510, 511, 513, 515, 517, 519, 521, 522, 524, 526, 528, 529, -531, 532, 534, 536, 538, 540, 542, 544, 546, 548, 550, 552, -554, 556, 558, 560, 562, 564, 566, 567, 569, 570, 572, 574, -576, 578, 582, 586, 590, 594, 598, 602, 606, 610, 614, 618, -620, 622, 624, 626, 628, 630, 632, 634, 636, 638, 640, 641, -642, 643, 644, 646, 648, 650, 652, 654, 656, 658 }; + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, + 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 87, 88, + 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, + 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, + 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, + 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 259, 260, 261, 262, 264, 266, 268, + 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 295, 297, 299, 301, 303, 305, 306, 307, 308, 310, + 312, 314, 316, 318, 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350, 351, 353, 355, + 357, 359, 360, 362, 364, 365, 366, 368, 370, 372, 374, 376, 378, 380, 382, 384, 386, 388, 390, 392, 394, 396, 398, + 400, 402, 404, 406, 407, 408, 410, 412, 414, 416, 418, 420, 422, 424, 426, 427, 429, 431, 433, 435, 437, 439, 441, + 443, 445, 447, 449, 451, 453, 455, 457, 459, 461, 463, 465, 467, 469, 471, 473, 475, 477, 479, 481, 483, 485, 487, + 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, 508, 510, 511, 513, 515, 517, 519, 521, 522, 524, 526, 528, 529, + 531, 532, 534, 536, 538, 540, 542, 544, 546, 548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 567, 569, 570, 572, + 574, 576, 578, 582, 586, 590, 594, 598, 602, 606, 610, 614, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, + 640, 641, 642, 643, 644, 646, 648, 650, 652, 654, 656, 658}; quint64 ComputeEmojiIndex(base::const_byte_span bytes) { Expects(bytes.size() == 8); - return ((gsl::to_integer(bytes[0]) & 0x7F) << 56) - | (gsl::to_integer(bytes[1]) << 48) - | (gsl::to_integer(bytes[2]) << 40) - | (gsl::to_integer(bytes[3]) << 32) - | (gsl::to_integer(bytes[4]) << 24) - | (gsl::to_integer(bytes[5]) << 16) - | (gsl::to_integer(bytes[6]) << 8) - | (gsl::to_integer(bytes[7])); + return ((gsl::to_integer(bytes[0]) & 0x7F) << 56) | (gsl::to_integer(bytes[1]) << 48) | + (gsl::to_integer(bytes[2]) << 40) | (gsl::to_integer(bytes[3]) << 32) | + (gsl::to_integer(bytes[4]) << 24) | (gsl::to_integer(bytes[5]) << 16) | + (gsl::to_integer(bytes[6]) << 8) | (gsl::to_integer(bytes[7])); } } // namespace @@ -151,7 +126,6 @@ std::vector ComputeEmojiFingerprint(not_null call) { } } return result; - } } // namespace Calls diff --git a/Telegram/SourceFiles/calls/calls_emoji_fingerprint.h b/Telegram/SourceFiles/calls/calls_emoji_fingerprint.h index 4596ed109..72d840098 100644 --- a/Telegram/SourceFiles/calls/calls_emoji_fingerprint.h +++ b/Telegram/SourceFiles/calls/calls_emoji_fingerprint.h @@ -20,9 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include -#include #include "settings.h" +#include +#include namespace Calls { diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index 194a3224a..6d6436689 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -19,24 +19,24 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include +#include "calls/calls_instance.h" #include +#include #include #include -#include "calls/calls_instance.h" -#include "mtproto/connection.h" -#include "messenger.h" -#include "auth_session.h" #include "apiwrap.h" -#include "lang/lang_keys.h" +#include "auth_session.h" #include "boxes/confirm_box.h" #include "calls/calls_call.h" #include "calls/calls_panel.h" +#include "lang/lang_keys.h" #include "media/media_audio_track.h" +#include "messenger.h" +#include "mtproto/connection.h" -#include "boxes/rate_call_box.h" #include "app.h" +#include "boxes/rate_call_box.h" namespace Calls { namespace { @@ -47,7 +47,7 @@ constexpr auto kServerConfigUpdateTimeoutMs = 24 * 3600 * TimeMs(1000); Instance::Instance() = default; -void Instance::startOutgoingCall(not_null user) { +void Instance::startOutgoingCall(not_null user) { if (alreadyInCall()) { // Already in a call. _currentCallPanel->showAndActivate(); return; @@ -61,15 +61,15 @@ void Instance::startOutgoingCall(not_null user) { createCall(user, Call::Type::Outgoing); } -void Instance::callFinished(not_null call) { +void Instance::callFinished(not_null call) { destroyCall(call); } -void Instance::callFailed(not_null call) { +void Instance::callFailed(not_null call) { destroyCall(call); } -void Instance::callRedial(not_null call) { +void Instance::callRedial(not_null call) { if (_currentCall.get() == call) { refreshDhConfig(); } @@ -103,7 +103,7 @@ void Instance::playSound(Sound sound) { } } -void Instance::destroyCall(not_null call) { +void Instance::destroyCall(not_null call) { if (_currentCall.get() == call) { destroyCurrentPanel(); _currentCall.reset(); @@ -117,15 +117,16 @@ void Instance::destroyCall(not_null call) { } void Instance::destroyCurrentPanel() { - _pendingPanels.erase(std::remove_if(_pendingPanels.begin(), _pendingPanels.end(), [](auto &&panel) { - return !panel; - }), _pendingPanels.end()); + _pendingPanels.erase( + std::remove_if(_pendingPanels.begin(), _pendingPanels.end(), [](auto &&panel) { return !panel; }), + _pendingPanels.end()); _pendingPanels.push_back(_currentCallPanel.release()); _pendingPanels.back()->hideAndDestroy(); // Always queues the destruction. } -void Instance::createCall(not_null user, Call::Type type) { - auto call = std::make_unique(getCallDelegate(), user, type);; +void Instance::createCall(not_null user, Call::Type type) { + auto call = std::make_unique(getCallDelegate(), user, type); + ; if (_currentCall) { _currentCallPanel->replaceCall(call.get()); std::swap(_currentCall, call); @@ -141,49 +142,52 @@ void Instance::createCall(not_null user, Call::Type type) { void Instance::refreshDhConfig() { Expects(_currentCall != nullptr); - request(MTPmessages_GetDhConfig(MTP_int(_dhConfig.version), MTP_int(Call::kRandomPowerSize))).done([this, call = base::make_weak_unique(_currentCall)](const MTPmessages_DhConfig &result) { - auto random = base::const_byte_span(); - switch (result.type()) { - case mtpc_messages_dhConfig: { - auto &config = result.c_messages_dhConfig(); - if (!MTP::IsPrimeAndGood(bytesFromMTP(config.vp), config.vg.v)) { - LOG(("API Error: bad p/g received in dhConfig.")); - callFailed(call.get()); - return; - } - _dhConfig.g = config.vg.v; - _dhConfig.p = byteVectorFromMTP(config.vp); - random = bytesFromMTP(config.vrandom); - } break; + request(MTPmessages_GetDhConfig(MTP_int(_dhConfig.version), MTP_int(Call::kRandomPowerSize))) + .done([this, call = base::make_weak_unique(_currentCall)](const MTPmessages_DhConfig &result) { + auto random = base::const_byte_span(); + switch (result.type()) { + case mtpc_messages_dhConfig: { + auto &config = result.c_messages_dhConfig(); + if (!MTP::IsPrimeAndGood(bytesFromMTP(config.vp), config.vg.v)) { + LOG(("API Error: bad p/g received in dhConfig.")); + callFailed(call.get()); + return; + } + _dhConfig.g = config.vg.v; + _dhConfig.p = byteVectorFromMTP(config.vp); + random = bytesFromMTP(config.vrandom); + } break; - case mtpc_messages_dhConfigNotModified: { - auto &config = result.c_messages_dhConfigNotModified(); - random = bytesFromMTP(config.vrandom); - if (!_dhConfig.g || _dhConfig.p.empty()) { - LOG(("API Error: dhConfigNotModified on zero version.")); - callFailed(call.get()); - return; - } - } break; + case mtpc_messages_dhConfigNotModified: { + auto &config = result.c_messages_dhConfigNotModified(); + random = bytesFromMTP(config.vrandom); + if (!_dhConfig.g || _dhConfig.p.empty()) { + LOG(("API Error: dhConfigNotModified on zero version.")); + callFailed(call.get()); + return; + } + } break; - default: Unexpected("Type in messages.getDhConfig"); - } + default: Unexpected("Type in messages.getDhConfig"); + } - if (random.size() != Call::kRandomPowerSize) { - LOG(("API Error: dhConfig random bytes wrong size: %1").arg(random.size())); - callFailed(call.get()); - return; - } - if (call) { - call->start(random); - } - }).fail([this, call = base::make_weak_unique(_currentCall)](const RPCError &error) { - if (!call) { - DEBUG_LOG(("API Warning: call was destroyed before got dhConfig.")); - return; - } - callFailed(call.get()); - }).send(); + if (random.size() != Call::kRandomPowerSize) { + LOG(("API Error: dhConfig random bytes wrong size: %1").arg(random.size())); + callFailed(call.get()); + return; + } + if (call) { + call->start(random); + } + }) + .fail([this, call = base::make_weak_unique(_currentCall)](const RPCError &error) { + if (!call) { + DEBUG_LOG(("API Warning: call was destroyed before got dhConfig.")); + return; + } + callFailed(call.get()); + }) + .send(); } void Instance::refreshServerConfig() { @@ -193,67 +197,72 @@ void Instance::refreshServerConfig() { if (_lastServerConfigUpdateTime && (getms(true) - _lastServerConfigUpdateTime) < kServerConfigUpdateTimeoutMs) { return; } - _serverConfigRequestId = request(MTPphone_GetCallConfig()).done([this](const MTPDataJSON &result) { - _serverConfigRequestId = 0; - _lastServerConfigUpdateTime = getms(true); + _serverConfigRequestId = + request(MTPphone_GetCallConfig()) + .done([this](const MTPDataJSON &result) { + _serverConfigRequestId = 0; + _lastServerConfigUpdateTime = getms(true); - auto configUpdate = std::map(); - auto bytes = bytesFromMTP(result.c_dataJSON().vdata); - auto error = QJsonParseError { 0, QJsonParseError::NoError }; - auto document = QJsonDocument::fromJson(QByteArray::fromRawData(reinterpret_cast(bytes.data()), bytes.size()), &error); - if (error.error != QJsonParseError::NoError) { - LOG(("API Error: Failed to parse call config JSON, error: %1").arg(error.errorString())); - return; - } else if (!document.isObject()) { - LOG(("API Error: Not an object received in call config JSON.")); - return; - } + auto configUpdate = std::map(); + auto bytes = bytesFromMTP(result.c_dataJSON().vdata); + auto error = QJsonParseError{0, QJsonParseError::NoError}; + auto document = QJsonDocument::fromJson( + QByteArray::fromRawData(reinterpret_cast(bytes.data()), bytes.size()), &error); + if (error.error != QJsonParseError::NoError) { + LOG(("API Error: Failed to parse call config JSON, error: %1").arg(error.errorString())); + return; + } else if (!document.isObject()) { + LOG(("API Error: Not an object received in call config JSON.")); + return; + } - auto parseValue = [](QJsonValueRef data) -> std::string { - switch (data.type()) { - case QJsonValue::String: return data.toString().toStdString(); - case QJsonValue::Double: return QString::number(data.toDouble(), 'f').toStdString(); - case QJsonValue::Bool: return data.toBool() ? "true" : "false"; - case QJsonValue::Null: { - LOG(("API Warning: null field in call config JSON.")); - } return "null"; - case QJsonValue::Undefined: { - LOG(("API Warning: undefined field in call config JSON.")); - } return "undefined"; - case QJsonValue::Object: - case QJsonValue::Array: { - LOG(("API Warning: complex field in call config JSON.")); - QJsonDocument serializer; - if (data.isArray()) { - serializer.setArray(data.toArray()); - } else { - serializer.setObject(data.toObject()); - } - auto byteArray = serializer.toJson(QJsonDocument::Compact); - return std::string(byteArray.constData(), byteArray.size()); - } break; - } - Unexpected("Type in Json parse."); - }; + auto parseValue = [](QJsonValueRef data) -> std::string { + switch (data.type()) { + case QJsonValue::String: return data.toString().toStdString(); + case QJsonValue::Double: return QString::number(data.toDouble(), 'f').toStdString(); + case QJsonValue::Bool: return data.toBool() ? "true" : "false"; + case QJsonValue::Null: { + LOG(("API Warning: null field in call config JSON.")); + } + return "null"; + case QJsonValue::Undefined: { + LOG(("API Warning: undefined field in call config JSON.")); + } + return "undefined"; + case QJsonValue::Object: + case QJsonValue::Array: { + LOG(("API Warning: complex field in call config JSON.")); + QJsonDocument serializer; + if (data.isArray()) { + serializer.setArray(data.toArray()); + } else { + serializer.setObject(data.toObject()); + } + auto byteArray = serializer.toJson(QJsonDocument::Compact); + return std::string(byteArray.constData(), byteArray.size()); + } break; + } + Unexpected("Type in Json parse."); + }; - auto object = document.object(); - for (auto i = object.begin(), e = object.end(); i != e; ++i) { - auto key = i.key().toStdString(); - auto value = parseValue(i.value()); - configUpdate[key] = value; - } + auto object = document.object(); + for (auto i = object.begin(), e = object.end(); i != e; ++i) { + auto key = i.key().toStdString(); + auto value = parseValue(i.value()); + configUpdate[key] = value; + } - UpdateConfig(configUpdate); - }).fail([this](const RPCError &error) { - _serverConfigRequestId = 0; - }).send(); + UpdateConfig(configUpdate); + }) + .fail([this](const RPCError &error) { _serverConfigRequestId = 0; }) + .send(); } -void Instance::handleUpdate(const MTPDupdatePhoneCall& update) { +void Instance::handleUpdate(const MTPDupdatePhoneCall &update) { handleCallUpdate(update.vphone_call); } -void Instance::showInfoPanel(not_null call) { +void Instance::showInfoPanel(not_null call) { if (_currentCall.get() == call) { _currentCallPanel->showAndActivate(); } @@ -281,7 +290,9 @@ void Instance::handleCallUpdate(const MTPPhoneCall &call) { LOG(("API Error: Self found in phoneCallRequested.")); } if (alreadyInCall() || !user || user->isSelf()) { - request(MTPphone_DiscardCall(MTP_inputPhoneCall(phoneCall.vid, phoneCall.vaccess_hash), MTP_int(0), MTP_phoneCallDiscardReasonBusy(), MTP_long(0))).send(); + request(MTPphone_DiscardCall(MTP_inputPhoneCall(phoneCall.vid, phoneCall.vaccess_hash), MTP_int(0), + MTP_phoneCallDiscardReasonBusy(), MTP_long(0))) + .send(); } else if (phoneCall.vdate.v + (Global::CallRingTimeoutMs() / 1000) < unixtime()) { LOG(("Ignoring too old call.")); } else { diff --git a/Telegram/SourceFiles/calls/calls_instance.h b/Telegram/SourceFiles/calls/calls_instance.h index 89c8c7163..939eae03f 100644 --- a/Telegram/SourceFiles/calls/calls_instance.h +++ b/Telegram/SourceFiles/calls/calls_instance.h @@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once -#include "mtproto/sender.h" #include "calls/calls_call.h" +#include "mtproto/sender.h" namespace Media { namespace Audio { @@ -37,11 +37,11 @@ class Instance : private MTP::Sender, private Call::Delegate, private base::Subs public: Instance(); - void startOutgoingCall(not_null user); + void startOutgoingCall(not_null user); void handleUpdate(const MTPDupdatePhoneCall &update); - void showInfoPanel(not_null call); + void showInfoPanel(not_null call); - base::Observable ¤tCallChanged() { + base::Observable ¤tCallChanged() { return _currentCallChanged; } @@ -54,19 +54,19 @@ public: ~Instance(); private: - not_null getCallDelegate() { - return static_cast(this); + not_null getCallDelegate() { + return static_cast(this); } DhConfig getDhConfig() const override { return _dhConfig; } - void callFinished(not_null call) override; - void callFailed(not_null call) override; - void callRedial(not_null call) override; + void callFinished(not_null call) override; + void callFailed(not_null call) override; + void callRedial(not_null call) override; using Sound = Call::Delegate::Sound; void playSound(Sound sound) override; - void createCall(not_null user, Call::Type type); - void destroyCall(not_null call); + void createCall(not_null user, Call::Type type); + void destroyCall(not_null call); void destroyCurrentPanel(); void refreshDhConfig(); @@ -82,14 +82,13 @@ private: std::unique_ptr _currentCall; std::unique_ptr _currentCallPanel; - base::Observable _currentCallChanged; + base::Observable _currentCallChanged; base::Observable _newServiceMessage; std::vector> _pendingPanels; std::unique_ptr _callConnectingTrack; std::unique_ptr _callEndedTrack; std::unique_ptr _callBusyTrack; - }; Instance &Current(); diff --git a/Telegram/SourceFiles/calls/calls_panel.cpp b/Telegram/SourceFiles/calls/calls_panel.cpp index 1ade7e41e..d31203689 100644 --- a/Telegram/SourceFiles/calls/calls_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_panel.cpp @@ -18,27 +18,27 @@ to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ -#include #include "calls/calls_panel.h" +#include +#include "apiwrap.h" +#include "app.h" +#include "auth_session.h" +#include "base/task_queue.h" #include "calls/calls_emoji_fingerprint.h" +#include "lang/lang_keys.h" +#include "mainwindow.h" +#include "messenger.h" +#include "observer_peer.h" +#include "platform/platform_specific.h" #include "styles/style_calls.h" #include "styles/style_history.h" +#include "ui/effects/ripple_animation.h" +#include "ui/effects/widget_fade_wrap.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" #include "ui/widgets/shadow.h" -#include "ui/effects/ripple_animation.h" -#include "ui/effects/widget_fade_wrap.h" -#include "messenger.h" -#include "mainwindow.h" -#include "lang/lang_keys.h" -#include "auth_session.h" -#include "apiwrap.h" -#include "observer_peer.h" -#include "platform/platform_specific.h" -#include "base/task_queue.h" #include "window/main_window.h" -#include "app.h" #include namespace Calls { @@ -64,10 +64,10 @@ protected: QPoint prepareRippleStartPosition() const override; private: - QPoint iconPosition(not_null st) const; + QPoint iconPosition(not_null st) const; void mixIconMasks(); - not_null _stFrom; + not_null _stFrom; const style::CallButton *_stTo = nullptr; double _progress = 0.; @@ -77,12 +77,12 @@ private: double _outerValue = 0.; Animation _outerAnimation; - }; -Panel::Button::Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo) : Ui::RippleButton(parent, stFrom.button.ripple) -, _stFrom(&stFrom) -, _stTo(stTo) { +Panel::Button::Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo) + : Ui::RippleButton(parent, stFrom.button.ripple) + , _stFrom(&stFrom) + , _stTo(stTo) { resize(_stFrom->button.width, _stFrom->button.height); _bgMask = prepareRippleMask(); @@ -103,14 +103,18 @@ Panel::Button::Button(QWidget *parent, const style::CallButton &stFrom, const st _iconFrom.fill(Qt::black); { Painter p(&_iconFrom); - p.drawImage((_stFrom->button.rippleAreaSize - _stFrom->button.icon.width()) / 2, (_stFrom->button.rippleAreaSize - _stFrom->button.icon.height()) / 2, _stFrom->button.icon.instance(Qt::white)); + p.drawImage((_stFrom->button.rippleAreaSize - _stFrom->button.icon.width()) / 2, + (_stFrom->button.rippleAreaSize - _stFrom->button.icon.height()) / 2, + _stFrom->button.icon.instance(Qt::white)); } _iconTo = QImage(_bgMask.size(), QImage::Format_ARGB32_Premultiplied); _iconTo.setDevicePixelRatio(cRetinaFactor()); _iconTo.fill(Qt::black); { Painter p(&_iconTo); - p.drawImage((_stTo->button.rippleAreaSize - _stTo->button.icon.width()) / 2, (_stTo->button.rippleAreaSize - _stTo->button.icon.height()) / 2, _stTo->button.icon.instance(Qt::white)); + p.drawImage((_stTo->button.rippleAreaSize - _stTo->button.icon.width()) / 2, + (_stTo->button.rippleAreaSize - _stTo->button.icon.height()) / 2, + _stTo->button.icon.instance(Qt::white)); } _iconMixed = QImage(_bgMask.size(), QImage::Format_ARGB32_Premultiplied); _iconMixed.setDevicePixelRatio(cRetinaFactor()); @@ -119,11 +123,13 @@ Panel::Button::Button(QWidget *parent, const style::CallButton &stFrom, const st void Panel::Button::setOuterValue(double value) { if (_outerValue != value) { - _outerAnimation.start([this] { - if (_progress == 0. || _progress == 1.) { - update(); - } - }, _outerValue, value, Call::kSoundSampleMs); + _outerAnimation.start( + [this] { + if (_progress == 0. || _progress == 1.) { + update(); + } + }, + _outerValue, value, Call::kSoundSampleMs); _outerValue = value; } } @@ -143,9 +149,13 @@ void Panel::Button::paintEvent(QPaintEvent *e) { auto outerValue = _outerAnimation.current(ms, _outerValue); if (outerValue > 0.) { - auto outerRadius = paintFrom ? _stFrom->outerRadius : paintTo ? _stTo->outerRadius : (_stFrom->outerRadius * (1. - _progress) + _stTo->outerRadius * _progress); + auto outerRadius = paintFrom ? + _stFrom->outerRadius : + paintTo ? _stTo->outerRadius : + (_stFrom->outerRadius * (1. - _progress) + _stTo->outerRadius * _progress); auto outerPixels = outerValue * outerRadius; - auto outerRect = QRectF(myrtlrect(bgPosition.x(), bgPosition.y(), _stFrom->button.rippleAreaSize, _stFrom->button.rippleAreaSize)); + auto outerRect = QRectF( + myrtlrect(bgPosition.x(), bgPosition.y(), _stFrom->button.rippleAreaSize, _stFrom->button.rippleAreaSize)); outerRect = outerRect.marginsAdded(QMarginsF(outerPixels, outerPixels, outerPixels, outerPixels)); PainterHighQualityEnabler hq(p); @@ -178,7 +188,8 @@ void Panel::Button::paintEvent(QPaintEvent *e) { } else { rippleColorInterpolated = anim::color(_stFrom->button.ripple.color, _stTo->button.ripple.color, _progress); } - paintRipple(p, _stFrom->button.rippleAreaPosition.x(), _stFrom->button.rippleAreaPosition.y(), ms, rippleColorOverride); + paintRipple(p, _stFrom->button.rippleAreaPosition.x(), _stFrom->button.rippleAreaPosition.y(), ms, + rippleColorOverride); auto positionFrom = iconPosition(_stFrom); if (paintFrom) { @@ -195,7 +206,7 @@ void Panel::Button::paintEvent(QPaintEvent *e) { } } -QPoint Panel::Button::iconPosition(not_null st) const { +QPoint Panel::Button::iconPosition(not_null st) const { auto result = st->button.iconPosition; if (result.x() < 0) { result.setX((width() - st->button.icon.width()) / 2); @@ -243,15 +254,15 @@ QImage Panel::Button::prepareRippleMask() const { return Ui::RippleAnimation::ellipseMask(QSize(_stFrom->button.rippleAreaSize, _stFrom->button.rippleAreaSize)); } -Panel::Panel(not_null call) -: _call(call) -, _user(call->user()) -, _answerHangupRedial(this, st::callAnswer, &st::callHangup) -, _decline(this, object_ptr