diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a6fdfa..efb159c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Bug fixes - build in release mode now no longer spams warnings - build now correctly installs all build plugin libs +- a bug where the correction message was received, the indication was on but the text didn't actually change ### Improvements - reduced amount of places where platform specific path separator is used @@ -13,6 +14,7 @@ - now it's possible to set up different qt styles from settings - if you have KConfig nad KConfigWidgets packages installed - you can chose from global color schemes - it's possible now to chose a folder where squawk is going to store downloaded files +- now you can correct your message ## Squawk 0.2.0 (Jan 10, 2022) ### Bug fixes diff --git a/core/account.cpp b/core/account.cpp index a923690..91d0f2b 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -935,3 +935,7 @@ void Core::Account::requestChangeMessage(const QString& jid, const QString& mess void Core::Account::resendMessage(const QString& jid, const QString& id) { mh->resendMessage(jid, id);} + +void Core::Account::replaceMessage(const QString& originalId, const Shared::Message& data) { + mh->sendMessage(data, false, originalId);} + diff --git a/core/account.h b/core/account.h index 5ba834c..664b547 100644 --- a/core/account.h +++ b/core/account.h @@ -104,6 +104,7 @@ public: void addRoomRequest(const QString& jid, const QString& nick, const QString& password, bool autoJoin); void uploadVCard(const Shared::VCard& card); void resendMessage(const QString& jid, const QString& id); + void replaceMessage(const QString& originalId, const Shared::Message& data); public slots: void connect(); diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index 1e89dd6..559bee3 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -41,10 +41,10 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg) handled = handleGroupMessage(msg); break; case QXmppMessage::Error: { - QString id = msg.id(); - std::map::const_iterator itr = pendingStateMessages.find(id); - if (itr != pendingStateMessages.end()) { - QString jid = itr->second; + std::tuple ids = getOriginalPendingMessageId(msg.id()); + if (std::get<0>(ids)) { + QString id = std::get<1>(ids); + QString jid = std::get<2>(ids); RosterItem* cnt = acc->rh->getRosterItem(jid); QMap cData = { {"state", static_cast(Shared::Message::State::error)}, @@ -53,9 +53,7 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg) if (cnt != 0) { cnt->changeMessage(id, cData); } - ; emit acc->changeMessage(jid, id, cData); - pendingStateMessages.erase(itr); handled = true; } else { qDebug() << "received a message with type \"Error\", not sure what to do with it now, skipping"; @@ -111,7 +109,6 @@ bool Core::MessageHandler::handleGroupMessage(const QXmppMessage& msg, bool outg { const QString& body(msg.body()); if (body.size() != 0) { - QString id = msg.id(); Shared::Message sMsg(Shared::Message::groupChat); initializeMessage(sMsg, msg, outgoing, forwarded, guessing); @@ -121,12 +118,11 @@ bool Core::MessageHandler::handleGroupMessage(const QXmppMessage& msg, bool outg return false; } - std::map::const_iterator pItr = pendingStateMessages.find(id); - if (pItr != pendingStateMessages.end()) { + std::tuple ids = getOriginalPendingMessageId(msg.id()); + if (std::get<0>(ids)) { QMap cData = {{"state", static_cast(Shared::Message::State::delivered)}}; - cnt->changeMessage(id, cData); - pendingStateMessages.erase(pItr); - emit acc->changeMessage(jid, id, cData); + cnt->changeMessage(std::get<1>(ids), cData); + emit acc->changeMessage(std::get<2>(ids), std::get<1>(ids), cData); } else { QString oId = msg.replaceId(); if (oId.size() > 0) { @@ -227,53 +223,70 @@ void Core::MessageHandler::onCarbonMessageSent(const QXmppMessage& msg) handleChatMessage(msg, true, true); } -void Core::MessageHandler::onReceiptReceived(const QString& jid, const QString& id) +std::tuple Core::MessageHandler::getOriginalPendingMessageId(const QString& id) { + std::tuple result({false, "", ""}); std::map::const_iterator itr = pendingStateMessages.find(id); if (itr != pendingStateMessages.end()) { - QMap cData = {{"state", static_cast(Shared::Message::State::delivered)}}; - RosterItem* ri = acc->rh->getRosterItem(itr->second); - if (ri != 0) { - ri->changeMessage(id, cData); + std::get<0>(result) = true; + std::get<2>(result) = itr->second; + + std::map::const_iterator itrC = pendingCorrectionMessages.find(id); + if (itrC != pendingCorrectionMessages.end()) { + std::get<1>(result) = itrC->second; + pendingCorrectionMessages.erase(itrC); + } else { + std::get<1>(result) = itr->first; } - emit acc->changeMessage(itr->second, id, cData); + pendingStateMessages.erase(itr); } + + return result; } -void Core::MessageHandler::sendMessage(const Shared::Message& data, bool newMessage) +void Core::MessageHandler::onReceiptReceived(const QString& jid, const QString& id) { - if (data.getOutOfBandUrl().size() == 0 && data.getAttachPath().size() > 0) { - prepareUpload(data, newMessage); - } else { - performSending(data, newMessage); + std::tuple ids = getOriginalPendingMessageId(id); + if (std::get<0>(ids)) { + QMap cData = {{"state", static_cast(Shared::Message::State::delivered)}}; + RosterItem* ri = acc->rh->getRosterItem(std::get<2>(ids)); + + if (ri != 0) { + ri->changeMessage(std::get<1>(ids), cData); + } + emit acc->changeMessage(std::get<2>(ids), std::get<1>(ids), cData); } } -void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) +void Core::MessageHandler::sendMessage(const Shared::Message& data, bool newMessage, QString originalId) +{ + if (data.getOutOfBandUrl().size() == 0 && data.getAttachPath().size() > 0) { + pendingCorrectionMessages.insert(std::make_pair(data.getId(), originalId)); + prepareUpload(data, newMessage); + } else { + performSending(data, originalId, newMessage); + } +} + +void Core::MessageHandler::performSending(Shared::Message data, const QString& originalId, bool newMessage) { QString jid = data.getPenPalJid(); QString id = data.getId(); - QString oob = data.getOutOfBandUrl(); + qDebug() << "Sending message with id:" << id; + if (originalId.size() > 0) { + qDebug() << "To replace one with id:" << originalId; + } RosterItem* ri = acc->rh->getRosterItem(jid); bool sent = false; - QMap changes; + if (newMessage && originalId.size() > 0) { + newMessage = false; + } QDateTime sendTime = QDateTime::currentDateTimeUtc(); if (acc->state == Shared::ConnectionState::connected) { - QXmppMessage msg(acc->getFullJid(), data.getTo(), data.getBody(), data.getThread()); - -#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0) - msg.setOriginId(id); -#endif - msg.setId(id); - msg.setType(static_cast(data.getType())); //it is safe here, my type is compatible - msg.setOutOfBandUrl(oob); - msg.setReceiptRequested(true); - msg.setStamp(sendTime); + QXmppMessage msg(createPacket(data, sendTime, originalId)); sent = acc->client.sendPacket(msg); - //sent = false; - if (sent) { data.setState(Shared::Message::State::sent); } else { @@ -286,6 +299,39 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) data.setErrorText("You are is offline or reconnecting"); } + QMap changes(getChanges(data, sendTime, newMessage, originalId)); + + QString realId; + if (originalId.size() > 0) { + realId = originalId; + } else { + realId = id; + } + if (ri != 0) { + if (newMessage) { + ri->appendMessageToArchive(data); + } else { + ri->changeMessage(realId, changes); + } + if (sent) { + pendingStateMessages.insert(std::make_pair(id, jid)); + if (originalId.size() > 0) { + pendingCorrectionMessages.insert(std::make_pair(id, originalId)); + } + } else { + pendingStateMessages.erase(id); + pendingCorrectionMessages.erase(id); + } + } + + emit acc->changeMessage(jid, realId, changes); +} + +QMap Core::MessageHandler::getChanges(Shared::Message& data, const QDateTime& time, bool newMessage, const QString& originalId) const +{ + QMap changes; + + QString oob = data.getOutOfBandUrl(); Shared::Message::State mstate = data.getState(); changes.insert("state", static_cast(mstate)); if (mstate == Shared::Message::State::error) { @@ -295,9 +341,12 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) changes.insert("outOfBandUrl", oob); } if (newMessage) { - data.setTime(sendTime); + data.setTime(time); } - changes.insert("stamp", sendTime); + if (originalId.size() > 0) { + changes.insert("body", data.getBody()); + } + changes.insert("stamp", time); //sometimes (when the image is pasted with ctrl+v) //I start sending message with one path, then copy it to downloads directory @@ -310,21 +359,29 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) data.setAttachPath(squawkified); } } - - if (ri != 0) { - if (newMessage) { - ri->appendMessageToArchive(data); - } else { - ri->changeMessage(id, changes); - } - if (sent) { - pendingStateMessages.insert(std::make_pair(id, jid)); - } else { - pendingStateMessages.erase(id); - } + + return changes; +} + +QXmppMessage Core::MessageHandler::createPacket(const Shared::Message& data, const QDateTime& time, const QString& originalId) const +{ + QXmppMessage msg(acc->getFullJid(), data.getTo(), data.getBody(), data.getThread()); + QString id(data.getId()); + + if (originalId.size() > 0) { + msg.setReplaceId(originalId); } - - emit acc->changeMessage(jid, id, changes); + +#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0) + msg.setOriginId(id); +#endif + msg.setId(id); + msg.setType(static_cast(data.getType())); //it is safe here, my type is compatible + msg.setOutOfBandUrl(data.getOutOfBandUrl()); + msg.setReceiptRequested(true); + msg.setStamp(time); + + return msg; } void Core::MessageHandler::prepareUpload(const Shared::Message& data, bool newMessage) @@ -444,7 +501,8 @@ void Core::MessageHandler::onLoadFileError(const std::list& void Core::MessageHandler::handleUploadError(const QString& jid, const QString& messageId, const QString& errorText) { emit acc->uploadFileError(jid, messageId, "Error requesting slot to upload file: " + errorText); - pendingStateMessages.erase(jid); + pendingStateMessages.erase(messageId); + pendingCorrectionMessages.erase(messageId); requestChangeMessage(jid, messageId, { {"state", static_cast(Shared::Message::State::error)}, {"errorText", errorText} @@ -473,11 +531,11 @@ void Core::MessageHandler::sendMessageWithLocalUploadedFile(Shared::Message msg, if (msg.getBody().size() == 0) { //not sure why, but most messages do that msg.setBody(url); //they duplicate oob in body, some of them wouldn't even show an attachment if you don't do that } - performSending(msg, newMessage); + performSending(msg, pendingCorrectionMessages.at(msg.getId()), newMessage); //TODO removal/progress update } -static const std::set allowerToChangeKeys({ +static const std::set allowedToChangeKeys({ "attachPath", "outOfBandUrl", "state", @@ -490,12 +548,12 @@ void Core::MessageHandler::requestChangeMessage(const QString& jid, const QStrin if (cnt != 0) { bool allSupported = true; QString unsupportedString; - for (QMap::const_iterator itr = data.begin(); itr != data.end(); ++itr) { //I need all this madness - if (allowerToChangeKeys.count(itr.key()) != 1) { //to not allow this method - allSupported = false; //to make a message to look like if it was edited - unsupportedString = itr.key(); //basically I needed to control who exaclty calls this method - break; //because the underlying tech assumes that the change is initiated by user - } //not by system + for (QMap::const_iterator itr = data.begin(); itr != data.end(); ++itr) { //I need all this madness + if (allowedToChangeKeys.count(itr.key()) != 1) { //to not allow this method + allSupported = false; //to make a message to look like if it was edited + unsupportedString = itr.key(); //basically I needed to control who exaclty calls this method + break; //because the underlying tech assumes that + } //the change is initiated by user, not by system } if (allSupported) { cnt->changeMessage(messageId, data); @@ -514,7 +572,13 @@ void Core::MessageHandler::resendMessage(const QString& jid, const QString& id) try { Shared::Message msg = cnt->getMessage(id); if (msg.getState() == Shared::Message::State::error) { - sendMessage(msg, false); + if (msg.getEdited()){ + QString originalId = msg.getId(); + msg.generateRandomId(); + sendMessage(msg, false, originalId); + } else { + sendMessage(msg, false); + } } else { qDebug() << "An attempt to resend a message to" << jid << "by account" << acc->getName() << ", but this message seems to have been normally sent, this method was made to retry sending failed to be sent messages, skipping"; } diff --git a/core/handlers/messagehandler.h b/core/handlers/messagehandler.h index 4f03484..1ab2d0d 100644 --- a/core/handlers/messagehandler.h +++ b/core/handlers/messagehandler.h @@ -46,7 +46,7 @@ public: MessageHandler(Account* account); public: - void sendMessage(const Shared::Message& data, bool newMessage = true); + void sendMessage(const Shared::Message& data, bool newMessage = true, QString originalId = ""); void initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing = false, bool forwarded = false, bool guessing = false) const; void resendMessage(const QString& jid, const QString& id); @@ -67,13 +67,17 @@ private: bool handleGroupMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false); void logMessage(const QXmppMessage& msg, const QString& reason = "Message wasn't handled: "); void sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url, bool newMessage = true); - void performSending(Shared::Message data, bool newMessage = true); + void performSending(Shared::Message data, const QString& originalId, bool newMessage = true); void prepareUpload(const Shared::Message& data, bool newMessage = true); void handleUploadError(const QString& jid, const QString& messageId, const QString& errorText); + QXmppMessage createPacket(const Shared::Message& data, const QDateTime& time, const QString& originalId) const; + QMap getChanges(Shared::Message& data, const QDateTime& time, bool newMessage, const QString& originalId) const; + std::tuple getOriginalPendingMessageId(const QString& id); private: Account* acc; std::map pendingStateMessages; //key is message id, value is JID + std::map pendingCorrectionMessages; //key is new mesage, value is originalOne std::deque> uploadingSlotsQueue; }; diff --git a/core/main.cpp b/core/main.cpp index 79ca648..f842c80 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -142,6 +142,7 @@ int main(int argc, char *argv[]) QObject::connect(&w, &Squawk::disconnectAccount, squawk, &Core::Squawk::disconnectAccount); QObject::connect(&w, &Squawk::changeState, squawk, &Core::Squawk::changeState); QObject::connect(&w, &Squawk::sendMessage, squawk,&Core::Squawk::sendMessage); + QObject::connect(&w, &Squawk::replaceMessage, squawk,&Core::Squawk::replaceMessage); QObject::connect(&w, &Squawk::resendMessage, squawk,&Core::Squawk::resendMessage); QObject::connect(&w, &Squawk::requestArchive, squawk, &Core::Squawk::requestArchive); QObject::connect(&w, &Squawk::subscribeContact, squawk, &Core::Squawk::subscribeContact); diff --git a/core/squawk.cpp b/core/squawk.cpp index 9f2b445..af131d5 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -341,6 +341,17 @@ void Core::Squawk::sendMessage(const QString& account, const Shared::Message& da itr->second->sendMessage(data); } +void Core::Squawk::replaceMessage(const QString& account, const QString& originalId, const Shared::Message& data) +{ + AccountsMap::const_iterator itr = amap.find(account); + if (itr == amap.end()) { + qDebug() << "An attempt to replace a message with non existing account" << account << ", skipping"; + return; + } + + itr->second->replaceMessage(originalId, data); +} + void Core::Squawk::resendMessage(const QString& account, const QString& jid, const QString& id) { AccountsMap::const_iterator itr = amap.find(account); diff --git a/core/squawk.h b/core/squawk.h index 738a957..6cd251f 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -101,6 +101,7 @@ public slots: void changeState(Shared::Availability state); void sendMessage(const QString& account, const Shared::Message& data); + void replaceMessage(const QString& account, const QString& originalId, const Shared::Message& data); void resendMessage(const QString& account, const QString& jid, const QString& id); void requestArchive(const QString& account, const QString& jid, int count, const QString& before); diff --git a/shared/message.cpp b/shared/message.cpp index f3f6b45..0e1b3c5 100644 --- a/shared/message.cpp +++ b/shared/message.cpp @@ -404,7 +404,9 @@ bool Shared::Message::change(const QMap& data) correctionDate = QDateTime::currentDateTimeUtc(); //in case there is no information about time of this correction it's applied } if (!edited || lastModified < correctionDate) { - originalMessage = body; + if (!edited) { + originalMessage = body; + } lastModified = correctionDate; setBody(b); setEdited(true); diff --git a/ui/squawk.cpp b/ui/squawk.cpp index e24640a..3ebb6a5 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -497,6 +497,17 @@ void Squawk::onConversationMessage(const Shared::Message& msg) emit sendMessage(acc, msg); } +void Squawk::onConversationReplaceMessage(const QString& originalId, const Shared::Message& msg) +{ + Conversation* conv = static_cast(sender()); + QString acc = conv->getAccount(); + + rosterModel.changeMessage(acc, msg.getPenPalJid(), originalId, { + {"state", static_cast(Shared::Message::State::pending)} + }); + emit replaceMessage(acc, originalId, msg); +} + void Squawk::onConversationResend(const QString& id) { Conversation* conv = static_cast(sender()); @@ -958,6 +969,7 @@ void Squawk::subscribeConversation(Conversation* conv) { connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed); connect(conv, &Conversation::sendMessage, this, &Squawk::onConversationMessage); + connect(conv, &Conversation::replaceMessage, this, &Squawk::onConversationReplaceMessage); connect(conv, &Conversation::resendMessage, this, &Squawk::onConversationResend); connect(conv, &Conversation::notifyableMessage, this, &Squawk::notify); } diff --git a/ui/squawk.h b/ui/squawk.h index 7551f66..7bd2e10 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -62,6 +62,7 @@ signals: void disconnectAccount(const QString&); void changeState(Shared::Availability state); void sendMessage(const QString& account, const Shared::Message& data); + void replaceMessage(const QString& account, const QString& originalId, const Shared::Message& data); void resendMessage(const QString& account, const QString& jid, const QString& id); void requestArchive(const QString& account, const QString& jid, int count, const QString& before); void subscribeContact(const QString& account, const QString& jid, const QString& reason); @@ -153,6 +154,7 @@ private slots: void onComboboxActivated(int index); void onRosterItemDoubleClicked(const QModelIndex& item); void onConversationMessage(const Shared::Message& msg); + void onConversationReplaceMessage(const QString& originalId, const Shared::Message& msg); void onConversationResend(const QString& id); void onRequestArchive(const QString& account, const QString& jid, const QString& before); void onRosterContextMenu(const QPoint& point); diff --git a/ui/widgets/conversation.cpp b/ui/widgets/conversation.cpp index 608faf3..02aefb4 100644 --- a/ui/widgets/conversation.cpp +++ b/ui/widgets/conversation.cpp @@ -58,7 +58,8 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, pasteImageAction(new QAction(tr("Paste Image"), this)), shadow(10, 1, Qt::black, this), contextMenu(new QMenu()), - currentAction(CurrentAction::none) + currentAction(CurrentAction::none), + currentMessageId() { m_ui->setupUi(this); @@ -84,11 +85,11 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, statusIcon = m_ui->statusIcon; statusLabel = m_ui->statusLabel; - connect(&ker, &KeyEnterReceiver::enterPressed, this, &Conversation::onEnterPressed); + connect(&ker, &KeyEnterReceiver::enterPressed, this, qOverload<>(&Conversation::initiateMessageSending)); connect(&ker, &KeyEnterReceiver::imagePasted, this, &Conversation::onImagePasted); - connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed); + connect(m_ui->sendButton, &QPushButton::clicked, this, qOverload<>(&Conversation::initiateMessageSending)); connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach); - connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton); + connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::clear); connect(m_ui->messageEditor->document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged, this, &Conversation::onTextEditDocSizeChanged); @@ -98,6 +99,9 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, connect(m_ui->messageEditor, &QTextEdit::customContextMenuRequested, this, &Conversation::onMessageEditorContext); connect(pasteImageAction, &QAction::triggered, this, &Conversation::onImagePasted); + connect(m_ui->currentActionBadge, &Badge::close, this, &Conversation::clear); + m_ui->currentActionBadge->setVisible(false); + //line->setAutoFillBackground(false); //if (testAttribute(Qt::WA_TranslucentBackground)) { //m_ui->scrollArea->setAutoFillBackground(false); @@ -109,9 +113,6 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, //line->setMyName(acc->getName()); initializeOverlay(); - - m_ui->currentActionBadge->setVisible(false); -// m_ui->currentActionBadge->setText(tr("Editing message...")); } Conversation::~Conversation() @@ -224,24 +225,33 @@ void Conversation::setPalResource(const QString& res) activePalResource = res; } -void Conversation::onEnterPressed() +void Conversation::initiateMessageSending() { QString body(m_ui->messageEditor->toPlainText()); if (body.size() > 0) { - m_ui->messageEditor->clear(); Shared::Message msg = createMessage(); msg.setBody(body); - emit sendMessage(msg); + initiateMessageSending(msg); } if (filesToAttach.size() > 0) { for (Badge* badge : filesToAttach) { Shared::Message msg = createMessage(); msg.setAttachPath(badge->id); element->feed->registerUpload(msg.getId()); - emit sendMessage(msg); + initiateMessageSending(msg); } - clearAttachedFiles(); + } + clear(); +} + +void Conversation::initiateMessageSending(const Shared::Message& msg) +{ + if (currentAction == CurrentAction::edit) { + emit replaceMessage(currentMessageId, msg); + currentAction = CurrentAction::none; + } else { + emit sendMessage(msg); } } @@ -348,8 +358,11 @@ void Conversation::clearAttachedFiles() filesLayout->setContentsMargins(0, 0, 0, 0); } -void Conversation::onClearButton() +void Conversation::clear() { + currentMessageId.clear(); + currentAction = CurrentAction::none; + m_ui->currentActionBadge->setVisible(false); clearAttachedFiles(); m_ui->messageEditor->clear(); } @@ -526,13 +539,12 @@ void Conversation::onMessageEditorContext(const QPoint& pos) void Conversation::onMessageEditRequested(const QString& id) { - if (currentAction == CurrentAction::edit) { - //todo; - } + clear(); try { Shared::Message msg = element->feed->getMessage(id); + currentMessageId = id; m_ui->currentActionBadge->setVisible(true); m_ui->currentActionBadge->setText(tr("Editing message...")); currentAction = CurrentAction::edit; diff --git a/ui/widgets/conversation.h b/ui/widgets/conversation.h index 4bccdfc..743df71 100644 --- a/ui/widgets/conversation.h +++ b/ui/widgets/conversation.h @@ -83,6 +83,7 @@ public: signals: void sendMessage(const Shared::Message& message); + void replaceMessage(const QString& originalId, const Shared::Message& message); void resendMessage(const QString& id); void requestArchive(const QString& before); void shown(); @@ -104,12 +105,13 @@ protected: virtual void onMessage(const Shared::Message& msg); protected slots: - void onEnterPressed(); + void initiateMessageSending(); + void initiateMessageSending(const Shared::Message& msg); void onImagePasted(); void onAttach(); void onFileSelected(); void onBadgeClose(); - void onClearButton(); + void clear(); void onTextEditDocSizeChanged(const QSizeF& size); void onAccountChanged(Models::Item* item, int row, int col); void onFeedMessage(const Shared::Message& msg); @@ -149,6 +151,7 @@ protected: ShadowOverlay shadow; QMenu* contextMenu; CurrentAction currentAction; + QString currentMessageId; private: static bool painterInitialized;