mirror of https://github.com/procxx/kepka.git
Components are now almost plain structs
Moved reply markups to history items which hold them
This commit is contained in:
parent
7d80cdc3cd
commit
daa5016c23
|
@ -1085,6 +1085,16 @@ msgInReplyBarColor: #2fa9e2;
|
||||||
msgOutReplyBarSelColor: #4da79f;
|
msgOutReplyBarSelColor: #4da79f;
|
||||||
msgInReplyBarSelColor: #2fa9e2;
|
msgInReplyBarSelColor: #2fa9e2;
|
||||||
|
|
||||||
|
msgBotKbDuration: 200;
|
||||||
|
msgBotKbFont: semiboldFont;
|
||||||
|
msgBotKbButton: botKeyboardButton {
|
||||||
|
margin: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
height: 36px;
|
||||||
|
textTop: 8px;
|
||||||
|
downTextTop: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
msgServiceBg: #89a0b47f;
|
msgServiceBg: #89a0b47f;
|
||||||
msgServiceSelectBg: #bbc8d4a2;
|
msgServiceSelectBg: #bbc8d4a2;
|
||||||
msgServiceColor: #FFF;
|
msgServiceColor: #FFF;
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
ApiWrap(QObject *parent);
|
ApiWrap(QObject *parent);
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
typedef SharedCallback2<void, ChannelData*, MsgId> RequestMessageDataCallback;
|
typedef SharedCallback<void, ChannelData*, MsgId> RequestMessageDataCallback;
|
||||||
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback *callback);
|
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback *callback);
|
||||||
|
|
||||||
void requestFullPeer(PeerData *peer);
|
void requestFullPeer(PeerData *peer);
|
||||||
|
@ -69,7 +69,7 @@ private:
|
||||||
struct MessageDataRequest {
|
struct MessageDataRequest {
|
||||||
MessageDataRequest() : req(0) {
|
MessageDataRequest() : req(0) {
|
||||||
}
|
}
|
||||||
typedef SharedCallback2<void, ChannelData*, MsgId>::Ptr CallbackPtr;
|
typedef SharedCallback<void, ChannelData*, MsgId>::Ptr CallbackPtr;
|
||||||
typedef QList<CallbackPtr> Callbacks;
|
typedef QList<CallbackPtr> Callbacks;
|
||||||
mtpRequestId req;
|
mtpRequestId req;
|
||||||
Callbacks callbacks;
|
Callbacks callbacks;
|
||||||
|
|
|
@ -55,12 +55,6 @@ namespace {
|
||||||
typedef QHash<WebPageId, WebPageData*> WebPagesData;
|
typedef QHash<WebPageId, WebPageData*> WebPagesData;
|
||||||
WebPagesData webPagesData;
|
WebPagesData webPagesData;
|
||||||
|
|
||||||
typedef QMap<MsgId, ReplyMarkup> ReplyMarkups;
|
|
||||||
ReplyMarkups replyMarkups;
|
|
||||||
ReplyMarkup zeroMarkup(qFlags(MTPDreplyKeyboardMarkup_ClientFlag::f_zero));
|
|
||||||
typedef QMap<ChannelId, ReplyMarkups> ChannelReplyMarkups;
|
|
||||||
ChannelReplyMarkups channelReplyMarkups;
|
|
||||||
|
|
||||||
PhotoItems photoItems;
|
PhotoItems photoItems;
|
||||||
DocumentItems documentItems;
|
DocumentItems documentItems;
|
||||||
WebPageItems webPageItems;
|
WebPageItems webPageItems;
|
||||||
|
@ -1851,8 +1845,6 @@ namespace App {
|
||||||
}
|
}
|
||||||
|
|
||||||
::hoveredItem = ::pressedItem = ::hoveredLinkItem = ::pressedLinkItem = ::contextItem = 0;
|
::hoveredItem = ::pressedItem = ::hoveredLinkItem = ::pressedLinkItem = ::contextItem = 0;
|
||||||
replyMarkups.clear();
|
|
||||||
channelReplyMarkups.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void historyClearItems() {
|
void historyClearItems() {
|
||||||
|
@ -2396,114 +2388,6 @@ namespace App {
|
||||||
::inlineResultLoaders.remove(loader);
|
::inlineResultLoaders.remove(loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineResult *inlineResultFromLoader(FileLoader *loader) {
|
|
||||||
InlineResultLoaders::const_iterator i = ::inlineResultLoaders.find(loader);
|
|
||||||
return (i == ::inlineResultLoaders.cend()) ? 0 : i.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void insertReplyMarkup(ChannelId channelId, MsgId msgId, const ReplyMarkup &markup) {
|
|
||||||
if (channelId == NoChannel) {
|
|
||||||
replyMarkups.insert(msgId, markup);
|
|
||||||
} else {
|
|
||||||
channelReplyMarkups[channelId].insert(msgId, markup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void feedReplyMarkup(ChannelId channelId, MsgId msgId, const MTPReplyMarkup &markup) {
|
|
||||||
ReplyMarkup data;
|
|
||||||
ReplyMarkup::Commands &commands(data.commands);
|
|
||||||
switch (markup.type()) {
|
|
||||||
case mtpc_replyKeyboardMarkup: {
|
|
||||||
const MTPDreplyKeyboardMarkup &d(markup.c_replyKeyboardMarkup());
|
|
||||||
data.flags = d.vflags.v;
|
|
||||||
|
|
||||||
const QVector<MTPKeyboardButtonRow> &v(d.vrows.c_vector().v);
|
|
||||||
if (!v.isEmpty()) {
|
|
||||||
commands.reserve(v.size());
|
|
||||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
|
||||||
switch (v.at(i).type()) {
|
|
||||||
case mtpc_keyboardButtonRow: {
|
|
||||||
const MTPDkeyboardButtonRow &r(v.at(i).c_keyboardButtonRow());
|
|
||||||
const QVector<MTPKeyboardButton> &b(r.vbuttons.c_vector().v);
|
|
||||||
if (!b.isEmpty()) {
|
|
||||||
QList<QString> btns;
|
|
||||||
btns.reserve(b.size());
|
|
||||||
for (int32 j = 0, s = b.size(); j < s; ++j) {
|
|
||||||
switch (b.at(j).type()) {
|
|
||||||
case mtpc_keyboardButton: {
|
|
||||||
btns.push_back(qs(b.at(j).c_keyboardButton().vtext));
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_keyboardButtonCallback: {
|
|
||||||
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_keyboardButtonRequestGeoLocation: {
|
|
||||||
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_keyboardButtonRequestPhone: {
|
|
||||||
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_keyboardButtonUrl: {
|
|
||||||
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!btns.isEmpty()) commands.push_back(btns);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!commands.isEmpty()) {
|
|
||||||
insertReplyMarkup(channelId, msgId, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_replyKeyboardHide: {
|
|
||||||
const MTPDreplyKeyboardHide &d(markup.c_replyKeyboardHide());
|
|
||||||
if (d.vflags.v) {
|
|
||||||
insertReplyMarkup(channelId, msgId, ReplyMarkup(mtpCastFlags(d.vflags.v) | MTPDreplyKeyboardMarkup_ClientFlag::f_zero));
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_replyKeyboardForceReply: {
|
|
||||||
const MTPDreplyKeyboardForceReply &d(markup.c_replyKeyboardForceReply());
|
|
||||||
insertReplyMarkup(channelId, msgId, ReplyMarkup(mtpCastFlags(d.vflags.v) | MTPDreplyKeyboardMarkup_ClientFlag::f_force_reply));
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearReplyMarkup(ChannelId channelId, MsgId msgId) {
|
|
||||||
if (channelId == NoChannel) {
|
|
||||||
replyMarkups.remove(msgId);
|
|
||||||
} else {
|
|
||||||
ChannelReplyMarkups::iterator i = channelReplyMarkups.find(channelId);
|
|
||||||
if (i != channelReplyMarkups.cend()) {
|
|
||||||
i->remove(msgId);
|
|
||||||
if (i->isEmpty()) {
|
|
||||||
channelReplyMarkups.erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const ReplyMarkup &replyMarkup(const ReplyMarkups &markups, MsgId msgId) {
|
|
||||||
ReplyMarkups::const_iterator i = markups.constFind(msgId);
|
|
||||||
if (i == markups.cend()) return zeroMarkup;
|
|
||||||
return i.value();
|
|
||||||
}
|
|
||||||
const ReplyMarkup &replyMarkup(ChannelId channelId, MsgId msgId) {
|
|
||||||
if (channelId == NoChannel) {
|
|
||||||
return replyMarkup(replyMarkups, msgId);
|
|
||||||
}
|
|
||||||
ChannelReplyMarkups::const_iterator j = channelReplyMarkups.constFind(channelId);
|
|
||||||
if (j == channelReplyMarkups.cend()) return zeroMarkup;
|
|
||||||
return replyMarkup(*j, msgId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setProxySettings(QNetworkAccessManager &manager) {
|
void setProxySettings(QNetworkAccessManager &manager) {
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||||
manager.setProxy(getHttpProxySettings());
|
manager.setProxy(getHttpProxySettings());
|
||||||
|
|
|
@ -44,14 +44,6 @@ typedef QHash<ClipReader*, HistoryItem*> GifItems;
|
||||||
typedef QHash<PhotoId, PhotoData*> PhotosData;
|
typedef QHash<PhotoId, PhotoData*> PhotosData;
|
||||||
typedef QHash<DocumentId, DocumentData*> DocumentsData;
|
typedef QHash<DocumentId, DocumentData*> DocumentsData;
|
||||||
|
|
||||||
struct ReplyMarkup {
|
|
||||||
ReplyMarkup(MTPDreplyKeyboardMarkup::Flags flags = 0) : flags(flags) {
|
|
||||||
}
|
|
||||||
typedef QList<QList<QString> > Commands;
|
|
||||||
Commands commands;
|
|
||||||
MTPDreplyKeyboardMarkup::Flags flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LayeredWidget;
|
class LayeredWidget;
|
||||||
|
|
||||||
namespace App {
|
namespace App {
|
||||||
|
@ -272,10 +264,6 @@ namespace App {
|
||||||
void unregInlineResultLoader(FileLoader *loader);
|
void unregInlineResultLoader(FileLoader *loader);
|
||||||
InlineResult *inlineResultFromLoader(FileLoader *loader);
|
InlineResult *inlineResultFromLoader(FileLoader *loader);
|
||||||
|
|
||||||
void feedReplyMarkup(ChannelId channelId, MsgId msgId, const MTPReplyMarkup &markup);
|
|
||||||
void clearReplyMarkup(ChannelId channelId, MsgId msgId);
|
|
||||||
const ReplyMarkup &replyMarkup(ChannelId channelId, MsgId msgId);
|
|
||||||
|
|
||||||
void setProxySettings(QNetworkAccessManager &manager);
|
void setProxySettings(QNetworkAccessManager &manager);
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||||
QNetworkProxy getHttpProxySettings();
|
QNetworkProxy getHttpProxySettings();
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace App {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void activateBotCommand(const HistoryMessageReplyMarkup::Button &button, MsgId replyTo) {
|
||||||
|
QString cmd(button.text);
|
||||||
|
App::sendBotCommand(cmd, replyTo);
|
||||||
|
}
|
||||||
|
|
||||||
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
||||||
if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel()) ? inPeer : 0);
|
if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel()) ? inPeer : 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace App {
|
||||||
|
|
||||||
void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
|
void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
|
||||||
bool insertBotCommand(const QString &cmd, bool specialGif = false);
|
bool insertBotCommand(const QString &cmd, bool specialGif = false);
|
||||||
|
void activateBotCommand(const HistoryMessageReplyMarkup::Button &button, MsgId replyTo = 0);
|
||||||
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
||||||
void openPeerByName(const QString &username, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString());
|
void openPeerByName(const QString &username, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString());
|
||||||
void joinGroupByHash(const QString &hash);
|
void joinGroupByHash(const QString &hash);
|
||||||
|
|
|
@ -211,7 +211,7 @@ public:
|
||||||
AnimationImplementation *create() const { return getPointerAndReset(_ptr); }
|
AnimationImplementation *create() const { return getPointerAndReset(_ptr); }
|
||||||
~AnimationCreator() { deleteAndMark(_ptr); }
|
~AnimationCreator() { deleteAndMark(_ptr); }
|
||||||
private:
|
private:
|
||||||
AnimationCreator &operator=(const AnimationCreator &other);
|
AnimationCreator &operator=(const AnimationCreator &other) = delete;
|
||||||
mutable AnimationImplementation *_ptr;
|
mutable AnimationImplementation *_ptr;
|
||||||
};
|
};
|
||||||
class AnimationCallbacks {
|
class AnimationCallbacks {
|
||||||
|
@ -222,7 +222,7 @@ public:
|
||||||
~AnimationCallbacks() { deleteAndMark(_implementation); }
|
~AnimationCallbacks() { deleteAndMark(_implementation); }
|
||||||
private:
|
private:
|
||||||
AnimationCallbacks(const AnimationCallbacks &other);
|
AnimationCallbacks(const AnimationCallbacks &other);
|
||||||
AnimationCallbacks &operator=(const AnimationCallbacks &other);
|
AnimationCallbacks &operator=(const AnimationCallbacks &other) = delete;
|
||||||
AnimationImplementation *_implementation;
|
AnimationImplementation *_implementation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1291,9 +1291,6 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
result = HistoryService::create(this, m.vid.v, date(m.vdate), lang(lng_message_empty), m.vflags.v, nullptr, m.has_from_id() ? m.vfrom_id.v : 0);
|
result = HistoryService::create(this, m.vid.v, date(m.vdate), lang(lng_message_empty), m.vflags.v, nullptr, m.has_from_id() ? m.vfrom_id.v : 0);
|
||||||
} else {
|
} else {
|
||||||
result = HistoryMessage::create(this, m);
|
result = HistoryMessage::create(this, m);
|
||||||
if (m.has_reply_markup()) {
|
|
||||||
App::feedReplyMarkup(channelId(), msgId, m.vreply_markup);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -1589,8 +1586,8 @@ HistoryItem *History::addNewItem(HistoryItem *adding, bool newMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (adding->hasReplyMarkup()) {
|
if (adding->definesReplyKeyboard()) {
|
||||||
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), adding->id).flags;
|
MTPDreplyKeyboardMarkup::Flags markupFlags = adding->replyKeyboardFlags();
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || adding->mentionsMe()) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || adding->mentionsMe()) {
|
||||||
OrderedSet<PeerData*> *markupSenders = 0;
|
OrderedSet<PeerData*> *markupSenders = 0;
|
||||||
if (peer->isChat()) {
|
if (peer->isChat()) {
|
||||||
|
@ -1759,8 +1756,8 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
}
|
}
|
||||||
if (item->author()->id) {
|
if (item->author()->id) {
|
||||||
if (markupSenders) { // chats with bots
|
if (markupSenders) { // chats with bots
|
||||||
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) {
|
if (!lastKeyboardInited && item->definesReplyKeyboard() && !item->out()) {
|
||||||
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
|
MTPDreplyKeyboardMarkup::Flags markupFlags = item->replyKeyboardFlags();
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
|
||||||
bool wasKeyboardHide = markupSenders->contains(item->author());
|
bool wasKeyboardHide = markupSenders->contains(item->author());
|
||||||
if (!wasKeyboardHide) {
|
if (!wasKeyboardHide) {
|
||||||
|
@ -1786,8 +1783,8 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots
|
} else if (!lastKeyboardInited && item->definesReplyKeyboard() && !item->out()) { // conversations with bots
|
||||||
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
|
MTPDreplyKeyboardMarkup::Flags markupFlags = item->replyKeyboardFlags();
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
|
||||||
if (markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero) {
|
if (markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero) {
|
||||||
clearLastKeyboard();
|
clearLastKeyboard();
|
||||||
|
@ -2708,6 +2705,63 @@ void HistoryBlock::removeItem(HistoryItem *item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryMessageReplyMarkup::create(const MTPReplyMarkup &markup) {
|
||||||
|
switch (markup.type()) {
|
||||||
|
case mtpc_replyKeyboardMarkup: {
|
||||||
|
const MTPDreplyKeyboardMarkup &d(markup.c_replyKeyboardMarkup());
|
||||||
|
flags = d.vflags.v;
|
||||||
|
|
||||||
|
const QVector<MTPKeyboardButtonRow> &v(d.vrows.c_vector().v);
|
||||||
|
if (!v.isEmpty()) {
|
||||||
|
rows.reserve(v.size());
|
||||||
|
for_const (const MTPKeyboardButtonRow &row, v) {
|
||||||
|
switch (row.type()) {
|
||||||
|
case mtpc_keyboardButtonRow: {
|
||||||
|
const MTPDkeyboardButtonRow &r(row.c_keyboardButtonRow());
|
||||||
|
const QVector<MTPKeyboardButton> &b(r.vbuttons.c_vector().v);
|
||||||
|
if (!b.isEmpty()) {
|
||||||
|
ButtonRow buttonRow;
|
||||||
|
buttonRow.reserve(b.size());
|
||||||
|
for_const (const MTPKeyboardButton &button, b) {
|
||||||
|
switch (button.type()) {
|
||||||
|
case mtpc_keyboardButton: {
|
||||||
|
buttonRow.push_back({ Button::Default, qs(button.c_keyboardButton().vtext), QString() });
|
||||||
|
} break;
|
||||||
|
case mtpc_keyboardButtonCallback: {
|
||||||
|
buttonRow.push_back({ Button::Callback, qs(button.c_keyboardButtonCallback().vtext), QString() });
|
||||||
|
} break;
|
||||||
|
case mtpc_keyboardButtonRequestGeoLocation: {
|
||||||
|
buttonRow.push_back({ Button::RequestLocation, qs(button.c_keyboardButtonRequestGeoLocation().vtext), QString() });
|
||||||
|
} break;
|
||||||
|
case mtpc_keyboardButtonRequestPhone: {
|
||||||
|
buttonRow.push_back({ Button::RequestPhone, qs(button.c_keyboardButtonRequestPhone().vtext), QString() });
|
||||||
|
} break;
|
||||||
|
case mtpc_keyboardButtonUrl: {
|
||||||
|
const MTPDkeyboardButtonUrl &u(button.c_keyboardButtonUrl());
|
||||||
|
buttonRow.push_back({ Button::Url, qs(u.vtext), qs(u.vurl) });
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!buttonRow.isEmpty()) rows.push_back(buttonRow);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case mtpc_replyKeyboardHide: {
|
||||||
|
const MTPDreplyKeyboardHide &d(markup.c_replyKeyboardHide());
|
||||||
|
flags = mtpCastFlags(d.vflags) | MTPDreplyKeyboardMarkup_ClientFlag::f_zero;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case mtpc_replyKeyboardForceReply: {
|
||||||
|
const MTPDreplyKeyboardForceReply &d(markup.c_replyKeyboardForceReply());
|
||||||
|
flags = mtpCastFlags(d.vflags) | MTPDreplyKeyboardMarkup_ClientFlag::f_force_reply;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryDependentItemCallback::call(ChannelData *channel, MsgId msgId) const {
|
void HistoryDependentItemCallback::call(ChannelData *channel, MsgId msgId) const {
|
||||||
if (HistoryItem *item = App::histItemById(_dependent)) {
|
if (HistoryItem *item = App::histItemById(_dependent)) {
|
||||||
item->updateDependencyItem();
|
item->updateDependencyItem();
|
||||||
|
@ -3789,7 +3843,7 @@ void HistoryDocumentVoice::checkPlaybackFinished() const {
|
||||||
HistoryDocument::HistoryDocument(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia()
|
HistoryDocument::HistoryDocument(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia()
|
||||||
, _parent(nullptr)
|
, _parent(nullptr)
|
||||||
, _data(document) {
|
, _data(document) {
|
||||||
createInterfaces(!caption.isEmpty());
|
createComponents(!caption.isEmpty());
|
||||||
if (auto *named = Get<HistoryDocumentNamed>()) {
|
if (auto *named = Get<HistoryDocumentNamed>()) {
|
||||||
named->_name = documentName(_data);
|
named->_name = documentName(_data);
|
||||||
named->_namew = st::semiboldFont->width(named->_name);
|
named->_namew = st::semiboldFont->width(named->_name);
|
||||||
|
@ -3809,7 +3863,7 @@ HistoryDocument::HistoryDocument(const HistoryDocument &other) : HistoryFileMedi
|
||||||
, _parent(nullptr)
|
, _parent(nullptr)
|
||||||
, _data(other._data) {
|
, _data(other._data) {
|
||||||
auto *captioned = other.Get<HistoryDocumentCaptioned>();
|
auto *captioned = other.Get<HistoryDocumentCaptioned>();
|
||||||
createInterfaces(captioned != 0);
|
createComponents(captioned != 0);
|
||||||
if (auto *named = Get<HistoryDocumentNamed>()) {
|
if (auto *named = Get<HistoryDocumentNamed>()) {
|
||||||
if (auto *othernamed = other.Get<HistoryDocumentNamed>()) {
|
if (auto *othernamed = other.Get<HistoryDocumentNamed>()) {
|
||||||
named->_name = othernamed->_name;
|
named->_name = othernamed->_name;
|
||||||
|
@ -3829,7 +3883,7 @@ HistoryDocument::HistoryDocument(const HistoryDocument &other) : HistoryFileMedi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryDocument::createInterfaces(bool caption) {
|
void HistoryDocument::createComponents(bool caption) {
|
||||||
uint64 mask = 0;
|
uint64 mask = 0;
|
||||||
if (_data->voice()) {
|
if (_data->voice()) {
|
||||||
mask |= HistoryDocumentVoice::Bit();
|
mask |= HistoryDocumentVoice::Bit();
|
||||||
|
@ -6041,7 +6095,7 @@ bool HistoryMessageReply::updateData(HistoryMessage *holder, bool force) {
|
||||||
replyToLnk = TextLinkPtr(new MessageLink(replyToMsg->history()->peer->id, replyToMsg->id));
|
replyToLnk = TextLinkPtr(new MessageLink(replyToMsg->history()->peer->id, replyToMsg->id));
|
||||||
if (!replyToMsg->Has<HistoryMessageForwarded>()) {
|
if (!replyToMsg->Has<HistoryMessageForwarded>()) {
|
||||||
if (UserData *bot = replyToMsg->viaBot()) {
|
if (UserData *bot = replyToMsg->viaBot()) {
|
||||||
_replyToVia = new HistoryMessageVia(0);
|
_replyToVia.reset(new HistoryMessageVia());
|
||||||
_replyToVia->create(peerToUser(bot->id));
|
_replyToVia->create(peerToUser(bot->id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6055,8 +6109,7 @@ bool HistoryMessageReply::updateData(HistoryMessage *holder, bool force) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessageReply::clearData(HistoryMessage *holder) {
|
void HistoryMessageReply::clearData(HistoryMessage *holder) {
|
||||||
delete _replyToVia;
|
_replyToVia.clear();
|
||||||
_replyToVia = nullptr;
|
|
||||||
if (replyToMsg) {
|
if (replyToMsg) {
|
||||||
App::historyUnregDependency(holder, replyToMsg);
|
App::historyUnregDependency(holder, replyToMsg);
|
||||||
replyToMsg = nullptr;
|
replyToMsg = nullptr;
|
||||||
|
@ -6164,20 +6217,22 @@ void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, in
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg)
|
HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg)
|
||||||
: HistoryItem(history, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) {
|
: HistoryItem(history, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) {
|
||||||
PeerId authorOriginalId = 0, fromOriginalId = 0;
|
CreateConfig config;
|
||||||
MsgId originalId = 0;
|
|
||||||
if (msg.has_fwd_from() && msg.vfwd_from.type() == mtpc_messageFwdHeader) {
|
if (msg.has_fwd_from() && msg.vfwd_from.type() == mtpc_messageFwdHeader) {
|
||||||
const MTPDmessageFwdHeader &f(msg.vfwd_from.c_messageFwdHeader());
|
const MTPDmessageFwdHeader &f(msg.vfwd_from.c_messageFwdHeader());
|
||||||
if (f.has_from_id() || f.has_channel_id()) {
|
if (f.has_from_id() || f.has_channel_id()) {
|
||||||
authorOriginalId = f.has_channel_id() ? peerFromChannel(f.vchannel_id) : peerFromUser(f.vfrom_id);
|
config.authorIdOriginal = f.has_channel_id() ? peerFromChannel(f.vchannel_id) : peerFromUser(f.vfrom_id);
|
||||||
fromOriginalId = f.has_from_id() ? peerFromUser(f.vfrom_id) : peerFromChannel(f.vchannel_id);
|
config.fromIdOriginal = f.has_from_id() ? peerFromUser(f.vfrom_id) : peerFromChannel(f.vchannel_id);
|
||||||
if (f.has_channel_post()) originalId = f.vchannel_post.v;
|
if (f.has_channel_post()) config.originalId = f.vchannel_post.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MsgId replyTo = msg.has_reply_to_msg_id() ? msg.vreply_to_msg_id.v : 0;
|
if (msg.has_reply_to_msg_id()) config.replyTo = msg.vreply_to_msg_id.v;
|
||||||
int32 viaBotId = msg.has_via_bot_id() ? msg.vvia_bot_id.v : 0;
|
if (msg.has_via_bot_id()) config.viaBotId = msg.vvia_bot_id.v;
|
||||||
int views = msg.has_views() ? msg.vviews.v : -1;
|
if (msg.has_views()) config.viewsCount = msg.vviews.v;
|
||||||
createInterfaces(replyTo, viaBotId, views, authorOriginalId, fromOriginalId, originalId);
|
if (msg.has_reply_markup()) config.markup = &msg.vreply_markup;
|
||||||
|
|
||||||
|
createComponents(config);
|
||||||
|
|
||||||
QString text(textClean(qs(msg.vmessage)));
|
QString text(textClean(qs(msg.vmessage)));
|
||||||
initMedia(msg.has_media() ? (&msg.vmedia) : 0, text);
|
initMedia(msg.has_media() ? (&msg.vmedia) : 0, text);
|
||||||
|
@ -6186,11 +6241,18 @@ HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg)
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd)
|
HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd)
|
||||||
: HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from) {
|
: HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from) {
|
||||||
|
CreateConfig config;
|
||||||
|
|
||||||
UserData *fwdViaBot = fwd->viaBot();
|
UserData *fwdViaBot = fwd->viaBot();
|
||||||
int32 viaBotId = fwdViaBot ? peerToUser(fwdViaBot->id) : 0;
|
if (fwdViaBot) config.viaBotId = peerToUser(fwdViaBot->id);
|
||||||
int fwdViewsCount = fwd->viewsCount(), views = (fwdViewsCount > 0) ? fwdViewsCount : (isPost() ? 1 : -1);
|
int fwdViewsCount = fwd->viewsCount();
|
||||||
MsgId replyTo = 0;
|
if (fwdViewsCount > 0) {
|
||||||
createInterfaces(replyTo, viaBotId, views, fwd->authorOriginal()->id, fwd->fromOriginal()->id, fwd->authorOriginal()->isChannel() ? fwd->id : 0);
|
config.viewsCount = fwdViewsCount;
|
||||||
|
} else if (isPost()) {
|
||||||
|
config.viewsCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
createComponents(config);
|
||||||
|
|
||||||
if (HistoryMedia *mediaOriginal = fwd->getMedia()) {
|
if (HistoryMedia *mediaOriginal = fwd->getMedia()) {
|
||||||
_media = mediaOriginal->clone();
|
_media = mediaOriginal->clone();
|
||||||
|
@ -6201,14 +6263,14 @@ HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags fl
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities)
|
HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities)
|
||||||
: HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
|
: HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
|
||||||
createInterfacesHelper(flags, replyTo, viaBotId);
|
createComponentsHelper(flags, replyTo, viaBotId);
|
||||||
|
|
||||||
setText(msg, entities);
|
setText(msg, entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption)
|
HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption)
|
||||||
: HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
|
: HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
|
||||||
createInterfacesHelper(flags, replyTo, viaBotId);
|
createComponentsHelper(flags, replyTo, viaBotId);
|
||||||
|
|
||||||
initMediaFromDocument(doc, caption);
|
initMediaFromDocument(doc, caption);
|
||||||
setText(QString(), EntitiesInText());
|
setText(QString(), EntitiesInText());
|
||||||
|
@ -6216,56 +6278,70 @@ HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption)
|
HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption)
|
||||||
: HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
|
: HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
|
||||||
createInterfacesHelper(flags, replyTo, viaBotId);
|
createComponentsHelper(flags, replyTo, viaBotId);
|
||||||
|
|
||||||
_media = new HistoryPhoto(photo, caption, this);
|
_media = new HistoryPhoto(photo, caption, this);
|
||||||
_media->attachToItem(this);
|
_media->attachToItem(this);
|
||||||
setText(QString(), EntitiesInText());
|
setText(QString(), EntitiesInText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessage::createInterfacesHelper(MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId) {
|
void HistoryMessage::createComponentsHelper(MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId) {
|
||||||
if (!(flags & MTPDmessage::Flag::f_via_bot_id)) viaBotId = 0;
|
CreateConfig config;
|
||||||
if (!(flags & MTPDmessage::Flag::f_reply_to_msg_id)) replyTo = 0;
|
|
||||||
createInterfaces(replyTo, viaBotId, isPost() ? 1 : -1);
|
if (flags & MTPDmessage::Flag::f_via_bot_id) config.viaBotId = viaBotId;
|
||||||
|
if (flags & MTPDmessage::Flag::f_reply_to_msg_id) config.replyTo = replyTo;
|
||||||
|
if (isPost()) config.viewsCount = 1;
|
||||||
|
|
||||||
|
createComponents(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessage::createInterfaces(MsgId replyTo, int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal, const PeerId &fromIdOriginal, MsgId originalId) {
|
void HistoryMessage::createComponents(const CreateConfig &config) {
|
||||||
uint64 mask = 0;
|
uint64 mask = 0;
|
||||||
if (replyTo) {
|
if (config.replyTo) {
|
||||||
mask |= HistoryMessageReply::Bit();
|
mask |= HistoryMessageReply::Bit();
|
||||||
}
|
}
|
||||||
if (viaBotId) {
|
if (config.viaBotId) {
|
||||||
mask |= HistoryMessageVia::Bit();
|
mask |= HistoryMessageVia::Bit();
|
||||||
}
|
}
|
||||||
if (viewsCount >= 0) {
|
if (config.viewsCount >= 0) {
|
||||||
mask |= HistoryMessageViews::Bit();
|
mask |= HistoryMessageViews::Bit();
|
||||||
}
|
}
|
||||||
if (isPost() && _from->isUser()) {
|
if (isPost() && _from->isUser()) {
|
||||||
mask |= HistoryMessageSigned::Bit();
|
mask |= HistoryMessageSigned::Bit();
|
||||||
}
|
}
|
||||||
if (authorIdOriginal && fromIdOriginal) {
|
if (config.authorIdOriginal && config.fromIdOriginal) {
|
||||||
mask |= HistoryMessageForwarded::Bit();
|
mask |= HistoryMessageForwarded::Bit();
|
||||||
}
|
}
|
||||||
|
if (config.markup) {
|
||||||
|
// optimization: don't create markup component for the case
|
||||||
|
// MTPDreplyKeyboardHide with flags = 0, assume it has f_zero flag
|
||||||
|
if (config.markup->type() != mtpc_replyKeyboardHide || config.markup->c_replyKeyboardHide().vflags.v != 0) {
|
||||||
|
mask |= HistoryMessageReplyMarkup::Bit();
|
||||||
|
}
|
||||||
|
}
|
||||||
UpdateComponents(mask);
|
UpdateComponents(mask);
|
||||||
if (auto *reply = Get<HistoryMessageReply>()) {
|
if (auto *reply = Get<HistoryMessageReply>()) {
|
||||||
reply->replyToMsgId = replyTo;
|
reply->replyToMsgId = config.replyTo;
|
||||||
if (!reply->updateData(this) && App::api()) {
|
if (!reply->updateData(this) && App::api()) {
|
||||||
App::api()->requestMessageData(history()->peer->asChannel(), replyTo, new HistoryDependentItemCallback(fullId()));
|
App::api()->requestMessageData(history()->peer->asChannel(), reply->replyToMsgId, new HistoryDependentItemCallback(fullId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (auto *via = Get<HistoryMessageVia>()) {
|
if (auto *via = Get<HistoryMessageVia>()) {
|
||||||
via->create(viaBotId);
|
via->create(config.viaBotId);
|
||||||
}
|
}
|
||||||
if (auto *views = Get<HistoryMessageViews>()) {
|
if (auto *views = Get<HistoryMessageViews>()) {
|
||||||
views->_views = viewsCount;
|
views->_views = config.viewsCount;
|
||||||
}
|
}
|
||||||
if (auto *msgsigned = Get<HistoryMessageSigned>()) {
|
if (auto *msgsigned = Get<HistoryMessageSigned>()) {
|
||||||
msgsigned->create(_from->asUser(), date);
|
msgsigned->create(_from->asUser(), date);
|
||||||
}
|
}
|
||||||
if (auto *fwd = Get<HistoryMessageForwarded>()) {
|
if (auto *fwd = Get<HistoryMessageForwarded>()) {
|
||||||
fwd->_authorOriginal = App::peer(authorIdOriginal);
|
fwd->_authorOriginal = App::peer(config.authorIdOriginal);
|
||||||
fwd->_fromOriginal = App::peer(fromIdOriginal);
|
fwd->_fromOriginal = App::peer(config.fromIdOriginal);
|
||||||
fwd->_originalId = originalId;
|
fwd->_originalId = config.originalId;
|
||||||
|
}
|
||||||
|
if (auto *markup = Get<HistoryMessageReplyMarkup>()) {
|
||||||
|
markup->create(*config.markup);
|
||||||
}
|
}
|
||||||
initTime();
|
initTime();
|
||||||
}
|
}
|
||||||
|
@ -6368,7 +6444,6 @@ int32 HistoryMessage::plainMaxWidth() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessage::initDimensions() {
|
void HistoryMessage::initDimensions() {
|
||||||
auto *reply = Get<HistoryMessageReply>();
|
|
||||||
if (drawBubble()) {
|
if (drawBubble()) {
|
||||||
auto fwd = Get<HistoryMessageForwarded>();
|
auto fwd = Get<HistoryMessageForwarded>();
|
||||||
auto via = Get<HistoryMessageVia>();
|
auto via = Get<HistoryMessageVia>();
|
||||||
|
@ -6427,7 +6502,7 @@ void HistoryMessage::initDimensions() {
|
||||||
_maxw = _media->maxWidth();
|
_maxw = _media->maxWidth();
|
||||||
_minh = _media->minHeight();
|
_minh = _media->minHeight();
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (auto *reply = Get<HistoryMessageReply>()) {
|
||||||
reply->updateName();
|
reply->updateName();
|
||||||
if (!_media) {
|
if (!_media) {
|
||||||
int replyw = st::msgPadding.left() + reply->_maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right();
|
int replyw = st::msgPadding.left() + reply->_maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right();
|
||||||
|
@ -6437,6 +6512,8 @@ void HistoryMessage::initDimensions() {
|
||||||
if (replyw > _maxw) _maxw = replyw;
|
if (replyw > _maxw) _maxw = replyw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (HistoryMessageReplyMarkup *markup = inlineReplyMarkup()) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const {
|
void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const {
|
||||||
|
@ -6741,11 +6818,15 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
|
||||||
|
|
||||||
textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle));
|
textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle));
|
||||||
|
|
||||||
//if (displayFromPhoto()) {
|
if (auto *markup = inlineReplyMarkup()) {
|
||||||
// int photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
|
height -= markup->rows.size() * (st::msgBotKbButton.margin + st::msgBotKbButton.height);
|
||||||
// int phototop = marginTop();
|
int y = marginTop() + height + st::msgBotKbButton.margin;
|
||||||
// author()->paintUserpic(p, st::msgPhotoSize, photoleft, phototop);
|
for_const (const HistoryMessageReplyMarkup::ButtonRow &row, markup->rows) {
|
||||||
//}
|
for_const (const HistoryMessageReplyMarkup::Button &button, row) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto *reply = Get<HistoryMessageReply>();
|
auto *reply = Get<HistoryMessageReply>();
|
||||||
if (reply) {
|
if (reply) {
|
||||||
|
@ -6945,6 +7026,10 @@ int HistoryMessage::resizeGetHeight_(int width) {
|
||||||
} else {
|
} else {
|
||||||
_height = _media->resize(width, this);
|
_height = _media->resize(width, this);
|
||||||
}
|
}
|
||||||
|
if (HistoryMessageReplyMarkup *markup = inlineReplyMarkup()) {
|
||||||
|
_height += (st::msgBotKbButton.margin + st::msgBotKbButton.height) * markup->rows.size();
|
||||||
|
}
|
||||||
|
|
||||||
_height += marginTop() + marginBottom();
|
_height += marginTop() + marginBottom();
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
@ -6996,6 +7081,10 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
|
||||||
//}
|
//}
|
||||||
if (width < 1) return;
|
if (width < 1) return;
|
||||||
|
|
||||||
|
if (const HistoryMessageReplyMarkup *markup = inlineReplyMarkup()) {
|
||||||
|
height -= (st::msgBotKbButton.margin + st::msgBotKbButton.height) * markup->rows.size();
|
||||||
|
}
|
||||||
|
|
||||||
if (drawBubble()) {
|
if (drawBubble()) {
|
||||||
auto *fwd = Get<HistoryMessageForwarded>();
|
auto *fwd = Get<HistoryMessageForwarded>();
|
||||||
auto *via = Get<HistoryMessageVia>();
|
auto *via = Get<HistoryMessageVia>();
|
||||||
|
@ -7172,9 +7261,6 @@ HistoryMessage::~HistoryMessage() {
|
||||||
if (auto *reply = Get<HistoryMessageReply>()) {
|
if (auto *reply = Get<HistoryMessageReply>()) {
|
||||||
reply->clearData(this);
|
reply->clearData(this);
|
||||||
}
|
}
|
||||||
if (_flags & MTPDmessage::Flag::f_reply_markup) {
|
|
||||||
App::clearReplyMarkup(channelId(), id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryService::setMessageByAction(const MTPmessageAction &action) {
|
void HistoryService::setMessageByAction(const MTPmessageAction &action) {
|
||||||
|
|
|
@ -966,8 +966,6 @@ enum HistoryItemType {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryMessageVia : public BaseComponent<HistoryMessageVia> {
|
struct HistoryMessageVia : public BaseComponent<HistoryMessageVia> {
|
||||||
HistoryMessageVia(Composer*) {
|
|
||||||
}
|
|
||||||
void create(int32 userId);
|
void create(int32 userId);
|
||||||
void resize(int32 availw) const;
|
void resize(int32 availw) const;
|
||||||
|
|
||||||
|
@ -979,18 +977,12 @@ struct HistoryMessageVia : public BaseComponent<HistoryMessageVia> {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryMessageViews : public BaseComponent<HistoryMessageViews> {
|
struct HistoryMessageViews : public BaseComponent<HistoryMessageViews> {
|
||||||
HistoryMessageViews(Composer*) {
|
|
||||||
}
|
|
||||||
|
|
||||||
QString _viewsText;
|
QString _viewsText;
|
||||||
int _views = 0;
|
int _views = 0;
|
||||||
int _viewsWidth = 0;
|
int _viewsWidth = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryMessageSigned : public BaseComponent<HistoryMessageSigned> {
|
struct HistoryMessageSigned : public BaseComponent<HistoryMessageSigned> {
|
||||||
HistoryMessageSigned(Composer*) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void create(UserData *from, const QDateTime &date);
|
void create(UserData *from, const QDateTime &date);
|
||||||
int maxWidth() const;
|
int maxWidth() const;
|
||||||
|
|
||||||
|
@ -998,8 +990,6 @@ struct HistoryMessageSigned : public BaseComponent<HistoryMessageSigned> {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryMessageForwarded : public BaseComponent<HistoryMessageForwarded> {
|
struct HistoryMessageForwarded : public BaseComponent<HistoryMessageForwarded> {
|
||||||
HistoryMessageForwarded(Composer*) {
|
|
||||||
}
|
|
||||||
void create(const HistoryMessageVia *via) const;
|
void create(const HistoryMessageVia *via) const;
|
||||||
|
|
||||||
PeerData *_authorOriginal = nullptr;
|
PeerData *_authorOriginal = nullptr;
|
||||||
|
@ -1009,24 +999,23 @@ struct HistoryMessageForwarded : public BaseComponent<HistoryMessageForwarded> {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryMessageReply : public BaseComponent<HistoryMessageReply> {
|
struct HistoryMessageReply : public BaseComponent<HistoryMessageReply> {
|
||||||
HistoryMessageReply(Composer*) {
|
|
||||||
}
|
|
||||||
HistoryMessageReply &operator=(HistoryMessageReply &&other) {
|
HistoryMessageReply &operator=(HistoryMessageReply &&other) {
|
||||||
replyToMsgId = other.replyToMsgId;
|
replyToMsgId = other.replyToMsgId;
|
||||||
std::swap(replyToMsg, other.replyToMsg);
|
std::swap(replyToMsg, other.replyToMsg);
|
||||||
replyToLnk = std11::move(other.replyToLnk);
|
replyToLnk = std_::move(other.replyToLnk);
|
||||||
replyToName = std11::move(other.replyToName);
|
replyToName = std_::move(other.replyToName);
|
||||||
replyToText = std11::move(other.replyToText);
|
replyToText = std_::move(other.replyToText);
|
||||||
replyToVersion = other.replyToVersion;
|
replyToVersion = other.replyToVersion;
|
||||||
_maxReplyWidth = other._maxReplyWidth;
|
_maxReplyWidth = other._maxReplyWidth;
|
||||||
std::swap(_replyToVia, other._replyToVia);
|
_replyToVia = std_::move(other._replyToVia);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
~HistoryMessageReply() {
|
~HistoryMessageReply() {
|
||||||
// clearData() should be called by holder
|
// clearData() should be called by holder
|
||||||
t_assert(replyToMsg == nullptr);
|
t_assert(replyToMsg == nullptr);
|
||||||
t_assert(_replyToVia == nullptr);
|
t_assert(_replyToVia.data() == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updateData(HistoryMessage *holder, bool force = false);
|
bool updateData(HistoryMessage *holder, bool force = false);
|
||||||
void clearData(HistoryMessage *holder); // must be called before destructor
|
void clearData(HistoryMessage *holder); // must be called before destructor
|
||||||
|
|
||||||
|
@ -1058,12 +1047,45 @@ struct HistoryMessageReply : public BaseComponent<HistoryMessageReply> {
|
||||||
mutable Text replyToName, replyToText;
|
mutable Text replyToName, replyToText;
|
||||||
mutable int replyToVersion = 0;
|
mutable int replyToVersion = 0;
|
||||||
mutable int _maxReplyWidth = 0;
|
mutable int _maxReplyWidth = 0;
|
||||||
HistoryMessageVia *_replyToVia = nullptr;
|
UniquePointer<HistoryMessageVia> _replyToVia;
|
||||||
int toWidth = 0;
|
int toWidth = 0;
|
||||||
};
|
};
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(HistoryMessageReply::PaintFlags);
|
Q_DECLARE_OPERATORS_FOR_FLAGS(HistoryMessageReply::PaintFlags);
|
||||||
|
|
||||||
class HistoryDependentItemCallback : public SharedCallback2<void, ChannelData*, MsgId> {
|
class ReplyKeyboard {
|
||||||
|
public:
|
||||||
|
ReplyKeyboard(HistoryItem *item);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HistoryMessageReplyMarkup : public BaseComponent<HistoryMessageReplyMarkup> {
|
||||||
|
HistoryMessageReplyMarkup() = default;
|
||||||
|
HistoryMessageReplyMarkup(MTPDreplyKeyboardMarkup::Flags f) : flags(f) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void create(const MTPReplyMarkup &markup);
|
||||||
|
|
||||||
|
struct Button {
|
||||||
|
enum Type {
|
||||||
|
Default,
|
||||||
|
Url,
|
||||||
|
Callback,
|
||||||
|
RequestPhone,
|
||||||
|
RequestLocation,
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
QString text, url;
|
||||||
|
};
|
||||||
|
using ButtonRow = QVector<Button>;
|
||||||
|
using ButtonRows = QVector<ButtonRow>;
|
||||||
|
|
||||||
|
ButtonRows rows;
|
||||||
|
MTPDreplyKeyboardMarkup::Flags flags = 0;
|
||||||
|
|
||||||
|
ReplyKeyboard *inlineKeyboard = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HistoryDependentItemCallback : public SharedCallback<void, ChannelData*, MsgId> {
|
||||||
public:
|
public:
|
||||||
HistoryDependentItemCallback(FullMsgId dependent) : _dependent(dependent) {
|
HistoryDependentItemCallback(FullMsgId dependent) : _dependent(dependent) {
|
||||||
}
|
}
|
||||||
|
@ -1077,8 +1099,6 @@ private:
|
||||||
// any HistoryItem can have this Interface for
|
// any HistoryItem can have this Interface for
|
||||||
// displaying the day mark above the message
|
// displaying the day mark above the message
|
||||||
struct HistoryMessageDate : public BaseComponent<HistoryMessageDate> {
|
struct HistoryMessageDate : public BaseComponent<HistoryMessageDate> {
|
||||||
HistoryMessageDate(Composer*) {
|
|
||||||
}
|
|
||||||
void init(const QDateTime &date);
|
void init(const QDateTime &date);
|
||||||
|
|
||||||
int height() const;
|
int height() const;
|
||||||
|
@ -1091,8 +1111,6 @@ struct HistoryMessageDate : public BaseComponent<HistoryMessageDate> {
|
||||||
// any HistoryItem can have this Interface for
|
// any HistoryItem can have this Interface for
|
||||||
// displaying the unread messages bar above the message
|
// displaying the unread messages bar above the message
|
||||||
struct HistoryMessageUnreadBar : public BaseComponent<HistoryMessageUnreadBar> {
|
struct HistoryMessageUnreadBar : public BaseComponent<HistoryMessageUnreadBar> {
|
||||||
HistoryMessageUnreadBar(Composer*) {
|
|
||||||
}
|
|
||||||
void init(int count);
|
void init(int count);
|
||||||
|
|
||||||
int height() const;
|
int height() const;
|
||||||
|
@ -1216,8 +1234,27 @@ public:
|
||||||
void markMediaRead() {
|
void markMediaRead() {
|
||||||
_flags &= ~MTPDmessage::Flag::f_media_unread;
|
_flags &= ~MTPDmessage::Flag::f_media_unread;
|
||||||
}
|
}
|
||||||
bool hasReplyMarkup() const {
|
bool definesReplyKeyboard() const {
|
||||||
return _flags & MTPDmessage::Flag::f_reply_markup;
|
if (auto *markup = Get<HistoryMessageReplyMarkup>()) {
|
||||||
|
if (markup->flags & MTPDreplyKeyboardMarkup::Flag::f_inline) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization: don't create markup component for the case
|
||||||
|
// MTPDreplyKeyboardHide with flags = 0, assume it has f_zero flag
|
||||||
|
return (_flags & MTPDmessage::Flag::f_reply_markup);
|
||||||
|
}
|
||||||
|
MTPDreplyKeyboardMarkup::Flags replyKeyboardFlags() const {
|
||||||
|
t_assert(definesReplyKeyboard());
|
||||||
|
if (auto *markup = Get<HistoryMessageReplyMarkup>()) {
|
||||||
|
return markup->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization: don't create markup component for the case
|
||||||
|
// MTPDreplyKeyboardHide with flags = 0, assume it has f_zero flag
|
||||||
|
return qFlags(MTPDreplyKeyboardMarkup_ClientFlag::f_zero);
|
||||||
}
|
}
|
||||||
bool hasTextLinks() const {
|
bool hasTextLinks() const {
|
||||||
return _flags & MTPDmessage_ClientFlag::f_has_text_links;
|
return _flags & MTPDmessage_ClientFlag::f_has_text_links;
|
||||||
|
@ -1510,7 +1547,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should be used only in previousItemChanged()
|
// this should be used only in previousItemChanged()
|
||||||
// to add required bits to the Interfaces mask
|
// to add required bits to the Composer mask
|
||||||
// after that always use Has<HistoryMessageDate>()
|
// after that always use Has<HistoryMessageDate>()
|
||||||
bool displayDate() const {
|
bool displayDate() const {
|
||||||
if (HistoryItem *prev = previous()) {
|
if (HistoryItem *prev = previous()) {
|
||||||
|
@ -1520,10 +1557,22 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should be used only in previousItemChanged() or when
|
// this should be used only in previousItemChanged() or when
|
||||||
// HistoryMessageDate or HistoryMessageUnreadBar bit is changed in the Interfaces mask
|
// HistoryMessageDate or HistoryMessageUnreadBar bit is changed in the Composer mask
|
||||||
// then the result should be cached in a client side flag MTPDmessage_ClientFlag::f_attach_to_previous
|
// then the result should be cached in a client side flag MTPDmessage_ClientFlag::f_attach_to_previous
|
||||||
void recountAttachToPrevious();
|
void recountAttachToPrevious();
|
||||||
|
|
||||||
|
const HistoryMessageReplyMarkup *inlineReplyMarkup() const {
|
||||||
|
if (auto *markup = Get<HistoryMessageReplyMarkup>()) {
|
||||||
|
if (markup->flags & MTPDreplyKeyboardMarkup::Flag::f_inline) {
|
||||||
|
return markup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
HistoryMessageReplyMarkup *inlineReplyMarkup() {
|
||||||
|
return const_cast<HistoryMessageReplyMarkup*>(static_cast<const HistoryItem*>(this)->inlineReplyMarkup());
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// make all the constructors in HistoryItem children protected
|
// make all the constructors in HistoryItem children protected
|
||||||
|
@ -1929,8 +1978,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryDocumentThumbed : public BaseComponent<HistoryDocumentThumbed> {
|
struct HistoryDocumentThumbed : public BaseComponent<HistoryDocumentThumbed> {
|
||||||
HistoryDocumentThumbed(Composer*) {
|
|
||||||
}
|
|
||||||
TextLinkPtr _linksavel, _linkcancell;
|
TextLinkPtr _linksavel, _linkcancell;
|
||||||
int _thumbw = 0;
|
int _thumbw = 0;
|
||||||
|
|
||||||
|
@ -1938,13 +1985,9 @@ struct HistoryDocumentThumbed : public BaseComponent<HistoryDocumentThumbed> {
|
||||||
mutable QString _link;
|
mutable QString _link;
|
||||||
};
|
};
|
||||||
struct HistoryDocumentCaptioned : public BaseComponent<HistoryDocumentCaptioned> {
|
struct HistoryDocumentCaptioned : public BaseComponent<HistoryDocumentCaptioned> {
|
||||||
HistoryDocumentCaptioned(Composer*) : _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
|
Text _caption = { st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right() };
|
||||||
}
|
|
||||||
Text _caption;
|
|
||||||
};
|
};
|
||||||
struct HistoryDocumentNamed : public BaseComponent<HistoryDocumentNamed> {
|
struct HistoryDocumentNamed : public BaseComponent<HistoryDocumentNamed> {
|
||||||
HistoryDocumentNamed(Composer*) {
|
|
||||||
}
|
|
||||||
QString _name;
|
QString _name;
|
||||||
int _namew = 0;
|
int _namew = 0;
|
||||||
};
|
};
|
||||||
|
@ -1957,8 +2000,6 @@ struct HistoryDocumentVoicePlayback {
|
||||||
Animation _a_progress;
|
Animation _a_progress;
|
||||||
};
|
};
|
||||||
struct HistoryDocumentVoice : public BaseComponent<HistoryDocumentVoice> {
|
struct HistoryDocumentVoice : public BaseComponent<HistoryDocumentVoice> {
|
||||||
HistoryDocumentVoice(Composer*) {
|
|
||||||
}
|
|
||||||
HistoryDocumentVoice &operator=(HistoryDocumentVoice &&other) {
|
HistoryDocumentVoice &operator=(HistoryDocumentVoice &&other) {
|
||||||
std::swap(_playback, other._playback);
|
std::swap(_playback, other._playback);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -2045,7 +2086,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void createInterfaces(bool caption);
|
void createComponents(bool caption);
|
||||||
const HistoryItem *_parent;
|
const HistoryItem *_parent;
|
||||||
DocumentData *_data;
|
DocumentData *_data;
|
||||||
|
|
||||||
|
@ -2623,8 +2664,17 @@ protected:
|
||||||
QString _timeText;
|
QString _timeText;
|
||||||
int _timeWidth = 0;
|
int _timeWidth = 0;
|
||||||
|
|
||||||
void createInterfacesHelper(MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId);
|
struct CreateConfig {
|
||||||
void createInterfaces(MsgId replyTo, int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal = 0, const PeerId &fromIdOriginal = 0, MsgId originalId = 0);
|
MsgId replyTo = 0;
|
||||||
|
UserId viaBotId = 0;
|
||||||
|
int viewsCount = -1;
|
||||||
|
PeerId authorIdOriginal = 0;
|
||||||
|
PeerId fromIdOriginal = 0;
|
||||||
|
MsgId originalId = 0;
|
||||||
|
const MTPReplyMarkup *markup = nullptr;
|
||||||
|
};
|
||||||
|
void createComponentsHelper(MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId);
|
||||||
|
void createComponents(const CreateConfig &config);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2659,9 +2709,6 @@ inline MTPDmessage::Flags newForwardedFlags(PeerData *p, int32 from, HistoryMess
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HistoryServicePinned : public BaseComponent<HistoryServicePinned> {
|
struct HistoryServicePinned : public BaseComponent<HistoryServicePinned> {
|
||||||
HistoryServicePinned(Composer*) {
|
|
||||||
}
|
|
||||||
|
|
||||||
MsgId msgId = 0;
|
MsgId msgId = 0;
|
||||||
HistoryItem *msg = nullptr;
|
HistoryItem *msg = nullptr;
|
||||||
TextLinkPtr lnk;
|
TextLinkPtr lnk;
|
||||||
|
|
|
@ -2241,8 +2241,8 @@ void BotKeyboard::resizeEvent(QResizeEvent *e) {
|
||||||
float64 widthForText = width() - (s * _st->margin + st::botKbScroll.width + s * 2 * _st->padding), widthOfText = 0.;
|
float64 widthForText = width() - (s * _st->margin + st::botKbScroll.width + s * 2 * _st->padding), widthOfText = 0.;
|
||||||
for (; j != s; ++j) {
|
for (; j != s; ++j) {
|
||||||
Button &btn(_btns[i][j]);
|
Button &btn(_btns[i][j]);
|
||||||
if (btn.text.isEmpty()) btn.text.setText(st::botKbFont, textOneLine(btn.cmd), _textPlainOptions);
|
if (btn.text.isEmpty()) btn.text.setText(st::botKbFont, textOneLine(btn.button.text), _textPlainOptions);
|
||||||
if (!btn.cwidth) btn.cwidth = btn.cmd.size();
|
if (!btn.cwidth) btn.cwidth = btn.button.text.size();
|
||||||
if (!btn.cwidth) btn.cwidth = 1;
|
if (!btn.cwidth) btn.cwidth = 1;
|
||||||
widthOfText += qMax(btn.text.maxWidth(), 1);
|
widthOfText += qMax(btn.text.maxWidth(), 1);
|
||||||
}
|
}
|
||||||
|
@ -2282,8 +2282,7 @@ void BotKeyboard::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
if (_sel == down && down >= 0) {
|
if (_sel == down && down >= 0) {
|
||||||
int row = (down / MatrixRowShift), col = down % MatrixRowShift;
|
int row = (down / MatrixRowShift), col = down % MatrixRowShift;
|
||||||
QString cmd(_btns.at(row).at(col).cmd);
|
App::activateBotCommand(_btns.at(row).at(col).button, _wasForMsgId.msg);
|
||||||
App::sendBotCommand(cmd, _wasForMsgId.msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2293,30 +2292,32 @@ void BotKeyboard::leaveEvent(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotKeyboard::updateMarkup(HistoryItem *to) {
|
bool BotKeyboard::updateMarkup(HistoryItem *to) {
|
||||||
if (to && to->hasReplyMarkup()) {
|
if (to && to->definesReplyKeyboard()) {
|
||||||
if (_wasForMsgId == FullMsgId(to->channelId(), to->id)) return false;
|
if (_wasForMsgId == FullMsgId(to->channelId(), to->id)) return false;
|
||||||
|
|
||||||
_wasForMsgId = FullMsgId(to->channelId(), to->id);
|
_wasForMsgId = FullMsgId(to->channelId(), to->id);
|
||||||
clearSelection();
|
clearSelection();
|
||||||
_btns.clear();
|
_btns.clear();
|
||||||
const ReplyMarkup &markup(App::replyMarkup(to->channelId(), to->id));
|
|
||||||
_forceReply = markup.flags & MTPDreplyKeyboardMarkup_ClientFlag::f_force_reply;
|
|
||||||
_maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup::Flag::f_resize);
|
|
||||||
_singleUse = _forceReply || (markup.flags & MTPDreplyKeyboardMarkup::Flag::f_single_use);
|
|
||||||
|
|
||||||
const ReplyMarkup::Commands &commands(markup.commands);
|
const auto *markup = to->Get<HistoryMessageReplyMarkup>();
|
||||||
if (!commands.isEmpty()) {
|
_forceReply = markup->flags & MTPDreplyKeyboardMarkup_ClientFlag::f_force_reply;
|
||||||
int32 i = 0, l = qMin(commands.size(), 512);
|
_maximizeSize = !(markup->flags & MTPDreplyKeyboardMarkup::Flag::f_resize);
|
||||||
_btns.reserve(l);
|
_singleUse = _forceReply || (markup->flags & MTPDreplyKeyboardMarkup::Flag::f_single_use);
|
||||||
for (; i != l; ++i) {
|
|
||||||
const QList<QString> &row(commands.at(i));
|
const HistoryMessageReplyMarkup::ButtonRows &rows(markup->rows);
|
||||||
|
if (!rows.isEmpty()) {
|
||||||
|
_btns.reserve(rows.size());
|
||||||
|
for_const (const HistoryMessageReplyMarkup::ButtonRow &row, rows) {
|
||||||
QList<Button> btns;
|
QList<Button> btns;
|
||||||
int32 j = 0, s = qMin(row.size(), 16);
|
btns.reserve(row.size());
|
||||||
btns.reserve(s);
|
for_const (const HistoryMessageReplyMarkup::Button &button, row) {
|
||||||
for (; j != s; ++j) {
|
btns.push_back(Button(button));
|
||||||
btns.push_back(Button(row.at(j)));
|
if (btns.size() > 16) break;
|
||||||
|
}
|
||||||
|
if (!btns.isEmpty()) {
|
||||||
|
_btns.push_back(btns);
|
||||||
|
if (_btns.size() > 512) break;
|
||||||
}
|
}
|
||||||
if (!btns.isEmpty()) _btns.push_back(btns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStyle();
|
updateStyle();
|
||||||
|
@ -2391,7 +2392,7 @@ void BotKeyboard::updateStyle(int32 w) {
|
||||||
int32 widthLeft = w - (s * _st->margin + st::botKbScroll.width + s * 2 * _st->padding);
|
int32 widthLeft = w - (s * _st->margin + st::botKbScroll.width + s * 2 * _st->padding);
|
||||||
for (; j != s; ++j) {
|
for (; j != s; ++j) {
|
||||||
Button &btn(_btns[i][j]);
|
Button &btn(_btns[i][j]);
|
||||||
if (btn.text.isEmpty()) btn.text.setText(st::botKbFont, textOneLine(btn.cmd), _textPlainOptions);
|
if (btn.text.isEmpty()) btn.text.setText(st::botKbFont, textOneLine(btn.button.text), _textPlainOptions);
|
||||||
widthLeft -= qMax(btn.text.maxWidth(), 1);
|
widthLeft -= qMax(btn.text.maxWidth(), 1);
|
||||||
if (widthLeft < 0) break;
|
if (widthLeft < 0) break;
|
||||||
}
|
}
|
||||||
|
@ -2424,7 +2425,7 @@ QString BotKeyboard::tooltipText() const {
|
||||||
if (_sel >= 0) {
|
if (_sel >= 0) {
|
||||||
int row = (_sel / MatrixRowShift), col = _sel % MatrixRowShift;
|
int row = (_sel / MatrixRowShift), col = _sel % MatrixRowShift;
|
||||||
if (!_btns.at(row).at(col).full) {
|
if (!_btns.at(row).at(col).full) {
|
||||||
return _btns.at(row).at(col).cmd;
|
return _btns.at(row).at(col).button.text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
|
|
|
@ -332,14 +332,16 @@ private:
|
||||||
|
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
struct Button {
|
struct Button {
|
||||||
Button(const QString &str = QString()) : cmd(str), text(1), cwidth(0), hover(0), full(true) {
|
Button() = default;
|
||||||
|
Button(const HistoryMessageReplyMarkup::Button &button) : button(button) {
|
||||||
}
|
}
|
||||||
|
HistoryMessageReplyMarkup::Button button;
|
||||||
|
|
||||||
|
Text text = { 1 };
|
||||||
QRect rect;
|
QRect rect;
|
||||||
QString cmd;
|
int cwidth = 0;
|
||||||
Text text;
|
float64 hover = 0.;
|
||||||
int32 cwidth;
|
bool full = true;
|
||||||
float64 hover;
|
|
||||||
bool full;
|
|
||||||
};
|
};
|
||||||
int32 _sel, _down;
|
int32 _sel, _down;
|
||||||
QList<QList<Button> > _btns;
|
QList<QList<Button> > _btns;
|
||||||
|
@ -781,7 +783,7 @@ private:
|
||||||
void destroyPinnedBar();
|
void destroyPinnedBar();
|
||||||
void unpinDone(const MTPUpdates &updates);
|
void unpinDone(const MTPUpdates &updates);
|
||||||
|
|
||||||
class ReplyEditMessageDataCallback : public SharedCallback2<void, ChannelData*, MsgId> {
|
class ReplyEditMessageDataCallback : public SharedCallback<void, ChannelData*, MsgId> {
|
||||||
public:
|
public:
|
||||||
void call(ChannelData *channel, MsgId msgId) const override;
|
void call(ChannelData *channel, MsgId msgId) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -271,20 +271,8 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class OverviewItemInfo : public BaseComponent<OverviewItemInfo> {
|
struct OverviewItemInfo : public BaseComponent<OverviewItemInfo> {
|
||||||
public:
|
int top = 0;
|
||||||
OverviewItemInfo(Composer*) {
|
|
||||||
}
|
|
||||||
int top() const {
|
|
||||||
return _top;
|
|
||||||
}
|
|
||||||
void setTop(int top) {
|
|
||||||
_top = top;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int _top = 0;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LayoutOverviewDate : public LayoutItem {
|
class LayoutOverviewDate : public LayoutItem {
|
||||||
|
|
|
@ -349,7 +349,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||||
mtpTypeId(mtpc_invokeWithLayer18),
|
mtpTypeId(mtpc_invokeWithLayer18),
|
||||||
};
|
};
|
||||||
static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||||
static const mtpPrime mtpCurrentLayer = 50;
|
static const mtpPrime mtpCurrentLayer = 51;
|
||||||
|
|
||||||
template <typename bareT>
|
template <typename bareT>
|
||||||
class MTPBoxed : public bareT {
|
class MTPBoxed : public bareT {
|
||||||
|
|
|
@ -771,6 +771,7 @@ for childName in parentFlagsList:
|
||||||
print('Flag ' + flag + ' has different value in ' + parentName + ' which should be a flags-parent of ' + childName);
|
print('Flag ' + flag + ' has different value in ' + parentName + ' which should be a flags-parent of ' + childName);
|
||||||
error
|
error
|
||||||
inlineMethods += 'inline ' + parentName + '::Flags mtpCastFlags(' + childName + '::Flags flags) { return ' + parentName + '::Flags(QFlag(flags)); }\n';
|
inlineMethods += 'inline ' + parentName + '::Flags mtpCastFlags(' + childName + '::Flags flags) { return ' + parentName + '::Flags(QFlag(flags)); }\n';
|
||||||
|
inlineMethods += 'inline ' + parentName + '::Flags mtpCastFlags(MTPflags<' + childName + '::Flags> flags) { return mtpCastFlags(flags.v); }\n';
|
||||||
|
|
||||||
# manual types added here
|
# manual types added here
|
||||||
textSerializeMethods += 'void _serialize_rpc_result(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n';
|
textSerializeMethods += 'void _serialize_rpc_result(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n';
|
||||||
|
|
|
@ -32872,13 +32872,21 @@ inline MTPauth_sentCodeType MTP_auth_sentCodeTypeFlashCall(const MTPstring &_pat
|
||||||
return MTP::internal::TypeCreator::new_auth_sentCodeTypeFlashCall(_pattern);
|
return MTP::internal::TypeCreator::new_auth_sentCodeTypeFlashCall(_pattern);
|
||||||
}
|
}
|
||||||
inline MTPDmessage::Flags mtpCastFlags(MTPDmessageService::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
|
inline MTPDmessage::Flags mtpCastFlags(MTPDmessageService::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
|
||||||
|
inline MTPDmessage::Flags mtpCastFlags(MTPflags<MTPDmessageService::Flags> flags) { return mtpCastFlags(flags.v); }
|
||||||
inline MTPDmessage::Flags mtpCastFlags(MTPDupdateShortMessage::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
|
inline MTPDmessage::Flags mtpCastFlags(MTPDupdateShortMessage::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
|
||||||
|
inline MTPDmessage::Flags mtpCastFlags(MTPflags<MTPDupdateShortMessage::Flags> flags) { return mtpCastFlags(flags.v); }
|
||||||
inline MTPDmessage::Flags mtpCastFlags(MTPDupdateShortChatMessage::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
|
inline MTPDmessage::Flags mtpCastFlags(MTPDupdateShortChatMessage::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
|
||||||
|
inline MTPDmessage::Flags mtpCastFlags(MTPflags<MTPDupdateShortChatMessage::Flags> flags) { return mtpCastFlags(flags.v); }
|
||||||
inline MTPDmessage::Flags mtpCastFlags(MTPDupdateShortSentMessage::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
|
inline MTPDmessage::Flags mtpCastFlags(MTPDupdateShortSentMessage::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
|
||||||
|
inline MTPDmessage::Flags mtpCastFlags(MTPflags<MTPDupdateShortSentMessage::Flags> flags) { return mtpCastFlags(flags.v); }
|
||||||
inline MTPDreplyKeyboardMarkup::Flags mtpCastFlags(MTPDreplyKeyboardHide::Flags flags) { return MTPDreplyKeyboardMarkup::Flags(QFlag(flags)); }
|
inline MTPDreplyKeyboardMarkup::Flags mtpCastFlags(MTPDreplyKeyboardHide::Flags flags) { return MTPDreplyKeyboardMarkup::Flags(QFlag(flags)); }
|
||||||
|
inline MTPDreplyKeyboardMarkup::Flags mtpCastFlags(MTPflags<MTPDreplyKeyboardHide::Flags> flags) { return mtpCastFlags(flags.v); }
|
||||||
inline MTPDreplyKeyboardMarkup::Flags mtpCastFlags(MTPDreplyKeyboardForceReply::Flags flags) { return MTPDreplyKeyboardMarkup::Flags(QFlag(flags)); }
|
inline MTPDreplyKeyboardMarkup::Flags mtpCastFlags(MTPDreplyKeyboardForceReply::Flags flags) { return MTPDreplyKeyboardMarkup::Flags(QFlag(flags)); }
|
||||||
|
inline MTPDreplyKeyboardMarkup::Flags mtpCastFlags(MTPflags<MTPDreplyKeyboardForceReply::Flags> flags) { return mtpCastFlags(flags.v); }
|
||||||
inline MTPDpeerNotifySettings::Flags mtpCastFlags(MTPDinputPeerNotifySettings::Flags flags) { return MTPDpeerNotifySettings::Flags(QFlag(flags)); }
|
inline MTPDpeerNotifySettings::Flags mtpCastFlags(MTPDinputPeerNotifySettings::Flags flags) { return MTPDpeerNotifySettings::Flags(QFlag(flags)); }
|
||||||
|
inline MTPDpeerNotifySettings::Flags mtpCastFlags(MTPflags<MTPDinputPeerNotifySettings::Flags> flags) { return mtpCastFlags(flags.v); }
|
||||||
inline MTPDinputPeerNotifySettings::Flags mtpCastFlags(MTPDpeerNotifySettings::Flags flags) { return MTPDinputPeerNotifySettings::Flags(QFlag(flags)); }
|
inline MTPDinputPeerNotifySettings::Flags mtpCastFlags(MTPDpeerNotifySettings::Flags flags) { return MTPDinputPeerNotifySettings::Flags(QFlag(flags)); }
|
||||||
|
inline MTPDinputPeerNotifySettings::Flags mtpCastFlags(MTPflags<MTPDpeerNotifySettings::Flags> flags) { return mtpCastFlags(flags.v); }
|
||||||
|
|
||||||
// Human-readable text serialization
|
// Human-readable text serialization
|
||||||
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons);
|
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons);
|
||||||
|
|
|
@ -354,7 +354,7 @@ void OverviewInner::repaintItem(MsgId itemId, int32 itemIndex) {
|
||||||
int32 row = (_photosToAdd + shownAtIndex) / _photosInRow, col = (_photosToAdd + shownAtIndex) % _photosInRow;
|
int32 row = (_photosToAdd + shownAtIndex) / _photosInRow, col = (_photosToAdd + shownAtIndex) % _photosInRow;
|
||||||
update(int32(col * w), _marginTop + int32(row * vsize), qCeil(w), vsize);
|
update(int32(col * w), _marginTop + int32(row * vsize), qCeil(w), vsize);
|
||||||
} else {
|
} else {
|
||||||
int32 top = _items.at(itemIndex)->Get<OverviewItemInfo>()->top();
|
int32 top = _items.at(itemIndex)->Get<OverviewItemInfo>()->top;
|
||||||
if (_reversed) top = _height - top;
|
if (_reversed) top = _height - top;
|
||||||
update(_rowsLeft, _marginTop + top, _rowWidth, _items.at(itemIndex)->height());
|
update(_rowsLeft, _marginTop + top, _rowWidth, _items.at(itemIndex)->height());
|
||||||
}
|
}
|
||||||
|
@ -727,7 +727,7 @@ QPoint OverviewInner::mapMouseToItem(QPoint p, MsgId itemId, int32 itemIndex) {
|
||||||
p.setX(p.x() - int32(col * w) - st::overviewPhotoSkip);
|
p.setX(p.x() - int32(col * w) - st::overviewPhotoSkip);
|
||||||
p.setY(p.y() - _marginTop - row * (_rowWidth + st::overviewPhotoSkip) - st::overviewPhotoSkip);
|
p.setY(p.y() - _marginTop - row * (_rowWidth + st::overviewPhotoSkip) - st::overviewPhotoSkip);
|
||||||
} else {
|
} else {
|
||||||
int32 top = _items.at(itemIndex)->Get<OverviewItemInfo>()->top();
|
int32 top = _items.at(itemIndex)->Get<OverviewItemInfo>()->top;
|
||||||
if (_reversed) top = _height - top;
|
if (_reversed) top = _height - top;
|
||||||
p.setY(p.y() - _marginTop - top);
|
p.setY(p.y() - _marginTop - top);
|
||||||
}
|
}
|
||||||
|
@ -763,7 +763,7 @@ int32 OverviewInner::itemTop(const FullMsgId &msgId) const {
|
||||||
int32 itemIndex = -1;
|
int32 itemIndex = -1;
|
||||||
fixItemIndex(itemIndex, (msgId.channel == _channel) ? msgId.msg : ((_migrated && msgId.channel == _migrated->channelId()) ? -msgId.msg : 0));
|
fixItemIndex(itemIndex, (msgId.channel == _channel) ? msgId.msg : ((_migrated && msgId.channel == _migrated->channelId()) ? -msgId.msg : 0));
|
||||||
if (itemIndex >= 0) {
|
if (itemIndex >= 0) {
|
||||||
int32 top = _items.at(itemIndex)->Get<OverviewItemInfo>()->top();
|
int32 top = _items.at(itemIndex)->Get<OverviewItemInfo>()->top;
|
||||||
if (_reversed) top = _height - top;
|
if (_reversed) top = _height - top;
|
||||||
return _marginTop + top;
|
return _marginTop + top;
|
||||||
}
|
}
|
||||||
|
@ -883,11 +883,11 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
|
||||||
int32 y = 0, w = _rowWidth;
|
int32 y = 0, w = _rowWidth;
|
||||||
for (int32 j = 0, l = _items.size(); j < l; ++j) {
|
for (int32 j = 0, l = _items.size(); j < l; ++j) {
|
||||||
int32 i = _reversed ? (l - j - 1) : j, nexti = _reversed ? (i - 1) : (i + 1);
|
int32 i = _reversed ? (l - j - 1) : j, nexti = _reversed ? (i - 1) : (i + 1);
|
||||||
int32 nextItemTop = (j + 1 == l) ? (_reversed ? 0 : _height) : _items.at(nexti)->Get<OverviewItemInfo>()->top();
|
int32 nextItemTop = (j + 1 == l) ? (_reversed ? 0 : _height) : _items.at(nexti)->Get<OverviewItemInfo>()->top;
|
||||||
if (_reversed) nextItemTop = _height - nextItemTop;
|
if (_reversed) nextItemTop = _height - nextItemTop;
|
||||||
if (_marginTop + nextItemTop > r.top()) {
|
if (_marginTop + nextItemTop > r.top()) {
|
||||||
OverviewItemInfo *info = _items.at(i)->Get<OverviewItemInfo>();
|
OverviewItemInfo *info = _items.at(i)->Get<OverviewItemInfo>();
|
||||||
int32 curY = info->top();
|
int32 curY = info->top;
|
||||||
if (_reversed) curY = _height - curY;
|
if (_reversed) curY = _height - curY;
|
||||||
if (_marginTop + curY >= r.y() + r.height()) break;
|
if (_marginTop + curY >= r.y() + r.height()) break;
|
||||||
|
|
||||||
|
@ -948,10 +948,10 @@ void OverviewInner::onUpdateSelected() {
|
||||||
for (int32 j = 0, l = _items.size(); j < l; ++j) {
|
for (int32 j = 0, l = _items.size(); j < l; ++j) {
|
||||||
bool lastItem = (j + 1 == l);
|
bool lastItem = (j + 1 == l);
|
||||||
int32 i = _reversed ? (l - j - 1) : j, nexti = _reversed ? (i - 1) : (i + 1);
|
int32 i = _reversed ? (l - j - 1) : j, nexti = _reversed ? (i - 1) : (i + 1);
|
||||||
int32 nextItemTop = lastItem ? (_reversed ? 0 : _height) : _items.at(nexti)->Get<OverviewItemInfo>()->top();
|
int32 nextItemTop = lastItem ? (_reversed ? 0 : _height) : _items.at(nexti)->Get<OverviewItemInfo>()->top;
|
||||||
if (_reversed) nextItemTop = _height - nextItemTop;
|
if (_reversed) nextItemTop = _height - nextItemTop;
|
||||||
if (_marginTop + nextItemTop > m.y() || lastItem) {
|
if (_marginTop + nextItemTop > m.y() || lastItem) {
|
||||||
int32 top = _items.at(i)->Get<OverviewItemInfo>()->top();
|
int32 top = _items.at(i)->Get<OverviewItemInfo>()->top;
|
||||||
if (_reversed) top = _height - top;
|
if (_reversed) top = _height - top;
|
||||||
if (!_items.at(i)->toLayoutMediaItem()) { // day item
|
if (!_items.at(i)->toLayoutMediaItem()) { // day item
|
||||||
int32 h = _items.at(i)->height();
|
int32 h = _items.at(i)->height();
|
||||||
|
@ -960,11 +960,11 @@ void OverviewInner::onUpdateSelected() {
|
||||||
if (i > 0 && (beforeItem || i == _items.size() - 1)) {
|
if (i > 0 && (beforeItem || i == _items.size() - 1)) {
|
||||||
--i;
|
--i;
|
||||||
if (!_items.at(i)->toLayoutMediaItem()) break; // wtf
|
if (!_items.at(i)->toLayoutMediaItem()) break; // wtf
|
||||||
top = _items.at(i)->Get<OverviewItemInfo>()->top();
|
top = _items.at(i)->Get<OverviewItemInfo>()->top;
|
||||||
} else if (i < _items.size() - 1 && (!beforeItem || !i)) {
|
} else if (i < _items.size() - 1 && (!beforeItem || !i)) {
|
||||||
++i;
|
++i;
|
||||||
if (!_items.at(i)->toLayoutMediaItem()) break; // wtf
|
if (!_items.at(i)->toLayoutMediaItem()) break; // wtf
|
||||||
top = _items.at(i)->Get<OverviewItemInfo>()->top();
|
top = _items.at(i)->Get<OverviewItemInfo>()->top;
|
||||||
} else {
|
} else {
|
||||||
break; // wtf
|
break; // wtf
|
||||||
}
|
}
|
||||||
|
@ -1386,7 +1386,7 @@ int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeigh
|
||||||
for (int32 i = 0, l = _items.size(); i < l; ++i) {
|
for (int32 i = 0, l = _items.size(); i < l; ++i) {
|
||||||
int32 h = _items.at(i)->resizeGetHeight(_rowWidth);
|
int32 h = _items.at(i)->resizeGetHeight(_rowWidth);
|
||||||
if (resize) {
|
if (resize) {
|
||||||
_items.at(i)->Get<OverviewItemInfo>()->setTop(_height + (_reversed ? h : 0));
|
_items.at(i)->Get<OverviewItemInfo>()->top = _height + (_reversed ? h : 0);
|
||||||
_height += h;
|
_height += h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1720,7 +1720,7 @@ void OverviewInner::mediaOverviewUpdated() {
|
||||||
if (allGood) {
|
if (allGood) {
|
||||||
if (_items.size() > index && complexMsgId(_items.at(index)->getItem()) == msgid) {
|
if (_items.size() > index && complexMsgId(_items.at(index)->getItem()) == msgid) {
|
||||||
if (withDates) prevDate = _items.at(index)->getItem()->date.date();
|
if (withDates) prevDate = _items.at(index)->getItem()->date.date();
|
||||||
top = _items.at(index)->Get<OverviewItemInfo>()->top();
|
top = _items.at(index)->Get<OverviewItemInfo>()->top;
|
||||||
if (!_reversed) {
|
if (!_reversed) {
|
||||||
top += _items.at(index)->height();
|
top += _items.at(index)->height();
|
||||||
}
|
}
|
||||||
|
@ -1730,7 +1730,7 @@ void OverviewInner::mediaOverviewUpdated() {
|
||||||
if (_items.size() > index + 1 && !_items.at(index)->toLayoutMediaItem() && complexMsgId(_items.at(index + 1)->getItem()) == msgid) { // day item
|
if (_items.size() > index + 1 && !_items.at(index)->toLayoutMediaItem() && complexMsgId(_items.at(index + 1)->getItem()) == msgid) { // day item
|
||||||
++index;
|
++index;
|
||||||
if (withDates) prevDate = _items.at(index)->getItem()->date.date();
|
if (withDates) prevDate = _items.at(index)->getItem()->date.date();
|
||||||
top = _items.at(index)->Get<OverviewItemInfo>()->top();
|
top = _items.at(index)->Get<OverviewItemInfo>()->top;
|
||||||
if (!_reversed) {
|
if (!_reversed) {
|
||||||
top += _items.at(index)->height();
|
top += _items.at(index)->height();
|
||||||
}
|
}
|
||||||
|
@ -1857,7 +1857,7 @@ void OverviewInner::repaintItem(const HistoryItem *msg) {
|
||||||
if (history == _migrated) msgid = -msgid;
|
if (history == _migrated) msgid = -msgid;
|
||||||
for (int32 i = 0, l = _items.size(); i != l; ++i) {
|
for (int32 i = 0, l = _items.size(); i != l; ++i) {
|
||||||
if (complexMsgId(_items.at(i)->getItem()) == msgid) {
|
if (complexMsgId(_items.at(i)->getItem()) == msgid) {
|
||||||
int32 top = _items.at(i)->Get<OverviewItemInfo>()->top();
|
int32 top = _items.at(i)->Get<OverviewItemInfo>()->top;
|
||||||
if (_reversed) top = _height - top;
|
if (_reversed) top = _height - top;
|
||||||
update(_rowsLeft, _marginTop + top, _rowWidth, _items.at(i)->height());
|
update(_rowsLeft, _marginTop + top, _rowWidth, _items.at(i)->height());
|
||||||
break;
|
break;
|
||||||
|
@ -1963,7 +1963,7 @@ int32 OverviewInner::setLayoutItem(int32 index, LayoutItem *item, int32 top) {
|
||||||
}
|
}
|
||||||
int32 h = item->resizeGetHeight(_rowWidth);
|
int32 h = item->resizeGetHeight(_rowWidth);
|
||||||
if (OverviewItemInfo *info = item->Get<OverviewItemInfo>()) {
|
if (OverviewItemInfo *info = item->Get<OverviewItemInfo>()) {
|
||||||
info->setTop(top + (_reversed ? h : 0));
|
info->top = top + (_reversed ? h : 0);
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,7 +289,7 @@ namespace Shortcuts {
|
||||||
if (seq.isEmpty()) {
|
if (seq.isEmpty()) {
|
||||||
DataPtr->errors.push_back(qsl("Could not derive key sequence '%1'!").arg(keys));
|
DataPtr->errors.push_back(qsl("Could not derive key sequence '%1'!").arg(keys));
|
||||||
} else {
|
} else {
|
||||||
QMap<QString, ShortcutCommands::Handler>::const_iterator it = DataPtr->commands.constFind(command);
|
auto it = DataPtr->commands.constFind(command);
|
||||||
if (it == DataPtr->commands.cend()) {
|
if (it == DataPtr->commands.cend()) {
|
||||||
LOG(("Warning: could not find shortcut command handler '%1'").arg(command));
|
LOG(("Warning: could not find shortcut command handler '%1'").arg(command));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -169,12 +169,8 @@ template <typename T, size_t N> char(&ArraySizeHelper(T(&array)[N]))[N];
|
||||||
// using for_const instead of plain range-based for loop to ensure usage of const_iterator
|
// using for_const instead of plain range-based for loop to ensure usage of const_iterator
|
||||||
// it is important for the copy-on-write Qt containers
|
// it is important for the copy-on-write Qt containers
|
||||||
// if you have "QVector<T*> v" then "for (T * const p : v)" will still call QVector::detach(),
|
// if you have "QVector<T*> v" then "for (T * const p : v)" will still call QVector::detach(),
|
||||||
// while "for_const(T *p, v)" won't and "for_const(T *&p, v)" won't compile
|
// while "for_const (T *p, v)" won't and "for_const (T *&p, v)" won't compile
|
||||||
template <typename T>
|
#define for_const(range_declaration, range_expression) for (range_declaration : std_::as_const(range_expression))
|
||||||
struct ForConstTraits {
|
|
||||||
typedef const T &ExpressionType;
|
|
||||||
};
|
|
||||||
#define for_const(range_declaration, range_expression) for (range_declaration : static_cast<ForConstTraits<decltype(range_expression)>::ExpressionType>(range_expression))
|
|
||||||
|
|
||||||
template <typename Enum>
|
template <typename Enum>
|
||||||
inline QFlags<Enum> qFlags(Enum v) {
|
inline QFlags<Enum> qFlags(Enum v) {
|
||||||
|
@ -217,9 +213,9 @@ using std::string;
|
||||||
using std::exception;
|
using std::exception;
|
||||||
using std::swap;
|
using std::swap;
|
||||||
|
|
||||||
// we copy some parts of C++11 std:: library, because on OS X 10.6+
|
// we copy some parts of C++11/14/17 std:: library, because on OS X 10.6+
|
||||||
// version we can use C++11, but we can't use its library :(
|
// version we can use C++11/14/17, but we can not use its library :(
|
||||||
namespace std11 {
|
namespace std_ {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_reference {
|
struct remove_reference {
|
||||||
|
@ -239,7 +235,23 @@ inline typename remove_reference<T>::type &&move(T &&value) {
|
||||||
return static_cast<typename remove_reference<T>::type&&>(value);
|
return static_cast<typename remove_reference<T>::type&&>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace std11
|
template <typename T>
|
||||||
|
struct add_const {
|
||||||
|
using type = const T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using add_const_t = typename add_const<T>::type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr add_const_t<T> &as_const(T& t) noexcept {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void as_const(const T&&) = delete;
|
||||||
|
|
||||||
|
} // namespace std_
|
||||||
|
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
|
|
||||||
|
@ -669,6 +681,47 @@ inline RefPairImplementation<T1, T2> RefPairCreator(T1 &first, T2 &second) {
|
||||||
|
|
||||||
#define RefPair(Type1, Name1, Type2, Name2) Type1 Name1; Type2 Name2; RefPairCreator(Name1, Name2)
|
#define RefPair(Type1, Name1, Type2, Name2) Type1 Name1; Type2 Name2; RefPairCreator(Name1, Name2)
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class UniquePointer {
|
||||||
|
public:
|
||||||
|
explicit UniquePointer(T *p = nullptr) : _p(p) {
|
||||||
|
}
|
||||||
|
UniquePointer(const UniquePointer<T> &other) = delete;
|
||||||
|
UniquePointer &operator=(const UniquePointer<T> &other) = delete;
|
||||||
|
UniquePointer(UniquePointer<T> &&other) : _p(getPointerAndReset(other._p)) {
|
||||||
|
}
|
||||||
|
UniquePointer &operator=(UniquePointer<T> &&other) {
|
||||||
|
std::swap(_p, other._p);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
T *data() const {
|
||||||
|
return _p;
|
||||||
|
}
|
||||||
|
void reset(T *p = nullptr) {
|
||||||
|
*this = UniquePointer<T>(p);
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
T *operator->() const {
|
||||||
|
return data();
|
||||||
|
}
|
||||||
|
T &operator*() const {
|
||||||
|
t_assert(data() != nullptr);
|
||||||
|
return *data();
|
||||||
|
}
|
||||||
|
explicit operator bool() const {
|
||||||
|
return data() != nullptr;
|
||||||
|
}
|
||||||
|
~UniquePointer() {
|
||||||
|
delete _p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T *_p;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
inline void destroyImplementation(I *&ptr) {
|
inline void destroyImplementation(I *&ptr) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
|
@ -705,26 +758,11 @@ struct CeilDivideMinimumOne {
|
||||||
static const int Result = ((Value / Denominator) + ((!Value || (Value % Denominator)) ? 1 : 0));
|
static const int Result = ((Value / Denominator) + ((!Value || (Value % Denominator)) ? 1 : 0));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
struct ComponentWrapTemplate {
|
|
||||||
static const int Size = CeilDivideMinimumOne<sizeof(Type), sizeof(uint64)>::Result * sizeof(uint64);
|
|
||||||
static void Construct(void *location, Composer *composer) {
|
|
||||||
new (location) Type(composer);
|
|
||||||
}
|
|
||||||
static void Destruct(void *location) {
|
|
||||||
((Type*)location)->~Type();
|
|
||||||
}
|
|
||||||
static void Move(void *location, void *waslocation) {
|
|
||||||
*(Type*)location = std11::move(*(Type*)waslocation);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern ComponentWrapStruct ComponentWraps[64];
|
extern ComponentWrapStruct ComponentWraps[64];
|
||||||
extern QAtomicInt ComponentIndexLast;
|
extern QAtomicInt ComponentIndexLast;
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
class BaseComponent {
|
struct BaseComponent {
|
||||||
public:
|
|
||||||
BaseComponent() {
|
BaseComponent() {
|
||||||
}
|
}
|
||||||
BaseComponent(const BaseComponent &other) = delete;
|
BaseComponent(const BaseComponent &other) = delete;
|
||||||
|
@ -742,7 +780,9 @@ public:
|
||||||
if (ComponentIndexLast.testAndSetOrdered(last, last + 1)) {
|
if (ComponentIndexLast.testAndSetOrdered(last, last + 1)) {
|
||||||
t_assert(last < 64);
|
t_assert(last < 64);
|
||||||
if (_index.testAndSetOrdered(0, last + 1)) {
|
if (_index.testAndSetOrdered(0, last + 1)) {
|
||||||
ComponentWraps[last] = ComponentWrapStruct(ComponentWrapTemplate<Type>::Size, ComponentWrapTemplate<Type>::Construct, ComponentWrapTemplate<Type>::Destruct, ComponentWrapTemplate<Type>::Move);
|
ComponentWraps[last] = ComponentWrapStruct(
|
||||||
|
CeilDivideMinimumOne<sizeof(Type), sizeof(uint64)>::Result * sizeof(uint64),
|
||||||
|
Type::ComponentConstruct, Type::ComponentDestruct, Type::ComponentMove);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -753,6 +793,17 @@ public:
|
||||||
return (1ULL << Index());
|
return (1ULL << Index());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void ComponentConstruct(void *location, Composer *composer) {
|
||||||
|
new (location) Type();
|
||||||
|
}
|
||||||
|
static void ComponentDestruct(void *location) {
|
||||||
|
((Type*)location)->~Type();
|
||||||
|
}
|
||||||
|
static void ComponentMove(void *location, void *waslocation) {
|
||||||
|
*(Type*)location = std_::move(*(Type*)waslocation);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComposerMetadata {
|
class ComposerMetadata {
|
||||||
|
@ -848,6 +899,21 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
bool Has() const {
|
||||||
|
return (_meta()->offsets[Type::Index()] >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
void UpdateComponents(uint64 mask = 0) {
|
void UpdateComponents(uint64 mask = 0) {
|
||||||
if (!_meta()->equals(mask)) {
|
if (!_meta()->equals(mask)) {
|
||||||
Composer tmp(mask);
|
Composer tmp(mask);
|
||||||
|
@ -870,19 +936,6 @@ public:
|
||||||
UpdateComponents(_meta()->maskremove(mask));
|
UpdateComponents(_meta()->maskremove(mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
|
||||||
bool Has() const {
|
|
||||||
return (_meta()->offsets[Type::Index()] >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const ComposerMetadata *ZeroComposerMetadata;
|
static const ComposerMetadata *ZeroComposerMetadata;
|
||||||
static void *zerodata() {
|
static void *zerodata() {
|
||||||
|
@ -906,13 +959,13 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2>
|
template <typename R, typename ... Args>
|
||||||
class SharedCallback2 {
|
class SharedCallback {
|
||||||
public:
|
public:
|
||||||
virtual R call(A1 channel, A2 msgId) const = 0;
|
virtual R call(Args ... args) const = 0;
|
||||||
virtual ~SharedCallback2() {
|
virtual ~SharedCallback() {
|
||||||
}
|
}
|
||||||
typedef QSharedPointer<SharedCallback2<R, A1, A2> > Ptr;
|
typedef QSharedPointer<SharedCallback<R, Args ...>> Ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
|
|
Loading…
Reference in New Issue