Inline bot cancel button added.

It replaces Send button when the user is editing an inline bot
query. First cancel clears the inline bot request, second one
clears the field entirely. Escape key acts the same as cancel.
This commit is contained in:
John Preston 2016-04-09 15:02:50 +04:00
parent c3c82eac2d
commit 0110a62776
9 changed files with 246 additions and 153 deletions

View File

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

View File

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

View File

@ -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<IconedButton>(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 {

View File

@ -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<IconedButton> _inlineBotCancel;
void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result);
bool inlineBotResolveFail(QString name, const RPCError &error);

View File

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

View File

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

View File

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

View File

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

View File

@ -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<int, int> LinkRange;
typedef QList<LinkRange> LinkRanges;