diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index 7d8eddad43..79aee3ad76 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -498,7 +498,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_sure_delete_group" = "Are you sure, you want to delete this group? All members will be removed and all messages will be lost."; "lng_message_empty" = "Empty Message"; -"lng_media_unsupported" = "Media Unsupported"; +"lng_message_unsupported" = "This message is not supported by your version of Telegram Desktop. Please update to the last version in Settings or install it from {link}"; "lng_action_add_user" = "{from} added {user}"; "lng_action_add_users_many" = "{from} added {users}"; @@ -600,6 +600,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_saved_gifs" = "Saved GIFs"; "lng_inline_bot_results" = "Results from {inline_bot}"; "lng_inline_bot_no_results" = "No results"; +"lng_inline_bot_via" = "via {inline_bot}"; "lng_box_remove" = "Remove"; @@ -793,7 +794,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_selected_delete" = "Delete"; "lng_selected_forward" = "Forward"; "lng_selected_count" = "{count:_not_used_|# message|# messages}"; -"lng_selected_cancel_sure_this" = "Do you want to cancel this upload?"; +"lng_selected_cancel_sure_this" = "Cancel uploading?"; +"lng_selected_upload_stop" = "Stop"; "lng_selected_delete_sure_this" = "Do you want to delete this message?"; "lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?"; "lng_box_delete" = "Delete"; diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp index fb8401019e..ac47b58e4d 100644 --- a/Telegram/SourceFiles/gui/text.cpp +++ b/Telegram/SourceFiles/gui/text.cpp @@ -263,7 +263,7 @@ const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink) class TextParser { public: - + static Qt::LayoutDirection stringDirection(const QString &str, int32 from, int32 to) { const ushort *p = reinterpret_cast(str.unicode()) + from; const ushort *end = p + (to - from); @@ -340,7 +340,7 @@ public: void getLinkData(const QString &original, QString &result, int32 &fullDisplayed) { if (!original.isEmpty() && original.at(0) == '/') { result = original; - fullDisplayed = -4; // bot command + fullDisplayed = -4; // bot command } else if (!original.isEmpty() && original.at(0) == '@') { result = original; fullDisplayed = -3; // mention @@ -454,7 +454,7 @@ public: while (waitingEntity != entitiesEnd && waitingEntity->length <= 0) ++waitingEntity; } } - + bool readCommand() { const QChar *afterCmd = textSkipCommand(ptr, end, links.size() < 0x7FFF); if (afterCmd == ptr) { @@ -975,7 +975,7 @@ public: void initParagraphBidi() { if (!_parLength || !_parAnalysis.isEmpty()) return; - + Text::TextBlocks::const_iterator i = _parStartBlock, e = _t->_blocks.cend(), n = i + 1; bool ignore = false; @@ -1340,7 +1340,7 @@ public: *_getSymbolAfter = false; *_getSymbolUpon = ((_lnkX >= _x) && (_lineStart > 0)) ? true : false; } - return false; + return false; } else if (_lnkX >= x + (_w - _wLeft)) { if (_parDirection == Qt::RightToLeft) { *_getSymbol = _lineStart; @@ -2428,7 +2428,7 @@ private: style::font _f; QFixed _x, _w, _wLeft; int32 _y, _yDelta, _lineHeight, _fontHeight; - + // elided hack support int32 _blocksSize; int32 _elideSavedIndex; @@ -2913,7 +2913,7 @@ QString Text::original(uint16 selectedFrom, uint16 selectedTo, ExpandLinksMode m result.reserve(_text.size()); int32 lnkFrom = 0, lnkIndex = 0; - for (TextBlocks::const_iterator i = _blocks.cbegin(), e = _blocks.cend(); true; ++i) { + for (TextBlocks::const_iterator i = _blocks.cbegin(), e = _blocks.cend(); true; ++i) { int32 blockLnkIndex = (i == e) ? 0 : (*i)->lnkIndex(); int32 blockFrom = (i == e) ? _text.size() : (*i)->from(); if (blockLnkIndex != lnkIndex) { @@ -3156,7 +3156,8 @@ namespace { class BlockParser { public: - BlockParser(QTextEngine *e, TextBlock *b, QFixed minResizeWidth, int32 blockFrom) : block(b), eng(e) { + BlockParser(QTextEngine *e, TextBlock *b, QFixed minResizeWidth, int32 blockFrom, const QString &str) + : block(b), eng(e), str(str) { parseWords(minResizeWidth, blockFrom); } @@ -3234,7 +3235,7 @@ public: if (lbh.currentPosition >= eng->layoutData->string.length() || attributes[lbh.currentPosition].whiteSpace - || attributes[lbh.currentPosition].lineBreak) { + || isLineBreak(attributes, lbh.currentPosition)) { lbh.adjustRightBearing(); block->_words.push_back(TextWord(wordStart + blockFrom, lbh.tmpData.textWidth, qMin(QFixed(), lbh.rightBearing))); block->_width += lbh.tmpData.textWidth; @@ -3281,10 +3282,19 @@ public: } } + bool isLineBreak(const QCharAttributes *attributes, int32 index) { + bool lineBreak = attributes[index].lineBreak; + if (lineBreak && block->lnkIndex() > 0 && index > 0 && str.at(index - 1) == '/') { + return false; // don't break after / in links + } + return lineBreak; + } + private: TextBlock *block; QTextEngine *eng; + const QString &str; }; @@ -3318,14 +3328,15 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi } } - QStackTextEngine engine(str.mid(_from, length), blockFont->f); + QString part = str.mid(_from, length); + QStackTextEngine engine(part, blockFont->f); engine.itemize(); QTextLayout layout(&engine); layout.beginLayout(); layout.createLine(); - BlockParser parser(&engine, this, minResizeWidth, _from); + BlockParser parser(&engine, this, minResizeWidth, _from, part); layout.endLayout(); } @@ -3687,7 +3698,7 @@ void initLinkSets() { namespace { // accent char list taken from https://github.com/aristus/accent-folding - inline QChar chNoAccent(int32 code) { + inline QChar chNoAccent(int32 code) { switch (code) { case 7834: return QChar(97); case 193: return QChar(97); @@ -4411,7 +4422,7 @@ QString textAccentFold(const QString &text) { result[i] = noAccent; } else { if (copying) result[i] = *ch; - ++ch, ++i; + ++ch, ++i; if (copying) result[i] = *ch; } } else { diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index cd309b382f..2cc47fda1c 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -1390,10 +1390,13 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo case mtpc_messageMediaUnsupported: default: badMedia = 1; break; } - if (false && badMedia == 1) { -// QString text(lng_message_unsupported(lt_link, qsl("https://desktop.telegram.org"))); + if (badMedia == 1) { + 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 = new HistoryMessage(this, block, m.vid.v, m.vflags.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v, text, entities, 0); } else if (badMedia) { - result = new HistoryServiceMsg(this, block, m.vid.v, date(m.vdate), lang((badMedia == 2) ? lng_message_empty : lng_media_unsupported), m.vflags.v, 0, m.has_from_id() ? m.vfrom_id.v : 0); + result = new HistoryServiceMsg(this, block, m.vid.v, date(m.vdate), lang(lng_message_empty), m.vflags.v, 0, m.has_from_id() ? m.vfrom_id.v : 0); } else { if ((m.has_fwd_date() && m.vfwd_date.v > 0) || (m.has_fwd_from_id() && peerFromMTP(m.vfwd_from_id) != 0)) { result = new HistoryForwarded(this, block, m); @@ -5979,10 +5982,10 @@ void ViaInlineBotLink::onClick(Qt::MouseButton button) const { } HistoryMessageVia::HistoryMessageVia(int32 userId) - : bot(App::userLoaded(peerFromUser(userId))) - , width(0) - , maxWidth(st::msgServiceNameFont->width(qsl("via @") + bot->username)) - , lnk(new ViaInlineBotLink(bot)) { +: bot(App::userLoaded(peerFromUser(userId))) +, width(0) +, maxWidth(bot ? st::msgServiceNameFont->width(lng_inline_bot_via(lt_inline_bot, '@' + bot->username)) : 0) +, lnk(new ViaInlineBotLink(bot)) { } bool HistoryMessageVia::isNull() const { @@ -5990,22 +5993,17 @@ bool HistoryMessageVia::isNull() const { } void HistoryMessageVia::resize(int32 availw) { - if (width < maxWidth && availw > width) { + if (availw < 0) { + text = QString(); + width = 0; + } else { + text = lng_inline_bot_via(lt_inline_bot, '@' + bot->username); if (availw < maxWidth) { - text = st::msgServiceNameFont->elided(qsl("via @") + bot->username, availw); + text = st::msgServiceNameFont->elided(text, availw); width = st::msgServiceNameFont->width(text); - } else { - text = qsl("via @") + bot->username; + } else if (width < maxWidth) { width = maxWidth; } - } else if (availw < width) { - if (availw > 0) { - text = st::msgServiceNameFont->elided(qsl("via @") + bot->username, availw); - width = st::msgServiceNameFont->width(text); - } else { - text = QString(); - width = 0; - } } } @@ -6024,11 +6022,11 @@ HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPD } HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities, HistoryMedia *fromMedia) : -HistoryItem(history, block, msgId, flags, date, from) +HistoryItem(history, block, msgId, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0) , _text(st::msgMinWidth) , _textWidth(0) , _textHeight(0) -, _via(viaBotId ? new HistoryMessageVia(viaBotId) : 0) +, _via((flags & MTPDmessage::flag_via_bot_id) ? new HistoryMessageVia(viaBotId) : 0) , _media(0) , _views(fromChannel() ? 1 : -1) { initTime(); @@ -6040,11 +6038,11 @@ HistoryItem(history, block, msgId, flags, date, from) } HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) : -HistoryItem(history, block, msgId, flags, date, from) +HistoryItem(history, block, msgId, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0) , _text(st::msgMinWidth) , _textWidth(0) , _textHeight(0) -, _via(viaBotId ? new HistoryMessageVia(viaBotId) : 0) +, _via((flags & MTPDmessage::flag_via_bot_id) ? new HistoryMessageVia(viaBotId) : 0) , _media(0) , _views(fromChannel() ? 1 : -1) { initTime(); @@ -6053,11 +6051,11 @@ HistoryItem(history, block, msgId, flags, date, from) } HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) : -HistoryItem(history, block, msgId, flags, date, from) +HistoryItem(history, block, msgId, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0) , _text(st::msgMinWidth) , _textWidth(0) , _textHeight(0) -, _via(viaBotId ? new HistoryMessageVia(viaBotId) : 0) +, _via((flags & MTPDmessage::flag_via_bot_id) ? new HistoryMessageVia(viaBotId) : 0) , _media(0) , _views(fromChannel() ? 1 : -1) { initTime(); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 703aa35efb..bc412b9d0a 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -6368,11 +6368,11 @@ void HistoryWidget::onFieldTabbed() { } void HistoryWidget::onStickerSend(DocumentData *sticker) { - sendExistingDocument(sticker, QString(), 0); + sendExistingDocument(sticker, QString()); } void HistoryWidget::onPhotoSend(PhotoData *photo) { - sendExistingPhoto(photo, QString(), 0); + sendExistingPhoto(photo, QString()); } void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) { @@ -6495,7 +6495,7 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) { _field.setFocus(); } -void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &caption, UserData *bot) { +void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &caption) { if (!_history || !doc || !canSendMessages(_peer)) return; App::main()->readServerHistory(_history, false); @@ -6519,7 +6519,7 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti } else { flags |= MTPDmessage::flag_from_id; } - _history->addNewDocument(newId.msg, flags, bot ? peerToUser(bot->id) : 0, replyToId(), date(MTP_int(unixtime())), fromChannelName ? 0 : MTP::authedId(), doc, caption); + _history->addNewDocument(newId.msg, flags, 0, replyToId(), date(MTP_int(unixtime())), fromChannelName ? 0 : MTP::authedId(), doc, caption); _history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(doc->id), MTP_long(doc->access)), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId); App::main()->finishForwarding(_history, _broadcast.checked()); @@ -6536,7 +6536,7 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti _field.setFocus(); } -void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption, UserData *bot) { +void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption) { if (!_history || !photo || !canSendMessages(_peer)) return; App::main()->readServerHistory(_history, false); @@ -6560,7 +6560,7 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption, } else { flags |= MTPDmessage::flag_from_id; } - _history->addNewPhoto(newId.msg, flags, bot ? peerToUser(bot->id) : 0, replyToId(), date(MTP_int(unixtime())), fromChannelName ? 0 : MTP::authedId(), photo, caption); + _history->addNewPhoto(newId.msg, flags, 0, replyToId(), date(MTP_int(unixtime())), fromChannelName ? 0 : MTP::authedId(), photo, caption); _history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaPhoto(MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId); App::main()->finishForwarding(_history, _broadcast.checked()); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 24a9bdad5b..1936ccbb4e 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -693,8 +693,8 @@ private: IconedButton _replyForwardPreviewCancel; void updateReplyToName(); - void sendExistingDocument(DocumentData *doc, const QString &caption, UserData *bot); - void sendExistingPhoto(PhotoData *photo, const QString &caption, UserData *bot); + void sendExistingDocument(DocumentData *doc, const QString &caption); + void sendExistingPhoto(PhotoData *photo, const QString &caption); void drawField(Painter &p); void drawRecordButton(Painter &p); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 28cf54a838..a846f9aed3 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -907,7 +907,8 @@ void MainWidget::forwardLayer(int32 forwardSelected) { void MainWidget::deleteLayer(int32 selectedCount) { QString str((selectedCount < 0) ? lang(selectedCount < -1 ? lng_selected_cancel_sure_this : lng_selected_delete_sure_this) : lng_selected_delete_sure(lt_count, selectedCount)); - ConfirmBox *box = new ConfirmBox((selectedCount < 0) ? str : str.arg(selectedCount), lang(lng_box_delete)); + QString btn(lang((selectedCount < -1) ? lng_selected_upload_stop : lng_box_delete)), cancel(lang((selectedCount < -1) ? lng_continue : lng_cancel)); + ConfirmBox *box = new ConfirmBox(str, btn, st::defaultBoxButton, cancel); if (selectedCount < 0) { if (selectedCount < -1) { if (HistoryItem *item = App::contextItem()) {