beta 9026001 message/post edit done

This commit is contained in:
John Preston 2016-02-25 13:32:31 +03:00
parent 9c8ae7f32b
commit 4ec579112c
18 changed files with 660 additions and 259 deletions

View File

@ -127,6 +127,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_edit_deleted" = "This message was deleted";
"lng_edit_too_long" = "Your message text is too long";
"lng_edit_message" = "Edit message";
"lng_edit_message_text" = "New message text..";
"lng_deleted" = "Unknown";
"lng_deleted_message" = "Deleted message";
@ -653,6 +654,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_comment_ph" = "Write a comment..";
"lng_broadcast_ph" = "Broadcast a message..";
"lng_record_cancel" = "Release outside this field to cancel";
"lng_will_be_notified" = "Members will be notified when you post";
"lng_wont_be_notified" = "Members will not be notified when you post";
"lng_empty_history" = "";
"lng_willbe_history" = "Please select a chat to start messaging";
"lng_message_with_from" = "[c]{from}:[/c] {message}";
@ -712,6 +715,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_context_open_link" = "Open Link";
"lng_context_copy_link" = "Copy Link";
"lng_context_copy_post_link" = "Copy Post Link";
"lng_context_open_email" = "Write to this address";
"lng_context_copy_email" = "Copy email address";
"lng_context_open_hashtag" = "Search by hashtag";

View File

@ -1429,6 +1429,7 @@ replyTop: 8px;
replyBottom: 6px;
replyIconPos: point(13px, 13px);
replyIcon: sprite(343px, 197px, 24px, 24px);
editIcon: sprite(371px, 286px, 24px, 24px);
replyCancel: iconedButton(btnDefIconed) {
icon: sprite(165px, 24px, 14px, 14px);
iconPos: point(17px, 17px);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 239 KiB

View File

@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
static const int32 AppVersion = 9026;
static const wchar_t *AppVersionStr = L"0.9.26";
static const bool DevVersion = false;
//#define BETA_VERSION (9019002ULL) // just comment this line to build public version
#define BETA_VERSION (9026001ULL) // 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";

View File

@ -280,7 +280,8 @@ History::History(const PeerId &peerId) : width(0), height(0)
, oldLoaded(false)
, newLoaded(true)
, lastMsg(0)
, draftToId(0)
, msgDraft(0)
, editDraft(0)
, lastWidth(0)
, lastScrollTop(ScrollMax)
, lastShowAtMsgId(ShowAtUnreadMsgId)
@ -294,8 +295,7 @@ History::History(const PeerId &peerId) : width(0), height(0)
, textCachedFor(0)
, lastItemTextCache(st::dlgRichMinWidth)
, posInDialogs(0)
, typingText(st::dlgRichMinWidth)
{
, typingText(st::dlgRichMinWidth) {
if (peer->isChannel() || (peer->isUser() && peer->asUser()->botInfo)) {
outboxReadBefore = INT_MAX;
}
@ -2674,6 +2674,12 @@ void History::removeBlock(HistoryBlock *block) {
delete block;
}
History::~History() {
clear();
deleteAndMark(msgDraft);
deleteAndMark(editDraft);
}
int32 HistoryBlock::geomResize(int32 newWidth, int32 *ytransform, const HistoryItem *resizedItem) {
int32 y = 0;
for (Items::iterator i = items.begin(), e = items.end(); i != e; ++i) {
@ -2926,7 +2932,8 @@ bool HistoryItem::canEdit(const QDateTime &cur) const {
t != MediaTypeFile &&
t != MediaTypeGif &&
t != MediaTypeMusicFile &&
t != MediaTypeVoiceFile) {
t != MediaTypeVoiceFile &&
t != MediaTypeWebPage) {
return false;
}
}

View File

@ -149,6 +149,42 @@ struct SendAction {
int32 progress;
};
struct HistoryDraft {
HistoryDraft() : msgId(0), previewCancelled(false) {
}
HistoryDraft(const QString &text, MsgId msgId, const MessageCursor &cursor, bool previewCancelled)
: text(text)
, msgId(msgId)
, cursor(cursor)
, previewCancelled(previewCancelled) {
}
HistoryDraft(const FlatTextarea &field, MsgId msgId, bool previewCancelled)
: text(field.getLastText())
, msgId(msgId)
, cursor(field)
, previewCancelled(previewCancelled) {
}
QString text;
MsgId msgId; // replyToId for message draft, editMsgId for edit draft
MessageCursor cursor;
bool previewCancelled;
};
struct HistoryEditDraft : public HistoryDraft {
HistoryEditDraft()
: HistoryDraft()
, saveRequest(0) {
}
HistoryEditDraft(const QString &text, MsgId msgId, const MessageCursor &cursor, bool previewCancelled, mtpRequestId saveRequest = 0)
: HistoryDraft(text, msgId, cursor, previewCancelled)
, saveRequest(saveRequest) {
}
HistoryEditDraft(const FlatTextarea &field, MsgId msgId, bool previewCancelled, mtpRequestId saveRequest = 0)
: HistoryDraft(field, msgId, previewCancelled)
, saveRequest(saveRequest) {
}
mtpRequestId saveRequest;
};
class HistoryMedia;
class HistoryMessage;
class HistoryUnreadBar;
@ -184,9 +220,7 @@ public:
void blockResized(HistoryBlock *block, int32 dh);
void removeBlock(HistoryBlock *block);
virtual ~History() {
clear();
}
virtual ~History();
HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction);
HistoryItem *createItemForwarded(HistoryBlock *block, MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg);
@ -284,10 +318,20 @@ public:
typedef QList<HistoryItem*> NotifyQueue;
NotifyQueue notifies;
QString draft;
MsgId draftToId;
MessageCursor draftCursor;
bool draftPreviewCancelled;
HistoryDraft *msgDraft;
HistoryEditDraft *editDraft;
HistoryDraft *draft() {
return editDraft ? editDraft : msgDraft;
}
void setMsgDraft(HistoryDraft *draft) {
if (msgDraft) delete msgDraft;
msgDraft = draft;
}
void setEditDraft(HistoryEditDraft *draft) {
if (editDraft) delete editDraft;
editDraft = draft;
}
int32 lastWidth, lastScrollTop;
MsgId lastShowAtMsgId;
bool mute;

View File

@ -2609,9 +2609,11 @@ void CollapseButton::paintEvent(QPaintEvent *e) {
HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _replyToId(0)
, _replyTo(0)
, _replyToNameVersion(0)
, _replyForwardPreviewCancel(this, st::replyCancel)
, _editMsgId(0)
, _replyEditMsg(0)
, _fieldBarCancel(this, st::replyCancel)
, _saveEditMsgRequestId(0)
, _reportSpamStatus(dbiprsUnknown)
, _previewData(0)
, _previewRequest(0)
@ -2661,7 +2663,10 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _field(this, st::taMsgField, lang(lng_message_ph))
, _a_record(animation(this, &HistoryWidget::step_record))
, _a_recording(animation(this, &HistoryWidget::step_recording))
, _recording(false), _inRecord(false), _inField(false), _inReply(false)
, _recording(false)
, _inRecord(false)
, _inField(false)
, _inReplyEdit(false)
, a_recordingLevel(0, 0), _recordingSamples(0)
, a_recordOver(0, 0), a_recordDown(0, 0), a_recordCancel(st::recordCancel->c, st::recordCancel->c)
, _recordCancelWidth(st::recordFont->width(lang(lng_record_cancel)))
@ -2697,7 +2702,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
connect(&_reportSpamPanel, SIGNAL(clearClicked()), this, SLOT(onReportSpamClear()));
connect(&_toHistoryEnd, SIGNAL(clicked()), this, SLOT(onHistoryToEnd()));
connect(&_collapseComments, SIGNAL(clicked()), this, SLOT(onCollapseComments()));
connect(&_replyForwardPreviewCancel, SIGNAL(clicked()), this, SLOT(onReplyForwardPreviewCancel()));
connect(&_fieldBarCancel, SIGNAL(clicked()), this, SLOT(onFieldBarCancel()));
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
connect(&_unblock, SIGNAL(clicked()), this, SLOT(onUnblock()));
connect(&_botStart, SIGNAL(clicked()), this, SLOT(onBotStart()));
@ -2745,7 +2750,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
connect(&_field, SIGNAL(cursorPositionChanged()), this, SLOT(onDraftSaveDelayed()));
connect(&_field, SIGNAL(cursorPositionChanged()), this, SLOT(onCheckMentionDropdown()), Qt::QueuedConnection);
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
_scroll.hide();
_scroll.move(0, 0);
@ -2897,20 +2902,20 @@ void HistoryWidget::onTextChange() {
updateStickersByEmoji();
if (_peer && (!_peer->isChannel() || _peer->isMegagroup() || !_peer->asChannel()->canPublish() || (!_peer->asChannel()->isBroadcast() && !_broadcast.checked()))) {
if (!_inlineBot && (_textUpdateEventsFlags & TextUpdateEventsSendTyping)) {
if (!_inlineBot && !_editMsgId && (_textUpdateEventsFlags & TextUpdateEventsSendTyping)) {
updateSendAction(_history, SendActionTyping);
}
}
if (cHasAudioCapture()) {
if (!_field.hasSendText() && !readyToForward()) {
if (!_field.hasSendText() && !readyToForward() && !_editMsgId) {
_previewCancelled = false;
_send.hide();
setMouseTracking(true);
updateMouseTracking();
mouseMoveEvent(0);
} else if (!_field.isHidden() && _send.isHidden()) {
_send.show();
setMouseTracking(false);
updateMouseTracking();
_a_record.stop();
_inRecord = _inField = false;
a_recordOver = a_recordDown = anim::fvalue(0, 0);
@ -2931,7 +2936,9 @@ void HistoryWidget::onTextChange() {
void HistoryWidget::onDraftSaveDelayed() {
if (!_peer || !(_textUpdateEventsFlags & TextUpdateEventsSaveDraft)) return;
if (!_field.textCursor().anchor() && !_field.textCursor().position() && !_field.verticalScrollBar()->value()) {
if (!Local::hasDraftPositions(_peer->id)) return;
if (!Local::hasDraftCursors(_peer->id)) {
return;
}
}
onDraftSave(true);
}
@ -2947,30 +2954,77 @@ void HistoryWidget::onDraftSave(bool delayed) {
return _saveDraftTimer.start(SaveDraftTimeout);
}
}
writeDraft();
writeDrafts(Nil, Nil);
}
void HistoryWidget::writeDraft(MsgId *replyTo, const QString *text, const MessageCursor *cursor, bool *previewCancelled) {
void HistoryWidget::writeDrafts(HistoryDraft **msgDraft, HistoryEditDraft **editDraft) {
if (!msgDraft && _editMsgId) msgDraft = &_history->msgDraft;
bool save = _peer && (_saveDraftStart > 0);
_saveDraftStart = 0;
_saveDraftTimer.stop();
if (_saveDraftText) {
if (save) {
Local::writeDraft(_peer->id, Local::MessageDraft(replyTo ? (*replyTo) : _replyToId, text ? (*text) : _field.getLastText(), previewCancelled ? (*previewCancelled) : _previewCancelled));
Local::MessageDraft localMsgDraft, localEditDraft;
if (msgDraft) {
if (*msgDraft) {
localMsgDraft = Local::MessageDraft((*msgDraft)->msgId, (*msgDraft)->text, (*msgDraft)->previewCancelled);
}
} else {
localMsgDraft = Local::MessageDraft(_replyToId, _field.getLastText(), _previewCancelled);
}
if (editDraft) {
if (*editDraft) {
localEditDraft = Local::MessageDraft((*editDraft)->msgId, (*editDraft)->text, (*editDraft)->previewCancelled);
}
} else if (_editMsgId) {
localEditDraft = Local::MessageDraft(_editMsgId, _field.getLastText(), _previewCancelled);
}
Local::writeDrafts(_peer->id, localMsgDraft, localEditDraft);
if (_migrated) {
Local::writeDraft(_migrated->peer->id, Local::MessageDraft());
Local::writeDrafts(_migrated->peer->id, Local::MessageDraft(), Local::MessageDraft());
}
}
_saveDraftText = false;
}
if (save) {
Local::writeDraftPositions(_peer->id, cursor ? (*cursor) : MessageCursor(_field));
MessageCursor msgCursor, editCursor;
if (msgDraft) {
if (*msgDraft) {
msgCursor = (*msgDraft)->cursor;
}
} else {
msgCursor = MessageCursor(_field);
}
if (editDraft) {
if (*editDraft) {
editCursor = (*editDraft)->cursor;
}
} else if (_editMsgId) {
editCursor = MessageCursor(_field);
}
Local::writeDraftCursors(_peer->id, msgCursor, editCursor);
if (_migrated) {
Local::writeDraftPositions(_migrated->peer->id, MessageCursor());
Local::writeDraftCursors(_migrated->peer->id, MessageCursor(), MessageCursor());
}
}
}
void HistoryWidget::writeDrafts(History *history) {
Local::MessageDraft localMsgDraft, localEditDraft;
MessageCursor msgCursor, editCursor;
if (history->msgDraft) {
localMsgDraft = Local::MessageDraft(history->msgDraft->msgId, history->msgDraft->text, history->msgDraft->previewCancelled);
msgCursor = history->msgDraft->cursor;
}
if (history->editDraft) {
localEditDraft = Local::MessageDraft(history->editDraft->msgId, history->editDraft->text, history->editDraft->previewCancelled);
editCursor = history->editDraft->cursor;
}
Local::writeDrafts(history->peer->id, localMsgDraft, localEditDraft);
Local::writeDraftCursors(history->peer->id, msgCursor, editCursor);
}
void HistoryWidget::cancelSendAction(History *history, SendActionType type) {
QMap<QPair<History*, SendActionType>, mtpRequestId>::iterator i = _sendActionRequests.find(qMakePair(history, type));
if (i != _sendActionRequests.cend()) {
@ -3374,16 +3428,36 @@ void HistoryWidget::fastShowAtEnd(History *h) {
}
void HistoryWidget::applyDraft(bool parseLinks) {
if (!_history) return;
setFieldText(_history->draft);
_field.setFocus();
HistoryDraft *draft = _history ? _history->draft() : 0;
if (!draft) {
setFieldText(QString());
_field.setFocus();
_editMsgId = _replyToId = 0;
return;
}
_textUpdateEventsFlags = 0;
_history->draftCursor.applyTo(_field);
setFieldText(draft->text);
_field.setFocus();
draft->cursor.applyTo(_field);
_textUpdateEventsFlags = TextUpdateEventsSaveDraft | TextUpdateEventsSendTyping;
_previewCancelled = _history->draftPreviewCancelled;
_previewCancelled = draft->previewCancelled;
if (_history->editDraft) {
_editMsgId = _history->editDraft->msgId;
_replyToId = 0;
} else {
_editMsgId = 0;
_replyToId = readyToForward() ? 0 : _history->msgDraft->msgId;
}
if (parseLinks) {
onPreviewParse();
}
if (_editMsgId || _replyToId) {
updateReplyEditTexts();
if (!_replyEditMsg && App::api()) {
App::api()->requestReplyTo(0, _peer->asChannel(), _editMsgId ? _editMsgId : _replyToId);
}
}
}
void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool reload) {
@ -3441,13 +3515,22 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
clearAllLoadRequests();
if (_history) {
_history->draft = _field.getLastText();
if (_migrated) _migrated->draft = QString(); // use migrated draft only once
_history->draftCursor.fillFrom(_field);
_history->draftToId = _replyToId;
_history->draftPreviewCancelled = _previewCancelled;
if (_editMsgId) {
_history->setEditDraft(new HistoryEditDraft(_field, _editMsgId, _previewCancelled, _saveEditMsgRequestId));
} else {
if (_replyToId || !_field.getLastText().isEmpty()) {
_history->setMsgDraft(new HistoryDraft(_field, _replyToId, _previewCancelled));
} else {
_history->setMsgDraft(Nil);
}
_history->setEditDraft(Nil);
}
if (_migrated) {
_migrated->setMsgDraft(Nil); // use migrated draft only once
_migrated->setEditDraft(Nil);
}
writeDraft(&_history->draftToId, &_history->draft, &_history->draftCursor, &_history->draftPreviewCancelled);
writeDrafts(&_history->msgDraft, &_history->editDraft);
if (_scroll.scrollTop() + 1 <= _scroll.scrollTopMax()) {
_history->lastWidth = _list->width();
@ -3467,16 +3550,14 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
updateBotKeyboard();
}
if (_replyToId) {
_replyTo = 0;
_replyToId = 0;
_replyForwardPreviewCancel.hide();
}
if (_previewData && _previewData->pendingTill >= 0) {
_previewData = 0;
_replyForwardPreviewCancel.hide();
}
_editMsgId = 0;
_saveEditMsgRequestId = 0;
_replyToId = 0;
_replyEditMsg = 0;
_previewData = 0;
_previewCache.clear();
_fieldBarCancel.hide();
if (_list) _list->deleteLater();
_list = 0;
_scroll.takeWidget();
@ -3552,39 +3633,20 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
App::main()->peerUpdated(_peer);
if (_history->draftToId > 0 || !_history->draft.isEmpty()) {
applyDraft(false);
_replyToId = readyToForward() ? 0 : _history->draftToId;
} else if (_migrated && !_migrated->draft.isEmpty()) {
_history->draft = _migrated->draft;
_history->draftCursor = _migrated->draftCursor;
_history->draftPreviewCancelled = _migrated->draftPreviewCancelled;
_history->draftToId = 0;
_migrated->draft = QString(); // use migrated draft only once
applyDraft(false);
_replyToId = 0;
} else {
bool fromMigrated = false;
Local::MessageDraft draft = Local::readDraft(_peer->id);
if (draft.replyTo <= 0 && draft.text.isEmpty() && _migrated) {
fromMigrated = true;
draft = Local::readDraft(_migrated->peer->id);
Local::readDraftsWithCursors(_history);
if (_migrated) {
Local::readDraftsWithCursors(_migrated);
_migrated->setEditDraft(Nil);
if (_migrated->msgDraft && !_migrated->msgDraft->text.isEmpty()) {
_migrated->msgDraft->msgId = 0; // edit and reply to drafts can't migrate
if (!_history->msgDraft) {
_history->setMsgDraft(new HistoryDraft(*_migrated->msgDraft));
}
}
setFieldText(draft.text);
_field.setFocus();
if (!draft.text.isEmpty()) {
MessageCursor cur = Local::readDraftPositions(fromMigrated ? _migrated->peer->id : _peer->id);
_textUpdateEventsFlags = 0;
cur.applyTo(_field);
_textUpdateEventsFlags = TextUpdateEventsSaveDraft | TextUpdateEventsSendTyping;
}
_replyToId = readyToForward() ? 0 : draft.replyTo;
_previewCancelled = draft.previewCancelled;
}
if (_replyToId) {
updateReplyTo();
if (!_replyTo && App::api()) App::api()->requestReplyTo(0, _peer->asChannel(), _replyToId);
_migrated->setMsgDraft(Nil);
}
applyDraft(false);
resizeEvent(0);
if (!_previewCancelled) {
onPreviewParse();
@ -3755,7 +3817,7 @@ void HistoryWidget::updateControlsVisibility() {
_muteUnmute.hide();
_attachMention.hide();
_field.hide();
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
_attachDocument.hide();
_attachPhoto.hide();
_attachEmoji.hide();
@ -3812,7 +3874,7 @@ void HistoryWidget::updateControlsVisibility() {
_attachPhoto.hide();
_broadcast.hide();
_kbScroll.hide();
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
_attachDocument.hide();
_attachPhoto.hide();
_attachEmoji.hide();
@ -3849,7 +3911,7 @@ void HistoryWidget::updateControlsVisibility() {
_attachPhoto.hide();
_broadcast.hide();
_kbScroll.hide();
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
} else {
_unblock.hide();
_botStart.hide();
@ -3857,11 +3919,9 @@ void HistoryWidget::updateControlsVisibility() {
_muteUnmute.hide();
if (cHasAudioCapture() && !_field.hasSendText() && !readyToForward()) {
_send.hide();
setMouseTracking(true);
mouseMoveEvent(0);
} else {
_send.show();
setMouseTracking(false);
_a_record.stop();
_inRecord = _inField = false;
a_recordOver = anim::fvalue(0, 0);
@ -3924,14 +3984,14 @@ void HistoryWidget::updateControlsVisibility() {
}
updateFieldPlaceholder();
}
if (_replyToId || readyToForward() || (_previewData && _previewData->pendingTill >= 0) || _kbReplyTo) {
if (_replyForwardPreviewCancel.isHidden()) {
_replyForwardPreviewCancel.show();
if (_editMsgId || _replyToId || readyToForward() || (_previewData && _previewData->pendingTill >= 0) || _kbReplyTo) {
if (_fieldBarCancel.isHidden()) {
_fieldBarCancel.show();
resizeEvent(0);
update();
}
} else {
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
}
}
} else {
@ -3945,7 +4005,7 @@ void HistoryWidget::updateControlsVisibility() {
_attachPhoto.hide();
_broadcast.hide();
_kbScroll.hide();
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
_attachDocument.hide();
_attachPhoto.hide();
_attachEmoji.hide();
@ -3961,6 +4021,12 @@ void HistoryWidget::updateControlsVisibility() {
update();
}
}
updateMouseTracking();
}
void HistoryWidget::updateMouseTracking() {
bool trackMouse = !_fieldBarCancel.isHidden() || (cHasAudioCapture() && _send.isHidden() && !_field.isHidden());
setMouseTracking(trackMouse);
}
void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
@ -4432,12 +4498,84 @@ void HistoryWidget::onCollapseComments() {
showHistory(_peer->id, switchAt);
}
void HistoryWidget::saveEditMsg() {
if (_saveEditMsgRequestId) return;
WebPageId webPageId = _previewCancelled ? CancelledWebPageId : ((_previewData && _previewData->pendingTill >= 0) ? _previewData->id : 0);
EntitiesInText sendingEntities, leftEntities;
QString sendingText, leftText = prepareTextWithEntities(_field.getLastText(), leftEntities, itemTextOptions(_history, App::self()).flags);
if (!textSplit(sendingText, sendingEntities, leftText, leftEntities, MaxMessageSize)) {
_field.selectAll();
_field.setFocus();
return;
} else if (!leftText.isEmpty()) {
Ui::showLayer(new InformBox(lang(lng_edit_too_long)));
return;
}
int32 sendFlags = 0;
if (webPageId == CancelledWebPageId) {
sendFlags |= MTPmessages_SendMessage::flag_no_webpage;
}
MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities), sentEntities = linksToMTP(sendingEntities, true);
if (!sentEntities.c_vector().v.isEmpty()) {
sendFlags |= MTPmessages_SendMessage::flag_entities;
}
_saveEditMsgRequestId = MTP::send(MTPchannels_EditMessage(MTP_int(sendFlags), _history->peer->asChannel()->inputChannel, MTP_int(_editMsgId), MTP_string(sendingText), sentEntities), rpcDone(&HistoryWidget::saveEditMsgDone, _history), rpcFail(&HistoryWidget::saveEditMsgFail, _history));
}
void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req) {
if (App::main()) {
App::main()->sentUpdatesReceived(updates);
}
if (req == _saveEditMsgRequestId) {
_saveEditMsgRequestId = 0;
cancelEdit();
}
if (history->editDraft && history->editDraft->saveRequest == req) {
history->setEditDraft(Nil);
writeDrafts(history);
}
}
bool HistoryWidget::saveEditMsgFail(History *history, const RPCError &error, mtpRequestId req) {
if (mtpIsFlood(error)) return false;
if (req == _saveEditMsgRequestId) {
_saveEditMsgRequestId = 0;
}
if (history->editDraft && history->editDraft->saveRequest == req) {
history->editDraft->saveRequest = 0;
}
QString err = error.type();
if (err == qstr("MESSAGE_ID_INVALID") || err == qstr("CHAT_ADMIN_REQUIRED") || err == qstr("MESSAGE_EDIT_TIME_EXPIRED")) {
Ui::showLayer(new InformBox(lang(lng_edit_error)));
} else if (err == qstr("MESSAGE_NOT_MODIFIED")) {
cancelEdit();
} else if (err == qstr("MESSAGE_EMPTY")) {
_field.selectAll();
_field.setFocus();
} else {
Ui::showLayer(new InformBox(lang(lng_edit_error)));
}
update();
return true;
}
void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
if (!_history) return;
if (_editMsgId) {
saveEditMsg();
return;
}
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(_channel, replyTo));
WebPageId webPageId = _previewCancelled ? CancelledWebPageId : ((_previewData && _previewData->pendingTill >= 0) ? _previewData->id : 0);
App::main()->sendMessage(_history, _field.getLastText(), replyTo, _broadcast.checked(), webPageId);
setFieldText(QString());
@ -4658,7 +4796,7 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
_kbHide.hide();
_cmdStart.hide();
_field.hide();
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
_send.hide();
_unblock.hide();
_botStart.hide();
@ -4846,7 +4984,7 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
QPoint pos(e ? e->pos() : mapFromGlobal(QCursor::pos()));
bool inRecord = _send.geometry().contains(pos);
bool inField = pos.y() >= (_scroll.y() + _scroll.height()) && pos.y() < height() && pos.x() >= 0 && pos.x() < width();
bool inReply = QRect(st::replySkip, _field.y() - st::sendPadding - st::replyHeight, width() - st::replySkip - _replyForwardPreviewCancel.width(), st::replyHeight).contains(pos) && replyToId();
bool inReplyEdit = QRect(st::replySkip, _field.y() - st::sendPadding - st::replyHeight, width() - st::replySkip - _fieldBarCancel.width(), st::replyHeight).contains(pos) && (_editMsgId || replyToId());
bool startAnim = false;
if (inRecord != _inRecord) {
_inRecord = inRecord;
@ -4862,9 +5000,9 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
a_recordCancel.start(_inField ? st::recordCancel->c : st::recordCancelActive->c);
startAnim = true;
}
if (inReply != _inReply) {
_inReply = inReply;
setCursor(inReply ? style::cur_pointer : style::cur_default);
if (inReplyEdit != _inReplyEdit) {
_inReplyEdit = inReplyEdit;
setCursor(inReplyEdit ? style::cur_pointer : style::cur_default);
}
if (startAnim) _a_record.start();
}
@ -5204,8 +5342,9 @@ void HistoryWidget::onKbToggle(bool manual) {
_field.setMaxHeight(st::maxFieldHeight);
_kbReplyTo = 0;
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyToId) {
_replyForwardPreviewCancel.hide();
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_editMsgId && !_replyToId) {
_fieldBarCancel.hide();
updateMouseTracking();
}
} else {
if (_history) {
@ -5223,10 +5362,11 @@ void HistoryWidget::onKbToggle(bool manual) {
_field.setMaxHeight(st::maxFieldHeight);
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
if (_kbReplyTo && !_replyToId) {
if (_kbReplyTo && !_editMsgId && !_replyToId) {
updateReplyToName();
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_replyForwardPreviewCancel.show();
_replyEditMsgText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_fieldBarCancel.show();
updateMouseTracking();
}
if (manual && _history) {
_history->lastKeyboardHiddenId = 0;
@ -5241,10 +5381,11 @@ void HistoryWidget::onKbToggle(bool manual) {
_field.setMaxHeight(st::maxFieldHeight - maxh);
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
if (_kbReplyTo && !_replyToId) {
if (_kbReplyTo && !_editMsgId && !_replyToId) {
updateReplyToName();
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_replyForwardPreviewCancel.show();
_replyEditMsgText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_fieldBarCancel.show();
updateMouseTracking();
}
if (manual && _history) {
_history->lastKeyboardHiddenId = 0;
@ -5414,7 +5555,7 @@ void HistoryWidget::onFieldResize() {
_kbScroll.setGeometry(0, height() - kbh, width(), kbh);
}
_field.move(_attachDocument.x() + _attachDocument.width(), height() - kbh - _field.height() - st::sendPadding);
_replyForwardPreviewCancel.move(width() - _replyForwardPreviewCancel.width(), _field.y() - st::sendPadding - _replyForwardPreviewCancel.height());
_fieldBarCancel.move(width() - _fieldBarCancel.width(), _field.y() - st::sendPadding - _fieldBarCancel.height());
_attachDocument.move(0, height() - kbh - _attachDocument.height());
_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
@ -5454,12 +5595,18 @@ void HistoryWidget::onCheckMentionDropdown() {
}
void HistoryWidget::updateFieldPlaceholder() {
if (_inlineBot && _inlineBot != InlineBotLookingUpData) {
_field.setPlaceholder(_inlineBot->botInfo->inlinePlaceholder.mid(1), _inlineBot->username.size() + 2);
} else if (hasBroadcastToggle()) {
_field.setPlaceholder(lang(_broadcast.checked() ? lng_broadcast_ph : lng_comment_ph));
if (_editMsgId) {
_field.setPlaceholder(lang(lng_edit_message_text));
_send.setText(lang(lng_settings_save));
} else {
_field.setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_peer->asChannel()->canPublish() ? lng_broadcast_ph : lng_comment_ph) : lng_message_ph));
if (_inlineBot && _inlineBot != InlineBotLookingUpData) {
_field.setPlaceholder(_inlineBot->botInfo->inlinePlaceholder.mid(1), _inlineBot->username.size() + 2);
} else if (hasBroadcastToggle()) {
_field.setPlaceholder(lang(_broadcast.checked() ? lng_broadcast_ph : lng_comment_ph));
} else {
_field.setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_peer->asChannel()->canPublish() ? lng_broadcast_ph : lng_comment_ph) : lng_message_ph));
}
_send.setText(lang(lng_send_button));
}
}
@ -5896,7 +6043,7 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
_attachDocument.move(0, height() - kbh - _attachDocument.height());
_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
_replyForwardPreviewCancel.move(width() - _replyForwardPreviewCancel.width(), _field.y() - st::sendPadding - _replyForwardPreviewCancel.height());
_fieldBarCancel.move(width() - _fieldBarCancel.width(), _field.y() - st::sendPadding - _fieldBarCancel.height());
updateListSize(App::main() ? App::main()->contentScrollAddToY() : 0);
bool kbShowShown = _history && !_kbShown && _keyboard.hasMarkup();
@ -5945,8 +6092,12 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
void HistoryWidget::itemRemoved(HistoryItem *item) {
if (_list) _list->itemRemoved(item);
if (item == _replyTo) {
cancelReply();
if (item == _replyEditMsg) {
if (_editMsgId) {
cancelEdit();
} else {
cancelReply();
}
}
if (item == _replyReturn) {
calcNextReplyReturn();
@ -5980,7 +6131,7 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
if (_canSendMessages) {
newScrollHeight -= (_field.height() + 2 * st::sendPadding);
}
if (replyToId() || readyToForward() || (_previewData && _previewData->pendingTill >= 0)) {
if (_editMsgId || replyToId() || readyToForward() || (_previewData && _previewData->pendingTill >= 0)) {
newScrollHeight -= st::replyHeight;
}
if (_kbShown) {
@ -6163,22 +6314,22 @@ void HistoryWidget::updateBotKeyboard(History *h) {
bool changed = false;
bool wasVisible = _kbShown || _kbReplyTo;
if ((_replyToId && !_replyTo) || !_history) {
if ((_replyToId && !_replyEditMsg) || _editMsgId || !_history) {
changed = _keyboard.updateMarkup(0);
} else if (_replyTo) {
changed = _keyboard.updateMarkup(_replyTo);
} else if (_replyToId && _replyEditMsg) {
changed = _keyboard.updateMarkup(_replyEditMsg);
} else {
changed = _keyboard.updateMarkup(_history->lastKeyboardId ? App::histItemById(_channel, _history->lastKeyboardId) : 0);
}
updateCmdStartShown();
if (!changed) return;
bool hasMarkup = _keyboard.hasMarkup(), forceReply = _keyboard.forceReply() && !_replyTo;
bool hasMarkup = _keyboard.hasMarkup(), forceReply = _keyboard.forceReply() && (!_replyToId || !_replyEditMsg);
if (hasMarkup || forceReply) {
if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) {
_history->lastKeyboardHiddenId = _history->lastKeyboardId;
}
if (!isBotStart() && !isBlocked() && _canSendMessages && (wasVisible || _replyTo || (!_field.hasSendText() && !kbWasHidden()))) {
if (!isBotStart() && !isBlocked() && _canSendMessages && (wasVisible || (_replyToId && _replyEditMsg) || (!_field.hasSendText() && !kbWasHidden()))) {
if (!_a_show.animating()) {
if (hasMarkup) {
_kbScroll.show();
@ -6198,8 +6349,9 @@ void HistoryWidget::updateBotKeyboard(History *h) {
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
if (_kbReplyTo && !_replyToId) {
updateReplyToName();
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_replyForwardPreviewCancel.show();
_replyEditMsgText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_fieldBarCancel.show();
updateMouseTracking();
}
} else {
if (!_a_show.animating()) {
@ -6213,7 +6365,8 @@ void HistoryWidget::updateBotKeyboard(History *h) {
_kbShown = false;
_kbReplyTo = 0;
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyToId) {
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
updateMouseTracking();
}
}
} else {
@ -6227,8 +6380,9 @@ void HistoryWidget::updateBotKeyboard(History *h) {
_field.setMaxHeight(st::maxFieldHeight);
_kbShown = false;
_kbReplyTo = 0;
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyToId) {
_replyForwardPreviewCancel.hide();
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyToId && !_editMsgId) {
_fieldBarCancel.hide();
updateMouseTracking();
}
}
resizeEvent(0);
@ -6271,7 +6425,7 @@ void HistoryWidget::updateCollapseCommentsVisibility() {
void HistoryWidget::mousePressEvent(QMouseEvent *e) {
_replyForwardPressed = QRect(0, _field.y() - st::sendPadding - st::replyHeight, st::replySkip, st::replyHeight).contains(e->pos());
if (_replyForwardPressed && !_replyForwardPreviewCancel.isHidden()) {
if (_replyForwardPressed && !_fieldBarCancel.isHidden()) {
updateField();
} else if (_inRecord && cHasAudioCapture()) {
audioCapture()->start();
@ -6285,8 +6439,8 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
a_recordDown.start(1);
a_recordOver.restart();
_a_record.start();
} else if (_inReply) {
Ui::showPeerHistory(_peer, replyToId());
} else if (_inReplyEdit) {
Ui::showPeerHistory(_peer, _editMsgId ? _editMsgId : replyToId());
}
}
@ -6615,16 +6769,25 @@ void HistoryWidget::onReplyToMessage() {
App::main()->cancelForwarding();
_replyTo = to;
_replyToId = to->id;
_replyToText.setText(st::msgFont, _replyTo->inDialogsText(), _textDlgOptions);
if (_editMsgId) {
if (!_history->msgDraft) {
_history->setMsgDraft(new HistoryDraft(QString(), to->id, MessageCursor(), false));
} else {
_history->msgDraft->msgId = to->id;
}
} else {
_replyEditMsg = to;
_replyToId = to->id;
_replyEditMsgText.setText(st::msgFont, _replyEditMsg->inDialogsText(), _textDlgOptions);
updateBotKeyboard();
updateBotKeyboard();
if (!_field.isHidden()) _replyForwardPreviewCancel.show();
updateReplyToName();
resizeEvent(0);
updateField();
if (!_field.isHidden()) _fieldBarCancel.show();
updateMouseTracking();
updateReplyToName();
resizeEvent(0);
updateField();
}
_saveDraftText = true;
_saveDraftStart = getms();
@ -6642,7 +6805,42 @@ void HistoryWidget::onEditMessage() {
Ui::showLayer(box);
} else {
delete box;
// edit post
if (_replyToId || !_field.getLastText().isEmpty()) {
_history->setMsgDraft(new HistoryDraft(_field, _replyToId, _previewCancelled));
} else {
_history->setMsgDraft(Nil);
}
QString text(textApplyEntities(to->originalText(), to->originalEntities()));
_history->setEditDraft(new HistoryEditDraft(text, to->id, MessageCursor(text.size(), text.size(), QFIXED_MAX), false));
applyDraft(false);
_previewData = 0;
if (HistoryMedia *media = to->getMedia()) {
if (media->type() == MediaTypeWebPage) {
_previewData = static_cast<HistoryWebPage*>(media)->webpage();
updatePreview();
}
}
if (!_previewData) {
onPreviewParse();
}
updateBotKeyboard();
if (!_field.isHidden()) _fieldBarCancel.show();
updateFieldPlaceholder();
updateMouseTracking();
updateReplyToName();
resizeEvent(0);
updateField();
_saveDraftText = true;
_saveDraftStart = getms();
onDraftSave();
_field.setFocus();
}
}
@ -6652,37 +6850,77 @@ bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
}
void HistoryWidget::cancelReply(bool lastKeyboardUsed) {
bool wasReply = _replyToId || (_history && _history->msgDraft && _history->msgDraft->msgId);
if (_replyToId) {
_replyTo = 0;
_replyEditMsg = 0;
_replyToId = 0;
mouseMoveEvent(0);
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_kbReplyTo) {
_replyForwardPreviewCancel.hide();
_fieldBarCancel.hide();
updateMouseTracking();
}
updateBotKeyboard();
resizeEvent(0);
update();
} else if (wasReply) {
if (_history->msgDraft->text.isEmpty()) {
_history->setMsgDraft(Nil);
} else {
_history->msgDraft->msgId = 0;
}
}
if (wasReply) {
_saveDraftText = true;
_saveDraftStart = getms();
onDraftSave();
}
if (_keyboard.singleUse() && _keyboard.forceReply() && lastKeyboardUsed) {
if (!_editMsgId && _keyboard.singleUse() && _keyboard.forceReply() && lastKeyboardUsed) {
if (_kbReplyTo) {
onKbToggle(false);
}
}
}
void HistoryWidget::cancelEdit() {
if (!_editMsgId) return;
_editMsgId = 0;
_replyEditMsg = 0;
_history->setEditDraft(Nil);
applyDraft();
if (_saveEditMsgRequestId) {
MTP::cancel(_saveEditMsgRequestId);
_saveEditMsgRequestId = 0;
}
_saveDraftText = true;
_saveDraftStart = getms();
onDraftSave();
mouseMoveEvent(0);
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !replyToId()) {
_fieldBarCancel.hide();
updateMouseTracking();
}
onTextChange();
updateBotKeyboard();
updateFieldPlaceholder();
resizeEvent(0);
update();
}
void HistoryWidget::cancelForwarding() {
updateControlsVisibility();
resizeEvent(0);
update();
}
void HistoryWidget::onReplyForwardPreviewCancel() {
void HistoryWidget::onFieldBarCancel() {
_replyForwardPressed = false;
if (_previewData && _previewData->pendingTill >= 0) {
_previewCancelled = true;
@ -6691,6 +6929,8 @@ void HistoryWidget::onReplyForwardPreviewCancel() {
_saveDraftText = true;
_saveDraftStart = getms();
onDraftSave();
} else if (_editMsgId) {
cancelEdit();
} else if (readyToForward()) {
App::main()->cancelForwarding();
} else if (_replyToId) {
@ -6717,7 +6957,10 @@ void HistoryWidget::previewCancel() {
_previewData = 0;
_previewLinks.clear();
updatePreview();
if (!_replyToId && !readyToForward() && !_kbReplyTo) _replyForwardPreviewCancel.hide();
if (!_editMsgId && !_replyToId && !readyToForward() && !_kbReplyTo) {
_fieldBarCancel.hide();
updateMouseTracking();
}
}
void HistoryWidget::onPreviewParse() {
@ -6781,7 +7024,8 @@ void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtp
void HistoryWidget::updatePreview() {
_previewTimer.stop();
if (_previewData && _previewData->pendingTill >= 0) {
_replyForwardPreviewCancel.show();
_fieldBarCancel.show();
updateMouseTracking();
if (_previewData->pendingTill) {
_previewTitle.setText(st::msgServiceNameFont, lang(lng_preview_loading), _textNameOptions);
_previewDescription.setText(st::msgFont, _previewLinks.splitRef(' ').at(0).toString(), _textDlgOptions);
@ -6818,8 +7062,9 @@ void HistoryWidget::updatePreview() {
_previewTitle.setText(st::msgServiceNameFont, title, _textNameOptions);
_previewDescription.setText(st::msgFont, desc, _textDlgOptions);
}
} else if (!readyToForward() && !replyToId()) {
_replyForwardPreviewCancel.hide();
} else if (!readyToForward() && !replyToId() && !_editMsgId) {
_fieldBarCancel.hide();
updateMouseTracking();
}
resizeEvent(0);
update();
@ -7035,19 +7280,28 @@ void HistoryWidget::updateTopBarSelection() {
update();
}
void HistoryWidget::updateReplyTo(bool force) {
if (!_replyToId || _replyTo) return;
_replyTo = App::histItemById(_channel, _replyToId);
if (_replyTo) {
_replyToText.setText(st::msgFont, _replyTo->inDialogsText(), _textDlgOptions);
void HistoryWidget::updateReplyEditTexts(bool force) {
if (_replyEditMsg || (!_editMsgId && !_replyToId)) {
return;
}
_replyEditMsg = App::histItemById(_channel, _editMsgId ? _editMsgId : _replyToId);
if (_replyEditMsg) {
_replyEditMsgText.setText(st::msgFont, _replyEditMsg->inDialogsText(), _textDlgOptions);
updateBotKeyboard();
if (!_field.isHidden() || _recording) _replyForwardPreviewCancel.show();
if (!_field.isHidden() || _recording) {
_fieldBarCancel.show();
updateMouseTracking();
}
updateReplyToName();
updateField();
} else if (force) {
cancelReply();
if (_editMsgId) {
cancelEdit();
} else {
cancelReply();
}
}
}
@ -7061,9 +7315,10 @@ void HistoryWidget::updateForwarding(bool force) {
}
void HistoryWidget::updateReplyToName() {
if (!_replyTo && (_replyToId || !_kbReplyTo)) return;
_replyToName.setText(st::msgServiceNameFont, App::peerName((_replyTo ? _replyTo : _kbReplyTo)->author()), _textNameOptions);
_replyToNameVersion = (_replyTo ? _replyTo : _kbReplyTo)->author()->nameVersion;
if (_editMsgId) return;
if (!_replyEditMsg && (_replyToId || !_kbReplyTo)) return;
_replyToName.setText(st::msgServiceNameFont, App::peerName((_replyEditMsg ? _replyEditMsg : _kbReplyTo)->author()), _textNameOptions);
_replyToNameVersion = (_replyEditMsg ? _replyEditMsg : _kbReplyTo)->author()->nameVersion;
}
void HistoryWidget::updateField() {
@ -7076,9 +7331,9 @@ void HistoryWidget::drawField(Painter &p) {
Text *from = 0, *text = 0;
bool serviceColor = false, hasForward = readyToForward();
ImagePtr preview;
HistoryItem *drawReplyTo = _replyToId ? _replyTo : _kbReplyTo;
if (_replyToId || (!hasForward && _kbReplyTo)) {
if (drawReplyTo && drawReplyTo->author()->nameVersion > _replyToNameVersion) {
HistoryItem *drawMsgText = (_editMsgId || _replyToId) ? _replyEditMsg : _kbReplyTo;
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
if (!_editMsgId && drawMsgText && drawMsgText->author()->nameVersion > _replyToNameVersion) {
updateReplyToName();
}
backy -= st::replyHeight;
@ -7093,27 +7348,32 @@ void HistoryWidget::drawField(Painter &p) {
}
bool drawPreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
p.fillRect(0, backy, width(), backh, st::taMsgField.bgColor->b);
if (_replyToId || (!hasForward && _kbReplyTo)) {
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
int32 replyLeft = st::replySkip;
p.drawPixmap(QPoint(st::replyIconPos.x(), backy + st::replyIconPos.y()), App::sprite(), st::replyIcon);
p.drawPixmap(QPoint(st::replyIconPos.x(), backy + st::replyIconPos.y()), App::sprite(), _editMsgId ? st::editIcon : st::replyIcon);
if (!drawPreview) {
if (drawReplyTo) {
if (drawReplyTo->getMedia() && drawReplyTo->getMedia()->hasReplyPreview()) {
ImagePtr replyPreview = drawReplyTo->getMedia()->replyPreview();
if (drawMsgText) {
if (drawMsgText->getMedia() && drawMsgText->getMedia()->hasReplyPreview()) {
ImagePtr replyPreview = drawMsgText->getMedia()->replyPreview();
if (!replyPreview->isNull()) {
QRect to(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height()));
}
replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
}
p.setPen(st::replyColor->p);
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _replyForwardPreviewCancel.width() - st::msgReplyPadding.right());
p.setPen((((drawReplyTo->toHistoryMessage() && drawReplyTo->toHistoryMessage()->emptyText()) || drawReplyTo->serviceMsg()) ? st::msgInDateFg : st::msgColor)->p);
_replyToText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - replyLeft - _replyForwardPreviewCancel.width() - st::msgReplyPadding.right());
p.setPen(st::replyColor);
if (_editMsgId) {
p.setFont(st::msgServiceNameFont);
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->ascent, lang(lng_edit_message));
} else {
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel.width() - st::msgReplyPadding.right());
}
p.setPen((((drawMsgText->toHistoryMessage() && drawMsgText->toHistoryMessage()->emptyText()) || drawMsgText->serviceMsg()) ? st::msgInDateFg : st::msgColor)->p);
_replyEditMsgText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - replyLeft - _fieldBarCancel.width() - st::msgReplyPadding.right());
} else {
p.setFont(st::msgDateFont->f);
p.setPen(st::msgInDateFg->p);
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - replyLeft - _replyForwardPreviewCancel.width() - st::msgReplyPadding.right()));
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - replyLeft - _fieldBarCancel.width() - st::msgReplyPadding.right()));
}
}
} else if (from && text) {
@ -7131,9 +7391,9 @@ void HistoryWidget::drawField(Painter &p) {
forwardLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
}
p.setPen(st::replyColor->p);
from->drawElided(p, forwardLeft, backy + st::msgReplyPadding.top(), width() - forwardLeft - _replyForwardPreviewCancel.width() - st::msgReplyPadding.right());
from->drawElided(p, forwardLeft, backy + st::msgReplyPadding.top(), width() - forwardLeft - _fieldBarCancel.width() - st::msgReplyPadding.right());
p.setPen((serviceColor ? st::msgInDateFg : st::msgColor)->p);
text->drawElided(p, forwardLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - forwardLeft - _replyForwardPreviewCancel.width() - st::msgReplyPadding.right());
text->drawElided(p, forwardLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - forwardLeft - _fieldBarCancel.width() - st::msgReplyPadding.right());
}
}
if (drawPreview) {
@ -7153,9 +7413,9 @@ void HistoryWidget::drawField(Painter &p) {
previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
}
p.setPen(st::replyColor->p);
_previewTitle.drawElided(p, previewLeft, backy + st::msgReplyPadding.top(), width() - previewLeft - _replyForwardPreviewCancel.width() - st::msgReplyPadding.right());
_previewTitle.drawElided(p, previewLeft, backy + st::msgReplyPadding.top(), width() - previewLeft - _fieldBarCancel.width() - st::msgReplyPadding.right());
p.setPen(st::msgColor->p);
_previewDescription.drawElided(p, previewLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - previewLeft - _replyForwardPreviewCancel.width() - st::msgReplyPadding.right());
_previewDescription.drawElided(p, previewLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - previewLeft - _fieldBarCancel.width() - st::msgReplyPadding.right());
}
}

View File

@ -505,9 +505,10 @@ public:
void updateScrollColors();
MsgId replyToId() const;
void updateReplyTo(bool force = false);
void updateReplyEditTexts(bool force = false);
bool lastForceReplyReplied(const FullMsgId &replyTo = FullMsgId(NoChannel, -1)) const;
void cancelReply(bool lastKeyboardUsed = false);
void cancelEdit();
void updateForwarding(bool force = false);
void cancelForwarding(); // called by MainWidget
@ -595,7 +596,7 @@ public slots:
void onCancel();
void onReplyToMessage();
void onEditMessage();
void onReplyForwardPreviewCancel();
void onFieldBarCancel();
void onCancelSendAction();
@ -689,12 +690,17 @@ public slots:
private:
MsgId _replyToId;
HistoryItem *_replyTo;
Text _replyToName, _replyToText;
Text _replyToName;
int32 _replyToNameVersion;
IconedButton _replyForwardPreviewCancel;
void updateReplyToName();
MsgId _editMsgId;
HistoryItem *_replyEditMsg;
Text _replyEditMsgText;
IconedButton _fieldBarCancel;
void sendExistingDocument(DocumentData *doc, const QString &caption);
void sendExistingPhoto(PhotoData *photo, const QString &caption);
@ -702,6 +708,13 @@ private:
void drawRecordButton(Painter &p);
void drawRecording(Painter &p);
void updateMouseTracking();
mtpRequestId _saveEditMsgRequestId;
void saveEditMsg();
void saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req);
bool saveEditMsgFail(History *history, const RPCError &error, mtpRequestId req);
DBIPeerReportSpamStatus _reportSpamStatus;
void updateReportSpamStatus();
@ -747,7 +760,8 @@ private:
void savedGifsGot(const MTPmessages_SavedGifs &gifs);
bool savedGifsFailed(const RPCError &error);
void writeDraft(MsgId *replyTo = 0, const QString *text = 0, const MessageCursor *cursor = 0, bool *previewCancelled = 0);
void writeDrafts(HistoryDraft **msgDraft, HistoryEditDraft **editDraft);
void writeDrafts(History *history);
void setFieldText(const QString &text, int32 textUpdateEventsFlags = 0, bool clearUndoHistory = true);
QStringList getMediasFromMime(const QMimeData *d);
@ -806,7 +820,7 @@ private:
bool _cmdStartShown;
MessageField _field;
Animation _a_record, _a_recording;
bool _recording, _inRecord, _inField, _inReply;
bool _recording, _inRecord, _inField, _inReplyEdit;
anim::ivalue a_recordingLevel;
int32 _recordingSamples;
anim::fvalue a_recordOver, a_recordDown;

View File

@ -557,7 +557,7 @@ namespace {
};
typedef QMap<PeerId, FileKey> DraftsMap;
DraftsMap _draftsMap, _draftsPositionsMap;
DraftsMap _draftsMap, _draftCursorsMap;
typedef QMap<PeerId, bool> DraftsNotReadMap;
DraftsNotReadMap _draftsNotReadMap;
@ -1672,7 +1672,7 @@ namespace {
}
LOG(("App Info: reading encrypted map.."));
DraftsMap draftsMap, draftsPositionsMap;
DraftsMap draftsMap, draftCursorsMap;
DraftsNotReadMap draftsNotReadMap;
StorageMap imagesMap, stickerImagesMap, audiosMap;
qint64 storageImagesSize = 0, storageStickersSize = 0, storageAudiosSize = 0;
@ -1701,7 +1701,7 @@ namespace {
FileKey key;
quint64 p;
map.stream >> key >> p;
draftsPositionsMap.insert(p, key);
draftCursorsMap.insert(p, key);
}
} break;
case lskImages: {
@ -1781,7 +1781,7 @@ namespace {
}
_draftsMap = draftsMap;
_draftsPositionsMap = draftsPositionsMap;
_draftCursorsMap = draftCursorsMap;
_draftsNotReadMap = draftsNotReadMap;
_imagesMap = imagesMap;
@ -1860,7 +1860,7 @@ namespace {
uint32 mapSize = 0;
if (!_draftsMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _draftsMap.size() * sizeof(quint64) * 2;
if (!_draftsPositionsMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _draftsPositionsMap.size() * sizeof(quint64) * 2;
if (!_draftCursorsMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _draftCursorsMap.size() * sizeof(quint64) * 2;
if (!_imagesMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _imagesMap.size() * (sizeof(quint64) * 3 + sizeof(qint32));
if (!_stickerImagesMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _stickerImagesMap.size() * (sizeof(quint64) * 3 + sizeof(qint32));
if (!_audiosMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _audiosMap.size() * (sizeof(quint64) * 3 + sizeof(qint32));
@ -1880,9 +1880,9 @@ namespace {
mapData.stream << quint64(i.value()) << quint64(i.key());
}
}
if (!_draftsPositionsMap.isEmpty()) {
mapData.stream << quint32(lskDraftPosition) << quint32(_draftsPositionsMap.size());
for (DraftsMap::const_iterator i = _draftsPositionsMap.cbegin(), e = _draftsPositionsMap.cend(); i != e; ++i) {
if (!_draftCursorsMap.isEmpty()) {
mapData.stream << quint32(lskDraftPosition) << quint32(_draftCursorsMap.size());
for (DraftsMap::const_iterator i = _draftCursorsMap.cbegin(), e = _draftCursorsMap.cend(); i != e; ++i) {
mapData.stream << quint64(i.value()) << quint64(i.key());
}
}
@ -2180,7 +2180,7 @@ namespace Local {
_passKeySalt.clear(); // reset passcode, local key
_draftsMap.clear();
_draftsPositionsMap.clear();
_draftCursorsMap.clear();
_fileLocations.clear();
_fileLocationPairs.clear();
_fileLocationAliases.clear();
@ -2237,10 +2237,10 @@ namespace Local {
return _oldSettingsVersion;
}
void writeDraft(const PeerId &peer, const MessageDraft &draft) {
void writeDrafts(const PeerId &peer, const MessageDraft &msgDraft, const MessageDraft &editDraft) {
if (!_working()) return;
if (draft.replyTo <= 0 && draft.text.isEmpty()) {
if (msgDraft.msgId <= 0 && msgDraft.text.isEmpty() && editDraft.msgId <= 0) {
DraftsMap::iterator i = _draftsMap.find(peer);
if (i != _draftsMap.cend()) {
clearKey(i.value());
@ -2257,8 +2257,12 @@ namespace Local {
_mapChanged = true;
_writeMap(WriteMapFast);
}
EncryptedDescriptor data(sizeof(quint64) + _stringSize(draft.text) + sizeof(qint32));
data.stream << quint64(peer) << draft.text << qint32(draft.replyTo) << qint32(draft.previewCancelled ? 1 : 0);
EncryptedDescriptor data(sizeof(quint64) + _stringSize(msgDraft.text) + 2 * sizeof(qint32) + _stringSize(editDraft.text) + 2 * sizeof(qint32));
data.stream << quint64(peer);
data.stream << msgDraft.text << qint32(msgDraft.msgId) << qint32(msgDraft.previewCancelled ? 1 : 0);
data.stream << editDraft.text << qint32(editDraft.msgId) << qint32(editDraft.previewCancelled ? 1 : 0);
FileWriteDescriptor file(i.value());
file.writeEncrypted(data);
@ -2266,75 +2270,123 @@ namespace Local {
}
}
MessageDraft readDraft(const PeerId &peer) {
if (!_draftsNotReadMap.remove(peer)) return MessageDraft();
void clearDraftCursors(const PeerId &peer) {
DraftsMap::iterator i = _draftCursorsMap.find(peer);
if (i != _draftCursorsMap.cend()) {
clearKey(i.value());
_draftCursorsMap.erase(i);
_mapChanged = true;
_writeMap();
}
}
void _readDraftCursors(const PeerId &peer, MessageCursor &msgCursor, MessageCursor &editCursor) {
DraftsMap::iterator j = _draftCursorsMap.find(peer);
if (j == _draftCursorsMap.cend()) {
return;
}
FileReadDescriptor draft;
if (!readEncryptedFile(draft, j.value())) {
clearDraftCursors(peer);
return;
}
quint64 draftPeer;
qint32 msgPosition = 0, msgAnchor = 0, msgScroll = QFIXED_MAX;
qint32 editPosition = 0, editAnchor = 0, editScroll = QFIXED_MAX;
draft.stream >> draftPeer >> msgPosition >> msgAnchor >> msgScroll;
if (!draft.stream.atEnd()) {
draft.stream >> editPosition >> editAnchor >> editScroll;
}
if (draftPeer != peer) {
clearDraftCursors(peer);
return;
}
msgCursor = MessageCursor(msgPosition, msgAnchor, msgScroll);
editCursor = MessageCursor(editPosition, editAnchor, editScroll);
}
void readDraftsWithCursors(History *h) {
PeerId peer = h->peer->id;
if (!_draftsNotReadMap.remove(peer)) {
clearDraftCursors(peer);
return;
}
DraftsMap::iterator j = _draftsMap.find(peer);
if (j == _draftsMap.cend()) {
return MessageDraft();
clearDraftCursors(peer);
return;
}
FileReadDescriptor draft;
if (!readEncryptedFile(draft, j.value())) {
clearKey(j.value());
_draftsMap.erase(j);
return MessageDraft();
clearDraftCursors(peer);
return;
}
quint64 draftPeer;
QString draftText;
qint32 draftReplyTo = 0, draftPreviewCancelled = 0;
draft.stream >> draftPeer >> draftText;
if (draft.version >= 7021) draft.stream >> draftReplyTo;
if (draft.version >= 8001) draft.stream >> draftPreviewCancelled;
return (draftPeer == peer) ? MessageDraft(MsgId(draftReplyTo), draftText, (draftPreviewCancelled == 1)) : MessageDraft();
quint64 draftPeer = 0;
QString msgText, editText;
qint32 msgReplyTo = 0, msgPreviewCancelled = 0, editMsgId = 0, editPreviewCancelled = 0;
draft.stream >> draftPeer >> msgText;
if (draft.version >= 7021) {
draft.stream >> msgReplyTo;
if (draft.version >= 8001) {
draft.stream >> msgPreviewCancelled;
if (!draft.stream.atEnd()) {
draft.stream >> editText >> editMsgId >> editPreviewCancelled;
}
}
}
if (draftPeer != peer) {
clearKey(j.value());
_draftsMap.erase(j);
clearDraftCursors(peer);
return;
}
MessageCursor msgCursor, editCursor;
_readDraftCursors(peer, msgCursor, editCursor);
if (msgText.isEmpty() && !msgReplyTo) {
h->setMsgDraft(Nil);
} else {
h->setMsgDraft(new HistoryDraft(msgText, msgReplyTo, msgCursor, msgPreviewCancelled));
}
if (!editMsgId) {
h->setEditDraft(Nil);
} else {
h->setEditDraft(new HistoryEditDraft(editText, editMsgId, editCursor, editPreviewCancelled));
}
}
void writeDraftPositions(const PeerId &peer, const MessageCursor &cur) {
void writeDraftCursors(const PeerId &peer, const MessageCursor &msgCursor, const MessageCursor &editCursor) {
if (!_working()) return;
if (cur.position == 0 && cur.anchor == 0 && cur.scroll == QFIXED_MAX) {
DraftsMap::iterator i = _draftsPositionsMap.find(peer);
if (i != _draftsPositionsMap.cend()) {
clearKey(i.value());
_draftsPositionsMap.erase(i);
_mapChanged = true;
_writeMap();
}
if (msgCursor == MessageCursor() && editCursor == MessageCursor()) {
clearDraftCursors(peer);
} else {
DraftsMap::const_iterator i = _draftsPositionsMap.constFind(peer);
if (i == _draftsPositionsMap.cend()) {
i = _draftsPositionsMap.insert(peer, genKey());
DraftsMap::const_iterator i = _draftCursorsMap.constFind(peer);
if (i == _draftCursorsMap.cend()) {
i = _draftCursorsMap.insert(peer, genKey());
_mapChanged = true;
_writeMap(WriteMapFast);
}
EncryptedDescriptor data(sizeof(quint64) + sizeof(qint32) * 3);
data.stream << quint64(peer) << qint32(cur.position) << qint32(cur.anchor) << qint32(cur.scroll);
data.stream << quint64(peer) << qint32(msgCursor.position) << qint32(msgCursor.anchor) << qint32(msgCursor.scroll);
data.stream << qint32(editCursor.position) << qint32(editCursor.anchor) << qint32(editCursor.scroll);
FileWriteDescriptor file(i.value());
file.writeEncrypted(data);
}
}
MessageCursor readDraftPositions(const PeerId &peer) {
DraftsMap::iterator j = _draftsPositionsMap.find(peer);
if (j == _draftsPositionsMap.cend()) {
return MessageCursor();
}
FileReadDescriptor draft;
if (!readEncryptedFile(draft, j.value())) {
clearKey(j.value());
_draftsPositionsMap.erase(j);
return MessageCursor();
}
quint64 draftPeer;
qint32 curPosition, curAnchor, curScroll;
draft.stream >> draftPeer >> curPosition >> curAnchor >> curScroll;
return (draftPeer == peer) ? MessageCursor(curPosition, curAnchor, curScroll) : MessageCursor();
}
bool hasDraftPositions(const PeerId &peer) {
return (_draftsPositionsMap.constFind(peer) != _draftsPositionsMap.cend());
bool hasDraftCursors(const PeerId &peer) {
return (_draftCursorsMap.constFind(peer) != _draftCursorsMap.cend());
}
void writeFileLocation(MediaKey location, const FileLocation &local) {
@ -3795,8 +3847,8 @@ namespace Local {
_draftsMap.clear();
_mapChanged = true;
}
if (!_draftsPositionsMap.isEmpty()) {
_draftsPositionsMap.clear();
if (!_draftCursorsMap.isEmpty()) {
_draftCursorsMap.clear();
_mapChanged = true;
}
if (_locationsKey) {

View File

@ -106,17 +106,16 @@ namespace Local {
int32 oldSettingsVersion();
struct MessageDraft {
MessageDraft(MsgId replyTo = 0, QString text = QString(), bool previewCancelled = false) : replyTo(replyTo), text(text), previewCancelled(previewCancelled) {
MessageDraft(MsgId msgId = 0, QString text = QString(), bool previewCancelled = false) : msgId(msgId), text(text), previewCancelled(previewCancelled) {
}
MsgId replyTo;
MsgId msgId;
QString text;
bool previewCancelled;
};
void writeDraft(const PeerId &peer, const MessageDraft &draft);
MessageDraft readDraft(const PeerId &peer);
void writeDraftPositions(const PeerId &peer, const MessageCursor &cur);
MessageCursor readDraftPositions(const PeerId &peer);
bool hasDraftPositions(const PeerId &peer);
void writeDrafts(const PeerId &peer, const MessageDraft &msgDraft, const MessageDraft &editDraft);
void readDraftsWithCursors(History *h);
void writeDraftCursors(const PeerId &peer, const MessageCursor &msgCursor, const MessageCursor &editCursor);
bool hasDraftCursors(const PeerId &peer);
void writeFileLocation(MediaKey location, const FileLocation &local);
FileLocation readFileLocation(MediaKey location, bool check = true);

View File

@ -516,10 +516,8 @@ bool MainWidget::onShareUrl(const PeerId &peer, const QString &url, const QStrin
return false;
}
History *h = App::history(peer);
h->draft = url + '\n' + text;
h->draftCursor.anchor = url.size() + 1;
h->draftCursor.position = h->draftCursor.anchor + text.size();
h->draftPreviewCancelled = false;
h->setMsgDraft(new HistoryDraft(url + '\n' + text, 0, MessageCursor(url.size() + 1, url.size() + 1 + text.size(), QFIXED_MAX), false));
h->setEditDraft(Nil);
bool opened = history.peer() && (history.peer()->id == peer);
if (opened) {
history.applyDraft();
@ -2039,7 +2037,7 @@ ApiWrap *MainWidget::api() {
}
void MainWidget::updateReplyTo() {
history.updateReplyTo(true);
history.updateReplyEditTexts(true);
}
void MainWidget::updateBotKeyboard(History *h) {

View File

@ -1217,3 +1217,7 @@ struct MessageCursor {
}
int position, anchor, scroll;
};
inline bool operator==(const MessageCursor &a, const MessageCursor &b) {
return (a.position == b.position) && (a.anchor == b.anchor) && (a.scroll == b.scroll);
}

View File

@ -35,6 +35,8 @@ uint64 _SharedMemoryLocation[4] = { 0x00, 0x01, 0x02, 0x03 };
// Base types compile-time check
NilPointer Nil;
namespace {
template <typename T, int N>
class _TypeSizeCheckerHelper {

View File

@ -36,6 +36,22 @@ T *exchange(T *&ptr) {
struct NullType {
};
class NilPointer {
public:
template <typename T>
operator T*() const {
return 0;
}
template <typename C, typename T>
operator T C::*() const {
return 0;
}
private:
void operator&() const;
};
extern NilPointer Nil;
template <typename T>
class OrderedSet : public QMap<T, NullType> {
public:

View File

@ -34,8 +34,8 @@ IDI_ICON1 ICON "SourceFiles\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,9,26,0
PRODUCTVERSION 0,9,26,0
FILEVERSION 0,9,26,1
PRODUCTVERSION 0,9,26,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -51,10 +51,10 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileVersion", "0.9.26.0"
VALUE "FileVersion", "0.9.26.1"
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.9.26.0"
VALUE "ProductVersion", "0.9.26.1"
END
END
BLOCK "VarFileInfo"

View File

@ -1739,7 +1739,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 0.9.25;
CURRENT_PROJECT_VERSION = 0.9.26;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = fast;
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
@ -1768,10 +1768,10 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.9.25;
CURRENT_PROJECT_VERSION = 0.9.26;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 0.9;
DYLIB_CURRENT_VERSION = 0.9.25;
DYLIB_CURRENT_VERSION = 0.9.26;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
@ -1909,10 +1909,10 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.9.25;
CURRENT_PROJECT_VERSION = 0.9.26;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 0.9;
DYLIB_CURRENT_VERSION = 0.9.25;
DYLIB_CURRENT_VERSION = 0.9.26;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = "";

View File

@ -3,4 +3,4 @@ AppVersionStrMajor 0.9
AppVersionStrSmall 0.9.26
AppVersionStr 0.9.26
DevChannel 0
BetaVersion 0 9019002
BetaVersion 9026001