diff --git a/core/account.h b/core/account.h index 2dda75c..f3dd4c6 100644 --- a/core/account.h +++ b/core/account.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "../global.h" #include "contact.h" #include "conference.h" diff --git a/core/networkaccess.cpp b/core/networkaccess.cpp index 002f9d7..4863535 100644 --- a/core/networkaccess.cpp +++ b/core/networkaccess.cpp @@ -23,7 +23,8 @@ Core::NetworkAccess::NetworkAccess(QObject* parent): running(false), manager(0), files("files"), - downloads() + downloads(), + uploads() { } @@ -34,9 +35,9 @@ Core::NetworkAccess::~NetworkAccess() void Core::NetworkAccess::fileLocalPathRequest(const QString& messageId, const QString& url) { - std::map::iterator itr = downloads.find(url); + std::map::iterator itr = downloads.find(url); if (itr != downloads.end()) { - Download* dwn = itr->second; + Transfer* dwn = itr->second; std::set::const_iterator mItr = dwn->messages.find(messageId); if (mItr == dwn->messages.end()) { dwn->messages.insert(messageId); @@ -63,9 +64,9 @@ void Core::NetworkAccess::fileLocalPathRequest(const QString& messageId, const Q void Core::NetworkAccess::downladFileRequest(const QString& messageId, const QString& url) { - std::map::iterator itr = downloads.find(url); + std::map::iterator itr = downloads.find(url); if (itr != downloads.end()) { - Download* dwn = itr->second; + Transfer* dwn = itr->second; std::set::const_iterator mItr = dwn->messages.find(messageId); if (mItr == dwn->messages.end()) { dwn->messages.insert(messageId); @@ -85,7 +86,7 @@ void Core::NetworkAccess::downladFileRequest(const QString& messageId, const QSt startDownload(messageId, url); } catch (Archive::Unknown e) { qDebug() << "Error requesting file path:" << e.what(); - startDownload(messageId, url); + emit downloadFileError(messageId, QString("Database error: ") + e.what()); } } } @@ -107,7 +108,7 @@ void Core::NetworkAccess::stop() manager = 0; running = false; - for (std::map::const_iterator itr = downloads.begin(), end = downloads.end(); itr != end; ++itr) { + for (std::map::const_iterator itr = downloads.begin(), end = downloads.end(); itr != end; ++itr) { itr->second->success = false; itr->second->reply->abort(); //assuming it's gonna call onRequestFinished slot } @@ -118,11 +119,11 @@ void Core::NetworkAccess::onDownloadProgress(qint64 bytesReceived, qint64 bytesT { QNetworkReply* rpl = static_cast(sender()); QString url = rpl->url().toString(); - std::map::const_iterator itr = downloads.find(url); + std::map::const_iterator itr = downloads.find(url); if (itr == downloads.end()) { qDebug() << "an error downloading" << url << ": the request had some progress but seems like noone is waiting for it, skipping"; } else { - Download* dwn = itr->second; + Transfer* dwn = itr->second; qreal received = bytesReceived; qreal total = bytesTotal; qreal progress = received/total; @@ -133,132 +134,18 @@ void Core::NetworkAccess::onDownloadProgress(qint64 bytesReceived, qint64 bytesT } } -void Core::NetworkAccess::onRequestError(QNetworkReply::NetworkError code) +void Core::NetworkAccess::onDownloadError(QNetworkReply::NetworkError code) { QNetworkReply* rpl = static_cast(sender()); QString url = rpl->url().toString(); - std::map::const_iterator itr = downloads.find(url); + std::map::const_iterator itr = downloads.find(url); if (itr == downloads.end()) { qDebug() << "an error downloading" << url << ": the request is reporting an error but seems like noone is waiting for it, skipping"; } else { - QString errorText; - switch (code) { - case QNetworkReply::NoError: - //this never is supposed to happen - break; - - // network layer errors [relating to the destination server] (1-99): - case QNetworkReply::ConnectionRefusedError: - errorText = "Connection refused"; - break; - case QNetworkReply::RemoteHostClosedError: - errorText = "Remote server closed the connection"; - break; - case QNetworkReply::HostNotFoundError: - errorText = "Remote host is not found"; - break; - case QNetworkReply::TimeoutError: - errorText = "Connection was closed because it timed out"; - break; - case QNetworkReply::OperationCanceledError: - //this means I closed it myself by abort() or close(), don't think I need to notify here - break; - case QNetworkReply::SslHandshakeFailedError: - errorText = "Security error"; //TODO need to handle sslErrors signal to get a better description here - break; - case QNetworkReply::TemporaryNetworkFailureError: - //this means the connection is lost by opened route, but it's going to be resumed, not sure I need to notify - break; - case QNetworkReply::NetworkSessionFailedError: - errorText = "Outgoing connection problem"; - break; - case QNetworkReply::BackgroundRequestNotAllowedError: - errorText = "Background request is not allowed"; - break; - case QNetworkReply::TooManyRedirectsError: - errorText = "The request was redirected too many times"; - break; - case QNetworkReply::InsecureRedirectError: - errorText = "The request was redirected to insecure connection"; - break; - case QNetworkReply::UnknownNetworkError: - errorText = "Unknown network error"; - break; - - // proxy errors (101-199): - case QNetworkReply::ProxyConnectionRefusedError: - errorText = "The connection to the proxy server was refused"; - break; - case QNetworkReply::ProxyConnectionClosedError: - errorText = "Proxy server closed the connection"; - break; - case QNetworkReply::ProxyNotFoundError: - errorText = "Proxy host was not found"; - break; - case QNetworkReply::ProxyTimeoutError: - errorText = "Connection to the proxy server was closed because it timed out"; - break; - case QNetworkReply::ProxyAuthenticationRequiredError: - errorText = "Couldn't connect to proxy server, authentication is required"; - break; - case QNetworkReply::UnknownProxyError: - errorText = "Unknown proxy error"; - break; - - // content errors (201-299): - case QNetworkReply::ContentAccessDenied: - errorText = "The access to file is denied"; - break; - case QNetworkReply::ContentOperationNotPermittedError: - errorText = "The operation over requesting file is not permitted"; - break; - case QNetworkReply::ContentNotFoundError: - errorText = "The file was not found"; - break; - case QNetworkReply::AuthenticationRequiredError: - errorText = "Couldn't access the file, authentication is required"; - break; - case QNetworkReply::ContentReSendError: - errorText = "Sending error, one more attempt will probably solve this problem"; - break; - case QNetworkReply::ContentConflictError: - errorText = "The request could not be completed due to a conflict with the current state of the resource"; - break; - case QNetworkReply::ContentGoneError: - errorText = "The requested resource is no longer available at the server"; - break; - case QNetworkReply::UnknownContentError: - errorText = "Unknown content error"; - break; - - // protocol errors - case QNetworkReply::ProtocolUnknownError: - errorText = "Unknown protocol error"; - break; - case QNetworkReply::ProtocolInvalidOperationError: - errorText = "Requested operation is not permitted in this protocol"; - break; - case QNetworkReply::ProtocolFailure: - errorText = "Low level protocol error"; - break; - - // Server side errors (401-499) - case QNetworkReply::InternalServerError: - errorText = "Internal server error"; - break; - case QNetworkReply::OperationNotImplementedError: - errorText = "Server doesn't support requested operation"; - break; - case QNetworkReply::ServiceUnavailableError: - errorText = "The server is not available for this operation right now"; - break; - case QNetworkReply::UnknownServerError: - errorText = "Unknown server error"; - break; - } + QString errorText = getErrorText(code); if (errorText.size() > 0) { itr->second->success = false; - Download* dwn = itr->second; + Transfer* dwn = itr->second; for (std::set::const_iterator mItr = dwn->messages.begin(), end = dwn->messages.end(); mItr != end; ++mItr) { emit downloadFileError(*mItr, errorText); } @@ -266,16 +153,137 @@ void Core::NetworkAccess::onRequestError(QNetworkReply::NetworkError code) } } -void Core::NetworkAccess::onRequestFinished() +QString Core::NetworkAccess::getErrorText(QNetworkReply::NetworkError code) +{ + QString errorText(""); + switch (code) { + case QNetworkReply::NoError: + //this never is supposed to happen + break; + + // network layer errors [relating to the destination server] (1-99): + case QNetworkReply::ConnectionRefusedError: + errorText = "Connection refused"; + break; + case QNetworkReply::RemoteHostClosedError: + errorText = "Remote server closed the connection"; + break; + case QNetworkReply::HostNotFoundError: + errorText = "Remote host is not found"; + break; + case QNetworkReply::TimeoutError: + errorText = "Connection was closed because it timed out"; + break; + case QNetworkReply::OperationCanceledError: + //this means I closed it myself by abort() or close(), don't think I need to notify here + break; + case QNetworkReply::SslHandshakeFailedError: + errorText = "Security error"; //TODO need to handle sslErrors signal to get a better description here + break; + case QNetworkReply::TemporaryNetworkFailureError: + //this means the connection is lost by opened route, but it's going to be resumed, not sure I need to notify + break; + case QNetworkReply::NetworkSessionFailedError: + errorText = "Outgoing connection problem"; + break; + case QNetworkReply::BackgroundRequestNotAllowedError: + errorText = "Background request is not allowed"; + break; + case QNetworkReply::TooManyRedirectsError: + errorText = "The request was redirected too many times"; + break; + case QNetworkReply::InsecureRedirectError: + errorText = "The request was redirected to insecure connection"; + break; + case QNetworkReply::UnknownNetworkError: + errorText = "Unknown network error"; + break; + + // proxy errors (101-199): + case QNetworkReply::ProxyConnectionRefusedError: + errorText = "The connection to the proxy server was refused"; + break; + case QNetworkReply::ProxyConnectionClosedError: + errorText = "Proxy server closed the connection"; + break; + case QNetworkReply::ProxyNotFoundError: + errorText = "Proxy host was not found"; + break; + case QNetworkReply::ProxyTimeoutError: + errorText = "Connection to the proxy server was closed because it timed out"; + break; + case QNetworkReply::ProxyAuthenticationRequiredError: + errorText = "Couldn't connect to proxy server, authentication is required"; + break; + case QNetworkReply::UnknownProxyError: + errorText = "Unknown proxy error"; + break; + + // content errors (201-299): + case QNetworkReply::ContentAccessDenied: + errorText = "The access to file is denied"; + break; + case QNetworkReply::ContentOperationNotPermittedError: + errorText = "The operation over requesting file is not permitted"; + break; + case QNetworkReply::ContentNotFoundError: + errorText = "The file was not found"; + break; + case QNetworkReply::AuthenticationRequiredError: + errorText = "Couldn't access the file, authentication is required"; + break; + case QNetworkReply::ContentReSendError: + errorText = "Sending error, one more attempt will probably solve this problem"; + break; + case QNetworkReply::ContentConflictError: + errorText = "The request could not be completed due to a conflict with the current state of the resource"; + break; + case QNetworkReply::ContentGoneError: + errorText = "The requested resource is no longer available at the server"; + break; + case QNetworkReply::UnknownContentError: + errorText = "Unknown content error"; + break; + + // protocol errors + case QNetworkReply::ProtocolUnknownError: + errorText = "Unknown protocol error"; + break; + case QNetworkReply::ProtocolInvalidOperationError: + errorText = "Requested operation is not permitted in this protocol"; + break; + case QNetworkReply::ProtocolFailure: + errorText = "Low level protocol error"; + break; + + // Server side errors (401-499) + case QNetworkReply::InternalServerError: + errorText = "Internal server error"; + break; + case QNetworkReply::OperationNotImplementedError: + errorText = "Server doesn't support requested operation"; + break; + case QNetworkReply::ServiceUnavailableError: + errorText = "The server is not available for this operation right now"; + break; + case QNetworkReply::UnknownServerError: + errorText = "Unknown server error"; + break; + } + return errorText; +} + + +void Core::NetworkAccess::onDownloadFinished() { QString path(""); QNetworkReply* rpl = static_cast(sender()); QString url = rpl->url().toString(); - std::map::const_iterator itr = downloads.find(url); + std::map::const_iterator itr = downloads.find(url); if (itr == downloads.end()) { qDebug() << "an error downloading" << url << ": the request is done but seems like noone is waiting for it, skipping"; } else { - Download* dwn = itr->second; + Transfer* dwn = itr->second; if (dwn->success) { qDebug() << "download success for" << url; QStringList hops = url.split("/"); @@ -320,13 +328,130 @@ void Core::NetworkAccess::onRequestFinished() void Core::NetworkAccess::startDownload(const QString& messageId, const QString& url) { - Download* dwn = new Download({{messageId}, 0, 0, true}); + Transfer* dwn = new Transfer({{messageId}, 0, 0, true, "", 0}); QNetworkRequest req(url); dwn->reply = manager->get(req); connect(dwn->reply, SIGNAL(downloadProgress(qint64, qint64)), SLOT(onDownloadProgress(qint64, qint64))); - connect(dwn->reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onRequestError(QNetworkReply::NetworkError))); - connect(dwn->reply, SIGNAL(finished()), SLOT(onRequestFinished())); + connect(dwn->reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onDownloadError(QNetworkReply::NetworkError))); + connect(dwn->reply, SIGNAL(finished()), SLOT(onDownloadFinished())); downloads.insert(std::make_pair(url, dwn)); emit downloadFileProgress(messageId, 0); } +void Core::NetworkAccess::onUploadError(QNetworkReply::NetworkError code) +{ + QNetworkReply* rpl = static_cast(sender()); + QString url = rpl->url().toString(); + std::map::const_iterator itr = uploads.find(url); + if (itr == uploads.end()) { + qDebug() << "an error uploading" << url << ": the request is reporting an error but seems like noone is waiting for it, skipping"; + } else { + QString errorText = getErrorText(code); + if (errorText.size() > 0) { + itr->second->success = false; + Transfer* upl = itr->second; + for (std::set::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) { + emit uploadFileError(*mItr, errorText); + } + } + } +} + +void Core::NetworkAccess::onUploadFinished() +{ + QNetworkReply* rpl = static_cast(sender()); + QString url = rpl->url().toString(); + std::map::const_iterator itr = uploads.find(url); + if (itr == downloads.end()) { + qDebug() << "an error uploading" << url << ": the request is done but seems like noone is waiting for it, skipping"; + } else { + Transfer* upl = itr->second; + if (upl->success) { + qDebug() << "upload success for" << url; + files.addRecord(url, upl->path); + + for (std::set::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) { + emit fileLocalPathResponse(*mItr, upl->path); + } + } + + upl->reply->deleteLater(); + upl->file->close(); + upl->file->deleteLater(); + delete upl; + uploads.erase(itr); + } +} + +void Core::NetworkAccess::onUploadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + QNetworkReply* rpl = static_cast(sender()); + QString url = rpl->url().toString(); + std::map::const_iterator itr = uploads.find(url); + if (itr == uploads.end()) { + qDebug() << "an error downloading" << url << ": the request had some progress but seems like noone is waiting for it, skipping"; + } else { + Transfer* upl = itr->second; + qreal received = bytesReceived; + qreal total = bytesTotal; + qreal progress = received/total; + upl->progress = progress; + for (std::set::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) { + emit uploadFileProgress(*mItr, progress); + } + } +} + +void Core::NetworkAccess::startUpload(const QString& messageId, const QString& url, const QString& path) +{ + Transfer* upl = new Transfer({{messageId}, 0, 0, true, path, 0}); + QNetworkRequest req(url); + QFile* file = new QFile(path); + if (file->open(QIODevice::ReadOnly)) { + upl->reply = manager->put(req, file); + + connect(upl->reply, SIGNAL(uploadProgress(qint64, qint64)), SLOT(onUploadProgress(qint64, qint64))); + connect(upl->reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onUploadError(QNetworkReply::NetworkError))); + connect(upl->reply, SIGNAL(finished()), SLOT(onUploadFinished())); + uploads.insert(std::make_pair(url, upl)); + emit downloadFileProgress(messageId, 0); + } else { + qDebug() << "couldn't upload file" << path; + emit uploadFileError(messageId, "Error opening file"); + delete file; + } +} + +void Core::NetworkAccess::uploadFileRequest(const QString& messageId, const QString& url, const QString& path) +{ + std::map::iterator itr = uploads.find(url); + if (itr != uploads.end()) { + Transfer* upl = itr->second; + std::set::const_iterator mItr = upl->messages.find(messageId); + if (mItr == upl->messages.end()) { + upl->messages.insert(messageId); + } + emit uploadFileProgress(messageId, upl->progress); + } else { + try { + QString ePath = files.getRecord(url); + if (ePath == path) { + emit fileLocalPathResponse(messageId, path); + } else { + files.changeRecord(url, path); + } + QFileInfo info(path); + if (info.exists() && info.isFile()) { + emit fileLocalPathResponse(messageId, path); + } else { + files.removeRecord(url); + startDownload(messageId, url); + } + } catch (Archive::NotFound e) { + startUpload(messageId, url, path); + } catch (Archive::Unknown e) { + qDebug() << "Error requesting file path on upload:" << e.what(); + emit uploadFileError(messageId, QString("Database error: ") + e.what()); + } + } +} diff --git a/core/networkaccess.h b/core/networkaccess.h index 526cf2d..de3f2bc 100644 --- a/core/networkaccess.h +++ b/core/networkaccess.h @@ -39,7 +39,7 @@ namespace Core { class NetworkAccess : public QObject { Q_OBJECT - struct Download; + struct Transfer; public: NetworkAccess(QObject* parent = nullptr); virtual ~NetworkAccess(); @@ -51,30 +51,41 @@ signals: void fileLocalPathResponse(const QString& messageId, const QString& path); void downloadFileProgress(const QString& messageId, qreal value); void downloadFileError(const QString& messageId, const QString& path); + void uploadFileProgress(const QString& messageId, qreal value); + void uploadFileError(const QString& messageId, const QString& path); public slots: void fileLocalPathRequest(const QString& messageId, const QString& url); void downladFileRequest(const QString& messageId, const QString& url); + void uploadFileRequest(const QString& messageId, const QString& url, const QString& path); private: void startDownload(const QString& messageId, const QString& url); + void startUpload(const QString& messageId, const QString& url, const QString& path); + QString getErrorText(QNetworkReply::NetworkError code); private slots: void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); - void onRequestError(QNetworkReply::NetworkError code); - void onRequestFinished(); + void onDownloadError(QNetworkReply::NetworkError code); + void onDownloadFinished(); + void onUploadProgress(qint64 bytesReceived, qint64 bytesTotal); + void onUploadError(QNetworkReply::NetworkError code); + void onUploadFinished(); private: bool running; QNetworkAccessManager* manager; Storage files; - std::map downloads; + std::map downloads; + std::map uploads; - struct Download { + struct Transfer { std::set messages; qreal progress; QNetworkReply* reply; bool success; + QString path; + QFile* file; }; }; diff --git a/core/squawk.cpp b/core/squawk.cpp index bf9550f..50275a5 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -31,6 +31,8 @@ Core::Squawk::Squawk(QObject* parent): connect(&network, SIGNAL(fileLocalPathResponse(const QString&, const QString&)), this, SIGNAL(fileLocalPathResponse(const QString&, const QString&))); connect(&network, SIGNAL(downloadFileProgress(const QString&, qreal)), this, SIGNAL(downloadFileProgress(const QString&, qreal))); connect(&network, SIGNAL(downloadFileError(const QString&, const QString&)), this, SIGNAL(downloadFileError(const QString&, const QString&))); + connect(&network, SIGNAL(uploadFileProgress(const QString&, qreal)), this, SIGNAL(uploadFileProgress(const QString&, qreal))); + connect(&network, SIGNAL(uploadFileError(const QString&, const QString&)), this, SIGNAL(uploadFileError(const QString&, const QString&))); } Core::Squawk::~Squawk() @@ -276,6 +278,11 @@ void Core::Squawk::sendMessage(const QString& account, const Shared::Message& da itr->second->sendMessage(data); } +void Core::Squawk::sendMessage(const QString& account, const Shared::Message& data, const QString& path) +{ + +} + void Core::Squawk::requestArchive(const QString& account, const QString& jid, int count, const QString& before) { AccountsMap::const_iterator itr = amap.find(account); @@ -368,7 +375,6 @@ void Core::Squawk::removeAccountRequest(const QString& name) acc->deleteLater(); } - void Core::Squawk::subscribeContact(const QString& account, const QString& jid, const QString& reason) { AccountsMap::const_iterator itr = amap.find(account); diff --git a/core/squawk.h b/core/squawk.h index 89f4c2d..7403ba8 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -65,6 +65,8 @@ signals: void fileLocalPathResponse(const QString& messageId, const QString& path); void downloadFileError(const QString& messageId, const QString& error); void downloadFileProgress(const QString& messageId, qreal value); + void uploadFileError(const QString& messageId, const QString& error); + void uploadFileProgress(const QString& messageId, qreal value); public slots: void start(); @@ -76,6 +78,7 @@ public slots: void disconnectAccount(const QString& account); void changeState(int state); void sendMessage(const QString& account, const Shared::Message& data); + void sendMessage(const QString& account, const Shared::Message& data, const QString& path); void requestArchive(const QString& account, const QString& jid, int count, const QString& before); void subscribeContact(const QString& account, const QString& jid, const QString& reason); void unsubscribeContact(const QString& account, const QString& jid, const QString& reason); diff --git a/core/storage.cpp b/core/storage.cpp index 8f6c17c..7ff0ef7 100644 --- a/core/storage.cpp +++ b/core/storage.cpp @@ -73,7 +73,7 @@ void Core::Storage::close() void Core::Storage::addRecord(const QString& key, const QString& value) { if (!opened) { - throw Archive::Closed("addElement", name.toStdString()); + throw Archive::Closed("addRecord", name.toStdString()); } const std::string& id = key.toStdString(); const std::string& val = value.toStdString(); @@ -99,6 +99,33 @@ void Core::Storage::addRecord(const QString& key, const QString& value) } } +void Core::Storage::changeRecord(const QString& key, const QString& value) +{ + if (!opened) { + throw Archive::Closed("changeRecord", name.toStdString()); + } + const std::string& id = key.toStdString(); + const std::string& val = value.toStdString(); + + MDB_val lmdbKey, lmdbData; + lmdbKey.mv_size = id.size(); + lmdbKey.mv_data = (char*)id.c_str(); + lmdbData.mv_size = val.size(); + lmdbData.mv_data = (char*)val.c_str(); + MDB_txn *txn; + mdb_txn_begin(environment, NULL, 0, &txn); + int rc; + rc = mdb_put(txn, base, &lmdbKey, &lmdbData, 0); + if (rc != 0) { + mdb_txn_abort(txn); + if (rc) { + throw Archive::Unknown(name.toStdString(), mdb_strerror(rc)); + } + } else { + mdb_txn_commit(txn); + } +} + QString Core::Storage::getRecord(const QString& key) const { if (!opened) { diff --git a/core/storage.h b/core/storage.h index 9fe64ca..d2abfde 100644 --- a/core/storage.h +++ b/core/storage.h @@ -39,6 +39,7 @@ public: void close(); void addRecord(const QString& key, const QString& value); + void changeRecord(const QString& key, const QString& value); void removeRecord(const QString& key); QString getRecord(const QString& key) const; diff --git a/main.cpp b/main.cpp index d0fba26..085a01f 100644 --- a/main.cpp +++ b/main.cpp @@ -70,6 +70,8 @@ int main(int argc, char *argv[]) QObject::connect(&w, SIGNAL(disconnectAccount(const QString&)), squawk, SLOT(disconnectAccount(const QString&))); QObject::connect(&w, SIGNAL(changeState(int)), squawk, SLOT(changeState(int))); QObject::connect(&w, SIGNAL(sendMessage(const QString&, const Shared::Message&)), squawk, SLOT(sendMessage(const QString&, const Shared::Message&))); + QObject::connect(&w, SIGNAL(sendMessage(const QString&, const Shared::Message&, const QString&)), + squawk, SLOT(sendMessage(const QString&, const Shared::Message&, const QString&))); QObject::connect(&w, SIGNAL(requestArchive(const QString&, const QString&, int, const QString&)), squawk, SLOT(requestArchive(const QString&, const QString&, int, const QString&))); QObject::connect(&w, SIGNAL(subscribeContact(const QString&, const QString&, const QString&)), @@ -125,9 +127,6 @@ int main(int argc, char *argv[]) QObject::connect(squawk, SIGNAL(downloadFileProgress(const QString&, qreal)), &w, SLOT(downloadFileProgress(const QString&, qreal))); QObject::connect(squawk, SIGNAL(downloadFileError(const QString&, const QString&)), &w, SLOT(downloadFileError(const QString&, const QString&))); - - //qDebug() << QStandardPaths::writableLocation(QStandardPaths::CacheLocation); - coreThread->start(); int result = app.exec(); diff --git a/ui/squawk.cpp b/ui/squawk.cpp index f30a8bb..599c909 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -285,6 +285,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item) connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*))); connect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&))); + connect(conv, SIGNAL(sendMessage(const Shared::Message&, const QString&)), this, SLOT(onConversationMessage(const Shared::Message&, const QString&))); connect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&))); connect(conv, SIGNAL(requestLocalFile(const QString&, const QString&)), this, SLOT(onConversationRequestLocalFile(const QString&, const QString&))); connect(conv, SIGNAL(downloadFile(const QString&, const QString&)), this, SLOT(onConversationDownloadFile(const QString&, const QString&))); @@ -468,10 +469,15 @@ void Squawk::notify(const QString& account, const Shared::Message& msg) void Squawk::onConversationMessage(const Shared::Message& msg) { Conversation* conv = static_cast(sender()); - emit sendMessage(conv->getAccount(), msg); } +void Squawk::onConversationMessage(const Shared::Message& msg, const QString& path) +{ + Conversation* conv = static_cast(sender()); + emit sendMessage(conv->getAccount(), msg, path); +} + void Squawk::onConversationRequestArchive(const QString& before) { Conversation* conv = static_cast(sender()); diff --git a/ui/squawk.h b/ui/squawk.h index 99a6be7..2e92b28 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -57,6 +57,7 @@ signals: void disconnectAccount(const QString&); void changeState(int state); void sendMessage(const QString& account, const Shared::Message& data); + void sendMessage(const QString& account, const Shared::Message& data, const QString& path); void requestArchive(const QString& account, const QString& jid, int count, const QString& before); void subscribeContact(const QString& account, const QString& jid, const QString& reason); void unsubscribeContact(const QString& account, const QString& jid, const QString& reason); @@ -121,6 +122,7 @@ private slots: void onComboboxActivated(int index); void onRosterItemDoubleClicked(const QModelIndex& item); void onConversationMessage(const Shared::Message& msg); + void onConversationMessage(const Shared::Message& msg, const QString& path); void onConversationRequestArchive(const QString& before); void onRosterContextMenu(const QPoint& point); void onConversationShown(); diff --git a/ui/widgets/conversation.h b/ui/widgets/conversation.h index 5bc2d33..cb738b9 100644 --- a/ui/widgets/conversation.h +++ b/ui/widgets/conversation.h @@ -80,6 +80,7 @@ public: signals: void sendMessage(const Shared::Message& message); + void sendMessage(const Shared::Message& message, const QString& path); void requestArchive(const QString& before); void shown(); void requestLocalFile(const QString& messageId, const QString& url);