diff --git a/core/account.cpp b/core/account.cpp index 49746b7..f7b1665 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -93,6 +93,9 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& QObject::connect(um, &QXmppUploadRequestManager::slotReceived, this, &Account::onUploadSlotReceived); QObject::connect(um, &QXmppUploadRequestManager::requestFailed, this, &Account::onUploadSlotRequestFailed); + QObject::connect(network, &NetworkAccess::uploadFileComplete, this, &Account::onFileUploaded); + QObject::connect(network, &NetworkAccess::uploadFileError, this, &Account::onFileUploadError); + QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); path += "/" + name; QDir dir(path); @@ -141,6 +144,9 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& Account::~Account() { + QObject::disconnect(network, &NetworkAccess::uploadFileComplete, this, &Account::onFileUploaded); + QObject::disconnect(network, &NetworkAccess::uploadFileError, this, &Account::onFileUploadError); + for (std::map::const_iterator itr = contacts.begin(), end = contacts.end(); itr != end; ++itr) { delete itr->second; } @@ -1640,3 +1646,11 @@ void Core::Account::onFileUploaded(const QString& messageId, const QString& url) pendingMessages.erase(itr); } } + +void Core::Account::onFileUploadError(const QString& messageId, const QString& errMsg) +{ + std::map::const_iterator itr = pendingMessages.find(messageId); + if (itr != pendingMessages.end()) { + pendingMessages.erase(itr); + } +} diff --git a/core/account.h b/core/account.h index 8f22913..c8419d1 100644 --- a/core/account.h +++ b/core/account.h @@ -196,7 +196,7 @@ private slots: void onUploadSlotReceived(const QXmppHttpUploadSlotIq& slot); void onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request); void onFileUploaded(const QString& messageId, const QString& url); - void onFileUploadError(const QString& messageId, const QString& path); + void onFileUploadError(const QString& messageId, const QString& errMsg); private: void addedAccount(const QString &bareJid); diff --git a/core/networkaccess.cpp b/core/networkaccess.cpp index ea726f2..2a41909 100644 --- a/core/networkaccess.cpp +++ b/core/networkaccess.cpp @@ -437,16 +437,22 @@ void Core::NetworkAccess::uploadFileRequest(const QString& messageId, const QStr try { QString ePath = files.getRecord(url); if (ePath == path) { - emit fileLocalPathResponse(messageId, path); + QFileInfo info(path); + if (info.exists() && info.isFile()) { + emit fileLocalPathResponse(messageId, path); + } else { + files.removeRecord(url); + startUpload(messageId, url, 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); + QFileInfo info(path); + if (info.exists() && info.isFile()) { + files.changeRecord(url, path); + emit fileLocalPathResponse(messageId, path); + } else { + files.removeRecord(url); + startUpload(messageId, url, path); + } } } catch (Archive::NotFound e) { startUpload(messageId, url, path); @@ -474,6 +480,9 @@ void Core::NetworkAccess::uploadFile(const QString& messageId, const QString& pa { Transfer* upl = new Transfer({{messageId}, 0, 0, true, path, get.toString(), 0}); QNetworkRequest req(put); + for (QMap::const_iterator itr = headers.begin(), end = headers.end(); itr != end; itr++) { + req.setRawHeader(itr.key().toUtf8(), itr.value().toUtf8()); + } QFile* file = new QFile(path); if (file->open(QIODevice::ReadOnly)) { upl->reply = manager->put(req, file); diff --git a/main.cpp b/main.cpp index a66230f..76b1984 100644 --- a/main.cpp +++ b/main.cpp @@ -131,6 +131,8 @@ int main(int argc, char *argv[]) QObject::connect(squawk, &Core::Squawk::fileLocalPathResponse, &w, &Squawk::fileLocalPathResponse); QObject::connect(squawk, &Core::Squawk::downloadFileProgress, &w, &Squawk::downloadFileProgress); QObject::connect(squawk, &Core::Squawk::downloadFileError, &w, &Squawk::downloadFileError); + QObject::connect(squawk, &Core::Squawk::uploadFileProgress, &w, &Squawk::uploadFileProgress); + QObject::connect(squawk, &Core::Squawk::uploadFileError, &w, &Squawk::uploadFileError); QObject::connect(squawk, &Core::Squawk::responseVCard, &w, &Squawk::responseVCard); coreThread->start(); diff --git a/ui/squawk.h b/ui/squawk.h index 70f0d5f..cc43992 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -100,6 +100,8 @@ public slots: 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); void responseVCard(const QString& jid, const Shared::VCard& card); private: diff --git a/ui/utils/message.cpp b/ui/utils/message.cpp index 951037a..4bb9f46 100644 --- a/ui/utils/message.cpp +++ b/ui/utils/message.cpp @@ -38,12 +38,10 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_ file(0), progress(0), fileComment(new QLabel()), - errorText(""), hasDownloadButton(false), hasProgress(false), hasFile(false), - commentAdded(false), - errorDownloadingFile(false) + commentAdded(false) { body->setBackgroundRole(QPalette::AlternateBase); body->setAutoFillBackground(true); @@ -101,12 +99,17 @@ QString Message::getId() const return msg.getId(); } +QString Message::getFileUrl() const +{ + return msg.getOutOfBandUrl(); +} + void Message::setSender(const QString& p_sender) { sender->setText(p_sender); } -void Message::addDownloadDialog() +void Message::addButton(const QIcon& icon, const QString& buttonText, const QString& comment) { hideFile(); hideProgress(); @@ -116,16 +119,14 @@ void Message::addDownloadDialog() text->setText(""); text->hide(); } - downloadButton = new QPushButton(QIcon::fromTheme("download"), tr("Download")); + downloadButton = new QPushButton(icon, buttonText); downloadButton->setToolTip("" + msg.getOutOfBandUrl() + ""); - if (errorDownloadingFile) { + if (comment.size() != 0) { fileComment->setWordWrap(true); - fileComment->setText(tr("Error downloading file: %1\nYou can try again").arg(QCoreApplication::translate("NetworkErrors", errorText.toLatin1()))); - } else { - fileComment->setText(tr("%1 is offering you to download a file").arg(sender->text())); + fileComment->setText(comment); + fileComment->show(); } - fileComment->show(); - connect(downloadButton, &QPushButton::clicked, this, &Message::onDownload); + connect(downloadButton, &QPushButton::clicked, this, &Message::downloadFile); bodyLayout->insertWidget(2, fileComment); bodyLayout->insertWidget(3, downloadButton); hasDownloadButton = true; @@ -133,12 +134,7 @@ void Message::addDownloadDialog() } } -void Message::onDownload() -{ - emit downloadFile(msg.getId(), msg.getOutOfBandUrl()); -} - -void Message::setProgress(qreal value) +void Message::setProgress(qreal value, const QString& label) { hideFile(); hideDownload(); @@ -150,7 +146,9 @@ void Message::setProgress(qreal value) } progress = new QProgressBar(); progress->setRange(0, 100); - fileComment->setText("Downloading..."); + if (label.size() != 0) { + fileComment->setText(label); + } fileComment->show(); bodyLayout->insertWidget(2, progress); bodyLayout->insertWidget(3, fileComment); @@ -214,7 +212,6 @@ void Message::hideDownload() downloadButton->deleteLater(); downloadButton = 0; hasDownloadButton = false; - errorDownloadingFile = false; } } @@ -235,10 +232,3 @@ void Message::hideProgress() hasProgress = false;; } } - -void Message::showError(const QString& error) -{ - errorDownloadingFile = true; - errorText = error; - addDownloadDialog(); -} diff --git a/ui/utils/message.h b/ui/utils/message.h index 8a89268..22375a1 100644 --- a/ui/utils/message.h +++ b/ui/utils/message.h @@ -30,9 +30,9 @@ #include #include -#include "../../global.h" -#include "../utils/resizer.h" -#include "../utils/image.h" +#include "global.h" +#include "resizer.h" +#include "image.h" /** * @todo write docs @@ -46,14 +46,14 @@ public: void setSender(const QString& sender); QString getId() const; + QString getFileUrl() const; - void addDownloadDialog(); + void addButton(const QIcon& icon, const QString& buttonText, const QString& comment = ""); void showFile(const QString& path); - void showError(const QString& error); - void setProgress(qreal value); + void setProgress(qreal value, const QString& label = ""); signals: - void downloadFile(const QString& messageId, const QString& url); + void downloadFile(); private: Shared::Message msg; @@ -67,15 +67,10 @@ private: QLabel* file; QProgressBar* progress; QLabel* fileComment; - QString errorText; bool hasDownloadButton; bool hasProgress; bool hasFile; bool commentAdded; - bool errorDownloadingFile; - -private slots: - void onDownload(); private: void hideDownload(); diff --git a/ui/utils/messageline.cpp b/ui/utils/messageline.cpp index 06efa85..60c31f9 100644 --- a/ui/utils/messageline.cpp +++ b/ui/utils/messageline.cpp @@ -26,10 +26,13 @@ MessageLine::MessageLine(bool p_room, QWidget* parent): messageOrder(), myMessages(), palMessages(), + uploadPaths(), layout(new QVBoxLayout(this)), myName(), palNames(), views(), + uploading(), + downloading(), room(p_room), busyShown(false), progress() @@ -125,14 +128,27 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg) layout->insertLayout(index, message); } - if (msg.hasOutOfBandUrl()) {\ + if (msg.hasOutOfBandUrl()) { emit requestLocalFile(msg.getId(), msg.getOutOfBandUrl()); - connect(message, &Message::downloadFile, this, &MessageLine::downloadFile); + connect(message, &Message::downloadFile, this, &MessageLine::onDownload); } return res; } +void MessageLine::onDownload() +{ + Message* msg = static_cast(sender()); + QString messageId = msg->getId(); + Index::const_iterator itr = downloading.find(messageId); + if (itr == downloading.end()) { + downloading.insert(std::make_pair(messageId, msg)); + emit downloadFile(messageId, msg->getFileUrl()); + } else { + qDebug() << "An attempt to initiate download for already downloading file" << msg->getFileUrl() << ", skipping"; + } +} + void MessageLine::setMyName(const QString& name) { myName = name; @@ -192,13 +208,18 @@ void MessageLine::hideBusyIndicator() } } -void MessageLine::responseDownloadProgress(const QString& messageId, qreal progress) +void MessageLine::fileProgress(const QString& messageId, qreal progress) { - Index::const_iterator itr = messageIndex.find(messageId); - if (itr == messageIndex.end()) { - + Index::const_iterator itr = downloading.find(messageId); + if (itr == downloading.end()) { + Index::const_iterator itr = uploading.find(messageId); + if (itr == uploading.end()) { + //TODO may be some logging, that's not normal + } else { + itr->second->setProgress(progress, tr("Uploading...")); + } } else { - itr->second->setProgress(progress); + itr->second->setProgress(progress, tr("Downloading...")); } } @@ -211,18 +232,31 @@ void MessageLine::responseLocalFile(const QString& messageId, const QString& pat if (path.size() > 0) { itr->second->showFile(path); } else { - itr->second->addDownloadDialog(); + itr->second->addButton(QIcon::fromTheme("download"), tr("Download"), tr("Push the button to daownload the file")); } } } -void MessageLine::downloadError(const QString& messageId, const QString& error) +void MessageLine::fileError(const QString& messageId, const QString& error) { - Index::const_iterator itr = messageIndex.find(messageId); - if (itr == messageIndex.end()) { - + Index::const_iterator itr = downloading.find(messageId); + if (itr == downloading.end()) { + Index::const_iterator itr = uploading.find(messageId); + if (itr == uploading.end()) { + //TODO may be some logging, that's not normal + } else { + //itr->second->showError(error); + //itr->second->addDownloadDialog(); + } } else { - itr->second->showError(error); + itr->second->addButton(QIcon::fromTheme("download"), tr("Download"), + tr("Error downloading file: %1\nYou can try again").arg(QCoreApplication::translate("NetworkErrors", error.toLatin1()))); } } +void MessageLine::appendMessageWithUpload(const Shared::Message& msg, const QString& path) +{ + message(msg); + +} + diff --git a/ui/utils/messageline.h b/ui/utils/messageline.h index 67280e4..5bdb733 100644 --- a/ui/utils/messageline.h +++ b/ui/utils/messageline.h @@ -50,17 +50,22 @@ public: void showBusyIndicator(); void hideBusyIndicator(); void responseLocalFile(const QString& messageId, const QString& path); - void downloadError(const QString& messageId, const QString& error); - void responseDownloadProgress(const QString& messageId, qreal progress); + void fileError(const QString& messageId, const QString& error); + void fileProgress(const QString& messageId, qreal progress); + void appendMessageWithUpload(const Shared::Message& message, const QString& path); signals: void resize(int amount); void downloadFile(const QString& messageId, const QString& url); + void uploadFile(const Shared::Message& msg, const QString& path); void requestLocalFile(const QString& messageId, const QString& url); protected: void resizeEvent(QResizeEvent * event) override; +protected: + void onDownload(); + private: struct Comparator { bool operator()(const Shared::Message& a, const Shared::Message& b) const { @@ -76,11 +81,14 @@ private: Order messageOrder; Index myMessages; std::map palMessages; + std::map uploadPaths; QVBoxLayout* layout; QString myName; std::map palNames; std::deque views; + Index uploading; + Index downloading; bool room; bool busyShown; Progress progress;