diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 917c77ca1..5fd98d4b2 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -1489,6 +1489,11 @@ replyCancel: iconedButton(btnDefIconed) { width: 49px; height: 49px; } +inlineBotCancel: iconedButton(replyCancel) { + height: 46px; + iconPos: point(-1px, 16px); // < 0 means draw in the center of the button + downIconPos: point(-1px, 17px); +} forwardIcon: sprite(368px, 197px, 24px, 24px); historyScroll: flatScroll(scrollDef) { diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index c66d6a784..8e9537bfd 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -3655,7 +3655,7 @@ void EmojiPan::inlineBotChanged() { if (_inlineRequestId) MTP::cancel(_inlineRequestId); _inlineRequestId = 0; _inlineQuery = _inlineNextQuery = _inlineNextOffset = QString(); - _inlineBot = 0; + _inlineBot = nullptr; for (InlineCache::const_iterator i = _inlineCache.cbegin(), e = _inlineCache.cend(); i != e; ++i) { delete i.value(); } diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index a25461361..454e62234 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2816,7 +2816,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) connect(&_attachMention, SIGNAL(chosen(QString)), this, SLOT(onMentionHashtagOrBotCommandInsert(QString))); connect(&_attachMention, SIGNAL(stickerSelected(DocumentData*)), this, SLOT(onStickerSend(DocumentData*))); _field.installEventFilter(&_attachMention); - _field.setCtrlEnterSubmit(cCtrlEnter()); + updateFieldSubmitSettings(); _field.hide(); _send.hide(); @@ -2884,28 +2884,31 @@ void HistoryWidget::onMentionHashtagOrBotCommandInsert(QString str) { } void HistoryWidget::updateInlineBotQuery() { - UserData *bot = _inlineBot; - bool start = false; - QString inlineBotUsername(_inlineBotUsername); - QString query = _field.getInlineBotQuery(_inlineBot, _inlineBotUsername); + UserData *bot = nullptr; + QString inlineBotUsername; + QString query = _field.getInlineBotQuery(&bot, &inlineBotUsername); if (inlineBotUsername != _inlineBotUsername) { + _inlineBotUsername = inlineBotUsername; if (_inlineBotResolveRequestId) { // Notify::inlineBotRequesting(false); MTP::cancel(_inlineBotResolveRequestId); _inlineBotResolveRequestId = 0; } - if (_inlineBot == LookingUpInlineBot) { + if (bot == LookingUpInlineBot) { + _inlineBot = LookingUpInlineBot; // Notify::inlineBotRequesting(true); _inlineBotResolveRequestId = MTP::send(MTPcontacts_ResolveUsername(MTP_string(_inlineBotUsername)), rpcDone(&HistoryWidget::inlineBotResolveDone), rpcFail(&HistoryWidget::inlineBotResolveFail, _inlineBotUsername)); return; } - } else if (_inlineBot == LookingUpInlineBot) { + } else if (bot == LookingUpInlineBot) { + _inlineBot = LookingUpInlineBot; return; } - if (_inlineBot) { + if (bot) { if (_inlineBot != bot) { - updateFieldPlaceholder(); + _inlineBot = bot; + inlineBotChanged(); } if (_inlineBot->username == cInlineGifBotUsername() && query.isEmpty()) { _emojiPan.clearInlineBot(); @@ -2916,12 +2919,7 @@ void HistoryWidget::updateInlineBotQuery() { _attachMention.hideStart(); } } else { - if (_inlineBot != bot) { - updateFieldPlaceholder(); - _field.finishPlaceholder(); - } - _emojiPan.clearInlineBot(); - onCheckMentionDropdown(); + clearInlineBot(); } } @@ -3531,7 +3529,7 @@ void HistoryWidget::fastShowAtEnd(History *h) { void HistoryWidget::applyDraft(bool parseLinks) { HistoryDraft *draft = _history ? _history->draft() : nullptr; if (!draft) { - setFieldText(QString()); + clearFieldText(); _field.setFocus(); _editMsgId = _replyToId = 0; return; @@ -3672,11 +3670,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re _scroll.takeWidget(); updateTopBarSelection(); - if (_inlineBot) { - _inlineBot = nullptr; - _emojiPan.clearInlineBot(); - updateFieldPlaceholder(); - } + clearInlineBot(); _showAtMsgId = showAtMsgId; _histInited = false; @@ -3776,7 +3770,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re onBotStart(); } } else { - setFieldText(QString()); + clearFieldText(); doneShow(); } @@ -3815,8 +3809,14 @@ void HistoryWidget::updateAfterDrag() { if (_list) _list->dragActionUpdate(QCursor::pos()); } -void HistoryWidget::ctrlEnterSubmitUpdated() { - _field.setCtrlEnterSubmit(cCtrlEnter()); +void HistoryWidget::updateFieldSubmitSettings() { + FlatTextarea::SubmitSettings settings = FlatTextarea::SubmitSettings::Enter; + if (_inlineBotCancel) { + settings = FlatTextarea::SubmitSettings::None; + } else if (cCtrlEnter()) { + settings = FlatTextarea::SubmitSettings::CtrlEnter; + } + _field.setSubmitSettings(settings); } void HistoryWidget::updateNotifySettings() { @@ -3943,6 +3943,7 @@ void HistoryWidget::updateControlsVisibility() { _scroll.hide(); _kbScroll.hide(); _send.hide(); + if (_inlineBotCancel) _inlineBotCancel->hide(); _unblock.hide(); _botStart.hide(); _joinChannel.hide(); @@ -4010,6 +4011,7 @@ void HistoryWidget::updateControlsVisibility() { _kbShown = false; _attachMention.hide(); _send.hide(); + if (_inlineBotCancel) _inlineBotCancel->hide(); _botStart.hide(); _attachDocument.hide(); _attachPhoto.hide(); @@ -4044,6 +4046,7 @@ void HistoryWidget::updateControlsVisibility() { } _kbShown = false; _send.hide(); + if (_inlineBotCancel) _inlineBotCancel->hide(); _field.hide(); _attachEmoji.hide(); _kbShow.hide(); @@ -4064,7 +4067,12 @@ void HistoryWidget::updateControlsVisibility() { _send.hide(); mouseMoveEvent(0); } else { - _send.show(); + if (_inlineBotCancel) { + _inlineBotCancel->show(); + _send.hide(); + } else { + _send.show(); + } _a_record.stop(); _inRecord = _inField = false; a_recordOver = anim::fvalue(0, 0); @@ -4146,6 +4154,7 @@ void HistoryWidget::updateControlsVisibility() { } else { _attachMention.hide(); _send.hide(); + if (_inlineBotCancel) _inlineBotCancel->hide(); _unblock.hide(); _botStart.hide(); _joinChannel.hide(); @@ -4630,6 +4639,15 @@ void HistoryWidget::preloadHistoryIfNeeded() { } } +void HistoryWidget::onInlineBotCancel() { + QString text = _field.getLastText(); + if (text.size() > _inlineBotUsername.size() + 2) { + setFieldText('@' + _inlineBotUsername + ' ', TextUpdateEventsSaveDraft, false); + } else { + clearFieldText(TextUpdateEventsSaveDraft, false); + } +} + void HistoryWidget::onWindowVisibleChanged() { QTimer::singleShot(0, this, SLOT(preloadHistoryIfNeeded())); } @@ -4746,7 +4764,7 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) { App::main()->sendMessage(_history, _field.getLastText(), replyTo, _broadcast.checked(), _silent.checked(), webPageId); - setFieldText(QString()); + clearFieldText(); _saveDraftText = true; _saveDraftStart = getms(); onDraftSave(); @@ -4971,6 +4989,7 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo _field.hide(); _fieldBarCancel.hide(); _send.hide(); + if (_inlineBotCancel) _inlineBotCancel->hide(); _unblock.hide(); _botStart.hide(); _joinChannel.hide(); @@ -5341,7 +5360,7 @@ bool HistoryWidget::insertBotCommand(const QString &cmd, bool specialGif) { QString text = _field.getLastText(); if (specialGif) { if (text.trimmed() == '@' + cInlineGifBotUsername() && text.at(0) == '@') { - setFieldText(QString(), TextUpdateEventsSaveDraft, false); + clearFieldText(TextUpdateEventsSaveDraft, false); } } else { QRegularExpressionMatch m = QRegularExpression(qsl("^/[A-Za-z_0-9]{0,64}(@[A-Za-z_0-9]{0,32})?(\\s|$)")).match(text); @@ -5481,8 +5500,7 @@ bool HistoryWidget::inlineBotResolveFail(QString name, const RPCError &error) { _inlineBotResolveRequestId = 0; // Notify::inlineBotRequesting(false); if (name == _inlineBotUsername) { - _inlineBot = nullptr; - onCheckMentionDropdown(); + clearInlineBot(); } return true; } @@ -5654,7 +5672,6 @@ void HistoryWidget::onKbToggle(bool manual) { void HistoryWidget::onCmdStart() { setFieldText(qsl("/")); - _field.moveCursor(QTextCursor::End); } void HistoryWidget::contextMenuEvent(QContextMenuEvent *e) { @@ -5816,35 +5833,92 @@ void HistoryWidget::updateOnlineDisplayTimer() { App::main()->updateOnlineDisplayIn(minIn * 1000); } -void HistoryWidget::onFieldResize() { - int32 maxKeyboardHeight = int(st::maxFieldHeight) - _field.height(); +void HistoryWidget::moveFieldControls() { + int w = width(), h = height(), right = w, bottom = h, keyboardHeight = 0; + int maxKeyboardHeight = int(st::maxFieldHeight) - _field.height(); _keyboard.resizeToWidth(width(), maxKeyboardHeight); - - int32 kbh = 0; if (_kbShown) { - kbh = qMin(_keyboard.height(), maxKeyboardHeight); - _kbScroll.setGeometry(0, height() - kbh, width(), kbh); + keyboardHeight = qMin(_keyboard.height(), maxKeyboardHeight); + bottom -= keyboardHeight; + _kbScroll.setGeometry(0, bottom, w, keyboardHeight); } - _field.move(_attachDocument.x() + _attachDocument.width(), height() - kbh - _field.height() - st::sendPadding); - _fieldBarCancel.move(width() - _fieldBarCancel.width(), _field.y() - st::sendPadding - _fieldBarCancel.height()); - _attachDocument.move(0, height() - kbh - _attachDocument.height()); - _attachPhoto.move(_attachDocument.x(), _attachDocument.y()); - _botStart.setGeometry(0, _attachDocument.y(), width(), _botStart.height()); - _unblock.setGeometry(0, _attachDocument.y(), width(), _unblock.height()); - _joinChannel.setGeometry(0, _attachDocument.y(), width(), _joinChannel.height()); - _muteUnmute.setGeometry(0, _attachDocument.y(), width(), _muteUnmute.height()); - _send.move(width() - _send.width(), _attachDocument.y()); - _broadcast.move(_send.x() - _broadcast.width(), height() - kbh - _broadcast.height()); - _attachEmoji.move((hasBroadcastToggle() ? _broadcast.x() : _send.x()) - _attachEmoji.width(), height() - kbh - _attachEmoji.height()); - _kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height()); - _kbHide.move(_attachEmoji.x(), _attachEmoji.y()); - _cmdStart.move(_attachEmoji.x() - _cmdStart.width(), height() - kbh - _cmdStart.height()); - _silent.move(_attachEmoji.x() - _silent.width(), height() - kbh - _silent.height()); +// _attachType ----------------------------------------------------------- _emojiPan --------- _fieldBarCancel +// (_attachDocument|_attachPhoto) _field (_silent|_cmdStart|_kbShow) (_kbHide|_attachEmoji) [_broadcast] _send +// (_botStart|_unblock|_joinChannel|_muteUnmute) + int buttonsBottom = bottom - _attachDocument.height(); + _attachDocument.move(0, buttonsBottom); + _attachPhoto.move(0, buttonsBottom); + _field.move(_attachDocument.width(), bottom - _field.height() - st::sendPadding); + _send.move(right - _send.width(), buttonsBottom); + if (_inlineBotCancel) _inlineBotCancel->move(_send.pos()); + right -= _send.width(); + _broadcast.move(right - _broadcast.width(), buttonsBottom); + if (hasBroadcastToggle()) right -= _broadcast.width(); + _attachEmoji.move(right - _attachEmoji.width(), buttonsBottom); + _kbHide.move(right - _kbHide.width(), buttonsBottom); + right -= _attachEmoji.width(); + _kbShow.move(right - _kbShow.width(), buttonsBottom); + _cmdStart.move(right - _cmdStart.width(), buttonsBottom); + _silent.move(right - _silent.width(), buttonsBottom); + + right = w; + _fieldBarCancel.move(right - _fieldBarCancel.width(), _field.y() - st::sendPadding - _fieldBarCancel.height()); _attachType.move(0, _attachDocument.y() - _attachType.height()); _emojiPan.moveBottom(_attachEmoji.y()); + _botStart.setGeometry(0, bottom - _botStart.height(), w, _botStart.height()); + _unblock.setGeometry(0, bottom - _unblock.height(), w, _unblock.height()); + _joinChannel.setGeometry(0, bottom - _joinChannel.height(), w, _joinChannel.height()); + _muteUnmute.setGeometry(0, bottom - _muteUnmute.height(), w, _muteUnmute.height()); +} + +void HistoryWidget::updateFieldSize() { + bool kbShowShown = _history && !_kbShown && _keyboard.hasMarkup(); + int fieldWidth = width() - _attachDocument.width(); + fieldWidth -= _send.width(); + fieldWidth -= _attachEmoji.width(); + if (kbShowShown) fieldWidth -= _kbShow.width(); + if (_cmdStartShown) fieldWidth -= _cmdStart.width(); + if (hasBroadcastToggle()) fieldWidth -= _broadcast.width(); + if (hasSilentToggle()) fieldWidth -= _silent.width(); + + if (_field.width() != fieldWidth) { + _field.resize(fieldWidth, _field.height()); + } else { + moveFieldControls(); + } +} + +void HistoryWidget::clearInlineBot() { + if (_inlineBot) { + _inlineBot = nullptr; + inlineBotChanged(); + _field.finishPlaceholder(); + } + _emojiPan.clearInlineBot(); + onCheckMentionDropdown(); +} + +void HistoryWidget::inlineBotChanged() { + bool isInlineBot = _inlineBot && (_inlineBot != LookingUpInlineBot); + if (isInlineBot && !_inlineBotCancel) { + _inlineBotCancel = MakeUnique(this, st::inlineBotCancel); + connect(_inlineBotCancel.data(), SIGNAL(clicked()), this, SLOT(onInlineBotCancel())); + _inlineBotCancel->setGeometry(_send.geometry()); + updateFieldSubmitSettings(); + updateControlsVisibility(); + } else if (!isInlineBot && _inlineBotCancel) { + _inlineBotCancel.clear(); + updateFieldSubmitSettings(); + updateControlsVisibility(); + } + updateFieldPlaceholder(); +} + +void HistoryWidget::onFieldResize() { + moveFieldControls(); updateListSize(); updateField(); } @@ -5996,7 +6070,7 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif void HistoryWidget::cancelSendFile(const FileLoadResultPtr &file) { if (_confirmWithTextId && file->id == _confirmWithTextId) { - setFieldText(QString()); + clearFieldText(); _confirmWithTextId = 0; } if (!file->originalText.isEmpty()) { @@ -6017,7 +6091,7 @@ void HistoryWidget::confirmShareContact(const QString &phone, const QString &fna void HistoryWidget::cancelShareContact() { if (_confirmWithTextId == 0xFFFFFFFFFFFFFFFFL) { - setFieldText(QString()); + clearFieldText(); _confirmWithTextId = 0; } } @@ -6331,15 +6405,7 @@ void HistoryWidget::notify_handlePendingHistoryUpdate() { void HistoryWidget::resizeEvent(QResizeEvent *e) { _reportSpamPanel.resize(width(), _reportSpamPanel.height()); - int32 maxKeyboardHeight = int(st::maxFieldHeight) - _field.height(); - _keyboard.resizeToWidth(width(), maxKeyboardHeight); - - int32 kbh = 0; - if (_kbShown) { - kbh = qMin(_keyboard.height(), maxKeyboardHeight); - _kbScroll.setGeometry(0, height() - kbh, width(), kbh); - } - _field.move(_attachDocument.x() + _attachDocument.width(), height() - kbh - _field.height() - st::sendPadding); + moveFieldControls(); if (_pinnedBar) { if (_scroll.y() != st::replyHeight) { @@ -6355,32 +6421,13 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) { _attachMention.setBoundings(_scroll.geometry()); } - _attachDocument.move(0, height() - kbh - _attachDocument.height()); - _attachPhoto.move(_attachDocument.x(), _attachDocument.y()); - - _fieldBarCancel.move(width() - _fieldBarCancel.width(), _field.y() - st::sendPadding - _fieldBarCancel.height()); updateListSize(false, false, { ScrollChangeAdd, App::main() ? App::main()->contentScrollAddToY() : 0 }); - bool kbShowShown = _history && !_kbShown && _keyboard.hasMarkup(); - _field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width() - (kbShowShown ? _kbShow.width() : 0) - (_cmdStartShown ? _cmdStart.width() : 0) - (hasBroadcastToggle() ? _broadcast.width() : 0) - (hasSilentToggle() ? _silent.width() : 0), _field.height()); + updateFieldSize(); _toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip); updateCollapseCommentsVisibility(); - _send.move(width() - _send.width(), _attachDocument.y()); - _botStart.setGeometry(0, _attachDocument.y(), width(), _botStart.height()); - _unblock.setGeometry(0, _attachDocument.y(), width(), _unblock.height()); - _joinChannel.setGeometry(0, _attachDocument.y(), width(), _joinChannel.height()); - _muteUnmute.setGeometry(0, _attachDocument.y(), width(), _muteUnmute.height()); - _broadcast.move(_send.x() - _broadcast.width(), height() - kbh - _broadcast.height()); - _attachEmoji.move((hasBroadcastToggle() ? _broadcast.x() : _send.x()) - _attachEmoji.width(), height() - kbh - _attachEmoji.height()); - _kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height()); - _kbHide.move(_attachEmoji.x(), _attachEmoji.y()); - _cmdStart.move(_attachEmoji.x() - _cmdStart.width(), height() - kbh - _cmdStart.height()); - _silent.move(_attachEmoji.x() - _silent.width(), height() - kbh - _silent.height()); - - _attachType.move(0, _attachDocument.y() - _attachType.height()); - _emojiPan.moveBottom(_attachEmoji.y()); _emojiPan.setMaxHeight(height() - st::dropdownDef.padding.top() - st::dropdownDef.padding.bottom() - _attachEmoji.height()); switch (_attachDrag) { @@ -6904,7 +6951,7 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot App::historyRegRandom(randomId, newId); - setFieldText(QString()); + clearFieldText(); _saveDraftText = true; _saveDraftStart = getms(); onDraftSave(); @@ -7079,7 +7126,7 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti App::historyRegRandom(randomId, newId); if (_attachMention.stickersShown()) { - setFieldText(QString()); + clearFieldText(); _saveDraftText = true; _saveDraftStart = getms(); onDraftSave(); @@ -7142,10 +7189,11 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption) void HistoryWidget::setFieldText(const QString &text, int32 textUpdateEventsFlags, bool clearUndoHistory) { _textUpdateEventsFlags = textUpdateEventsFlags; _field.setTextFast(text, clearUndoHistory); + _field.moveCursor(QTextCursor::End); _textUpdateEventsFlags = TextUpdateEventsSaveDraft | TextUpdateEventsSendTyping; _previewCancelled = false; - _previewData = 0; + _previewData = nullptr; if (_previewRequest) { MTP::cancel(_previewRequest); _previewRequest = 0; @@ -7554,8 +7602,8 @@ void HistoryWidget::updatePreview() { } void HistoryWidget::onCancel() { - if (_inlineBot && _field.getLastText().startsWith('@' + _inlineBot->username + ' ')) { - setFieldText(QString(), TextUpdateEventsSaveDraft, false); + if (_inlineBotCancel) { + onInlineBotCancel(); } else if (!_attachMention.isHidden()) { _attachMention.hideStart(); } else { diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index e314c6e26..1544d2b12 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -270,11 +270,9 @@ public: bool hasSendText() const; public slots: - void onEmojiInsert(EmojiPtr emoji); signals: - void focused(); private: @@ -490,13 +488,9 @@ enum TextUpdateEventsFlags { namespace InlineBots { namespace Layout { - class ItemBase; - } // namespace Layout - class Result; - } // namespace InlineBots class HistoryWidget : public TWidget, public RPCSender { @@ -653,7 +647,7 @@ public: void updateCollapseCommentsVisibility(); void updateAfterDrag(); - void ctrlEnterSubmitUpdated(); + void updateFieldSubmitSettings(); void setInnerFocus(); bool canSendMessages(PeerData *peer) const; @@ -813,8 +807,20 @@ public slots: // in the scroll area and preloads history if needed void preloadHistoryIfNeeded(); +private slots: + + void onInlineBotCancel(); + private: + // Updates position of controls around the message field, + // like send button, emoji button and others. + void moveFieldControls(); + void updateFieldSize(); + + void clearInlineBot(); + void inlineBotChanged(); + MsgId _replyToId = 0; Text _replyToName; int _replyToNameVersion = 0; @@ -950,6 +956,9 @@ private: void writeDrafts(HistoryDraft **msgDraft, HistoryEditDraft **editDraft); void writeDrafts(History *history); void setFieldText(const QString &text, int32 textUpdateEventsFlags = 0, bool clearUndoHistory = true); + void clearFieldText(int32 textUpdateEventsFlags = 0, bool clearUndoHistory = true) { + setFieldText(QString()); + } QStringList getMediasFromMime(const QMimeData *d); @@ -998,9 +1007,11 @@ private: CollapseButton _collapseComments; MentionsDropdown _attachMention; + UserData *_inlineBot = nullptr; QString _inlineBotUsername; mtpRequestId _inlineBotResolveRequestId = 0; + UniquePointer _inlineBotCancel; void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result); bool inlineBotResolveFail(QString name, const RPCError &error); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index b4243bda6..89dd46e24 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -723,6 +723,15 @@ void MainWidget::onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data) } } +void MainWidget::rpcClear() { + history.rpcClear(); + dialogs.rpcClear(); + if (profile) profile->rpcClear(); + if (overview) overview->rpcClear(); + if (_api) _api->rpcClear(); + RPCSender::rpcClear(); +} + QPixmap MainWidget::grabInner() { if (overview && !overview->isHidden()) { return myGrab(overview); @@ -2306,7 +2315,7 @@ void MainWidget::updateAfterDrag() { } void MainWidget::ctrlEnterSubmitUpdated() { - history.ctrlEnterSubmitUpdated(); + history.updateFieldSubmitSettings(); } void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back) { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 0098355d5..a2cf9d6ec 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -20,17 +20,24 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +#include "apiwrap.h" #include "dialogswidget.h" #include "historywidget.h" #include "profilewidget.h" #include "overviewwidget.h" #include "playerwidget.h" -#include "apiwrap.h" class Window; struct DialogRow; + +class ApiWrap; class MainWidget; class ConfirmBox; +class DialogsWidget; +class HistoryWidget; +class ProfileWidget; +class OverviewWidget; +class PlayerWidget; class TopBarWidget : public TWidget { Q_OBJECT @@ -433,14 +440,7 @@ public: QPixmap grabTopBar(); QPixmap grabInner(); - void rpcClear() override { - history.rpcClear(); - dialogs.rpcClear(); - if (profile) profile->rpcClear(); - if (overview) overview->rpcClear(); - if (_api) _api->rpcClear(); - RPCSender::rpcClear(); - } + void rpcClear() override; bool isItemVisible(HistoryItem *item); @@ -620,8 +620,8 @@ private: DialogsWidget dialogs; HistoryWidget history; - ProfileWidget *profile = nullptr; - OverviewWidget *overview = nullptr; + ProfileWidget* profile = nullptr; + OverviewWidget* overview = nullptr; PlayerWidget _player; TopBarWidget _topBar; ConfirmBox *_forwardConfirm = nullptr; // for single column layout diff --git a/Telegram/SourceFiles/ui/flatbutton.cpp b/Telegram/SourceFiles/ui/flatbutton.cpp index a2facf888..7079c2cb6 100644 --- a/Telegram/SourceFiles/ui/flatbutton.cpp +++ b/Telegram/SourceFiles/ui/flatbutton.cpp @@ -241,7 +241,7 @@ void IconedButton::onStateChange(int oldState, ButtonStateChangeSource source) { } void IconedButton::paintEvent(QPaintEvent *e) { - QPainter p(this); + Painter p(this); p.setOpacity(_opacity); @@ -256,10 +256,16 @@ void IconedButton::paintEvent(QPaintEvent *e) { const QPoint &t((_state & StateDown) ? _st.downTextPos : _st.textPos); p.drawText(t.x(), t.y() + _st.font->ascent, _text); } - const QRect &i((_state & StateDown) ? _st.downIcon : _st.icon); - if (i.width()) { - const QPoint &t((_state & StateDown) ? _st.downIconPos : _st.iconPos); - p.drawPixmap(t, App::sprite(), i); + const style::sprite &i((_state & StateDown) ? _st.downIcon : _st.icon); + if (i.pxWidth()) { + QPoint t((_state & StateDown) ? _st.downIconPos : _st.iconPos); + if (t.x() < 0) { + t.setX((width() - i.pxWidth()) / 2); + } + if (t.y() < 0) { + t.setY((height() - i.pxHeight()) / 2); + } + p.drawSprite(t, i); } } diff --git a/Telegram/SourceFiles/ui/flattextarea.cpp b/Telegram/SourceFiles/ui/flattextarea.cpp index efe8bcdfd..89a729e1e 100644 --- a/Telegram/SourceFiles/ui/flattextarea.cpp +++ b/Telegram/SourceFiles/ui/flattextarea.cpp @@ -25,27 +25,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window.h" FlatTextarea::FlatTextarea(QWidget *parent, const style::flatTextarea &st, const QString &pholder, const QString &v) : QTextEdit(parent) -, _minHeight(-1) -, _maxHeight(-1) -, _maxLength(-1) -, _ctrlEnterSubmit(true) , _oldtext(v) -, _phAfter(0) , _phVisible(!v.length()) , a_phLeft(_phVisible ? 0 : st.phShift) , a_phAlpha(_phVisible ? 1 : 0) , a_phColor(st.phColor->c) , _a_appearance(animation(this, &FlatTextarea::step_appearance)) -, _st(st) -, _undoAvailable(false) -, _redoAvailable(false) -, _inDrop(false) -, _inHeightCheck(false) -, _fakeMargin(0) -, _touchPress(false) -, _touchRightButton(false) -, _touchMove(false) -, _correcting(false) { +, _st(st) { setAcceptRichText(false); resize(_st.width, _st.font->height); @@ -270,7 +256,10 @@ EmojiPtr FlatTextarea::getSingleEmoji() const { return 0; } -QString FlatTextarea::getInlineBotQuery(UserData *&inlineBot, QString &inlineBotUsername) const { +QString FlatTextarea::getInlineBotQuery(UserData **outInlineBot, QString *outInlineBotUsername) const { + t_assert(outInlineBot != nullptr); + t_assert(outInlineBotUsername != nullptr); + const QString &text(getLastText()); int32 inlineUsernameStart = 1, inlineUsernameLength = 0, size = text.size(); @@ -288,23 +277,23 @@ QString FlatTextarea::getInlineBotQuery(UserData *&inlineBot, QString &inlineBot } if (inlineUsernameLength && inlineUsernameStart + inlineUsernameLength < text.size() && text.at(inlineUsernameStart + inlineUsernameLength).isSpace()) { QStringRef username = text.midRef(inlineUsernameStart, inlineUsernameLength); - if (username != inlineBotUsername) { - inlineBotUsername = username.toString(); - PeerData *peer = App::peerByName(inlineBotUsername); + if (username != *outInlineBotUsername) { + *outInlineBotUsername = username.toString(); + PeerData *peer = App::peerByName(*outInlineBotUsername); if (peer) { if (peer->isUser()) { - inlineBot = peer->asUser(); + *outInlineBot = peer->asUser(); } else { - inlineBot = 0; + *outInlineBot = nullptr; } } else { - inlineBot = LookingUpInlineBot; + *outInlineBot = LookingUpInlineBot; } } - if (inlineBot == LookingUpInlineBot) return QString(); + if (*outInlineBot == LookingUpInlineBot) return QString(); - if (inlineBot && (!inlineBot->botInfo || inlineBot->botInfo->inlinePlaceholder.isEmpty())) { - inlineBot = 0; + if (*outInlineBot && (!(*outInlineBot)->botInfo || (*outInlineBot)->botInfo->inlinePlaceholder.isEmpty())) { + *outInlineBot = nullptr; } else { return text.mid(inlineUsernameStart + inlineUsernameLength + 1); } @@ -313,8 +302,8 @@ QString FlatTextarea::getInlineBotQuery(UserData *&inlineBot, QString &inlineBot } } if (inlineUsernameLength < 3) { - inlineBot = 0; - inlineBotUsername = QString(); + *outInlineBot = nullptr; + *outInlineBotUsername = QString(); } return QString(); } @@ -945,14 +934,21 @@ QMimeData *FlatTextarea::createMimeDataFromSelection() const { return result; } -void FlatTextarea::setCtrlEnterSubmit(bool ctrlEnterSubmit) { - _ctrlEnterSubmit = ctrlEnterSubmit; +void FlatTextarea::setSubmitSettings(SubmitSettings settings) { + _submitSettings = settings; } void FlatTextarea::keyPressEvent(QKeyEvent *e) { bool shift = e->modifiers().testFlag(Qt::ShiftModifier); bool macmeta = (cPlatform() == dbipMac || cPlatform() == dbipMacOld) && e->modifiers().testFlag(Qt::ControlModifier) && !e->modifiers().testFlag(Qt::MetaModifier) && !e->modifiers().testFlag(Qt::AltModifier); - bool ctrl = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier), ctrlGood = (ctrl && _ctrlEnterSubmit) || (!ctrl && !shift && !_ctrlEnterSubmit) || (ctrl && shift); + bool ctrl = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier); + bool enterSubmit = (ctrl && shift); + if (ctrl && _submitSettings != SubmitSettings::None && _submitSettings != SubmitSettings::Enter) { + enterSubmit = true; + } + if (!ctrl && _submitSettings != SubmitSettings::None && _submitSettings != SubmitSettings::CtrlEnter) { + enterSubmit = true; + } bool enter = (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return); if (macmeta && e->key() == Qt::Key_Backspace) { @@ -960,7 +956,7 @@ void FlatTextarea::keyPressEvent(QKeyEvent *e) { start.movePosition(QTextCursor::StartOfLine); tc.setPosition(start.position(), QTextCursor::KeepAnchor); tc.removeSelectedText(); - } else if (enter && ctrlGood) { + } else if (enter && enterSubmit) { emit submitted(ctrl && shift); } else if (e->key() == Qt::Key_Escape) { emit cancelled(); diff --git a/Telegram/SourceFiles/ui/flattextarea.h b/Telegram/SourceFiles/ui/flattextarea.h index cd3c47636..2a115107a 100644 --- a/Telegram/SourceFiles/ui/flattextarea.h +++ b/Telegram/SourceFiles/ui/flattextarea.h @@ -67,7 +67,12 @@ public: EmojiPtr getSingleEmoji() const; QString getMentionHashtagBotCommandPart(bool &start) const; - QString getInlineBotQuery(UserData *&contextBot, QString &contextBotUsername) const; + + // Get the current inline bot and request string for it. + // The *outInlineBot can be filled by LookingUpInlineBot shared ptr. + // In that case the caller should lookup the bot by *outInlineBotUsername. + QString getInlineBotQuery(UserData **outInlineBot, QString *outInlineBotUsername) const; + void removeSingleEmoji(); bool hasText() const; @@ -80,7 +85,14 @@ public: void insertFromMimeData(const QMimeData *source); QMimeData *createMimeDataFromSelection() const; - void setCtrlEnterSubmit(bool ctrlEnterSubmit); + + enum class SubmitSettings { + None, + Enter, + CtrlEnter, + Both, + }; + void setSubmitSettings(SubmitSettings settings); void setTextFast(const QString &text, bool clearUndoHistory = true); @@ -123,12 +135,13 @@ private: void processDocumentContentsChange(int position, int charsAdded); bool heightAutoupdated(); - int32 _minHeight, _maxHeight; // < 0 - no autosize - int32 _maxLength; - bool _ctrlEnterSubmit; + int _minHeight = -1; // < 0 - no autosize + int _maxHeight = -1; + int _maxLength = -1; + SubmitSettings _submitSettings = SubmitSettings::Enter; QString _ph, _phelided, _oldtext; - int32 _phAfter; + int _phAfter = 0; bool _phVisible; anim::ivalue a_phLeft; anim::fvalue a_phAlpha; @@ -137,15 +150,20 @@ private: style::flatTextarea _st; - bool _undoAvailable, _redoAvailable, _inDrop, _inHeightCheck; + bool _undoAvailable = false; + bool _redoAvailable = false; + bool _inDrop = false; + bool _inHeightCheck = false; - int32 _fakeMargin; + int _fakeMargin = 0; QTimer _touchTimer; - bool _touchPress, _touchRightButton, _touchMove; + bool _touchPress = false; + bool _touchRightButton = false; + bool _touchMove = false; QPoint _touchStart; - bool _correcting; + bool _correcting = false; typedef QPair LinkRange; typedef QList LinkRanges;