From 0e937199b0187f97ba178309c867db39509cfe5a Mon Sep 17 00:00:00 2001 From: blue Date: Wed, 21 Apr 2021 00:56:47 +0300 Subject: [PATCH] debug and actual first way to display pictures in messageFeed --- shared/global.cpp | 31 ++++++++++++++++++- shared/global.h | 21 +++++++++++++ ui/models/messagefeed.cpp | 2 +- ui/utils/feedview.cpp | 7 +++++ ui/utils/feedview.h | 1 + ui/utils/messagedelegate.cpp | 59 +++++++++++++++++++++++++++++++++--- ui/utils/messagedelegate.h | 5 ++- 7 files changed, 118 insertions(+), 8 deletions(-) diff --git a/shared/global.cpp b/shared/global.cpp index a6b7b60..981dd60 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -81,7 +81,8 @@ Shared::Global::Global(): }), pluginSupport({ {"KWallet", false} - }) + }), + fileCache() { if (instance != 0) { throw 551; @@ -90,6 +91,34 @@ Shared::Global::Global(): instance = this; } +Shared::Global::FileInfo Shared::Global::getFileInfo(const QString& path) +{ + std::map::const_iterator itr = instance->fileCache.find(path); + if (itr == instance->fileCache.end()) { + QMimeDatabase db; + QMimeType type = db.mimeTypeForFile(path); + QStringList parts = type.name().split("/"); + QString big = parts.front(); + QFileInfo info(path); + + FileInfo::Preview p = FileInfo::Preview::none; + QSize size; + if (big == "image") { + if (parts.back() == "gif") { + //TODO need to consider GIF as a movie + } + p = FileInfo::Preview::picture; + QImage img(path); + size = img.size(); + } + + itr = instance->fileCache.insert(std::make_pair(path, FileInfo({info.fileName(), size, type, p}))).first; + } + + return itr->second; +} + + Shared::Global * Shared::Global::getInstance() { return instance; diff --git a/shared/global.h b/shared/global.h index 54e1584..bb9e5b7 100644 --- a/shared/global.h +++ b/shared/global.h @@ -29,6 +29,11 @@ #include #include +#include +#include +#include +#include +#include namespace Shared { @@ -36,6 +41,19 @@ namespace Shared { Q_DECLARE_TR_FUNCTIONS(Global) public: + struct FileInfo { + enum class Preview { + none, + picture, + movie + }; + + QString name; + QSize size; + QMimeType mime; + Preview preview; + }; + Global(); static Global* getInstance(); @@ -64,6 +82,8 @@ namespace Shared { static const std::set supportedImagesExts; + static FileInfo getFileInfo(const QString& path); + template static T fromInt(int src); @@ -87,6 +107,7 @@ namespace Shared { static Global* instance; std::map pluginSupport; + std::map fileCache; }; } diff --git a/ui/models/messagefeed.cpp b/ui/models/messagefeed.cpp index 7c82900..2345816 100644 --- a/ui/models/messagefeed.cpp +++ b/ui/models/messagefeed.cpp @@ -407,7 +407,7 @@ QModelIndex Models::MessageFeed::modelIndexByTime(const QString& id, const QDate --tItr; } - if (found) { + if (found || id == (*tItr)->getId()) { int position = indexByTime.rank(tItr); return createIndex(position, 0, *tItr); } diff --git a/ui/utils/feedview.cpp b/ui/utils/feedview.cpp index 15f6fb3..7155d95 100644 --- a/ui/utils/feedview.cpp +++ b/ui/utils/feedview.cpp @@ -113,6 +113,13 @@ void FeedView::rowsInserted(const QModelIndex& parent, int start, int end) QAbstractItemView::rowsInserted(parent, start, end); } +void FeedView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles) +{ + //TODO make optimisations! There are some roles but not all that change geometry! + updateGeometries(); + QAbstractItemView::dataChanged(topLeft, bottomRight, roles); +} + void FeedView::updateGeometries() { qDebug() << "updateGeometries"; diff --git a/ui/utils/feedview.h b/ui/utils/feedview.h index 6d16ea3..a0b9252 100644 --- a/ui/utils/feedview.h +++ b/ui/utils/feedview.h @@ -52,6 +52,7 @@ public slots: protected slots: void rowsInserted(const QModelIndex & parent, int start, int end) override; void verticalScrollbarValueChanged(int value) override; + void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector & roles) override; void onMessageButtonPushed(const QString& messageId, bool download); protected: diff --git a/ui/utils/messagedelegate.cpp b/ui/utils/messagedelegate.cpp index 83eaa42..6d53141 100644 --- a/ui/utils/messagedelegate.cpp +++ b/ui/utils/messagedelegate.cpp @@ -115,7 +115,6 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio painter->setFont(nickFont); painter->drawText(opt.rect, opt.displayAlignment, data.sender, &rect); - opt.rect.adjust(0, rect.height(), 0, 0); painter->save(); switch (data.attach.state) { @@ -131,6 +130,11 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio paintButton(getButton(data), painter, data.sentByMe, opt); break; case Models::ready: + clearHelperWidget(data); + paintPreview(data, painter, opt); + break; + case Models::errorDownload: + case Models::errorUpload: break; } painter->restore(); @@ -178,6 +182,7 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel messageSize.rheight() += buttonHeight; break; case Models::ready: + messageSize.rheight() += calculateAttachSize(attach.localPath, messageRect).height(); break; case Models::errorDownload: case Models::errorUpload: @@ -245,15 +250,41 @@ void MessageDelegate::paintBar(QProgressBar* bar, QPainter* painter, bool sentBy { QPoint start = option.rect.topLeft(); - QWidget* vp = static_cast(painter->device()); - bar->setParent(vp); - bar->move(start); + //QWidget* vp = static_cast(painter->device()); + +// if (bar->parent() != vp) { +// bar->setParent(vp); +// } +// bar->move(start); bar->resize(option.rect.width(), barHeight); - bar->show(); + // bar->show(); + + painter->translate(start); + bar->render(painter, QPoint(), QRegion(), QWidget::DrawChildren); option.rect.adjust(0, barHeight, 0, 0); } +void MessageDelegate::paintPreview(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const +{ + Shared::Global::FileInfo info = Shared::Global::getFileInfo(data.attach.localPath); + if (info.preview == Shared::Global::FileInfo::Preview::picture) { + QSize size = constrainAttachSize(info.size, option.rect.size()); + + QPoint start; + if (data.sentByMe) { + start = {option.rect.width() - size.width(), option.rect.top()}; + start.rx() += margin; + } else { + start = option.rect.topLeft(); + } + QImage img(data.attach.localPath); + painter->drawImage(QRect(start, size), img); + + option.rect.adjust(0, size.height(), 0, 0); + } +} + QPushButton * MessageDelegate::getButton(const Models::FeedItem& data) const { std::map::const_iterator itr = buttons->find(data.id); @@ -376,6 +407,24 @@ void MessageDelegate::clearHelperWidget(const Models::FeedItem& data) const } } +QSize MessageDelegate::calculateAttachSize(const QString& path, const QRect& bounds) const +{ + Shared::Global::FileInfo info = Shared::Global::getFileInfo(path); + + return constrainAttachSize(info.size, bounds.size()); +} + +QSize MessageDelegate::constrainAttachSize(QSize src, QSize bounds) const +{ + bounds.setHeight(500); + + if (src.width() > bounds.width() || src.height() > bounds.height()) { + src.scale(bounds, Qt::KeepAspectRatio); + } + + return src; +} + // void MessageDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const // { diff --git a/ui/utils/messagedelegate.h b/ui/utils/messagedelegate.h index 56f9ebf..cbad6cd 100644 --- a/ui/utils/messagedelegate.h +++ b/ui/utils/messagedelegate.h @@ -30,6 +30,7 @@ #include #include "shared/icons.h" +#include "shared/global.h" namespace Models { struct FeedItem; @@ -57,9 +58,12 @@ signals: protected: void paintButton(QPushButton* btn, QPainter* painter, bool sentByMe, QStyleOptionViewItem& option) const; void paintBar(QProgressBar* bar, QPainter* painter, bool sentByMe, QStyleOptionViewItem& option) const; + void paintPreview(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const; QPushButton* getButton(const Models::FeedItem& data) const; QProgressBar* getBar(const Models::FeedItem& data) const; void clearHelperWidget(const Models::FeedItem& data) const; + QSize calculateAttachSize(const QString& path, const QRect& bounds) const; + QSize constrainAttachSize(QSize src, QSize bounds) const; protected slots: void onButtonPushed() const; @@ -86,7 +90,6 @@ private: std::set* idsToKeep; bool clearingWidgets; - }; #endif // MESSAGEDELEGATE_H