initial attempt to paint buttons in the messagefeed

This commit is contained in:
Blue 2021-01-14 14:22:02 +03:00
parent ff4124d1f0
commit 00ffbac6b0
8 changed files with 156 additions and 18 deletions

View File

@ -375,6 +375,10 @@ void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firs
archiveState = complete; archiveState = complete;
archive->setFromTheBeginning(true); archive->setFromTheBeginning(true);
} }
if (added == 0 && wasEmpty) {
archiveState = empty;
break;
}
if (requestedCount != -1) { if (requestedCount != -1) {
QString before; QString before;
if (responseCache.size() > 0) { if (responseCache.size() > 0) {

View File

@ -36,7 +36,8 @@ Shared::Message::Message(Shared::Message::Type p_type):
errorText(), errorText(),
originalMessage(), originalMessage(),
lastModified(), lastModified(),
stanzaId() stanzaId(),
attachPath()
{} {}
Shared::Message::Message(): Shared::Message::Message():
@ -56,7 +57,8 @@ Shared::Message::Message():
errorText(), errorText(),
originalMessage(), originalMessage(),
lastModified(), lastModified(),
stanzaId() stanzaId(),
attachPath()
{} {}
QString Shared::Message::getBody() const QString Shared::Message::getBody() const
@ -311,6 +313,7 @@ void Shared::Message::serialize(QDataStream& data) const
data << lastModified; data << lastModified;
} }
data << stanzaId; data << stanzaId;
data << attachPath;
} }
void Shared::Message::deserialize(QDataStream& data) void Shared::Message::deserialize(QDataStream& data)
@ -341,6 +344,7 @@ void Shared::Message::deserialize(QDataStream& data)
data >> lastModified; data >> lastModified;
} }
data >> stanzaId; data >> stanzaId;
data >> attachPath;
} }
bool Shared::Message::change(const QMap<QString, QVariant>& data) bool Shared::Message::change(const QMap<QString, QVariant>& data)
@ -350,6 +354,16 @@ bool Shared::Message::change(const QMap<QString, QVariant>& data)
setState(static_cast<State>(itr.value().toUInt())); setState(static_cast<State>(itr.value().toUInt()));
} }
itr = data.find("outOfBandUrl");
if (itr != data.end()) {
setOutOfBandUrl(itr.value().toString());
}
itr = data.find("attachPath");
if (itr != data.end()) {
setAttachPath(itr.value().toString());
}
if (state == State::error) { if (state == State::error) {
itr = data.find("errorText"); itr = data.find("errorText");
if (itr != data.end()) { if (itr != data.end()) {
@ -432,3 +446,13 @@ QString Shared::Message::getStanzaId() const
{ {
return stanzaId; return stanzaId;
} }
QString Shared::Message::getAttachPath() const
{
return attachPath;
}
void Shared::Message::setAttachPath(const QString& path)
{
attachPath = path;
}

View File

@ -16,15 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SHAPER_MESSAGE_H
#define SHAPER_MESSAGE_H
#include <QString> #include <QString>
#include <QDateTime> #include <QDateTime>
#include <QVariant> #include <QVariant>
#include <QMap> #include <QMap>
#include <QDataStream> #include <QDataStream>
#ifndef SHAPER_MESSAGE_H
#define SHAPER_MESSAGE_H
namespace Shared { namespace Shared {
/** /**
@ -72,6 +72,7 @@ public:
void setErrorText(const QString& err); void setErrorText(const QString& err);
bool change(const QMap<QString, QVariant>& data); bool change(const QMap<QString, QVariant>& data);
void setStanzaId(const QString& sid); void setStanzaId(const QString& sid);
void setAttachPath(const QString& path);
QString getFrom() const; QString getFrom() const;
QString getFromJid() const; QString getFromJid() const;
@ -100,6 +101,7 @@ public:
QDateTime getLastModified() const; QDateTime getLastModified() const;
QString getOriginalBody() const; QString getOriginalBody() const;
QString getStanzaId() const; QString getStanzaId() const;
QString getAttachPath() const;
void serialize(QDataStream& data) const; void serialize(QDataStream& data) const;
void deserialize(QDataStream& data); void deserialize(QDataStream& data);
@ -123,6 +125,7 @@ private:
QString originalMessage; QString originalMessage;
QDateTime lastModified; QDateTime lastModified;
QString stanzaId; QString stanzaId;
QString attachPath;
}; };
} }

View File

@ -40,7 +40,9 @@ Models::MessageFeed::MessageFeed(const Element* ri, QObject* parent):
indexById(storage.get<id>()), indexById(storage.get<id>()),
indexByTime(storage.get<time>()), indexByTime(storage.get<time>()),
rosterItem(ri), rosterItem(ri),
syncState(incomplete) syncState(incomplete),
uploads(),
downloads()
{ {
} }
@ -138,11 +140,8 @@ QVariant Models::MessageFeed::data(const QModelIndex& index, int role) const
} }
} }
break; break;
case Attach: { case Attach:
::Models::Attach att; answer.setValue(fillAttach(*msg));
answer.setValue(att);
}
break; break;
case Bulk: { case Bulk: {
FeedItem item; FeedItem item;
@ -171,6 +170,7 @@ QVariant Models::MessageFeed::data(const QModelIndex& index, int role) const
if (item.avatar.size() == 0) { if (item.avatar.size() == 0) {
item.avatar = Shared::iconPath("user", true); item.avatar = Shared::iconPath("user", true);
} }
item.attach = fillAttach(*msg);
answer.setValue(item); answer.setValue(item);
} }
break; break;
@ -246,3 +246,39 @@ bool Models::MessageFeed::sentByMe(const Shared::Message& msg) const
return msg.getOutgoing(); return msg.getOutgoing();
} }
} }
Models::Attachment Models::MessageFeed::fillAttach(const Shared::Message& msg) const
{
::Models::Attachment att;
att.localPath = msg.getAttachPath();
att.remotePath = msg.getOutOfBandUrl();
if (att.remotePath.size() == 0) {
if (att.localPath.size() == 0) {
att.state = none;
} else {
Progress::const_iterator itr = uploads.find(msg.getId());
if (itr == uploads.end()) {
att.state = local;
} else {
att.state = uploading;
att.progress = itr->second;
}
}
} else {
if (att.localPath.size() == 0) {
Progress::const_iterator itr = downloads.find(msg.getId());
if (itr == downloads.end()) {
att.state = remote;
} else {
att.state = downloading;
att.progress = itr->second;
}
} else {
att.state = ready;
}
}
return att;
}

View File

@ -34,6 +34,7 @@
namespace Models { namespace Models {
class Element; class Element;
struct Attachment;
class MessageFeed : public QAbstractListModel class MessageFeed : public QAbstractListModel
{ {
@ -63,6 +64,7 @@ signals:
protected: protected:
bool sentByMe(const Shared::Message& msg) const; bool sentByMe(const Shared::Message& msg) const;
Attachment fillAttach(const Shared::Message& msg) const;
public: public:
enum MessageRoles { enum MessageRoles {
@ -120,21 +122,27 @@ private:
const Element* rosterItem; const Element* rosterItem;
SyncState syncState; SyncState syncState;
typedef std::map<QString, qreal> Progress;
Progress uploads;
Progress downloads;
static const QHash<int, QByteArray> roles; static const QHash<int, QByteArray> roles;
}; };
enum Attachment { enum AttachmentType {
none, none,
remote, remote,
local,
downloading, downloading,
uploading, uploading,
ready ready
}; };
struct Attach { struct Attachment {
Attachment state; AttachmentType state;
qreal progress; qreal progress;
QString localPath; QString localPath;
QString remotePath;
}; };
struct FeedItem { struct FeedItem {
@ -145,11 +153,11 @@ struct FeedItem {
bool correction; bool correction;
QDateTime date; QDateTime date;
Shared::Message::State state; Shared::Message::State state;
Attach attach; Attachment attach;
}; };
}; };
Q_DECLARE_METATYPE(Models::Attach); Q_DECLARE_METATYPE(Models::Attachment);
Q_DECLARE_METATYPE(Models::FeedItem); Q_DECLARE_METATYPE(Models::FeedItem);
#endif // MESSAGEFEED_H #endif // MESSAGEFEED_H

View File

@ -191,7 +191,7 @@ bool FeedView::tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewIt
void FeedView::paintEvent(QPaintEvent* event) void FeedView::paintEvent(QPaintEvent* event)
{ {
qDebug() << "paint" << event->rect(); //qDebug() << "paint" << event->rect();
const QAbstractItemModel* m = model(); const QAbstractItemModel* m = model();
QWidget* vp = viewport(); QWidget* vp = viewport();
QRect zone = event->rect().translated(0, -vo); QRect zone = event->rect().translated(0, -vo);

View File

@ -33,12 +33,24 @@ nickFont(),
dateFont(), dateFont(),
bodyMetrics(bodyFont), bodyMetrics(bodyFont),
nickMetrics(nickFont), nickMetrics(nickFont),
dateMetrics(dateFont) dateMetrics(dateFont),
downloadButton(new QPushButton()),
uploadButton(new QPushButton())
{ {
downloadButton->setText(tr("Download"));
uploadButton->setText(tr("Retry"));
//this is done for the buttons to calculate their acual size for we are going to use them further
downloadButton->setAttribute(Qt::WA_DontShowOnScreen);
uploadButton->setAttribute(Qt::WA_DontShowOnScreen);
downloadButton->show();
uploadButton->show();
} }
MessageDelegate::~MessageDelegate() MessageDelegate::~MessageDelegate()
{ {
delete uploadButton;
delete downloadButton;
} }
void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
@ -89,7 +101,38 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
painter->setFont(nickFont); painter->setFont(nickFont);
painter->drawText(opt.rect, opt.displayAlignment, data.sender, &rect); painter->drawText(opt.rect, opt.displayAlignment, data.sender, &rect);
opt.rect.adjust(0, rect.height(), 0, 0); opt.rect.adjust(0, rect.height(), 0, 0);
painter->save();
switch (data.attach.state) {
case Models::none:
break;
case Models::uploading:
case Models::downloading:
break;
case Models::remote:
if (data.sentByMe) {
painter->translate(option.rect.width() - avatarHeight - margin * 2 - downloadButton->width(), opt.rect.top());
} else {
painter->translate(opt.rect.topLeft());
}
downloadButton->render(painter, QPoint(), QRegion(), QWidget::DrawChildren);
opt.rect.adjust(0, downloadButton->height(), 0, 0);
break;
case Models::local:
if (data.sentByMe) {
painter->translate(option.rect.width() - avatarHeight - margin * 2 - uploadButton->width(), opt.rect.top());
} else {
painter->translate(opt.rect.topLeft());
}
uploadButton->render(painter, QPoint(), QRegion(), QWidget::DrawChildren);
opt.rect.adjust(0, uploadButton->height(), 0, 0);
break;
case Models::ready:
break;
}
painter->restore();
painter->setFont(bodyFont); painter->setFont(bodyFont);
painter->drawText(opt.rect, opt.displayAlignment | Qt::TextWordWrap, data.text, &rect); painter->drawText(opt.rect, opt.displayAlignment | Qt::TextWordWrap, data.text, &rect);
@ -108,8 +151,24 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
QRect messageRect = option.rect.adjusted(0, margin / 2, -(avatarHeight + 3 * margin), -margin / 2); QRect messageRect = option.rect.adjusted(0, margin / 2, -(avatarHeight + 3 * margin), -margin / 2);
QStyleOptionViewItem opt = option; QStyleOptionViewItem opt = option;
opt.rect = messageRect; opt.rect = messageRect;
QVariant va = index.data(Models::MessageFeed::Attach);
Models::Attachment attach = qvariant_cast<Models::Attachment>(va);
QSize messageSize = bodyMetrics.boundingRect(messageRect, Qt::TextWordWrap, index.data(Models::MessageFeed::Text).toString()).size(); QSize messageSize = bodyMetrics.boundingRect(messageRect, Qt::TextWordWrap, index.data(Models::MessageFeed::Text).toString()).size();
switch (attach.state) {
case Models::none:
break;
case Models::uploading:
case Models::downloading:
break;
case Models::remote:
case Models::local:
messageSize.rheight() += downloadButton->height();
break;
case Models::ready:
break;
}
messageSize.rheight() += nickMetrics.lineSpacing(); messageSize.rheight() += nickMetrics.lineSpacing();
messageSize.rheight() += dateMetrics.height(); messageSize.rheight() += dateMetrics.height();

View File

@ -22,6 +22,7 @@
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QFont> #include <QFont>
#include <QFontMetrics> #include <QFontMetrics>
#include <QPushButton>
#include "shared/icons.h" #include "shared/icons.h"
@ -46,6 +47,9 @@ private:
QFontMetrics bodyMetrics; QFontMetrics bodyMetrics;
QFontMetrics nickMetrics; QFontMetrics nickMetrics;
QFontMetrics dateMetrics; QFontMetrics dateMetrics;
QPushButton* downloadButton;
QPushButton* uploadButton;
}; };
#endif // MESSAGEDELEGATE_H #endif // MESSAGEDELEGATE_H