Apply clang-format

This commit is contained in:
Evgenii Zheltonozhskii 2018-06-05 20:47:37 +03:00 committed by Berkus Decker
parent 49982a33a5
commit b9cd813127
613 changed files with 28517 additions and 24506 deletions

File diff suppressed because it is too large Load Diff

View File

@ -20,16 +20,16 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "base/timer.h"
#include <QtCore/QObject>
#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 <QtCore/QObject>
class AuthSession;
@ -49,17 +49,17 @@ class History;
class ApiWrap : private MTP::Sender, private base::Subscriber {
public:
ApiWrap(not_null<AuthSession*> session);
ApiWrap(not_null<AuthSession *> session);
void start();
void applyUpdates(const MTPUpdates &updates, quint64 sentMessageRandomId = 0);
using RequestMessageDataCallback = base::lambda<void(ChannelData*, MsgId)>;
using RequestMessageDataCallback = base::lambda<void(ChannelData *, MsgId)>;
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback);
void requestFullPeer(PeerData *peer);
void requestPeer(PeerData *peer);
void requestPeers(const QList<PeerData*> &peers);
void requestPeers(const QList<PeerData *> &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<ChannelData*> megagroup, const MTPInputStickerSet &set);
void setGroupStickerSet(not_null<ChannelData *> megagroup, const MTPInputStickerSet &set);
void joinChannel(ChannelData *channel);
void leaveChannel(ChannelData *channel);
@ -96,7 +96,7 @@ public:
void handlePrivacyChange(mtpTypeId keyTypeId, const MTPVector<MTPPrivacyRule> &rules);
int onlineTillFromStatus(const MTPUserStatus &status, int currentOnlineTill);
base::Observable<PeerData*> &fullPeerUpdated() {
base::Observable<PeerData *> &fullPeerUpdated() {
return _fullPeerUpdated;
}
@ -105,15 +105,12 @@ public:
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
void applyUpdateNoPtsCheck(const MTPUpdate &update);
void jumpToDate(not_null<PeerData*> peer, const QDate &date);
void jumpToDate(not_null<PeerData *> peer, const QDate &date);
void preloadEnoughUnreadMentions(not_null<History*> history);
void preloadEnoughUnreadMentions(not_null<History *> history);
void checkForUnreadMentions(const base::flat_set<MsgId> &possiblyReadMentions, ChannelData *channel = nullptr);
void editChatAdmins(
not_null<ChatData*> chat,
bool adminsEnabled,
base::flat_set<not_null<UserData*>> &&admins);
void editChatAdmins(not_null<ChatData *> chat, bool adminsEnabled, base::flat_set<not_null<UserData *>> &&admins);
~ApiWrap();
@ -156,18 +153,18 @@ private:
void requestFeaturedStickers(TimeId now);
void requestSavedGifs(TimeId now);
void cancelEditChatAdmins(not_null<ChatData*> chat);
void saveChatAdmins(not_null<ChatData*> chat);
void sendSaveChatAdminsRequests(not_null<ChatData*> chat);
void cancelEditChatAdmins(not_null<ChatData *> chat);
void saveChatAdmins(not_null<ChatData *> chat);
void sendSaveChatAdminsRequests(not_null<ChatData *> chat);
not_null<AuthSession*> _session;
not_null<AuthSession *> _session;
mtpRequestId _changelogSubscription = 0;
MessageDataRequests _messageDataRequests;
QMap<ChannelData*, MessageDataRequests> _channelMessageDataRequests;
QMap<ChannelData *, MessageDataRequests> _channelMessageDataRequests;
SingleQueuedInvokation _messageDataResolveDelayed;
using PeerRequests = QMap<PeerData*, mtpRequestId>;
using PeerRequests = QMap<PeerData *, mtpRequestId>;
PeerRequests _fullPeerRequests;
PeerRequests _peerRequests;
@ -175,24 +172,24 @@ private:
PeerRequests _botsRequests;
base::DelayedCallTimer _participantsCountRequestTimer;
typedef QPair<PeerData*, UserData*> KickRequest;
typedef QPair<PeerData *, UserData *> KickRequest;
typedef QMap<KickRequest, mtpRequestId> KickRequests;
KickRequests _kickRequests;
QMap<ChannelData*, mtpRequestId> _selfParticipantRequests;
QMap<ChannelData *, mtpRequestId> _selfParticipantRequests;
QMap<WebPageData*, mtpRequestId> _webPagesPending;
QMap<WebPageData *, mtpRequestId> _webPagesPending;
base::Timer _webPagesTimer;
QMap<quint64, QPair<quint64, mtpRequestId> > _stickerSetRequests;
QMap<quint64, QPair<quint64, mtpRequestId>> _stickerSetRequests;
QMap<ChannelData*, mtpRequestId> _channelAmInRequests;
QMap<UserData*, mtpRequestId> _blockRequests;
QMap<PeerData*, mtpRequestId> _exportInviteRequests;
QMap<ChannelData *, mtpRequestId> _channelAmInRequests;
QMap<UserData *, mtpRequestId> _blockRequests;
QMap<PeerData *, mtpRequestId> _exportInviteRequests;
QMap<PeerData*, mtpRequestId> _notifySettingRequests;
QMap<PeerData *, mtpRequestId> _notifySettingRequests;
QMap<History*, mtpRequestId> _draftsSaveRequestIds;
QMap<History *, mtpRequestId> _draftsSaveRequestIds;
base::Timer _draftsSaveTimer;
OrderedSet<mtpRequestId> _stickerSetDisenableRequests;
@ -210,12 +207,11 @@ private:
mtpRequestId _contactsStatusesRequestId = 0;
base::flat_map<not_null<History*>, mtpRequestId> _unreadMentionsRequests;
base::flat_map<not_null<History *>, mtpRequestId> _unreadMentionsRequests;
base::flat_map<not_null<ChatData*>, mtpRequestId> _chatAdminsEnabledRequests;
base::flat_map<not_null<ChatData*>, base::flat_set<not_null<UserData*>>> _chatAdminsToSave;
base::flat_map<not_null<ChatData*>, base::flat_set<mtpRequestId>> _chatAdminsSaveRequests;
base::Observable<PeerData*> _fullPeerUpdated;
base::flat_map<not_null<ChatData *>, mtpRequestId> _chatAdminsEnabledRequests;
base::flat_map<not_null<ChatData *>, base::flat_set<not_null<UserData *>>> _chatAdminsToSave;
base::flat_map<not_null<ChatData *>, base::flat_set<mtpRequestId>> _chatAdminsSaveRequests;
base::Observable<PeerData *> _fullPeerUpdated;
};

File diff suppressed because it is too large Load Diff

View File

@ -20,288 +20,304 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <QString>
#include <QNetworkAccessManager>
#include <QString>
#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<HistoryItem*>;
using PhotoItems = QHash<PhotoData*, HistoryItemsMap>;
using DocumentItems = QHash<DocumentData*, HistoryItemsMap>;
using WebPageItems = QHash<WebPageData*, HistoryItemsMap>;
using GameItems = QHash<GameData*, HistoryItemsMap>;
using HistoryItemsMap = OrderedSet<HistoryItem *>;
using PhotoItems = QHash<PhotoData *, HistoryItemsMap>;
using DocumentItems = QHash<DocumentData *, HistoryItemsMap>;
using WebPageItems = QHash<WebPageData *, HistoryItemsMap>;
using GameItems = QHash<GameData *, HistoryItemsMap>;
using SharedContactItems = QHash<qint32, HistoryItemsMap>;
using GifItems = QHash<Media::Clip::Reader*, HistoryItem*>;
using GifItems = QHash<Media::Clip::Reader *, HistoryItem *>;
using PhotosData = QHash<PhotoId, PhotoData*>;
using DocumentsData = QHash<DocumentId, DocumentData*>;
using PhotosData = QHash<PhotoId, PhotoData *>;
using DocumentsData = QHash<DocumentId, DocumentData *>;
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<MTPUser> &users); // returns last user
PeerData *feedChat(const MTPChat &chat);
PeerData *feedChats(const MTPVector<MTPChat> &chats); // returns last chat
UserData *feedUser(const MTPUser &user);
UserData *feedUsers(const MTPVector<MTPUser> &users); // returns last user
PeerData *feedChat(const MTPChat &chat);
PeerData *feedChats(const MTPVector<MTPChat> &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<MTPMessage> &msgs, NewMessageType type);
void feedMsgs(const MTPVector<MTPMessage> &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<MTPint> &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<MTPMessage> &msgs, NewMessageType type);
void feedMsgs(const MTPVector<MTPMessage> &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<MTPint> &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<void(UserData*)> 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<void(UserData *)> 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<MTPDocumentAttribute> &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<MTPDocumentAttribute> &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*> 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*> 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 *> 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 *> 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<WallPaper> 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<WallPaper> WallPapers;
DeclareSetting(WallPapers, ServerBackgrounds);
}; // namespace App

View File

@ -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 <QDesktopWidget>
#include <QScreen>
@ -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<Application*>(QApplication::instance());
return qobject_cast<Application *>(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);

View File

@ -23,8 +23,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <memory>
#include <QApplication>
#include <QLocalSocket>
#include <QLocalServer>
#include <QLocalSocket>
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<QLocalSocket*, QByteArray> LocalClient;
typedef QPair<QLocalSocket *, QByteArray> LocalClient;
typedef QList<LocalClient> LocalClients;
std::unique_ptr<Messenger> _messengerInstance;

View File

@ -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<ApiWrap>(this))
, _calls(std::make_unique<Calls::Instance>())
, _downloader(std::make_unique<Storage::Downloader>())
, _uploader(std::make_unique<Storage::Uploader>())
, _notifications(std::make_unique<Window::Notifications::System>(this)) {
: _userId(userId)
, _autoLockTimer([this] { checkAutoLock(); })
, _api(std::make_unique<ApiWrap>(this))
, _calls(std::make_unique<Calls::Instance>())
, _downloader(std::make_unique<Storage::Downloader>())
, _uploader(std::make_unique<Storage::Uploader>())
, _notifications(std::make_unique<Window::Notifications::System>(this)) {
Expects(_userId != 0);
_saveDataTimer.setCallback([this] {
Local::writeUserSettings();
});
_saveDataTimer.setCallback([this] { Local::writeUserSettings(); });
subscribe(Messenger::Instance().passcodedChanged(), [this] {
_shouldLockAt = 0;
notifications().updateAll();

View File

@ -64,18 +64,18 @@ public:
base::Observable<void> &savedGifsUpdated() {
return _savedGifsUpdated;
}
base::Observable<not_null<History*>> &historyCleared() {
base::Observable<not_null<History *>> &historyCleared() {
return _historyCleared;
}
base::Observable<not_null<const HistoryItem*>> &repaintLogEntry() {
base::Observable<not_null<const HistoryItem *>> &repaintLogEntry() {
return _repaintLogEntry;
}
base::Observable<void> &pendingHistoryResize() {
return _pendingHistoryResize;
}
struct ItemVisibilityQuery {
not_null<HistoryItem*> item;
not_null<bool*> isVisible;
not_null<HistoryItem *> item;
not_null<bool *> isVisible;
};
base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
return _queryItemVisibility;
@ -160,18 +160,17 @@ private:
OrderedSet<PeerId> groupStickersSectionHidden;
};
base::Variable<bool> _contactsLoaded = { false };
base::Variable<bool> _allChatsLoaded = { false };
base::Variable<bool> _contactsLoaded = {false};
base::Variable<bool> _allChatsLoaded = {false};
base::Observable<void> _moreChatsLoaded;
base::Observable<void> _stickersUpdated;
base::Observable<void> _savedGifsUpdated;
base::Observable<not_null<History*>> _historyCleared;
base::Observable<not_null<const HistoryItem*>> _repaintLogEntry;
base::Observable<not_null<History *>> _historyCleared;
base::Observable<not_null<const HistoryItem *>> _repaintLogEntry;
base::Observable<void> _pendingHistoryResize;
base::Observable<ItemVisibilityQuery> _queryItemVisibility;
Variables _variables;
TimeMs _lastTimeVideoPlayedAt = 0;
};
// One per Messenger.
@ -225,8 +224,8 @@ public:
void checkAutoLock();
void checkAutoLockIn(TimeMs time);
base::Observable<DocumentData*> documentUpdated;
base::Observable<std::pair<HistoryItem*, MsgId>> messageIdChanging;
base::Observable<DocumentData *> documentUpdated;
base::Observable<std::pair<HistoryItem *, MsgId>> messageIdChanging;
~AuthSession();
@ -243,5 +242,4 @@ private:
const std::unique_ptr<Storage::Downloader> _downloader;
const std::unique_ptr<Storage::Uploader> _uploader;
const std::unique_ptr<Window::Notifications::System> _notifications;
};

View File

@ -20,22 +20,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <iterator>
#include <algorithm>
#include <iterator>
namespace base {
// @todo use ranges-v3 here
template <typename Range, typename Method>
decltype(auto) for_each(Range &&range, Method &&method) {
return std::for_each(
std::begin(std::forward<Range>(range)),
std::end(std::forward<Range>(range)),
std::forward<Method>(method));
template <typename Range, typename Method> decltype(auto) for_each(Range &&range, Method &&method) {
return std::for_each(std::begin(std::forward<Range>(range)), std::end(std::forward<Range>(range)),
std::forward<Method>(method));
}
template <typename Method>
decltype(auto) for_each_apply(Method &&method) {
template <typename Method> decltype(auto) for_each_apply(Method &&method) {
return [&method](auto &&range) {
return for_each(std::forward<decltype(range)>(range), std::forward<Method>(method));
};

View File

@ -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();
}

View File

@ -30,49 +30,41 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace base {
template <typename EnumType>
class flags;
template <typename EnumType> class flags;
template <typename ExtendedEnum>
struct extended_flags;
template <typename ExtendedEnum> struct extended_flags;
template <typename ExtendedEnum>
using extended_flags_t = typename extended_flags<ExtendedEnum>::type;
template <typename ExtendedEnum> using extended_flags_t = typename extended_flags<ExtendedEnum>::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 <typename ExtendedEnum,
typename Enum = typename base::extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename Enum = typename base::extended_flags<ExtendedEnum>::type>
inline constexpr auto extended_flag_convert(ExtendedEnum value) {
return static_cast<Enum>(value);
}
template <typename ExtendedEnum,
typename Enum = typename base::extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename Enum = typename base::extended_flags<ExtendedEnum>::type>
inline constexpr auto extended_flags_convert(ExtendedEnum value) {
return flags<Enum>(extended_flag_convert(value));
}
} // namespace details
template <typename EnumType>
class flags {
template <typename EnumType> class flags {
public:
using Enum = EnumType;
using Type = std::underlying_type_t<Enum>;
constexpr flags() = default;
constexpr flags(details::flags_zero_helper) noexcept {
}
constexpr flags(Enum value) noexcept : _value(static_cast<Type>(value)) {
}
explicit constexpr flags(Type value) noexcept : _value(value) {
}
constexpr flags(details::flags_zero_helper) noexcept {}
constexpr flags(Enum value) noexcept
: _value(static_cast<Type>(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 <typename Enum>
constexpr auto make_flags(Enum value) noexcept {
template <typename Enum> constexpr auto make_flags(Enum value) noexcept {
return flags<Enum>(value);
}
template <typename Enum,
typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
template <typename Enum, typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
inline constexpr auto operator|(Enum a, flags<Enum> b) noexcept {
return b | a;
}
template <typename Enum,
typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
template <typename Enum, typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
inline constexpr auto operator&(Enum a, flags<Enum> b) noexcept {
return b & a;
}
template <typename Enum,
typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
template <typename Enum, typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
inline constexpr auto operator^(Enum a, flags<Enum> b) noexcept {
return b ^ a;
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator|(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return a | details::extended_flags_convert(b);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator|(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return b | a;
}
template <typename ExtendedEnum,
typename = extended_flags_t<ExtendedEnum>>
template <typename ExtendedEnum, typename = extended_flags_t<ExtendedEnum>>
inline constexpr auto operator&(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return a & details::extended_flags_convert(b);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator&(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return b & a;
}
template <typename ExtendedEnum,
typename = extended_flags_t<ExtendedEnum>>
template <typename ExtendedEnum, typename = extended_flags_t<ExtendedEnum>>
inline constexpr auto operator^(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return a ^ details::extended_flags_convert(b);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator^(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return b ^ a;
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto &operator&=(flags<extended_flags_t<ExtendedEnum>> &a, ExtendedEnum b) {
return (a &= details::extended_flags_convert(b));
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto &operator|=(flags<extended_flags_t<ExtendedEnum>> &a, ExtendedEnum b) {
return (a |= details::extended_flags_convert(b));
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto &operator^=(flags<extended_flags_t<ExtendedEnum>> &a, ExtendedEnum b) {
return (a ^= details::extended_flags_convert(b));
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator==(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return a == details::extended_flags_convert(b);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator==(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return (b == a);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator!=(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return !(a == b);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator!=(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return !(a == b);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator<(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return a < details::extended_flags_convert(b);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator<(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return details::extended_flags_convert(a) < b;
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator>(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return (b < a);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator>(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return (b < a);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator<=(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return !(b < a);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator<=(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return !(b < a);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator>=(flags<extended_flags_t<ExtendedEnum>> a, ExtendedEnum b) {
return !(a < b);
}
template <typename ExtendedEnum,
typename = typename extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename extended_flags<ExtendedEnum>::type>
inline constexpr auto operator>=(ExtendedEnum a, flags<extended_flags_t<ExtendedEnum>> b) {
return !(a < b);
}
@ -298,73 +264,62 @@ inline constexpr auto operator>=(ExtendedEnum a, flags<extended_flags_t<Extended
#undef FLAGS_CONSTEXPR
template <typename Enum,
typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
template <typename Enum, typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
inline constexpr auto operator!(Enum a) noexcept {
return !base::make_flags(a);
}
template <typename Enum,
typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
template <typename Enum, typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
inline constexpr auto operator~(Enum a) noexcept {
return ~base::make_flags(a);
}
template <typename Enum,
typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
template <typename Enum, typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
inline constexpr auto operator|(Enum a, Enum b) noexcept {
return base::make_flags(a) | b;
}
template <typename Enum,
typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
template <typename Enum, typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
inline constexpr auto operator|(Enum a, base::details::flags_zero_helper) noexcept {
return base::make_flags(a);
}
template <typename Enum,
typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
template <typename Enum, typename = std::enable_if_t<std::is_enum<Enum>::value>,
typename = std::enable_if_t<is_flag_type(Enum{})>>
inline constexpr auto operator|(base::details::flags_zero_helper, Enum b) noexcept {
return base::make_flags(b);
}
template <typename ExtendedEnum,
typename = typename base::extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename base::extended_flags<ExtendedEnum>::type>
inline constexpr auto operator|(ExtendedEnum a, ExtendedEnum b) {
return base::details::extended_flags_convert(a) | b;
}
template <typename ExtendedEnum,
typename = typename base::extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename base::extended_flags<ExtendedEnum>::type>
inline constexpr auto operator|(ExtendedEnum a, typename base::extended_flags<ExtendedEnum>::type b) {
return base::details::extended_flags_convert(a) | b;
}
template <typename ExtendedEnum,
typename = typename base::extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename base::extended_flags<ExtendedEnum>::type>
inline constexpr auto operator|(typename base::extended_flags<ExtendedEnum>::type a, ExtendedEnum b) {
return b | a;
}
template <typename ExtendedEnum,
typename = typename base::extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename base::extended_flags<ExtendedEnum>::type>
inline constexpr auto operator|(base::details::flags_zero_helper, ExtendedEnum b) {
return 0 | base::details::extended_flag_convert(b);
}
template <typename ExtendedEnum,
typename = typename base::extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename base::extended_flags<ExtendedEnum>::type>
inline constexpr auto operator|(ExtendedEnum a, base::details::flags_zero_helper) {
return base::details::extended_flag_convert(a) | 0;
}
template <typename ExtendedEnum,
typename = typename base::extended_flags<ExtendedEnum>::type>
template <typename ExtendedEnum, typename = typename base::extended_flags<ExtendedEnum>::type>
inline constexpr auto operator~(ExtendedEnum b) {
return ~base::details::extended_flags_convert(b);
}

View File

@ -20,17 +20,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <deque>
#include <algorithm>
#include "base/optional.h"
#include <algorithm>
#include <deque>
namespace base {
template <typename Key, typename Type>
class flat_map;
template <typename Key, typename Type> class flat_map;
template <typename Key, typename Type>
class flat_multi_map;
template <typename Key, typename Type> class flat_multi_map;
template <typename Key, typename Type, typename iterator_impl, typename pointer_impl, typename reference_impl>
class flat_multi_map_iterator_base_impl;
@ -47,8 +45,8 @@ public:
using reference = reference_impl;
using const_reference = typename flat_multi_map<Key, Type>::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<Key, Type>;
};
template <typename Key, typename Type>
class flat_multi_map {
template <typename Key, typename Type> class flat_multi_map {
using self = flat_multi_map<Key, Type>;
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<key_const_wrap, Type>;
using impl = std::deque<pair_type>;
using iterator_base = flat_multi_map_iterator_base_impl<Key, Type, typename impl::iterator, pair_type*, pair_type&>;
using const_iterator_base = flat_multi_map_iterator_base_impl<Key, Type, typename impl::const_iterator, const pair_type*, const pair_type&>;
using reverse_iterator_base = flat_multi_map_iterator_base_impl<Key, Type, typename impl::reverse_iterator, pair_type*, pair_type&>;
using const_reverse_iterator_base = flat_multi_map_iterator_base_impl<Key, Type, typename impl::const_reverse_iterator, const pair_type*, const pair_type&>;
using iterator_base =
flat_multi_map_iterator_base_impl<Key, Type, typename impl::iterator, pair_type *, pair_type &>;
using const_iterator_base = flat_multi_map_iterator_base_impl<Key, Type, typename impl::const_iterator,
const pair_type *, const pair_type &>;
using reverse_iterator_base =
flat_multi_map_iterator_base_impl<Key, Type, typename impl::reverse_iterator, pair_type *, pair_type &>;
using const_reverse_iterator_base =
flat_multi_map_iterator_base_impl<Key, Type, typename impl::const_reverse_iterator, const pair_type *,
const pair_type &>;
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 <typename... Args>
iterator emplace(Args&&... args) {
template <typename... Args> iterator emplace(Args &&... args) {
return insert(value_type(std::forward<Args>(args)...));
}
@ -372,11 +367,9 @@ private:
std::pair<typename impl::const_iterator, typename impl::const_iterator> getEqualRange(const Key &key) const {
return std::equal_range(_impl.begin(), _impl.end(), key, Comparator());
}
};
template <typename Key, typename Type>
class flat_map : public flat_multi_map<Key, Type> {
template <typename Key, typename Type> class flat_map : public flat_multi_map<Key, Type> {
using parent = flat_multi_map<Key, Type>;
using pair_type = typename parent::pair_type;
@ -414,8 +407,7 @@ public:
}
return this->end();
}
template <typename... Args>
iterator emplace(Args&&... args) {
template <typename... Args> iterator emplace(Args &&... args) {
return this->insert(value_type(std::forward<Args>(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

View File

@ -20,22 +20,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <deque>
#include <algorithm>
#include <deque>
namespace base {
template <typename Type>
class flat_set;
template <typename Type> class flat_set;
template <typename Type>
class flat_multi_set;
template <typename Type> class flat_multi_set;
template <typename Type, typename iterator_impl>
class flat_multi_set_iterator_base_impl;
template <typename Type, typename iterator_impl> class flat_multi_set_iterator_base_impl;
template <typename Type, typename iterator_impl>
class flat_multi_set_iterator_base_impl {
template <typename Type, typename iterator_impl> 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<Type>::pointer;
using reference = typename flat_multi_set<Type>::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<Type>;
};
template <typename Type>
class flat_multi_set {
template <typename Type> class flat_multi_set {
using self = flat_multi_set<Type>;
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<const_wrap>;
@ -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 <typename Iterator, typename = typename std::iterator_traits<Iterator>::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 <typename... Args>
iterator emplace(Args&&... args) {
template <typename... Args> iterator emplace(Args &&... args) {
return insert(Type(std::forward<Args>(args)...));
}
@ -350,11 +339,9 @@ private:
std::pair<typename impl::const_iterator, typename impl::const_iterator> getEqualRange(const Type &value) const {
return std::equal_range(_impl.begin(), _impl.end(), value);
}
};
template <typename Type>
class flat_set : public flat_multi_set<Type> {
template <typename Type> class flat_set : public flat_multi_set<Type> {
using parent = flat_multi_set<Type>;
public:
@ -365,10 +352,11 @@ public:
flat_set() = default;
template <typename Iterator, typename = typename std::iterator_traits<Iterator>::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 <typename... Args>
iterator emplace(Args&&... args) {
template <typename... Args> iterator emplace(Args &&... args) {
return this->insert(Type(std::forward<Args>(args)...));
}
@ -414,7 +401,6 @@ public:
const_iterator find(const Type &value) const {
return this->findFirst(value);
}
};
} // namespace base

View File

@ -26,17 +26,14 @@ namespace base {
namespace functors {
struct abs_helper {
template <typename Type,
typename = decltype(0 < std::declval<Type>()),
typename = decltype(-std::declval<Type>())>
constexpr Type operator()(Type value) const {
template <typename Type, typename = decltype(0 < std::declval<Type>()), typename = decltype(-std::declval<Type>())>
constexpr Type operator()(Type value) const {
return (0 < value) ? value : (-value);
}
};
constexpr auto abs = abs_helper {};
constexpr auto abs = abs_helper{};
template <typename Type>
inline auto add(Type a) {
template <typename Type> inline auto add(Type a) {
return [a](auto b) { return a + b; };
};

View File

@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <memory>
#include <cstddef> // std::max_align_t
#include <memory>
#ifndef Assert
#define LambdaAssertDefined
@ -42,31 +42,26 @@ template <typename Function> class lambda;
namespace lambda_internal {
template <typename FunctionType>
struct type_resolver;
template <typename FunctionType> struct type_resolver;
template <typename Lambda, typename R, typename ...Args>
struct type_resolver<R(Lambda::*)(Args...) const> {
template <typename Lambda, typename R, typename... Args> struct type_resolver<R (Lambda::*)(Args...) const> {
using type = lambda<R(Args...)>;
static constexpr auto is_mutable = false;
};
template <typename Lambda, typename R, typename ...Args>
struct type_resolver<R(Lambda::*)(Args...)> {
template <typename Lambda, typename R, typename... Args> struct type_resolver<R (Lambda::*)(Args...)> {
using type = lambda_once<R(Args...)>;
static constexpr auto is_mutable = true;
};
template <typename Lambda>
struct type_helper {
template <typename Lambda> struct type_helper {
using type = typename type_resolver<decltype(&Lambda::operator())>::type;
static constexpr auto is_mutable = type_resolver<decltype(&Lambda::operator())>::is_mutable;
};
} // namespace lambda_internal
template <typename Lambda>
using lambda_type = typename lambda_internal::type_helper<std::decay_t<Lambda>>::type;
template <typename Lambda> using lambda_type = typename lambda_internal::type_helper<std::decay_t<Lambda>>::type;
template <typename Lambda>
constexpr bool lambda_is_mutable = lambda_internal::type_helper<std::decay_t<Lambda>>::is_mutable;
@ -74,205 +69,165 @@ constexpr bool lambda_is_mutable = lambda_internal::type_helper<std::decay_t<Lam
namespace lambda_internal {
constexpr auto kFullStorageSize = 32U;
static_assert(kFullStorageSize % sizeof(void*) == 0, "Invalid pointer size!");
static_assert(kFullStorageSize % sizeof(void *) == 0, "Invalid pointer size!");
constexpr auto kStorageSize = kFullStorageSize - sizeof(void*);
constexpr auto kStorageSize = kFullStorageSize - sizeof(void *);
using alignment = std::max_align_t;
template <typename Lambda>
constexpr bool is_large = (sizeof(std::decay_t<Lambda>) > kStorageSize);
template <typename Lambda> constexpr bool is_large = (sizeof(std::decay_t<Lambda>) > kStorageSize);
[[noreturn]] inline void bad_construct_copy(void *lambda, const void *source) {
Unexpected("base::lambda bad_construct_copy() called!");
}
template <typename Return, typename ...Args>
[[noreturn]] Return bad_const_call(const void *lambda, Args...) {
Unexpected("base::lambda bad_const_call() called!");
}
template <typename Return, typename... Args>
[[noreturn]] Return bad_const_call(const void *lambda, Args...) { Unexpected("base::lambda bad_const_call() called!"); }
template <typename Return, typename ...Args>
template <typename Return, typename... Args>
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 <typename Lambda, bool IsLarge, typename Return, typename ...Args> struct vtable_once_impl;
template <typename Lambda, bool IsLarge, typename Return, typename... Args> struct vtable_once_impl;
template <typename Lambda, typename Return, typename ...Args>
template <typename Lambda, typename Return, typename... Args>
struct vtable_once_impl<Lambda, true, Return, Args...> : public vtable_base<Return, Args...> {
using JustLambda = std::decay_t<Lambda>;
using LambdaPtr = std::unique_ptr<JustLambda>;
using Parent = vtable_base<Return, Args...>;
static void construct_move_other_method(void *storage, void *source) {
auto source_lambda_ptr = static_cast<LambdaPtr*>(source);
auto source_lambda_ptr = static_cast<LambdaPtr *>(source);
new (storage) LambdaPtr(std::move(*source_lambda_ptr));
}
static Return call_method(void *storage, Args... args) {
return (**static_cast<LambdaPtr*>(storage))(std::forward<Args>(args)...);
return (**static_cast<LambdaPtr *>(storage))(std::forward<Args>(args)...);
}
static void destruct_method(const void *storage) {
static_cast<const LambdaPtr*>(storage)->~LambdaPtr();
}
vtable_once_impl() : Parent(
&bad_construct_copy,
&vtable_once_impl::construct_move_other_method,
&bad_const_call<Return, Args...>,
&vtable_once_impl::call_method,
&vtable_once_impl::destruct_method) {
static_cast<const LambdaPtr *>(storage)->~LambdaPtr();
}
vtable_once_impl()
: Parent(&bad_construct_copy, &vtable_once_impl::construct_move_other_method, &bad_const_call<Return, Args...>,
&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<JustLambda*>(source);
new (storage) LambdaPtr(std::make_unique<JustLambda>(static_cast<JustLambda&&>(*source_lambda)));
auto source_lambda = static_cast<JustLambda *>(source);
new (storage) LambdaPtr(std::make_unique<JustLambda>(static_cast<JustLambda &&>(*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 <typename Lambda, typename Return, typename ...Args>
template <typename Lambda, typename Return, typename... Args>
struct vtable_once_impl<Lambda, false, Return, Args...> : public vtable_base<Return, Args...> {
using JustLambda = std::decay_t<Lambda>;
using Parent = vtable_base<Return, Args...>;
static void construct_move_other_method(void *storage, void *source) {
auto source_lambda = static_cast<JustLambda*>(source);
new (storage) JustLambda(static_cast<JustLambda&&>(*source_lambda));
auto source_lambda = static_cast<JustLambda *>(source);
new (storage) JustLambda(static_cast<JustLambda &&>(*source_lambda));
}
static Return call_method(void *storage, Args... args) {
return (*static_cast<JustLambda*>(storage))(std::forward<Args>(args)...);
return (*static_cast<JustLambda *>(storage))(std::forward<Args>(args)...);
}
static void destruct_method(const void *storage) {
static_cast<const JustLambda*>(storage)->~JustLambda();
}
vtable_once_impl() : Parent(
&bad_construct_copy,
&vtable_once_impl::construct_move_other_method,
&bad_const_call<Return, Args...>,
&vtable_once_impl::call_method,
&vtable_once_impl::destruct_method) {
static_cast<const JustLambda *>(storage)->~JustLambda();
}
vtable_once_impl()
: Parent(&bad_construct_copy, &vtable_once_impl::construct_move_other_method, &bad_const_call<Return, Args...>,
&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<JustLambda*>(source);
new (storage) JustLambda(static_cast<JustLambda&&>(*source_lambda));
auto source_lambda = static_cast<JustLambda *>(source);
new (storage) JustLambda(static_cast<JustLambda &&>(*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 <typename Lambda, typename Return, typename ...Args>
template <typename Lambda, typename Return, typename... Args>
struct vtable_once : public vtable_once_impl<Lambda, is_large<Lambda>, Return, Args...> {
static const vtable_once instance;
};
template <typename Lambda, typename Return, typename ...Args>
template <typename Lambda, typename Return, typename... Args>
const vtable_once<Lambda, Return, Args...> vtable_once<Lambda, Return, Args...>::instance = {};
template <typename Lambda, bool IsLarge, typename Return, typename ...Args> struct vtable_impl;
template <typename Lambda, bool IsLarge, typename Return, typename... Args> struct vtable_impl;
template <typename Lambda, typename Return, typename ...Args>
template <typename Lambda, typename Return, typename... Args>
struct vtable_impl<Lambda, true, Return, Args...> : public vtable_once_impl<Lambda, true, Return, Args...> {
using JustLambda = std::decay_t<Lambda>;
using LambdaPtr = std::unique_ptr<JustLambda>;
using Parent = vtable_once_impl<Lambda, true, Return, Args...>;
static void construct_copy_other_method(void *storage, const void *source) {
auto source_lambda = static_cast<const LambdaPtr*>(source);
auto source_lambda = static_cast<const LambdaPtr *>(source);
new (storage) LambdaPtr(std::make_unique<JustLambda>(*source_lambda->get()));
}
static Return const_call_method(const void *storage, Args... args) {
auto lambda_ptr = static_cast<const LambdaPtr*>(storage)->get();
return (*static_cast<const JustLambda*>(lambda_ptr))(std::forward<Args>(args)...);
auto lambda_ptr = static_cast<const LambdaPtr *>(storage)->get();
return (*static_cast<const JustLambda *>(lambda_ptr))(std::forward<Args>(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 <typename Lambda, typename Return, typename ...Args>
template <typename Lambda, typename Return, typename... Args>
struct vtable_impl<Lambda, false, Return, Args...> : public vtable_once_impl<Lambda, false, Return, Args...> {
using JustLambda = std::decay_t<Lambda>;
using Parent = vtable_once_impl<Lambda, false, Return, Args...>;
static void construct_copy_other_method(void *storage, const void *source) {
auto source_lambda = static_cast<const JustLambda*>(source);
auto source_lambda = static_cast<const JustLambda *>(source);
new (storage) JustLambda(static_cast<const JustLambda &>(*source_lambda));
}
static Return const_call_method(const void *storage, Args... args) {
return (*static_cast<const JustLambda*>(storage))(std::forward<Args>(args)...);
return (*static_cast<const JustLambda *>(storage))(std::forward<Args>(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 <typename Lambda, typename Return, typename ...Args>
template <typename Lambda, typename Return, typename... Args>
struct vtable : public vtable_impl<Lambda, is_large<Lambda>, Return, Args...> {
static const vtable instance;
};
template <typename Lambda, typename Return, typename ...Args>
template <typename Lambda, typename Return, typename... Args>
const vtable<Lambda, Return, Args...> vtable<Lambda, Return, Args...>::instance = {};
} // namespace lambda_internal
template <typename Return, typename ...Args>
class lambda_once<Return(Args...)> {
template <typename Return, typename... Args> class lambda_once<Return(Args...)> {
using VTable = lambda_internal::vtable_base<Return, Args...>;
public:
@ -345,12 +300,14 @@ public:
}
// Copy / move construct / assign from an arbitrary type.
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<decltype(std::declval<Lambda>()(std::declval<Args>()...)),Return>::value>>
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<
decltype(std::declval<Lambda>()(std::declval<Args>()...)), Return>::value>>
lambda_once(Lambda other) {
data_.vtable = &lambda_internal::vtable_once<Lambda, Return, Args...>::instance;
lambda_internal::vtable_once<Lambda, Return, Args...>::construct_move_lambda_method(data_.storage, &other);
}
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<decltype(std::declval<Lambda>()(std::declval<Args>()...)),Return>::value>>
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<
decltype(std::declval<Lambda>()(std::declval<Args>()...)), 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 <typename Return, typename ...Args>
class lambda<Return(Args...)> final : public lambda_once<Return(Args...)> {
template <typename Return, typename... Args> class lambda<Return(Args...)> final : public lambda_once<Return(Args...)> {
using Parent = lambda_once<Return(Args...)>;
public:
lambda() = default;
// Move construct / assign from the same type.
lambda(lambda<Return(Args...)> &&other) : Parent(std::move(other)) {
}
lambda(lambda<Return(Args...)> &&other)
: Parent(std::move(other)) {}
lambda &operator=(lambda<Return(Args...)> &&other) {
Parent::operator=(std::move(other));
return *this;
}
// Copy construct / assign from the same type.
lambda(const lambda<Return(Args...)> &other) : Parent(other) {
}
lambda(const lambda<Return(Args...)> &other)
: Parent(other) {}
lambda &operator=(const lambda<Return(Args...)> &other) {
Parent::operator=(other);
return *this;
}
// Copy / move construct / assign from an arbitrary type.
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<decltype(std::declval<Lambda>()(std::declval<Args>()...)),Return>::value>>
lambda(Lambda other) : Parent(&lambda_internal::vtable<Lambda, Return, Args...>::instance, typename Parent::Private()) {
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<
decltype(std::declval<Lambda>()(std::declval<Args>()...)), Return>::value>>
lambda(Lambda other)
: Parent(&lambda_internal::vtable<Lambda, Return, Args...>::instance, typename Parent::Private()) {
lambda_internal::vtable<Lambda, Return, Args...>::construct_move_lambda_method(this->data_.storage, &other);
}
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<decltype(std::declval<Lambda>()(std::declval<Args>()...)),Return>::value>>
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<
decltype(std::declval<Lambda>()(std::declval<Args>()...)), 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

View File

@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <QPointer>
#include "base/lambda.h"
#include <QPointer>
namespace base {
@ -29,23 +29,22 @@ namespace base {
namespace lambda_internal {
template <int N, typename Lambda>
class guard_data {
template <int N, typename Lambda> class guard_data {
public:
using return_type = typename lambda_type<Lambda>::return_type;
template <typename ...PointersAndLambda>
inline guard_data(PointersAndLambda&&... qobjectsAndLambda) : _lambda(init(_pointers, std::forward<PointersAndLambda>(qobjectsAndLambda)...)) {
}
template <typename... PointersAndLambda>
inline guard_data(PointersAndLambda &&... qobjectsAndLambda)
: _lambda(init(_pointers, std::forward<PointersAndLambda>(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 <typename ...Args>
inline return_type operator()(Args&&... args) {
template <typename... Args> 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>(args)...);
}
template <typename ...Args>
inline return_type operator()(Args&&... args) const {
template <typename... Args> 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 <typename ...PointersAndLambda>
Lambda init(QPointer<QObject> *pointers, QObject *qobject, PointersAndLambda&&... qobjectsAndLambda) {
template <typename... PointersAndLambda>
Lambda init(QPointer<QObject> *pointers, QObject *qobject, PointersAndLambda &&... qobjectsAndLambda) {
*pointers = qobject;
return init(++pointers, std::forward<PointersAndLambda>(qobjectsAndLambda)...);
}
@ -76,24 +74,24 @@ private:
QPointer<QObject> _pointers[N];
Lambda _lambda;
};
template <int N, typename Lambda>
class guard {
template <int N, typename Lambda> class guard {
public:
using return_type = typename lambda_type<Lambda>::return_type;
template <typename Pointer, typename Other, typename ...PointersAndLambda>
inline guard(Pointer &&qobject, Other &&other, PointersAndLambda&&... qobjectsAndLambda) : _data(std::make_unique<guard_data<N, Lambda>>(std::forward<Pointer>(qobject), std::forward<Other>(other), std::forward<PointersAndLambda>(qobjectsAndLambda)...)) {
template <typename Pointer, typename Other, typename... PointersAndLambda>
inline guard(Pointer &&qobject, Other &&other, PointersAndLambda &&... qobjectsAndLambda)
: _data(std::make_unique<guard_data<N, Lambda>>(std::forward<Pointer>(qobject), std::forward<Other>(other),
std::forward<PointersAndLambda>(qobjectsAndLambda)...)) {
static_assert(1 + 1 + sizeof...(PointersAndLambda) == N + 1, "Wrong argument count!");
}
inline guard(const guard &other) : _data(std::make_unique<guard_data<N, Lambda>>(static_cast<const guard_data<N, Lambda> &>(*other._data))) {
}
inline guard(const guard &other)
: _data(std::make_unique<guard_data<N, Lambda>>(static_cast<const guard_data<N, Lambda> &>(*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 <typename ...Args>
inline return_type operator()(Args&&... args) {
template <typename... Args> inline return_type operator()(Args &&... args) {
return (*_data)(std::forward<Args>(args)...);
}
template <typename ...Args>
inline return_type operator()(Args&&... args) const {
template <typename... Args> inline return_type operator()(Args &&... args) const {
return (*_data)(std::forward<Args>(args)...);
}
@ -121,41 +117,33 @@ public:
private:
mutable std::unique_ptr<guard_data<N, Lambda>> _data;
};
template <int N, int K, typename ...PointersAndLambda>
struct guard_type;
template <int N, int K, typename... PointersAndLambda> struct guard_type;
template <int N, int K, typename Pointer, typename ...PointersAndLambda>
template <int N, int K, typename Pointer, typename... PointersAndLambda>
struct guard_type<N, K, Pointer, PointersAndLambda...> {
using type = typename guard_type<N, K - 1, PointersAndLambda...>::type;
};
template <int N, typename Lambda>
struct guard_type<N, 0, Lambda> {
using type = guard<N, Lambda>;
};
template <int N, typename Lambda> struct guard_type<N, 0, Lambda> { using type = guard<N, Lambda>; };
template <typename ...PointersAndLambda>
struct guard_type_helper {
template <typename... PointersAndLambda> struct guard_type_helper {
static constexpr int N = sizeof...(PointersAndLambda);
using type = typename guard_type<N - 1, N - 1, PointersAndLambda...>::type;
};
template <typename ...PointersAndLambda>
using guard_t = typename guard_type_helper<PointersAndLambda...>::type;
template <typename... PointersAndLambda> using guard_t = typename guard_type_helper<PointersAndLambda...>::type;
template <int N, typename Lambda>
struct type_helper<guard<N, Lambda>> {
template <int N, typename Lambda> struct type_helper<guard<N, Lambda>> {
using type = typename type_helper<Lambda>::type;
static constexpr auto is_mutable = type_helper<Lambda>::is_mutable;
};
} // namespace lambda_internal
template <typename ...PointersAndLambda>
inline lambda_internal::guard_t<PointersAndLambda...> lambda_guarded(PointersAndLambda&&... qobjectsAndLambda) {
template <typename... PointersAndLambda>
inline lambda_internal::guard_t<PointersAndLambda...> lambda_guarded(PointersAndLambda &&... qobjectsAndLambda) {
static_assert(sizeof...(PointersAndLambda) > 0, "Lambda should be passed here.");
return lambda_internal::guard_t<PointersAndLambda...>(std::forward<PointersAndLambda>(qobjectsAndLambda)...);
}

View File

@ -20,27 +20,25 @@ Copyright (c) 2018 pro.cxx Community
*/
#pragma once
#include "core/utils.h" // @todo used for base::take
#include <QObject>
#include <QPointer>
#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 <typename Object>
class object_ptr {
template <typename Object> 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 <typename Parent, typename... Args>
explicit object_ptr(Parent &&parent, Args&&... args) : _object(new Object(std::forward<Parent>(parent), std::forward<Args>(args)...)) {
}
explicit object_ptr(Parent &&parent, Args &&... args)
: _object(new Object(std::forward<Parent>(parent), std::forward<Args>(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 <typename OtherObject, typename = std::enable_if_t<std::is_base_of<Object, OtherObject>::value>>
object_ptr(object_ptr<OtherObject> &&other) : _object(base::take(other._object)) {
}
object_ptr(object_ptr<OtherObject> &&other)
: _object(base::take(other._object)) {}
template <typename OtherObject, typename = std::enable_if_t<std::is_base_of<Object, OtherObject>::value>>
object_ptr &operator=(object_ptr<OtherObject> &&other) {
@ -65,9 +63,9 @@ public:
// So we can pass this pointer to methods like connect().
Object *data() const {
return static_cast<Object*>(_object.data());
return static_cast<Object *>(_object.data());
}
operator Object*() const {
operator Object *() const {
return data();
}
@ -83,8 +81,7 @@ public:
}
// Use that instead "= new Object(parent, ...)"
template <typename Parent, typename... Args>
void create(Parent &&parent, Args&&... args) {
template <typename Parent, typename... Args> void create(Parent &&parent, Args &&... args) {
destroy();
_object = new Object(std::forward<Parent>(parent), std::forward<Args>(args)...);
}
@ -93,7 +90,7 @@ public:
}
void destroyDelayed() {
if (_object) {
if (auto widget = base::up_cast<QWidget*>(data())) {
if (auto widget = base::up_cast<QWidget *>(data())) {
widget->hide();
}
base::take(_object)->deleteLater();
@ -112,16 +109,14 @@ public:
friend object_ptr<ResultType> static_object_cast(object_ptr<SourceType> source);
private:
template <typename OtherObject>
friend class object_ptr;
template <typename OtherObject> friend class object_ptr;
QPointer<QObject> _object;
};
template <typename ResultType, typename SourceType>
inline object_ptr<ResultType> static_object_cast(object_ptr<SourceType> source) {
auto result = object_ptr<ResultType>(nullptr);
result._object = static_cast<ResultType*>(base::take(source._object).data());
result._object = static_cast<ResultType *>(base::take(source._object).data());
return std::move(result);
}

View File

@ -31,7 +31,7 @@ struct ObservableListWrap {
~ObservableListWrap() {
CantUseObservables = true;
}
OrderedSet<ObservableCallHandlers*> list;
OrderedSet<ObservableCallHandlers *> list;
};
ObservableListWrap &PendingObservables() {

View File

@ -20,13 +20,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <vector>
#include <deque>
#include <QSharedPointer>
#include "base/assertion.h"
#include "base/lambda.h"
#include "base/type_traits.h"
#include "core/utils.h"
#include <QSharedPointer>
#include <deque>
#include <vector>
namespace base {
namespace internal {
@ -36,28 +36,20 @@ void RegisterPendingObservable(ObservableCallHandlers *handlers);
void UnregisterActiveObservable(ObservableCallHandlers *handlers);
void UnregisterObservable(ObservableCallHandlers *handlers);
template <typename EventType>
struct SubscriptionHandlerHelper {
template <typename EventType> struct SubscriptionHandlerHelper {
using type = base::lambda<void(parameter_type<EventType>)>;
};
template <>
struct SubscriptionHandlerHelper<void> {
using type = base::lambda<void()>;
};
template <> struct SubscriptionHandlerHelper<void> { using type = base::lambda<void()>; };
template <typename EventType>
using SubscriptionHandler = typename SubscriptionHandlerHelper<EventType>::type;
template <typename EventType> using SubscriptionHandler = typename SubscriptionHandlerHelper<EventType>::type;
// Required because QShared/WeakPointer can't point to void.
class BaseObservableData {
};
class BaseObservableData {};
template <typename EventType, typename Handler>
class CommonObservableData;
template <typename EventType, typename Handler> class CommonObservableData;
template <typename EventType, typename Handler>
class ObservableData;
template <typename EventType, typename Handler> 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<internal::BaseObservableData> &observable) : observable(observable) {
}
Node(const QSharedPointer<internal::BaseObservableData> &observable)
: observable(observable) {}
Node *next = nullptr;
Node *prev = nullptr;
QWeakPointer<internal::BaseObservableData> 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 <typename EventType, typename Handler>
friend class internal::CommonObservableData;
template <typename EventType, typename Handler>
friend class internal::ObservableData;
template <typename EventType, typename Handler> friend class internal::CommonObservableData;
template <typename EventType, typename Handler> friend class internal::ObservableData;
};
namespace internal {
template <typename EventType, typename Handler, bool EventTypeIsSimple>
class BaseObservable;
template <typename EventType, typename Handler, bool EventTypeIsSimple> class BaseObservable;
template <typename EventType, typename Handler>
class CommonObservable {
template <typename EventType, typename Handler> class CommonObservable {
public:
Subscription add_subscription(Handler &&handler) {
if (!_data) {
@ -128,7 +117,6 @@ private:
friend class CommonObservableData<EventType, Handler>;
friend class BaseObservable<EventType, Handler, base::type_traits<EventType>::is_fast_copy_type::value>;
};
template <typename EventType, typename Handler>
@ -139,7 +127,6 @@ public:
this->_data->notify(std::move(event), sync);
}
}
};
template <typename EventType, typename Handler>
@ -156,18 +143,16 @@ public:
this->_data->notify(std::move(event_copy), sync);
}
}
};
} // namespace internal
namespace internal {
template <typename EventType, typename Handler>
class CommonObservableData : public BaseObservableData {
template <typename EventType, typename Handler> class CommonObservableData : public BaseObservableData {
public:
CommonObservableData(CommonObservable<EventType, Handler> *observable) : _observable(observable) {
}
CommonObservableData(CommonObservable<EventType, Handler> *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<BaseObservableData> &observer, Handler &&handler) : Subscription::Node(observer), handler(std::move(handler)) {
}
Node(const QSharedPointer<BaseObservableData> &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*>(node->next);
_begin = static_cast<Node *>(node->next);
}
if (_end == node) {
_end = static_cast<Node*>(node->prev);
_end = static_cast<Node *>(node->prev);
}
if (_current == node) {
_current = static_cast<Node*>(node->prev);
_current = static_cast<Node *>(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<CommonObservableData*>(that.data())->remove(node);
static_cast<CommonObservableData *>(that.data())->remove(node);
}
delete static_cast<Node*>(node);
delete static_cast<Node *>(node);
}
template <typename CallCurrent>
void notifyEnumerate(CallCurrent callCurrent) {
template <typename CallCurrent> void notifyEnumerate(CallCurrent callCurrent) {
_current = _begin;
do {
callCurrent();
if (_current) {
_current = static_cast<Node*>(_current->next);
_current = static_cast<Node *>(_current->next);
} else if (_begin) {
_current = _begin;
} else {
@ -249,11 +234,9 @@ private:
ObservableCallHandlers _callHandlers;
friend class ObservableData<EventType, Handler>;
};
template <typename EventType, typename Handler>
class ObservableData : public CommonObservableData<EventType, Handler> {
template <typename EventType, typename Handler> class ObservableData : public CommonObservableData<EventType, Handler> {
public:
using CommonObservableData<EventType, Handler>::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<EventType> _events;
bool _handling = false;
};
template <class Handler>
class ObservableData<void, Handler> : public CommonObservableData<void, Handler> {
template <class Handler> class ObservableData<void, Handler> : public CommonObservableData<void, Handler> {
public:
using CommonObservableData<void, Handler>::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 <typename Handler>
class BaseObservable<void, Handler, base::type_traits<void>::is_fast_copy_type::value> : public internal::CommonObservable<void, Handler> {
class BaseObservable<void, Handler, base::type_traits<void>::is_fast_copy_type::value>
: public internal::CommonObservable<void, Handler> {
public:
void notify(bool sync = false) {
if (this->_data) {
this->_data->notify(sync);
}
}
};
} // namespace internal
template <typename EventType, typename Handler = internal::SubscriptionHandler<EventType>>
class Observable : public internal::BaseObservable<EventType, Handler, base::type_traits<EventType>::is_fast_copy_type::value> {
class Observable
: public internal::BaseObservable<EventType, Handler, base::type_traits<EventType>::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 <typename Type>
class Variable {
template <typename Type> class Variable {
public:
Variable(parameter_type<Type> startValue = Type()) : _value(startValue) {
}
Variable(parameter_type<Type> startValue = Type())
: _value(startValue) {}
Variable(Variable &&other) = default;
Variable &operator=(Variable &&other) = default;
@ -399,8 +370,7 @@ public:
}
}
template <typename Callback>
void process(Callback callback, bool sync = false) {
template <typename Callback> void process(Callback callback, bool sync = false) {
callback(_value);
changed().notify(_value, sync);
}
@ -412,7 +382,6 @@ public:
private:
Type _value;
mutable Observable<Type> _changed;
};
class Subscriber {
@ -428,13 +397,11 @@ protected:
return subscribe(*observable, std::forward<Lambda>(handler));
}
template <typename Type, typename Lambda>
size_t subscribe(const base::Variable<Type> &variable, Lambda &&handler) {
template <typename Type, typename Lambda> size_t subscribe(const base::Variable<Type> &variable, Lambda &&handler) {
return subscribe(variable.changed(), std::forward<Lambda>(handler));
}
template <typename Type, typename Lambda>
size_t subscribe(const base::Variable<Type> *variable, Lambda &&handler) {
template <typename Type, typename Lambda> size_t subscribe(const base::Variable<Type> *variable, Lambda &&handler) {
return subscribe(variable->changed(), std::forward<Lambda>(handler));
}
@ -459,7 +426,6 @@ protected:
private:
std::vector<base::Subscription> _subscriptions;
};
void HandleObservables();

View File

@ -21,8 +21,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#pragma once
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#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<const unsigned char*>(bytes.data()),
bytes.size(),
raw())) {
if (!BN_bin2bn(reinterpret_cast<const unsigned char *>(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<unsigned char*>(result.data()));
auto resultSize = BN_bn2bin(raw(), reinterpret_cast<unsigned char *>(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_DIGEST_LENGTH> Sha256(base::const_byte_span bytes) {
auto result = base::byte_array<SHA256_DIGEST_LENGTH>();
SHA256(reinterpret_cast<const unsigned char*>(bytes.data()), bytes.size(), reinterpret_cast<unsigned char*>(result.data()));
SHA256(reinterpret_cast<const unsigned char *>(bytes.data()), bytes.size(),
reinterpret_cast<unsigned char *>(result.data()));
return result;
}
inline base::byte_array<SHA_DIGEST_LENGTH> Sha1(base::const_byte_span bytes) {
auto result = base::byte_array<SHA_DIGEST_LENGTH>();
SHA1(reinterpret_cast<const unsigned char*>(bytes.data()), bytes.size(), reinterpret_cast<unsigned char*>(result.data()));
SHA1(reinterpret_cast<const unsigned char *>(bytes.data()), bytes.size(),
reinterpret_cast<unsigned char *>(result.data()));
return result;
}
inline int FillRandom(base::byte_span bytes) {
return RAND_bytes(reinterpret_cast<unsigned char*>(bytes.data()), bytes.size());
return RAND_bytes(reinterpret_cast<unsigned char *>(bytes.data()), bytes.size());
}
} // namespace openssl

View File

@ -44,23 +44,21 @@ struct none_type {
bool operator>=(none_type other) const {
return true;
}
};
constexpr none_type none = {};
template <typename... Types>
class optional_variant {
template <typename... Types> 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 <typename T, typename = std::enable_if_t<!std::is_base_of<optional_variant, std::decay_t<T>>::value>>
optional_variant(T &&value) : _impl(std::forward<T>(value)) {
}
optional_variant(T &&value)
: _impl(std::forward<T>(value)) {}
optional_variant &operator=(const optional_variant &other) {
_impl = other._impl;
return *this;
@ -97,65 +95,43 @@ public:
return _impl >= other._impl;
}
template <typename T>
decltype(auto) is() const {
template <typename T> decltype(auto) is() const {
return _impl.template is<T>();
}
template <typename T>
decltype(auto) get_unchecked() {
template <typename T> decltype(auto) get_unchecked() {
return _impl.template get_unchecked<T>();
}
template <typename T>
decltype(auto) get_unchecked() const {
template <typename T> decltype(auto) get_unchecked() const {
return _impl.template get_unchecked<T>();
}
private:
variant<none_type, Types...> _impl;
};
template <typename T, typename... Types>
inline T *get_if(optional_variant<Types...> *v) {
template <typename T, typename... Types> inline T *get_if(optional_variant<Types...> *v) {
return (v && v->template is<T>()) ? &v->template get_unchecked<T>() : nullptr;
}
template <typename T, typename... Types>
inline const T *get_if(const optional_variant<Types...> *v) {
template <typename T, typename... Types> inline const T *get_if(const optional_variant<Types...> *v) {
return (v && v->template is<T>()) ? &v->template get_unchecked<T>() : nullptr;
}
template <typename Type>
class optional;
template <typename Type> class optional;
template <typename Type>
struct optional_wrap_once {
using type = optional<Type>;
};
template <typename Type> struct optional_wrap_once { using type = optional<Type>; };
template <typename Type>
struct optional_wrap_once<optional<Type>> {
using type = optional<Type>;
};
template <typename Type> struct optional_wrap_once<optional<Type>> { using type = optional<Type>; };
template <typename Type>
using optional_wrap_once_t = typename optional_wrap_once<std::decay_t<Type>>::type;
template <typename Type> using optional_wrap_once_t = typename optional_wrap_once<std::decay_t<Type>>::type;
template <typename Type>
struct optional_chain_result {
using type = optional_wrap_once_t<Type>;
};
template <typename Type> struct optional_chain_result { using type = optional_wrap_once_t<Type>; };
template <>
struct optional_chain_result<void> {
using type = bool;
};
template <> struct optional_chain_result<void> { using type = bool; };
template <typename Type>
using optional_chain_result_t = typename optional_chain_result<Type>::type;
template <typename Type> using optional_chain_result_t = typename optional_chain_result<Type>::type;
template <typename Type>
class optional : public optional_variant<Type> {
template <typename Type> class optional : public optional_variant<Type> {
public:
using optional_variant<Type>::optional_variant;
@ -179,37 +155,28 @@ public:
Expects(result != nullptr);
return result;
}
};
template <typename Type>
optional_wrap_once_t<Type> make_optional(Type &&value) {
return optional_wrap_once_t<Type> { std::forward<Type>(value) };
template <typename Type> optional_wrap_once_t<Type> make_optional(Type &&value) {
return optional_wrap_once_t<Type>{std::forward<Type>(value)};
}
template <typename Type, typename Method>
inline auto optional_chain(
const optional<Type> &value,
Method &method,
std::false_type)
-> optional_chain_result_t<decltype(method(*value))> {
inline auto optional_chain(const optional<Type> &value, Method &method, std::false_type)
-> optional_chain_result_t<decltype(method(*value))> {
return value ? make_optional(method(*value)) : none;
}
template <typename Type, typename Method>
inline auto optional_chain(
const optional<Type> &value,
Method &method,
std::true_type)
-> optional_chain_result_t<decltype(method(*value))> {
inline auto optional_chain(const optional<Type> &value, Method &method, std::true_type)
-> optional_chain_result_t<decltype(method(*value))> {
return value ? (method(*value), true) : false;
}
template <typename Type, typename Method>
inline auto operator|(const optional<Type> &value, Method method)
-> optional_chain_result_t<decltype(method(*value))> {
inline auto operator|(const optional<Type> &value, Method method) -> optional_chain_result_t<decltype(method(*value))> {
using is_void_return = std::is_same<decltype(method(*value)), void>;
return optional_chain(value, method, is_void_return {});
return optional_chain(value, method, is_void_return{});
}
} // namespace base

View File

@ -23,10 +23,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <QMap>
// ordered set template based on QMap
template <typename T>
class OrderedSet {
struct NullType {
};
template <typename T> class OrderedSet {
struct NullType {};
using Self = OrderedSet<T>;
using Impl = QMap<T, NullType>;
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<T> 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<T> 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<T>;
};
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<T>;
};
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();
}
};

View File

@ -20,9 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "base/assertion.h"
#include <QByteArray>
#include <QLatin1String>
#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);

View File

@ -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<RegExOption>;
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<int>(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<int>(options));
#ifndef OS_MAC_OLD
return RegularExpressionMatch(QRegularExpression(string, qtOptions).match(subjectRef));

View File

@ -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 <QStringList>
#include "core/utils.h"
#include "base/qthelp_url.h"
#include "core/utils.h"
#include <QStringList>
namespace qthelp {
@ -34,7 +34,7 @@ QMap<QString, QString> url_parse_params(const QString &params, UrlParamNameTrans
return name;
};
auto paramsList = params.split('&');
auto paramsList = params.split('&');
for_const (auto &param, paramsList) {
// Skip params without a name (starting with '=').
if (auto separatorPosition = param.indexOf('=')) {

View File

@ -20,9 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <QMap>
#include <QString>
#include <QUrl>
#include <QMap>
namespace qthelp {
@ -39,6 +39,7 @@ enum class UrlParamNameTransform {
ToLower,
};
// Parses a string like "p1=v1&p2=v2&..&pn=vn" to a map.
QMap<QString, QString> url_parse_params(const QString &params, UrlParamNameTransform transform = UrlParamNameTransform::NoTransform);
QMap<QString, QString> url_parse_params(const QString &params,
UrlParamNameTransform transform = UrlParamNameTransform::NoTransform);
} // namespace qthelp

View File

@ -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 <QMutexLocker>
#include "base/runtime_composer.h"
#include <QMutexLocker>
struct RuntimeComposerMetadatasMap {
QMap<quint64, RuntimeComposerMetadata*> data;
QMap<quint64, RuntimeComposerMetadata *> data;
~RuntimeComposerMetadatasMap() {
for_const (const RuntimeComposerMetadata *p, data) {
delete p;
}
for_const (const RuntimeComposerMetadata *p, data) { delete p; }
}
};

View File

@ -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 <cstddef>
#include <QAtomicInt>
#include <cstddef>
#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 <int Value, int Denominator>
struct CeilDivideMinimumOne {
template <int Value, int Denominator> struct CeilDivideMinimumOne {
static constexpr int Result = ((Value / Denominator) + ((!Value || (Value % Denominator)) ? 1 : 0));
};
extern RuntimeComponentWrapStruct RuntimeComponentWraps[64];
extern QAtomicInt RuntimeComponentIndexLast;
template <typename Type>
struct RuntimeComponent {
template <typename Type> 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 <typename Type>
bool Has() const {
template <typename Type> bool Has() const {
return (_meta()->offsets[Type::Index()] >= sizeof(_meta()));
}
template <typename Type>
Type *Get() {
return static_cast<Type*>(_dataptr(_meta()->offsets[Type::Index()]));
template <typename Type> Type *Get() {
return static_cast<Type *>(_dataptr(_meta()->offsets[Type::Index()]));
}
template <typename Type>
const Type *Get() const {
return static_cast<const Type*>(_dataptr(_meta()->offsets[Type::Index()]));
template <typename Type> const Type *Get() const {
return static_cast<const Type *>(_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<const RuntimeComposerMetadata**>(_data);
return *static_cast<const RuntimeComposerMetadata **>(_data);
}
void *_data = nullptr;
void swap(RuntimeComposer &other) {
std::swap(_data, other._data);
}
};

View File

@ -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 <algorithm>
#include <thread>
#include <condition_variable>
#include "base/task_queue.h"
#include "base/assertion.h"
#include "facades.h"
#include <QMutex>
#include <QWaitCondition>
#include "base/assertion.h"
#include "base/task_queue.h"
#include "facades.h"
#include <algorithm>
#include <condition_variable>
#include <thread>
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<TaskThreadPool> &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;
}

View File

@ -20,11 +20,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <memory>
#include <deque>
#include <QMutex>
#include "base/lambda.h"
#include "base/timer.h"
#include <QMutex>
#include <deque>
#include <memory>
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

View File

@ -25,8 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace MethodNamespace {
template <typename Enum>
void TestFlags(Enum a, Enum b, Enum c) {
template <typename Enum> 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<ExtendedNamespace::Flag> {
using type = FlagsNamespace::Flag;
};
template <> struct extended_flags<ExtendedNamespace::Flag> { 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;

View File

@ -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 <QTimerEvent>
#include "base/timer.h"
#include <QTimerEvent>
namespace base {
namespace {
@ -31,10 +31,11 @@ QObject *TimersAdjuster() {
} // namespace
Timer::Timer(base::lambda<void()> callback) : QObject(nullptr)
, _callback(std::move(callback))
, _type(Qt::PreciseTimer)
, _adjusted(false) {
Timer::Timer(base::lambda<void()> callback)
: QObject(nullptr)
, _callback(std::move(callback))
, _type(Qt::PreciseTimer)
, _adjusted(false) {
setRepeat(Repeat::Interval);
connect(TimersAdjuster(), &QObject::destroyed, this, [this] { adjust(); }, Qt::QueuedConnection);
}

View File

@ -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<int, lambda_once<void()>> _callbacks; // Better to use flatmap.
};
} // namespace base

View File

@ -24,9 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace base {
template <typename T>
struct custom_is_fast_copy_type : public std::false_type {
};
template <typename T> 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<MyTinyType> : public std::true_type {
@ -34,28 +32,24 @@ struct custom_is_fast_copy_type : public std::false_type {
namespace internal {
template <typename ...Types>
struct type_list_contains;
template <typename... Types> struct type_list_contains;
template <typename T>
struct type_list_contains<T> : public std::false_type {
};
template <typename T> struct type_list_contains<T> : public std::false_type {};
template <typename T, typename Head, typename ...Types>
struct type_list_contains<T, Head, Types...> : public std::integral_constant<bool, std::is_same<Head, T>::value || type_list_contains<T, Types...>::value> {
};
template <typename T, typename Head, typename... Types>
struct type_list_contains<T, Head, Types...>
: public std::integral_constant<bool, std::is_same<Head, T>::value || type_list_contains<T, Types...>::value> {};
template <typename T>
using is_std_unsigned_int = type_list_contains<T, unsigned char, unsigned short int, unsigned int, unsigned long int>;
template <typename T>
using is_std_signed_int = type_list_contains<T, signed char, short int, int, long int>;
template <typename T> using is_std_signed_int = type_list_contains<T, signed char, short int, int, long int>;
template <typename T>
using is_std_integral = std::integral_constant<bool, is_std_unsigned_int<T>::value || is_std_signed_int<T>::value || type_list_contains<T, bool, char, wchar_t>::value>;
using is_std_integral = std::integral_constant<bool, is_std_unsigned_int<T>::value || is_std_signed_int<T>::value ||
type_list_contains<T, bool, char, wchar_t>::value>;
template <typename T>
using is_std_float = type_list_contains<T, float, double, long double>;
template <typename T> using is_std_float = type_list_contains<T, float, double, long double>;
template <typename T>
using is_std_arith = std::integral_constant<bool, is_std_integral<T>::value || is_std_float<T>::value>;
@ -63,55 +57,34 @@ using is_std_arith = std::integral_constant<bool, is_std_integral<T>::value || i
template <typename T>
using is_std_fundamental = std::integral_constant<bool, is_std_arith<T>::value || std::is_same<T, void>::value>;
template <typename T>
struct is_pointer : public std::false_type {
};
template <typename T> struct is_pointer : public std::false_type {};
template <typename T> struct is_pointer<T *> : public std::true_type {};
template <typename T> struct is_member_pointer : public std::false_type {};
template <typename T, typename C> struct is_member_pointer<T C::*> : public std::true_type {};
template <typename T>
struct is_pointer<T*> : public std::true_type {
};
using is_fast_copy_type =
std::integral_constant<bool, is_std_fundamental<T>::value || is_pointer<T>::value || is_member_pointer<T>::value ||
custom_is_fast_copy_type<T>::value>;
template <typename T>
struct is_member_pointer : public std::false_type {
};
template <typename T> struct add_const_reference { using type = const T &; };
template <typename T, typename C>
struct is_member_pointer<T C::*> : public std::true_type {
};
template <> struct add_const_reference<void> { using type = void; };
template <typename T>
using is_fast_copy_type = std::integral_constant<bool, is_std_fundamental<T>::value || is_pointer<T>::value || is_member_pointer<T>::value || custom_is_fast_copy_type<T>::value>;
template <typename T> using add_const_reference_t = typename add_const_reference<T>::type;
template <typename T>
struct add_const_reference {
using type = const T &;
};
template <typename T> struct remove_pointer { using type = T; };
template <>
struct add_const_reference<void> {
using type = void;
};
template <typename T> struct remove_pointer<T *> { using type = T; };
template <typename T>
using add_const_reference_t = typename add_const_reference<T>::type;
template <typename T>
struct remove_pointer {
using type = T;
};
template <typename T>
struct remove_pointer<T*> {
using type = T;
};
template <typename T>
using remove_pointer_t = typename remove_pointer<T>::type;
template <typename T> using remove_pointer_t = typename remove_pointer<T>::type;
} // namespace internal
template <typename T>
struct type_traits {
template <typename T> struct type_traits {
using is_std_unsigned_int = internal::is_std_unsigned_int<T>;
using is_std_signed_int = internal::is_std_signed_int<T>;
using is_std_integral = internal::is_std_integral<T>;
@ -126,7 +99,6 @@ struct type_traits {
using pointed_type = internal::remove_pointer_t<T>;
};
template <typename T>
using parameter_type = typename type_traits<T>::parameter_type;
template <typename T> using parameter_type = typename type_traits<T>::parameter_type;
} // namespace base

View File

@ -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 <typename... Types>
using variant = mapbox::util::variant<Types...>;
template <typename... Types> using variant = mapbox::util::variant<Types...>;
template <typename T, typename... Types>
inline T *get_if(variant<Types...> *v) {
template <typename T, typename... Types> inline T *get_if(variant<Types...> *v) {
return (v && v->template is<T>()) ? &v->template get_unchecked<T>() : nullptr;
}
template <typename T, typename... Types>
inline const T *get_if(const variant<Types...> *v) {
template <typename T, typename... Types> inline const T *get_if(const variant<Types...> *v) {
return (v && v->template is<T>()) ? &v->template get_unchecked<T>() : nullptr;
}

View File

@ -22,23 +22,20 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <memory>
// @todo replace this with std::experimental::observer_ptr
#include <utility>
#include <QCoreApplication>
#include <utility>
namespace base {
class enable_weak_from_this;
template <typename T>
class weak_unique_ptr;
template <typename T> 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 <typename Child>
friend class weak_unique_ptr;
template <typename Child> friend class weak_unique_ptr;
std::shared_ptr<enable_weak_from_this*> getGuarded() {
std::shared_ptr<enable_weak_from_this *> getGuarded() {
if (!_guarded) {
_guarded = std::make_shared<enable_weak_from_this*>(static_cast<enable_weak_from_this*>(this));
_guarded = std::make_shared<enable_weak_from_this *>(static_cast<enable_weak_from_this *>(this));
}
return _guarded;
}
std::shared_ptr<enable_weak_from_this*> _guarded;
std::shared_ptr<enable_weak_from_this *> _guarded;
};
template <typename T>
class weak_unique_ptr {
template <typename T> class weak_unique_ptr {
public:
weak_unique_ptr() = default;
weak_unique_ptr(T *value) : _guarded(value ? value->getGuarded() : std::shared_ptr<enable_weak_from_this*>()) {
}
weak_unique_ptr(const std::unique_ptr<T> &value) : weak_unique_ptr(value.get()) {
}
weak_unique_ptr(T *value)
: _guarded(value ? value->getGuarded() : std::shared_ptr<enable_weak_from_this *>()) {}
weak_unique_ptr(const std::unique_ptr<T> &value)
: weak_unique_ptr(value.get()) {}
weak_unique_ptr &operator=(T *value) {
_guarded = value ? value->getGuarded() : std::shared_ptr<enable_weak_from_this*>();
_guarded = value ? value->getGuarded() : std::shared_ptr<enable_weak_from_this *>();
return *this;
}
weak_unique_ptr &operator=(const std::unique_ptr<T> &value) {
@ -80,7 +74,7 @@ public:
T *get() const noexcept {
if (auto shared = _guarded.lock()) {
return static_cast<T*>(*shared);
return static_cast<T *>(*shared);
}
return nullptr;
}
@ -95,50 +89,44 @@ public:
}
private:
std::weak_ptr<enable_weak_from_this*> _guarded;
std::weak_ptr<enable_weak_from_this *> _guarded;
};
template <typename T>
inline bool operator==(const weak_unique_ptr<T> &pointer, std::nullptr_t) {
template <typename T> inline bool operator==(const weak_unique_ptr<T> &pointer, std::nullptr_t) {
return (pointer.get() == nullptr);
}
template <typename T>
inline bool operator==(std::nullptr_t, const weak_unique_ptr<T> &pointer) {
template <typename T> inline bool operator==(std::nullptr_t, const weak_unique_ptr<T> &pointer) {
return (pointer == nullptr);
}
template <typename T>
inline bool operator!=(const weak_unique_ptr<T> &pointer, std::nullptr_t) {
template <typename T> inline bool operator!=(const weak_unique_ptr<T> &pointer, std::nullptr_t) {
return !(pointer == nullptr);
}
template <typename T>
inline bool operator!=(std::nullptr_t, const weak_unique_ptr<T> &pointer) {
template <typename T> inline bool operator!=(std::nullptr_t, const weak_unique_ptr<T> &pointer) {
return !(pointer == nullptr);
}
template <typename T>
weak_unique_ptr<T> make_weak_unique(T *value) {
template <typename T> weak_unique_ptr<T> make_weak_unique(T *value) {
return weak_unique_ptr<T>(value);
}
template <typename T>
weak_unique_ptr<T> make_weak_unique(const std::unique_ptr<T> &value) {
template <typename T> weak_unique_ptr<T> make_weak_unique(const std::unique_ptr<T> &value) {
return weak_unique_ptr<T>(value);
}
} // namespace base
#ifdef QT_VERSION
template <typename Lambda>
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>(lambda)] {
if (guard) {
lambda();
}
}, Qt::QueuedConnection);
template <typename Lambda> 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>(lambda)] {
if (guard) {
lambda();
}
},
Qt::QueuedConnection);
}
#endif // QT_VERSION

View File

@ -25,8 +25,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <QByteArray>
#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<InMemoryFile*>(opaque)->open(filename, mode);
static voidpf Open(voidpf opaque, const char *filename, int mode) {
return static_cast<InMemoryFile *>(opaque)->open(filename, mode);
}
static uLong Read(voidpf opaque, voidpf stream, void* buf, uLong size) {
return static_cast<InMemoryFile*>(opaque)->read(stream, buf, size);
static uLong Read(voidpf opaque, voidpf stream, void *buf, uLong size) {
return static_cast<InMemoryFile *>(opaque)->read(stream, buf, size);
}
static uLong Write(voidpf opaque, voidpf stream, const void* buf, uLong size) {
return static_cast<InMemoryFile*>(opaque)->write(stream, buf, size);
static uLong Write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
return static_cast<InMemoryFile *>(opaque)->write(stream, buf, size);
}
static int Close(voidpf opaque, voidpf stream) {
return static_cast<InMemoryFile*>(opaque)->close(stream);
return static_cast<InMemoryFile *>(opaque)->close(stream);
}
static int Error(voidpf opaque, voidpf stream) {
return static_cast<InMemoryFile*>(opaque)->error(stream);
return static_cast<InMemoryFile *>(opaque)->error(stream);
}
static long Tell(voidpf opaque, voidpf stream) {
return static_cast<InMemoryFile*>(opaque)->tell(stream);
return static_cast<InMemoryFile *>(opaque)->tell(stream);
}
static long Seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
return static_cast<InMemoryFile*>(opaque)->seek(stream, offset, origin);
return static_cast<InMemoryFile *>(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<quint32>(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

View File

@ -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 <QDesktopServices>
#include "boxes/about_box.h"
#include <QDesktopServices>
#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<const char*, QString>::value;
constexpr auto test = std::is_convertible<const char *, QString>::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);
}

View File

@ -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<Ui::FlatLabel> _text1;
object_ptr<Ui::FlatLabel> _text2;
object_ptr<Ui::FlatLabel> _text3;
};
QString telegramFaqLink();

View File

@ -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 <algorithm>
#include "boxes/abstract_box.h"
#include <algorithm>
#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<Ui::RoundButton> BoxContent::addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback) {
QPointer<Ui::RoundButton> BoxContent::addButton(base::lambda<QString()> textFactory,
base::lambda<void()> clickCallback) {
return addButton(std::move(textFactory), std::move(clickCallback), st::defaultBoxButton);
}
QPointer<Ui::RoundButton> BoxContent::addLeftButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback) {
QPointer<Ui::RoundButton> BoxContent::addLeftButton(base::lambda<QString()> textFactory,
base::lambda<void()> 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<TWidget*>(_scroll ? _scroll->widget() : nullptr)) {
if (auto widget = static_cast<TWidget *>(_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<BoxContent> content) : LayerWidget(parent)
, _controller(controller)
, _content(std::move(content)) {
AbstractBox::AbstractBox(QWidget *parent, Window::Controller *controller, object_ptr<BoxContent> 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<Ui::RoundButton> AbstractBox::addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) {
QPointer<Ui::RoundButton> AbstractBox::addButton(base::lambda<QString()> textFactory,
base::lambda<void()> clickCallback, const style::RoundButton &st) {
_buttons.push_back(object_ptr<Ui::RoundButton>(this, std::move(textFactory), st));
auto result = QPointer<Ui::RoundButton>(_buttons.back());
result->setClickedCallback(std::move(clickCallback));
@ -358,7 +365,8 @@ QPointer<Ui::RoundButton> AbstractBox::addButton(base::lambda<QString()> textFac
return result;
}
QPointer<Ui::RoundButton> AbstractBox::addLeftButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) {
QPointer<Ui::RoundButton> AbstractBox::addLeftButton(base::lambda<QString()> textFactory,
base::lambda<void()> clickCallback, const style::RoundButton &st) {
_leftButton = object_ptr<Ui::RoundButton>(this, std::move(textFactory), st);
auto result = QPointer<Ui::RoundButton>(_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);
}

View File

@ -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 <typename Widget>
class WidgetFadeWrap;
template <typename Widget> class WidgetFadeWrap;
} // namespace Ui
namespace Window {
@ -51,15 +50,17 @@ public:
virtual void setAdditionalTitle(base::lambda<QString()> additionalFactory) = 0;
virtual void clearButtons() = 0;
virtual QPointer<Ui::RoundButton> addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) = 0;
virtual QPointer<Ui::RoundButton> addLeftButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) = 0;
virtual QPointer<Ui::RoundButton> addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback,
const style::RoundButton &st) = 0;
virtual QPointer<Ui::RoundButton> addLeftButton(base::lambda<QString()> textFactory,
base::lambda<void()> 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<QString()> titleFactory) {
if (titleFactory) {
getDelegate()->setTitle([titleFactory] { return TextWithEntities { titleFactory(), EntitiesInText() }; });
getDelegate()->setTitle([titleFactory] { return TextWithEntities{titleFactory(), EntitiesInText()}; });
} else {
getDelegate()->setTitle(base::lambda<TextWithEntities()>());
}
@ -96,7 +97,8 @@ public:
}
QPointer<Ui::RoundButton> addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback);
QPointer<Ui::RoundButton> addLeftButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback);
QPointer<Ui::RoundButton> addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) {
QPointer<Ui::RoundButton> addButton(base::lambda<QString()> textFactory, base::lambda<void()> 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 <typename Widget>
QPointer<Widget> setInnerWidget(object_ptr<Widget> inner, int topSkip = 0) {
template <typename Widget> QPointer<Widget> setInnerWidget(object_ptr<Widget> inner, int topSkip = 0) {
auto result = QPointer<Widget>(inner.data());
setInnerTopSkip(topSkip);
setInner(std::move(inner));
return result;
}
template <typename Widget>
object_ptr<Widget> takeInnerWidget() {
template <typename Widget> object_ptr<Widget> takeInnerWidget() {
return static_object_cast<Widget>(doTakeInnerWidget());
}
@ -196,13 +196,12 @@ private:
bool _preparing = false;
bool _noContentMargin = false;
int _innerTopSkip = 0;
object_ptr<Ui::ScrollArea> _scroll = { nullptr };
object_ptr<Ui::WidgetFadeWrap<BoxLayerTitleShadow>> _topShadow = { nullptr };
object_ptr<Ui::WidgetFadeWrap<BoxLayerTitleShadow>> _bottomShadow = { nullptr };
object_ptr<Ui::ScrollArea> _scroll = {nullptr};
object_ptr<Ui::WidgetFadeWrap<BoxLayerTitleShadow>> _topShadow = {nullptr};
object_ptr<Ui::WidgetFadeWrap<BoxLayerTitleShadow>> _bottomShadow = {nullptr};
object_ptr<QTimer> _draggingScrollTimer = { nullptr };
object_ptr<QTimer> _draggingScrollTimer = {nullptr};
int _draggingScrollDelta = 0;
};
class AbstractBox : public LayerWidget, public BoxContentDelegate, protected base::Subscriber {
@ -219,8 +218,10 @@ public:
void setAdditionalTitle(base::lambda<QString()> additionalFactory) override;
void clearButtons() override;
QPointer<Ui::RoundButton> addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) override;
QPointer<Ui::RoundButton> addLeftButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) override;
QPointer<Ui::RoundButton> addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback,
const style::RoundButton &st) override;
QPointer<Ui::RoundButton> addLeftButton(base::lambda<QString()> textFactory, base::lambda<void()> 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<BoxContent> _content;
object_ptr<Ui::FlatLabel> _title = { nullptr };
object_ptr<Ui::FlatLabel> _title = {nullptr};
base::lambda<TextWithEntities()> _titleFactory;
QString _additionalTitle;
base::lambda<QString()> _additionalTitleFactory;
@ -283,14 +284,12 @@ private:
bool _layerType = false;
std::vector<object_ptr<Ui::RoundButton>> _buttons;
object_ptr<Ui::RoundButton> _leftButton = { nullptr };
object_ptr<Ui::RoundButton> _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 {

File diff suppressed because it is too large Load Diff

View File

@ -33,10 +33,8 @@ class PhoneInput;
class InputArea;
class UsernameInput;
class Checkbox;
template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
template <typename Enum> class RadioenumGroup;
template <typename Enum> 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<PeerListBox*> selectUsersBox, const QString &title, const std::vector<not_null<PeerData*>> &users);
void createGroup(not_null<PeerListBox *> selectUsersBox, const QString &title,
const std::vector<not_null<PeerData *>> &users);
void updateMaxHeight();
void updateSelected(const QPoint &cursorGlobalPosition);
@ -126,21 +124,20 @@ private:
object_ptr<Ui::NewAvatarButton> _photo;
object_ptr<Ui::InputField> _title;
object_ptr<Ui::InputArea> _description = { nullptr };
object_ptr<Ui::InputArea> _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<PeerData*> peer);
EditNameTitleBox(QWidget *, not_null<PeerData *> peer);
protected:
void setInnerFocus() override;
@ -225,7 +221,7 @@ private:
void onSaveChatDone(const MTPUpdates &updates);
bool onSaveChatFail(const RPCError &e);
not_null<PeerData*> _peer;
not_null<PeerData *> _peer;
object_ptr<Ui::InputField> _first;
object_ptr<Ui::InputField> _last;
@ -234,12 +230,11 @@ private:
mtpRequestId _requestId = 0;
QString _sentName;
};
class EditBioBox : public BoxContent, private MTP::Sender {
public:
EditBioBox(QWidget*, not_null<UserData*> self);
EditBioBox(QWidget *, not_null<UserData *> self);
protected:
void setInnerFocus() override;
@ -253,21 +248,20 @@ private:
void save();
style::InputField _dynamicFieldStyle;
not_null<UserData*> _self;
not_null<UserData *> _self;
object_ptr<Ui::InputArea> _bio;
object_ptr<Ui::FlatLabel> _countdown;
object_ptr<Ui::FlatLabel> _about;
mtpRequestId _requestId = 0;
QString _sentBio;
};
class EditChannelBox : public BoxContent, public RPCSender {
Q_OBJECT
public:
EditChannelBox(QWidget*, not_null<ChannelData*> channel);
EditChannelBox(QWidget *, not_null<ChannelData *> channel);
protected:
void prepare() override;
@ -301,7 +295,7 @@ private:
void saveSign();
void saveInvites();
not_null<ChannelData*> _channel;
not_null<ChannelData *> _channel;
object_ptr<Ui::InputField> _title;
object_ptr<Ui::InputArea> _description;
@ -323,12 +317,11 @@ private:
mtpRequestId _saveInvitesRequestId = 0;
QString _sentTitle, _sentDescription;
};
class RevokePublicLinkBox : public BoxContent, public RPCSender {
public:
RevokePublicLinkBox(QWidget*, base::lambda<void()> revokeCallback);
RevokePublicLinkBox(QWidget *, base::lambda<void()> revokeCallback);
protected:
void prepare() override;
@ -343,5 +336,4 @@ private:
int _innerTop = 0;
base::lambda<void()> _revokeCallback;
};

View File

@ -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<Ui::RadiobuttonGroup>(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) {

View File

@ -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<object_ptr<Ui::Radiobutton>> _options;
};

View File

@ -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<Ui::RoundCheckbox> _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<Ui::RoundCheckbox>(st::overviewCheck, [this] { update(); })) {
BackgroundBox::Inner::Inner(QWidget *parent)
: TWidget(parent)
, _check(std::make_unique<Ui::RoundCheckbox>(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<MTPWallPaper> &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<MTPWallPaper> &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;

View File

@ -38,5 +38,4 @@ private:
class Inner;
QPointer<Inner> _inner;
};

View File

@ -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<Ui::RippleAnimation>(st::defaultRippleAnimation, std::move(mask), std::move(update))).first;
it = _ripples
.emplace(_selected, std::make_unique<Ui::RippleAnimation>(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<void(QDate date)> callback)
: _context(std::make_unique<Context>(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<void(QDate date)> callback)
: _context(std::make_unique<Context>(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<Inner>(this, _context.get()), st::calendarScroll, st::calendarTitleHeight);
// _inner = setInnerWidget(object_ptr<Inner>(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);
}

View File

@ -28,7 +28,7 @@ class IconButton;
class CalendarBox : public BoxContent {
public:
CalendarBox(QWidget*, QDate month, QDate highlighted, base::lambda<void(QDate date)> callback);
CalendarBox(QWidget *, QDate month, QDate highlighted, base::lambda<void(QDate date)> callback);
void setMinDate(QDate date);
void setMaxDate(QDate date);
@ -58,5 +58,4 @@ private:
object_ptr<Ui::IconButton> _next;
base::lambda<void(QDate date)> _callback;
};

View File

@ -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<Ui::WidgetFadeWrap<Ui::FlatLabel>> &label, const QString &text, int x, int y) {
void createErrorLabel(QWidget *parent, object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> &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_ptr<Ui::WidgetFadeWrap<Ui::FlatLab
errorFadeOut->hideAnimated();
}
if (!text.isEmpty()) {
label.create(parent, object_ptr<Ui::FlatLabel>(parent, text, Ui::FlatLabel::InitType::Simple, st::changePhoneError));
label.create(parent,
object_ptr<Ui::FlatLabel>(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_ptr<Ui::WidgetFadeWrap<Ui::FlatLab
class ChangePhoneBox::EnterPhone : public BoxContent {
public:
EnterPhone(QWidget*) {
}
EnterPhone(QWidget *) {}
void setInnerFocus() override {
_phone->setFocusFast();
@ -74,15 +75,14 @@ private:
showError(QString());
}
object_ptr<Ui::PhoneInput> _phone = { nullptr };
object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> _error = { nullptr };
object_ptr<Ui::PhoneInput> _phone = {nullptr};
object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> _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<SentCodeField> _code = { nullptr };
object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> _error = { nullptr };
object_ptr<Ui::FlatLabel> _callLabel = { nullptr };
object_ptr<SentCodeField> _code = {nullptr};
object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> _error = {nullptr};
object_ptr<Ui::FlatLabel> _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<Ui::FlatLabel>(this, lang(lng_change_phone_new_description), Ui::FlatLabel::InitType::Simple, st::changePhoneLabel);
auto description = object_ptr<Ui::FlatLabel>(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<Ui::FlatLabel>(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<Ui::FlatLabel>(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<ConfirmBox>(lang(lng_change_phone_warning), [] {
Ui::show(Box<EnterPhone>());
}));
});
addButton(langFactory(lng_cancel), [this] {
closeBox();
});
addButton(langFactory(lng_change_phone_button),
[] { Ui::show(Box<ConfirmBox>(lang(lng_change_phone_warning), [] { Ui::show(Box<EnterPhone>()); })); });
addButton(langFactory(lng_cancel), [this] { closeBox(); });
auto label = object_ptr<Ui::FlatLabel>(this, lang(lng_change_phone_description), Ui::FlatLabel::InitType::Rich, st::changePhoneDescription);
auto label = object_ptr<Ui::FlatLabel>(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);

View File

@ -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;
};

View File

@ -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<void()> confirmedCallback, base::lambda_once<void()> 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<void()> confirmedCallback,
base::lambda_once<void()> 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<void()> confirmedCallback, base::lambda_once<void()> 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<void()> confirmedCallback, base::lambda_once<void()> 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<void()> confirmedCallback, base::lambda_once<void()> 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<void()> confirmedCallback,
base::lambda_once<void()> 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<void()> confirmedCallback, base::lambda_once<void()> 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<void()> confirmedCallback, base::lambda_once<void()> 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<void()> confirmedCallback, base::lambda_once<void()> 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<void()> confirmedCallback, base::lambda_once<void()> 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<void()> 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<void()> 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<void()> closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, lang(lng_box_ok), std::move(closedCallback)) {
}
InformBox::InformBox(QWidget *, const QString &text, base::lambda<void()> closedCallback)
: ConfirmBox(ConfirmBox::InformBoxTag(), text, lang(lng_box_ok), std::move(closedCallback)) {}
InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, base::lambda<void()> closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std::move(closedCallback)) {
}
InformBox::InformBox(QWidget *, const QString &text, const QString &doneText, base::lambda<void()> closedCallback)
: ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std::move(closedCallback)) {}
MaxInviteBox::MaxInviteBox(QWidget*, not_null<ChannelData*> 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<ChannelData *> 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<MTPint>(1, MTP_int(_ids[0].msg))));
MTP::send(MTPchannels_ReportSpam(_moderateInChannel->inputChannel, _moderateFrom->inputUser,
MTP_vector<MTPint>(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<PeerData*, QVector<MTPint>> idsByPeer;
QMap<PeerData *, QVector<MTPint>> 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<UserData*> &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<UserData *> &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;
}
}

View File

@ -31,11 +31,21 @@ class FlatLabel;
class InformBox;
class ConfirmBox : public BoxContent, public ClickHandlerHost {
public:
ConfirmBox(QWidget*, const QString &text, base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(), base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget*, const QString &text, const QString &confirmText, base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(), base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(), base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const QString &cancelText, base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(), base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, const QString &cancelText, base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(), base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget *, const QString &text,
base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(),
base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget *, const QString &text, const QString &confirmText,
base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(),
base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget *, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle,
base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(),
base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget *, const QString &text, const QString &confirmText, const QString &cancelText,
base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(),
base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
ConfirmBox(QWidget *, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle,
const QString &cancelText, base::lambda_once<void()> confirmedCallback = base::lambda_once<void()>(),
base::lambda_once<void()> cancelledCallback = base::lambda_once<void()>());
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<void()> closedCallback);
base::lambda_once<void()> generateInformCallback(base::lambda<void()> closedCallback);
friend class InformBox;
@ -87,19 +96,18 @@ private:
bool _strictCancel = false;
base::lambda_once<void()> _confirmedCallback;
base::lambda_once<void()> _cancelledCallback;
};
class InformBox : public ConfirmBox {
public:
InformBox(QWidget*, const QString &text, base::lambda<void()> closedCallback = base::lambda<void()>());
InformBox(QWidget*, const QString &text, const QString &doneText, base::lambda<void()> closedCallback = base::lambda<void()>());
InformBox(QWidget *, const QString &text, base::lambda<void()> closedCallback = base::lambda<void()>());
InformBox(QWidget *, const QString &text, const QString &doneText,
base::lambda<void()> closedCallback = base::lambda<void()>());
};
class MaxInviteBox : public BoxContent {
public:
MaxInviteBox(QWidget*, not_null<ChannelData*> channel);
MaxInviteBox(QWidget *, not_null<ChannelData *> channel);
protected:
void prepare() override;
@ -113,7 +121,7 @@ protected:
private:
void updateSelected(const QPoint &cursorGlobalPosition);
not_null<ChannelData*> _channel;
not_null<ChannelData *> _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<Ui::Checkbox> _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<Ui::FlatLabel> _text = { nullptr };
object_ptr<Ui::Checkbox> _forEveryone = { nullptr };
object_ptr<Ui::Checkbox> _banUser = { nullptr };
object_ptr<Ui::Checkbox> _reportSpam = { nullptr };
object_ptr<Ui::Checkbox> _deleteAll = { nullptr };
object_ptr<Ui::FlatLabel> _text = {nullptr};
object_ptr<Ui::Checkbox> _forEveryone = {nullptr};
object_ptr<Ui::Checkbox> _banUser = {nullptr};
object_ptr<Ui::Checkbox> _reportSpam = {nullptr};
object_ptr<Ui::Checkbox> _deleteAll = {nullptr};
};
class ConfirmInviteBox : public BoxContent, public RPCSender {
public:
ConfirmInviteBox(QWidget*, const QString &title, bool isChannel, const MTPChatPhoto &photo, int count, const QVector<UserData*> &participants);
ConfirmInviteBox(QWidget *, const QString &title, bool isChannel, const MTPChatPhoto &photo, int count,
const QVector<UserData *> &participants);
protected:
void prepare() override;
@ -215,8 +220,7 @@ private:
object_ptr<Ui::FlatLabel> _status;
ImagePtr _photo;
EmptyUserpic _photoEmpty;
QVector<UserData*> _participants;
QVector<UserData *> _participants;
int _userWidth = 0;
};

View File

@ -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<ConfirmPhoneBox> CurrentConfirmPhoneBox = { nullptr };
object_ptr<ConfirmPhoneBox> CurrentConfirmPhoneBox = {nullptr};
} // namespace
@ -90,9 +90,9 @@ void SentCodeField::fix() {
}
SentCodeCall::SentCodeCall(QObject *parent, base::lambda_once<void()> callCallback, base::lambda<void()> 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) {

View File

@ -30,7 +30,10 @@ class FlatLabel;
class SentCodeField : public Ui::InputField {
public:
SentCodeField(QWidget *parent, const style::InputField &st, base::lambda<QString()> placeholderFactory = base::lambda<QString()>(), const QString &val = QString()) : Ui::InputField(parent, st, std::move(placeholderFactory), val) {
SentCodeField(QWidget *parent, const style::InputField &st,
base::lambda<QString()> placeholderFactory = base::lambda<QString()>(),
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<void()> _submitCallback;
base::lambda<void()> _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<QTimer> _timer;
base::lambda_once<void()> _call;
base::lambda<void()> _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<ConfirmPhoneBox>;
void sendCall();
@ -146,10 +147,9 @@ private:
mtpRequestId _checkCodeRequestId = 0;
object_ptr<Ui::FlatLabel> _about = { nullptr };
object_ptr<SentCodeField> _code = { nullptr };
object_ptr<Ui::FlatLabel> _about = {nullptr};
object_ptr<SentCodeField> _code = {nullptr};
QString _error;
SentCodeCall _call;
};

View File

@ -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<QString, QString> &fields) {
auto server = fields.value(qsl("server"));
auto port = fields.value(qsl("port")).toInt();
if (!server.isEmpty() && port != 0) {
auto weakBox = std::make_shared<QPointer<ConfirmBox>>(nullptr);
auto box = Ui::show(Box<ConfirmBox>(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<ConfirmBox>(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<Ui::RadioenumGroup<DBIConnectionType>>(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<Ui::RadioenumGroup<DBIConnectionType>>(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));

View File

@ -27,10 +27,8 @@ class InputField;
class PortInput;
class PasswordInput;
class Checkbox;
template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
template <typename Enum> class RadioenumGroup;
template <typename Enum> class Radioenum;
} // namespace Ui
class ConnectionBox : public BoxContent {
@ -67,7 +65,6 @@ private:
object_ptr<Ui::Radioenum<DBIConnectionType>> _httpProxyRadio;
object_ptr<Ui::Radioenum<DBIConnectionType>> _tcpProxyRadio;
object_ptr<Ui::Checkbox> _tryIPv6;
};
class AutoDownloadBox : public BoxContent {
@ -95,5 +92,4 @@ private:
object_ptr<Ui::Checkbox> _gifPlay;
int _sectionHeight = 0;
};

View File

@ -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<Ui::RadioenumGroup<Directory>>(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<Ui::RadioenumGroup<Directory>>(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));
}

View File

@ -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 <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
template <typename Enum> class RadioenumGroup;
template <typename Enum> class Radioenum;
class LinkButton;
} // namespace Ui
@ -73,5 +71,4 @@ private:
object_ptr<Ui::Radioenum<Directory>> _temp;
object_ptr<Ui::Radioenum<Directory>> _dir;
object_ptr<Ui::LinkButton> _pathLink;
};

View File

@ -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<void> _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<quint32*>(_palette.bits());
auto ints = reinterpret_cast<quint32 *>(_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<void> _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<quint32*>(image.bits());
auto ints = reinterpret_cast<quint32 *>(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]);

View File

@ -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<void(QColor)> callback) {
_saveCallback = std::move(callback);
@ -105,5 +105,4 @@ private:
base::lambda<void(QColor)> _saveCallback;
base::lambda<void()> _cancelCallback;
};

View File

@ -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<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights);
Inner(QWidget *parent, not_null<ChannelData *> channel, not_null<UserData *> user, bool hasAdminRights);
template <typename Widget>
QPointer<Widget> addControl(object_ptr<Widget> widget, QMargins margin) {
template <typename Widget> QPointer<Widget> addControl(object_ptr<Widget> widget, QMargins margin) {
doAddControl(std::move(widget), margin);
return static_cast<Widget*>(_rows.back().widget.data());
return static_cast<Widget *>(_rows.back().widget.data());
}
void removeControl(QPointer<TWidget> widget);
@ -94,8 +93,8 @@ protected:
private:
void doAddControl(object_ptr<TWidget> widget, QMargins margin);
not_null<ChannelData*> _channel;
not_null<UserData*> _user;
not_null<ChannelData *> _channel;
not_null<UserData *> _user;
object_ptr<Ui::PeerAvatarButton> _userPhoto;
Text _userName;
bool _hasAdminRights = false;
@ -104,22 +103,21 @@ private:
QMargins margin;
};
std::vector<Control> _rows;
};
EditParticipantBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights) : TWidget(parent)
, _channel(channel)
, _user(user)
, _userPhoto(this, _user, st::rightsPhotoButton)
, _hasAdminRights(hasAdminRights) {
EditParticipantBox::Inner::Inner(QWidget *parent, not_null<ChannelData *> channel, not_null<UserData *> 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<TWidget> 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<TWidget> widget) {
void EditParticipantBox::Inner::doAddControl(object_ptr<TWidget> 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<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights) : BoxContent()
, _channel(channel)
, _user(user)
, _hasAdminRights(hasAdminRights) {
}
EditParticipantBox::EditParticipantBox(QWidget *, not_null<ChannelData *> channel, not_null<UserData *> user,
bool hasAdminRights)
: BoxContent()
, _channel(channel)
, _user(user)
, _hasAdminRights(hasAdminRights) {}
void EditParticipantBox::prepare() {
_inner = setInnerWidget(object_ptr<Inner>(this, _channel, _user, hasAdminRights()));
}
template <typename Widget>
QPointer<Widget> EditParticipantBox::addControl(object_ptr<Widget> widget, QMargins margin) {
template <typename Widget> QPointer<Widget> EditParticipantBox::addControl(object_ptr<Widget> 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<ChannelData*> channel, not_null<UserData*> user, const MTPChannelAdminRights &rights) : EditParticipantBox(nullptr, channel, user, (rights.c_channelAdminRights().vflags.v != 0))
, _oldRights(rights) {
EditAdminBox::EditAdminBox(QWidget *, not_null<ChannelData *> channel, not_null<UserData *> 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<ChannelData*> channel, not_null<Us
dependency(Flag::f_invite_users, Flag::f_invite_link);
}
MTPChannelAdminRights EditAdminBox::DefaultRights(not_null<ChannelData*> 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<ChannelData *> 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<BoxContentDivider>(this), QMargins());
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_edit_admin_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
addControl(object_ptr<Ui::FlatLabel>(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<Ui::Checkbox>(this, text, checked, st::rightsCheckbox, st::rightsToggle), st::rightsToggleMargin);
auto control = addControl(object_ptr<Ui::Checkbox>(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<Ui::FlatLabel>(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<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights, const MTPChannelBannedRights &rights) : EditParticipantBox(nullptr, channel, user, hasAdminRights)
, _oldRights(rights) {
EditRestrictedBox::EditRestrictedBox(QWidget *, not_null<ChannelData *> channel, not_null<UserData *> 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<BoxContentDivider>(this), QMargins());
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_user_restrictions_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
addControl(object_ptr<Ui::FlatLabel>(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<Ui::Checkbox>(this, text, checked, st::rightsCheckbox, st::rightsToggle), st::rightsToggleMargin);
auto control = addControl(object_ptr<Ui::Checkbox>(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<BoxContentDivider>(this), st::rightsUntilMargin);
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_chat_banned_until_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_chat_banned_until_header),
Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel),
st::rightsHeaderMargin);
setRestrictUntil(_until);
//addControl(object_ptr<Ui::LinkButton>(this, lang(lng_rights_chat_banned_block), st::boxLinkButton));
// addControl(object_ptr<Ui::LinkButton>(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<Ui::Checkbox> changed) {
ApplyDependencies(_checkboxes, _dependencies, changed);
}
MTPChannelBannedRights EditRestrictedBox::DefaultRights(not_null<ChannelData*> 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<ChannelData *> 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<CalendarBox>(month, highlighted, [this](const QDate &date) { setRestrictUntil(static_cast<int>(QDateTime(date).toTime_t())); }), KeepOtherLayers);
_restrictUntilBox = Ui::show(
Box<CalendarBox>(month, highlighted,
[this](const QDate &date) { setRestrictUntil(static_cast<int>(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<Ui::Radiobutton>(this, _untilGroup, value, text, st::defaultBoxCheckbox), st::rightsToggleMargin));
_untilVariants.push_back(
addControl(object_ptr<Ui::Radiobutton>(this, _untilGroup, value, text, st::defaultBoxCheckbox),
st::rightsToggleMargin));
if (!canSave()) {
_untilVariants.back()->setDisabled(true);
}

View File

@ -34,22 +34,21 @@ class CalendarBox;
class EditParticipantBox : public BoxContent {
public:
EditParticipantBox(QWidget*, not_null<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights);
EditParticipantBox(QWidget *, not_null<ChannelData *> channel, not_null<UserData *> user, bool hasAdminRights);
protected:
void prepare() override;
void resizeToContent();
not_null<UserData*> user() const {
not_null<UserData *> user() const {
return _user;
}
not_null<ChannelData*> channel() const {
not_null<ChannelData *> channel() const {
return _channel;
}
template <typename Widget>
QPointer<Widget> addControl(object_ptr<Widget> widget, QMargins margin);
template <typename Widget> QPointer<Widget> addControl(object_ptr<Widget> widget, QMargins margin);
void removeControl(QPointer<TWidget> widget);
@ -58,18 +57,18 @@ protected:
}
private:
not_null<ChannelData*> _channel;
not_null<UserData*> _user;
not_null<ChannelData *> _channel;
not_null<UserData *> _user;
bool _hasAdminRights = false;
class Inner;
QPointer<Inner> _inner;
};
class EditAdminBox : public EditParticipantBox {
public:
EditAdminBox(QWidget*, not_null<ChannelData*> channel, not_null<UserData*> user, const MTPChannelAdminRights &rights);
EditAdminBox(QWidget *, not_null<ChannelData *> channel, not_null<UserData *> user,
const MTPChannelAdminRights &rights);
void setSaveCallback(base::lambda<void(MTPChannelAdminRights, MTPChannelAdminRights)> callback) {
_saveCallback = std::move(callback);
@ -82,7 +81,7 @@ private:
using Flag = MTPDchannelAdminRights::Flag;
using Flags = MTPDchannelAdminRights::Flags;
static MTPChannelAdminRights DefaultRights(not_null<ChannelData*> channel);
static MTPChannelAdminRights DefaultRights(not_null<ChannelData *> channel);
bool canSave() const {
return !!_saveCallback;
@ -96,7 +95,6 @@ private:
std::map<Flags, QPointer<Ui::Checkbox>> _checkboxes;
QPointer<Ui::FlatLabel> _aboutAddAdmins;
};
// Restricted box works with flags in the opposite way.
@ -104,7 +102,8 @@ private:
class EditRestrictedBox : public EditParticipantBox {
public:
EditRestrictedBox(QWidget*, not_null<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights, const MTPChannelBannedRights &rights);
EditRestrictedBox(QWidget *, not_null<ChannelData *> channel, not_null<UserData *> user, bool hasAdminRights,
const MTPChannelBannedRights &rights);
void setSaveCallback(base::lambda<void(MTPChannelBannedRights, MTPChannelBannedRights)> callback) {
_saveCallback = std::move(callback);
@ -117,7 +116,7 @@ private:
using Flag = MTPDchannelBannedRights::Flag;
using Flags = MTPDchannelBannedRights::Flags;
static MTPChannelBannedRights DefaultRights(not_null<ChannelData*> channel);
static MTPChannelBannedRights DefaultRights(not_null<ChannelData *> 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;
};

View File

@ -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<QString()> titleFactory, const std::vector<not_null<UserData*>> &selected);
void rowClicked(not_null<PeerListRow*> row) override;
PrivacyExceptionsBoxController(base::lambda<QString()> titleFactory,
const std::vector<not_null<UserData *>> &selected);
void rowClicked(not_null<PeerListRow *> row) override;
std::vector<not_null<UserData*>> getResult() const;
std::vector<not_null<UserData *>> getResult() const;
protected:
void prepareViewHook() override;
std::unique_ptr<Row> createRow(not_null<History*> history) override;
std::unique_ptr<Row> createRow(not_null<History *> history) override;
private:
base::lambda<QString()> _titleFactory;
std::vector<not_null<UserData*>> _selected;
std::vector<not_null<UserData *>> _selected;
};
PrivacyExceptionsBoxController::PrivacyExceptionsBoxController(base::lambda<QString()> titleFactory, const std::vector<not_null<UserData*>> &selected)
: _titleFactory(std::move(titleFactory))
, _selected(selected) {
}
PrivacyExceptionsBoxController::PrivacyExceptionsBoxController(base::lambda<QString()> titleFactory,
const std::vector<not_null<UserData *>> &selected)
: _titleFactory(std::move(titleFactory))
, _selected(selected) {}
void PrivacyExceptionsBoxController::prepareViewHook() {
delegate()->peerListSetTitle(_titleFactory);
delegate()->peerListAddSelectedRows(_selected);
}
std::vector<not_null<UserData*>> PrivacyExceptionsBoxController::getResult() const {
std::vector<not_null<UserData *>> PrivacyExceptionsBoxController::getResult() const {
auto peers = delegate()->peerListCollectSelectedRows();
auto users = std::vector<not_null<UserData*>>();
auto users = std::vector<not_null<UserData *>>();
if (!peers.empty()) {
users.reserve(peers.size());
for_const (auto peer, peers) {
@ -75,11 +75,12 @@ std::vector<not_null<UserData*>> PrivacyExceptionsBoxController::getResult() con
return users;
}
void PrivacyExceptionsBoxController::rowClicked(not_null<PeerListRow*> row) {
void PrivacyExceptionsBoxController::rowClicked(not_null<PeerListRow *> row) {
delegate()->peerListSetRowChecked(row, !row->checked());
}
std::unique_ptr<PrivacyExceptionsBoxController::Row> PrivacyExceptionsBoxController::createRow(not_null<History*> history) {
std::unique_ptr<PrivacyExceptionsBoxController::Row>
PrivacyExceptionsBoxController::createRow(not_null<History *> history) {
if (history->peer->isSelf()) {
return nullptr;
}
@ -91,10 +92,10 @@ std::unique_ptr<PrivacyExceptionsBoxController::Row> PrivacyExceptionsBoxControl
} // namespace
EditPrivacyBox::EditPrivacyBox(QWidget*, std::unique_ptr<Controller> 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> 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<PrivacyExceptionsBoxController>(base::lambda_guarded(this, [this, exception] {
return _controller->exceptionBoxTitle(exception);
}), exceptionUsers(exception));
auto initBox = [this, exception, controller = controller.get()](not_null<PeerListBox*> box) {
auto controller = std::make_unique<PrivacyExceptionsBoxController>(
base::lambda_guarded(this, [this, exception] { return _controller->exceptionBoxTitle(exception); }),
exceptionUsers(exception));
auto initBox = [this, exception, controller = controller.get()](not_null<PeerListBox *> 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<PeerListBox>(std::move(controller), std::move(initBox)), KeepOtherLayers);
@ -246,7 +247,7 @@ style::margins EditPrivacyBox::exceptionLinkMargins() const {
return st::editPrivacyLinkMargin;
}
std::vector<not_null<UserData*>> &EditPrivacyBox::exceptionUsers(Exception exception) {
std::vector<not_null<UserData *>> &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<Ui::LinkButton>(this, exceptionLinkText(exception)), exceptionLinkMargins(), [this] {
resizeGetHeight(width());
});
exceptionLink(exception).create(this, object_ptr<Ui::LinkButton>(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();
}

View File

@ -26,12 +26,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace Ui {
class FlatLabel;
class LinkButton;
template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
template <typename Widget>
class WidgetSlideWrap;
template <typename Enum> class RadioenumGroup;
template <typename Enum> class Radioenum;
template <typename Widget> 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> controller);
EditPrivacyBox(QWidget *, std::unique_ptr<Controller> controller);
protected:
void prepare() override;
@ -102,7 +98,7 @@ private:
void editExceptionUsers(Exception exception);
QString exceptionLinkText(Exception exception);
std::vector<not_null<UserData*>> &exceptionUsers(Exception exception);
std::vector<not_null<UserData *>> &exceptionUsers(Exception exception);
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> &exceptionLink(Exception exception);
std::unique_ptr<Controller> _controller;
@ -110,17 +106,16 @@ private:
std::shared_ptr<Ui::RadioenumGroup<Option>> _optionGroup;
object_ptr<Ui::FlatLabel> _loading;
object_ptr<Ui::FlatLabel> _description = { nullptr };
object_ptr<Ui::Radioenum<Option>> _everyone = { nullptr };
object_ptr<Ui::Radioenum<Option>> _contacts = { nullptr };
object_ptr<Ui::Radioenum<Option>> _nobody = { nullptr };
object_ptr<Ui::FlatLabel> _warning = { nullptr };
object_ptr<Ui::FlatLabel> _exceptionsTitle = { nullptr };
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _alwaysLink = { nullptr };
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _neverLink = { nullptr };
object_ptr<Ui::FlatLabel> _exceptionsDescription = { nullptr };
std::vector<not_null<UserData*>> _alwaysUsers;
std::vector<not_null<UserData*>> _neverUsers;
object_ptr<Ui::FlatLabel> _description = {nullptr};
object_ptr<Ui::Radioenum<Option>> _everyone = {nullptr};
object_ptr<Ui::Radioenum<Option>> _contacts = {nullptr};
object_ptr<Ui::Radioenum<Option>> _nobody = {nullptr};
object_ptr<Ui::FlatLabel> _warning = {nullptr};
object_ptr<Ui::FlatLabel> _exceptionsTitle = {nullptr};
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _alwaysLink = {nullptr};
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _neverLink = {nullptr};
object_ptr<Ui::FlatLabel> _exceptionsDescription = {nullptr};
std::vector<not_null<UserData *>> _alwaysUsers;
std::vector<not_null<UserData *>> _neverUsers;
};

View File

@ -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*> languages);
Inner(QWidget *parent, not_null<Languages *> languages);
void setSelected(int index);
void refresh();
@ -41,14 +41,14 @@ private:
void activateCurrent();
void languageChanged(int languageIndex);
not_null<Languages*> _languages;
not_null<Languages *> _languages;
std::shared_ptr<Ui::RadiobuttonGroup> _group;
std::vector<object_ptr<Ui::Radiobutton>> _buttons;
};
LanguageBox::Inner::Inner(QWidget *parent, not_null<Languages*> languages) : TWidget(parent)
, _languages(languages) {
LanguageBox::Inner::Inner(QWidget *parent, not_null<Languages *> languages)
: TWidget(parent)
, _languages(languages) {
_group = std::make_shared<Ui::RadiobuttonGroup>(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<Inner>(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);
}

View File

@ -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> _inner;
};

View File

@ -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) {

View File

@ -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;
};

View File

@ -29,15 +29,14 @@ void MuteSettingsBox::prepare() {
object_ptr<Ui::FlatLabel> 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<Ui::RadiobuttonGroup>(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(); });

View File

@ -14,15 +14,14 @@
class MuteSettingsBox : public BoxContent {
Q_OBJECT
public:
MuteSettingsBox(QWidget *parent, not_null<PeerData*> peer)
: _peer(peer) {
}
public:
MuteSettingsBox(QWidget *parent, not_null<PeerData *> peer)
: _peer(peer) {}
protected:
protected:
void prepare() override;
private:
not_null<PeerData*> _peer;
private:
not_null<PeerData *> _peer;
};
// vi: ts=4 tw=80

View File

@ -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<Notify::ScreenCorner>(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<int>(_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<int>(_overCorner)]) {
widget->hideFast();
}
for_const (auto widget, _cornerSamples[static_cast<int>(_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<SampleWidget>(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();
}

View File

@ -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<Ui::SettingsSlider> _countSlider;
QVector<SampleWidget*> _cornerSamples[4];
QVector<SampleWidget *> _cornerSamples[4];
};

View File

@ -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<InformBox>(text));
}
@ -319,9 +362,10 @@ void PasscodeBox::onSave(bool force) {
}
if (!_recoverEmail->isHidden() && email.isEmpty() && !force) {
_skipEmailWarning = true;
_replacedBy = Ui::show(Box<ConfirmBox>(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<ConfirmBox>(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);
}

View File

@ -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<Ui::LinkButton> _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<Ui::InputField> _recoverCode;
QString _error;
};

View File

@ -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<PeerListController> controller
, base::lambda<void(not_null<PeerListBox*>)> init)
: _controller(std::move(controller))
, _init(std::move(init))
{
PeerListBox::PeerListBox(QWidget *, std::unique_ptr<PeerListController> controller,
base::lambda<void(not_null<PeerListBox *>)> init)
: _controller(std::move(controller))
, _init(std::move(init)) {
Expects(_controller != nullptr);
}
@ -159,7 +157,7 @@ void PeerListBox::peerListAppendSearchRow(std::unique_ptr<PeerListRow> row) {
_inner->appendSearchRow(std::move(row));
}
void PeerListBox::peerListAppendFoundRow(not_null<PeerListRow*> row) {
void PeerListBox::peerListAppendFoundRow(not_null<PeerListRow *> row) {
_inner->appendFoundRow(row);
}
@ -167,7 +165,7 @@ void PeerListBox::peerListPrependRow(std::unique_ptr<PeerListRow> row) {
_inner->prependRow(std::move(row));
}
void PeerListBox::peerListPrependRowFromSearchResult(not_null<PeerListRow*> row) {
void PeerListBox::peerListPrependRowFromSearchResult(not_null<PeerListRow *> row) {
_inner->prependRowFromSearchResult(row);
}
@ -175,19 +173,19 @@ PeerListRow *PeerListBox::peerListFindRow(PeerListRowId id) {
return _inner->findRow(id);
}
void PeerListBox::peerListUpdateRow(not_null<PeerListRow*> row) {
void PeerListBox::peerListUpdateRow(not_null<PeerListRow *> row) {
_inner->updateRow(row);
}
void PeerListBox::peerListRemoveRow(not_null<PeerListRow*> row) {
void PeerListBox::peerListRemoveRow(not_null<PeerListRow *> row) {
_inner->removeRow(row);
}
void PeerListBox::peerListConvertRowToSearchResult(not_null<PeerListRow*> row) {
void PeerListBox::peerListConvertRowToSearchResult(not_null<PeerListRow *> row) {
_inner->convertRowToSearchResult(row);
}
void PeerListBox::peerListSetRowChecked(not_null<PeerListRow*> row, bool checked) {
void PeerListBox::peerListSetRowChecked(not_null<PeerListRow *> 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<PeerListRow*> PeerListBox::peerListRowAt(int index) {
not_null<PeerListRow *> PeerListBox::peerListRowAt(int index) {
return _inner->rowAt(index);
}
@ -251,21 +249,18 @@ void PeerListBox::peerListSetSearchMode(PeerListSearchMode mode) {
void PeerListBox::peerListSortRows(base::lambda<bool(PeerListRow &a, PeerListRow &b)> 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<bool(PeerListRow &a)> border) {
_inner->reorderRows([border = std::move(border)](auto &&begin, auto &&end) {
std::stable_partition(begin, end, [border](auto &&current) {
return border(*current);
});
std::stable_partition(begin, end, [border](auto &&current) { return border(*current); });
});
}
PeerListController::PeerListController(std::unique_ptr<PeerListSearchController> searchController) : _searchController(std::move(searchController)) {
PeerListController::PeerListController(std::unique_ptr<PeerListSearchController> 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<PeerData*> peer) {
void PeerListController::peerListSearchAddRow(not_null<PeerData *> 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<PeerData*> peer, PeerListRow::SetStyle style) {
void PeerListBox::addSelectItem(not_null<PeerData *> peer, PeerListRow::SetStyle style) {
if (!_select) {
createMultiSelect();
_select->toggleFast(false);
@ -326,7 +321,8 @@ void PeerListBox::addSelectItem(not_null<PeerData*> 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<PeerData*> peer) {
bool PeerListBox::peerListIsRowSelected(not_null<PeerData *> peer) {
return _select ? _select->entity()->hasItem(peer->id) : false;
}
@ -343,27 +339,24 @@ int PeerListBox::peerListSelectedRowsCount() {
return _select ? _select->entity()->getItemsCount() : 0;
}
std::vector<not_null<PeerData*>> PeerListBox::peerListCollectSelectedRows() {
auto result = std::vector<not_null<PeerData*>> {};
auto items = _select ? _select->entity()->getItems() : QVector<quint64> {};
std::vector<not_null<PeerData *>> PeerListBox::peerListCollectSelectedRows() {
auto result = std::vector<not_null<PeerData *>>{};
auto items = _select ? _select->entity()->getItems() : QVector<quint64>{};
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<PeerData*> peer) : PeerListRow(peer, peer->id) {
}
PeerListRow::PeerListRow(not_null<PeerData *> peer)
: PeerListRow(peer, peer->id) {}
PeerListRow::PeerListRow(not_null<PeerData*> peer, PeerListRowId id)
: _id(id)
, _peer(peer)
, _initialized(false)
, _isSearchResult(false) {
}
PeerListRow::PeerListRow(not_null<PeerData *> 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<void()> updateCallback) {
_checkbox = std::make_unique<Ui::RoundImageCheckbox>(st::contactsPhotoCheckbox, std::move(updateCallback), PaintUserpicCallback(_peer));
_checkbox = std::make_unique<Ui::RoundImageCheckbox>(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<PeerListController*> controller) : TWidget(parent)
, _controller(controller)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) {
PeerListBox::Inner::Inner(QWidget *parent, not_null<PeerListController *> 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<PeerListRow> row) {
}
}
void PeerListBox::Inner::appendFoundRow(not_null<PeerListRow*> row) {
void PeerListBox::Inner::appendFoundRow(not_null<PeerListRow *> row) {
Expects(showingSearch());
auto index = findRowIndex(row);
if (index.value < 0) {
@ -574,13 +570,11 @@ void PeerListBox::Inner::appendFoundRow(not_null<PeerListRow*> row) {
}
}
void PeerListBox::Inner::changeCheckState(not_null<PeerListRow*> row, bool checked, PeerListRow::SetStyle style) {
row->setChecked(checked, style, [this, row] {
updateRow(row);
});
void PeerListBox::Inner::changeCheckState(not_null<PeerListRow *> row, bool checked, PeerListRow::SetStyle style) {
row->setChecked(checked, style, [this, row] { updateRow(row); });
}
void PeerListBox::Inner::addRowEntry(not_null<PeerListRow*> row) {
void PeerListBox::Inner::addRowEntry(not_null<PeerListRow *> 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<PeerListRow*> row) {
void PeerListBox::Inner::addToSearchIndex(not_null<PeerListRow *> 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<PeerListRow*> row) {
void PeerListBox::Inner::removeFromSearchIndex(not_null<PeerListRow *> 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<PeerListRow> row) {
}
}
void PeerListBox::Inner::prependRowFromSearchResult(not_null<PeerListRow*> row) {
void PeerListBox::Inner::prependRowFromSearchResult(not_null<PeerListRow *> 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<PeerListRow*> row) {
void PeerListBox::Inner::removeRow(not_null<PeerListRow *> row) {
auto index = row->absoluteIndex();
auto isSearchResult = row->isSearchResult();
auto &eraseFrom = isSearchResult ? _searchRows : _rows;
@ -700,7 +692,7 @@ void PeerListBox::Inner::removeRow(not_null<PeerListRow*> row) {
restoreSelection();
}
void PeerListBox::Inner::convertRowToSearchResult(not_null<PeerListRow*> row) {
void PeerListBox::Inner::convertRowToSearchResult(not_null<PeerListRow *> row) {
if (row->isSearchResult()) {
return;
} else if (!showingSearch() || !_controller->hasComplexSearch()) {
@ -721,7 +713,7 @@ int PeerListBox::Inner::fullRowsCount() const {
return _rows.size();
}
not_null<PeerListRow*> PeerListBox::Inner::rowAt(int index) const {
not_null<PeerListRow *> 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<Ui::FlatLabel>(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout));
setSearchLoading(object_ptr<Ui::FlatLabel>(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<PeerListRow*> row) {
enumerateShownRows([&firstEnabled, &lastEnabled, &index](not_null<PeerListRow *> 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<not_null<PeerListRow*>>*)nullptr;
auto minimalList = (const std::vector<not_null<PeerListRow *>> *)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<PeerListRow*> row, RowIndex index) const {
QRect PeerListBox::Inner::getActionRect(not_null<PeerListRow *> 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<PeerListRow*> row, RowIndex hint) {
void PeerListBox::Inner::updateRow(not_null<PeerListRow *> row, RowIndex hint) {
updateRow(findRowIndex(row, hint));
}
@ -1248,13 +1242,11 @@ void PeerListBox::Inner::updateRow(RowIndex index) {
update(0, getRowTop(index), width(), _rowHeight);
}
template <typename Callback>
bool PeerListBox::Inner::enumerateShownRows(Callback callback) {
template <typename Callback> bool PeerListBox::Inner::enumerateShownRows(Callback callback) {
return enumerateShownRows(0, shownRowsCount(), std::move(callback));
}
template <typename Callback>
bool PeerListBox::Inner::enumerateShownRows(int from, int to, Callback callback) {
template <typename Callback> 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<PeerListRow*> row, RowIndex hint) {
PeerListBox::Inner::RowIndex PeerListBox::Inner::findRowIndex(not_null<PeerListRow *> row, RowIndex hint) {
if (!showingSearch()) {
Assert(!row->isSearchResult());
return RowIndex(row->absoluteIndex());

View File

@ -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 <typename Widget>
class WidgetSlideWrap;
template <typename Widget> class WidgetSlideWrap;
class FlatLabel;
} // namespace Ui
@ -46,8 +45,8 @@ inline auto PaintUserpicCallback(PeerData *peer) {
using PeerListRowId = quint64;
class PeerListRow {
public:
PeerListRow(not_null<PeerData*> peer);
PeerListRow(not_null<PeerData*> peer, PeerListRowId id);
PeerListRow(not_null<PeerData *> peer);
PeerListRow(not_null<PeerData *> 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<PeerData*> peer() const {
not_null<PeerData *> 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<void()> 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<void()> 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 <typename UpdateCallback>
void setChecked(bool checked, SetStyle style, UpdateCallback callback) {
template <typename UpdateCallback> void setChecked(bool checked, SetStyle style, UpdateCallback callback) {
if (checked && !_checkbox) {
createCheckbox(std::move(callback));
}
@ -134,8 +129,7 @@ public:
}
void invalidatePixmapsCache();
template <typename UpdateCallback>
void addRipple(QSize size, QPoint point, UpdateCallback updateCallback);
template <typename UpdateCallback> 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<PeerData*> _peer;
not_null<PeerData *> _peer;
std::unique_ptr<Ui::RippleAnimation> _ripple;
std::unique_ptr<Ui::RoundImageCheckbox> _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<PeerListRow> row) = 0;
virtual void peerListAppendSearchRow(std::unique_ptr<PeerListRow> row) = 0;
virtual void peerListAppendFoundRow(not_null<PeerListRow*> row) = 0;
virtual void peerListAppendFoundRow(not_null<PeerListRow *> row) = 0;
virtual void peerListPrependRow(std::unique_ptr<PeerListRow> row) = 0;
virtual void peerListPrependRowFromSearchResult(not_null<PeerListRow*> row) = 0;
virtual void peerListUpdateRow(not_null<PeerListRow*> row) = 0;
virtual void peerListRemoveRow(not_null<PeerListRow*> row) = 0;
virtual void peerListConvertRowToSearchResult(not_null<PeerListRow*> row) = 0;
virtual bool peerListIsRowSelected(not_null<PeerData*> peer) = 0;
virtual void peerListSetRowChecked(not_null<PeerListRow*> row, bool checked) = 0;
virtual not_null<PeerListRow*> peerListRowAt(int index) = 0;
virtual void peerListPrependRowFromSearchResult(not_null<PeerListRow *> row) = 0;
virtual void peerListUpdateRow(not_null<PeerListRow *> row) = 0;
virtual void peerListRemoveRow(not_null<PeerListRow *> row) = 0;
virtual void peerListConvertRowToSearchResult(not_null<PeerListRow *> row) = 0;
virtual bool peerListIsRowSelected(not_null<PeerData *> peer) = 0;
virtual void peerListSetRowChecked(not_null<PeerListRow *> row, bool checked) = 0;
virtual not_null<PeerListRow *> 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<bool(PeerListRow &a, PeerListRow &b)> compare) = 0;
virtual void peerListPartitionRows(base::lambda<bool(PeerListRow &a)> border) = 0;
template <typename PeerDataRange>
void peerListAddSelectedRows(PeerDataRange &&range) {
template <typename PeerDataRange> void peerListAddSelectedRows(PeerDataRange &&range) {
for (auto peer : range) {
peerListAddSelectedRowInBunch(peer);
}
@ -218,21 +210,19 @@ public:
}
virtual int peerListSelectedRowsCount() = 0;
virtual std::vector<not_null<PeerData*>> peerListCollectSelectedRows() = 0;
virtual std::vector<not_null<PeerData *>> peerListCollectSelectedRows() = 0;
virtual ~PeerListDelegate() = default;
private:
virtual void peerListAddSelectedRowInBunch(not_null<PeerData*> peer) = 0;
virtual void peerListAddSelectedRowInBunch(not_null<PeerData *> peer) = 0;
virtual void peerListFinishSelectedRowsBunch() = 0;
};
class PeerListSearchDelegate {
public:
virtual void peerListSearchAddRow(not_null<PeerData*> peer) = 0;
virtual void peerListSearchAddRow(not_null<PeerData *> 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<PeerListSearchDelegate*> delegate) {
void setDelegate(not_null<PeerListSearchDelegate *> delegate) {
_delegate = delegate;
}
protected:
not_null<PeerListSearchDelegate*> delegate() const {
not_null<PeerListSearchDelegate *> 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<PeerListSearchController> searchController = nullptr);
void setDelegate(not_null<PeerListDelegate*> delegate) {
void setDelegate(not_null<PeerListDelegate *> delegate) {
_delegate = delegate;
prepare();
}
virtual void prepare() = 0;
virtual void rowClicked(not_null<PeerListRow*> row) = 0;
virtual void rowActionClicked(not_null<PeerListRow*> row) {
}
virtual void loadMoreRows() {
}
virtual void itemDeselectedHook(not_null<PeerData*> peer) {
}
virtual void rowClicked(not_null<PeerListRow *> row) = 0;
virtual void rowActionClicked(not_null<PeerListRow *> row) {}
virtual void loadMoreRows() {}
virtual void itemDeselectedHook(not_null<PeerData *> peer) {}
bool isSearchLoading() const {
return _searchController ? _searchController->isLoading() : false;
}
virtual std::unique_ptr<PeerListRow> createSearchRow(not_null<PeerData*> peer) {
virtual std::unique_ptr<PeerListRow> createSearchRow(not_null<PeerData *> peer) {
return nullptr;
}
bool isRowSelected(not_null<PeerData*> peer) {
bool isRowSelected(not_null<PeerData *> peer) {
return delegate()->peerListIsRowSelected(peer);
}
@ -291,13 +277,13 @@ public:
bool hasComplexSearch() const;
void search(const QString &query);
void peerListSearchAddRow(not_null<PeerData*> peer) override;
void peerListSearchAddRow(not_null<PeerData *> peer) override;
void peerListSearchRefreshRows() override;
virtual ~PeerListController() = default;
protected:
not_null<PeerListDelegate*> delegate() const {
not_null<PeerListDelegate *> delegate() const {
return _delegate;
}
PeerListSearchController *searchController() const {
@ -320,12 +306,12 @@ protected:
private:
PeerListDelegate *_delegate = nullptr;
std::unique_ptr<PeerListSearchController> _searchController = nullptr;
};
class PeerListBox : public BoxContent, public PeerListDelegate {
public:
PeerListBox(QWidget*, std::unique_ptr<PeerListController> controller, base::lambda<void(not_null<PeerListBox*>)> init);
PeerListBox(QWidget *, std::unique_ptr<PeerListController> controller,
base::lambda<void(not_null<PeerListBox *>)> init);
void peerListSetTitle(base::lambda<QString()> title) override {
setTitle(std::move(title));
@ -340,17 +326,17 @@ public:
void peerListSetSearchMode(PeerListSearchMode mode) override;
void peerListAppendRow(std::unique_ptr<PeerListRow> row) override;
void peerListAppendSearchRow(std::unique_ptr<PeerListRow> row) override;
void peerListAppendFoundRow(not_null<PeerListRow*> row) override;
void peerListAppendFoundRow(not_null<PeerListRow *> row) override;
void peerListPrependRow(std::unique_ptr<PeerListRow> row) override;
void peerListPrependRowFromSearchResult(not_null<PeerListRow*> row) override;
void peerListUpdateRow(not_null<PeerListRow*> row) override;
void peerListRemoveRow(not_null<PeerListRow*> row) override;
void peerListConvertRowToSearchResult(not_null<PeerListRow*> row) override;
void peerListSetRowChecked(not_null<PeerListRow*> row, bool checked) override;
not_null<PeerListRow*> peerListRowAt(int index) override;
bool peerListIsRowSelected(not_null<PeerData*> peer) override;
void peerListPrependRowFromSearchResult(not_null<PeerListRow *> row) override;
void peerListUpdateRow(not_null<PeerListRow *> row) override;
void peerListRemoveRow(not_null<PeerListRow *> row) override;
void peerListConvertRowToSearchResult(not_null<PeerListRow *> row) override;
void peerListSetRowChecked(not_null<PeerListRow *> row, bool checked) override;
not_null<PeerListRow *> peerListRowAt(int index) override;
bool peerListIsRowSelected(not_null<PeerData *> peer) override;
int peerListSelectedRowsCount() override;
std::vector<not_null<PeerData*>> peerListCollectSelectedRows() override;
std::vector<not_null<PeerData *>> 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<PeerData*> peer) override {
void peerListAddSelectedRowInBunch(not_null<PeerData *> peer) override {
addSelectItem(peer, PeerListRow::SetStyle::Fast);
}
void peerListFinishSelectedRowsBunch() override;
void addSelectItem(not_null<PeerData*> peer, PeerListRow::SetStyle style);
void addSelectItem(not_null<PeerData *> peer, PeerListRow::SetStyle style);
void createMultiSelect();
int getTopScrollSkip() const;
void updateScrollSkips();
void searchQueryChanged(const QString &query);
object_ptr<Ui::WidgetSlideWrap<Ui::MultiSelect>> _select = { nullptr };
object_ptr<Ui::WidgetSlideWrap<Ui::MultiSelect>> _select = {nullptr};
class Inner;
QPointer<Inner> _inner;
std::unique_ptr<PeerListController> _controller;
base::lambda<void(PeerListBox*)> _init;
base::lambda<void(PeerListBox *)> _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<PeerListController*> controller);
Inner(QWidget *parent, not_null<PeerListController *> 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<PeerListRow> row);
void appendSearchRow(std::unique_ptr<PeerListRow> row);
void appendFoundRow(not_null<PeerListRow*> row);
void appendFoundRow(not_null<PeerListRow *> row);
void prependRow(std::unique_ptr<PeerListRow> row);
void prependRowFromSearchResult(not_null<PeerListRow*> row);
void prependRowFromSearchResult(not_null<PeerListRow *> row);
PeerListRow *findRow(PeerListRowId id);
void updateRow(not_null<PeerListRow*> row) {
void updateRow(not_null<PeerListRow *> row) {
updateRow(row, RowIndex());
}
void removeRow(not_null<PeerListRow*> row);
void convertRowToSearchResult(not_null<PeerListRow*> row);
void removeRow(not_null<PeerListRow *> row);
void convertRowToSearchResult(not_null<PeerListRow *> row);
int fullRowsCount() const;
not_null<PeerListRow*> rowAt(int index) const;
not_null<PeerListRow *> rowAt(int index) const;
void setDescription(object_ptr<Ui::FlatLabel> description);
void setSearchLoading(object_ptr<Ui::FlatLabel> loading);
void setSearchNoResults(object_ptr<Ui::FlatLabel> noResults);
@ -427,10 +412,9 @@ public:
void refreshRows();
void setSearchMode(PeerListSearchMode mode);
void changeCheckState(not_null<PeerListRow*> row, bool checked, PeerListRow::SetStyle style);
void changeCheckState(not_null<PeerListRow *> row, bool checked, PeerListRow::SetStyle style);
template <typename ReorderCallback>
void reorderRows(ReorderCallback &&callback) {
template <typename ReorderCallback> 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<PeerListRow*> row, RowIndex hint);
void updateRow(not_null<PeerListRow *> row, RowIndex hint);
void updateRow(RowIndex row);
int getRowTop(RowIndex row) const;
PeerListRow *getRow(RowIndex element);
RowIndex findRowIndex(not_null<PeerListRow*> row, RowIndex hint = RowIndex());
QRect getActionRect(not_null<PeerListRow*> row, RowIndex index) const;
RowIndex findRowIndex(not_null<PeerListRow *> row, RowIndex hint = RowIndex());
QRect getActionRect(not_null<PeerListRow *> row, RowIndex index) const;
void paintRow(Painter &p, TimeMs ms, RowIndex index);
void addRowEntry(not_null<PeerListRow*> row);
void addToSearchIndex(not_null<PeerListRow*> row);
void addRowEntry(not_null<PeerListRow *> row);
void addToSearchIndex(not_null<PeerListRow *> row);
bool addingToSearchIndex() const;
void removeFromSearchIndex(not_null<PeerListRow*> row);
void removeFromSearchIndex(not_null<PeerListRow *> 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 <typename Callback>
bool enumerateShownRows(Callback callback);
template <typename Callback>
bool enumerateShownRows(int from, int to, Callback callback);
template <typename Callback> bool enumerateShownRows(Callback callback);
template <typename Callback> bool enumerateShownRows(int from, int to, Callback callback);
int rowsTop() const;
int labelHeight() const;
void clearSearchRows();
not_null<PeerListController*> _controller;
not_null<PeerListController *> _controller;
PeerListSearchMode _searchMode = PeerListSearchMode::Disabled;
int _rowHeight = 0;
@ -541,23 +523,22 @@ private:
bool _mouseSelection = false;
std::vector<std::unique_ptr<PeerListRow>> _rows;
std::map<PeerListRowId, not_null<PeerListRow*>> _rowsById;
std::map<PeerData*, std::vector<not_null<PeerListRow*>>> _rowsByPeer;
std::map<PeerListRowId, not_null<PeerListRow *>> _rowsById;
std::map<PeerData *, std::vector<not_null<PeerListRow *>>> _rowsByPeer;
std::map<QChar, std::vector<not_null<PeerListRow*>>> _searchIndex;
std::map<QChar, std::vector<not_null<PeerListRow *>>> _searchIndex;
QString _searchQuery;
QString _normalizedSearchQuery;
QString _mentionHighlight;
std::vector<not_null<PeerListRow*>> _filterResults;
std::vector<not_null<PeerListRow *>> _filterResults;
int _aboveHeight = 0;
object_ptr<TWidget> _aboveWidget = { nullptr };
object_ptr<Ui::FlatLabel> _description = { nullptr };
object_ptr<Ui::FlatLabel> _searchNoResults = { nullptr };
object_ptr<Ui::FlatLabel> _searchLoading = { nullptr };
object_ptr<TWidget> _aboveWidget = {nullptr};
object_ptr<Ui::FlatLabel> _description = {nullptr};
object_ptr<Ui::FlatLabel> _searchNoResults = {nullptr};
object_ptr<Ui::FlatLabel> _searchLoading = {nullptr};
QPoint _lastMousePosition;
std::vector<std::unique_ptr<PeerListRow>> _searchRows;
};

View File

@ -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<not_null<UserData*>> GetAlreadyInFromPeer(PeerData *peer) {
base::flat_set<not_null<UserData *>> 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<not_null<UserData*>> 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<not_null<UserData*>> 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<bool> 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<PeerListSearchController> searchController) : PeerListController(std::move(searchController)) {
}
ChatsListBoxController::ChatsListBoxController(std::unique_ptr<PeerListSearchController> 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<Row&>(a).history();
auto history = static_cast<Row &>(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<PeerListRow> ChatsListBoxController::createSearchRow(not_null<PeerData*> peer) {
std::unique_ptr<PeerListRow> ChatsListBoxController::createSearchRow(not_null<PeerData *> peer) {
return createRow(App::history(peer));
}
bool ChatsListBoxController::appendRow(not_null<History*> history) {
bool ChatsListBoxController::appendRow(not_null<History *> history) {
if (auto row = delegate()->peerListFindRow(history->peer->id)) {
updateRowHook(static_cast<Row*>(row));
updateRowHook(static_cast<Row *>(row));
return false;
}
if (auto row = createRow(history)) {
@ -282,8 +277,8 @@ bool ChatsListBoxController::appendRow(not_null<History*> history) {
return false;
}
ContactsBoxController::ContactsBoxController(std::unique_ptr<PeerListSearchController> searchController) : PeerListController(std::move(searchController)) {
}
ContactsBoxController::ContactsBoxController(std::unique_ptr<PeerListSearchController> 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<PeerListRow> ContactsBoxController::createSearchRow(not_null<PeerData*> peer) {
std::unique_ptr<PeerListRow> ContactsBoxController::createSearchRow(not_null<PeerData *> peer) {
if (auto user = peer->asUser()) {
return createRow(user);
}
return nullptr;
}
void ContactsBoxController::rowClicked(not_null<PeerListRow*> row) {
void ContactsBoxController::rowClicked(not_null<PeerListRow *> row) {
Ui::showPeerHistory(row->peer(), ShowAtUnreadMsgId);
}
bool ContactsBoxController::appendRow(not_null<UserData*> user) {
bool ContactsBoxController::appendRow(not_null<UserData *> user) {
if (auto row = delegate()->peerListFindRow(user->id)) {
updateRowHook(row);
return false;
@ -351,25 +344,22 @@ bool ContactsBoxController::appendRow(not_null<UserData*> user) {
return false;
}
std::unique_ptr<PeerListRow> ContactsBoxController::createRow(not_null<UserData*> user) {
std::unique_ptr<PeerListRow> ContactsBoxController::createRow(not_null<UserData *> user) {
return std::make_unique<PeerListRow>(user);
}
AddParticipantsBoxController::AddParticipantsBoxController(PeerData *peer)
: ContactsBoxController(std::make_unique<PeerListGlobalSearchController>())
, _peer(peer)
, _alreadyIn(GetAlreadyInFromPeer(peer)) {
}
: ContactsBoxController(std::make_unique<PeerListGlobalSearchController>())
, _peer(peer)
, _alreadyIn(GetAlreadyInFromPeer(peer)) {}
AddParticipantsBoxController::AddParticipantsBoxController(
not_null<ChannelData*> channel,
base::flat_set<not_null<UserData*>> &&alreadyIn)
: ContactsBoxController(std::make_unique<PeerListGlobalSearchController>())
, _peer(channel)
, _alreadyIn(std::move(alreadyIn)) {
}
AddParticipantsBoxController::AddParticipantsBoxController(not_null<ChannelData *> channel,
base::flat_set<not_null<UserData *>> &&alreadyIn)
: ContactsBoxController(std::make_unique<PeerListGlobalSearchController>())
, _peer(channel)
, _alreadyIn(std::move(alreadyIn)) {}
void AddParticipantsBoxController::rowClicked(not_null<PeerListRow*> row) {
void AddParticipantsBoxController::rowClicked(not_null<PeerListRow *> 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<PeerListRow*> row) {
Ui::show(Box<MaxInviteBox>(_peer->asChannel()), KeepOtherLayers);
}
} else if (count >= Global::ChatSizeMax() && count < Global::MegagroupSizeMax()) {
Ui::show(Box<InformBox>(lng_profile_add_more_after_upgrade(lt_count, Global::MegagroupSizeMax())), KeepOtherLayers);
Ui::show(Box<InformBox>(lng_profile_add_more_after_upgrade(lt_count, Global::MegagroupSizeMax())),
KeepOtherLayers);
}
}
void AddParticipantsBoxController::itemDeselectedHook(not_null<PeerData*> peer) {
void AddParticipantsBoxController::itemDeselectedHook(not_null<PeerData *> peer) {
updateTitle();
}
@ -404,15 +395,15 @@ int AddParticipantsBoxController::alreadyInCount() const {
Unexpected("User in AddParticipantsBoxController::alreadyInCount");
}
bool AddParticipantsBoxController::isAlreadyIn(not_null<UserData*> user) const {
bool AddParticipantsBoxController::isAlreadyIn(not_null<UserData *> 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<PeerListRow> AddParticipantsBoxController::createRow(not_null<UserData*> user) {
std::unique_ptr<PeerListRow> AddParticipantsBoxController::createRow(not_null<UserData *> user) {
if (user->isSelf()) {
return nullptr;
}
@ -433,19 +424,19 @@ std::unique_ptr<PeerListRow> AddParticipantsBoxController::createRow(not_null<Us
}
void AddParticipantsBoxController::updateTitle() {
auto additional = (_peer && _peer->isChannel() && !_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<ChatData*> chat) {
auto initBox = [chat](not_null<PeerListBox*> box) {
void AddParticipantsBoxController::Start(not_null<ChatData *> chat) {
auto initBox = [chat](not_null<PeerListBox *> box) {
box->addButton(langFactory(lng_participant_invite), [box, chat] {
auto rows = box->peerListCollectSelectedRows();
if (!rows.empty()) {
auto users = std::vector<not_null<UserData*>>();
auto users = std::vector<not_null<UserData *>>();
for (auto peer : rows) {
auto user = peer->asUser();
Assert(user != nullptr);
@ -461,16 +452,14 @@ void AddParticipantsBoxController::Start(not_null<ChatData*> chat) {
Ui::show(Box<PeerListBox>(std::make_unique<AddParticipantsBoxController>(chat), std::move(initBox)));
}
void AddParticipantsBoxController::Start(
not_null<ChannelData*> channel,
base::flat_set<not_null<UserData*>> &&alreadyIn,
bool justCreated) {
auto initBox = [channel, justCreated](not_null<PeerListBox*> box) {
void AddParticipantsBoxController::Start(not_null<ChannelData *> channel,
base::flat_set<not_null<UserData *>> &&alreadyIn, bool justCreated) {
auto initBox = [channel, justCreated](not_null<PeerListBox *> box) {
auto subscription = std::make_shared<base::Subscription>();
box->addButton(langFactory(lng_participant_invite), [box, channel, subscription] {
auto rows = box->peerListCollectSelectedRows();
if (!rows.empty()) {
auto users = std::vector<not_null<UserData*>>();
auto users = std::vector<not_null<UserData *>>();
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<PeerListBox>(std::make_unique<AddParticipantsBoxController>(channel, std::move(alreadyIn)), std::move(initBox)));
Ui::show(Box<PeerListBox>(std::make_unique<AddParticipantsBoxController>(channel, std::move(alreadyIn)),
std::move(initBox)));
}
void AddParticipantsBoxController::Start(
not_null<ChannelData*> channel,
base::flat_set<not_null<UserData*>> &&alreadyIn) {
void AddParticipantsBoxController::Start(not_null<ChannelData *> channel,
base::flat_set<not_null<UserData *>> &&alreadyIn) {
Start(channel, std::move(alreadyIn), false);
}
void AddParticipantsBoxController::Start(not_null<ChannelData*> channel) {
void AddParticipantsBoxController::Start(not_null<ChannelData *> 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<ChatData*> chat)
: PeerListController()
, _chat(chat) {
}
EditChatAdminsBoxController::EditChatAdminsBoxController(not_null<ChatData *> 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<LabeledCheckbox>(nullptr, lang(lng_chat_all_members_admins), !_chat->adminsEnabled(), st::defaultBoxCheckbox);
auto checkbox = object_ptr<LabeledCheckbox>(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<not_null<UserData*>>();
auto admins = std::vector<not_null<UserData *>>();
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<UserData*> user) {
auto addOne = [this](not_null<UserData *> user) {
if (auto row = createRow(user)) {
delegate()->peerListAppendRow(std::move(row));
}
@ -655,7 +634,7 @@ void EditChatAdminsBoxController::rebuildRows() {
delegate()->peerListRefreshRows();
}
std::unique_ptr<PeerListRow> EditChatAdminsBoxController::createRow(not_null<UserData*> user) {
std::unique_ptr<PeerListRow> EditChatAdminsBoxController::createRow(not_null<UserData *> user) {
auto result = std::make_unique<PeerListRow>(user);
if (allAreAdmins() || user->id == peerFromUser(_chat->creator)) {
result->setDisabledState(PeerListRow::State::DisabledChecked);
@ -663,23 +642,23 @@ std::unique_ptr<PeerListRow> EditChatAdminsBoxController::createRow(not_null<Use
return result;
}
void EditChatAdminsBoxController::rowClicked(not_null<PeerListRow*> row) {
void EditChatAdminsBoxController::rowClicked(not_null<PeerListRow *> row) {
delegate()->peerListSetRowChecked(row, !row->checked());
}
void EditChatAdminsBoxController::Start(not_null<ChatData*> chat) {
void EditChatAdminsBoxController::Start(not_null<ChatData *> chat) {
auto controller = std::make_unique<EditChatAdminsBoxController>(chat);
auto initBox = [chat, controller = controller.get()](not_null<PeerListBox*> box) {
auto initBox = [chat, controller = controller.get()](not_null<PeerListBox *> box) {
box->addButton(langFactory(lng_settings_save), [box, chat, controller] {
auto rows = box->peerListCollectSelectedRows();
auto users = std::vector<not_null<UserData*>>();
auto users = std::vector<not_null<UserData *>>();
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<ChatData*> chat) {
Ui::show(Box<PeerListBox>(std::move(controller), std::move(initBox)));
}
void AddBotToGroupBoxController::Start(not_null<UserData*> bot) {
auto initBox = [bot](not_null<PeerListBox*> box) {
void AddBotToGroupBoxController::Start(not_null<UserData *> bot) {
auto initBox = [bot](not_null<PeerListBox *> box) {
box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); });
};
Ui::show(Box<PeerListBox>(std::make_unique<AddBotToGroupBoxController>(bot), std::move(initBox)));
}
AddBotToGroupBoxController::AddBotToGroupBoxController(not_null<UserData*> bot)
: ChatsListBoxController(SharingBotGame(bot)
? std::make_unique<PeerListGlobalSearchController>()
: nullptr)
, _bot(bot) {
}
AddBotToGroupBoxController::AddBotToGroupBoxController(not_null<UserData *> bot)
: ChatsListBoxController(SharingBotGame(bot) ? std::make_unique<PeerListGlobalSearchController>() : nullptr)
, _bot(bot) {}
void AddBotToGroupBoxController::rowClicked(not_null<PeerListRow*> row) {
void AddBotToGroupBoxController::rowClicked(not_null<PeerListRow *> row) {
if (sharingBotGame()) {
shareBotGame(row->peer());
} else {
@ -709,7 +685,7 @@ void AddBotToGroupBoxController::rowClicked(not_null<PeerListRow*> row) {
}
}
void AddBotToGroupBoxController::shareBotGame(not_null<PeerData*> chat) {
void AddBotToGroupBoxController::shareBotGame(not_null<PeerData *> 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<PeerData*> chat) {
auto afterRequestId = history ? history->sendRequestId : 0;
auto randomId = rand_value<quint64>();
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<PeerData*> chat) {
Ui::show(Box<ConfirmBox>(confirmText(), send), KeepOtherLayers);
}
void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData *> chat) {
if (auto megagroup = chat->asMegagroup()) {
if (!megagroup->canAddMembers()) {
Ui::show(Box<InformBox>(lang(lng_error_cant_add_member)), KeepOtherLayers);
@ -761,26 +730,16 @@ void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
}
if (auto &info = bot->botInfo) {
if (!info->startGroupToken.isEmpty()) {
auto request = MTPmessages_StartBot(
bot->inputUser,
chat->input,
MTP_long(rand_value<quint64>()),
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<quint64>()),
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<PeerData*> chat) {
Ui::show(Box<ConfirmBox>(confirmText, send), KeepOtherLayers);
}
std::unique_ptr<ChatsListBoxController::Row> AddBotToGroupBoxController::createRow(not_null<History*> history) {
std::unique_ptr<ChatsListBoxController::Row> AddBotToGroupBoxController::createRow(not_null<History *> history) {
if (!needToCreateRow(history->peer)) {
return nullptr;
}
return std::make_unique<Row>(history);
}
bool AddBotToGroupBoxController::needToCreateRow(not_null<PeerData*> peer) const {
bool AddBotToGroupBoxController::needToCreateRow(not_null<PeerData *> peer) const {
if (sharingBotGame()) {
if (!peer->canWrite()) {
return false;
@ -818,7 +777,7 @@ bool AddBotToGroupBoxController::needToCreateRow(not_null<PeerData*> peer) const
return false;
}
bool AddBotToGroupBoxController::SharingBotGame(not_null<UserData*> bot) {
bool AddBotToGroupBoxController::SharingBotGame(not_null<UserData *> 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(); });
}

View File

@ -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<QString, MTPcontacts_Found> _cache;
std::map<mtpRequestId, QString> _queries;
};
class ChatsListBoxController : public PeerListController, protected base::Subscriber {
public:
ChatsListBoxController(std::unique_ptr<PeerListSearchController> searchController = std::make_unique<PeerListGlobalSearchController>());
ChatsListBoxController(std::unique_ptr<PeerListSearchController> searchController =
std::make_unique<PeerListGlobalSearchController>());
void prepare() override final;
std::unique_ptr<PeerListRow> createSearchRow(not_null<PeerData*> peer) override final;
std::unique_ptr<PeerListRow> createSearchRow(not_null<PeerData *> peer) override final;
protected:
class Row : public PeerListRow {
public:
Row(not_null<History*> history) : PeerListRow(history->peer), _history(history) {
}
not_null<History*> history() const {
Row(not_null<History *> history)
: PeerListRow(history->peer)
, _history(history) {}
not_null<History *> history() const {
return _history;
}
private:
not_null<History*> _history;
not_null<History *> _history;
};
virtual std::unique_ptr<Row> createRow(not_null<History*> history) = 0;
virtual std::unique_ptr<Row> createRow(not_null<History *> history) = 0;
virtual void prepareViewHook() = 0;
virtual void updateRowHook(not_null<Row*> row) {
}
virtual void updateRowHook(not_null<Row *> row) {}
virtual QString emptyBoxText() const;
private:
void rebuildRows();
void checkForEmptyRows();
bool appendRow(not_null<History*> history);
bool appendRow(not_null<History *> history);
};
class ContactsBoxController : public PeerListController, protected base::Subscriber {
public:
ContactsBoxController(std::unique_ptr<PeerListSearchController> searchController = std::make_unique<PeerListGlobalSearchController>());
ContactsBoxController(std::unique_ptr<PeerListSearchController> searchController =
std::make_unique<PeerListGlobalSearchController>());
void prepare() override final;
std::unique_ptr<PeerListRow> createSearchRow(not_null<PeerData*> peer) override final;
void rowClicked(not_null<PeerListRow*> row) override;
std::unique_ptr<PeerListRow> createSearchRow(not_null<PeerData *> peer) override final;
void rowClicked(not_null<PeerListRow *> row) override;
protected:
virtual std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user);
virtual void prepareViewHook() {
}
virtual void updateRowHook(not_null<PeerListRow*> row) {
}
virtual std::unique_ptr<PeerListRow> createRow(not_null<UserData *> user);
virtual void prepareViewHook() {}
virtual void updateRowHook(not_null<PeerListRow *> row) {}
private:
void rebuildRows();
void checkForEmptyRows();
bool appendRow(not_null<UserData*> user);
bool appendRow(not_null<UserData *> user);
};
class EditChatAdminsBoxController : public PeerListController, private base::Subscriber {
public:
static void Start(not_null<ChatData*> chat);
static void Start(not_null<ChatData *> chat);
EditChatAdminsBoxController(not_null<ChatData*> chat);
EditChatAdminsBoxController(not_null<ChatData *> chat);
bool allAreAdmins() const;
void prepare() override;
void rowClicked(not_null<PeerListRow*> row) override;
void rowClicked(not_null<PeerListRow *> row) override;
private:
void createAllAdminsCheckbox();
void rebuildRows();
std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user);
std::unique_ptr<PeerListRow> createRow(not_null<UserData *> user);
not_null<ChatData*> _chat;
not_null<ChatData *> _chat;
int _adminsUpdatedSubscription = 0;
class LabeledCheckbox;
QPointer<LabeledCheckbox> _allAdmins;
};
class AddParticipantsBoxController : public ContactsBoxController {
public:
static void Start(not_null<ChatData*> chat);
static void Start(not_null<ChannelData*> channel);
static void Start(
not_null<ChannelData*> channel,
base::flat_set<not_null<UserData*>> &&alreadyIn);
static void Start(not_null<ChatData *> chat);
static void Start(not_null<ChannelData *> channel);
static void Start(not_null<ChannelData *> channel, base::flat_set<not_null<UserData *>> &&alreadyIn);
AddParticipantsBoxController(PeerData *peer);
AddParticipantsBoxController(
not_null<ChannelData*> channel,
base::flat_set<not_null<UserData*>> &&alreadyIn);
AddParticipantsBoxController(not_null<ChannelData *> channel, base::flat_set<not_null<UserData *>> &&alreadyIn);
using ContactsBoxController::ContactsBoxController;
void rowClicked(not_null<PeerListRow*> row) override;
void itemDeselectedHook(not_null<PeerData*> peer) override;
void rowClicked(not_null<PeerListRow *> row) override;
void itemDeselectedHook(not_null<PeerData *> peer) override;
protected:
void prepareViewHook() override;
std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user) override;
std::unique_ptr<PeerListRow> createRow(not_null<UserData *> user) override;
private:
static void Start(
not_null<ChannelData*> channel,
base::flat_set<not_null<UserData*>> &&alreadyIn,
bool justCreated);
static void Start(not_null<ChannelData *> channel, base::flat_set<not_null<UserData *>> &&alreadyIn,
bool justCreated);
int alreadyInCount() const;
bool isAlreadyIn(not_null<UserData*> user) const;
bool isAlreadyIn(not_null<UserData *> user) const;
int fullCount() const;
void updateTitle();
PeerData *_peer = nullptr;
base::flat_set<not_null<UserData*>> _alreadyIn;
base::flat_set<not_null<UserData *>> _alreadyIn;
};
class AddBotToGroupBoxController : public ChatsListBoxController, public base::enable_weak_from_this {
public:
static void Start(not_null<UserData*> bot);
static void Start(not_null<UserData *> bot);
AddBotToGroupBoxController(not_null<UserData*> bot);
AddBotToGroupBoxController(not_null<UserData *> bot);
void rowClicked(not_null<PeerListRow*> row) override;
void rowClicked(not_null<PeerListRow *> row) override;
protected:
std::unique_ptr<Row> createRow(not_null<History*> history) override;
std::unique_ptr<Row> createRow(not_null<History *> history) override;
void prepareViewHook() override;
QString emptyBoxText() const override;
private:
static bool SharingBotGame(not_null<UserData*> bot);
static bool SharingBotGame(not_null<UserData *> bot);
bool needToCreateRow(not_null<PeerData*> peer) const;
bool needToCreateRow(not_null<PeerData *> peer) const;
bool sharingBotGame() const;
QString noResultsText() const;
QString descriptionText() const;
void updateLabels();
void shareBotGame(not_null<PeerData*> chat);
void addBotToGroup(not_null<PeerData*> chat);
not_null<UserData*> _bot;
void shareBotGame(not_null<PeerData *> chat);
void addBotToGroup(not_null<PeerData *> chat);
not_null<UserData *> _bot;
};

View File

@ -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);

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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<object_ptr<Ui::IconButton>> _stars;
object_ptr<Ui::InputArea> _comment = { nullptr };
object_ptr<Ui::InputArea> _comment = {nullptr};
mtpRequestId _requestId = 0;
};

View File

@ -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<Ui::RadioenumGroup<Reason>>(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<Ui::RadioenumGroup<Reason>>(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);
}

View File

@ -23,10 +23,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/abstract_box.h"
namespace Ui {
template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
template <typename Enum> class RadioenumGroup;
template <typename Enum> 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<Ui::Radioenum<Reason>> _reasonViolence;
object_ptr<Ui::Radioenum<Reason>> _reasonPornography;
object_ptr<Ui::Radioenum<Reason>> _reasonOther;
object_ptr<Ui::InputArea> _reasonOtherText = { nullptr };
object_ptr<Ui::InputArea> _reasonOtherText = {nullptr};
mtpRequestId _requestId = 0;
};

View File

@ -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<Ui::FlatLabel>(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<Ui::FlatLabel>(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<Ui::FlatLabel>(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout);
auto loading =
object_ptr<Ui::FlatLabel>(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<Ui::RadiobuttonGroup>(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<Ui::RadiobuttonGroup>(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();
}

View File

@ -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<int> _ttlValues;
object_ptr<Ui::FlatLabel> _description = { nullptr };
object_ptr<Ui::FlatLabel> _description = {nullptr};
std::shared_ptr<Ui::RadiobuttonGroup> _ttlGroup;
std::vector<object_ptr<Ui::Radiobutton>> _options;
};

View File

@ -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<HistoryGif*>(media)->getDocument();
doc = static_cast<HistoryGif *>(media)->getDocument();
dimensions = doc->dimensions;
image = doc->thumb;
} break;
case MediaTypePhoto: {
_photo = true;
auto photo = static_cast<HistoryPhoto*>(media)->photo();
auto photo = static_cast<HistoryPhoto *>(media)->photo();
dimensions = QSize(photo->full->width(), photo->full->height());
image = photo->full;
} break;
case MediaTypeVideo: {
_animated = true;
doc = static_cast<HistoryVideo*>(media)->getDocument();
doc = static_cast<HistoryVideo *>(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<HistoryDocument*>(media)->getDocument();
doc = static_cast<HistoryDocument *>(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();

View File

@ -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<void(const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, bool ctrlShiftEnter)> callback) {
void setConfirmedCallback(base::lambda<void(const QStringList &files, const QImage &image,
std::unique_ptr<FileLoadTask::MediaInformation> information,
bool compressed, const QString &caption, bool ctrlShiftEnter)>
callback) {
_confirmedCallback = std::move(callback);
}
void setCancelledCallback(base::lambda<void()> callback) {
@ -99,22 +102,24 @@ private:
QString _contactLastName;
EmptyUserpic _contactPhotoEmpty;
base::lambda<void(const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, bool ctrlShiftEnter)> _confirmedCallback;
base::lambda<void(const QStringList &files, const QImage &image,
std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed,
const QString &caption, bool ctrlShiftEnter)>
_confirmedCallback;
base::lambda<void()> _cancelledCallback;
bool _confirmed = false;
object_ptr<Ui::InputArea> _caption = { nullptr };
object_ptr<Ui::Checkbox> _compressed = { nullptr };
object_ptr<Ui::InputArea> _caption = {nullptr};
object_ptr<Ui::Checkbox> _compressed = {nullptr};
QPointer<Ui::RoundButton> _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<Ui::InputArea> _field = { nullptr };
object_ptr<Ui::InputArea> _field = {nullptr};
int _thumbx = 0;
int _thumby = 0;
@ -164,5 +169,4 @@ private:
mtpRequestId _saveRequestId = 0;
QString _error;
};

View File

@ -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<ConfirmBox>(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<ConfirmBox>(
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<ConfirmBox>(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<ConfirmBox>(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();
}

View File

@ -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<SingleTimer> _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<quint64, Ui::IconButton*> TerminateButtons;
typedef QMap<quint64, Ui::IconButton *> TerminateButtons;
TerminateButtons _terminateButtons;
object_ptr<Ui::LinkButton> _terminateAll;
QPointer<ConfirmBox> _terminateBox;
};

View File

@ -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 &&copyCallback, 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 &&copyCallback, 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<Inner>(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::IndexedList>(Dialogs::SortMode::Add)) {
ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallback)
: TWidget(parent)
, _filterCallback(std::move(filterCallback))
, _chatsIndexed(std::make_unique<Dialogs::IndexedList>(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<Chat*>(row->attached);
return static_cast<Chat *>(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<Chat*>(row->attached);
auto data = static_cast<Chat *>(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<void()> 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<PeerData*> ShareBox::Inner::selected() const {
QVector<PeerData*> result;
QVector<PeerData *> ShareBox::Inner::selected() const {
QVector<PeerData *> result;
result.reserve(_dataMap.size());
for_const (auto chat, _dataMap) {
if (chat->checkbox.checked()) {
@ -801,10 +797,10 @@ QVector<PeerData*> ShareBox::Inner::selected() const {
QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
auto shareHashData = QByteArray(0x10, Qt::Uninitialized);
auto shareHashDataInts = reinterpret_cast<qint32*>(shareHashData.data());
auto channel = fullId.channel ? App::channelLoaded(fullId.channel) : static_cast<ChannelData*>(nullptr);
auto shareHashDataInts = reinterpret_cast<qint32 *>(shareHashData.data());
auto channel = fullId.channel ? App::channelLoaded(fullId.channel) : static_cast<ChannelData *>(nullptr);
auto channelAccessHash = channel ? channel->access : 0ULL;
auto channelAccessHashInts = reinterpret_cast<qint32*>(&channelAccessHash);
auto channelAccessHashInts = reinterpret_cast<qint32 *>(&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<quint64*>(shareHashEncrypted.data()) ^= *reinterpret_cast<quint64*>(channelAccessHashInts);
*reinterpret_cast<quint64 *>(shareHashEncrypted.data()) ^= *reinterpret_cast<quint64 *>(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<InformBox>(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<quint64*>(hashEncrypted.data()) ^ *reinterpret_cast<quint64*>(dataSha1);
auto channelAccessHash =
*reinterpret_cast<quint64 *>(hashEncrypted.data()) ^ *reinterpret_cast<quint64 *>(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<qint32*>(hashData.data());
auto hashDataInts = reinterpret_cast<qint32 *>(hashData.data());
if (!AuthSession::Exists() || hashDataInts[0] != Auth().userId()) {
Ui::show(Box<InformBox>(lang(lng_share_wrong_user)));
return;
}
// Check first 32 bits of channel access hash.
auto channelAccessHashInts = reinterpret_cast<qint32*>(&channelAccessHash);
auto channelAccessHashInts = reinterpret_cast<qint32 *>(&channelAccessHash);
if (channelAccessHashInts[0] != hashDataInts[3]) {
Ui::show(Box<InformBox>(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<MTPInputChannel>(1, MTP_inputChannel(MTP_int(channelId), MTP_long(channelAccessHash)));
auto requestChannelIds =
MTP_vector<MTPInputChannel>(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);
}
}));
}
}
}

View File

@ -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<void()>;
using SubmitCallback = base::lambda<void(const QVector<PeerData*> &)>;
using FilterCallback = base::lambda<bool(PeerData*)>;
ShareBox(QWidget*, CopyCallback &&copyCallback, SubmitCallback &&submitCallback, FilterCallback &&filterCallback);
using SubmitCallback = base::lambda<void(const QVector<PeerData *> &)>;
using FilterCallback = base::lambda<bool(PeerData *)>;
ShareBox(QWidget *, CopyCallback &&copyCallback, 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<void(PeerData *peer, bool selected)> callback);
void peerUnselected(PeerData *peer);
QVector<PeerData*> selected() const;
QVector<PeerData *> selected() const;
bool hasSelected() const;
void peopleReceived(const QString &query, const QVector<MTPPeer> &people);
@ -195,12 +194,12 @@ private:
ShareBox::FilterCallback _filterCallback;
std::unique_ptr<Dialogs::IndexedList> _chatsIndexed;
QString _filter;
using FilteredDialogs = QVector<Dialogs::Row*>;
using FilteredDialogs = QVector<Dialogs::Row *>;
FilteredDialogs _filtered;
using DataMap = QMap<PeerData*, Chat*>;
using DataMap = QMap<PeerData *, Chat *>;
DataMap _dataMap;
using SelectedChats = OrderedSet<PeerData*>;
using SelectedChats = OrderedSet<PeerData *>;
SelectedChats _selected;
base::lambda<void(PeerData *peer, bool selected)> _peerSelectedChangedCallback;
@ -209,9 +208,8 @@ private:
bool _searching = false;
QString _lastQuery;
using ByUsernameRows = QVector<PeerData*>;
using ByUsernameDatas = QVector<Chat*>;
using ByUsernameRows = QVector<PeerData *>;
using ByUsernameDatas = QVector<Chat *>;
ByUsernameRows _byUsernameFiltered;
ByUsernameDatas d_byUsernameFiltered;
};

View File

@ -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 <QApplication>
#include <QClipboard>
@ -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<InformBox>(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<TextWithEntities()> 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() {}

View File

@ -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> _inner;
};
// This class is hold in header because it requires Qt preprocessing.
@ -129,5 +128,4 @@ private:
QTimer _previewTimer;
int _previewShown = -1;
};

View File

@ -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 <typename ...Args>
StickersBox::Tab::Tab(int index, Args&&... args)
: _index(index)
, _widget(std::forward<Args>(args)...)
, _weak(_widget) {
}
template <typename... Args>
StickersBox::Tab::Tab(int index, Args &&... args)
: _index(index)
, _widget(std::forward<Args>(args)...)
, _weak(_widget) {}
object_ptr<StickersBox::Inner> 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<ChannelData*> megagroup)
: _section(Section::Installed)
, _installed(0, this, megagroup)
, _megagroupSet(megagroup) {
StickersBox::StickersBox(QWidget *, not_null<ChannelData *> 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<ChannelData*> 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<ChannelData *> 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<Ui::RippleAnimation>(st::contactsRipple, std::move(rippleMask), [this, index = _pressed] {
update(0, _itemsTop + index * _rowHeight, width(), _rowHeight);
});
_rows[_pressed]->ripple = std::make_unique<Ui::RippleAnimation>(
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<Ui::RippleAnimation>(st, std::move(mask), [this, index = _actionDown, removeButton] {
update(myrtlrect(relativeButtonRect(removeButton).translated(0, _itemsTop + index * _rowHeight)));
});
_rows[_actionDown]->ripple =
std::make_unique<Ui::RippleAnimation>(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<Row>(it->id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh);
_megagroupSelectedSet = std::make_unique<Row>(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<Row>(set.id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh));
_rows.push_back(std::make_unique<Row>(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 <typename Check>
Stickers::Order StickersBox::Inner::collectSets(Check check) const {
template <typename Check> 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 {

View File

@ -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<ChannelData*> megagroup);
StickersBox(QWidget *, Section section);
StickersBox(QWidget *, not_null<ChannelData *> megagroup);
void setInnerFocus() override;
@ -65,8 +65,7 @@ private:
public:
Tab() = default;
template <typename ...Args>
Tab(int index, Args&&... args);
template <typename... Args> Tab(int index, Args &&... args);
object_ptr<Inner> takeWidget();
void returnWidget(object_ptr<Inner> widget);
@ -85,10 +84,9 @@ private:
private:
int _index = 0;
object_ptr<Inner> _widget = { nullptr };
object_ptr<Inner> _widget = {nullptr};
QPointer<Inner> _weak;
int _scrollTop = 0;
};
void handleStickersUpdated();
@ -110,11 +108,11 @@ private:
void loadMoreArchived();
void getArchivedDone(quint64 offsetId, const MTPmessages_ArchivedStickers &result);
object_ptr<Ui::SettingsSlider> _tabs = { nullptr };
object_ptr<Ui::SettingsSlider> _tabs = {nullptr};
QList<Section> _tabIndices;
class CounterWidget;
object_ptr<CounterWidget> _unreadBadge = { nullptr };
object_ptr<CounterWidget> _unreadBadge = {nullptr};
Section _section;
@ -126,7 +124,7 @@ private:
ChannelData *_megagroupSet = nullptr;
std::unique_ptr<Ui::SlideAnimation> _slideAnimation;
object_ptr<BoxLayerTitleShadow> _titleShadow = { nullptr };
object_ptr<BoxLayerTitleShadow> _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<ChannelData*> megagroup);
Inner(QWidget *parent, not_null<ChannelData *> megagroup);
base::Observable<int> 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<Ui::RippleAnimation> ripple;
};
template <typename Check>
Stickers::Order collectSets(Check check) const;
template <typename Check> 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<Row> _megagroupSelectedSet;
object_ptr<Ui::UsernameInput> _megagroupSetField = { nullptr };
object_ptr<BoxLayerTitleShadow> _megagroupSelectedShadow = { nullptr };
object_ptr<Ui::CrossButton> _megagroupSelectedRemove = { nullptr };
object_ptr<BoxContentDivider> _megagroupDivider = { nullptr };
object_ptr<Ui::FlatLabel> _megagroupSubTitle = { nullptr };
object_ptr<Ui::UsernameInput> _megagroupSetField = {nullptr};
object_ptr<BoxLayerTitleShadow> _megagroupSelectedShadow = {nullptr};
object_ptr<Ui::CrossButton> _megagroupSelectedRemove = {nullptr};
object_ptr<BoxContentDivider> _megagroupDivider = {nullptr};
object_ptr<Ui::FlatLabel> _megagroupSubTitle = {nullptr};
base::Timer _megagroupSetAddressChangedTimer;
mtpRequestId _megagroupSetRequestId = 0;
};

View File

@ -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 <QApplication>
#include <QClipboard>
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();

View File

@ -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<QTimer> _checkTimer;
};

View File

@ -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<HistoryItem*> _items;
std::vector<HistoryItem *> _items;
QDate _date;
Type _type;
std::unique_ptr<Ui::RippleAnimation> _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<HistoryCall*>(media)->reason();
auto reason = static_cast<HistoryCall *>(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<void()> updateCallback) {
if (!_actionRipple) {
auto mask = Ui::RippleAnimation::ellipseMask(QSize(st::callReDial.rippleAreaSize, st::callReDial.rippleAreaSize));
_actionRipple = std::make_unique<Ui::RippleAnimation>(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<Ui::RippleAnimation>(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<PeerListRow*> row) {
auto itemsRow = static_cast<Row*>(row.get());
void BoxController::rowClicked(not_null<PeerListRow *> row) {
auto itemsRow = static_cast<Row *>(row.get());
auto itemId = itemsRow->maxItemId();
Ui::showPeerHistoryAsync(row->peer()->id, itemId);
}
void BoxController::rowActionClicked(not_null<PeerListRow*> row) {
void BoxController::rowActionClicked(not_null<PeerListRow *> 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<Row&>(a).maxItemId() > static_cast<Row&>(b).maxItemId();
return static_cast<Row &>(a).maxItemId() > static_cast<Row &>(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<Row*>(v->peerListRowAt(fullRowsCount - 1).get());
auto lastRow = static_cast<Row *>(v->peerListRowAt(fullRowsCount - 1).get());
if (itemId < lastRow->minItemId()) {
return lastRow;
}
auto firstRow = static_cast<Row*>(v->peerListRowAt(0).get());
auto firstRow = static_cast<Row *>(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<Row*>(v->peerListRowAt(middle).get());
auto middleRow = static_cast<Row *>(v->peerListRowAt(middle).get());
if (middleRow->maxItemId() >= itemId) {
left = middle;
} else {
right = middle;
}
}
auto result = static_cast<Row*>(v->peerListRowAt(left).get());
auto result = static_cast<Row *>(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<Row*>(v->peerListRowAt(left + 1).get());
auto possibleResult = static_cast<Row *>(v->peerListRowAt(left + 1).get());
Assert(possibleResult->maxItemId() < itemId);
if (possibleResult->canAddItem(item)) {
return possibleResult;

Some files were not shown because too many files have changed in this diff Show More