basic error download/upload files handling, need more testing

This commit is contained in:
Blue 2021-05-14 22:49:38 +03:00
parent bd07c49755
commit 4307262f6e
8 changed files with 206 additions and 77 deletions

View File

@ -70,6 +70,9 @@ void Core::NetworkAccess::start()
{ {
if (!running) { if (!running) {
manager = new QNetworkAccessManager(); manager = new QNetworkAccessManager();
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
manager->setTransferTimeout();
#endif
storage.open(); storage.open();
running = true; running = true;
} }
@ -99,31 +102,56 @@ void Core::NetworkAccess::onDownloadProgress(qint64 bytesReceived, qint64 bytesT
qDebug() << "an error downloading" << url << ": the request had some progress but seems like no one is waiting for it, skipping"; qDebug() << "an error downloading" << url << ": the request had some progress but seems like no one is waiting for it, skipping";
} else { } else {
Transfer* dwn = itr->second; Transfer* dwn = itr->second;
qreal received = bytesReceived; if (dwn->success) {
qreal total = bytesTotal; qreal received = bytesReceived;
qreal progress = received/total; qreal total = bytesTotal;
dwn->progress = progress; qreal progress = received/total;
emit loadFileProgress(dwn->messages, progress, false); dwn->progress = progress;
emit loadFileProgress(dwn->messages, progress, false);
}
} }
} }
void Core::NetworkAccess::onDownloadError(QNetworkReply::NetworkError code) void Core::NetworkAccess::onDownloadError(QNetworkReply::NetworkError code)
{ {
qDebug() << "DEBUG: DOWNLOAD ERROR";
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender()); QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
qDebug() << rpl->errorString();
QString url = rpl->url().toString(); QString url = rpl->url().toString();
std::map<QString, Transfer*>::const_iterator itr = downloads.find(url); std::map<QString, Transfer*>::const_iterator itr = downloads.find(url);
if (itr == downloads.end()) { if (itr == downloads.end()) {
qDebug() << "an error downloading" << url << ": the request is reporting an error but seems like no one is waiting for it, skipping"; qDebug() << "an error downloading" << url << ": the request is reporting an error but seems like no one is waiting for it, skipping";
} else { } else {
QString errorText = getErrorText(code); QString errorText = getErrorText(code);
if (errorText.size() > 0) { //if (errorText.size() > 0) {
itr->second->success = false; itr->second->success = false;
Transfer* dwn = itr->second; Transfer* dwn = itr->second;
emit loadFileError(dwn->messages, errorText, false); emit loadFileError(dwn->messages, errorText, false);
} //}
} }
} }
void Core::NetworkAccess::onDownloadSSLError(const QList<QSslError>& errors)
{
qDebug() << "DEBUG: DOWNLOAD SSL ERRORS";
for (const QSslError& err : errors) {
qDebug() << err.errorString();
}
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
QString url = rpl->url().toString();
std::map<QString, Transfer*>::const_iterator itr = downloads.find(url);
if (itr == downloads.end()) {
qDebug() << "an SSL error downloading" << url << ": the request is reporting an error but seems like no one is waiting for it, skipping";
} else {
//if (errorText.size() > 0) {
itr->second->success = false;
Transfer* dwn = itr->second;
emit loadFileError(dwn->messages, "SSL errors occured", false);
//}
}
}
QString Core::NetworkAccess::getErrorText(QNetworkReply::NetworkError code) QString Core::NetworkAccess::getErrorText(QNetworkReply::NetworkError code)
{ {
QString errorText(""); QString errorText("");
@ -146,7 +174,11 @@ QString Core::NetworkAccess::getErrorText(QNetworkReply::NetworkError code)
errorText = "Connection was closed because it timed out"; errorText = "Connection was closed because it timed out";
break; break;
case QNetworkReply::OperationCanceledError: case QNetworkReply::OperationCanceledError:
//this means I closed it myself by abort() or close(), don't think I need to notify here //this means I closed it myself by abort() or close()
//I don't call them directory, but this is the error code
//Qt returns when it can not resume donwload after the network failure
//or when the download is canceled by the timout;
errorText = "Connection lost";
break; break;
case QNetworkReply::SslHandshakeFailedError: case QNetworkReply::SslHandshakeFailedError:
errorText = "Security error"; //TODO need to handle sslErrors signal to get a better description here errorText = "Security error"; //TODO need to handle sslErrors signal to get a better description here
@ -247,6 +279,7 @@ QString Core::NetworkAccess::getErrorText(QNetworkReply::NetworkError code)
void Core::NetworkAccess::onDownloadFinished() void Core::NetworkAccess::onDownloadFinished()
{ {
qDebug() << "DEBUG: DOWNLOAD FINISHED";
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender()); QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
QString url = rpl->url().toString(); QString url = rpl->url().toString();
std::map<QString, Transfer*>::const_iterator itr = downloads.find(url); std::map<QString, Transfer*>::const_iterator itr = downloads.find(url);
@ -256,11 +289,14 @@ void Core::NetworkAccess::onDownloadFinished()
Transfer* dwn = itr->second; Transfer* dwn = itr->second;
if (dwn->success) { if (dwn->success) {
qDebug() << "download success for" << url; qDebug() << "download success for" << url;
QString err;
QStringList hops = url.split("/"); QStringList hops = url.split("/");
QString fileName = hops.back(); QString fileName = hops.back();
QString jid; QString jid;
if (dwn->messages.size() > 0) { if (dwn->messages.size() > 0) {
jid = dwn->messages.front().jid; jid = dwn->messages.front().jid;
} else {
qDebug() << "An attempt to save the file but it doesn't seem to belong to any message, download is definately going to be broken";
} }
QString path = prepareDirectory(jid); QString path = prepareDirectory(jid);
if (path.size() > 0) { if (path.size() > 0) {
@ -274,15 +310,16 @@ void Core::NetworkAccess::onDownloadFinished()
qDebug() << "file" << path << "was successfully downloaded"; qDebug() << "file" << path << "was successfully downloaded";
} else { } else {
qDebug() << "couldn't save file" << path; qDebug() << "couldn't save file" << path;
path = QString(); err = "Error opening file to write:" + file.errorString();
} }
} else {
err = "Couldn't prepare a directory for file";
} }
if (path.size() > 0) { if (path.size() > 0) {
emit downloadFileComplete(dwn->messages, path); emit downloadFileComplete(dwn->messages, path);
} else { } else {
//TODO do I need to handle the failure here or it's already being handled in error? emit loadFileError(dwn->messages, "Error saving file " + url + "; " + err, false);
//emit loadFileError(dwn->messages, path, false);
} }
} }
@ -298,6 +335,7 @@ void Core::NetworkAccess::startDownload(const std::list<Shared::MessageInfo>& ms
QNetworkRequest req(url); QNetworkRequest req(url);
dwn->reply = manager->get(req); dwn->reply = manager->get(req);
connect(dwn->reply, &QNetworkReply::downloadProgress, this, &NetworkAccess::onDownloadProgress); connect(dwn->reply, &QNetworkReply::downloadProgress, this, &NetworkAccess::onDownloadProgress);
connect(dwn->reply, &QNetworkReply::sslErrors, this, &NetworkAccess::onDownloadSSLError);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
connect(dwn->reply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::errorOccurred), this, &NetworkAccess::onDownloadError); connect(dwn->reply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::errorOccurred), this, &NetworkAccess::onDownloadError);
#else #else
@ -317,11 +355,11 @@ void Core::NetworkAccess::onUploadError(QNetworkReply::NetworkError code)
qDebug() << "an error uploading" << url << ": the request is reporting an error but there is no record of it being uploading, ignoring"; qDebug() << "an error uploading" << url << ": the request is reporting an error but there is no record of it being uploading, ignoring";
} else { } else {
QString errorText = getErrorText(code); QString errorText = getErrorText(code);
if (errorText.size() > 0) { //if (errorText.size() > 0) {
itr->second->success = false; itr->second->success = false;
Transfer* upl = itr->second; Transfer* upl = itr->second;
emit loadFileError(upl->messages, errorText, true); emit loadFileError(upl->messages, errorText, true);
} //}
//TODO deletion? //TODO deletion?
} }
@ -360,11 +398,13 @@ void Core::NetworkAccess::onUploadProgress(qint64 bytesReceived, qint64 bytesTot
qDebug() << "an error downloading" << url << ": the request had some progress but seems like no one is waiting for it, skipping"; qDebug() << "an error downloading" << url << ": the request had some progress but seems like no one is waiting for it, skipping";
} else { } else {
Transfer* upl = itr->second; Transfer* upl = itr->second;
qreal received = bytesReceived; if (upl->success) {
qreal total = bytesTotal; qreal received = bytesReceived;
qreal progress = received/total; qreal total = bytesTotal;
upl->progress = progress; qreal progress = received/total;
emit loadFileProgress(upl->messages, progress, true); upl->progress = progress;
emit loadFileProgress(upl->messages, progress, true);
}
} }
} }

View File

@ -75,6 +75,7 @@ private:
private slots: private slots:
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void onDownloadError(QNetworkReply::NetworkError code); void onDownloadError(QNetworkReply::NetworkError code);
void onDownloadSSLError(const QList<QSslError> &errors);
void onDownloadFinished(); void onDownloadFinished();
void onUploadProgress(qint64 bytesReceived, qint64 bytesTotal); void onUploadProgress(qint64 bytesReceived, qint64 bytesTotal);
void onUploadError(QNetworkReply::NetworkError code); void onUploadError(QNetworkReply::NetworkError code);

View File

@ -45,6 +45,8 @@ Models::MessageFeed::MessageFeed(const Element* ri, QObject* parent):
syncState(incomplete), syncState(incomplete),
uploads(), uploads(),
downloads(), downloads(),
failedDownloads(),
failedUploads(),
unreadMessages(new std::set<QString>()), unreadMessages(new std::set<QString>()),
observersAmount(0) observersAmount(0)
{ {
@ -142,6 +144,18 @@ void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, Q
} }
} }
Err::const_iterator eitr = failedDownloads.find(id);
if (eitr != failedDownloads.end()) {
failedDownloads.erase(eitr);
changeRoles.insert(MessageRoles::Attach);
} else {
eitr = failedUploads.find(id);
if (eitr != failedUploads.end()) {
failedUploads.erase(eitr);
changeRoles.insert(MessageRoles::Attach);
}
}
QVector<int> cr; QVector<int> cr;
for (MessageRoles role : changeRoles) { for (MessageRoles role : changeRoles) {
cr.push_back(role); cr.push_back(role);
@ -421,6 +435,7 @@ bool Models::MessageFeed::sentByMe(const Shared::Message& msg) const
Models::Attachment Models::MessageFeed::fillAttach(const Shared::Message& msg) const Models::Attachment Models::MessageFeed::fillAttach(const Shared::Message& msg) const
{ {
::Models::Attachment att; ::Models::Attachment att;
QString id = msg.getId();
att.localPath = msg.getAttachPath(); att.localPath = msg.getAttachPath();
att.remotePath = msg.getOutOfBandUrl(); att.remotePath = msg.getOutOfBandUrl();
@ -429,22 +444,34 @@ Models::Attachment Models::MessageFeed::fillAttach(const Shared::Message& msg) c
if (att.localPath.size() == 0) { if (att.localPath.size() == 0) {
att.state = none; att.state = none;
} else { } else {
Progress::const_iterator itr = uploads.find(msg.getId()); Err::const_iterator eitr = failedUploads.find(id);
if (itr == uploads.end()) { if (eitr != failedUploads.end()) {
att.state = local; att.state = errorUpload;
att.error = eitr->second;
} else { } else {
att.state = uploading; Progress::const_iterator itr = uploads.find(id);
att.progress = itr->second; if (itr == uploads.end()) {
att.state = local;
} else {
att.state = uploading;
att.progress = itr->second;
}
} }
} }
} else { } else {
if (att.localPath.size() == 0) { if (att.localPath.size() == 0) {
Progress::const_iterator itr = downloads.find(msg.getId()); Err::const_iterator eitr = failedDownloads.find(id);
if (itr == downloads.end()) { if (eitr != failedDownloads.end()) {
att.state = remote; att.state = errorDownload;
att.error = eitr->second;
} else { } else {
att.state = downloading; Progress::const_iterator itr = downloads.find(id);
att.progress = itr->second; if (itr == downloads.end()) {
att.state = remote;
} else {
att.state = downloading;
att.progress = itr->second;
}
} }
} else { } else {
att.state = ready; att.state = ready;
@ -456,12 +483,19 @@ Models::Attachment Models::MessageFeed::fillAttach(const Shared::Message& msg) c
void Models::MessageFeed::downloadAttachment(const QString& messageId) void Models::MessageFeed::downloadAttachment(const QString& messageId)
{ {
bool notify = false;
Err::const_iterator eitr = failedDownloads.find(messageId);
if (eitr != failedDownloads.end()) {
failedDownloads.erase(eitr);
notify = true;
}
QModelIndex ind = modelIndexById(messageId); QModelIndex ind = modelIndexById(messageId);
if (ind.isValid()) { if (ind.isValid()) {
std::pair<Progress::iterator, bool> progressPair = downloads.insert(std::make_pair(messageId, 0)); std::pair<Progress::iterator, bool> progressPair = downloads.insert(std::make_pair(messageId, 0));
if (progressPair.second) { //Only to take action if we weren't already downloading it if (progressPair.second) { //Only to take action if we weren't already downloading it
Shared::Message* msg = static_cast<Shared::Message*>(ind.internalPointer()); Shared::Message* msg = static_cast<Shared::Message*>(ind.internalPointer());
emit dataChanged(ind, ind, {MessageRoles::Attach}); notify = true;
emit fileDownloadRequest(msg->getOutOfBandUrl()); emit fileDownloadRequest(msg->getOutOfBandUrl());
} else { } else {
qDebug() << "Attachment download for message with id" << messageId << "is already in progress, skipping"; qDebug() << "Attachment download for message with id" << messageId << "is already in progress, skipping";
@ -469,32 +503,55 @@ void Models::MessageFeed::downloadAttachment(const QString& messageId)
} else { } else {
qDebug() << "An attempt to download an attachment for the message that doesn't exist. ID:" << messageId; qDebug() << "An attempt to download an attachment for the message that doesn't exist. ID:" << messageId;
} }
}
if (notify) {
void Models::MessageFeed::uploadAttachment(const QString& messageId) emit dataChanged(ind, ind, {MessageRoles::Attach});
{ }
qDebug() << "request to upload attachment of the message" << messageId;
} }
bool Models::MessageFeed::registerUpload(const QString& messageId) bool Models::MessageFeed::registerUpload(const QString& messageId)
{ {
return uploads.insert(std::make_pair(messageId, 0)).second; bool success = uploads.insert(std::make_pair(messageId, 0)).second;
QVector<int> roles({});
Err::const_iterator eitr = failedUploads.find(messageId);
if (eitr != failedUploads.end()) {
failedUploads.erase(eitr);
roles.push_back(MessageRoles::Attach);
} else if (success) {
roles.push_back(MessageRoles::Attach);
}
QModelIndex ind = modelIndexById(messageId);
emit dataChanged(ind, ind, roles);
return success;
} }
void Models::MessageFeed::fileProgress(const QString& messageId, qreal value, bool up) void Models::MessageFeed::fileProgress(const QString& messageId, qreal value, bool up)
{ {
Progress* pr = 0; Progress* pr = 0;
Err* err = 0;
if (up) { if (up) {
pr = &uploads; pr = &uploads;
err = &failedUploads;
} else { } else {
pr = &downloads; pr = &downloads;
err = &failedDownloads;
}
QVector<int> roles({});
Err::const_iterator eitr = err->find(messageId);
if (eitr != err->end() && value != 1) { //like I want to clear this state when the download is started anew
err->erase(eitr);
roles.push_back(MessageRoles::Attach);
} }
Progress::iterator itr = pr->find(messageId); Progress::iterator itr = pr->find(messageId);
if (itr != pr->end()) { if (itr != pr->end()) {
itr->second = value; itr->second = value;
QModelIndex ind = modelIndexById(messageId); QModelIndex ind = modelIndexById(messageId);
emit dataChanged(ind, ind); //the type of the attach didn't change, so, there is no need to relayout, there is no role in event emit dataChanged(ind, ind, roles);
} }
} }
@ -505,7 +562,29 @@ void Models::MessageFeed::fileComplete(const QString& messageId, bool up)
void Models::MessageFeed::fileError(const QString& messageId, const QString& error, bool up) void Models::MessageFeed::fileError(const QString& messageId, const QString& error, bool up)
{ {
//TODO Err* failed;
Progress* loads;
if (up) {
failed = &failedUploads;
loads = &uploads;
} else {
failed = &failedDownloads;
loads = &downloads;
}
Progress::iterator pitr = loads->find(messageId);
if (pitr != loads->end()) {
loads->erase(pitr);
}
std::pair<Err::iterator, bool> pair = failed->insert(std::make_pair(messageId, error));
if (!pair.second) {
pair.first->second = error;
}
QModelIndex ind = modelIndexById(messageId);
if (ind.isValid()) {
emit dataChanged(ind, ind, {MessageRoles::Attach});
}
} }
void Models::MessageFeed::incrementObservers() void Models::MessageFeed::incrementObservers()
@ -533,19 +612,18 @@ QModelIndex Models::MessageFeed::modelIndexById(const QString& id) const
QModelIndex Models::MessageFeed::modelIndexByTime(const QString& id, const QDateTime& time) const QModelIndex Models::MessageFeed::modelIndexByTime(const QString& id, const QDateTime& time) const
{ {
if (indexByTime.size() > 0) { if (indexByTime.size() > 0) {
StorageByTime::const_iterator tItr = indexByTime.upper_bound(time); StorageByTime::const_iterator tItr = indexByTime.lower_bound(time);
StorageByTime::const_iterator tBeg = indexByTime.begin(); StorageByTime::const_iterator tEnd = indexByTime.upper_bound(time);
StorageByTime::const_iterator tEnd = indexByTime.end();
bool found = false; bool found = false;
while (tItr != tBeg) { while (tItr != tEnd) {
if (tItr != tEnd && id == (*tItr)->getId()) { if (id == (*tItr)->getId()) {
found = true; found = true;
break; break;
} }
--tItr; ++tItr;
} }
if (found && tItr != tEnd && id == (*tItr)->getId()) { if (found) {
int position = indexByTime.rank(tItr); int position = indexByTime.rank(tItr);
return createIndex(position, 0, *tItr); return createIndex(position, 0, *tItr);
} }
@ -566,7 +644,7 @@ void Models::MessageFeed::reportLocalPathInvalid(const QString& messageId)
emit localPathInvalid(msg->getAttachPath()); emit localPathInvalid(msg->getAttachPath());
//gonna change the message in current model right away, to prevent spam on each attemt to draw element //gonna change the message in current model right away, to prevent spam on each attempt to draw element
QModelIndex index = modelIndexByTime(messageId, msg->getTime()); QModelIndex index = modelIndexByTime(messageId, msg->getTime());
msg->setAttachPath(""); msg->setAttachPath("");

View File

@ -65,7 +65,6 @@ public:
void responseArchive(const std::list<Shared::Message> list, bool last); void responseArchive(const std::list<Shared::Message> list, bool last);
void downloadAttachment(const QString& messageId); void downloadAttachment(const QString& messageId);
void uploadAttachment(const QString& messageId);
bool registerUpload(const QString& messageId); bool registerUpload(const QString& messageId);
void reportLocalPathInvalid(const QString& messageId); void reportLocalPathInvalid(const QString& messageId);
@ -148,12 +147,16 @@ private:
SyncState syncState; SyncState syncState;
typedef std::map<QString, qreal> Progress; typedef std::map<QString, qreal> Progress;
typedef std::map<QString, QString> Err;
Progress uploads; Progress uploads;
Progress downloads; Progress downloads;
Err failedDownloads;
Err failedUploads;
std::set<QString>* unreadMessages; std::set<QString>* unreadMessages;
uint16_t observersAmount; uint16_t observersAmount;
static const QHash<int, QByteArray> roles; static const QHash<int, QByteArray> roles;
}; };
@ -173,6 +176,7 @@ struct Attachment {
qreal progress; qreal progress;
QString localPath; QString localPath;
QString remotePath; QString remotePath;
QString error;
}; };
struct FeedItem { struct FeedItem {

View File

@ -394,16 +394,11 @@ void FeedView::setModel(QAbstractItemModel* p_model)
} }
} }
void FeedView::onMessageButtonPushed(const QString& messageId, bool download) void FeedView::onMessageButtonPushed(const QString& messageId)
{ {
if (specialModel) { if (specialModel) {
Models::MessageFeed* feed = static_cast<Models::MessageFeed*>(model()); Models::MessageFeed* feed = static_cast<Models::MessageFeed*>(model());
feed->downloadAttachment(messageId);
if (download) {
feed->downloadAttachment(messageId);
} else {
feed->uploadAttachment(messageId);
}
} }
} }

View File

@ -58,7 +58,7 @@ protected slots:
void rowsInserted(const QModelIndex & parent, int start, int end) override; void rowsInserted(const QModelIndex & parent, int start, int end) override;
void verticalScrollbarValueChanged(int value) override; void verticalScrollbarValueChanged(int value) override;
void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles) override; void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles) override;
void onMessageButtonPushed(const QString& messageId, bool download); void onMessageButtonPushed(const QString& messageId);
void onMessageInvalidPath(const QString& messageId); void onMessageInvalidPath(const QString& messageId);
void onModelSyncStateChange(Models::MessageFeed::SyncState state); void onModelSyncStateChange(Models::MessageFeed::SyncState state);

View File

@ -137,19 +137,39 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
clearHelperWidget(data); //i can't imagine the situation where it's gonna be needed clearHelperWidget(data); //i can't imagine the situation where it's gonna be needed
break; //but it's a possible performance problem break; //but it's a possible performance problem
case Models::uploading: case Models::uploading:
paintPreview(data, painter, opt);
case Models::downloading: case Models::downloading:
paintBar(getBar(data), painter, data.sentByMe, opt); paintBar(getBar(data), painter, data.sentByMe, opt);
break; break;
case Models::remote: case Models::remote:
case Models::local:
paintButton(getButton(data), painter, data.sentByMe, opt); paintButton(getButton(data), painter, data.sentByMe, opt);
break; break;
case Models::ready: case Models::ready:
case Models::local:
clearHelperWidget(data); clearHelperWidget(data);
paintPreview(data, painter, opt); paintPreview(data, painter, opt);
break; break;
case Models::errorDownload: case Models::errorDownload: {
case Models::errorUpload: paintButton(getButton(data), painter, data.sentByMe, opt);
painter->setFont(dateFont);
QColor q = painter->pen().color();
q.setAlpha(180);
painter->setPen(q);
painter->drawText(opt.rect, opt.displayAlignment, data.attach.error, &rect);
opt.rect.adjust(0, rect.height() + textMargin, 0, 0);
}
break;
case Models::errorUpload:{
clearHelperWidget(data);
paintPreview(data, painter, opt);
painter->setFont(dateFont);
QColor q = painter->pen().color();
q.setAlpha(180);
painter->setPen(q);
painter->drawText(opt.rect, opt.displayAlignment, data.attach.error, &rect);
opt.rect.adjust(0, rect.height() + textMargin, 0, 0);
}
break; break;
} }
painter->restore(); painter->restore();
@ -212,18 +232,24 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
case Models::none: case Models::none:
break; break;
case Models::uploading: case Models::uploading:
messageSize.rheight() += calculateAttachSize(attach.localPath, messageRect).height() + textMargin;
case Models::downloading: case Models::downloading:
messageSize.rheight() += barHeight + textMargin; messageSize.rheight() += barHeight + textMargin;
break; break;
case Models::remote: case Models::remote:
case Models::local:
messageSize.rheight() += buttonHeight + textMargin; messageSize.rheight() += buttonHeight + textMargin;
break; break;
case Models::ready: case Models::ready:
case Models::local:
messageSize.rheight() += calculateAttachSize(attach.localPath, messageRect).height() + textMargin; messageSize.rheight() += calculateAttachSize(attach.localPath, messageRect).height() + textMargin;
break; break;
case Models::errorDownload: case Models::errorDownload:
messageSize.rheight() += buttonHeight + textMargin;
messageSize.rheight() += dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, attach.error).size().height() + textMargin;
break;
case Models::errorUpload: case Models::errorUpload:
messageSize.rheight() += calculateAttachSize(attach.localPath, messageRect).height() + textMargin;
messageSize.rheight() += dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, attach.error).size().height() + textMargin;
break; break;
} }
@ -356,15 +382,7 @@ QPushButton * MessageDelegate::getButton(const Models::FeedItem& data) const
std::map<QString, FeedButton*>::const_iterator itr = buttons->find(data.id); std::map<QString, FeedButton*>::const_iterator itr = buttons->find(data.id);
FeedButton* result = 0; FeedButton* result = 0;
if (itr != buttons->end()) { if (itr != buttons->end()) {
if ( result = itr->second;
(data.attach.state == Models::remote && itr->second->download) ||
(data.attach.state == Models::local && !itr->second->download)
) {
result = itr->second;
} else {
delete itr->second;
buttons->erase(itr);
}
} else { } else {
std::map<QString, QProgressBar*>::const_iterator barItr = bars->find(data.id); std::map<QString, QProgressBar*>::const_iterator barItr = bars->find(data.id);
if (barItr != bars->end()) { if (barItr != bars->end()) {
@ -376,13 +394,7 @@ QPushButton * MessageDelegate::getButton(const Models::FeedItem& data) const
if (result == 0) { if (result == 0) {
result = new FeedButton(); result = new FeedButton();
result->messageId = data.id; result->messageId = data.id;
if (data.attach.state == Models::remote) { result->setText(QCoreApplication::translate("MessageLine", "Download"));
result->setText(QCoreApplication::translate("MessageLine", "Download"));
result->download = true;
} else {
result->setText(QCoreApplication::translate("MessageLine", "Upload"));
result->download = false;
}
buttons->insert(std::make_pair(data.id, result)); buttons->insert(std::make_pair(data.id, result));
connect(result, &QPushButton::clicked, this, &MessageDelegate::onButtonPushed); connect(result, &QPushButton::clicked, this, &MessageDelegate::onButtonPushed);
} }
@ -529,7 +541,7 @@ void MessageDelegate::endClearWidgets()
void MessageDelegate::onButtonPushed() const void MessageDelegate::onButtonPushed() const
{ {
FeedButton* btn = static_cast<FeedButton*>(sender()); FeedButton* btn = static_cast<FeedButton*>(sender());
emit buttonPushed(btn->messageId, btn->download); emit buttonPushed(btn->messageId);
} }
void MessageDelegate::clearHelperWidget(const Models::FeedItem& data) const void MessageDelegate::clearHelperWidget(const Models::FeedItem& data) const

View File

@ -55,7 +55,7 @@ public:
void beginClearWidgets(); void beginClearWidgets();
signals: signals:
void buttonPushed(const QString& messageId, bool download) const; void buttonPushed(const QString& messageId) const;
void invalidPath(const QString& messageId) const; void invalidPath(const QString& messageId) const;
protected: protected:
@ -77,7 +77,6 @@ private:
class FeedButton : public QPushButton { class FeedButton : public QPushButton {
public: public:
QString messageId; QString messageId;
bool download;
}; };
QFont bodyFont; QFont bodyFont;