diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 1836349..9369cb7 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -32,4 +32,3 @@ target_include_directories(squawk PRIVATE ${LMDB_INCLUDE_DIRS}) add_subdirectory(handlers) add_subdirectory(passwordStorageEngines) -add_subdirectory(utils) diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index eb840f8..fc05a67 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -298,6 +298,14 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) data.setTime(sendTime); } changes.insert("stamp", sendTime); + + //sometimes (when the image is pasted with ctrl+v) + //I start sending message with one path, then copy it to downloads directory + //so, the final path changes. Let's assume it changes always since it costs me close to nothing + QString attachPath = data.getAttachPath(); + if (attachPath.size() > 0) { + changes.insert("attachPath", attachPath); + } if (ri != 0) { if (newMessage) { @@ -439,14 +447,15 @@ void Core::MessageHandler::handleUploadError(const QString& jid, const QString& }); } -void Core::MessageHandler::onUploadFileComplete(const std::list& msgs, const QString& path) +void Core::MessageHandler::onUploadFileComplete(const std::list& msgs, const QString& url, const QString& path) { for (const Shared::MessageInfo& info : msgs) { if (info.account == acc->getName()) { RosterItem* ri = acc->rh->getRosterItem(info.jid); if (ri != 0) { Shared::Message msg = ri->getMessage(info.messageId); - sendMessageWithLocalUploadedFile(msg, path, false); + msg.setAttachPath(path); + sendMessageWithLocalUploadedFile(msg, url, false); } else { qDebug() << "A signal received about complete upload to" << acc->name << "for pal" << info.jid << "but the object for this pal wasn't found, something went terrebly wrong, skipping send"; } diff --git a/core/handlers/messagehandler.h b/core/handlers/messagehandler.h index 4eb9265..b88c46a 100644 --- a/core/handlers/messagehandler.h +++ b/core/handlers/messagehandler.h @@ -57,7 +57,7 @@ public slots: void onUploadSlotReceived(const QXmppHttpUploadSlotIq& slot); void onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request); void onDownloadFileComplete(const std::list& msgs, const QString& path); - void onUploadFileComplete(const std::list& msgs, const QString& path); + void onUploadFileComplete(const std::list& msgs, const QString& url, const QString& path); void onLoadFileError(const std::list& msgs, const QString& path, bool up); void requestChangeMessage(const QString& jid, const QString& messageId, const QMap& data); diff --git a/core/main.cpp b/core/main.cpp index 570bad4..9a10062 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -18,10 +18,10 @@ #include "../shared/global.h" #include "../shared/messageinfo.h" +#include "../shared/pathcheck.h" #include "../ui/squawk.h" #include "signalcatcher.h" #include "squawk.h" -#include "utils/pathcheck.h" #include #include @@ -109,7 +109,7 @@ int main(int argc, char *argv[]) } } } - QString path = Utils::downloadsPathCheck(); + QString path = Shared::downloadsPathCheck(); if (path.size() > 0) { settings.setValue("downloadsPath", path); } else { diff --git a/core/networkaccess.cpp b/core/networkaccess.cpp index 48d26aa..25fafc8 100644 --- a/core/networkaccess.cpp +++ b/core/networkaccess.cpp @@ -305,7 +305,7 @@ void Core::NetworkAccess::onDownloadFinished() if (path.size() > 0) { path = checkFileName(fileName, path); - QFile file(path); + QFile file(Shared::resolvePath(path)); if (file.open(QIODevice::WriteOnly)) { file.write(dwn->reply->readAll()); file.close(); @@ -379,23 +379,20 @@ void Core::NetworkAccess::onUploadFinished() Transfer* upl = itr->second; if (upl->success) { qDebug() << "upload success for" << url; - - storage.addFile(upl->messages, upl->url, upl->path); - emit uploadFileComplete(upl->messages, upl->url, upl->path); // Copy file to Download folder if it is a temp file. See Conversation::onImagePasted. - if (upl->path.startsWith(QDir::tempPath() + QStringLiteral("/squawk_img_attach_")) && upl->path.endsWith(".png")) { + if (upl->path.startsWith(QDir::tempPath() + QDir::separator() + QStringLiteral("squawk_img_attach_")) && upl->path.endsWith(".png")) { QString err = ""; QString downloadDirPath = prepareDirectory(upl->messages.front().jid); if (downloadDirPath.size() > 0) { - QString newPath = downloadDirPath + "/" + upl->path.mid(QDir::tempPath().length() + 1); + QString newPath = downloadDirPath + QDir::separator() + upl->path.mid(QDir::tempPath().length() + 1); // Copy {TEMPDIR}/squawk_img_attach_XXXXXX.png to Download folder - bool copyResult = QFile::copy(upl->path, newPath); + bool copyResult = QFile::copy(upl->path, Shared::resolvePath(newPath)); if (copyResult) { // Change storage - storage.setPath(upl->url, newPath); + upl->path = newPath; } else { err = "copying to " + newPath + " failed"; } @@ -407,6 +404,9 @@ void Core::NetworkAccess::onUploadFinished() qDebug() << "failed to copy temporary upload file " << upl->path << " to download folder:" << err; } } + + storage.addFile(upl->messages, upl->url, upl->path); + emit uploadFileComplete(upl->messages, upl->url, upl->path); } upl->reply->deleteLater(); @@ -519,9 +519,12 @@ bool Core::NetworkAccess::checkAndAddToUploading(const QString& acc, const QStri QString Core::NetworkAccess::prepareDirectory(const QString& jid) { QString path = currentPath; + QString addition; if (jid.size() > 0) { - path += "/" + jid; + addition = jid; + path += QDir::separator() + jid; } + QDir location(path); if (!location.exists()) { @@ -529,10 +532,10 @@ QString Core::NetworkAccess::prepareDirectory(const QString& jid) if (!res) { return ""; } else { - return path; + return "squawk://" + addition; } } - return path; + return "squawk://" + addition; } QString Core::NetworkAccess::checkFileName(const QString& name, const QString& path) @@ -546,14 +549,17 @@ QString Core::NetworkAccess::checkFileName(const QString& name, const QString& p suffix += "." + (*sItr); } QString postfix(""); - QFileInfo proposedName(path + "/" + realName + suffix); + QString resolvedPath = Shared::resolvePath(path); + QString count(""); + QFileInfo proposedName(resolvedPath + QDir::separator() + realName + count + suffix); + int counter = 0; while (proposedName.exists()) { - QString count = QString("(") + std::to_string(++counter).c_str() + ")"; - proposedName = QFileInfo(path + "/" + realName + count + suffix); + count = QString("(") + std::to_string(++counter).c_str() + ")"; + proposedName = QFileInfo(resolvedPath + QDir::separator() + realName + count + suffix); } - - return proposedName.absoluteFilePath(); + + return path + QDir::separator() + realName + count + suffix; } QString Core::NetworkAccess::addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id) @@ -568,5 +574,10 @@ std::list Core::NetworkAccess::reportPathInvalid(const QStr void Core::NetworkAccess::moveFilesDirectory(const QString& newPath) { - + QDir dir; + if (dir.rename(currentPath, newPath)) { + currentPath = newPath; + } else { + qDebug() << "couldn't move downloads directory, most probably downloads will be broken"; + } } diff --git a/core/networkaccess.h b/core/networkaccess.h index cf24fc4..0b7bb7d 100644 --- a/core/networkaccess.h +++ b/core/networkaccess.h @@ -31,6 +31,7 @@ #include #include "urlstorage.h" +#include "shared/pathcheck.h" namespace Core { diff --git a/core/utils/CMakeLists.txt b/core/utils/CMakeLists.txt deleted file mode 100644 index 6722da7..0000000 --- a/core/utils/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -target_sources(squawk PRIVATE - pathcheck.h - pathcheck.cpp -) diff --git a/shared/CMakeLists.txt b/shared/CMakeLists.txt index a36b516..0ab7dbd 100644 --- a/shared/CMakeLists.txt +++ b/shared/CMakeLists.txt @@ -16,4 +16,6 @@ target_sources(squawk PRIVATE utils.h vcard.cpp vcard.h + pathcheck.cpp + pathcheck.h ) diff --git a/core/utils/pathcheck.cpp b/shared/pathcheck.cpp similarity index 59% rename from core/utils/pathcheck.cpp rename to shared/pathcheck.cpp index 3f1b86a..0850742 100644 --- a/core/utils/pathcheck.cpp +++ b/shared/pathcheck.cpp @@ -1,6 +1,7 @@ #include "pathcheck.h" -QString Utils::downloadsPathCheck() +QRegularExpression squawk("^squawk:\\/\\/"); +QString Shared::downloadsPathCheck() { QSettings settings; QVariant dpv = settings.value("downloadsPath"); @@ -8,40 +9,47 @@ QString Utils::downloadsPathCheck() if (!dpv.isValid()) { path = defaultDownloadsPath(); qDebug() << "no downloadsPath variable in config, using default" << path; - path = getCanonicalWritablePath(path); + path = getAbsoluteWritablePath(path); return path; } else { path = dpv.toString(); - path = getCanonicalWritablePath(path); + path = getAbsoluteWritablePath(path); if (path.size() == 0) { path = defaultDownloadsPath(); qDebug() << "falling back to the default downloads path" << path; - path = getCanonicalWritablePath(path); + path = getAbsoluteWritablePath(path); } return path; } } -QString Utils::defaultDownloadsPath() +QString Shared::defaultDownloadsPath() { return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/" + QApplication::applicationName(); } -QString Utils::getCanonicalWritablePath(const QString& path) +QString Shared::getAbsoluteWritablePath(const QString& path) { QDir location(path); if (!location.exists()) { - bool res = location.mkpath(location.canonicalPath()); + bool res = location.mkpath(location.absolutePath()); if (!res) { qDebug() << "couldn't create directory" << path; return ""; } } - QFileInfo info(location.canonicalPath()); + QFileInfo info(location.absolutePath()); if (info.isWritable()) { - return location.canonicalPath(); + return location.absolutePath(); } else { qDebug() << "directory" << path << "is not writable"; return ""; } } + +QString Shared::resolvePath(QString path) +{ + QSettings settings; + QVariant dpv = settings.value("downloadsPath"); + return path.replace(squawk, dpv.toString() + "/"); +} diff --git a/core/utils/pathcheck.h b/shared/pathcheck.h similarity index 66% rename from core/utils/pathcheck.h rename to shared/pathcheck.h index 8618012..6e7cd39 100644 --- a/core/utils/pathcheck.h +++ b/shared/pathcheck.h @@ -8,13 +8,15 @@ #include #include #include +#include -namespace Utils { +namespace Shared { QString downloadsPathCheck(); QString defaultDownloadsPath(); -QString getCanonicalWritablePath(const QString& path); +QString getAbsoluteWritablePath(const QString& path); +QString resolvePath(QString path); } diff --git a/ui/widgets/conversation.cpp b/ui/widgets/conversation.cpp index 69eac19..1c82024 100644 --- a/ui/widgets/conversation.cpp +++ b/ui/widgets/conversation.cpp @@ -483,7 +483,7 @@ void Conversation::onFeedContext(const QPoint& pos) }); } - QString path = item->getAttachPath(); + QString path = Shared::resolvePath(item->getAttachPath()); if (path.size() > 0) { showMenu = true; QAction* open = contextMenu->addAction(Shared::icon("document-preview"), tr("Open")); diff --git a/ui/widgets/conversation.h b/ui/widgets/conversation.h index a758b2c..76a8dd5 100644 --- a/ui/widgets/conversation.h +++ b/ui/widgets/conversation.h @@ -33,6 +33,7 @@ #include "shared/order.h" #include "shared/icons.h" #include "shared/utils.h" +#include "shared/pathcheck.h" #include "ui/models/account.h" #include "ui/models/roster.h" diff --git a/ui/widgets/messageline/messagedelegate.cpp b/ui/widgets/messageline/messagedelegate.cpp index d692752..22e8dcb 100644 --- a/ui/widgets/messageline/messagedelegate.cpp +++ b/ui/widgets/messageline/messagedelegate.cpp @@ -314,7 +314,7 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel case Models::none: break; case Models::uploading: - messageSize.rheight() += Preview::calculateAttachSize(data.attach.localPath, messageRect).height() + textMargin; + messageSize.rheight() += Preview::calculateAttachSize(Shared::resolvePath(data.attach.localPath), messageRect).height() + textMargin; [[fallthrough]]; case Models::downloading: messageSize.rheight() += barHeight + textMargin; @@ -326,7 +326,7 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel break; case Models::ready: case Models::local: { - QSize aSize = Preview::calculateAttachSize(data.attach.localPath, messageRect); + QSize aSize = Preview::calculateAttachSize(Shared::resolvePath(data.attach.localPath), messageRect); messageSize.rheight() += aSize.height() + textMargin; messageSize.setWidth(std::max(messageSize.width(), aSize.width())); } @@ -338,7 +338,7 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel } break; case Models::errorUpload: { - QSize aSize = Preview::calculateAttachSize(data.attach.localPath, messageRect); + QSize aSize = Preview::calculateAttachSize(Shared::resolvePath(data.attach.localPath), messageRect); QSize commentSize = dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size(); messageSize.rheight() += aSize.height() + commentSize.height() + textMargin * 2; messageSize.setWidth(std::max(messageSize.width(), std::max(commentSize.width(), aSize.width()))); @@ -455,12 +455,13 @@ int MessageDelegate::paintPreview(const Models::FeedItem& data, QPainter* painte std::map::iterator itr = previews->find(data.id); QSize size = option.rect.size(); + QString path = Shared::resolvePath(data.attach.localPath); if (itr != previews->end()) { preview = itr->second; - preview->actualize(data.attach.localPath, size, option.rect.topLeft()); + preview->actualize(path, size, option.rect.topLeft()); } else { QWidget* vp = static_cast(painter->device()); - preview = new Preview(data.attach.localPath, size, option.rect.topLeft(), vp); + preview = new Preview(path, size, option.rect.topLeft(), vp); previews->insert(std::make_pair(data.id, preview)); } diff --git a/ui/widgets/messageline/messagedelegate.h b/ui/widgets/messageline/messagedelegate.h index b58a1bb..9225412 100644 --- a/ui/widgets/messageline/messagedelegate.h +++ b/ui/widgets/messageline/messagedelegate.h @@ -33,6 +33,7 @@ #include "shared/icons.h" #include "shared/global.h" #include "shared/utils.h" +#include "shared/pathcheck.h" #include "preview.h"