From 55e8612f27e39171343b73e2202736d03042bf6d Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 24 Mar 2016 21:12:30 +0300 Subject: [PATCH 1/4] fixed QtCreator build --- Telegram/SourceFiles/mtproto/connection_auto.cpp | 4 ++-- Telegram/Telegram.pro | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/mtproto/connection_auto.cpp b/Telegram/SourceFiles/mtproto/connection_auto.cpp index 3723f495c..74aa09baf 100644 --- a/Telegram/SourceFiles/mtproto/connection_auto.cpp +++ b/Telegram/SourceFiles/mtproto/connection_auto.cpp @@ -255,7 +255,7 @@ void AutoConnection::requestFinished(QNetworkReply *reply) { void AutoConnection::socketPacket(const char *packet, uint32 length) { if (status == FinishedWork) return; - mtpBuffer data = TCPConnection::handleResponse(packet, length); + mtpBuffer data = AbstractTCPConnection::handleResponse(packet, length); if (data.size() == 1) { if (status == WaitingBoth) { status = WaitingHttp; @@ -326,7 +326,7 @@ QString AutoConnection::transport() const { void AutoConnection::socketError(QAbstractSocket::SocketError e) { if (status == FinishedWork) return; - TCPConnection::handleError(e, sock); + AbstractTCPConnection::handleError(e, sock); if (status == WaitingBoth) { status = WaitingHttp; } else if (status == HttpReady) { diff --git a/Telegram/Telegram.pro b/Telegram/Telegram.pro index b6242d3ed..775839e3e 100644 --- a/Telegram/Telegram.pro +++ b/Telegram/Telegram.pro @@ -117,6 +117,10 @@ SOURCES += \ ./SourceFiles/mtproto/facade.cpp \ ./SourceFiles/mtproto/auth_key.cpp \ ./SourceFiles/mtproto/connection.cpp \ + ./SourceFiles/mtproto/connection_abstract.cpp \ + ./SourceFiles/mtproto/connection_auto.cpp \ + ./SourceFiles/mtproto/connection_http.cpp \ + ./SourceFiles/mtproto/connection_tcp.cpp \ ./SourceFiles/mtproto/core_types.cpp \ ./SourceFiles/mtproto/dcenter.cpp \ ./SourceFiles/mtproto/file_download.cpp \ @@ -209,6 +213,10 @@ HEADERS += \ ./SourceFiles/mtproto/facade.h \ ./SourceFiles/mtproto/auth_key.h \ ./SourceFiles/mtproto/connection.h \ + ./SourceFiles/mtproto/connection_abstract.h \ + ./SourceFiles/mtproto/connection_auto.h \ + ./SourceFiles/mtproto/connection_http.h \ + ./SourceFiles/mtproto/connection_tcp.h \ ./SourceFiles/mtproto/core_types.h \ ./SourceFiles/mtproto/dcenter.h \ ./SourceFiles/mtproto/file_download.h \ From a299c1f9e8ef1f19b69096fff7de306e28a33de4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 24 Mar 2016 23:35:46 +0300 Subject: [PATCH 2/4] fixed upload of files --- Telegram/SourceFiles/mtproto/facade.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/mtproto/facade.h b/Telegram/SourceFiles/mtproto/facade.h index 2c58d4d3f..dfd5f22ad 100644 --- a/Telegram/SourceFiles/mtproto/facade.h +++ b/Telegram/SourceFiles/mtproto/facade.h @@ -122,8 +122,9 @@ namespace internal { // send(req, callbacks, MTP::uplDcId(index)) - for upload shifted dc id // uploading always to the main dc so bareDcId == 0 -inline ShiftedDcId uplDcId(DcId dcId) { - return internal::uploadDcId(dcId, 0); +inline ShiftedDcId uplDcId(int index) { + t_assert(index >= 0 && index < MTPUploadSessionsCount); + return internal::uploadDcId(0, index); }; constexpr bool isUplDcId(ShiftedDcId shiftedDcId) { return (shiftedDcId >= internal::uploadDcId(0, 0)) && (shiftedDcId < internal::uploadDcId(0, MTPUploadSessionsCount - 1) + DCShift); From 599ede9a0b01f7b43e516f70dbd48cce684e614e Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 25 Mar 2016 14:29:45 +0300 Subject: [PATCH 3/4] Beta 9034004 version: Some lang grammar fixes, all "audio" changed to "voice message" PeerData can have three loaded states (not loaded, minimal, full) Interface/Interfaces renamed to Component/Composer HistoryReply moved to a Component named HistoryMessageReply --- Telegram/Resources/lang.strings | 35 +- Telegram/SourceFiles/app.cpp | 86 +- Telegram/SourceFiles/app.h | 54 +- Telegram/SourceFiles/boxes/addcontactbox.cpp | 11 +- Telegram/SourceFiles/config.h | 2 +- Telegram/SourceFiles/gui/text.cpp | 53 +- Telegram/SourceFiles/gui/text.h | 10 +- Telegram/SourceFiles/history.cpp | 1017 ++++++++---------- Telegram/SourceFiles/history.h | 327 +++--- Telegram/SourceFiles/historywidget.cpp | 13 +- Telegram/SourceFiles/layout.cpp | 21 +- Telegram/SourceFiles/layout.h | 27 +- Telegram/SourceFiles/localstorage.cpp | 14 +- Telegram/SourceFiles/mainwidget.cpp | 16 +- Telegram/SourceFiles/overviewwidget.cpp | 5 +- Telegram/SourceFiles/structs.cpp | 18 +- Telegram/SourceFiles/structs.h | 129 ++- Telegram/SourceFiles/types.cpp | 49 +- Telegram/SourceFiles/types.h | 171 +-- Telegram/SourceFiles/window.cpp | 6 +- Telegram/Telegram.rc | 8 +- Telegram/Version | 2 +- 22 files changed, 1036 insertions(+), 1038 deletions(-) diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index 942d92582..c5b317fdd 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -663,9 +663,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_stickers_count" = "{count:Loading...|# sticker|# stickers}"; "lng_in_dlg_photo" = "Photo"; -"lng_in_dlg_video" = "Video"; +"lng_in_dlg_video" = "Video file"; +"lng_in_dlg_audio_file" = "Audio file"; "lng_in_dlg_contact" = "Contact"; -"lng_in_dlg_audio" = "Audio"; +"lng_in_dlg_audio" = "Voice message"; "lng_in_dlg_file" = "File"; "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; @@ -720,28 +721,29 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_user_typing" = "{user} is typing"; "lng_users_typing" = "{user} and {second_user} are typing"; "lng_many_typing" = "{count:_not_used_|# is|# are} typing"; -"lng_send_action_record_video" = "recording video"; +"lng_send_action_record_video" = "recording a video"; "lng_user_action_record_video" = "{user} is recording a video"; -"lng_send_action_upload_video" = "sending video"; +"lng_send_action_upload_video" = "sending a video"; "lng_user_action_upload_video" = "{user} is sending a video"; -"lng_send_action_record_audio" = "recording audio"; -"lng_user_action_record_audio" = "{user} is recording an audio"; -"lng_send_action_upload_audio" = "sending audio"; -"lng_user_action_upload_audio" = "{user} is sending an audio"; -"lng_send_action_upload_photo" = "sending photo"; +"lng_send_action_record_audio" = "recording a voice message"; +"lng_user_action_record_audio" = "{user} is recording a voice message"; +"lng_send_action_upload_audio" = "sending a voice message"; +"lng_user_action_upload_audio" = "{user} is sending a voice message"; +"lng_send_action_upload_photo" = "sending a photo"; "lng_user_action_upload_photo" = "{user} is sending a photo"; -"lng_send_action_upload_file" = "sending file"; +"lng_send_action_upload_file" = "sending a file"; "lng_user_action_upload_file" = "{user} is sending a file"; -"lng_send_action_geo_location" = "picking location"; +"lng_send_action_geo_location" = "picking a location"; "lng_user_action_geo_location" = "{user} is picking a location"; -"lng_send_action_choose_contact" = "choosing contact"; +"lng_send_action_choose_contact" = "choosing a contact"; "lng_user_action_choose_contact" = "{user} is choosing a contact"; "lng_unread_bar" = "{count:_not_used_|# unread message|# unread messages}"; "lng_maps_point" = "Location"; "lng_save_photo" = "Save image"; -"lng_save_video" = "Save video"; -"lng_save_audio" = "Save audio"; +"lng_save_video" = "Save video file"; +"lng_save_audio_file" = "Save audio file"; +"lng_save_audio" = "Save voice message"; "lng_save_file" = "Save file"; "lng_save_downloaded" = "{ready} / {total} {mb}"; "lng_duration_and_size" = "{duration}, {size}"; @@ -766,8 +768,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_cancel_download" = "Cancel Download"; "lng_context_show_in_folder" = "Show in Folder"; "lng_context_show_in_finder" = "Show in Finder"; -"lng_context_save_video" = "Save Video As..."; -"lng_context_save_audio" = "Save Audio As..."; +"lng_context_save_video" = "Save Video File As..."; +"lng_context_save_audio_file" = "Save Audio File As..."; +"lng_context_save_audio" = "Save Voice Message As..."; "lng_context_pack_info" = "Pack Info"; "lng_context_pack_add" = "Add Stickers"; "lng_context_save_file" = "Save File As..."; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index e9d2bbe5c..407ea84e9 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -478,7 +478,13 @@ namespace App { if (!data) continue; - data->loaded = true; + if (minimal) { + if (data->loadedStatus == PeerData::NotLoaded) { + data->loadedStatus = PeerData::MinimalLoaded; + } + } else if (data->loadedStatus != PeerData::FullLoaded) { + data->loadedStatus = PeerData::FullLoaded; + } if (status && !minimal) switch (status->type()) { case mtpc_userStatusEmpty: data->onlineTill = 0; break; case mtpc_userStatusRecently: @@ -655,7 +661,13 @@ namespace App { } if (!data) continue; - data->loaded = true; + if (minimal) { + if (data->loadedStatus == PeerData::NotLoaded) { + data->loadedStatus = PeerData::MinimalLoaded; + } + } else if (data->loadedStatus != PeerData::FullLoaded) { + data->loadedStatus = PeerData::FullLoaded; + } if (App::main()) { if (emitPeerUpdated) { App::main()->peerUpdated(data); @@ -1000,7 +1012,7 @@ namespace App { } void checkSavedGif(HistoryItem *item) { - if (!item->Is() && (item->out() || item->history()->peer == App::self())) { + if (!item->Has() && (item->out() || item->history()->peer == App::self())) { if (HistoryMedia *media = item->getMedia()) { if (DocumentData *doc = media->getDocument()) { if (doc->isGifv()) { @@ -1394,41 +1406,16 @@ namespace App { return 0; } - PeerData *peerLoaded(const PeerId &peer) { - PeersData::const_iterator i = peersData.constFind(peer); - return (i != peersData.cend()) ? i.value() : 0; - } - - UserData *userLoaded(const PeerId &id) { - PeerData *peer = peerLoaded(id); - return (peer && peer->loaded) ? peer->asUser() : 0; - } - ChatData *chatLoaded(const PeerId &id) { - PeerData *peer = peerLoaded(id); - return (peer && peer->loaded) ? peer->asChat() : 0; - } - ChannelData *channelLoaded(const PeerId &id) { - PeerData *peer = peerLoaded(id); - return (peer && peer->loaded) ? peer->asChannel() : 0; - } - UserData *userLoaded(int32 user_id) { - return userLoaded(peerFromUser(user_id)); - } - ChatData *chatLoaded(int32 chat_id) { - return chatLoaded(peerFromChat(chat_id)); - } - ChannelData *channelLoaded(int32 channel_id) { - return channelLoaded(peerFromChannel(channel_id)); - } - UserData *curUser() { return user(MTP::authedId()); } - PeerData *peer(const PeerId &id) { - PeersData::const_iterator i = peersData.constFind(id); + PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction) { + if (!id) return nullptr; + + auto i = peersData.constFind(id); if (i == peersData.cend()) { - PeerData *newData = 0; + PeerData *newData = nullptr; if (peerIsUser(id)) { newData = new UserData(id); } else if (peerIsChat(id)) { @@ -1436,33 +1423,26 @@ namespace App { } else if (peerIsChannel(id)) { newData = new ChannelData(id); } - if (!newData) return 0; + t_assert(newData != nullptr); newData->input = MTPinputPeer(MTP_inputPeerEmpty()); i = peersData.insert(id, newData); } + switch (restriction) { + case PeerData::MinimalLoaded: { + if (i.value()->loadedStatus == PeerData::NotLoaded) { + return nullptr; + } + } break; + case PeerData::FullLoaded: { + if (i.value()->loadedStatus != PeerData::FullLoaded) { + return nullptr; + } + } break; + } return i.value(); } - UserData *user(const PeerId &id) { - return peer(id)->asUser(); - } - ChatData *chat(const PeerId &id) { - return peer(id)->asChat(); - } - ChannelData *channel(const PeerId &id) { - return peer(id)->asChannel(); - } - UserData *user(int32 user_id) { - return user(peerFromUser(user_id)); - } - ChatData *chat(int32 chat_id) { - return chat(peerFromChat(chat_id)); - } - ChannelData *channel(int32 channel_id) { - return channel(peerFromChannel(channel_id)); - } - UserData *self() { return ::self; } diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 77bd4e5b6..ebe1711e5 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -110,21 +110,47 @@ namespace App { WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = 0); WebPageData *feedWebPage(const MTPWebPage &webpage); - PeerData *peerLoaded(const PeerId &id); - UserData *userLoaded(const PeerId &id); - ChatData *chatLoaded(const PeerId &id); - ChannelData *channelLoaded(const PeerId &id); - UserData *userLoaded(int32 user); - ChatData *chatLoaded(int32 chat); - ChannelData *channelLoaded(int32 channel); + 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); + } - PeerData *peer(const PeerId &id); - UserData *user(const PeerId &id); - ChatData *chat(const PeerId &id); - ChannelData *channel(const PeerId &id); - UserData *user(int32 user_id); - ChatData *chat(int32 chat_id); - ChannelData *channel(int32 channel_id); UserData *self(); PeerData *peerByName(const QString &username); QString peerName(const PeerData *peer, bool forDialogs = false); diff --git a/Telegram/SourceFiles/boxes/addcontactbox.cpp b/Telegram/SourceFiles/boxes/addcontactbox.cpp index b3e1c85c7..53d9e5d80 100644 --- a/Telegram/SourceFiles/boxes/addcontactbox.cpp +++ b/Telegram/SourceFiles/boxes/addcontactbox.cpp @@ -224,18 +224,15 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) { App::feedUsers(d.vusers); const QVector &v(d.vimported.c_vector().v); - int32 uid = 0; + UserData *user = nullptr; if (!v.isEmpty()) { const MTPDimportedContact &c(v.front().c_importedContact()); if (c.vclient_id.v != _contactId) return; - uid = c.vuser_id.v; - if (uid && !App::userLoaded(uid)) { - uid = 0; - } + user = App::userLoaded(c.vuser_id.v); } - if (uid) { - Notify::userIsContactChanged(App::userLoaded(peerFromUser(uid)), true); + if (user) { + Notify::userIsContactChanged(user, true); Ui::hideLayer(); } else { _save.hide(); diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 758dee907..6aad20f74 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org static const int32 AppVersion = 9034; static const wchar_t *AppVersionStr = L"0.9.34"; static const bool DevVersion = false; -#define BETA_VERSION (9034003ULL) // just comment this line to build public version +#define BETA_VERSION (9034004ULL) // just comment this line to build public version static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; static const wchar_t *AppName = L"Telegram Desktop"; diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp index 30eab680e..f350a1f3e 100644 --- a/Telegram/SourceFiles/gui/text.cpp +++ b/Telegram/SourceFiles/gui/text.cpp @@ -2534,20 +2534,32 @@ Text::Text(style::font font, const QString &text, const TextParseOptions &option } } -Text::Text(const Text &other) : -_minResizeWidth(other._minResizeWidth), _maxWidth(other._maxWidth), -_minHeight(other._minHeight), -_text(other._text), -_font(other._font), -_blocks(other._blocks.size()), -_links(other._links), -_startDir(other._startDir) -{ +Text::Text(const Text &other) +: _minResizeWidth(other._minResizeWidth) +, _maxWidth(other._maxWidth) +, _minHeight(other._minHeight) +, _text(other._text) +, _font(other._font) +, _blocks(other._blocks.size()) +, _links(other._links) +, _startDir(other._startDir) { for (int32 i = 0, l = _blocks.size(); i < l; ++i) { _blocks[i] = other._blocks.at(i)->clone(); } } +Text::Text(Text &&other) +: _minResizeWidth(other._minResizeWidth) +, _maxWidth(other._maxWidth) +, _minHeight(other._minHeight) +, _text(other._text) +, _font(other._font) +, _blocks(other._blocks) +, _links(other._links) +, _startDir(other._startDir) { + other.clearFields(); +} + Text &Text::operator=(const Text &other) { _minResizeWidth = other._minResizeWidth; _maxWidth = other._maxWidth; @@ -2563,10 +2575,23 @@ Text &Text::operator=(const Text &other) { return *this; } +Text &Text::operator=(Text &&other) { + _minResizeWidth = other._minResizeWidth; + _maxWidth = other._maxWidth; + _minHeight = other._minHeight; + _text = other._text; + _font = other._font; + _blocks = other._blocks; + _links = other._links; + _startDir = other._startDir; + other.clearFields(); + return *this; +} + void Text::setText(style::font font, const QString &text, const TextParseOptions &options) { if (!_textStyle) _initDefault(); _font = font; - clean(); + clear(); { TextParser parser(this, text, options); } @@ -2644,7 +2669,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) { void Text::setMarkedText(style::font font, const QString &text, const EntitiesInText &entities, const TextParseOptions &options) { if (!_textStyle) _initDefault(); _font = font; - clean(); + clear(); { // QString newText; // utf16 of the text for emoji // newText.reserve(8 * text.size()); @@ -3216,10 +3241,14 @@ EntitiesInText Text::originalEntities() const { return result; } -void Text::clean() { +void Text::clear() { for (TextBlocks::iterator i = _blocks.begin(), e = _blocks.end(); i != e; ++i) { delete *i; } + clearFields(); +} + +void Text::clearFields() { _blocks.clear(); _links.clear(); _maxWidth = _minHeight = 0; diff --git a/Telegram/SourceFiles/gui/text.h b/Telegram/SourceFiles/gui/text.h index d78f20cf5..7cb1e23a0 100644 --- a/Telegram/SourceFiles/gui/text.h +++ b/Telegram/SourceFiles/gui/text.h @@ -598,7 +598,9 @@ public: Text(int32 minResizeWidth = QFIXED_MAX); Text(style::font font, const QString &text, const TextParseOptions &options = _defaultOptions, int32 minResizeWidth = QFIXED_MAX, bool richText = false); Text(const Text &other); + Text(Text &&other); Text &operator=(const Text &other); + Text &operator=(Text &&other); int32 countWidth(int32 width) const; int32 countHeight(int32 width) const; @@ -686,15 +688,19 @@ public: return true; } - void clean(); + void clear(); ~Text() { - clean(); + clear(); } private: void recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir = Qt::LayoutDirectionAuto); + // clear() deletes all blocks and calls this method + // it is also called from move constructor / assignment operator + void clearFields(); + QFixed _minResizeWidth, _maxWidth; int32 _minHeight; diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index fd5a698d1..b04fb0b06 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -75,12 +75,6 @@ namespace { _webpageDescriptionOptions.maxh = st::webPageDescriptionFont->height * 3; } - inline HistoryReply *toHistoryReply(HistoryItem *item) { - return item ? item->toHistoryReply() : 0; - } - inline const HistoryReply *toHistoryReply(const HistoryItem *item) { - return item ? item->toHistoryReply() : 0; - } inline const TextParseOptions &itemTextOptions(HistoryItem *item) { return itemTextOptions(item->history(), item->author()); } @@ -1235,7 +1229,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, switch (msg.type()) { case mtpc_messageEmpty: - result = HistoryServiceMessage::create(this, msg.c_messageEmpty().vid.v, date(), lang(lng_message_empty)); + result = HistoryService::create(this, msg.c_messageEmpty().vid.v, date(), lang(lng_message_empty)); break; case mtpc_message: { @@ -1287,15 +1281,11 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, QString text(lng_message_unsupported(lt_link, qsl("https://desktop.telegram.org"))); EntitiesInText entities = textParseEntities(text, _historyTextNoMonoOptions.flags); entities.push_front(EntityInText(EntityInTextItalic, 0, text.size())); - result = HistoryMessage::create(this, m.vid.v, m.vflags.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v, text, entities); + result = HistoryMessage::create(this, m.vid.v, m.vflags.v, m.vreply_to_msg_id.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v, text, entities); } else if (badMedia) { - result = HistoryServiceMessage::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 { - if (m.has_reply_to_msg_id() && m.vreply_to_msg_id.v > 0) { - result = HistoryReply::create(this, m); - } else { - result = HistoryMessage::create(this, m); - } + result = HistoryMessage::create(this, m); if (m.has_reply_markup()) { App::feedReplyMarkup(channelId(), msgId, m.vreply_markup); } @@ -1304,7 +1294,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, case mtpc_messageService: { const MTPDmessageService &d(msg.c_messageService()); - result = HistoryServiceMessage::create(this, d); + result = HistoryService::create(this, d); if (applyServiceAction) { const MTPmessageAction &action(d.vaction); @@ -1424,12 +1414,12 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, peer->asChat()->flags |= MTPDchat::Flag::f_deactivated; //const MTPDmessageActionChatMigrateTo &d(action.c_messageActionChatMigrateTo()); - //PeerData *channel = App::peerLoaded(peerFromChannel(d.vchannel_id)); + //PeerData *channel = App::channelLoaded(d.vchannel_id.v); } break; case mtpc_messageActionChannelMigrateFrom: { //const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom()); - //PeerData *chat = App::peerLoaded(peerFromChat(d.vchat_id)); + //PeerData *chat = App::chatLoaded(d.vchat_id.v); } break; case mtpc_messageActionPinMessage: { @@ -1455,21 +1445,15 @@ HistoryItem *History::createItemForwarded(MsgId id, MTPDmessage::Flags flags, QD } HistoryItem *History::createItemDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { - if ((flags & MTPDmessage::Flag::f_reply_to_msg_id) && replyTo > 0) { - return HistoryReply::create(this, id, flags, viaBotId, replyTo, date, from, doc, caption); - } - return HistoryMessage::create(this, id, flags, viaBotId, date, from, doc, caption); + return HistoryMessage::create(this, id, flags, replyTo, viaBotId, date, from, doc, caption); } HistoryItem *History::createItemPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) { - if ((flags & MTPDmessage::Flag::f_reply_to_msg_id) && replyTo > 0) { - return HistoryReply::create(this, id, flags, viaBotId, replyTo, date, from, photo, caption); - } - return HistoryMessage::create(this, id, flags, viaBotId, date, from, photo, caption); + return HistoryMessage::create(this, id, flags, replyTo, viaBotId, date, from, photo, caption); } HistoryItem *History::addNewService(MsgId msgId, QDateTime date, const QString &text, MTPDmessage::Flags flags, HistoryMedia *media, bool newMsg) { - return addNewItem(HistoryServiceMessage::create(this, msgId, date, text, flags, media), newMsg); + return addNewItem(HistoryService::create(this, msgId, date, text, flags, media), newMsg); } HistoryItem *History::addNewMessage(const MTPMessage &msg, NewMessageType type) { @@ -2723,9 +2707,6 @@ void HistoryDependentItemCallback::call(ChannelData *channel, MsgId msgId) const } } -HistoryMessageUnreadBar::HistoryMessageUnreadBar(Interfaces*) : _width(0), _freezed(false) { -} - void HistoryMessageUnreadBar::init(int count) { if (_freezed) return; _text = lng_unread_bar(lt_count, count); @@ -2752,9 +2733,6 @@ void HistoryMessageUnreadBar::paint(Painter &p, int y, int w) const { p.drawText((w - _width) / 2, y + (st::unreadBarHeight - st::lineWidth - st::unreadBarFont->height) / 2 + st::unreadBarFont->ascent, _text); } -HistoryMessageDate::HistoryMessageDate(Interfaces*) : _width(0) { -} - void HistoryMessageDate::init(const QDateTime &date) { _text = langDayOfMonthFull(date.date()); _width = st::msgServiceFont->width(_text); @@ -2835,13 +2813,13 @@ void HistoryItem::detachFast() { void HistoryItem::previousItemChanged() { if (displayDate()) { - if (!Is()) { - AddInterfaces(HistoryMessageDate::Bit()); + if (!Has()) { + AddComponents(HistoryMessageDate::Bit()); Get()->init(date); setPendingInitDimensions(); } - } else if (Is()) { - RemoveInterfaces(HistoryMessageDate::Bit()); + } else if (Has()) { + RemoveComponents(HistoryMessageDate::Bit()); setPendingInitDimensions(); } @@ -2850,7 +2828,7 @@ void HistoryItem::previousItemChanged() { void HistoryItem::recountAttachToPrevious() { bool attach = false; - if (!isPost() && !Is() && !Is()) { + if (!isPost() && !Has() && !Has()) { if (HistoryItem *prev = previous()) { attach = !prev->isPost() && !prev->serviceMsg() && prev->from() == from() && qAbs(prev->date.secsTo(date)) < AttachMessageToPreviousSecondsDelta; } @@ -2875,7 +2853,7 @@ bool HistoryItem::canEdit(const QDateTime &cur) const { if (!channel || id < 0 || date.secsTo(cur) >= Global::EditTimeLimit()) return false; if (const HistoryMessage *msg = toHistoryMessage()) { - if (msg->Is() || msg->Is()) return false; + if (msg->Has() || msg->Has()) return false; if (HistoryMedia *media = msg->getMedia()) { HistoryMediaType t = media->type(); @@ -2898,8 +2876,8 @@ bool HistoryItem::canEdit(const QDateTime &cur) const { } void HistoryItem::destroyUnreadBar() { - if (Is()) { - RemoveInterfaces(HistoryMessageUnreadBar::Bit()); + if (Has()) { + RemoveComponents(HistoryMessageUnreadBar::Bit()); setPendingInitDimensions(); if (_history->unreadBar == this) { _history->unreadBar = nullptr; @@ -2912,8 +2890,8 @@ void HistoryItem::destroyUnreadBar() { void HistoryItem::setUnreadBarCount(int count) { if (count > 0) { HistoryMessageUnreadBar *bar; - if (!Is()) { - AddInterfaces(HistoryMessageUnreadBar::Bit()); + if (!Has()) { + AddComponents(HistoryMessageUnreadBar::Bit()); setPendingInitDimensions(); recountAttachToPrevious(); @@ -3795,15 +3773,15 @@ void HistoryDocumentVoice::ensurePlayback(const HistoryDocument *that) const { void HistoryDocumentVoice::checkPlaybackFinished() const { if (_playback && !_playback->_a_progress.animating()) { delete _playback; - _playback = 0; + _playback = nullptr; } } HistoryDocument::HistoryDocument(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia() -, _parent(0) +, _parent(nullptr) , _data(document) { createInterfaces(!caption.isEmpty()); - if (HistoryDocumentNamed *named = Get()) { + if (auto *named = Get()) { named->_name = documentName(_data); named->_namew = st::semiboldFont->width(named->_name); } @@ -3812,21 +3790,21 @@ HistoryDocument::HistoryDocument(DocumentData *document, const QString &caption, setStatusSize(FileStatusSizeReady); - if (HistoryDocumentCaptioned *captioned = Get()) { + if (auto *captioned = Get()) { captioned->_caption.setText(st::msgFont, caption + parent->skipBlock(), itemTextNoMonoOptions(parent)); } } HistoryDocument::HistoryDocument(const HistoryDocument &other) : HistoryFileMedia() -, Interfaces() -, _parent(0) +, Composer() +, _parent(nullptr) , _data(other._data) { - const HistoryDocumentCaptioned *captioned = other.Get(); + auto *captioned = other.Get(); createInterfaces(captioned != 0); - if (HistoryDocumentNamed *named = Get()) { - if (const HistoryDocumentNamed *oin = other.Get()) { - named->_name = oin->_name; - named->_namew = oin->_namew; + if (auto *named = Get()) { + if (auto *othernamed = other.Get()) { + named->_name = othernamed->_name; + named->_namew = othernamed->_namew; } else { named->_name = documentName(_data); named->_namew = st::semiboldFont->width(named->_name); @@ -3855,8 +3833,8 @@ void HistoryDocument::createInterfaces(bool caption) { if (caption) { mask |= HistoryDocumentCaptioned::Bit(); } - UpdateInterfaces(mask); - if (HistoryDocumentThumbed *thumbed = Get()) { + UpdateComponents(mask); + if (auto *thumbed = Get()) { thumbed->_linksavel.reset(new DocumentSaveLink(_data)); thumbed->_linkcancell.reset(new DocumentCancelLink(_data)); } @@ -3865,12 +3843,12 @@ void HistoryDocument::createInterfaces(bool caption) { void HistoryDocument::initDimensions(const HistoryItem *parent) { _parent = parent; - HistoryDocumentCaptioned *captioned = Get(); + auto *captioned = Get(); if (captioned && captioned->_caption.hasSkipBlock()) { captioned->_caption.setSkipBlock(parent->skipBlockWidth(), parent->skipBlockHeight()); } - HistoryDocumentThumbed *thumbed = Get(); + auto *thumbed = Get(); if (thumbed) { _data->thumb->load(); int32 tw = convertScale(_data->thumb->width()), th = convertScale(_data->thumb->height()); @@ -3895,14 +3873,14 @@ void HistoryDocument::initDimensions(const HistoryItem *parent) { _maxw = qMax(_maxw, tleft + documentMaxStatusWidth(_data) + unread + parent->skipBlockWidth() + st::msgPadding.right()); } - if (HistoryDocumentNamed *named = Get()) { + if (auto *named = Get()) { _maxw = qMax(tleft + named->_namew + tright, _maxw); _maxw = qMin(_maxw, int(st::msgMaxWidth)); } if (thumbed) { _minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); - if (!captioned && parent->Is()) { + if (!captioned && parent->Has()) { _minh += st::msgDateFont->height - st::msgDateDelta.y(); } } else { @@ -3917,7 +3895,7 @@ void HistoryDocument::initDimensions(const HistoryItem *parent) { } int32 HistoryDocument::resize(int32 width, const HistoryItem *parent) { - HistoryDocumentCaptioned *captioned = Get(); + auto *captioned = Get(); if (!captioned) { return HistoryFileMedia::resize(width, parent); } @@ -3953,7 +3931,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r bool radial = isRadialAnimation(ms); int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0; - if (const HistoryDocumentThumbed *thumbed = Get()) { + if (auto *thumbed = Get()) { nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); nametop = st::msgFileThumbNameTop; nameright = st::msgFileThumbPadding.left(); @@ -4061,7 +4039,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r } int32 namewidth = _width - nameleft - nameright; - if (const HistoryDocumentVoice *voice = Get()) { + if (auto *voice = Get()) { const VoiceWaveform *wf = 0; uchar norm_value = 0; if (_data->voice()) { @@ -4120,7 +4098,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r sum_i += bar_count; } } - } else if (const HistoryDocumentNamed *named = Get()) { + } else if (auto *named = Get()) { p.setFont(st::semiboldFont); p.setPen(st::black); if (namewidth < named->_namew) { @@ -4147,7 +4125,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r } } - if (const HistoryDocumentCaptioned *captioned = Get()) { + if (auto *captioned = Get()) { p.setPen(st::black); captioned->_caption.draw(p, st::msgPadding.left(), bottom, captionw); } @@ -4162,7 +4140,7 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3 bool showPause = updateStatusText(parent); int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0; - if (const HistoryDocumentThumbed *thumbed = Get()) { + if (auto *thumbed = Get()) { nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); linktop = st::msgFileThumbLinkTop; bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); @@ -4191,7 +4169,7 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3 } int32 height = _height; - if (const HistoryDocumentCaptioned *captioned = Get()) { + if (auto *captioned = Get()) { if (y >= bottom) { bool inText = false; captioned->_caption.getState(lnk, inText, x - st::msgPadding.left(), y - bottom, _width - st::msgPadding.left() - st::msgPadding.right()); @@ -4208,13 +4186,15 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3 const QString HistoryDocument::inDialogsText() const { QString result; - if (Get()) { + if (Has()) { result = lang(lng_in_dlg_audio); + } else if (_data->song()) { + result = lang(lng_in_dlg_audio_file); } else { - const HistoryDocumentNamed *named = Get(); + auto *named = Get(); result = (!named || named->_name.isEmpty()) ? lang(lng_in_dlg_file) : named->_name; } - if (const HistoryDocumentCaptioned *captioned = Get()) { + if (auto *captioned = Get()) { if (!captioned->_caption.isEmpty()) { result.append(' ').append(captioned->_caption.original(0, 0xFFFF, Text::ExpandLinksNone)); } @@ -4223,24 +4203,31 @@ const QString HistoryDocument::inDialogsText() const { } const QString HistoryDocument::inHistoryText() const { - QString result = qsl("[ ") + lang(Get() ? lng_in_dlg_audio : lng_in_dlg_file); - if (const HistoryDocumentNamed *named = Get()) { + QString result; + if (Has()) { + result = lang(lng_in_dlg_audio); + } else if (_data->song()) { + result = lang(lng_in_dlg_audio_file); + } else { + result = lang(lng_in_dlg_file); + } + if (auto *named = Get()) { if (!named->_name.isEmpty()) { result.append(qsl(" : ")).append(named->_name); } } - if (const HistoryDocumentCaptioned *captioned = Get()) { + if (auto *captioned = Get()) { if (!captioned->_caption.isEmpty()) { result.append(qsl(", ")).append(captioned->_caption.original(0, 0xFFFF, Text::ExpandLinksAll)); } } - return result.append(qsl(" ]")); + return qsl("[ ") + result.append(qsl(" ]")); } void HistoryDocument::setStatusSize(int32 newSize, qint64 realDuration) const { int32 duration = _data->song() ? _data->song()->duration : (_data->voice() ? _data->voice()->duration : -1); HistoryFileMedia::setStatusSize(newSize, _data->size, duration, realDuration); - if (const HistoryDocumentThumbed *thumbed = Get()) { + if (auto *thumbed = Get()) { if (_statusSize == FileStatusSizeReady) { thumbed->_link = lang(lng_media_download).toUpper(); } else if (_statusSize == FileStatusSizeLoaded) { @@ -4276,7 +4263,7 @@ bool HistoryDocument::updateStatusText(const HistoryItem *parent) const { } if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { - if (const HistoryDocumentVoice *voice = Get()) { + if (auto *voice = Get()) { bool was = voice->_playback; voice->ensurePlayback(this); if (!was || playingPosition != voice->_playback->_position) { @@ -4296,7 +4283,7 @@ bool HistoryDocument::updateStatusText(const HistoryItem *parent) const { showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); } else { statusSize = FileStatusSizeLoaded; - if (const HistoryDocumentVoice *voice = Get()) { + if (auto *voice = Get()) { voice->checkPlaybackFinished(); } } @@ -4332,7 +4319,7 @@ bool HistoryDocument::updateStatusText(const HistoryItem *parent) const { } void HistoryDocument::step_voiceProgress(float64 ms, bool timer) { - if (HistoryDocumentVoice *voice = Get()) { + if (auto *voice = Get()) { if (voice->_playback) { float64 dt = ms / (2 * AudioVoiceMsgUpdateView); if (dt >= 1) { @@ -4372,12 +4359,12 @@ ImagePtr HistoryDocument::replyPreview() { } HistoryGif::HistoryGif(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia() -, _parent(0) +, _parent(nullptr) , _data(document) , _thumbw(1) , _thumbh(1) , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) -, _gif(0) { +, _gif(nullptr) { setLinks(new GifOpenLink(_data), new GifOpenLink(_data), new DocumentCancelLink(_data)); setStatusSize(FileStatusSizeReady); @@ -4390,12 +4377,12 @@ HistoryGif::HistoryGif(DocumentData *document, const QString &caption, const His } HistoryGif::HistoryGif(const HistoryGif &other) : HistoryFileMedia() -, _parent(0) +, _parent(nullptr) , _data(other._data) , _thumbw(other._thumbw) , _thumbh(other._thumbh) , _caption(other._caption) -, _gif(0) { +, _gif(nullptr) { setLinks(new GifOpenLink(_data), new GifOpenLink(_data), new DocumentCancelLink(_data)); setStatusSize(other._statusSize); @@ -4783,7 +4770,7 @@ void HistorySticker::initDimensions(const HistoryItem *parent) { if (_pixh < 1) _pixh = 1; _maxw = qMax(_pixw, int16(st::minPhotoSize)); _minh = qMax(_pixh, int16(st::minPhotoSize)); - if (const HistoryReply *reply = toHistoryReply(parent)) { + if (auto *reply = parent->Get()) { _maxw += st::msgReplyPadding.left() + reply->replyToWidth(); } _height = _minh; @@ -4791,10 +4778,10 @@ void HistorySticker::initDimensions(const HistoryItem *parent) { int32 HistorySticker::resize(int32 width, const HistoryItem *parent) { // return new height _width = qMin(width, _maxw); - if (const HistoryReply *reply = toHistoryReply(parent)) { + if (auto *reply = parent->Get()) { int32 usew = _maxw - st::msgReplyPadding.left() - reply->replyToWidth(); int32 rw = _width - usew - st::msgReplyPadding.left() - st::msgReplyPadding.left() - st::msgReplyPadding.right(); - reply->resizeVia(rw); + reply->resize(rw); } return _height; } @@ -4808,7 +4795,7 @@ void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r, bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; int32 usew = _maxw, usex = 0; - const HistoryReply *reply = toHistoryReply(parent); + auto *reply = parent->Get(); if (reply) { usew -= st::msgReplyPadding.left() + reply->replyToWidth(); if (isPost) { @@ -4842,7 +4829,11 @@ void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r, App::roundRect(p, rx, ry, rw, rh, selected ? App::msgServiceSelectBg() : App::msgServiceBg(), selected ? ServiceSelectedCorners : ServiceCorners); - reply->drawReplyTo(p, rx + st::msgReplyPadding.left(), ry, rw - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected, true); + HistoryMessageReply::PaintFlags flags = 0; + if (selected) { + flags |= HistoryMessageReply::PaintSelected; + } + reply->paint(p, parent, rx + st::msgReplyPadding.left(), ry, rw - st::msgReplyPadding.left() - st::msgReplyPadding.right(), flags); } } } @@ -4853,7 +4844,7 @@ void HistorySticker::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; int32 usew = _maxw, usex = 0; - const HistoryReply *reply = toHistoryReply(parent); + auto *reply = parent->Get(); if (reply) { usew -= reply->replyToWidth(); if (isPost) { @@ -5782,7 +5773,7 @@ void HistoryLocation::initDimensions(const HistoryItem *parent) { _minh += st::mediaPadding.top() + st::mediaPadding.bottom(); if (!_title.isEmpty() || !_description.isEmpty()) { _minh += st::webPagePhotoSkip; - if (!parent->Is() && !parent->toHistoryReply()) { + if (!parent->Has() && !parent->Has()) { _minh += st::msgPadding.top(); } } @@ -5822,7 +5813,7 @@ int32 HistoryLocation::resize(int32 width, const HistoryItem *parent) { } if (!_title.isEmpty() || !_description.isEmpty()) { _height += st::webPagePhotoSkip; - if (!parent->Is() && !parent->toHistoryReply()) { + if (!parent->Has() && !parent->Has()) { _height += st::msgPadding.top(); } } @@ -5841,7 +5832,7 @@ void HistoryLocation::draw(Painter &p, const HistoryItem *parent, const QRect &r skipy = st::mediaPadding.top(); if (!_title.isEmpty() || !_description.isEmpty()) { - if (!parent->Is() && !parent->toHistoryReply()) { + if (!parent->Has() && !parent->Has()) { skipy += st::msgPadding.top(); } } @@ -5904,7 +5895,7 @@ void HistoryLocation::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3 skipy = st::mediaPadding.top(); if (!_title.isEmpty() || !_description.isEmpty()) { - if (!parent->Is() && !parent->toHistoryReply()) { + if (!parent->Has() && !parent->Has()) { skipy += st::msgPadding.top(); } } @@ -5956,12 +5947,6 @@ void ViaInlineBotLink::onClick(Qt::MouseButton button) const { App::insertBotCommand('@' + _bot->username); } -HistoryMessageVia::HistoryMessageVia(Interfaces *) -: _bot(0) -, _width(0) -, _maxWidth(0) { -} - void HistoryMessageVia::create(int32 userId) { _bot = App::user(peerFromUser(userId)); _maxWidth = st::msgServiceNameFont->width(lng_inline_bot_via(lt_inline_bot, '@' + _bot->username)); @@ -5983,14 +5968,6 @@ void HistoryMessageVia::resize(int32 availw) const { } } -HistoryMessageViews::HistoryMessageViews(Interfaces *) -: _views(0) -, _viewsWidth(0) { -} - -HistoryMessageSigned::HistoryMessageSigned(Interfaces *) { -} - void HistoryMessageSigned::create(UserData *from, const QDateTime &date) { QString time = qsl(", ") + date.toString(cTimeFormat()), name = App::peerName(from); int32 timew = st::msgDateFont->width(time), namew = st::msgDateFont->width(name); @@ -6000,17 +5977,10 @@ void HistoryMessageSigned::create(UserData *from, const QDateTime &date) { _signature.setText(st::msgDateFont, name + time, _textNameOptions); } -int32 HistoryMessageSigned::maxWidth() const { +int HistoryMessageSigned::maxWidth() const { return _signature.maxWidth(); } -HistoryMessageForwarded::HistoryMessageForwarded(Interfaces *) -: _authorOriginal(0) -, _fromOriginal(0) -, _originalId(0) -, _text(1) { -} - void HistoryMessageForwarded::create(const HistoryMessageVia *via) const { QString text; if (_authorOriginal != _fromOriginal) { @@ -6041,8 +6011,150 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const { } } -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) { +bool HistoryMessageReply::updateData(HistoryMessage *holder, bool force) { + if (!force) { + if (replyToMsg || !replyToMsgId) { + return true; + } + } + if (!replyToMsg) { + replyToMsg = App::histItemById(holder->channelId(), replyToMsgId); + if (replyToMsg) { + App::historyRegDependency(holder, replyToMsg); + } + } + + if (replyToMsg) { + replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions); + + updateName(); + + replyToLnk = TextLinkPtr(new MessageLink(replyToMsg->history()->peer->id, replyToMsg->id)); + if (!replyToMsg->Has()) { + if (UserData *bot = replyToMsg->viaBot()) { + _replyToVia = new HistoryMessageVia(0); + _replyToVia->create(peerToUser(bot->id)); + } + } + } else if (force) { + replyToMsgId = 0; + } + if (force) { + holder->setPendingInitDimensions(); + } + return (replyToMsg || !replyToMsgId); +} + +void HistoryMessageReply::clearData(HistoryMessage *holder) { + delete _replyToVia; + _replyToVia = nullptr; + if (replyToMsg) { + App::historyUnregDependency(holder, replyToMsg); + replyToMsg = nullptr; + } + replyToMsgId = 0; +} + +void HistoryMessageReply::checkNameUpdate() const { + if (replyToMsg && replyToMsg->author()->nameVersion > replyToVersion) { + updateName(); + } +} + +void HistoryMessageReply::updateName() const { + if (replyToMsg) { + QString name = (_replyToVia && replyToMsg->author()->isUser()) ? replyToMsg->author()->asUser()->firstName : App::peerName(replyToMsg->author()); + replyToName.setText(st::msgServiceNameFont, name, _textNameOptions); + replyToVersion = replyToMsg->author()->nameVersion; + bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; + int32 previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; + int32 w = replyToName.maxWidth(); + if (_replyToVia) { + w += st::msgServiceFont->spacew + _replyToVia->_maxWidth; + } + + _maxReplyWidth = previewSkip + qMax(w, qMin(replyToText.maxWidth(), int32(st::maxSignatureSize))); + } else { + _maxReplyWidth = st::msgDateFont->width(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message)); + } + _maxReplyWidth = st::msgReplyPadding.left() + st::msgReplyBarSkip + _maxReplyWidth + st::msgReplyPadding.right(); +} + +void HistoryMessageReply::resize(int width) const { + if (_replyToVia) { + bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; + int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; + _replyToVia->resize(width - st::msgReplyBarSkip - previewSkip - replyToName.maxWidth() - st::msgServiceFont->spacew); + } +} + +void HistoryMessageReply::itemRemoved(HistoryMessage *holder, HistoryItem *removed) { + if (replyToMsg == removed) { + clearData(holder); + holder->setPendingInitDimensions(); + } +} + +void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, int y, int w, PaintFlags flags) const { + bool selected = (flags & PaintSelected), outbg = holder->hasOutLayout(); + + style::color bar; + if (flags & PaintInBubble) { + bar = ((flags & PaintSelected) ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor)); + } else { + bar = st::white; + } + QRect rbar(rtlrect(x + st::msgReplyBarPos.x(), y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), w + 2 * x)); + p.fillRect(rbar, bar); + + if (w > st::msgReplyBarSkip) { + if (replyToMsg) { + bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; + int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; + + if (hasPreview) { + ImagePtr replyPreview = replyToMsg->getMedia()->replyPreview(); + if (!replyPreview->isNull()) { + QRect to(rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x)); + p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height())); + if (selected) { + App::roundRect(p, to, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); + } + } + } + if (w > st::msgReplyBarSkip + previewSkip) { + if (flags & PaintInBubble) { + p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg)); + } else { + p.setPen(st::white); + } + replyToName.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top(), w - st::msgReplyBarSkip - previewSkip, w + 2 * x); + if (_replyToVia && w > st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew) { + p.setFont(st::msgServiceFont); + p.drawText(x + st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew, y + st::msgReplyPadding.top() + st::msgServiceFont->ascent, _replyToVia->_text); + } + + HistoryMessage *replyToAsMsg = replyToMsg->toHistoryMessage(); + if (!(flags & PaintInBubble)) { + } else if ((replyToAsMsg && replyToAsMsg->emptyText()) || replyToMsg->serviceMsg()) { + style::color date(outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg)); + p.setPen(date); + } else { + p.setPen(st::msgColor); + } + replyToText.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top() + st::msgServiceNameFont->height, w - st::msgReplyBarSkip - previewSkip, w + 2 * x); + } + } else { + p.setFont(st::msgDateFont); + style::color date(outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg)); + p.setPen((flags & PaintInBubble) ? date : st::white); + p.drawTextLeft(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2, w + 2 * x, st::msgDateFont->elided(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message), w - st::msgReplyBarSkip)); + } + } +} + +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) { PeerId authorOriginalId = 0, fromOriginalId = 0; MsgId originalId = 0; if (msg.has_fwd_from() && msg.vfwd_from.type() == mtpc_messageFwdHeader) { @@ -6053,7 +6165,10 @@ HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) : if (f.has_channel_post()) originalId = f.vchannel_post.v; } } - createInterfaces(msg.has_via_bot_id() ? msg.vvia_bot_id.v : 0, msg.has_views() ? msg.vviews.v : -1, authorOriginalId, fromOriginalId, originalId); + MsgId replyTo = msg.has_reply_to_msg_id() ? msg.vreply_to_msg_id.v : 0; + int32 viaBotId = msg.has_via_bot_id() ? msg.vvia_bot_id.v : 0; + int views = msg.has_views() ? msg.vviews.v : -1; + createInterfaces(replyTo, viaBotId, views, authorOriginalId, fromOriginalId, originalId); QString text(textClean(qs(msg.vmessage))); initMedia(msg.has_media() ? (&msg.vmedia) : 0, text); @@ -6064,8 +6179,9 @@ HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags fl : HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from) { UserData *fwdViaBot = fwd->viaBot(); int32 viaBotId = fwdViaBot ? peerToUser(fwdViaBot->id) : 0; - int32 fwdViewsCount = fwd->viewsCount(), views = (fwdViewsCount > 0) ? fwdViewsCount : (isPost() ? 1 : -1); - createInterfaces(viaBotId, views, fwd->authorOriginal()->id, fwd->fromOriginal()->id, fwd->authorOriginal()->isChannel() ? fwd->id : 0); + int fwdViewsCount = fwd->viewsCount(), views = (fwdViewsCount > 0) ? fwdViewsCount : (isPost() ? 1 : -1); + MsgId replyTo = 0; + createInterfaces(replyTo, viaBotId, views, fwd->authorOriginal()->id, fwd->fromOriginal()->id, fwd->authorOriginal()->isChannel() ? fwd->id : 0); if (HistoryMedia *mediaOriginal = fwd->getMedia()) { _media = mediaOriginal->clone(); @@ -6074,32 +6190,41 @@ HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags fl setText(fwd->originalText(), fwd->originalEntities()); } -HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, 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) { - createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); +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) { + createInterfacesHelper(flags, replyTo, viaBotId); setText(msg, entities); } -HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) : -HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) { - createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); +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) { + createInterfacesHelper(flags, replyTo, viaBotId); initMediaFromDocument(doc, caption); setText(QString(), EntitiesInText()); } -HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) : -HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) { - createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); +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) { + createInterfacesHelper(flags, replyTo, viaBotId); _media = new HistoryPhoto(photo, caption, this); _media->attachToItem(this); setText(QString(), EntitiesInText()); } -void HistoryMessage::createInterfaces(int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal, const PeerId &fromIdOriginal, MsgId originalId) { +void HistoryMessage::createInterfacesHelper(MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId) { + if (!(flags & MTPDmessage::Flag::f_via_bot_id)) viaBotId = 0; + if (!(flags & MTPDmessage::Flag::f_reply_to_msg_id)) replyTo = 0; + createInterfaces(replyTo, viaBotId, isPost() ? 1 : -1); +} + +void HistoryMessage::createInterfaces(MsgId replyTo, int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal, const PeerId &fromIdOriginal, MsgId originalId) { uint64 mask = 0; + if (replyTo) { + mask |= HistoryMessageReply::Bit(); + } if (viaBotId) { mask |= HistoryMessageVia::Bit(); } @@ -6112,17 +6237,23 @@ void HistoryMessage::createInterfaces(int32 viaBotId, int32 viewsCount, const Pe if (authorIdOriginal && fromIdOriginal) { mask |= HistoryMessageForwarded::Bit(); } - UpdateInterfaces(mask); - if (HistoryMessageVia *via = Get()) { + UpdateComponents(mask); + if (auto *reply = Get()) { + reply->replyToMsgId = replyTo; + if (!reply->updateData(this) && App::api()) { + App::api()->requestMessageData(history()->peer->asChannel(), replyTo, new HistoryDependentItemCallback(fullId())); + } + } + if (auto *via = Get()) { via->create(viaBotId); } - if (HistoryMessageViews *views = Get()) { + if (auto *views = Get()) { views->_views = viewsCount; } - if (HistoryMessageSigned *msgsigned = Get()) { + if (auto *msgsigned = Get()) { msgsigned->create(_from->asUser(), date); } - if (HistoryMessageForwarded *fwd = Get()) { + if (auto *fwd = Get()) { fwd->_authorOriginal = App::peer(authorIdOriginal); fwd->_fromOriginal = App::peer(fromIdOriginal); fwd->_originalId = originalId; @@ -6150,13 +6281,13 @@ QString formatViewsCount(int32 views) { } void HistoryMessage::initTime() { - if (HistoryMessageSigned *msgsigned = Get()) { + if (auto *msgsigned = Get()) { _timeWidth = msgsigned->maxWidth(); } else { _timeText = date.toString(cTimeFormat()); _timeWidth = st::msgDateFont->width(_timeText); } - if (HistoryMessageViews *views = Get()) { + if (auto *views = Get()) { views->_viewsText = (views->_views >= 0) ? formatViewsCount(views->_views) : QString(); views->_viewsWidth = views->_viewsText.isEmpty() ? 0 : st::msgDateFont->width(views->_viewsText); } @@ -6228,9 +6359,10 @@ int32 HistoryMessage::plainMaxWidth() const { } void HistoryMessage::initDimensions() { + auto *reply = Get(); if (drawBubble()) { - HistoryMessageForwarded *fwd = Get(); - HistoryMessageVia *via = Get(); + auto fwd = Get(); + auto via = Get(); if (fwd) { fwd->create(via); } @@ -6286,6 +6418,16 @@ void HistoryMessage::initDimensions() { _maxw = _media->maxWidth(); _minh = _media->minHeight(); } + if (reply) { + reply->updateName(); + if (!_media) { + int replyw = st::msgPadding.left() + reply->_maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right(); + if (reply->_replyToVia) { + replyw += st::msgServiceFont->spacew + reply->_replyToVia->_maxWidth; + } + if (replyw > _maxw) _maxw = replyw; + } + } } void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const { @@ -6312,8 +6454,8 @@ void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const { void HistoryMessage::fromNameUpdated(int32 width) const { _authorNameVersion = author()->nameVersion; - if (!Is()) { - if (const HistoryMessageVia *via = Get()) { + if (!Has()) { + if (auto *via = Get()) { via->resize(width - st::msgPadding.left() - st::msgPadding.right() - author()->nameText.maxWidth() - st::msgServiceFont->spacew); } } @@ -6361,7 +6503,7 @@ QString HistoryMessage::selectedText(uint32 selection) const { uint16 selectedTo = (selection == FullSelection) ? 0xFFFF : (selection & 0xFFFF); result = _text.original(selectedFrom, selectedTo, Text::ExpandLinksAll); } - if (const HistoryMessageForwarded *fwd = Get()) { + if (auto *fwd = Get()) { if (selection == FullSelection) { QString fwdinfo = fwd->_text.original(0, 0xFFFF, Text::ExpandLinksAll), wrapped; wrapped.reserve(fwdinfo.size() + 4 + result.size()); @@ -6369,6 +6511,14 @@ QString HistoryMessage::selectedText(uint32 selection) const { result = wrapped; } } + if (auto *reply = Get()) { + if (selection == FullSelection && reply->replyToMsg) { + QString wrapped; + wrapped.reserve(lang(lng_in_reply_to).size() + reply->replyToMsg->author()->name.size() + 4 + result.size()); + wrapped.append('[').append(lang(lng_in_reply_to)).append(' ').append(reply->replyToMsg->author()->name).append(qsl("]\n")).append(result); + result = wrapped; + } + } return result; } @@ -6464,7 +6614,7 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width } dateX += HistoryMessage::timeLeft(); - if (const HistoryMessageSigned *msgsigned = Get()) { + if (auto *msgsigned = Get()) { msgsigned->_signature.drawElided(p, dateX, dateY, _timeWidth); } else { p.drawText(dateX, dateY + st::msgDateFont->ascent, _timeText); @@ -6472,7 +6622,7 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width QPoint iconPos; const QRect *iconRect = 0; - if (const HistoryMessageViews *views = Get()) { + if (auto *views = Get()) { iconPos = QPoint(infoRight - infoW + st::msgViewsPos.x(), infoBottom - st::msgViewsImg.pxHeight() + st::msgViewsPos.y()); if (id > 0) { if (outbg) { @@ -6511,7 +6661,7 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width } void HistoryMessage::setViewsCount(int32 count) { - HistoryMessageViews *views = Get(); + auto *views = Get(); if (!views || views->_views == count || (count >= 0 && views->_views > count)) return; int32 was = views->_viewsWidth; @@ -6588,9 +6738,14 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m // author()->paintUserpic(p, st::msgPhotoSize, photoleft, phototop); //} + auto *reply = Get(); + if (reply) { + reply->checkNameUpdate(); + } + if (bubble) { - const HistoryMessageForwarded *fwd = Get(); - const HistoryMessageVia *via = Get(); + auto *fwd = Get(); + auto *via = Get(); if (displayFromName() && author()->nameVersion > _authorNameVersion) { fromNameUpdated(width); } @@ -6619,7 +6774,16 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m } QRect trect(r.marginsAdded(-st::msgPadding)); - drawMessageText(p, trect, selection); + + paintForwardedInfo(p, trect, selected); + paintReplyInfo(p, trect, selected); + paintViaBotIdInfo(p, trect, selected); + + p.setPen(st::msgColor); + p.setFont(st::msgFont); + uint16 selectedFrom = selected ? 0 : ((selection >> 16) & 0xFFFF); + uint16 selectedTo = selected ? 0 : (selection & 0xFFFF); + _text.draw(p, trect.x(), trect.y(), trect.width(), style::al_left, 0, -1, selectedFrom, selectedTo); if (_media && _media->isDisplayed()) { int32 top = height - marginBottom() - _media->height(); @@ -6642,38 +6806,52 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m textstyleRestore(); } -void HistoryMessage::drawMessageText(Painter &p, QRect trect, uint32 selection) const { +void HistoryMessage::paintForwardedInfo(Painter &p, QRect &trect, bool selected) const { if (displayForwardedFrom()) { style::font serviceFont(st::msgServiceFont), serviceName(st::msgServiceNameFont); - bool outbg = out() && !isPost(); - p.setPen((selection == FullSelection) ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg)); + p.setPen(selected ? (hasOutLayout() ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (hasOutLayout() ? st::msgOutServiceFg : st::msgInServiceFg)); p.setFont(serviceFont); - const HistoryMessageForwarded *fwd = Get(); + auto *fwd = Get(); bool breakEverywhere = (fwd->_text.countHeight(trect.width()) > 2 * serviceFont->height); - textstyleSet(&((selection == FullSelection) ? (outbg ? st::outFwdTextStyleSelected : st::inFwdTextStyleSelected) : (outbg ? st::outFwdTextStyle : st::inFwdTextStyle))); + textstyleSet(&(selected ? (hasOutLayout() ? st::outFwdTextStyleSelected : st::inFwdTextStyleSelected) : (hasOutLayout() ? st::outFwdTextStyle : st::inFwdTextStyle))); fwd->_text.drawElided(p, trect.x(), trect.y(), trect.width(), 2, style::al_left, 0, -1, 0, breakEverywhere); - textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle)); + textstyleSet(&(hasOutLayout() ? st::outTextStyle : st::inTextStyle)); trect.setY(trect.y() + (((fwd->_text.maxWidth() > trect.width()) ? 2 : 1) * serviceFont->height)); } +} - bool outbg = out() && !isPost(), selected = (selection == FullSelection); - if (!displayFromName() && !Is()) { - if (const HistoryMessageVia *via = Get()) { +void HistoryMessage::paintReplyInfo(Painter &p, QRect &trect, bool selected) const { + if (auto *reply = Get()) { + int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); + + HistoryMessageReply::PaintFlags flags = HistoryMessageReply::PaintInBubble; + if (selected) { + flags |= HistoryMessageReply::PaintSelected; + } + reply->paint(p, this, trect.x(), trect.y(), trect.width(), flags); + + trect.setY(trect.y() + h); + } +} + +void HistoryMessage::paintViaBotIdInfo(Painter &p, QRect &trect, bool selected) const { + if (!displayFromName() && !Has()) { + if (auto *via = Get()) { p.setFont(st::msgServiceNameFont); - p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg)); + p.setPen(selected ? (hasOutLayout() ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (hasOutLayout() ? st::msgOutServiceFg : st::msgInServiceFg)); p.drawTextLeft(trect.left(), trect.top(), _history->width, via->_text); trect.setY(trect.y() + st::msgServiceNameFont->height); } } +} - p.setPen(st::msgColor); - p.setFont(st::msgFont); - uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF; - uint16 selectedTo = (selection == FullSelection) ? 0 : selection & 0xFFFF; - _text.draw(p, trect.x(), trect.y(), trect.width(), style::al_left, 0, -1, selectedFrom, selectedTo); +void HistoryMessage::dependencyItemRemoved(HistoryItem *dependency) { + if (auto *reply = Get()) { + reply->itemRemoved(this, dependency); + } } void HistoryMessage::destroy() { @@ -6691,8 +6869,9 @@ int HistoryMessage::resizeGetHeight_(int width) { width = st::msgMaxWidth; } if (drawBubble()) { - HistoryMessageForwarded *fwd = Get(); - HistoryMessageVia *via = Get(); + auto *fwd = Get(); + auto *reply = Get(); + auto *via = Get(); bool media = (_media && _media->isDisplayed()); if (width >= _maxw) { @@ -6745,6 +6924,15 @@ int HistoryMessage::resizeGetHeight_(int width) { _height += fwdheight; } } + + if (reply) { + if (emptyText() && !displayFromName() && !Has()) { + _height += st::msgPadding.top() + st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaHeaderSkip; + } else { + _height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); + } + reply->resize(width - st::msgPadding.left() - st::msgPadding.right()); + } } else { _height = _media->resize(width, this); } @@ -6800,26 +6988,27 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 if (width < 1) return; if (drawBubble()) { - const HistoryMessageForwarded *fwd = Get(); - const HistoryMessageVia *via = Get(); + auto *fwd = Get(); + auto *via = Get(); + auto *reply = Get(); int top = marginTop(); QRect r(left, top, width, height - top - marginBottom()); - if (displayFromName()) { // from user left name - if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + st::msgNameFont->height) { - if (x >= r.left() + st::msgPadding.left() && x < r.left() + r.width() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + author()->nameText.maxWidth()) { + QRect trect(r.marginsAdded(-st::msgPadding)); + if (displayFromName()) { + if (y >= trect.top() && y < trect.top() + st::msgNameFont->height) { + if (x >= trect.left() && x < trect.left() + trect.width() && x < trect.left() + author()->nameText.maxWidth()) { lnk = author()->lnk; return; } - if (via && !fwd && x >= r.left() + st::msgPadding.left() + author()->nameText.maxWidth() + st::msgServiceFont->spacew && x < r.left() + st::msgPadding.left() + author()->nameText.maxWidth() + st::msgServiceFont->spacew + via->_width) { + if (via && !fwd && x >= trect.left() + author()->nameText.maxWidth() + st::msgServiceFont->spacew && x < trect.left() + author()->nameText.maxWidth() + st::msgServiceFont->spacew + via->_width) { lnk = via->_lnk; return; } } - r.setTop(r.top() + st::msgNameFont->height); + trect.setTop(trect.top() + st::msgNameFont->height); } if (displayForwardedFrom()) { - QRect trect(r.marginsAdded(-st::msgPadding)); int32 fwdheight = ((fwd->_text.maxWidth() > trect.width()) ? 2 : 1) * st::semiboldFont->height; if (y >= trect.top() && y < trect.top() + fwdheight) { bool inText = false; @@ -6832,57 +7021,57 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 } return; } - y -= fwdheight; - r.setHeight(r.height() - fwdheight); + trect.setTop(trect.top() + fwdheight); } - getStateFromMessageText(lnk, state, x, y, r); - } else { - _media->getState(lnk, state, x - left, y - marginTop(), this); - } -} - -void HistoryMessage::getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const { - bool inDate = false; - - QRect trect(r.marginsAdded(-st::msgPadding)); - - const HistoryMessageForwarded *fwd = Get(); - if (!displayFromName() && !fwd) { - if (const HistoryMessageVia *via = Get()) { + if (via && !displayFromName() && !displayForwardedFrom()) { if (x >= trect.left() && y >= trect.top() && y < trect.top() + st::msgNameFont->height && x < trect.left() + via->_width) { lnk = via->_lnk; return; } trect.setTop(trect.top() + st::msgNameFont->height); } - } + if (reply) { + int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); + if (y >= trect.top() && y < trect.top() + h) { + if (reply->replyToMsg && y >= trect.top() + st::msgReplyPadding.top() && y < trect.top() + st::msgReplyPadding.top() + st::msgReplyBarSize.height() && x >= trect.left() && x < trect.left() + trect.width()) { + lnk = reply->replyToLink(); + } + return; + } + trect.setTop(trect.top() + h); + } - TextLinkPtr medialnk; - if (_media && _media->isDisplayed()) { - if (!_media->customInfoLayout()) { + bool inDate = false; + + TextLinkPtr medialnk; + if (_media && _media->isDisplayed()) { + if (!_media->customInfoLayout()) { + inDate = HistoryMessage::pointInTime(r.x() + r.width(), r.y() + r.height(), x, y, InfoDisplayDefault); + } + if (y >= r.bottom() - _media->height() && y < r.bottom()) { + _media->getState(lnk, state, x - r.left(), y - (r.bottom() - _media->height()), this); + if (inDate) state = HistoryInDateCursorState; + return; + } + trect.setBottom(trect.bottom() - _media->height()); + } else { inDate = HistoryMessage::pointInTime(r.x() + r.width(), r.y() + r.height(), x, y, InfoDisplayDefault); } - if (y >= r.bottom() - _media->height() && y < r.bottom()) { - _media->getState(lnk, state, x - r.left(), y - (r.bottom() - _media->height()), this); - if (inDate) state = HistoryInDateCursorState; - return; + + textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle)); + bool inText = false; + _text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width()); + textstyleRestore(); + + if (inDate) { + state = HistoryInDateCursorState; + } else if (inText) { + state = HistoryInTextCursorState; + } else { + state = HistoryDefaultCursorState; } - trect.setBottom(trect.bottom() - _media->height()); } else { - inDate = HistoryMessage::pointInTime(r.x() + r.width(), r.y() + r.height(), x, y, InfoDisplayDefault); - } - - textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle)); - bool inText = false; - _text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width()); - textstyleRestore(); - - if (inDate) { - state = HistoryInDateCursorState; - } else if (inText) { - state = HistoryInTextCursorState; - } else { - state = HistoryDefaultCursorState; + _media->getState(lnk, state, x - left, y - marginTop(), this); } } @@ -6890,26 +7079,31 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, symbol = 0; after = false; upon = false; + if (drawBubble()) { int left = 0, width = 0, height = _height; countPositionAndSize(left, width); if (width < 1) return; - const HistoryMessageForwarded *fwd = Get(); - const HistoryMessageVia *via = Get(); + auto *fwd = Get(); + auto *via = Get(); + auto *reply = Get(); int top = marginTop(); QRect r(left, top, width, height - top - marginBottom()); - if (displayFromName()) { // from user left name - r.setTop(r.top() + st::msgNameFont->height); - } else if (via && !fwd) { - r.setTop(r.top() + st::msgNameFont->height); - } QRect trect(r.marginsAdded(-st::msgPadding)); + if (displayFromName()) { + trect.setTop(trect.top() + st::msgNameFont->height); + } else if (via && !fwd) { + trect.setTop(trect.top() + st::msgNameFont->height); + } if (displayForwardedFrom()) { int32 fwdheight = ((fwd->_text.maxWidth() > trect.width()) ? 2 : 1) * st::semiboldFont->height; - y -= fwdheight; - r.setHeight(r.height() - fwdheight); + trect.setTop(trect.top() + fwdheight); + } + if (reply) { + int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); + trect.setTop(trect.top() + h); } if (_media && _media->isDisplayed()) { trect.setBottom(trect.bottom() - _media->height()); @@ -6966,332 +7160,15 @@ HistoryMessage::~HistoryMessage() { _media->detachFromItem(this); deleteAndMark(_media); } + if (auto *reply = Get()) { + reply->clearData(this); + } if (_flags & MTPDmessage::Flag::f_reply_markup) { App::clearReplyMarkup(channelId(), id); } } -HistoryReply::HistoryReply(History *history, const MTPDmessage &msg) : HistoryMessage(history, msg) -, replyToMsgId(msg.vreply_to_msg_id.v) -, replyToMsg(0) -, replyToVersion(0) -, _maxReplyWidth(0) -, _replyToVia(0) { - if (!updateReplyTo() && App::api()) { - App::api()->requestMessageData(history->peer->asChannel(), replyToMsgId, new HistoryDependentItemCallback(fullId())); - } -} - -HistoryReply::HistoryReply(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) -: HistoryMessage(history, msgId, flags, viaBotId, date, from, doc, caption) -, replyToMsgId(replyTo) -, replyToMsg(0) -, replyToVersion(0) -, _maxReplyWidth(0) -, _replyToVia(0) { - if (!updateReplyTo() && App::api()) { - App::api()->requestMessageData(history->peer->asChannel(), replyToMsgId, new HistoryDependentItemCallback(fullId())); - } -} - -HistoryReply::HistoryReply(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) -: HistoryMessage(history, msgId, flags, viaBotId, date, from, photo, caption) -, replyToMsgId(replyTo) -, replyToMsg(0) -, replyToVersion(0) -, _maxReplyWidth(0) -, _replyToVia(0) { - if (!updateReplyTo() && App::api()) { - App::api()->requestMessageData(history->peer->asChannel(), replyToMsgId, new HistoryDependentItemCallback(fullId())); - } - replyToNameUpdated(); -} - -QString HistoryReply::selectedText(uint32 selection) const { - if (selection != FullSelection || !replyToMsg) return HistoryMessage::selectedText(selection); - QString result, original = HistoryMessage::selectedText(selection); - result.reserve(lang(lng_in_reply_to).size() + replyToMsg->author()->name.size() + 4 + original.size()); - result.append('[').append(lang(lng_in_reply_to)).append(' ').append(replyToMsg->author()->name).append(qsl("]\n")).append(original); - return result; -} - -void HistoryReply::initDimensions() { - replyToNameUpdated(); - HistoryMessage::initDimensions(); - if (!_media) { - int32 replyw = st::msgPadding.left() + _maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right(); - if (_replyToVia) { - replyw += st::msgServiceFont->spacew + _replyToVia->_maxWidth; - } - if (replyw > _maxw) _maxw = replyw; - } -} - -bool HistoryReply::updateReplyTo(bool force) { - if (!force) { - if (replyToMsg || !replyToMsgId) { - return true; - } - } - if (!replyToMsg) { - replyToMsg = App::histItemById(channelId(), replyToMsgId); - if (replyToMsg) { - App::historyRegDependency(this, replyToMsg); - } - } - - if (replyToMsg) { - replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions); - - replyToNameUpdated(); - - replyToLnk = TextLinkPtr(new MessageLink(replyToMsg->history()->peer->id, replyToMsg->id)); - if (!replyToMsg->Is()) { - if (UserData *bot = replyToMsg->viaBot()) { - _replyToVia = new HistoryMessageVia(0); - _replyToVia->create(peerToUser(bot->id)); - } - } - } else if (force) { - replyToMsgId = 0; - } - if (force) { - setPendingInitDimensions(); - } - return (replyToMsg || !replyToMsgId); -} - -void HistoryReply::replyToNameUpdated() const { - if (replyToMsg) { - QString name = (_replyToVia && replyToMsg->author()->isUser()) ? replyToMsg->author()->asUser()->firstName : App::peerName(replyToMsg->author()); - replyToName.setText(st::msgServiceNameFont, name, _textNameOptions); - replyToVersion = replyToMsg->author()->nameVersion; - bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; - int32 previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; - int32 w = replyToName.maxWidth(); - if (_replyToVia) { - w += st::msgServiceFont->spacew + _replyToVia->_maxWidth; - } - - _maxReplyWidth = previewSkip + qMax(w, qMin(replyToText.maxWidth(), int32(st::maxSignatureSize))); - } else { - _maxReplyWidth = st::msgDateFont->width(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message)); - } - _maxReplyWidth = st::msgReplyPadding.left() + st::msgReplyBarSkip + _maxReplyWidth + st::msgReplyPadding.right(); -} - -int32 HistoryReply::replyToWidth() const { - return _maxReplyWidth; -} - -TextLinkPtr HistoryReply::replyToLink() const { - return replyToLnk; -} - -MsgId HistoryReply::replyToId() const { - return replyToMsgId; -} - -HistoryItem *HistoryReply::replyToMessage() const { - return replyToMsg; -} - -void HistoryReply::dependencyItemRemoved(HistoryItem *dependency) { - if (replyToMsg == dependency) { - delete _replyToVia; - _replyToVia = 0; - - replyToMsg = nullptr; - replyToMsgId = 0; - initDimensions(); - } -} - -void HistoryReply::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const { - if (replyToMsg && replyToMsg->author()->nameVersion > replyToVersion) { - replyToNameUpdated(); - } - HistoryMessage::draw(p, r, selection, ms); -} - -void HistoryReply::drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService) const { - style::color bar; - bool outbg = out() && !isPost(); - if (likeService) { - bar = st::white; - } else { - bar = (selected ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor)); - } - QRect rbar(rtlrect(x + st::msgReplyBarPos.x(), y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), w + 2 * x)); - p.fillRect(rbar, bar); - - if (w > st::msgReplyBarSkip) { - if (replyToMsg) { - bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; - int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; - - if (hasPreview) { - ImagePtr replyPreview = replyToMsg->getMedia()->replyPreview(); - if (!replyPreview->isNull()) { - QRect to(rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x)); - p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height())); - if (selected) { - App::roundRect(p, to, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); - } - } - } - if (w > st::msgReplyBarSkip + previewSkip) { - if (likeService) { - p.setPen(st::white); - } else { - p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg)); - } - replyToName.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top(), w - st::msgReplyBarSkip - previewSkip, w + 2 * x); - if (_replyToVia && w > st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew) { - p.setFont(st::msgServiceFont); - p.drawText(x + st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew, y + st::msgReplyPadding.top() + st::msgServiceFont->ascent, _replyToVia->_text); - } - - HistoryMessage *replyToAsMsg = replyToMsg->toHistoryMessage(); - if (likeService) { - } else if ((replyToAsMsg && replyToAsMsg->emptyText()) || replyToMsg->serviceMsg()) { - style::color date(outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg)); - p.setPen(date); - } else { - p.setPen(st::msgColor); - } - replyToText.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top() + st::msgServiceNameFont->height, w - st::msgReplyBarSkip - previewSkip, w + 2 * x); - } - } else { - p.setFont(st::msgDateFont); - style::color date(outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg)); - p.setPen(likeService ? st::white : date); - p.drawTextLeft(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2, w + 2 * x, st::msgDateFont->elided(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message), w - st::msgReplyBarSkip)); - } - } -} - -void HistoryReply::drawMessageText(Painter &p, QRect trect, uint32 selection) const { - int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); - - drawReplyTo(p, trect.x(), trect.y(), trect.width(), (selection == FullSelection)); - - trect.setY(trect.y() + h); - HistoryMessage::drawMessageText(p, trect, selection); -} - -int32 HistoryReply::resizeGetHeight_(int32 width) { - HistoryMessage::resizeGetHeight_(width); - - if (drawBubble()) { - if (emptyText() && !displayFromName() && !Is()) { - _height += st::msgPadding.top() + st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaHeaderSkip; - } else { - _height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); - } - if (_replyToVia) { - bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; - int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; - _replyToVia->resize(width - st::msgPadding.left() - st::msgPadding.right() - st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew); - } - } - return _height; -} - -void HistoryReply::resizeVia(int32 w) const { - if (!_replyToVia) return; - - bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; - int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; - _replyToVia->resize(w - st::msgReplyBarSkip - previewSkip - replyToName.maxWidth() - st::msgServiceFont->spacew); -} - -void HistoryReply::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const { - lnk = TextLinkPtr(); - state = HistoryDefaultCursorState; - - if (drawBubble()) { - int32 left = 0, width = 0; - countPositionAndSize(left, width); - //if (displayFromPhoto()) { - // int32 photoleft = left + ((!isPost() && out()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); - // if (x >= photoleft && x < photoleft + st::msgPhotoSize) { - // return HistoryMessage::getState(lnk, state, x, y); - // } - //} - if (width < 1) return; - - int top = marginTop(); - QRect r(left, top, width, _height - top - marginBottom()); - if (displayFromName()) { - style::font nameFont(st::msgNameFont); - if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) { - return HistoryMessage::getState(lnk, state, x, y); - } - r.setTop(r.top() + nameFont->height); - } - QRect trect(r.marginsAdded(-st::msgPadding)); - - int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); - if (y >= trect.top() && y < trect.top() + h) { - if (replyToMsg && y >= trect.top() + st::msgReplyPadding.top() && y < trect.top() + st::msgReplyPadding.top() + st::msgReplyBarSize.height() && x >= trect.left() && x < trect.left() + trect.width()) { - lnk = replyToLnk; - } - return; - } - y -= h; - } - return HistoryMessage::getState(lnk, state, x, y); -} - -void HistoryReply::getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const { - int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); - - QRect realr(r); - realr.setHeight(r.height() - h); - HistoryMessage::getStateFromMessageText(lnk, state, x, y, realr); -} - -void HistoryReply::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const { - symbol = 0; - after = false; - upon = false; - - if (drawBubble()) { - int32 left = 0, width = 0; - countPositionAndSize(left, width); - if (width < 1) return; - - int top = marginTop(); - QRect r(left, top, width, _height - top - marginBottom()); - if (displayFromName()) { - style::font nameFont(st::msgNameFont); - if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) { - return HistoryMessage::getSymbol(symbol, after, upon, x, y); - } - r.setTop(r.top() + nameFont->height); - } - QRect trect(r.marginsAdded(-st::msgPadding)); - - int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); - y -= h; - } - return HistoryMessage::getSymbol(symbol, after, upon, x, y); -} - -HistoryReply::~HistoryReply() { - if (replyToMsg) { - App::historyUnregDependency(this, replyToMsg); - } - deleteAndMark(_replyToVia); -} - -HistoryServicePinned::HistoryServicePinned(Interfaces *) -: msgId(0) -, msg(0) { -} - -void HistoryServiceMessage::setMessageByAction(const MTPmessageAction &action) { +void HistoryService::setMessageByAction(const MTPmessageAction &action) { QList links; LangString text = lang(lng_message_empty); QString from = textcmdLink(1, _from->name); @@ -7399,7 +7276,7 @@ void HistoryServiceMessage::setMessageByAction(const MTPmessageAction &action) { case mtpc_messageActionChatMigrateTo: { _flags |= MTPDmessage_ClientFlag::f_is_group_migrate; const MTPDmessageActionChatMigrateTo &d(action.c_messageActionChatMigrateTo()); - if (true/*PeerData *channel = App::peerLoaded(peerFromChannel(d.vchannel_id))*/) { + if (true/*PeerData *channel = App::channelLoaded(d.vchannel_id.v)*/) { text = lang(lng_action_group_migrate); } else { text = lang(lng_contacts_loading); @@ -7409,7 +7286,7 @@ void HistoryServiceMessage::setMessageByAction(const MTPmessageAction &action) { case mtpc_messageActionChannelMigrateFrom: { _flags |= MTPDmessage_ClientFlag::f_is_group_migrate; const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom()); - if (true/*PeerData *chat = App::peerLoaded(peerFromChannel(d.vchat_id))*/) { + if (true/*PeerData *chat = App::chatLoaded(d.vchat_id.v)*/) { text = lang(lng_action_group_migrate); } else { text = lang(lng_contacts_loading); @@ -7418,7 +7295,7 @@ void HistoryServiceMessage::setMessageByAction(const MTPmessageAction &action) { case mtpc_messageActionPinMessage: { if (updatePinnedText(&from, &text)) { - HistoryServicePinned *pinned = Get(); + auto *pinned = Get(); t_assert(pinned != nullptr); links.push_back(pinned->lnk); @@ -7439,8 +7316,8 @@ void HistoryServiceMessage::setMessageByAction(const MTPmessageAction &action) { } } -bool HistoryServiceMessage::updatePinned(bool force) { - HistoryServicePinned *pinned = Get(); +bool HistoryService::updatePinned(bool force) { + auto *pinned = Get(); t_assert(pinned != nullptr); if (!force) { @@ -7478,7 +7355,7 @@ bool HistoryServiceMessage::updatePinned(bool force) { return (pinned->msg || !pinned->msgId); } -bool HistoryServiceMessage::updatePinnedText(const QString *pfrom, QString *ptext) { +bool HistoryService::updatePinnedText(const QString *pfrom, QString *ptext) { bool result = false; QString from, text; if (pfrom) { @@ -7488,7 +7365,7 @@ bool HistoryServiceMessage::updatePinnedText(const QString *pfrom, QString *ptex } TextLinkPtr second; - HistoryServicePinned *pinned = Get(); + auto *pinned = Get(); if (pinned && pinned->msg) { HistoryMedia *media = pinned->msg->getMedia(); QString mediaText; @@ -7550,10 +7427,10 @@ bool HistoryServiceMessage::updatePinnedText(const QString *pfrom, QString *ptex return result; } -HistoryServiceMessage::HistoryServiceMessage(History *history, const MTPDmessageService &msg) : +HistoryService::HistoryService(History *history, const MTPDmessageService &msg) : HistoryItem(history, msg.vid.v, mtpCastFlags(msg.vflags.v), ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) { if (msg.has_reply_to_msg_id()) { - UpdateInterfaces(HistoryServicePinned::Bit()); + UpdateComponents(HistoryServicePinned::Bit()); MsgId pinnedMsgId = Get()->msgId = msg.vreply_to_msg_id.v; if (!updatePinned() && App::api()) { App::api()->requestMessageData(history->peer->asChannel(), pinnedMsgId, new HistoryDependentItemCallback(fullId())); @@ -7562,19 +7439,19 @@ HistoryServiceMessage::HistoryServiceMessage(History *history, const MTPDmessage setMessageByAction(msg.vaction); } -HistoryServiceMessage::HistoryServiceMessage(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags, HistoryMedia *media, int32 from) : +HistoryService::HistoryService(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags, HistoryMedia *media, int32 from) : HistoryItem(history, msgId, flags, date, from) , _text(st::msgServiceFont, msg, _historySrvOptions, st::dlgMinWidth) , _media(media) { } -void HistoryServiceMessage::initDimensions() { +void HistoryService::initDimensions() { _maxw = _text.maxWidth() + st::msgServicePadding.left() + st::msgServicePadding.right(); _minh = _text.minHeight(); if (_media) _media->initDimensions(this); } -void HistoryServiceMessage::countPositionAndSize(int32 &left, int32 &width) const { +void HistoryService::countPositionAndSize(int32 &left, int32 &width) const { left = st::msgServiceMargin.left(); int32 maxwidth = _history->width; if (Adaptive::Wide()) { @@ -7583,29 +7460,29 @@ void HistoryServiceMessage::countPositionAndSize(int32 &left, int32 &width) cons width = maxwidth - st::msgServiceMargin.left() - st::msgServiceMargin.left(); } -QString HistoryServiceMessage::selectedText(uint32 selection) const { +QString HistoryService::selectedText(uint32 selection) const { uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF; uint16 selectedTo = (selection == FullSelection) ? 0xFFFF : (selection & 0xFFFF); return _text.original(selectedFrom, selectedTo); } -QString HistoryServiceMessage::inDialogsText() const { +QString HistoryService::inDialogsText() const { return _text.original(0, 0xFFFF, Text::ExpandLinksNone); } -QString HistoryServiceMessage::inReplyText() const { - QString result = HistoryServiceMessage::inDialogsText(); +QString HistoryService::inReplyText() const { + QString result = HistoryService::inDialogsText(); return result.trimmed().startsWith(author()->name) ? result.trimmed().mid(author()->name.size()).trimmed() : result; } -void HistoryServiceMessage::setServiceText(const QString &text) { +void HistoryService::setServiceText(const QString &text) { textstyleSet(&st::serviceTextStyle); _text.setText(st::msgServiceFont, text, _historySrvOptions); textstyleRestore(); initDimensions(); } -void HistoryServiceMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const { +void HistoryService::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const { int left = 0, width = 0, height = _height - st::msgServiceMargin.top() - st::msgServiceMargin.bottom(); // two small margins countPositionAndSize(left, width); if (width < 1) return; @@ -7673,7 +7550,7 @@ void HistoryServiceMessage::draw(Painter &p, const QRect &r, uint32 selection, u } } -int32 HistoryServiceMessage::resizeGetHeight_(int32 width) { +int32 HistoryService::resizeGetHeight_(int32 width) { int32 maxwidth = _history->width; if (Adaptive::Wide()) { maxwidth = qMin(maxwidth, int32(st::msgMaxWidth + 2 * st::msgPhotoSkip + 2 * st::msgMargin.left())); @@ -7705,7 +7582,7 @@ int32 HistoryServiceMessage::resizeGetHeight_(int32 width) { return _height; } -bool HistoryServiceMessage::hasPoint(int32 x, int32 y) const { +bool HistoryService::hasPoint(int32 x, int32 y) const { int left = 0, width = 0, height = _height - st::msgServiceMargin.top() - st::msgServiceMargin.bottom(); // two small margins countPositionAndSize(left, width); if (width < 1) return false; @@ -7726,7 +7603,7 @@ bool HistoryServiceMessage::hasPoint(int32 x, int32 y) const { return QRect(left, st::msgServiceMargin.top(), width, height).contains(x, y); } -void HistoryServiceMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const { +void HistoryService::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const { lnk = TextLinkPtr(); state = HistoryDefaultCursorState; @@ -7759,7 +7636,7 @@ void HistoryServiceMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state } } -void HistoryServiceMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const { +void HistoryService::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const { symbol = 0; after = false; upon = false; @@ -7787,7 +7664,7 @@ void HistoryServiceMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, i textstyleRestore(); } -void HistoryServiceMessage::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const { +void HistoryService::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const { if (cacheFor != this) { cacheFor = this; cache.setText(st::dlgHistFont, inDialogsText(), _textDlgOptions); @@ -7797,17 +7674,17 @@ void HistoryServiceMessage::drawInDialog(Painter &p, const QRect &r, bool act, c cache.drawElided(p, tr.left(), tr.top(), tr.width(), tr.height() / st::dlgHistFont->height); } -QString HistoryServiceMessage::notificationText() const { +QString HistoryService::notificationText() const { QString msg = _text.original(); if (msg.size() > 0xFF) msg = msg.mid(0, 0xFF) + qsl("..."); return msg; } -HistoryMedia *HistoryServiceMessage::getMedia(bool inOverview) const { +HistoryMedia *HistoryService::getMedia(bool inOverview) const { return inOverview ? 0 : _media; } -HistoryServiceMessage::~HistoryServiceMessage() { +HistoryService::~HistoryService() { if (auto pinned = Get()) { if (pinned->msg) { App::historyUnregDependency(this, pinned->msg); @@ -7820,7 +7697,7 @@ HistoryServiceMessage::~HistoryServiceMessage() { } HistoryGroup::HistoryGroup(History *history, const MTPDmessageGroup &group, const QDateTime &date) - : HistoryServiceMessage(history, clientMsgId(), date, lng_channel_comments_count(lt_count, group.vcount.v)/* + qsl(" (%1 ... %2)").arg(group.vmin_id.v).arg(group.vmax_id.v)*/) + : HistoryService(history, clientMsgId(), date, lng_channel_comments_count(lt_count, group.vcount.v)/* + qsl(" (%1 ... %2)").arg(group.vmin_id.v).arg(group.vmax_id.v)*/) , _minId(group.vmin_id.v) , _maxId(group.vmax_id.v) , _count(group.vcount.v) @@ -7828,7 +7705,7 @@ HistoryGroup::HistoryGroup(History *history, const MTPDmessageGroup &group, cons } HistoryGroup::HistoryGroup(History *history, HistoryItem *newItem, const QDateTime &date) - : HistoryServiceMessage(history, clientMsgId(), date, lng_channel_comments_count(lt_count, 1)/* + qsl(" (%1 ... %2)").arg(newItem->id - 1).arg(newItem->id + 1)*/) + : HistoryService(history, clientMsgId(), date, lng_channel_comments_count(lt_count, 1)/* + qsl(" (%1 ... %2)").arg(newItem->id - 1).arg(newItem->id + 1)*/) , _minId(newItem->id - 1) , _maxId(newItem->id + 1) , _count(1) @@ -7898,7 +7775,7 @@ void HistoryGroup::updateText() { } HistoryCollapse::HistoryCollapse(History *history, MsgId wasMinId, const QDateTime &date) - : HistoryServiceMessage(history, clientMsgId(), date, qsl("-")) + : HistoryService(history, clientMsgId(), date, qsl("-")) , _wasMinId(wasMinId) { } @@ -7911,7 +7788,7 @@ void HistoryCollapse::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3 } HistoryJoined::HistoryJoined(History *history, const QDateTime &inviteDate, UserData *inviter, MTPDmessage::Flags flags) - : HistoryServiceMessage(history, clientMsgId(), inviteDate, QString(), flags) { + : HistoryService(history, clientMsgId(), inviteDate, QString(), flags) { textstyleSet(&st::serviceTextStyle); if (peerToUser(inviter->id) == MTP::authedId()) { _text.setText(st::msgServiceFont, lang(history->isMegagroup() ? lng_action_you_joined_group : lng_action_you_joined), _historySrvOptions); diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 1a8c9626d..07bce6754 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -936,7 +936,6 @@ protected: }; -class HistoryReply; // dynamic_cast optimize class HistoryMessage; // dynamic_cast optimize enum HistoryCursorState { @@ -962,43 +961,104 @@ enum HistoryItemType { HistoryItemJoined }; -struct HistoryMessageVia : public BasicInterface { - HistoryMessageVia(Interfaces *); +struct HistoryMessageVia : public BaseComponent { + HistoryMessageVia(Composer*) { + } void create(int32 userId); void resize(int32 availw) const; - UserData *_bot; + UserData *_bot = nullptr; mutable QString _text; - mutable int32 _width, _maxWidth; + mutable int _width = 0; + mutable int _maxWidth = 0; TextLinkPtr _lnk; }; -struct HistoryMessageViews : public BasicInterface { - HistoryMessageViews(Interfaces *); +struct HistoryMessageViews : public BaseComponent { + HistoryMessageViews(Composer*) { + } QString _viewsText; - int32 _views, _viewsWidth; + int _views = 0; + int _viewsWidth = 0; }; -struct HistoryMessageSigned : public BasicInterface { - HistoryMessageSigned(Interfaces *); +struct HistoryMessageSigned : public BaseComponent { + HistoryMessageSigned(Composer*) { + } void create(UserData *from, const QDateTime &date); - int32 maxWidth() const; + int maxWidth() const; Text _signature; }; -struct HistoryMessageForwarded : public BasicInterface { - HistoryMessageForwarded(Interfaces *); +struct HistoryMessageForwarded : public BaseComponent { + HistoryMessageForwarded(Composer*) { + } void create(const HistoryMessageVia *via) const; - bool display(bool hasVia) const; - PeerData *_authorOriginal, *_fromOriginal; - MsgId _originalId; - mutable Text _text; + PeerData *_authorOriginal = nullptr; + PeerData *_fromOriginal = nullptr; + MsgId _originalId = 0; + mutable Text _text = { 1 }; }; +struct HistoryMessageReply : public BaseComponent { + HistoryMessageReply(Composer*) { + } + HistoryMessageReply &operator=(HistoryMessageReply &&other) { + replyToMsgId = other.replyToMsgId; + std::swap(replyToMsg, other.replyToMsg); + replyToLnk = std11::move(other.replyToLnk); + replyToName = std11::move(other.replyToName); + replyToText = std11::move(other.replyToText); + replyToVersion = other.replyToVersion; + _maxReplyWidth = other._maxReplyWidth; + std::swap(_replyToVia, other._replyToVia); + return *this; + } + ~HistoryMessageReply() { + // clearData() should be called by holder + t_assert(replyToMsg == nullptr); + t_assert(_replyToVia == nullptr); + } + bool updateData(HistoryMessage *holder, bool force = false); + void clearData(HistoryMessage *holder); // must be called before destructor + + void checkNameUpdate() const; + void updateName() const; + void resize(int width) const; + void itemRemoved(HistoryMessage *holder, HistoryItem *removed); + + enum PaintFlag { + PaintInBubble = 0x01, + PaintSelected = 0x02, + }; + Q_DECLARE_FLAGS(PaintFlags, PaintFlag); + void paint(Painter &p, const HistoryItem *holder, int x, int y, int w, PaintFlags flags) const; + + MsgId replyToId() const { + return replyToMsgId; + } + int replyToWidth() const { + return _maxReplyWidth; + } + TextLinkPtr replyToLink() const { + return replyToLnk; + } + + MsgId replyToMsgId = 0; + HistoryItem *replyToMsg = nullptr; + TextLinkPtr replyToLnk; + mutable Text replyToName, replyToText; + mutable int replyToVersion = 0; + mutable int _maxReplyWidth = 0; + HistoryMessageVia *_replyToVia = nullptr; + int toWidth = 0; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(HistoryMessageReply::PaintFlags); + class HistoryDependentItemCallback : public SharedCallback2 { public: HistoryDependentItemCallback(FullMsgId dependent) : _dependent(dependent) { @@ -1012,28 +1072,30 @@ private: // any HistoryItem can have this Interface for // displaying the day mark above the message -struct HistoryMessageDate : public BasicInterface { - HistoryMessageDate(Interfaces *); +struct HistoryMessageDate : public BaseComponent { + HistoryMessageDate(Composer*) { + } void init(const QDateTime &date); int height() const; void paint(Painter &p, int y, int w) const; QString _text; - int _width; + int _width = 0; }; // any HistoryItem can have this Interface for // displaying the unread messages bar above the message -struct HistoryMessageUnreadBar : public BasicInterface { - HistoryMessageUnreadBar(Interfaces *); +struct HistoryMessageUnreadBar : public BaseComponent { + HistoryMessageUnreadBar(Composer*) { + } void init(int count); int height() const; void paint(Painter &p, int y, int w) const; QString _text; - int _width; + int _width = 0; // if unread bar is freezed the new messages do not // increment the counter displayed by this bar @@ -1041,11 +1103,11 @@ struct HistoryMessageUnreadBar : public BasicInterface // it happens when we've opened the conversation and // we've seen the bar and new messages are marked as read // as soon as they are added to the chat history - bool _freezed; + bool _freezed = false; }; class HistoryMedia; -class HistoryItem : public HistoryElem, public Interfaces { +class HistoryItem : public HistoryElem, public Composer { public: HistoryItem(const HistoryItem &) = delete; @@ -1075,8 +1137,11 @@ public: return true; } - virtual UserData *viaBot() const { - return 0; + UserData *viaBot() const { + if (const HistoryMessageVia *via = Get()) { + return via->_bot; + } + return nullptr; } History *history() const { @@ -1165,6 +1230,9 @@ public: bool isSilent() const { return _flags & MTPDmessage::Flag::f_silent; } + bool hasOutLayout() const { + return out() && !isPost(); + } virtual int32 viewsCount() const { return hasViews() ? 1 : -1; } @@ -1315,10 +1383,10 @@ public: virtual const HistoryMessage *toHistoryMessage() const { // dynamic_cast optimize return 0; } - virtual HistoryReply *toHistoryReply() { // dynamic_cast optimize - return 0; - } - virtual const HistoryReply *toHistoryReply() const { // dynamic_cast optimize + MsgId replyToId() const { + if (auto *reply = Get()) { + return reply->replyToId(); + } return 0; } @@ -1433,7 +1501,7 @@ protected: // this should be used only in previousItemChanged() // to add required bits to the Interfaces mask - // after that always use Is() + // after that always use Has() bool displayDate() const { if (HistoryItem *prev = previous()) { return prev->date.date().day() != date.date().day(); @@ -1750,7 +1818,7 @@ public: return _caption.original(); } bool needsBubble(const HistoryItem *parent) const override { - return !_caption.isEmpty() || parent->Is() || parent->toHistoryReply() || parent->viaBot(); + return !_caption.isEmpty() || parent->Has() || parent->Has() || parent->viaBot(); } bool customInfoLayout() const override { return _caption.isEmpty(); @@ -1819,7 +1887,7 @@ public: return _caption.original(); } bool needsBubble(const HistoryItem *parent) const override { - return !_caption.isEmpty() || parent->Is() || parent->toHistoryReply() || parent->viaBot(); + return !_caption.isEmpty() || parent->Has() || parent->Has() || parent->viaBot(); } bool customInfoLayout() const override { return _caption.isEmpty(); @@ -1850,25 +1918,25 @@ private: }; -struct HistoryDocumentThumbed : public BasicInterface { - HistoryDocumentThumbed(Interfaces *interfaces) : _thumbw(0), _linkw(0) { +struct HistoryDocumentThumbed : public BaseComponent { + HistoryDocumentThumbed(Composer*) { } TextLinkPtr _linksavel, _linkcancell; - int32 _thumbw; + int _thumbw = 0; - mutable int32 _linkw; + mutable int _linkw = 0; mutable QString _link; }; -struct HistoryDocumentCaptioned : public BasicInterface { - HistoryDocumentCaptioned(Interfaces *interfaces) : _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) { +struct HistoryDocumentCaptioned : public BaseComponent { + HistoryDocumentCaptioned(Composer*) : _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) { } Text _caption; }; -struct HistoryDocumentNamed : public BasicInterface { - HistoryDocumentNamed(Interfaces *interfaces) : _namew(0) { +struct HistoryDocumentNamed : public BaseComponent { + HistoryDocumentNamed(Composer*) { } QString _name; - int32 _namew; + int _namew = 0; }; class HistoryDocument; struct HistoryDocumentVoicePlayback { @@ -1878,18 +1946,22 @@ struct HistoryDocumentVoicePlayback { anim::fvalue a_progress; Animation _a_progress; }; -struct HistoryDocumentVoice : public BasicInterface { - HistoryDocumentVoice(Interfaces *that) : _playback(0) { +struct HistoryDocumentVoice : public BaseComponent { + HistoryDocumentVoice(Composer*) { + } + HistoryDocumentVoice &operator=(HistoryDocumentVoice &&other) { + std::swap(_playback, other._playback); + return *this; } ~HistoryDocumentVoice() { deleteAndMark(_playback); } void ensurePlayback(const HistoryDocument *interfaces) const; void checkPlaybackFinished() const; - mutable HistoryDocumentVoicePlayback *_playback; + mutable HistoryDocumentVoicePlayback *_playback = nullptr; }; -class HistoryDocument : public HistoryFileMedia, public Interfaces { +class HistoryDocument : public HistoryFileMedia, public Composer { public: HistoryDocument(DocumentData *document, const QString &caption, const HistoryItem *parent); @@ -2021,7 +2093,7 @@ public: return _caption.original(); } bool needsBubble(const HistoryItem *parent) const override { - return !_caption.isEmpty() || parent->Is() || parent->toHistoryReply() || parent->viaBot(); + return !_caption.isEmpty() || parent->Has() || parent->Has() || parent->viaBot(); } bool customInfoLayout() const override { return _caption.isEmpty(); @@ -2327,7 +2399,7 @@ public: } bool needsBubble(const HistoryItem *parent) const { - return !_title.isEmpty() || !_description.isEmpty() || parent->Is() || parent->toHistoryReply() || parent->viaBot(); + return !_title.isEmpty() || !_description.isEmpty() || parent->Has() || parent->Has() || parent->viaBot(); } bool customInfoLayout() const { return true; @@ -2365,14 +2437,14 @@ public: static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd) { return _create(history, msgId, flags, date, from, fwd); } - static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities) { - return _create(history, msgId, flags, viaBotId, date, from, msg, entities); + static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities) { + return _create(history, msgId, flags, replyTo, viaBotId, date, from, msg, entities); } - static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { - return _create(history, msgId, flags, viaBotId, date, from, doc, caption); + static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { + return _create(history, msgId, flags, replyTo, viaBotId, date, from, doc, caption); } - static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) { - return _create(history, msgId, flags, viaBotId, date, from, photo, caption); + static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) { + return _create(history, msgId, flags, replyTo, viaBotId, date, from, photo, caption); } void initTime(); @@ -2380,13 +2452,6 @@ public: void initMediaFromDocument(DocumentData *doc, const QString &caption); void fromNameUpdated(int32 width) const; - virtual UserData *viaBot() const override { - if (const HistoryMessageVia *via = Get()) { - return via->_bot; - } - return 0; - } - int32 plainMaxWidth() const; void countPositionAndSize(int32 &left, int32 &width) const; @@ -2403,7 +2468,7 @@ public: if (!hasFromName()) return false; if (isAttachedToPrevious()) return false; - return (!emptyText() || !_media || !_media->isDisplayed() || toHistoryReply() || Is() || viaBot() || !_media->hideFromName()); + return (!emptyText() || !_media || !_media->isDisplayed() || Has() || Has() || viaBot() || !_media->hideFromName()); } bool uploading() const { return _media && _media->uploading(); @@ -2414,7 +2479,7 @@ public: void setId(MsgId newId) override; void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override; - virtual void drawMessageText(Painter &p, QRect trect, uint32 selection) const; + void dependencyItemRemoved(HistoryItem *dependency) override; void destroy() override; @@ -2422,7 +2487,6 @@ public: bool pointInTime(int32 right, int32 bottom, int32 x, int32 y, InfoDisplayType type) const override; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override; - virtual void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const; void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const override; uint32 adjustSelection(uint16 from, uint16 to, TextSelectType type) const override { @@ -2491,6 +2555,16 @@ public: return HistoryItem::viewsCount(); } + bool updateDependencyItem() override { + if (auto *reply = Get()) { + return reply->updateData(this, true); + } + return true; + } + MsgId dependencyMsgId() const override { + return replyToId(); + } + HistoryMessage *toHistoryMessage() override { // dynamic_cast optimize return this; } @@ -2509,23 +2583,26 @@ protected: HistoryMessage(History *history, const MTPDmessage &msg); HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd); // local forwarded - HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities); // local message - HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption); // local document - HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo + HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities); // local message + HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption); // local document + HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo friend class HistoryItemInstantiated; void initDimensions() override; int resizeGetHeight_(int width) override; - void createInterfaces(int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal = 0, const PeerId &fromIdOriginal = 0, MsgId originalId = 0); - bool displayForwardedFrom() const { if (const HistoryMessageForwarded *fwd = Get()) { - return Is() || !_media || !_media->isDisplayed() || fwd->_authorOriginal->isChannel() || !_media->hideForwardedFrom(); + return Has() || !_media || !_media->isDisplayed() || fwd->_authorOriginal->isChannel() || !_media->hideForwardedFrom(); } return false; } - void paintForwardedInfo(Painter &p, int32 x, int32 y, int32 w, bool selected) const; + + void paintForwardedInfo(Painter &p, QRect &trect, bool selected) const; + void paintReplyInfo(Painter &p, QRect &trect, bool selected) const; + + // this method draws "via @bot" if it is not painted in forwarded info or in from name + void paintViaBotIdInfo(Painter &p, QRect &trect, bool selected) const; Text _text = { int(st::msgMinWidth) }; @@ -2536,79 +2613,8 @@ protected: QString _timeText; int _timeWidth = 0; -}; - -class HistoryReply : public HistoryMessage, private HistoryItemInstantiated { -public: - - static HistoryReply *create(History *history, const MTPDmessage &msg) { - return _create(history, msg); - } - static HistoryReply *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { - return _create(history, msgId, flags, viaBotId, replyTo, date, from, doc, caption); - } - static HistoryReply *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) { - return _create(history, msgId, flags, viaBotId, replyTo, date, from, photo, caption); - } - - bool updateDependencyItem() override { - return updateReplyTo(true); - } - MsgId dependencyMsgId() const override { - return replyToId(); - } - int32 replyToWidth() const; - - TextLinkPtr replyToLink() const; - - MsgId replyToId() const; - HistoryItem *replyToMessage() const; - void dependencyItemRemoved(HistoryItem *dependency) override; - - void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override; - void drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const; - void drawMessageText(Painter &p, QRect trect, uint32 selection) const override; - void resizeVia(int32 w) const; - void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override; - void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const override; - void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const override; - - PeerData *replyTo() const { - return replyToMsg ? replyToMsg->author() : 0; - } - QString selectedText(uint32 selection) const override; - - HistoryReply *toHistoryReply() override { // dynamic_cast optimize - return this; - } - const HistoryReply *toHistoryReply() const override { // dynamic_cast optimize - return this; - } - - ~HistoryReply(); - -protected: - - HistoryReply(History *history, const MTPDmessage &msg); - HistoryReply(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption); - HistoryReply(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption); - using HistoryItemInstantiated::_create; - friend class HistoryItemInstantiated; - - void initDimensions() override; - int resizeGetHeight_(int width) override; - - bool updateReplyTo(bool force = false); - void replyToNameUpdated() const; - - MsgId replyToMsgId; - HistoryItem *replyToMsg; - TextLinkPtr replyToLnk; - mutable Text replyToName, replyToText; - mutable int32 replyToVersion; - mutable int32 _maxReplyWidth; - HistoryMessageVia *_replyToVia; - int32 toWidth; + void createInterfacesHelper(MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId); + void createInterfaces(MsgId replyTo, int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal = 0, const PeerId &fromIdOriginal = 0, MsgId originalId = 0); }; @@ -2627,7 +2633,7 @@ inline MTPDmessage::Flags newForwardedFlags(PeerData *p, int32 from, HistoryMess if (from) { result |= MTPDmessage::Flag::f_from_id; } - if (fwd->Is()) { + if (fwd->Has()) { result |= MTPDmessage::Flag::f_via_bot_id; } if (!p->isChannel()) { @@ -2642,21 +2648,22 @@ inline MTPDmessage::Flags newForwardedFlags(PeerData *p, int32 from, HistoryMess return result; } -struct HistoryServicePinned : public BasicInterface { - HistoryServicePinned(Interfaces *); +struct HistoryServicePinned : public BaseComponent { + HistoryServicePinned(Composer*) { + } - MsgId msgId; - HistoryItem *msg; + MsgId msgId = 0; + HistoryItem *msg = nullptr; TextLinkPtr lnk; }; -class HistoryServiceMessage : public HistoryItem, private HistoryItemInstantiated { +class HistoryService : public HistoryItem, private HistoryItemInstantiated { public: - static HistoryServiceMessage *create(History *history, const MTPDmessageService &msg) { + static HistoryService *create(History *history, const MTPDmessageService &msg) { return _create(history, msg); } - static HistoryServiceMessage *create(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, int32 from = 0) { + static HistoryService *create(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, int32 from = 0) { return _create(history, msgId, date, msg, flags, media, from); } @@ -2710,13 +2717,13 @@ public: void setServiceText(const QString &text); - ~HistoryServiceMessage(); + ~HistoryService(); protected: - HistoryServiceMessage(History *history, const MTPDmessageService &msg); - HistoryServiceMessage(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, int32 from = 0); - friend class HistoryItemInstantiated; + HistoryService(History *history, const MTPDmessageService &msg); + HistoryService(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, int32 from = 0); + friend class HistoryItemInstantiated; void initDimensions() override; int resizeGetHeight_(int width) override; @@ -2731,7 +2738,7 @@ protected: int32 _textWidth, _textHeight; }; -class HistoryGroup : public HistoryServiceMessage, private HistoryItemInstantiated { +class HistoryGroup : public HistoryService, private HistoryItemInstantiated { public: static HistoryGroup *create(History *history, const MTPDmessageGroup &group, const QDateTime &date) { @@ -2787,7 +2794,7 @@ private: }; -class HistoryCollapse : public HistoryServiceMessage, private HistoryItemInstantiated { +class HistoryCollapse : public HistoryService, private HistoryItemInstantiated { public: static HistoryCollapse *create(History *history, MsgId wasMinId, const QDateTime &date) { @@ -2822,7 +2829,7 @@ private: }; -class HistoryJoined : public HistoryServiceMessage, private HistoryItemInstantiated { +class HistoryJoined : public HistoryService, private HistoryItemInstantiated { public: static HistoryJoined *create(History *history, const QDateTime &date, UserData *from, MTPDmessage::Flags flags) { diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index ab66e4639..902fe59c5 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -948,7 +948,8 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { PhotoLink *lnkPhoto = dynamic_cast(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast(_contextMenuLnk.data()); bool lnkIsVideo = lnkDocument ? lnkDocument->document()->isVideo() : false; - bool lnkIsAudio = lnkDocument ? (lnkDocument->document()->voice() != 0) : false; + bool lnkIsAudio = lnkDocument ? (lnkDocument->document()->voice() != nullptr) : false; + bool lnkIsSong = lnkDocument ? (lnkDocument->document()->song() != nullptr) : false; if (lnkPhoto || lnkDocument) { if (isUponSelected > 0) { _menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true); @@ -978,7 +979,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { if (lnkDocument && !lnkDocument->document()->filepath(DocumentData::FilePathResolveChecked).isEmpty()) { _menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true); } - _menu->addAction(lang(lnkIsVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true); + _menu->addAction(lang(lnkIsVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : (lnkIsSong ? lng_context_save_audio_file : lng_context_save_file))), this, SLOT(saveContextFile()))->setEnabled(true); } } if (item && item->hasDirectLink() && isUponSelected != 2 && isUponSelected != -2) { @@ -5996,7 +5997,7 @@ void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, bool silent, const M uint64 randomId = rand_value(); App::historyRegRandom(randomId, newId); History *hist = item->history(); - MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0; + MsgId replyTo = item->replyToId(); MTPmessages_SendMedia::Flags sendFlags = 0; if (replyTo) { sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; @@ -6048,7 +6049,7 @@ void HistoryWidget::onDocumentUploaded(const FullMsgId &newId, bool silent, cons uint64 randomId = rand_value(); App::historyRegRandom(randomId, newId); History *hist = item->history(); - MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0; + MsgId replyTo = item->replyToId(); MTPmessages_SendMedia::Flags sendFlags = 0; if (replyTo) { sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; @@ -6077,7 +6078,7 @@ void HistoryWidget::onThumbDocumentUploaded(const FullMsgId &newId, bool silent, uint64 randomId = rand_value(); App::historyRegRandom(randomId, newId); History *hist = item->history(); - MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0; + MsgId replyTo = item->replyToId(); MTPmessages_SendMedia::Flags sendFlags = 0; if (replyTo) { sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; @@ -6986,7 +6987,7 @@ bool HistoryWidget::pinnedMsgVisibilityUpdated() { } else if (_pinnedBar->msgId != pinnedMsgId) { _pinnedBar->msgId = pinnedMsgId; _pinnedBar->msg = 0; - _pinnedBar->text.clean(); + _pinnedBar->text.clear(); updatePinnedBar(); update(); } diff --git a/Telegram/SourceFiles/layout.cpp b/Telegram/SourceFiles/layout.cpp index 87998c2fc..794d81de5 100644 --- a/Telegram/SourceFiles/layout.cpp +++ b/Telegram/SourceFiles/layout.cpp @@ -293,9 +293,10 @@ void LayoutAbstractFileItem::setStatusSize(int32 newSize, int32 fullSize, int32 } } -LayoutOverviewDate::LayoutOverviewDate(const QDate &date, bool month) : LayoutItem(OverviewItemInfo::Bit()) +LayoutOverviewDate::LayoutOverviewDate(const QDate &date, bool month) : LayoutItem() , _date(date) , _text(month ? langMonthFull(date) : langDayOfMonthFull(date)) { + AddComponents(OverviewItemInfo::Bit()); } void LayoutOverviewDate::initDimensions() { @@ -311,7 +312,7 @@ void LayoutOverviewDate::paint(Painter &p, const QRect &clip, uint32 selection, } } -LayoutOverviewPhoto::LayoutOverviewPhoto(PhotoData *photo, HistoryItem *parent) : LayoutMediaItem(0, parent) +LayoutOverviewPhoto::LayoutOverviewPhoto(PhotoData *photo, HistoryItem *parent) : LayoutMediaItem(parent) , _data(photo) , _link(new PhotoLink(photo)) , _goodLoaded(false) { @@ -385,7 +386,7 @@ void LayoutOverviewPhoto::getState(TextLinkPtr &link, HistoryCursorState &cursor } } -LayoutOverviewVideo::LayoutOverviewVideo(DocumentData *video, HistoryItem *parent) : LayoutAbstractFileItem(0, parent) +LayoutOverviewVideo::LayoutOverviewVideo(DocumentData *video, HistoryItem *parent) : LayoutAbstractFileItem(parent) , _data(video) , _duration(formatDurationText(_data->duration())) , _thumbLoaded(false) { @@ -549,9 +550,11 @@ void LayoutOverviewVideo::updateStatusText() const { } } -LayoutOverviewVoice::LayoutOverviewVoice(DocumentData *voice, HistoryItem *parent) : LayoutAbstractFileItem(OverviewItemInfo::Bit(), parent) +LayoutOverviewVoice::LayoutOverviewVoice(DocumentData *voice, HistoryItem *parent) : LayoutAbstractFileItem(parent) , _data(voice) , _namel(new DocumentOpenLink(_data)) { + AddComponents(OverviewItemInfo::Bit()); + t_assert(_data->voice() != 0); setLinks(new DocumentOpenLink(_data), new DocumentOpenLink(_data), new DocumentCancelLink(_data)); @@ -741,7 +744,7 @@ bool LayoutOverviewVoice::updateStatusText() const { return showPause; } -LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent) : LayoutAbstractFileItem(OverviewItemInfo::Bit(), parent) +LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent) : LayoutAbstractFileItem(parent) , _data(document) , _msgl(new MessageLink(parent)) , _namel(new DocumentOpenLink(_data)) @@ -751,6 +754,8 @@ LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryIt , _namew(st::semiboldFont->width(_name)) , _datew(st::normalFont->width(_date)) , _colorIndex(documentColorIndex(_data, _ext)) { + AddComponents(OverviewItemInfo::Bit()); + setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data)); setStatusSize(FileStatusSizeReady, _data->size, _data->song() ? _data->song()->duration : -1, 0); @@ -1066,7 +1071,9 @@ namespace { } } -LayoutOverviewLink::LayoutOverviewLink(HistoryMedia *media, HistoryItem *parent) : LayoutMediaItem(OverviewItemInfo::Bit(), parent) { +LayoutOverviewLink::LayoutOverviewLink(HistoryMedia *media, HistoryItem *parent) : LayoutMediaItem(parent) { + AddComponents(OverviewItemInfo::Bit()); + QString text = _parent->originalText(); EntitiesInText entities = _parent->originalEntities(); @@ -1319,7 +1326,7 @@ LayoutOverviewLink::Link::Link(const QString &url, const QString &text) , lnk(linkFromUrl(url)) { } -LayoutInlineItem::LayoutInlineItem(InlineResult *result, DocumentData *doc, PhotoData *photo) : LayoutItem(0) +LayoutInlineItem::LayoutInlineItem(InlineResult *result, DocumentData *doc, PhotoData *photo) : LayoutItem() , _result(result) , _doc(doc) , _photo(photo) diff --git a/Telegram/SourceFiles/layout.h b/Telegram/SourceFiles/layout.h index d52d1e3eb..a91d83bb2 100644 --- a/Telegram/SourceFiles/layout.h +++ b/Telegram/SourceFiles/layout.h @@ -101,10 +101,11 @@ public: }; class LayoutMediaItem; -class LayoutItem : public Interfaces { +class LayoutItem : public Composer { public: - LayoutItem(uint64 i_mask) : Interfaces(i_mask), _maxw(0), _minh(0) { + LayoutItem() { } + LayoutItem &operator=(const LayoutItem &) = delete; int32 maxWidth() const { return _maxw; @@ -167,14 +168,16 @@ public: } protected: - int32 _width, _height, _maxw, _minh; - LayoutItem &operator=(const LayoutItem &); + int _width = 0; + int _height = 0; + int _maxw = 0; + int _minh = 0; }; class LayoutMediaItem : public LayoutItem { public: - LayoutMediaItem(uint64 i_mask, HistoryItem *parent) : LayoutItem(i_mask), _parent(parent) { + LayoutMediaItem(HistoryItem *parent) : _parent(parent) { } virtual LayoutMediaItem *toLayoutMediaItem() { @@ -194,7 +197,7 @@ protected: class LayoutRadialProgressItem : public LayoutMediaItem { public: - LayoutRadialProgressItem(uint64 i_mask, HistoryItem *parent) : LayoutMediaItem(i_mask, parent) + LayoutRadialProgressItem(HistoryItem *parent) : LayoutMediaItem(parent) , _radial(0) , a_iconOver(0, 0) , _a_iconOver(animation(this, &LayoutRadialProgressItem::step_iconOver)) { @@ -240,7 +243,7 @@ private: class LayoutAbstractFileItem : public LayoutRadialProgressItem { public: - LayoutAbstractFileItem(uint64 i_mask, HistoryItem *parent) : LayoutRadialProgressItem(i_mask, parent) { + LayoutAbstractFileItem(HistoryItem *parent) : LayoutRadialProgressItem(parent) { } protected: @@ -268,19 +271,19 @@ public: }; -class OverviewItemInfo : public BasicInterface { +class OverviewItemInfo : public BaseComponent { public: - OverviewItemInfo(Interfaces *) : _top(0) { + OverviewItemInfo(Composer*) { } - int32 top() const { + int top() const { return _top; } - void setTop(int32 top) { + void setTop(int top) { _top = top; } private: - int32 _top; + int _top = 0; }; diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 16fed59d5..035b1b5a3 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -3550,7 +3550,7 @@ namespace Local { return result; } - void _writePeer(QDataStream &stream, PeerData *peer, int32 fileVersion = AppVersion) { + void _writePeer(QDataStream &stream, PeerData *peer) { stream << quint64(peer->id) << quint64(peer->photoId); _writeStorageImageLocation(stream, peer->photoLoc); if (peer->isUser()) { @@ -3560,7 +3560,7 @@ namespace Local { if (AppVersion >= 9012) { stream << qint32(user->flags); } - if (AppVersion >= 9016 || fileVersion >= 9016) { + if (AppVersion >= 9016) { stream << (user->botInfo ? user->botInfo->inlinePlaceholder : QString()); } stream << qint32(user->onlineTill) << qint32(user->contact) << qint32(user->botInfo ? user->botInfo->version : -1); @@ -3580,18 +3580,16 @@ namespace Local { } PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) { - PeerData *result = 0; quint64 peerId = 0, photoId = 0; from.stream >> peerId >> photoId; StorageImageLocation photoLoc(_readStorageImageLocation(from)); - result = App::peerLoaded(peerId); - bool wasLoaded = (result && result->loaded); - + PeerData *result = App::peerLoaded(peerId); + bool wasLoaded = (result != nullptr); if (!wasLoaded) { result = App::peer(peerId); - result->loaded = true; + result->loadedStatus = PeerData::FullLoaded; } if (result->isUser()) { UserData *user = result->asUser(); @@ -3737,7 +3735,7 @@ namespace Local { } data.stream << quint32(botsCnt); for (RecentInlineBots::const_iterator i = bots.cbegin(), e = bots.cend(); i != e; ++i) { - _writePeer(data.stream, *i, 9016); + _writePeer(data.stream, *i); } FileWriteDescriptor file(_recentHashtagsAndBotsKey); file.writeEncrypted(data); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 1833b4296..2f2805d1e 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -4099,17 +4099,17 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) { case mtpc_updateShortMessage: { const MTPDupdateShortMessage &d(updates.c_updateShortMessage()); - if (!App::userLoaded(d.vuser_id.v) || (d.has_via_bot_id() && !App::peerLoaded(peerFromUser(d.vvia_bot_id)))) { + if (!App::userLoaded(d.vuser_id.v) || (d.has_via_bot_id() && !App::userLoaded(d.vvia_bot_id.v))) { MTP_LOG(0, ("getDifference { good - getting user for updateShortMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); return getDifference(); } if (d.has_fwd_from() && d.vfwd_from.type() == mtpc_messageFwdHeader) { const MTPDmessageFwdHeader &f(d.vfwd_from.c_messageFwdHeader()); - if (f.has_from_id() && !App::peerLoaded(peerFromUser(f.vfrom_id))) { + if (f.has_from_id() && !App::userLoaded(f.vfrom_id.v)) { MTP_LOG(0, ("getDifference { good - getting user for updateShortMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); return getDifference(); } - if (f.has_channel_id() && !App::peerLoaded(peerFromChannel(f.vchannel_id))) { + if (f.has_channel_id() && !App::channelLoaded(f.vchannel_id.v)) { MTP_LOG(0, ("getDifference { good - getting user for updateShortMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); return getDifference(); } @@ -4133,18 +4133,18 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) { case mtpc_updateShortChatMessage: { const MTPDupdateShortChatMessage &d(updates.c_updateShortChatMessage()); bool noFrom = !App::userLoaded(d.vfrom_id.v); - if (!App::chatLoaded(d.vchat_id.v) || noFrom || (d.has_via_bot_id() && !App::peerLoaded(peerFromUser(d.vvia_bot_id)))) { + if (!App::chatLoaded(d.vchat_id.v) || noFrom || (d.has_via_bot_id() && !App::userLoaded(d.vvia_bot_id.v))) { MTP_LOG(0, ("getDifference { good - getting user for updateShortChatMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); if (noFrom && App::api()) App::api()->requestFullPeer(App::chatLoaded(d.vchat_id.v)); return getDifference(); } if (d.has_fwd_from() && d.vfwd_from.type() == mtpc_messageFwdHeader) { const MTPDmessageFwdHeader &f(d.vfwd_from.c_messageFwdHeader()); - if (f.has_from_id() && !App::peerLoaded(peerFromUser(f.vfrom_id))) { + if (f.has_from_id() && !App::userLoaded(f.vfrom_id.v)) { MTP_LOG(0, ("getDifference { good - getting user for updateShortChatMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); return getDifference(); } - if (f.has_channel_id() && !App::peerLoaded(peerFromChannel(f.vchannel_id))) { + if (f.has_channel_id() && !App::channelLoaded(f.vchannel_id.v)) { MTP_LOG(0, ("getDifference { good - getting user for updateShortChatMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); return getDifference(); } @@ -4357,9 +4357,9 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { case mtpc_updateChatUserTyping: { const MTPDupdateChatUserTyping &d(update.c_updateChatUserTyping()); History *history = 0; - if (PeerData *chat = App::peerLoaded(peerFromChat(d.vchat_id.v))) { + if (PeerData *chat = App::chatLoaded(d.vchat_id.v)) { history = App::historyLoaded(chat->id); - } else if (PeerData *channel = App::peerLoaded(peerFromChannel(d.vchat_id.v))) { + } else if (PeerData *channel = App::channelLoaded(d.vchat_id.v)) { history = App::historyLoaded(channel->id); } UserData *user = (d.vuser_id.v == MTP::authedId()) ? 0 : App::userLoaded(d.vuser_id.v); diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index c75c84698..f0c06c53d 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -1267,8 +1267,9 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { _contextMenuLnk = textlnkOver(); PhotoLink *lnkPhoto = dynamic_cast(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast(_contextMenuLnk.data()); - bool lnkIsAudio = lnkDocument ? (lnkDocument->document()->voice() != 0) : false; bool lnkIsVideo = lnkDocument ? lnkDocument->document()->isVideo() : false; + bool lnkIsAudio = lnkDocument ? (lnkDocument->document()->voice() != nullptr) : false; + bool lnkIsSong = lnkDocument ? (lnkDocument->document()->song() != nullptr) : false; if (lnkPhoto || lnkDocument) { _menu = new PopupMenu(); if (App::hoveredLinkItem()) { @@ -1282,7 +1283,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { if (lnkDocument && !lnkDocument->document()->filepath(DocumentData::FilePathResolveChecked).isEmpty()) { _menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true); } - _menu->addAction(lang(lnkIsVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true); + _menu->addAction(lang(lnkIsVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : (lnkIsSong ? lng_context_save_audio_file : lng_context_save_file))), this, SLOT(saveContextFile()))->setEnabled(true); } } if (isUponSelected > 1) { diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 0426f8620..85932fb31 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -35,8 +35,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "localstorage.h" namespace { - int32 peerColorIndex(const PeerId &peer) { - int32 myId(MTP::authedId()), peerId(peerToBareInt(peer)); + int peerColorIndex(const PeerId &peer) { + UserId myId(MTP::authedId()), peerId(peerToBareInt(peer)); QByteArray both(qsl("%1%2").arg(peerId).arg(myId).toUtf8()); if (both.size() > 15) { both = both.mid(0, 15); @@ -47,7 +47,7 @@ namespace { } } -style::color peerColor(int32 index) { +style::color peerColor(int index) { static const style::color peerColors[8] = { style::color(st::color1), style::color(st::color2), @@ -61,7 +61,7 @@ style::color peerColor(int32 index) { return peerColors[index]; } -ImagePtr userDefPhoto(int32 index) { +ImagePtr userDefPhoto(int index) { static const ImagePtr userDefPhotos[UserColorsCount] = { ImagePtr(qsl(":/ava/art/usercolor1.png"), "PNG"), ImagePtr(qsl(":/ava/art/usercolor2.png"), "PNG"), @@ -75,7 +75,7 @@ ImagePtr userDefPhoto(int32 index) { return userDefPhotos[index]; } -ImagePtr chatDefPhoto(int32 index) { +ImagePtr chatDefPhoto(int index) { static const ImagePtr chatDefPhotos[4] = { ImagePtr(qsl(":/ava/art/chatcolor1.png"), "PNG"), ImagePtr(qsl(":/ava/art/chatcolor2.png"), "PNG"), @@ -85,7 +85,7 @@ ImagePtr chatDefPhoto(int32 index) { return chatDefPhotos[index]; } -ImagePtr channelDefPhoto(int32 index) { +ImagePtr channelDefPhoto(int index) { static const ImagePtr channelDefPhotos[4] = { ImagePtr(qsl(":/ava/art/channelcolor1.png"), "PNG"), ImagePtr(qsl(":/ava/art/channelcolor2.png"), "PNG"), @@ -100,7 +100,7 @@ NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersP PeerData::PeerData(const PeerId &id) : id(id) , lnk(new PeerLink(this)) -, loaded(false) +, loadedStatus(NotLoaded) , colorIndex(peerColorIndex(id)) , color(peerColor(colorIndex)) , photoId(UnknownPeerPhotoId) @@ -279,7 +279,7 @@ void UserData::setPhone(const QString &newPhone) { phone = newPhone; } -void UserData::setBotInfoVersion(int32 version) { +void UserData::setBotInfoVersion(int version) { if (version < 0) { if (botInfo) { if (!botInfo->commands.isEmpty()) { @@ -850,7 +850,7 @@ QString documentSaveFilename(const DocumentData *data, bool forceSavingAs = fals } else { filter = mimeType.filterString() + qsl(";;All files (*.*)"); } - caption = lang(lng_save_file); + caption = lang(data->song() ? lng_save_audio_file : lng_save_file); prefix = qsl("doc"); } diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 4896a0cea..6546a8c03 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -20,9 +20,21 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +typedef int32 UserId; +typedef int32 ChatId; typedef int32 ChannelId; static const ChannelId NoChannel = 0; +typedef int32 MsgId; +struct FullMsgId { + FullMsgId() : channel(NoChannel), msg(0) { + } + FullMsgId(ChannelId channel, MsgId msg) : channel(channel), msg(msg) { + } + ChannelId channel; + MsgId msg; +}; + typedef uint64 PeerId; static const uint64 PeerIdMask = 0xFFFFFFFFULL; static const uint64 PeerIdTypeMask = 0x300000000ULL; @@ -38,10 +50,10 @@ inline bool peerIsChat(const PeerId &id) { inline bool peerIsChannel(const PeerId &id) { return (id & PeerIdTypeMask) == PeerIdChannelShift; } -inline PeerId peerFromUser(int32 user_id) { +inline PeerId peerFromUser(UserId user_id) { return PeerIdUserShift | uint64(uint32(user_id)); } -inline PeerId peerFromChat(int32 chat_id) { +inline PeerId peerFromChat(ChatId chat_id) { return PeerIdChatShift | uint64(uint32(chat_id)); } inline PeerId peerFromChannel(ChannelId channel_id) { @@ -59,10 +71,10 @@ inline PeerId peerFromChannel(const MTPint &channel_id) { inline int32 peerToBareInt(const PeerId &id) { return int32(uint32(id & PeerIdMask)); } -inline int32 peerToUser(const PeerId &id) { +inline UserId peerToUser(const PeerId &id) { return peerIsUser(id) ? peerToBareInt(id) : 0; } -inline int32 peerToChat(const PeerId &id) { +inline ChatId peerToChat(const PeerId &id) { return peerIsChat(id) ? peerToBareInt(id) : 0; } inline ChannelId peerToChannel(const PeerId &id) { @@ -112,7 +124,7 @@ inline MTPDmessage::Flags flagsFromMessage(const MTPmessage &msg) { } return 0; } -inline int32 idFromMessage(const MTPmessage &msg) { +inline MsgId idFromMessage(const MTPmessage &msg) { switch (msg.type()) { case mtpc_messageEmpty: return msg.c_messageEmpty().vid.v; case mtpc_message: return msg.c_message().vid.v; @@ -120,7 +132,7 @@ inline int32 idFromMessage(const MTPmessage &msg) { } return 0; } -inline int32 dateFromMessage(const MTPmessage &msg) { +inline TimeId dateFromMessage(const MTPmessage &msg) { switch (msg.type()) { case mtpc_message: return msg.c_message().vdate.v; case mtpc_messageService: return msg.c_messageService().vdate.v; @@ -135,15 +147,6 @@ typedef uint64 DocumentId; typedef uint64 WebPageId; static const WebPageId CancelledWebPageId = 0xFFFFFFFFFFFFFFFFULL; -typedef int32 MsgId; -struct FullMsgId { - FullMsgId() : channel(NoChannel), msg(0) { - } - FullMsgId(ChannelId channel, MsgId msg) : channel(channel), msg(msg) { - } - ChannelId channel; - MsgId msg; -}; inline bool operator==(const FullMsgId &a, const FullMsgId &b) { return (a.channel == b.channel) && (a.msg == b.msg); } @@ -168,7 +171,7 @@ struct NotifySettings { NotifySettings() : flags(MTPDpeerNotifySettings::Flag::f_show_previews), mute(0), sound("default") { } MTPDpeerNotifySettings::Flags flags; - int32 mute; + TimeId mute; string sound; bool previews() const { return flags & MTPDpeerNotifySettings::Flag::f_show_previews; @@ -184,9 +187,9 @@ static const NotifySettingsPtr EmptyNotifySettings = NotifySettingsPtr(1); extern NotifySettings globalNotifyAll, globalNotifyUsers, globalNotifyChats; extern NotifySettingsPtr globalNotifyAllPtr, globalNotifyUsersPtr, globalNotifyChatsPtr; -inline bool isNotifyMuted(NotifySettingsPtr settings, int32 *changeIn = 0) { +inline bool isNotifyMuted(NotifySettingsPtr settings, TimeId *changeIn = 0) { if (settings != UnknownNotifySettings && settings != EmptyNotifySettings) { - int32 t = unixtime(); + TimeId t = unixtime(); if (settings->mute > t) { if (changeIn) *changeIn = settings->mute - t + 1; return true; @@ -196,12 +199,12 @@ inline bool isNotifyMuted(NotifySettingsPtr settings, int32 *changeIn = 0) { return false; } -static const int32 UserColorsCount = 8; +static const int UserColorsCount = 8; -style::color peerColor(int32 index); -ImagePtr userDefPhoto(int32 index); -ImagePtr chatDefPhoto(int32 index); -ImagePtr channelDefPhoto(int32 index); +style::color peerColor(int index); +ImagePtr userDefPhoto(int index); +ImagePtr chatDefPhoto(int index); +ImagePtr channelDefPhoto(int index); static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL; @@ -276,10 +279,15 @@ public: typedef QSet NameFirstChars; NameFirstChars chars; - bool loaded; + enum LoadedStatus { + NotLoaded = 0x00, + MinimalLoaded = 0x01, + FullLoaded = 0x02, + }; + LoadedStatus loadedStatus; MTPinputPeer input; - int32 colorIndex; + int colorIndex; style::color color; void setUserpic(ImagePtr userpic); @@ -297,7 +305,7 @@ public: PhotoId photoId; StorageImageLocation photoLoc; - int32 nameVersion; + int nameVersion; NotifySettingsPtr notify; @@ -358,7 +366,7 @@ struct BotInfo { } bool inited; bool readsAllHistory, cantJoinGroups; - int32 version; + int version; QString description, inlinePlaceholder; QList commands; Text text; // description @@ -382,7 +390,7 @@ public: void setPhoto(const MTPUserProfilePhoto &photo); void setName(const QString &first, const QString &last, const QString &phoneName, const QString &username); void setPhone(const QString &newPhone); - void setBotInfoVersion(int32 version); + void setBotInfoVersion(int version); void setBotInfo(const MTPBotInfo &info); void setNameOrPhone(const QString &newNameOrPhone); @@ -407,13 +415,13 @@ public: QString phone; QString nameOrPhone; Text phoneText; - int32 onlineTill = 0; + TimeId onlineTill = 0; int32 contact = -1; // -1 - not contact, cant add (self, empty, deleted, foreign), 0 - not contact, can add (request), 1 - contact UserBlockedStatus blocked = UserBlockUnknown; typedef QList Photos; Photos photos; - int32 photosCount = -1; // -1 not loaded, 0 all loaded + int photosCount = -1; // -1 not loaded, 0 all loaded QString about; @@ -462,10 +470,10 @@ public: ChannelData *migrateToPtr; - int32 count; - int32 date; - int32 version; - int32 creator; + int count; + TimeId date; + int version; + UserId creator; MTPDchat::Flags flags; bool isForbidden; @@ -499,7 +507,7 @@ public: bool isMigrated() const { return flags & MTPDchat::Flag::f_migrated_to; } - typedef QMap Participants; + typedef QMap Participants; Participants participants; typedef OrderedSet InvitedByMe; InvitedByMe invitedByMe; @@ -753,29 +761,59 @@ private: }; +inline bool isUser(const PeerData *peer) { + return peer ? peer->isUser() : false; +} inline UserData *PeerData::asUser() { - return isUser() ? static_cast(this) : 0; + return isUser() ? static_cast(this) : nullptr; +} +inline UserData *asUser(PeerData *peer) { + return peer ? peer->asUser() : nullptr; } inline const UserData *PeerData::asUser() const { - return isUser() ? static_cast(this) : 0; + return isUser() ? static_cast(this) : nullptr; +} +inline const UserData *asUser(const PeerData *peer) { + return peer ? peer->asUser() : nullptr; +} +inline bool isChat(const PeerData *peer) { + return peer ? peer->isChat() : false; } inline ChatData *PeerData::asChat() { - return isChat() ? static_cast(this) : 0; + return isChat() ? static_cast(this) : nullptr; +} +inline ChatData *asChat(PeerData *peer) { + return peer ? peer->asChat() : nullptr; } inline const ChatData *PeerData::asChat() const { - return isChat() ? static_cast(this) : 0; + return isChat() ? static_cast(this) : nullptr; +} +inline const ChatData *asChat(const PeerData *peer) { + return peer ? peer->asChat() : nullptr; +} +inline bool isChannel(const PeerData *peer) { + return peer ? peer->isChannel() : false; } inline ChannelData *PeerData::asChannel() { - return isChannel() ? static_cast(this) : 0; + return isChannel() ? static_cast(this) : nullptr; +} +inline ChannelData *asChannel(PeerData *peer) { + return peer ? peer->asChannel() : nullptr; } inline const ChannelData *PeerData::asChannel() const { - return isChannel() ? static_cast(this) : 0; + return isChannel() ? static_cast(this) : nullptr; +} +inline const ChannelData *asChannel(const PeerData *peer) { + return peer ? peer->asChannel() : nullptr; +} +inline bool isMegagroup(const PeerData *peer) { + return peer ? peer->isMegagroup() : false; } inline ChatData *PeerData::migrateFrom() const { - return (isMegagroup() && asChannel()->amIn()) ? asChannel()->mgInfo->migrateFromPtr : 0; + return (isMegagroup() && asChannel()->amIn()) ? asChannel()->mgInfo->migrateFromPtr : nullptr; } inline ChannelData *PeerData::migrateTo() const { - return (isChat() && asChat()->migrateToPtr && asChat()->migrateToPtr->amIn()) ? asChat()->migrateToPtr : 0; + return (isChat() && asChat()->migrateToPtr && asChat()->migrateToPtr->amIn()) ? asChat()->migrateToPtr : nullptr; } inline const Text &PeerData::dialogName() const { return migrateTo() ? migrateTo()->dialogName() : ((isUser() && !asUser()->phoneText.isEmpty()) ? asUser()->phoneText : nameText); @@ -998,11 +1036,14 @@ public: SongData *song() { return (type == SongDocument) ? static_cast(_additional) : 0; } + const SongData *song() const { + return (type == SongDocument) ? static_cast(_additional) : 0; + } VoiceData *voice() { return (type == VoiceDocument) ? static_cast(_additional) : 0; } const VoiceData *voice() const { - return (type == VoiceDocument) ? static_cast(_additional) : 0; + return (type == VoiceDocument) ? static_cast(_additional) : 0; } bool isAnimation() const { return (type == AnimatedDocument) || !mime.compare(qstr("image/gif"), Qt::CaseInsensitive); diff --git a/Telegram/SourceFiles/types.cpp b/Telegram/SourceFiles/types.cpp index 6f0b408d9..e4541be90 100644 --- a/Telegram/SourceFiles/types.cpp +++ b/Telegram/SourceFiles/types.cpp @@ -120,8 +120,8 @@ namespace { } } -int32 myunixtime() { - return (int32)time(NULL); +TimeId myunixtime() { + return (TimeId)time(NULL); } void unixtimeInit() { @@ -149,19 +149,19 @@ void unixtimeSet(int32 serverTime, bool force) { _initMsgIdConstants(); } -int32 unixtime() { - int32 result = myunixtime(); +TimeId unixtime() { + TimeId result = myunixtime(); QReadLocker locker(&unixtimeLock); return result + unixtimeDelta; } -int32 fromServerTime(const MTPint &serverTime) { +TimeId fromServerTime(const MTPint &serverTime) { QReadLocker locker(&unixtimeLock); return serverTime.v - unixtimeDelta; } -MTPint toServerTime(const int32 &clientTime) { +MTPint toServerTime(const TimeId &clientTime) { QReadLocker locker(&unixtimeLock); return MTP_int(clientTime + unixtimeDelta); } @@ -1034,35 +1034,32 @@ MimeType mimeTypeForData(const QByteArray &data) { return MimeType(QMimeDatabase().mimeTypeForData(data)); } -class InterfacesMetadatasMap : public QMap { -public: - ~InterfacesMetadatasMap() { - for (const_iterator i = cbegin(), e = cend(); i != e; ++i) { - delete i.value(); +struct ComposerMetadatasMap { + QMap data; + ~ComposerMetadatasMap() { + for_const (const ComposerMetadata *p, data) { + delete p; } } }; -const InterfacesMetadata *GetInterfacesMetadata(uint64 mask) { - typedef QMap InterfacesMetadatasMap; - static InterfacesMetadatasMap InterfacesMetadatas; - static QMutex InterfacesMetadatasMutex; +const ComposerMetadata *GetComposerMetadata(uint64 mask) { + static ComposerMetadatasMap ComposerMetadatas; + static QMutex ComposerMetadatasMutex; - QMutexLocker lock(&InterfacesMetadatasMutex); - InterfacesMetadatasMap::const_iterator i = InterfacesMetadatas.constFind(mask); - if (i == InterfacesMetadatas.cend()) { - InterfacesMetadata *meta = new InterfacesMetadata(mask); - if (!meta) { // terminate if we can't allocate memory - throw "Can't allocate memory!"; - } + QMutexLocker lock(&ComposerMetadatasMutex); + auto i = ComposerMetadatas.data.constFind(mask); + if (i == ComposerMetadatas.data.cend()) { + ComposerMetadata *meta = new ComposerMetadata(mask); + t_assert(meta != nullptr); - i = InterfacesMetadatas.insert(mask, meta); + i = ComposerMetadatas.data.insert(mask, meta); } return i.value(); } -const InterfacesMetadata *Interfaces::ZeroInterfacesMetadata = GetInterfacesMetadata(0); +const ComposerMetadata *Composer::ZeroComposerMetadata = GetComposerMetadata(0); -InterfaceWrapStruct InterfaceWraps[64]; +ComponentWrapStruct ComponentWraps[64]; -QAtomicInt InterfaceIndexLast(0); +QAtomicInt ComponentIndexLast; diff --git a/Telegram/SourceFiles/types.h b/Telegram/SourceFiles/types.h index fd6ea2438..4d3263332 100644 --- a/Telegram/SourceFiles/types.h +++ b/Telegram/SourceFiles/types.h @@ -104,6 +104,30 @@ using std::string; using std::exception; using std::swap; +// we copy some parts of C++11 std:: library, because on OS X 10.6+ +// version we can use C++11, but we can't use its library :( +namespace std11 { + +template +struct remove_reference { + typedef T type; +}; +template +struct remove_reference { + typedef T type; +}; +template +struct remove_reference { + typedef T type; +}; + +template +inline typename remove_reference::type &&move(T &&value) { + return static_cast::type&&>(value); +} + +} // namespace std11 + #include "logs.h" static volatile int *t_assert_nullptr = 0; @@ -140,12 +164,12 @@ private: }; class MTPint; - -int32 myunixtime(); +typedef int32 TimeId; +TimeId myunixtime(); void unixtimeInit(); -void unixtimeSet(int32 servertime, bool force = false); -int32 unixtime(); -int32 fromServerTime(const MTPint &serverTime); +void unixtimeSet(TimeId servertime, bool force = false); +TimeId unixtime(); +TimeId fromServerTime(const MTPint &serverTime); uint64 msgid(); int32 reqid(); @@ -541,24 +565,26 @@ inline void destroyImplementation(I *&ptr) { deleteAndMark(ptr); } -class Interfaces; -typedef void(*InterfaceConstruct)(void *location, Interfaces *interfaces); -typedef void(*InterfaceDestruct)(void *location); -typedef void(*InterfaceMove)(void *location, void *waslocation); +class Composer; +typedef void(*ComponentConstruct)(void *location, Composer *composer); +typedef void(*ComponentDestruct)(void *location); +typedef void(*ComponentMove)(void *location, void *waslocation); -struct InterfaceWrapStruct { - InterfaceWrapStruct() : Size(0), Construct(0), Destruct(0) { +struct ComponentWrapStruct { + // don't init any fields, because it is only created in + // global scope, so it will be filled by zeros from the start + ComponentWrapStruct() { } - InterfaceWrapStruct(int size, InterfaceConstruct construct, InterfaceDestruct destruct, InterfaceMove move) + ComponentWrapStruct(int size, ComponentConstruct construct, ComponentDestruct destruct, ComponentMove move) : Size(size) , Construct(construct) , Destruct(destruct) , Move(move) { } int Size; - InterfaceConstruct Construct; - InterfaceDestruct Destruct; - InterfaceMove Move; + ComponentConstruct Construct; + ComponentDestruct Destruct; + ComponentMove Move; }; template @@ -567,36 +593,43 @@ struct CeilDivideMinimumOne { }; template -struct InterfaceWrapTemplate { +struct ComponentWrapTemplate { static const int Size = CeilDivideMinimumOne::Result * sizeof(uint64); - static void Construct(void *location, Interfaces *interfaces) { - new (location) Type(interfaces); + 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 = *(Type*)waslocation; + *(Type*)location = std11::move(*(Type*)waslocation); } }; -extern InterfaceWrapStruct InterfaceWraps[64]; -extern QAtomicInt InterfaceIndexLast; +extern ComponentWrapStruct ComponentWraps[64]; +extern QAtomicInt ComponentIndexLast; template -class BasicInterface { +class BaseComponent { public: + BaseComponent() { + } + BaseComponent(const BaseComponent &other) = delete; + BaseComponent &operator=(const BaseComponent &other) = delete; + BaseComponent(BaseComponent &&other) = delete; + BaseComponent &operator=(BaseComponent &&other) = default; + static int Index() { static QAtomicInt _index(0); if (int index = _index.loadAcquire()) { return index - 1; } while (true) { - int last = InterfaceIndexLast.loadAcquire(); - if (InterfaceIndexLast.testAndSetOrdered(last, last + 1)) { + int last = ComponentIndexLast.loadAcquire(); + if (ComponentIndexLast.testAndSetOrdered(last, last + 1)) { t_assert(last < 64); if (_index.testAndSetOrdered(0, last + 1)) { - InterfaceWraps[last] = InterfaceWrapStruct(InterfaceWrapTemplate::Size, InterfaceWrapTemplate::Construct, InterfaceWrapTemplate::Destruct, InterfaceWrapTemplate::Move); + ComponentWraps[last] = ComponentWrapStruct(ComponentWrapTemplate::Size, ComponentWrapTemplate::Construct, ComponentWrapTemplate::Destruct, ComponentWrapTemplate::Move); } break; } @@ -609,22 +642,14 @@ public: }; -template -class BasicInterfaceWithPointer : public BasicInterface { -public: - BasicInterfaceWithPointer(Interfaces *interfaces) : interfaces(interfaces) { - } - Interfaces *interfaces = 0; -}; - -class InterfacesMetadata { +class ComposerMetadata { public: - InterfacesMetadata(uint64 mask) : size(0), last(64), _mask(mask) { + ComposerMetadata(uint64 mask) : size(0), last(64), _mask(mask) { for (int i = 0; i < 64; ++i) { uint64 m = (1 << i); if (_mask & m) { - int s = InterfaceWraps[i].Size; + int s = ComponentWraps[i].Size; if (s) { offsets[i] = size; size += s; @@ -660,15 +685,15 @@ private: }; -const InterfacesMetadata *GetInterfacesMetadata(uint64 mask); +const ComposerMetadata *GetComposerMetadata(uint64 mask); -class Interfaces { +class Composer { public: - Interfaces(uint64 mask = 0) : _data(zerodata()) { + Composer(uint64 mask = 0) : _data(zerodata()) { if (mask) { - const InterfacesMetadata *meta = GetInterfacesMetadata(mask); - int32 size = sizeof(const InterfacesMetadata *) + meta->size; + const ComposerMetadata *meta = GetComposerMetadata(mask); + int size = sizeof(meta) + meta->size; void *data = operator new(size); if (!data) { // terminate if we can't allocate memory throw "Can't allocate memory!"; @@ -680,13 +705,13 @@ public: int offset = meta->offsets[i]; if (offset >= 0) { try { - InterfaceWraps[i].Construct(_dataptrunsafe(offset), this); + ComponentWraps[i].Construct(_dataptrunsafe(offset), this); } catch (...) { while (i > 0) { --i; offset = meta->offsets[--i]; if (offset >= 0) { - InterfaceWraps[i].Destruct(_dataptrunsafe(offset)); + ComponentWraps[i].Destruct(_dataptrunsafe(offset)); } } throw; @@ -695,38 +720,41 @@ public: } } } - void UpdateInterfaces(uint64 mask = 0) { + Composer(const Composer &other) = delete; + Composer &operator=(const Composer &other) = delete; + ~Composer() { + if (_data != zerodata()) { + const ComposerMetadata *meta = _meta(); + for (int i = 0; i < meta->last; ++i) { + int offset = meta->offsets[i]; + if (offset >= 0) { + ComponentWraps[i].Destruct(_dataptrunsafe(offset)); + } + } + operator delete(_data); + } + } + + void UpdateComponents(uint64 mask = 0) { if (!_meta()->equals(mask)) { - Interfaces tmp(mask); + Composer tmp(mask); tmp.swap(*this); if (_data != zerodata() && tmp._data != zerodata()) { - const InterfacesMetadata *meta = _meta(), *wasmeta = tmp._meta(); + const ComposerMetadata *meta = _meta(), *wasmeta = tmp._meta(); for (int i = 0; i < meta->last; ++i) { int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i]; if (offset >= 0 && wasoffset >= 0) { - InterfaceWraps[i].Move(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset)); + ComponentWraps[i].Move(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset)); } } } } } - void AddInterfaces(uint64 mask = 0) { - UpdateInterfaces(_meta()->maskadd(mask)); + void AddComponents(uint64 mask = 0) { + UpdateComponents(_meta()->maskadd(mask)); } - void RemoveInterfaces(uint64 mask = 0) { - UpdateInterfaces(_meta()->maskremove(mask)); - } - ~Interfaces() { - if (_data != zerodata()) { - const InterfacesMetadata *meta = _meta(); - for (int i = 0; i < meta->last; ++i) { - int offset = meta->offsets[i]; - if (offset >= 0) { - InterfaceWraps[i].Destruct(_dataptrunsafe(offset)); - } - } - operator delete(_data); - } + void RemoveComponents(uint64 mask = 0) { + UpdateComponents(_meta()->maskremove(mask)); } template @@ -738,31 +766,28 @@ public: return static_cast(_dataptr(_meta()->offsets[Type::Index()])); } template - bool Is() const { + bool Has() const { return (_meta()->offsets[Type::Index()] >= 0); } private: - static const InterfacesMetadata *ZeroInterfacesMetadata; + static const ComposerMetadata *ZeroComposerMetadata; static void *zerodata() { - return &ZeroInterfacesMetadata; + return &ZeroComposerMetadata; } void *_dataptrunsafe(int skip) const { - return (char*)_data + sizeof(const InterfacesMetadata*) + skip; + return (char*)_data + sizeof(_meta()) + skip; } void *_dataptr(int skip) const { return (skip >= 0) ? _dataptrunsafe(skip) : 0; } - const InterfacesMetadata *&_meta() const { - return *static_cast(_data); + const ComposerMetadata *&_meta() const { + return *static_cast(_data); } void *_data; - Interfaces(const Interfaces &other); - Interfaces &operator=(const Interfaces &other); - - void swap(Interfaces &other) { + void swap(Composer &other) { std::swap(_data, other._data); } diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 4c155538d..d2ce17a4f 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -1410,7 +1410,7 @@ void Window::notifySchedule(History *history, HistoryItem *item) { haveSetting = false; } - int delay = item->Is() ? 500 : 100, t = unixtime(); + int delay = item->Has() ? 500 : 100, t = unixtime(); uint64 ms = getms(true); bool isOnline = main->lastWasOnline(), otherNotOld = ((cOtherOnline() * uint64(1000)) + Global::OnlineCloudTimeout() > t * uint64(1000)); bool otherLaterThanMe = (cOtherOnline() * uint64(1000) + (ms - main->lastSetOnline()) > t * uint64(1000)); @@ -1629,7 +1629,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { notifyWaitTimer.start(next - ms); break; } else { - HistoryItem *fwd = notifyItem->Is() ? notifyItem : 0; // forwarded notify grouping + HistoryItem *fwd = notifyItem->Has() ? notifyItem : nullptr; // forwarded notify grouping int32 fwdCount = 1; uint64 ms = getms(true); @@ -1657,7 +1657,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { } while (history->hasNotification()); if (nextNotify) { if (fwd) { - HistoryItem *nextFwd = nextNotify->Is() ? nextNotify : 0; + HistoryItem *nextFwd = nextNotify->Has() ? nextNotify : nullptr; if (nextFwd && fwd->author() == nextFwd->author() && qAbs(int64(nextFwd->date.toTime_t()) - int64(fwd->date.toTime_t())) < 2) { fwd = nextFwd; ++fwdCount; diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc index cd7485bd7..863775349 100644 --- a/Telegram/Telegram.rc +++ b/Telegram/Telegram.rc @@ -34,8 +34,8 @@ IDI_ICON1 ICON "SourceFiles\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,9,34,3 - PRODUCTVERSION 0,9,34,3 + FILEVERSION 0,9,34,4 + PRODUCTVERSION 0,9,34,4 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.9.34.3" + VALUE "FileVersion", "0.9.34.4" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.9.34.3" + VALUE "ProductVersion", "0.9.34.4" END END BLOCK "VarFileInfo" diff --git a/Telegram/Version b/Telegram/Version index 9c0370804..7d9e063d1 100644 --- a/Telegram/Version +++ b/Telegram/Version @@ -3,4 +3,4 @@ AppVersionStrMajor 0.9 AppVersionStrSmall 0.9.34 AppVersionStr 0.9.34 DevChannel 0 -BetaVersion 9034003 +BetaVersion 9034004 From cbebf9ced70b4bdcc9a45fea9399ddcd7d67bbab Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 25 Mar 2016 14:31:40 +0300 Subject: [PATCH 4/4] langs updated for 9034004 --- Telegram/SourceFiles/langs/lang_de.strings | 96 ++++++++-------- Telegram/SourceFiles/langs/lang_es.strings | 48 ++++---- Telegram/SourceFiles/langs/lang_it.strings | 84 +++++++------- Telegram/SourceFiles/langs/lang_ko.strings | 106 +++++++++--------- Telegram/SourceFiles/langs/lang_nl.strings | 74 ++++++------ Telegram/SourceFiles/langs/lang_pt_BR.strings | 96 ++++++++-------- 6 files changed, 270 insertions(+), 234 deletions(-) diff --git a/Telegram/SourceFiles/langs/lang_de.strings b/Telegram/SourceFiles/langs/lang_de.strings index 3e247d1c5..de9dec99a 100644 --- a/Telegram/SourceFiles/langs/lang_de.strings +++ b/Telegram/SourceFiles/langs/lang_de.strings @@ -87,7 +87,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_continue" = "Weiter"; "lng_close" = "Schließen"; "lng_connecting" = "Verbinde..."; -"lng_reconnecting" = "Neu verbinden {count:jetzt|in # s|in # s}.."; +"lng_reconnecting" = "Neu verbinden {count:jetzt|in # s|in # s}..."; "lng_reconnecting_try_now" = "Jetzt versuchen"; "lng_status_service_notifications" = "Servicemeldungen"; @@ -108,7 +108,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_status_lastseen_date" = "zuletzt gesehen am {date}"; "lng_status_lastseen_date_time" = "zuletzt gesehen am {date} um {time}"; "lng_status_online" = "online"; -"lng_status_connecting" = "verbinden.."; +"lng_status_connecting" = "verbinden..."; "lng_chat_status_unaccessible" = "Gruppe ist nicht verfügbar"; "lng_chat_status_members" = "{count:keine Mitglieder|# Mitglied|# Mitglieder}"; @@ -127,7 +127,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_edit_deleted" = "Diese Nachricht wurde gelöscht"; "lng_edit_too_long" = "Der Text ist leider zu lang"; "lng_edit_message" = "Nachricht bearbeiten"; -"lng_edit_message_text" = "Neuer Text.."; +"lng_edit_message_text" = "Neuer Text..."; "lng_deleted" = "Gelöschter Kontakt"; "lng_deleted_message" = "Gelöschte Nachricht"; "lng_pinned_message" = "Angeheftete Nachricht"; @@ -162,7 +162,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_code_telegram" = "Bitte den Code eingeben, den du in der\nzuvor benutzen [b]Telegram[/b]-App erhalten hast."; "lng_code_no_telegram" = "Code per SMS senden"; "lng_code_call" = "Telegram ruft dich an in {minutes}:{seconds}"; -"lng_code_calling" = "Telegram ruft dich an.."; +"lng_code_calling" = "Telegram ruft dich an..."; "lng_code_called" = "Telegram ruft dich gerade an."; "lng_bad_phone" = "Falsche Nummer, bitte erneut versuchen."; @@ -201,7 +201,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_dlg_new_channel_name" = "Kanalname"; "lng_no_contacts" = "Du hast keine Kontakte"; "lng_no_chats" = "Noch keine Chats"; -"lng_contacts_loading" = "Lade.."; +"lng_contacts_loading" = "Lade..."; "lng_contacts_not_found" = "Keine Kontakte gefunden"; "lng_dlg_search_chat" = "In diesem Chat suchen"; "lng_dlg_search_channel" = "In diesem Kanal suchen"; @@ -210,7 +210,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_save" = "Speichern"; "lng_settings_upload" = "Profilbild festlegen"; "lng_settings_crop_profile" = "Sichtbaren Bereich für Bild wählen"; -"lng_settings_uploading_photo" = "Bild wird geladen.."; +"lng_settings_uploading_photo" = "Bild wird geladen..."; "lng_username_title" = "Benutzername"; "lng_username_about" = "Wähle einen (optionalen) öffentlichen \nBenutzernamen, wenn du von anderen \ngefunden werden willst, ohne, dass sie \ndeine Nummer kennen müssen.\n\nErlaubt sind a-z, 0-9 und Unterstriche. \nDie Mindestlänge beträgt 5 Zeichen."; @@ -247,9 +247,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_auto_update" = "Auto-Updates"; "lng_settings_current_version" = "Version {version}"; "lng_settings_check_now" = "Auf Updates prüfen"; -"lng_settings_update_checking" = "Prüfe auf Updates.."; +"lng_settings_update_checking" = "Prüfe auf Updates..."; "lng_settings_latest_installed" = "Aktuellste Version bereits installiert"; -"lng_settings_downloading" = "Update wird geladen {ready} / {total} MB.."; +"lng_settings_downloading" = "Update wird geladen {ready} / {total} MB..."; "lng_settings_update_ready" = "Neue Version kann installiert werden"; "lng_settings_update_now" = "Jetzt neustarten"; "lng_settings_update_fail" = "Konnte nicht auf Updates prüfen :("; @@ -291,7 +291,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_download_path_failed" = "Download konnte nicht gestartet werden. Das kann am eingestellten Speicherort liegen.\n\nDu kannst den Speicherort in den Einstellungen ändern."; "lng_download_path_settings" = "Einstellungen"; "lng_download_finish_failed" = "Datei konnte nicht geladen werden.\n\nErneut versuchen?"; -"lng_download_path_clearing" = "Leeren.."; +"lng_download_path_clearing" = "Leeren..."; "lng_download_path_cleared" = "Geleert!"; "lng_download_path_clear_failed" = "Ein Fehler ist aufgetreten :("; @@ -300,7 +300,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_images_cached" = "{count:_not_used_|# Bild|# Bilder}, {size}"; "lng_settings_audios_cached" = "{count:_not_used_|# Sprachnachricht|# Sprachnachrichten}, {size}"; "lng_local_storage_clear" = "Leeren"; -"lng_local_storage_clearing" = "Entferne.."; +"lng_local_storage_clearing" = "Leeren..."; "lng_local_storage_cleared" = "Alles entfernt!"; "lng_local_storage_clear_failed" = "Ein Fehler ist aufgetreten :("; @@ -331,7 +331,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_passcode_logout" = "Abmelden"; "lng_passcode_need_unblock" = "Bitte erst entsperren."; -"lng_cloud_password_waiting" = "Bestätigungslink gesendet an {email}.."; +"lng_cloud_password_waiting" = "Bestätigungslink gesendet an {email}..."; "lng_cloud_password_change" = "Kennwort ändern"; "lng_cloud_password_create" = "Kennwort erstellen"; "lng_cloud_password_remove" = "Kennwort entfernen"; @@ -358,7 +358,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_cloud_password_is_same" = "Kennwort wurde nicht geändert"; "lng_connection_type" = "Verbindungsart:"; -"lng_connection_auto_connecting" = "Standard (verbinden..)"; +"lng_connection_auto_connecting" = "Standard (verbinden...)"; "lng_connection_auto" = "Standard ({transport} verwendet)"; "lng_connection_proxy_connecting" = "Verbinde über Proxy..."; "lng_connection_proxy" = "{transport} mit Proxy"; @@ -439,7 +439,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_sure_kick" = "{user} aus der Gruppe entfernen?"; "lng_profile_sure_kick_channel" = "{user} aus dem Kanal entfernen?"; "lng_profile_sure_kick_admin" = "{user} als Administrator entfernen?"; -"lng_profile_loading" = "Lade.."; +"lng_profile_loading" = "Lade..."; "lng_profile_shared_media" = "Geteilte Medien"; "lng_profile_no_media" = "Noch keine Medien in diesem Chat"; "lng_profile_photos" = "{count:_not_used_|# Bild|# Bilder} »"; @@ -455,6 +455,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_shared_links" = "{count:_not_used_|# Link|# Links} »"; "lng_profile_shared_links_header" = "Links aus dem Chat"; "lng_profile_copy_phone" = "Telefonnummer kopieren"; +"lng_profile_copy_fullname" = "Anzeigename kopieren"; "lng_channel_add_admins" = "Neuer Administrator"; "lng_channel_add_members" = "Mitglieder hinzufügen"; @@ -659,12 +660,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_stickers_remove" = "Löschen"; "lng_stickers_return" = "Rückgängig"; "lng_stickers_restore" = "Zeigen"; -"lng_stickers_count" = "{count:Lade..|# Sticker|# Sticker}"; +"lng_stickers_count" = "{count:Lade...|# Sticker|# Sticker}"; "lng_in_dlg_photo" = "Bild"; -"lng_in_dlg_video" = "Video"; +"lng_in_dlg_video" = "Video file"; +"lng_in_dlg_audio_file" = "Audio file"; "lng_in_dlg_contact" = "Kontakt"; -"lng_in_dlg_audio" = "Sprachnachricht"; +"lng_in_dlg_audio" = "Voice message"; "lng_in_dlg_file" = "Datei"; "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (Sticker)"; @@ -678,18 +680,20 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_report_spam_sure_group" = "Spam in dieser Gruppe melden?"; "lng_report_spam_sure_channel" = "Möchtest du wirklich Spam in diesem Kanal melden?"; "lng_report_spam_ok" = "Melden"; -"lng_cant_send_to_not_contact" = "Derzeit kannst du nur Personen schreiben, wenn ihr eure Nummern ausgetauscht habt. {more_info}"; -"lng_cant_invite_not_contact" = "Du kannst nur Personen hinzufügen, wenn ihr eure Nummern ausgetauscht habt. {more_info}"; -"lng_cant_invite_not_contact_channel" = "Du kannst nur Personen hinzufügen,wenn ihr\neure Nummern ausgetauscht habt. {more_info}\n"; +"lng_cant_send_to_not_contact" = "Derzeit kannst du nur Personen schreiben,\nwenn ihr eure Nummern ausgetauscht habt.\n{more_info}"; +"lng_cant_invite_not_contact" = "Du kannst nur Personen hinzufügen,\nwenn ihr eure Nummern ausgetauscht habt.\n{more_info}"; +"lng_cant_invite_not_contact_channel" = "Du kannst nur Personen hinzufügen,\nwenn ihr eure Nummern ausgetauscht habt.\n{more_info}"; "lng_cant_more_info" = "Weitere Infos »"; +"lng_cant_invite_banned" = "Nur Admins können diesen Nutzer hinzufügen."; "lng_cant_invite_privacy" = "Du kannst mit diesen Nutzern keine Gruppe erstellen, weil sie es nicht erlauben."; "lng_cant_invite_privacy_channel" = "Du kannst diese Nutzer keinen Kanälen hinzufügen, weil sie es nicht erlauben."; +"lng_cant_do_this" = "Verzeihung. Das ist leider nicht möglich."; "lng_send_button" = "Senden"; -"lng_message_ph" = "Schreibe deine Nachricht.."; -"lng_comment_ph" = "Schreibe ein Kommentar.."; -"lng_broadcast_ph" = "Sende einen Broadcast.."; -"lng_broadcast_silent_ph" = "Lautloser Broadcast"; +"lng_message_ph" = "Schreibe deine Nachricht..."; +"lng_comment_ph" = "Schreibe ein Kommentar..."; +"lng_broadcast_ph" = "Sende einen Broadcast..."; +"lng_broadcast_silent_ph" = "Lautloser Broadcast..."; "lng_record_cancel" = "Zum Abbrechen rausbewegen"; "lng_will_be_notified" = "Mitglieder werden benachrichtigt"; "lng_wont_be_notified" = "Mitglieder werden nicht benachrichtigt"; @@ -718,27 +722,28 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_users_typing" = "{user} und {second_user} tippen"; "lng_many_typing" = "{count:_not_used_|# tippt|# tippen}"; "lng_send_action_record_video" = "schickt Video"; -"lng_user_action_record_video" = "{user} sendet Video"; -"lng_send_action_upload_video" = "schickt Video"; -"lng_user_action_upload_video" = "{user} sendet Video"; -"lng_send_action_record_audio" = "nimmt Audio auf"; -"lng_user_action_record_audio" = "{user} nimmt Audio auf"; -"lng_send_action_upload_audio" = "nimmt Audio auf"; -"lng_user_action_upload_audio" = "{user} sendet Audio"; -"lng_send_action_upload_photo" = "sendet Bild"; -"lng_user_action_upload_photo" = "{user} sendet Bild"; -"lng_send_action_upload_file" = "sendet Datei"; -"lng_user_action_upload_file" = "{user} sendet Datei"; -"lng_send_action_geo_location" = "wählt Standort aus"; -"lng_user_action_geo_location" = "{user} wählt Standort aus"; -"lng_send_action_choose_contact" = "wählt Kontakt aus"; -"lng_user_action_choose_contact" = "{user} wählt Kontakt aus"; +"lng_user_action_record_video" = "{user} sendet ein Video"; +"lng_send_action_upload_video" = "schickt ein Video"; +"lng_user_action_upload_video" = "{user} sendet ein Video"; +"lng_send_action_record_audio" = "nimmt ein Audio auf"; +"lng_user_action_record_audio" = "{user} nimmt eine Sprachnachricht auf"; +"lng_send_action_upload_audio" = "sendet eine Sprachnachricht"; +"lng_user_action_upload_audio" = "{user} sendet eine Sprachnachricht"; +"lng_send_action_upload_photo" = "sendet ein Bild"; +"lng_user_action_upload_photo" = "{user} sendet ein Bild"; +"lng_send_action_upload_file" = "sendet eine Datei"; +"lng_user_action_upload_file" = "{user} sendet eine Datei"; +"lng_send_action_geo_location" = "wählt einen Standort aus"; +"lng_user_action_geo_location" = "{user} wählt einen Standort aus"; +"lng_send_action_choose_contact" = "wählt einen Kontakt aus"; +"lng_user_action_choose_contact" = "{user} wählt einen Kontakt aus"; "lng_unread_bar" = "{count:_not_used_|# Ungelesene Nachricht|# Ungelesene Nachrichten}"; "lng_maps_point" = "Standort"; "lng_save_photo" = "Bild speichern"; -"lng_save_video" = "Video speichern"; -"lng_save_audio" = "Sprachnachricht speichern"; +"lng_save_video" = "Save video file"; +"lng_save_audio_file" = "Save audio file"; +"lng_save_audio" = "Save voice message"; "lng_save_file" = "Datei speichern"; "lng_save_downloaded" = "{ready} / {total} {mb}"; "lng_duration_and_size" = "{duration}, {size}"; @@ -755,7 +760,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_copy_email" = "E-Mail-Adresse kopieren"; "lng_context_copy_hashtag" = "Hashtag kopieren"; "lng_context_copy_mention" = "Benutzername kopieren"; -"lng_context_save_image" = "Bild speichern unter"; +"lng_context_save_image" = "Bild speichern unter..."; "lng_context_forward_image" = "Bild weiterleiten"; "lng_context_delete_image" = "Bild löschen"; "lng_context_copy_image" = "Bild kopieren"; @@ -763,11 +768,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_cancel_download" = "Download abbrechen"; "lng_context_show_in_folder" = "Im Ordner anzeigen"; "lng_context_show_in_finder" = "Im Finder zeigen"; -"lng_context_save_video" = "Video speichern unter.."; -"lng_context_save_audio" = "Sprachnachricht speichern unter.."; +"lng_context_save_video" = "Save Video File As..."; +"lng_context_save_audio_file" = "Save Audio File As..."; +"lng_context_save_audio" = "Save Voice Message As..."; "lng_context_pack_info" = "Sticker-Paket"; "lng_context_pack_add" = "Sticker hinzufügen"; -"lng_context_save_file" = "Datei speichern als.."; +"lng_context_save_file" = "Datei speichern unter..."; "lng_context_forward_file" = "Datei weiterleiten"; "lng_context_delete_file" = "Datei löschen"; "lng_context_close_file" = "Datei schließen"; @@ -794,7 +800,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_send_image_too_large" = "Nur Dateien bis maximal 1,5 GB können gesendet werden :("; "lng_send_folder" = "Verzeichnis «{name}» kann nicht gesendet werden :("; -"lng_forward_choose" = "Empfänger wählen.."; +"lng_forward_choose" = "Empfänger wählen..."; "lng_forward_cant" = "Weiterleiten nicht möglich :("; "lng_forward_confirm" = "An {recipient} weiterleiten?"; "lng_forward_share_contact" = "Kontakt an {recipient} senden?"; diff --git a/Telegram/SourceFiles/langs/lang_es.strings b/Telegram/SourceFiles/langs/lang_es.strings index dfa3a6261..27e704187 100644 --- a/Telegram/SourceFiles/langs/lang_es.strings +++ b/Telegram/SourceFiles/langs/lang_es.strings @@ -127,7 +127,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_edit_deleted" = "Este mensaje fue eliminado"; "lng_edit_too_long" = "Tu texto es demasiado largo"; "lng_edit_message" = "Editar mensaje"; -"lng_edit_message_text" = "Nuevo texto..."; +"lng_edit_message_text" = "Nuevo mensaje..."; "lng_deleted" = "Desconocido"; "lng_deleted_message" = "Mensaje eliminado"; "lng_pinned_message" = "Mensaje anclado"; @@ -210,7 +210,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_save" = "Guardar"; "lng_settings_upload" = "Poner foto de perfil"; "lng_settings_crop_profile" = "Selecciona el área para tu foto de perfil"; -"lng_settings_uploading_photo" = "Cargando foto..."; +"lng_settings_uploading_photo" = "Subiendo foto..."; "lng_username_title" = "Alias"; "lng_username_about" = "Puedes elegir un alias en Telegram. \nSi lo haces, otras personas te podrán \nencontrar por ese alias y contactarte \nsin saber tu número de teléfono.\n\nPuedes usar a-z, 0-9 y guiones bajos.\nLa longitud mínima es de 5 caracteres."; @@ -360,7 +360,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_connection_type" = "Tipo de conexión:"; "lng_connection_auto_connecting" = "Por defecto (conectando...)"; "lng_connection_auto" = "Por defecto ({transport} en uso)"; -"lng_connection_proxy_connecting" = "Conectando a través de un proxy..."; +"lng_connection_proxy_connecting" = "Conectando a través de proxy..."; "lng_connection_proxy" = "{transport} con un proxy"; "lng_connection_header" = "Tipo de conexión"; "lng_connection_auto_rb" = "Automático (TCP si existe o HTTP)"; @@ -455,6 +455,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_shared_links" = "{count:_not_used_|# enlace|# enlaces} »"; "lng_profile_shared_links_header" = "Enlaces"; "lng_profile_copy_phone" = "Copiar número"; +"lng_profile_copy_fullname" = "Copiar nombre"; "lng_channel_add_admins" = "Nuevo administrador"; "lng_channel_add_members" = "Añadir miembros"; @@ -662,9 +663,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_stickers_count" = "{count:Cargando...|# sticker|# stickers}"; "lng_in_dlg_photo" = "Foto"; -"lng_in_dlg_video" = "Vídeo"; +"lng_in_dlg_video" = "Video file"; +"lng_in_dlg_audio_file" = "Audio file"; "lng_in_dlg_contact" = "Contacto"; -"lng_in_dlg_audio" = "Audio"; +"lng_in_dlg_audio" = "Voice message"; "lng_in_dlg_file" = "Archivo"; "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; @@ -678,12 +680,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_report_spam_sure_group" = "¿Quieres reportar el spam en este grupo?"; "lng_report_spam_sure_channel" = "¿Quieres reportar a este canal como spam?"; "lng_report_spam_ok" = "Reportar"; -"lng_cant_send_to_not_contact" = "Por ahora, sólo puedes enviar mensajes\na contactos mutuos. {more_info}"; -"lng_cant_invite_not_contact" = "Por ahora, sólo puedes añadir contactos \nmutuos a grupos. {more_info}"; -"lng_cant_invite_not_contact_channel" = "Lo sentimos, sólo puedes añadir contactos\nmutuos a canales. {more_info}"; +"lng_cant_send_to_not_contact" = "Por ahora, sólo puedes enviar\nmensajes a contactos mutuos. \n{more_info}"; +"lng_cant_invite_not_contact" = "Por ahora, sólo puedes añadir \ncontactos mutuos a grupos. \n{more_info}"; +"lng_cant_invite_not_contact_channel" = "Por ahora, sólo puedes añadir \ncontactos mutuos a canales. \n{more_info}"; "lng_cant_more_info" = "Más información »"; +"lng_cant_invite_banned" = "Sólo el administrador puede añadir a este usuario."; "lng_cant_invite_privacy" = "No puedes añadir a este usuario a grupos por sus ajustes de privacidad."; "lng_cant_invite_privacy_channel" = "No puedes añadir a este usuario a canales por sus ajustes de privacidad."; +"lng_cant_do_this" = "Lo sentimos, esta acción no está disponible."; "lng_send_button" = "Enviar"; "lng_message_ph" = "Escribe un mensaje..."; @@ -717,28 +721,29 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_user_typing" = "{user} está escribiendo"; "lng_users_typing" = "{user} y {second_user} están escribiendo"; "lng_many_typing" = "{count:_not_used_|# está|# están} escribiendo"; -"lng_send_action_record_video" = "grabando vídeo"; +"lng_send_action_record_video" = "grabando un vídeo"; "lng_user_action_record_video" = "{user} está grabando un vídeo"; -"lng_send_action_upload_video" = "enviando vídeo"; +"lng_send_action_upload_video" = "enviando un vídeo"; "lng_user_action_upload_video" = "{user} está enviando un vídeo"; -"lng_send_action_record_audio" = "grabando audio"; -"lng_user_action_record_audio" = "{user} está grabando un audio"; -"lng_send_action_upload_audio" = "enviando audio"; -"lng_user_action_upload_audio" = "{user} está enviando un audio"; -"lng_send_action_upload_photo" = "enviando foto"; +"lng_send_action_record_audio" = "grabando un mensaje de voz"; +"lng_user_action_record_audio" = "{user} está grabando un mensaje de voz"; +"lng_send_action_upload_audio" = "enviando un mensaje de voz"; +"lng_user_action_upload_audio" = "{user} está enviando un mensaje de voz"; +"lng_send_action_upload_photo" = "enviando una foto"; "lng_user_action_upload_photo" = "{user} está enviando una foto"; -"lng_send_action_upload_file" = "enviando archivo"; +"lng_send_action_upload_file" = "enviando un archivo"; "lng_user_action_upload_file" = "{user} está enviando un archivo"; "lng_send_action_geo_location" = "obteniendo ubicación"; "lng_user_action_geo_location" = "{user} está obteniendo una ubicación"; -"lng_send_action_choose_contact" = "eligiendo contacto"; +"lng_send_action_choose_contact" = "eligiendo un contacto"; "lng_user_action_choose_contact" = "{user} está eligiendo un contacto"; "lng_unread_bar" = "{count:_not_used_|# mensaje sin leer|# mensajes sin leer}"; "lng_maps_point" = "Ubicación"; "lng_save_photo" = "Guardar imagen"; -"lng_save_video" = "Guardar vídeo"; -"lng_save_audio" = "Guardar audio"; +"lng_save_video" = "Save video file"; +"lng_save_audio_file" = "Save audio file"; +"lng_save_audio" = "Save voice message"; "lng_save_file" = "Guardar archivo"; "lng_save_downloaded" = "{ready} / {total} {mb}"; "lng_duration_and_size" = "{duration}, {size}"; @@ -763,8 +768,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_cancel_download" = "Cancelar descarga"; "lng_context_show_in_folder" = "Mostrar en la carpeta"; "lng_context_show_in_finder" = "Mostrar en el Finder"; -"lng_context_save_video" = "Guardar como..."; -"lng_context_save_audio" = "Guardar como..."; +"lng_context_save_video" = "Save Video File As..."; +"lng_context_save_audio_file" = "Save Audio File As..."; +"lng_context_save_audio" = "Save Voice Message As..."; "lng_context_pack_info" = "Información del pack"; "lng_context_pack_add" = "Añadir stickers"; "lng_context_save_file" = "Guardar como..."; diff --git a/Telegram/SourceFiles/langs/lang_it.strings b/Telegram/SourceFiles/langs/lang_it.strings index 1a8e00d88..636096cb5 100644 --- a/Telegram/SourceFiles/langs/lang_it.strings +++ b/Telegram/SourceFiles/langs/lang_it.strings @@ -127,7 +127,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_edit_deleted" = "Questo messaggio è stato eliminato"; "lng_edit_too_long" = "Il tuo messaggio è troppo lungo"; "lng_edit_message" = "Modifica messaggio"; -"lng_edit_message_text" = "Nuovo testo messaggio.."; +"lng_edit_message_text" = "Nuovo testo messaggio..."; "lng_deleted" = "Sconosciuto"; "lng_deleted_message" = "Messaggio eliminato"; "lng_pinned_message" = "Messaggio fissato"; @@ -162,7 +162,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_code_telegram" = "Per favore inserisci il codice che hai\nappena ricevuto nell'altra app di [b]Telegram[/b]."; "lng_code_no_telegram" = "Invia codice via SMS"; "lng_code_call" = "Telegram ti chiamerà tra {minutes}:{seconds}"; -"lng_code_calling" = "Richiedendo una telefonata da Telegram.."; +"lng_code_calling" = "Richiedo una telefonata da Telegram..."; "lng_code_called" = "Telegram ti ha chiamato"; "lng_bad_phone" = "Numero di telefono non valido. Per favore riprova."; @@ -201,7 +201,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_dlg_new_channel_name" = "Nome canale"; "lng_no_contacts" = "Non hai contatti"; "lng_no_chats" = "Le tua chat saranno qui"; -"lng_contacts_loading" = "Caricamento.."; +"lng_contacts_loading" = "Caricamento..."; "lng_contacts_not_found" = "Nessun contatto trovato"; "lng_dlg_search_chat" = "Cerca in questa chat"; "lng_dlg_search_channel" = "Cerca in questo canale"; @@ -210,7 +210,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_save" = "Salva"; "lng_settings_upload" = "Imposta foto profilo"; "lng_settings_crop_profile" = "Seleziona un riquadro per la tua foto profilo"; -"lng_settings_uploading_photo" = "Caricamento foto.."; +"lng_settings_uploading_photo" = "Caricamento foto..."; "lng_username_title" = "Username"; "lng_username_about" = "Puoi scegliere un username su Telegram.\nSe lo fai, le altre persone potranno trovarti\ntramite questo username e contattarti \nsenza conoscere il tuo numero di telefono.\n\nPuoi usare a-z, 0-9 e underscore.\nLa lunghezza minima è di 5 caratteri."; @@ -247,9 +247,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_auto_update" = "Aggiorna automaticamente"; "lng_settings_current_version" = "Versione {version}"; "lng_settings_check_now" = "Cerca aggiornamenti"; -"lng_settings_update_checking" = "Cerco aggiornamenti.."; +"lng_settings_update_checking" = "Cerco aggiornamenti..."; "lng_settings_latest_installed" = "L'ultima versione è installata"; -"lng_settings_downloading" = "Download aggiornamento {ready} / {total} MB.."; +"lng_settings_downloading" = "Download aggiornamento {ready} / {total} MB..."; "lng_settings_update_ready" = "La nuova versione è pronta"; "lng_settings_update_now" = "Riavvia ora"; "lng_settings_update_fail" = "Ricerca aggiornamenti fallita :("; @@ -291,7 +291,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_download_path_failed" = "Il download del file non può iniziare. La causa potrebbe essere una posizione sbagliata per i download.\n\nPuoi cambiare il percorso di download nelle Impostazioni."; "lng_download_path_settings" = "Impostazioni"; "lng_download_finish_failed" = "Il download del file non può essere concluso.\n\nVuoi riprovare?"; -"lng_download_path_clearing" = "Eliminazione.."; +"lng_download_path_clearing" = "Elimino..."; "lng_download_path_cleared" = "Eliminato!"; "lng_download_path_clear_failed" = "Eliminazione fallita :("; @@ -300,7 +300,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_images_cached" = "{count:_not_used_|# immagine|# immagini}, {size}"; "lng_settings_audios_cached" = "{count:_not_used_|# messaggio vocale|# messaggi vocali}, {size}"; "lng_local_storage_clear" = "Elimina tutto"; -"lng_local_storage_clearing" = "Eliminando.."; +"lng_local_storage_clearing" = "Elimino..."; "lng_local_storage_cleared" = "Eliminato!"; "lng_local_storage_clear_failed" = "Eliminazione fallita :("; @@ -331,7 +331,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_passcode_logout" = "Disconnetti"; "lng_passcode_need_unblock" = "Devi prima sbloccarmi."; -"lng_cloud_password_waiting" = "Link di conferma inviato a {email}.."; +"lng_cloud_password_waiting" = "Link di conferma inviato a {email}..."; "lng_cloud_password_change" = "Cambia password"; "lng_cloud_password_create" = "Password cloud"; "lng_cloud_password_remove" = "Rimuovi password"; @@ -358,9 +358,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_cloud_password_is_same" = "La password non è stata cambiata"; "lng_connection_type" = "Tipo di connessione:"; -"lng_connection_auto_connecting" = "Predefinita (connetto..)"; +"lng_connection_auto_connecting" = "Predefinita (connetto...)"; "lng_connection_auto" = "Predefinita ({transport} in uso)"; -"lng_connection_proxy_connecting" = "Connetto tramite proxy.."; +"lng_connection_proxy_connecting" = "Connetto tramite proxy..."; "lng_connection_proxy" = "{transport} con proxy"; "lng_connection_header" = "Tipo di connessione"; "lng_connection_auto_rb" = "Auto (TCP se disponibile o HTTP)"; @@ -396,7 +396,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_sessions_other_desc" = "Ti puoi connettere a Telegram da altri dispositivi mobili, tablet e desktop usando lo stesso numero. Tutti i tuoi dati saranno sincronizzati istantaneamente."; "lng_sessions_terminate_all" = "Termina tutte le altre sessioni"; -"lng_preview_loading" = "Recupero le info del link.."; +"lng_preview_loading" = "Recupero le info del link..."; "lng_profile_chat_unaccessible" = "Gruppo non accessibile"; "lng_topbar_info" = "Info"; @@ -439,7 +439,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_sure_kick" = "Rimuovere {user} dal gruppo?"; "lng_profile_sure_kick_channel" = "Rimuovere {user} dal canale?"; "lng_profile_sure_kick_admin" = "Rimuovere {user} dagli amministratori?"; -"lng_profile_loading" = "Caricamento.."; +"lng_profile_loading" = "Caricamento..."; "lng_profile_shared_media" = "Media condivisi"; "lng_profile_no_media" = "Nessun media in questa chat."; "lng_profile_photos" = "{count:_not_used_|# foto|# foto} »"; @@ -455,6 +455,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_shared_links" = "{count:_not_used_|# link condiviso|# link condivisi} »"; "lng_profile_shared_links_header" = "Panoramica link condivisi"; "lng_profile_copy_phone" = "Copia numero di telefono"; +"lng_profile_copy_fullname" = "Copia nome"; "lng_channel_add_admins" = "Nuovo amministratore"; "lng_channel_add_members" = "Aggiungi membri"; @@ -659,12 +660,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_stickers_remove" = "Elimina"; "lng_stickers_return" = "Annulla"; "lng_stickers_restore" = "Ripristina"; -"lng_stickers_count" = "{count:Caricamento..|# sticker|# sticker}"; +"lng_stickers_count" = "{count:Caricamento...|# sticker|# sticker}"; "lng_in_dlg_photo" = "Foto"; -"lng_in_dlg_video" = "Video"; +"lng_in_dlg_video" = "Video file"; +"lng_in_dlg_audio_file" = "Audio file"; "lng_in_dlg_contact" = "Contatto"; -"lng_in_dlg_audio" = "Audio"; +"lng_in_dlg_audio" = "Voice message"; "lng_in_dlg_file" = "File"; "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; @@ -678,18 +680,20 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_report_spam_sure_group" = "Sei sicuro di voler segnalare dello spam in questo gruppo?"; "lng_report_spam_sure_channel" = "Sei sicuro di voler segnalare dello spam in questo canale?"; "lng_report_spam_ok" = "Segnala"; -"lng_cant_send_to_not_contact" = "Spiacenti, ma al momento puoi scrivere\nsolo ai contatti reciproci. {more_info}"; -"lng_cant_invite_not_contact" = "Spiacenti, ma al momento puoi aggiungere\nai gruppi solo contatti reciproci. {more_info}"; -"lng_cant_invite_not_contact_channel" = "Spiacenti, ma al momento puoi aggiungere\nai canali solo contatti reciproci. {more_info}"; +"lng_cant_send_to_not_contact" = "Spiacenti, ma al momento puoi scrivere\nsolo ai contatti reciproci.\n{more_info}"; +"lng_cant_invite_not_contact" = "Spiacenti, ma al momento puoi aggiungere\nai gruppi solo contatti reciproci.\n{more_info}"; +"lng_cant_invite_not_contact_channel" = "Spiacenti, ma al momento puoi aggiungere\nai canali solo contatti reciproci.\n{more_info}"; "lng_cant_more_info" = "Più info »"; +"lng_cant_invite_banned" = "Spiacenti, solo l'amministratore può aggiungere questo utente."; "lng_cant_invite_privacy" = "Spiacenti, non puoi aggiungere questo utente al gruppo a causa delle sue impostazioni di privacy."; "lng_cant_invite_privacy_channel" = "Spiacenti, non puoi aggiungere questo utente al canale a causa delle sue impostazioni di privacy."; +"lng_cant_do_this" = "Spiacenti, questa azione non è disponibile."; "lng_send_button" = "Invia"; -"lng_message_ph" = "Scrivi un messaggio.."; -"lng_comment_ph" = "Scrivi un commento.."; -"lng_broadcast_ph" = "Pubblica un post.."; -"lng_broadcast_silent_ph" = "Post silenzioso.."; +"lng_message_ph" = "Scrivi un messaggio..."; +"lng_comment_ph" = "Scrivi un commento..."; +"lng_broadcast_ph" = "Pubblica un post..."; +"lng_broadcast_silent_ph" = "Post silenzioso..."; "lng_record_cancel" = "Rilascia fuori da qui per annullare"; "lng_will_be_notified" = "I post saranno notificati ai membri"; "lng_wont_be_notified" = "I post non saranno notificati ai membri"; @@ -721,24 +725,25 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_user_action_record_video" = "{user} sta registrando un video"; "lng_send_action_upload_video" = "inviando un video"; "lng_user_action_upload_video" = "{user} sta inviando un video"; -"lng_send_action_record_audio" = "registrando un audio"; -"lng_user_action_record_audio" = "{user} sta registrando un audio"; -"lng_send_action_upload_audio" = "inviando un audio"; -"lng_user_action_upload_audio" = "{user} sta inviando un audio"; +"lng_send_action_record_audio" = "registrando un messaggio vocale"; +"lng_user_action_record_audio" = "{user} sta registrando un messaggio vocale"; +"lng_send_action_upload_audio" = "inviando un messaggio vocale"; +"lng_user_action_upload_audio" = "{user} sta inviando un messaggio vocale"; "lng_send_action_upload_photo" = "inviando una foto"; "lng_user_action_upload_photo" = "{user} sta inviando una foto"; "lng_send_action_upload_file" = "inviando un file"; "lng_user_action_upload_file" = "{user} sta inviando un file"; -"lng_send_action_geo_location" = "selezionando una posizione"; -"lng_user_action_geo_location" = "{user} sta selezionando una posizione"; -"lng_send_action_choose_contact" = "selezionando un contatto"; -"lng_user_action_choose_contact" = "{user} sta selezionando un contatto"; +"lng_send_action_geo_location" = "scegliendo una posizione"; +"lng_user_action_geo_location" = "{user} sta scegliendo una posizione"; +"lng_send_action_choose_contact" = "scegliendo un contatto"; +"lng_user_action_choose_contact" = "{user} sta scegliendo un contatto"; "lng_unread_bar" = "{count:_not_used_|# messaggio non letto|# messaggi non letti}"; "lng_maps_point" = "Posizione"; "lng_save_photo" = "Salva immagine"; -"lng_save_video" = "Salva video"; -"lng_save_audio" = "Salva audio"; +"lng_save_video" = "Save video file"; +"lng_save_audio_file" = "Save audio file"; +"lng_save_audio" = "Save voice message"; "lng_save_file" = "Salva file"; "lng_save_downloaded" = "{ready} / {total} {mb}"; "lng_duration_and_size" = "{duration}, {size}"; @@ -755,7 +760,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_copy_email" = "Copia indirizzo email"; "lng_context_copy_hashtag" = "Copia hashtag"; "lng_context_copy_mention" = "Copia username"; -"lng_context_save_image" = "Salva immagine come.."; +"lng_context_save_image" = "Salva immagine come..."; "lng_context_forward_image" = "Inoltra immagine"; "lng_context_delete_image" = "Elimina immagine"; "lng_context_copy_image" = "Copia immagine"; @@ -763,11 +768,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_cancel_download" = "Annulla download"; "lng_context_show_in_folder" = "Mostra nella cartella"; "lng_context_show_in_finder" = "Mostra nel Finder"; -"lng_context_save_video" = "Salva video come.."; -"lng_context_save_audio" = "Salva audio come.."; +"lng_context_save_video" = "Save Video File As..."; +"lng_context_save_audio_file" = "Save Audio File As..."; +"lng_context_save_audio" = "Save Voice Message As..."; "lng_context_pack_info" = "Mostra sticker"; "lng_context_pack_add" = "Aggiungi sticker"; -"lng_context_save_file" = "Salva file come.."; +"lng_context_save_file" = "Salva file come..."; "lng_context_forward_file" = "Inoltra file"; "lng_context_delete_file" = "Elimina file"; "lng_context_close_file" = "Chiudi file"; @@ -794,7 +800,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_send_image_too_large" = "Impossibile inviare il file, perchè è più grande di 1.5 GB :("; "lng_send_folder" = "Impossibile inviare «{name}» perchè è una cartella :("; -"lng_forward_choose" = "Scegli destinatario.."; +"lng_forward_choose" = "Scegli destinatario..."; "lng_forward_cant" = "Spiacenti, impossibile inoltrare qui :("; "lng_forward_confirm" = "Inoltra a {recipient}?"; "lng_forward_share_contact" = "Condividi contatto con {recipient}?"; @@ -857,7 +863,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_search_global_results" = "Risultati ricerca globale"; "lng_media_save_progress" = "{ready} di {total} {mb}"; -"lng_mediaview_save_as" = "Salva come.."; +"lng_mediaview_save_as" = "Salva come..."; "lng_mediaview_copy" = "Copia"; "lng_mediaview_forward" = "Inoltra"; "lng_mediaview_delete" = "Elimina"; diff --git a/Telegram/SourceFiles/langs/lang_ko.strings b/Telegram/SourceFiles/langs/lang_ko.strings index cf661c075..ff30db37d 100644 --- a/Telegram/SourceFiles/langs/lang_ko.strings +++ b/Telegram/SourceFiles/langs/lang_ko.strings @@ -86,8 +86,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_cancel" = "취소"; "lng_continue" = "계속"; "lng_close" = "닫기"; -"lng_connecting" = "연결중입니다.."; -"lng_reconnecting" = " {count:지금| #초 후에| #초 후에} 다시 연결합니다.."; +"lng_connecting" = "Connecting..."; +"lng_reconnecting" = "Reconnect {count:now|in # s|in # s}..."; "lng_reconnecting_try_now" = "다시 시도"; "lng_status_service_notifications" = "서비스 알림"; @@ -108,7 +108,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_status_lastseen_date" = "{date}에 마지막으로 접속"; "lng_status_lastseen_date_time" = "{date}일 {time}에 마지막으로 접속"; "lng_status_online" = "온라인"; -"lng_status_connecting" = "연결중.."; +"lng_status_connecting" = "connecting..."; "lng_chat_status_unaccessible" = "그룹 접근 불가"; "lng_chat_status_members" = "{count:맴버 없음|#명|#명}"; @@ -127,7 +127,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_edit_deleted" = "메시지는 삭제 되었습니다."; "lng_edit_too_long" = "메시지 길이가 너무 깁니다."; "lng_edit_message" = "메시지 수정"; -"lng_edit_message_text" = "새로운 메시지 내용."; +"lng_edit_message_text" = "New message text..."; "lng_deleted" = "알 수 없음"; "lng_deleted_message" = "삭제된 메시지"; "lng_pinned_message" = "고정된 메시지"; @@ -162,7 +162,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_code_telegram" = "[b]텔레그램[/b] 앱으로 부터 방금 수신받은,\n코드를 입력해주세요."; "lng_code_no_telegram" = "코드를 SMS로 전송"; "lng_code_call" = "텔레그램이 {minutes}:{seconds}후에는 전화를 겁니다."; -"lng_code_calling" = "텔레그램으로부터 전화 요청을 하고 있습니다.."; +"lng_code_calling" = "Requesting a call from Telegram..."; "lng_code_called" = "텔레그램이 회원님의 전화번호로 전화를 걸었습니다."; "lng_bad_phone" = "잘못된 전화번호입니다. 다시 시도해주세요."; @@ -201,7 +201,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_dlg_new_channel_name" = "채널명"; "lng_no_contacts" = "연락처가 없습니다."; "lng_no_chats" = "대화시 대화방이 존재 할 곳입니다."; -"lng_contacts_loading" = "로드중.."; +"lng_contacts_loading" = "Loading..."; "lng_contacts_not_found" = "연락처를 찾을 수 없음"; "lng_dlg_search_chat" = "이 채팅에서 검색"; "lng_dlg_search_channel" = "이 채널방에서 검색"; @@ -210,7 +210,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_save" = "저장"; "lng_settings_upload" = "프로필 이미지 선택"; "lng_settings_crop_profile" = "프로필 사진으로 사용할 사각영역을 선택하세요"; -"lng_settings_uploading_photo" = "사진 업로드중.."; +"lng_settings_uploading_photo" = "Uploading photo..."; "lng_username_title" = "아이디"; "lng_username_about" = "텔레그램 아이디를 설정할 수 있습니다. \n아이디를 설정하면 회원님의 전화번호를 몰라도 아이디로 회원님을 찾아 대화를 나눌 수 있습니다.\n아이디는 영문, 밑줄, 숫자로 a-z, _, 0-9, \n다섯 글자 이상으로 설정해 주세요."; @@ -247,9 +247,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_auto_update" = "자동 업데이트"; "lng_settings_current_version" = " {version}"; "lng_settings_check_now" = "업데이트 확인"; -"lng_settings_update_checking" = "업데이트 확인 중.."; +"lng_settings_update_checking" = "Checking for updates..."; "lng_settings_latest_installed" = "최신 버전이 설치되어 있습니다."; -"lng_settings_downloading" = "업데이트를 다운로드중입니다.. {ready} / {total} MB.."; +"lng_settings_downloading" = "Downloading update {ready} / {total} MB..."; "lng_settings_update_ready" = "새로운 버전을 설치 할 수 있습니다."; "lng_settings_update_now" = "재시작 합니다."; "lng_settings_update_fail" = "업데이트 확인 실패 :("; @@ -291,7 +291,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_download_path_failed" = "파일 다운로드를 시작 할 수 없습니다. 올바르지 않은 다운로드 경로가 원인 일 수도 있습니다.\n\n설정에 가시면 다운로드 경로를 변경하실 수 있습니다."; "lng_download_path_settings" = "설정"; "lng_download_finish_failed" = "파일 다운로드를 끝낼 수 없습니다.\n\n다시 시도하시겠습니까?"; -"lng_download_path_clearing" = "초기화 중.."; +"lng_download_path_clearing" = "Clearing..."; "lng_download_path_cleared" = "초기화 완료!"; "lng_download_path_clear_failed" = "초기화 실패 :("; @@ -300,7 +300,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_images_cached" = "{count:_not_used_|이미지 #개|이미지 #개}, {size}"; "lng_settings_audios_cached" = "{count:_not_used_|음성 메시지 #개|음성 메시지 #개}, {size}"; "lng_local_storage_clear" = "전체 정리"; -"lng_local_storage_clearing" = "초기화 중.."; +"lng_local_storage_clearing" = "Clearing..."; "lng_local_storage_cleared" = "초기화 완료!"; "lng_local_storage_clear_failed" = "초기화 실패 :("; @@ -331,7 +331,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_passcode_logout" = "로그아웃"; "lng_passcode_need_unblock" = "잠금코드를 먼저 해제해주세요."; -"lng_cloud_password_waiting" = "{email}로 확인 이메일을 전송하였습니다.."; +"lng_cloud_password_waiting" = "Confirmation link sent to {email}..."; "lng_cloud_password_change" = "클라우드 비밀번호 변경"; "lng_cloud_password_create" = "클라우드 비밀번호"; "lng_cloud_password_remove" = "클라우드 비밀번호 삭제"; @@ -358,9 +358,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_cloud_password_is_same" = "비밀번호가 변경되지 않았습니다."; "lng_connection_type" = "연결 유형:"; -"lng_connection_auto_connecting" = "기본값 (연결중..)"; +"lng_connection_auto_connecting" = "Default (connecting...)"; "lng_connection_auto" = "기본값 ({transport} 사용)"; -"lng_connection_proxy_connecting" = "프록시 연결 중..."; +"lng_connection_proxy_connecting" = "Connecting through proxy..."; "lng_connection_proxy" = "{transport} 프록시 연결"; "lng_connection_header" = "연결 유형"; "lng_connection_auto_rb" = "자동 (사용 가능하다면 TCP 아니면 HTTP 사용)"; @@ -396,7 +396,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_sessions_other_desc" = "동일한 휴대번호로 다른 휴대기기, 태블릿과 데스크탑에서 텔레그램 로그인이 가능합니다. 모든 데이터는 즉시 동기화 됩니다."; "lng_sessions_terminate_all" = "다른 모든 세션 강제 종료"; -"lng_preview_loading" = "링크 정보를 가져오는 중.."; +"lng_preview_loading" = "Getting Link Info..."; "lng_profile_chat_unaccessible" = "그룹에 접근할 수 없습니다."; "lng_topbar_info" = "정보"; @@ -439,7 +439,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_sure_kick" = "{user}를 추방하시겠습니까?"; "lng_profile_sure_kick_channel" = "{user}를 추방하시겠습니까?"; "lng_profile_sure_kick_admin" = "{user}를 관리자에서 제외 하시겠습니까?"; -"lng_profile_loading" = "로딩중.."; +"lng_profile_loading" = "Loading..."; "lng_profile_shared_media" = "공유된 미디어"; "lng_profile_no_media" = "대화에 미디어가 존재하지 않습니다."; "lng_profile_photos" = "{count:_not_used_|#개의 사진|#개의 사진} »"; @@ -455,6 +455,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_shared_links" = "{count:_not_used_|# 공유된 링크|# 공유된 링크} »"; "lng_profile_shared_links_header" = "공유된 링크 현황"; "lng_profile_copy_phone" = "전화번호 복사"; +"lng_profile_copy_fullname" = "Copy name"; "lng_channel_add_admins" = "새로운 관리자"; "lng_channel_add_members" = "구성원 추가"; @@ -659,12 +660,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_stickers_remove" = "삭제"; "lng_stickers_return" = "실행취소"; "lng_stickers_restore" = "복구"; -"lng_stickers_count" = "{count:Loading..|# 스티커|# 스티커} "; +"lng_stickers_count" = "{count:Loading...|# sticker|# stickers}"; "lng_in_dlg_photo" = "사진"; -"lng_in_dlg_video" = "비디오"; +"lng_in_dlg_video" = "Video file"; +"lng_in_dlg_audio_file" = "Audio file"; "lng_in_dlg_contact" = "연락처"; -"lng_in_dlg_audio" = "음성"; +"lng_in_dlg_audio" = "Voice message"; "lng_in_dlg_file" = "파일"; "lng_in_dlg_sticker" = "스티커"; "lng_in_dlg_sticker_emoji" = "{emoji} (스티커)"; @@ -678,18 +680,20 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_report_spam_sure_group" = "선택한 그룹메시지를 스팸으로 신고하시겠습니까?"; "lng_report_spam_sure_channel" = "선택한 채널메시지를 스팸으로 신고하시겠습니까?"; "lng_report_spam_ok" = "신고하기"; -"lng_cant_send_to_not_contact" = "죄송하지만, 현재 서로 연락처가 추가된\n회원들끼리만 전송이 가능합니다. {more_info}"; -"lng_cant_invite_not_contact" = "죄송하지만, 현재 서로 연락처가 추가된\n회원들끼리만 추가 가능합니다. {more_info}"; -"lng_cant_invite_not_contact_channel" = "죄송하지만, 현재 서로 연락처가 추가된\n회원들끼리만 추가 가능합니다. {more_info}"; +"lng_cant_send_to_not_contact" = "Sorry, you can only send messages to\nmutual contacts at the moment.\n{more_info}"; +"lng_cant_invite_not_contact" = "Sorry, you can only add mutual contacts\nto groups at the moment.\n{more_info}"; +"lng_cant_invite_not_contact_channel" = "Sorry, you can only add mutual contacts\nto channels at the moment.\n{more_info}"; "lng_cant_more_info" = "자세한 정보 »"; +"lng_cant_invite_banned" = "Sorry, only admin can add this user."; "lng_cant_invite_privacy" = "죄송합니다, 개인설정으로 인하여 이 사용자를 그룹에 초대할 수 없습니다."; "lng_cant_invite_privacy_channel" = "죄송합니다, 개인설정으로 인하여 이 사용자를 채널에 초대할 수 없습니다."; +"lng_cant_do_this" = "Sorry, this action is unavailable."; "lng_send_button" = "보내기"; -"lng_message_ph" = "메시지 쓰기"; -"lng_comment_ph" = "코멘트 쓰기.."; -"lng_broadcast_ph" = "단체메시지 쓰기."; -"lng_broadcast_silent_ph" = "음소거 메시지.."; +"lng_message_ph" = "Write a message..."; +"lng_comment_ph" = "Write a comment..."; +"lng_broadcast_ph" = "Broadcast a message..."; +"lng_broadcast_silent_ph" = "Silent broadcast..."; "lng_record_cancel" = "이 영역 밖에서 마우스 클릭을 해제하시면 취소가 됩니다."; "lng_will_be_notified" = "메시지 작성시 구성원들에게 알림이 갑니다."; "lng_wont_be_notified" = "메시지 작성시 구성원들에게 알림이 가지 않습니다."; @@ -717,28 +721,29 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_user_typing" = "{user}님이 입력중입니다."; "lng_users_typing" = "{user}님과 {second_user}님이 입력중입니다."; "lng_many_typing" = "{count:_not_used_|#명이|#명이} 입력중입니다"; -"lng_send_action_record_video" = "비디오 녹화 중"; -"lng_user_action_record_video" = "{user}님이 녹화중입니다."; -"lng_send_action_upload_video" = "비디오 전송 중"; -"lng_user_action_upload_video" = "{user}님이 비디오를 전송 중입니다."; -"lng_send_action_record_audio" = "오디오 녹음 중"; -"lng_user_action_record_audio" = "{user}님이 오디오를 녹음 중입니다."; -"lng_send_action_upload_audio" = "오디오 전송 중"; -"lng_user_action_upload_audio" = "{user}님이 오디오를 전송 중입니다."; -"lng_send_action_upload_photo" = "사진 전송 중"; -"lng_user_action_upload_photo" = "{user}님이 사진을 전송 중입니다."; -"lng_send_action_upload_file" = "파일을 전송 중"; -"lng_user_action_upload_file" = "{user}님이 사진을 전송 중입니다."; -"lng_send_action_geo_location" = "위치 선택 중"; -"lng_user_action_geo_location" = "{user}님이 위치를 선택 중입니다."; -"lng_send_action_choose_contact" = "연락처 선택 중"; -"lng_user_action_choose_contact" = "{user}님이 연락처를 선택 중입니다."; +"lng_send_action_record_video" = "recording a video"; +"lng_user_action_record_video" = "{user} is recording a video"; +"lng_send_action_upload_video" = "sending a video"; +"lng_user_action_upload_video" = "{user} is sending a video"; +"lng_send_action_record_audio" = "recording a voice message"; +"lng_user_action_record_audio" = "{user} is recording a voice message"; +"lng_send_action_upload_audio" = "sending a voice message"; +"lng_user_action_upload_audio" = "{user} is sending a voice message"; +"lng_send_action_upload_photo" = "sending a photo"; +"lng_user_action_upload_photo" = "{user} is sending a photo"; +"lng_send_action_upload_file" = "sending a file"; +"lng_user_action_upload_file" = "{user} is sending a file"; +"lng_send_action_geo_location" = "picking a location"; +"lng_user_action_geo_location" = "{user} is picking a location"; +"lng_send_action_choose_contact" = "choosing a contact"; +"lng_user_action_choose_contact" = "{user} is choosing a contact"; "lng_unread_bar" = "{count:_not_used_|#개의 읽지 않은 메시지|#개의 읽지 않은 메시지}"; "lng_maps_point" = "위치"; "lng_save_photo" = "사진 저장"; -"lng_save_video" = "동영상 저장"; -"lng_save_audio" = "음성 저장"; +"lng_save_video" = "Save video file"; +"lng_save_audio_file" = "Save audio file"; +"lng_save_audio" = "Save voice message"; "lng_save_file" = "파일 저장"; "lng_save_downloaded" = "{ready} / {total} {mb}"; "lng_duration_and_size" = "{duration}, {size}"; @@ -755,7 +760,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_copy_email" = "이메일 복사"; "lng_context_copy_hashtag" = "해시태그 복사"; "lng_context_copy_mention" = "아이디 복사"; -"lng_context_save_image" = "이미지를 다른 이름으로 저장.."; +"lng_context_save_image" = "Save Image As..."; "lng_context_forward_image" = "이미지 전달"; "lng_context_delete_image" = "이미지 삭제"; "lng_context_copy_image" = "이미지 복사"; @@ -763,11 +768,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_cancel_download" = "다운로드 취소"; "lng_context_show_in_folder" = "탐색기에서 보기"; "lng_context_show_in_finder" = "탐색기에서 보기"; -"lng_context_save_video" = "비디오 이름을 다른이름으로 저장."; -"lng_context_save_audio" = "음성메시지를 다른 이름으로 저장.."; +"lng_context_save_video" = "Save Video File As..."; +"lng_context_save_audio_file" = "Save Audio File As..."; +"lng_context_save_audio" = "Save Voice Message As..."; "lng_context_pack_info" = "팩 정보"; "lng_context_pack_add" = "스티커 추가"; -"lng_context_save_file" = "파일을 다른 이름으로 저장.."; +"lng_context_save_file" = "Save File As..."; "lng_context_forward_file" = "파일 전달"; "lng_context_delete_file" = "파일 삭제"; "lng_context_close_file" = "파일 닫기"; @@ -794,7 +800,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_send_image_too_large" = "파일이 1.5GB 보다 큼으로 전송 할 수 없습니다 :("; "lng_send_folder" = " «{name}»은 폴더이기 때문에 전송 할 수 없습니다 :("; -"lng_forward_choose" = "수신자를 선택하세요.."; +"lng_forward_choose" = "Choose recipient..."; "lng_forward_cant" = "이쪽으로 전달 할 수 없습니다 :("; "lng_forward_confirm" = "{recipient} 님에게 전달하시겠습니까?"; "lng_forward_share_contact" = "{recipient} 님에게 연락처를 공유하시겠습니까?"; @@ -857,7 +863,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_search_global_results" = "아이디 검색 결과"; "lng_media_save_progress" = "{ready} / {total} {mb}"; -"lng_mediaview_save_as" = "다른 이름으로 저장하기"; +"lng_mediaview_save_as" = "Save As..."; "lng_mediaview_copy" = "복사하기"; "lng_mediaview_forward" = "전달"; "lng_mediaview_delete" = "삭제"; diff --git a/Telegram/SourceFiles/langs/lang_nl.strings b/Telegram/SourceFiles/langs/lang_nl.strings index 801c4b822..635693b07 100644 --- a/Telegram/SourceFiles/langs/lang_nl.strings +++ b/Telegram/SourceFiles/langs/lang_nl.strings @@ -86,8 +86,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_cancel" = "Annuleren"; "lng_continue" = "Doorgaan"; "lng_close" = "Sluiten"; -"lng_connecting" = "Verbinden"; -"lng_reconnecting" = "Opnieuw verbinden {count:nu|over # s|over # s}"; +"lng_connecting" = "Verbinden..."; +"lng_reconnecting" = "Opnieuw verbinden {count:nu|over # s|over # s}..."; "lng_reconnecting_try_now" = "Probeer nu"; "lng_status_service_notifications" = "servicemeldingen"; @@ -108,7 +108,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_status_lastseen_date" = "laatst gezien {date}"; "lng_status_lastseen_date_time" = "laatst gezien {date} om {time}"; "lng_status_online" = "online"; -"lng_status_connecting" = "verbinden"; +"lng_status_connecting" = "verbinden..."; "lng_chat_status_unaccessible" = "groep is ontoegankelijk"; "lng_chat_status_members" = "{count:geen leden|# lid|# leden}"; @@ -162,7 +162,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_code_telegram" = "Voer de code in die je zojuist\nhebt ontvangen in je vorige [b]Telegram[/b]-app."; "lng_code_no_telegram" = "Verstuur code via SMS"; "lng_code_call" = "Telegram belt je over {minutes}:{seconds}"; -"lng_code_calling" = "Oproepverzoek versturen naar Telegram"; +"lng_code_calling" = "Oproepverzoek naar Telegram..."; "lng_code_called" = "Telegram heeft je nummer gebeld"; "lng_bad_phone" = "Ongeldig telefoonnummer. \nProbeer het opnieuw."; @@ -201,7 +201,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_dlg_new_channel_name" = "Kanaalnaam"; "lng_no_contacts" = "Je hebt geen contacten"; "lng_no_chats" = "Hier komen je chats"; -"lng_contacts_loading" = "Bezig met laden"; +"lng_contacts_loading" = "Laden..."; "lng_contacts_not_found" = "Geen contacten gevonden"; "lng_dlg_search_chat" = "Zoek in deze chat"; "lng_dlg_search_channel" = "Zoek in dit kanaal"; @@ -210,7 +210,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_save" = "Opslaan"; "lng_settings_upload" = "Profielfoto instellen"; "lng_settings_crop_profile" = "Kies een vierkant voor je profielfoto"; -"lng_settings_uploading_photo" = "Foto uploaden"; +"lng_settings_uploading_photo" = "Foto uploaden..."; "lng_username_title" = "Gebruikersnaam"; "lng_username_about" = "Je kunt hier je gebruikersnaam kiezen. \nHiermee kunnen anderen je vinden \nen contact met je opnemen zonder \nje telefoonnummer te weten.\n\na-z, 0-9 en underscore is toegestaan. \nDe minimale lengte is 5 tekens."; @@ -247,9 +247,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_auto_update" = "Automatisch bijwerken"; "lng_settings_current_version" = "Versie {version}"; "lng_settings_check_now" = "Controleer op updates"; -"lng_settings_update_checking" = "Op updates controleren"; +"lng_settings_update_checking" = "Controleren op updates..."; "lng_settings_latest_installed" = "Meest recente versie is geïnstalleerd."; -"lng_settings_downloading" = "Update downloaden {ready} / {total} MB"; +"lng_settings_downloading" = "Update downloaden {ready} / {total} MB..."; "lng_settings_update_ready" = "Nieuwe versie staat klaar"; "lng_settings_update_now" = "Nu herstarten"; "lng_settings_update_fail" = "Controleren op updates mislukt"; @@ -291,7 +291,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_download_path_failed" = "Download kon niet worden gestart. De oorzaak kan een ongeldige downloadmap zijn.\n\nJe kunt de map aanpassen via instellingen."; "lng_download_path_settings" = "Instellingen"; "lng_download_finish_failed" = "Downloaden mislukt.\n\nWil je het opnieuw proberen?"; -"lng_download_path_clearing" = "Wissen"; +"lng_download_path_clearing" = "Wissen..."; "lng_download_path_cleared" = "Gewist!"; "lng_download_path_clear_failed" = "Wissen mislukt"; @@ -300,7 +300,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_images_cached" = "{count:_not_used_|# afbeelding|# afbeeldingen}, {size}"; "lng_settings_audios_cached" = "{count:_not_used_|# spraakbericht|# spraakberichten}, {size}"; "lng_local_storage_clear" = "Alles wissen"; -"lng_local_storage_clearing" = "Wissen"; +"lng_local_storage_clearing" = "Wissen..."; "lng_local_storage_cleared" = "Gewist!"; "lng_local_storage_clear_failed" = "Wissen mislukt"; @@ -358,9 +358,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_cloud_password_is_same" = "Wachtwoord is niet gewijzigd"; "lng_connection_type" = "Verbindingstype:"; -"lng_connection_auto_connecting" = "Standaard (verbinden)"; +"lng_connection_auto_connecting" = "Standaard (verbinden...)"; "lng_connection_auto" = "Standaard ({transport} wordt gebruikt)"; -"lng_connection_proxy_connecting" = "Verbinden via proxy.."; +"lng_connection_proxy_connecting" = "Verbinden via proxy..."; "lng_connection_proxy" = "{transport} met proxy"; "lng_connection_header" = "Verbindingstype"; "lng_connection_auto_rb" = "Auto (TCP indien beschikbaar of HTTP)"; @@ -439,7 +439,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_sure_kick" = "{user} uit de groep verwijderen?"; "lng_profile_sure_kick_channel" = "{user} uit het kanaal verwijderen?"; "lng_profile_sure_kick_admin" = "{user} ontslaan als beheerder?"; -"lng_profile_loading" = "Bezig met laden"; +"lng_profile_loading" = "Laden..."; "lng_profile_shared_media" = "Gedeelde media"; "lng_profile_no_media" = "Geen media in deze chat."; "lng_profile_photos" = "{count:_not_used_|# foto|# foto's} »"; @@ -455,6 +455,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_shared_links" = "{count:_not_used_|# gedeelde link|# gedeelde links} »"; "lng_profile_shared_links_header" = "Links-overzicht"; "lng_profile_copy_phone" = "Telefoonnummer kopiëren"; +"lng_profile_copy_fullname" = "Naam kopiëren"; "lng_channel_add_admins" = "Beheerder toevoegen"; "lng_channel_add_members" = "Leden toevoegen"; @@ -662,9 +663,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_stickers_count" = "{count:Laden..|# sticker|# stickers}"; "lng_in_dlg_photo" = "Foto"; -"lng_in_dlg_video" = "Video"; +"lng_in_dlg_video" = "Video file"; +"lng_in_dlg_audio_file" = "Audio file"; "lng_in_dlg_contact" = "Contact"; -"lng_in_dlg_audio" = "Geluidsbestand"; +"lng_in_dlg_audio" = "Voice message"; "lng_in_dlg_file" = "Bestand"; "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; @@ -678,18 +680,20 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_report_spam_sure_group" = "Spam van deze groep echt melden?"; "lng_report_spam_sure_channel" = "Spam van dit kanaal echt melden?"; "lng_report_spam_ok" = "Melden"; -"lng_cant_send_to_not_contact" = "Op dit moment kun je alleen berichten\nversturen naar onderlinge contacten. {more_info}"; -"lng_cant_invite_not_contact" = "Op dit moment kun je alleen onderlinge\ncontacten aan groepen toevoegen. {more_info}"; +"lng_cant_send_to_not_contact" = "Je kunt momenteel alleen berichten\nversturen naar onderlinge contacten.\n{more_info}"; +"lng_cant_invite_not_contact" = "Je kunt momenteel alleen onderlinge\ncontacten aan kanalen toevoegen.\n{more_info}"; "lng_cant_invite_not_contact_channel" = "Je kunt momenteel alleen onderlinge\ncontacten aan kanalen toevoegen.\n{more_info}"; "lng_cant_more_info" = "Meer informatie »"; +"lng_cant_invite_banned" = "Alleen beheerders kunnen deze gebruiker toevoegen."; "lng_cant_invite_privacy" = "Je kunt deze gebruiker niet toevoegen aan groepen door zijn/haar privacyinstellingen."; "lng_cant_invite_privacy_channel" = "Je kunt deze gebruiker niet toevoegen aan kanalen door zijn/haar privacyinstellingen."; +"lng_cant_do_this" = "Deze actie is niet beschikbaar."; "lng_send_button" = "Stuur"; -"lng_message_ph" = "Bericht schrijven"; -"lng_comment_ph" = "Reactie"; -"lng_broadcast_ph" = "Massabericht"; -"lng_broadcast_silent_ph" = "Stil massabericht.."; +"lng_message_ph" = "Bericht..."; +"lng_comment_ph" = "Reactie..."; +"lng_broadcast_ph" = "Massabericht..."; +"lng_broadcast_silent_ph" = "Stil massabericht..."; "lng_record_cancel" = "Annuleren: uit het vak loslaten"; "lng_will_be_notified" = "Berichtgeving voor leden"; "lng_wont_be_notified" = "Geen berichtgeving voor leden"; @@ -721,14 +725,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_user_action_record_video" = "{user} neemt video op"; "lng_send_action_upload_video" = "video versturen"; "lng_user_action_upload_video" = "{user} verstuurt video"; -"lng_send_action_record_audio" = "geluid opnemen"; -"lng_user_action_record_audio" = "{user} neemt geluid op"; -"lng_send_action_upload_audio" = "geluid versturen"; -"lng_user_action_upload_audio" = "{user} verstuurt geluid"; +"lng_send_action_record_audio" = "spraakbericht opnemen"; +"lng_user_action_record_audio" = "{user} neemt spraakbericht op"; +"lng_send_action_upload_audio" = "spraakbericht versturen"; +"lng_user_action_upload_audio" = "{user} verstuurt spraakbericht"; "lng_send_action_upload_photo" = "foto versturen"; "lng_user_action_upload_photo" = "{user} verstuurt een foto"; "lng_send_action_upload_file" = "bestand versturen"; -"lng_user_action_upload_file" = "{user} verstuurt een bestand"; +"lng_user_action_upload_file" = "{user} verstuurt bestand"; "lng_send_action_geo_location" = "locatie kiezen"; "lng_user_action_geo_location" = "{user} kiest een locatie"; "lng_send_action_choose_contact" = "contact kiezen"; @@ -737,8 +741,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_maps_point" = "Locatie"; "lng_save_photo" = "Afbeelding opslaan"; -"lng_save_video" = "Video opslaan"; -"lng_save_audio" = "Geluidsbestand opslaan"; +"lng_save_video" = "Save video file"; +"lng_save_audio_file" = "Save audio file"; +"lng_save_audio" = "Save voice message"; "lng_save_file" = "Bestand opslaan"; "lng_save_downloaded" = "{ready} / {total} {mb}"; "lng_duration_and_size" = "{duration}, {size}"; @@ -755,7 +760,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_copy_email" = "E-mailadres kopiëren"; "lng_context_copy_hashtag" = "Hashtag kopiëren"; "lng_context_copy_mention" = "Gebruikersnaam kopiëren"; -"lng_context_save_image" = "Afbeelding opslaan als"; +"lng_context_save_image" = "Afbeelding opslaan als..."; "lng_context_forward_image" = "Afbeelding doorsturen"; "lng_context_delete_image" = "Afbeelding verwijderen"; "lng_context_copy_image" = "Afbeelding kopiëren"; @@ -763,11 +768,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_cancel_download" = "Download annuleren"; "lng_context_show_in_folder" = "Weergeven in map"; "lng_context_show_in_finder" = "Weergeven in Finder"; -"lng_context_save_video" = "Video opslaan als"; -"lng_context_save_audio" = "Geluidsbestand opslaan als"; +"lng_context_save_video" = "Save Video File As..."; +"lng_context_save_audio_file" = "Save Audio File As..."; +"lng_context_save_audio" = "Save Voice Message As..."; "lng_context_pack_info" = "Bundelinformatie"; "lng_context_pack_add" = "Stickers toevoegen"; -"lng_context_save_file" = "Bestand opslaan als"; +"lng_context_save_file" = "Bestand opslaan als..."; "lng_context_forward_file" = "Bestand doorsturen"; "lng_context_delete_file" = "Bestand verwijderen"; "lng_context_close_file" = "Bestand sluiten"; @@ -794,7 +800,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_send_image_too_large" = "Dit bestand is groter dan 1,5 GB en kan niet worden verstuurd :("; "lng_send_folder" = "Kan de map «{name}» niet versturen, kies een bestand. :("; -"lng_forward_choose" = "Ontvanger kiezen"; +"lng_forward_choose" = "Ontvanger kiezen..."; "lng_forward_cant" = "Sorry, doorsturen hierheen kan niet :("; "lng_forward_confirm" = "Doorsturen naar {recipient}?"; "lng_forward_share_contact" = "Contact delen met {recipient}?"; @@ -857,7 +863,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_search_global_results" = "Wereldwijde zoekresultaten"; "lng_media_save_progress" = "{ready} van {total} {mb}"; -"lng_mediaview_save_as" = "Opslaan als"; +"lng_mediaview_save_as" = "Opslaan als..."; "lng_mediaview_copy" = "Kopiëren"; "lng_mediaview_forward" = "Doorsturen"; "lng_mediaview_delete" = "Verwijder"; diff --git a/Telegram/SourceFiles/langs/lang_pt_BR.strings b/Telegram/SourceFiles/langs/lang_pt_BR.strings index e0e255d99..cf8b4082e 100644 --- a/Telegram/SourceFiles/langs/lang_pt_BR.strings +++ b/Telegram/SourceFiles/langs/lang_pt_BR.strings @@ -87,7 +87,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_continue" = "Continuar"; "lng_close" = "Fechar"; "lng_connecting" = "Conectando..."; -"lng_reconnecting" = "Reconectar {count:agora|em # s|em # s}.."; +"lng_reconnecting" = "Reconectar {count:agora|em # s|em # s}..."; "lng_reconnecting_try_now" = "Tentar agora"; "lng_status_service_notifications" = "notificações de serviço"; @@ -127,7 +127,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_edit_deleted" = "Essa mensagem foi apagada"; "lng_edit_too_long" = "Sua mensagem está muito longa"; "lng_edit_message" = "Editar mensagem"; -"lng_edit_message_text" = "Nova mensagem..."; +"lng_edit_message_text" = "Nova mensagem de texto..."; "lng_deleted" = "Desconhecido"; "lng_deleted_message" = "Mensagem apagada"; "lng_pinned_message" = "Mensagem fixada"; @@ -201,7 +201,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_dlg_new_channel_name" = "Nome do canal"; "lng_no_contacts" = "Você não possui contatos"; "lng_no_chats" = "Seus chats estarão aqui"; -"lng_contacts_loading" = "Carregando.."; +"lng_contacts_loading" = "Carregando..."; "lng_contacts_not_found" = "Nenhum contato encontrado"; "lng_dlg_search_chat" = "Buscar nesse chat"; "lng_dlg_search_channel" = "Buscar nesse canal"; @@ -210,7 +210,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_save" = "Salvar"; "lng_settings_upload" = "Definir Foto de Perfil"; "lng_settings_crop_profile" = "Selecione uma área para a foto do perfil"; -"lng_settings_uploading_photo" = "Carregando foto.."; +"lng_settings_uploading_photo" = "Carregando foto..."; "lng_username_title" = "Nome de usuário"; "lng_username_about" = "Você pode escolher um nome de usuário no Telegram.\nAssim, outras pessoas poderão te encontrar\npelo nome de usuário e entrar em contato\nsem precisar saber seu telefone.\n\nVocê pode usar a-z, 0-9 e underline.\nO tamanho mínimo é 5 caracteres."; @@ -247,9 +247,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_auto_update" = "Atualizar automaticamente"; "lng_settings_current_version" = "Versão {version}"; "lng_settings_check_now" = "Verificar atualizações"; -"lng_settings_update_checking" = "Verificando atualizações"; +"lng_settings_update_checking" = "Verificando atualizações..."; "lng_settings_latest_installed" = "Última versão está instalada"; -"lng_settings_downloading" = "Baixando atualização {ready} / {total} MB.."; +"lng_settings_downloading" = "Baixando atualização {ready} / {total} MB..."; "lng_settings_update_ready" = "Nova versão está pronta"; "lng_settings_update_now" = "Reiniciar Agora"; "lng_settings_update_fail" = "Verificação de atualização falhou :("; @@ -291,7 +291,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_download_path_failed" = "Download do arquivo não pôde iniciar. Isso pode ter acontecido por um problema na pasta de downlaod.\n\nVocê pode alterar o caminho dos downloads em Configurações."; "lng_download_path_settings" = "Configurações"; "lng_download_finish_failed" = "Arquivo baixado não pôde ser finalizado.\n\nGostaria de tentar novamente?"; -"lng_download_path_clearing" = "Limpando.."; +"lng_download_path_clearing" = "Limpando..."; "lng_download_path_cleared" = "Concluído!"; "lng_download_path_clear_failed" = "Limpeza falhou :("; @@ -300,7 +300,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_images_cached" = "{count:_not_used_|# imagem|# imagens}, {size}"; "lng_settings_audios_cached" = "{count:_not_used_|# mensagem de voz|# mensagens de voz}, {size}"; "lng_local_storage_clear" = "Limpar tudo"; -"lng_local_storage_clearing" = "Limpando.."; +"lng_local_storage_clearing" = "Limpando..."; "lng_local_storage_cleared" = "Concluído!"; "lng_local_storage_clear_failed" = "Limpeza falhou :("; @@ -331,7 +331,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_passcode_logout" = "Sair"; "lng_passcode_need_unblock" = "Você precisa me desbloquear primeiro."; -"lng_cloud_password_waiting" = "Link de confirmação enviado para {email}.."; +"lng_cloud_password_waiting" = "Link de confirmação enviado para {email}..."; "lng_cloud_password_change" = "Alterar senha da nuvem"; "lng_cloud_password_create" = "Senha da nuvem"; "lng_cloud_password_remove" = "Remover senha da nuvem"; @@ -358,7 +358,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_cloud_password_is_same" = "Senha não alterada"; "lng_connection_type" = "Tipo de conexão:"; -"lng_connection_auto_connecting" = "Padrão (conectando..)"; +"lng_connection_auto_connecting" = "Padrão (conectando...)"; "lng_connection_auto" = "Padrão ({transport} usado)"; "lng_connection_proxy_connecting" = "Conectando via proxy..."; "lng_connection_proxy" = "{transport} com proxy"; @@ -396,7 +396,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_sessions_other_desc" = "Você pode entrar no Telegram de outro celular, tablet e computadores, usando o mesmo número de telefone. Todos seus dados estarão sincronizados."; "lng_sessions_terminate_all" = "Encerrar todas as outras sessões"; -"lng_preview_loading" = "Obtendo informações.."; +"lng_preview_loading" = "Obtendo Informações do Link..."; "lng_profile_chat_unaccessible" = "Grupo inacessível"; "lng_topbar_info" = "Info"; @@ -439,7 +439,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_sure_kick" = "Remover {user} do grupo?"; "lng_profile_sure_kick_channel" = "Remover {user} do canal?"; "lng_profile_sure_kick_admin" = "Remover {user} dos administradores?"; -"lng_profile_loading" = "Carregando.."; +"lng_profile_loading" = "Carregando..."; "lng_profile_shared_media" = "Mídia compartilhada"; "lng_profile_no_media" = "Nenhuma mídia nessa conversa."; "lng_profile_photos" = "{count:_not_used_|# foto|# fotos} »"; @@ -455,6 +455,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_shared_links" = "{count:_not_used_|# link|# links} »"; "lng_profile_shared_links_header" = "Links"; "lng_profile_copy_phone" = "Copiar número de telefone"; +"lng_profile_copy_fullname" = "Copiar nome"; "lng_channel_add_admins" = "Novo administrador"; "lng_channel_add_members" = "Adicionar membros"; @@ -659,12 +660,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_stickers_remove" = "Remover"; "lng_stickers_return" = "Desfazer"; "lng_stickers_restore" = "Restaurar"; -"lng_stickers_count" = "{count:Carregando..|# sticker|# stickers}"; +"lng_stickers_count" = "{count:Carregando...|# sticker|# stickers}"; "lng_in_dlg_photo" = "Foto"; -"lng_in_dlg_video" = "Vídeo"; +"lng_in_dlg_video" = "Video file"; +"lng_in_dlg_audio_file" = "Audio file"; "lng_in_dlg_contact" = "Contato"; -"lng_in_dlg_audio" = "Áudio"; +"lng_in_dlg_audio" = "Voice message"; "lng_in_dlg_file" = "Arquivo"; "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; @@ -678,18 +680,20 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_report_spam_sure_group" = "Tem certeza que deseja reportar spam desse grupo?"; "lng_report_spam_sure_channel" = "Tem certeza que deseja reportar spam desse canal?"; "lng_report_spam_ok" = "Reportar"; -"lng_cant_send_to_not_contact" = "Você só pode enviar mensagens para\ncontatos mútuos no momento. {more_info}"; -"lng_cant_invite_not_contact" = "Você só pode adicionar contatos\nmútuos ao grupo no momento. {more_info}"; -"lng_cant_invite_not_contact_channel" = "Desculpe, você só pode adicionar contatos\nmútuos para canais no momento. {more_info}"; +"lng_cant_send_to_not_contact" = "Desculpe, você só pode enviar mensagens\npara contatos mútuos no momento.\n{more_info}"; +"lng_cant_invite_not_contact" = "Desculpe, no momento você só pode adicionar\ncontatos mútuos em grupos.\n{more_info}"; +"lng_cant_invite_not_contact_channel" = "Desculpe, no momento você só pode adicionar\ncontatos mútuos nos canais.\n{more_info}"; "lng_cant_more_info" = "Informações »"; +"lng_cant_invite_banned" = "Apenas um administrador pode adicionar esse usuário."; "lng_cant_invite_privacy" = "Você não pode adicionar esse usuário em grupos devido as configurações de privacidade."; "lng_cant_invite_privacy_channel" = "Você não pode adicionar esse usuário em canais devido as configurações de privacidade."; +"lng_cant_do_this" = "Essa ação não está disponível."; "lng_send_button" = "Enviar"; -"lng_message_ph" = "Escrever a mensagem.."; +"lng_message_ph" = "Escrever uma mensagem..."; "lng_comment_ph" = "Escreva um comentário..."; -"lng_broadcast_ph" = "Transmitir a mensagem..."; -"lng_broadcast_silent_ph" = "Silenciar transmissão..."; +"lng_broadcast_ph" = "Transmitir uma mensagem..."; +"lng_broadcast_silent_ph" = "Transmissão silenciosa..."; "lng_record_cancel" = "Solte fora desse campo para cancelar"; "lng_will_be_notified" = "Os membros serão notificados quando você postar"; "lng_wont_be_notified" = "Os membros não serão notificados quando você postar"; @@ -717,28 +721,29 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_user_typing" = "{user} está escrevendo"; "lng_users_typing" = "{user} e {second_user} estão escrevendo"; "lng_many_typing" = "{count:_not_used_|# está|# estão} escrevendo"; -"lng_send_action_record_video" = "gravando vídeo"; -"lng_user_action_record_video" = "{user} está gravando vídeo"; -"lng_send_action_upload_video" = "enviando vídeo"; -"lng_user_action_upload_video" = "{user} está enviando vídeo"; -"lng_send_action_record_audio" = "gravando áudio"; -"lng_user_action_record_audio" = "{user} está gravando áudio"; -"lng_send_action_upload_audio" = "enviando áudio"; -"lng_user_action_upload_audio" = "{user} está gravando áudio"; -"lng_send_action_upload_photo" = "enviando foto"; -"lng_user_action_upload_photo" = "{user} está enviando foto"; -"lng_send_action_upload_file" = "enviando arquivo"; -"lng_user_action_upload_file" = "{user} está enviando arquivo"; -"lng_send_action_geo_location" = "escolhendo local"; -"lng_user_action_geo_location" = "{user} está escolhendo local"; -"lng_send_action_choose_contact" = "escolhendo contato"; -"lng_user_action_choose_contact" = "{user} está escolhendo contato"; +"lng_send_action_record_video" = "gravando um vídeo"; +"lng_user_action_record_video" = "{user} está gravando um vídeo"; +"lng_send_action_upload_video" = "enviando um vídeo"; +"lng_user_action_upload_video" = "{user} está enviando um vídeo"; +"lng_send_action_record_audio" = "gravando uma mensagem de voz"; +"lng_user_action_record_audio" = "{user} está gravando um áudio"; +"lng_send_action_upload_audio" = "enviando uma mensagem de voz"; +"lng_user_action_upload_audio" = "{user} está enviando um áudio"; +"lng_send_action_upload_photo" = "enviando uma foto"; +"lng_user_action_upload_photo" = "{user} está enviando uma foto"; +"lng_send_action_upload_file" = "enviando um arquivo"; +"lng_user_action_upload_file" = "{user} está enviando um arquivo"; +"lng_send_action_geo_location" = "escolhendo uma localização"; +"lng_user_action_geo_location" = "{user} está escolhendo uma localização"; +"lng_send_action_choose_contact" = "escolhendo um contato"; +"lng_user_action_choose_contact" = "{user} está escolhendo um contato"; "lng_unread_bar" = "{count:_not_used_|# mensagem não lida|# mensagens não lidas}"; "lng_maps_point" = "Localização"; "lng_save_photo" = "Salvar imagem"; -"lng_save_video" = "Salvar vídeo"; -"lng_save_audio" = "Salvar áudio"; +"lng_save_video" = "Save video file"; +"lng_save_audio_file" = "Save audio file"; +"lng_save_audio" = "Save voice message"; "lng_save_file" = "Salvar arquivo"; "lng_save_downloaded" = "{ready} / {total} {mb}"; "lng_duration_and_size" = "{duration}, {size}"; @@ -755,7 +760,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_copy_email" = "Copiar endereço de email"; "lng_context_copy_hashtag" = "Copiar hashtag"; "lng_context_copy_mention" = "Copiar nome de usuário"; -"lng_context_save_image" = "Salvar Imagem Como.."; +"lng_context_save_image" = "Salvar Imagem Como..."; "lng_context_forward_image" = "Encaminhar Imagem"; "lng_context_delete_image" = "Apagar Imagem"; "lng_context_copy_image" = "Copiar Imagem"; @@ -763,11 +768,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_cancel_download" = "Cancelar Download"; "lng_context_show_in_folder" = "Mostrar na Pasta"; "lng_context_show_in_finder" = "Mostrar no Finder"; -"lng_context_save_video" = "Salvar Vídeo Como.."; -"lng_context_save_audio" = "Salvar Áudio Como.."; +"lng_context_save_video" = "Save Video File As..."; +"lng_context_save_audio_file" = "Save Audio File As..."; +"lng_context_save_audio" = "Save Voice Message As..."; "lng_context_pack_info" = "Informação do pacote"; "lng_context_pack_add" = "Adicionar aos Stickers"; -"lng_context_save_file" = "Salvar Arquivo Como.."; +"lng_context_save_file" = "Salvar Arquivo Como..."; "lng_context_forward_file" = "Encaminhar Arquivo"; "lng_context_delete_file" = "Apagar Arquivo"; "lng_context_close_file" = "Fechar Arquivo"; @@ -794,7 +800,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_send_image_too_large" = "Não pude enviar, o arquivo é maior que 1.5GB :("; "lng_send_folder" = "Não pude enviar «{name}» porque é um diretório :("; -"lng_forward_choose" = "Escolher recipiente.."; +"lng_forward_choose" = "Escolher recipiente..."; "lng_forward_cant" = "Desculpe, não há como encaminhar aqui :("; "lng_forward_confirm" = "Encaminhar para {recipient}?"; "lng_forward_share_contact" = "Compartilhar contato com {recipient}?"; @@ -857,7 +863,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_search_global_results" = "Resultados da busca global"; "lng_media_save_progress" = "{ready} de {total} {mb}"; -"lng_mediaview_save_as" = "Salvar Como.."; +"lng_mediaview_save_as" = "Salvar Como..."; "lng_mediaview_copy" = "Copiar"; "lng_mediaview_forward" = "Encaminhar"; "lng_mediaview_delete" = "Apagar";