some bug fixes, initial work on avatars in dialog windows

This commit is contained in:
Blue 2019-12-20 18:41:20 +03:00
parent 867c3a18e9
commit f13b43d38b
18 changed files with 125 additions and 42 deletions

View File

@ -291,15 +291,17 @@ void Core::NetworkAccess::onDownloadFinished()
QStringList parts = fileName.split("."); QStringList parts = fileName.split(".");
path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/"; path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/";
QString suffix(""); QString suffix("");
QString realName = parts.front(); QStringList::const_iterator sItr = parts.begin();
for (QStringList::const_iterator sItr = (parts.begin()++), sEnd = parts.end(); sItr != sEnd; ++sItr) { QString realName = *sItr;
++sItr;
for (QStringList::const_iterator sEnd = parts.end(); sItr != sEnd; ++sItr) {
suffix += "." + (*sItr); suffix += "." + (*sItr);
} }
QString postfix(""); QString postfix("");
QFileInfo proposedName(path + realName + postfix + suffix); QFileInfo proposedName(path + realName + postfix + suffix);
int counter = 0; int counter = 0;
while (proposedName.exists()) { while (proposedName.exists()) {
suffix = QString("(") + std::to_string(++counter).c_str() + ")"; postfix = QString("(") + std::to_string(++counter).c_str() + ")";
proposedName = QFileInfo(path + realName + postfix + suffix); proposedName = QFileInfo(path + realName + postfix + suffix);
} }

View File

@ -622,9 +622,24 @@ QIcon Shared::icon(const QString& name, bool big)
const QString& prefix = QApplication::palette().window().color().lightnessF() > 0.5 ? const QString& prefix = QApplication::palette().window().color().lightnessF() > 0.5 ?
big ? db : ds: big ? db : ds:
big ? lb : ls; big ? lb : ls;
return QIcon::fromTheme(itr->second.first, QIcon(prefix + itr->second.second)); return QIcon::fromTheme(itr->second.first, QIcon(prefix + itr->second.second + ".svg"));
} else { } else {
qDebug() << "Icon" << name << "not found"; qDebug() << "Icon" << name << "not found";
return QIcon::fromTheme(name); return QIcon::fromTheme(name);
} }
} }
QString Shared::iconPath(const QString& name, bool big)
{
QString result = "";
std::map<QString, std::pair<QString, QString>>::const_iterator itr = icons.find(name);
if (itr != icons.end()) {
const QString& prefix = QApplication::palette().window().color().lightnessF() > 0.5 ?
big ? db : ds:
big ? lb : ls;
result = prefix + itr->second.second + ".svg";
}
return result;
}

View File

@ -438,6 +438,7 @@ QIcon availabilityIcon(Availability av, bool big = false);
QIcon subscriptionStateIcon(SubscriptionState ss, bool big = false); QIcon subscriptionStateIcon(SubscriptionState ss, bool big = false);
QIcon connectionStateIcon(ConnectionState cs, bool big = false); QIcon connectionStateIcon(ConnectionState cs, bool big = false);
QIcon icon(const QString& name, bool big = false); QIcon icon(const QString& name, bool big = false);
QString iconPath(const QString& name, bool big = false);
static const std::map<QString, std::pair<QString, QString>> icons = { static const std::map<QString, std::pair<QString, QString>> icons = {
{"user-online", {"user-online", "online"}}, {"user-online", {"user-online", "online"}},

View File

@ -961,3 +961,8 @@ QString Models::Roster::getContactIconPath(const QString& account, const QString
} }
return path; return path;
} }
Models::Account * Models::Roster::getAccount(const QString& name)
{
return accounts.find(name)->second;
}

View File

@ -74,6 +74,7 @@ public:
std::deque<QString> groupList(const QString& account) const; std::deque<QString> groupList(const QString& account) const;
bool groupHasContact(const QString& account, const QString& group, const QString& contactJID) const; bool groupHasContact(const QString& account, const QString& group, const QString& contactJID) const;
QString getContactIconPath(const QString& account, const QString& jid); QString getContactIconPath(const QString& account, const QString& jid);
Account* getAccount(const QString& name);
Accounts* accountsModel; Accounts* accountsModel;

View File

@ -276,6 +276,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
if (id != 0) { if (id != 0) {
Conversations::const_iterator itr = conversations.find(*id); Conversations::const_iterator itr = conversations.find(*id);
Models::Account* acc = rosterModel.getAccount(id->account);
Conversation* conv = 0; Conversation* conv = 0;
bool created = false; bool created = false;
Models::Contact::Messages deque; Models::Contact::Messages deque;
@ -283,11 +284,11 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
conv = itr->second; conv = itr->second;
} else if (contact != 0) { } else if (contact != 0) {
created = true; created = true;
conv = new Chat(contact); conv = new Chat(acc, contact);
contact->getMessages(deque); contact->getMessages(deque);
} else if (room != 0) { } else if (room != 0) {
created = true; created = true;
conv = new Room(room); conv = new Room(acc, room);
room->getMessages(deque); room->getMessages(deque);
if (!room->getJoined()) { if (!room->getJoined()) {

View File

@ -19,12 +19,17 @@
#include <QDebug> #include <QDebug>
#include "image.h" #include "image.h"
Image::Image(const QString& path, quint16 p_minWidth, QWidget* parent): Image::Image(const QString& p_path, quint16 p_minWidth, QWidget* parent):
QLabel(parent), QLabel(parent),
pixmap(path), pixmap(p_path),
path(p_path),
aspectRatio(0), aspectRatio(0),
minWidth(p_minWidth) minWidth(p_minWidth),
svgMode(false)
{ {
if (path.contains(".svg")) {
svgMode = true;
}
setScaledContents(true); setScaledContents(true);
recalculateAspectRatio(); recalculateAspectRatio();
} }
@ -55,7 +60,9 @@ void Image::recalculateAspectRatio()
qreal height = pixmap.height(); qreal height = pixmap.height();
qreal width = pixmap.width(); qreal width = pixmap.width();
aspectRatio = width / height; aspectRatio = width / height;
if (!svgMode) {
setPixmap(pixmap); setPixmap(pixmap);
}
setMinimumHeight(minWidth / aspectRatio); setMinimumHeight(minWidth / aspectRatio);
setMinimumWidth(minWidth); setMinimumWidth(minWidth);
} }
@ -68,8 +75,27 @@ void Image::setMinWidth(quint16 p_minWidth)
} }
} }
void Image::setPath(const QString& path) void Image::setPath(const QString& p_path)
{ {
if (path != p_path) {
path = p_path;
if (path.contains(".svg")) {
svgMode = true;
}
pixmap = QPixmap(path); pixmap = QPixmap(path);
recalculateAspectRatio(); recalculateAspectRatio();
}
} }
void Image::resizeEvent(QResizeEvent* event)
{
if (svgMode) {
QIcon ico;
QSize size = event->size();
ico.addFile(path, size);
setPixmap(ico.pixmap(size));
}
QLabel::resizeEvent(event);
}

View File

@ -21,6 +21,8 @@
#include <QLabel> #include <QLabel>
#include <QPixmap> #include <QPixmap>
#include <QResizeEvent>
#include <QIcon>
/** /**
* @todo write docs * @todo write docs
@ -29,7 +31,6 @@ class Image : public QLabel
{ {
public: public:
Image(const QString& path, quint16 minWidth = 50, QWidget* parent = nullptr); Image(const QString& path, quint16 minWidth = 50, QWidget* parent = nullptr);
~Image(); ~Image();
int heightForWidth(int width) const override; int heightForWidth(int width) const override;
@ -40,11 +41,14 @@ public:
private: private:
QPixmap pixmap; QPixmap pixmap;
QString path;
qreal aspectRatio; qreal aspectRatio;
quint16 minWidth; quint16 minWidth;
bool svgMode;
private: private:
void recalculateAspectRatio(); void recalculateAspectRatio();
void resizeEvent(QResizeEvent * event) override;
}; };
#endif // IMAGE_H #endif // IMAGE_H

View File

@ -26,7 +26,7 @@
const QRegularExpression urlReg("(?<!<a\\shref=['\"])(?<!<img\\ssrc=['\"])((?:https?|ftp)://\\S+)"); //finds all hypertext references which are not wrapped in a or img tags const QRegularExpression urlReg("(?<!<a\\shref=['\"])(?<!<img\\ssrc=['\"])((?:https?|ftp)://\\S+)"); //finds all hypertext references which are not wrapped in a or img tags
const QRegularExpression imgReg("((?:https?|ftp)://\\S+\\.(?:jpg|jpeg|png|svg|gif))"); const QRegularExpression imgReg("((?:https?|ftp)://\\S+\\.(?:jpg|jpeg|png|svg|gif))");
Message::Message(const Shared::Message& source, bool outgoing, const QString& p_sender, QWidget* parent): Message::Message(const Shared::Message& source, bool outgoing, const QString& p_sender, const QString& avatarPath, QWidget* parent):
QHBoxLayout(parent), QHBoxLayout(parent),
msg(source), msg(source),
body(new QWidget()), body(new QWidget()),
@ -39,6 +39,7 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_
file(0), file(0),
progress(0), progress(0),
fileComment(new QLabel()), fileComment(new QLabel()),
avatar(new Image(avatarPath.size() == 0 ? Shared::iconPath("user", true) : avatarPath, 60)),
hasButton(false), hasButton(false),
hasProgress(false), hasProgress(false),
hasFile(false), hasFile(false),
@ -77,13 +78,21 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_
shadow->setYOffset(1); shadow->setYOffset(1);
shadow->setColor(Qt::black); shadow->setColor(Qt::black);
body->setGraphicsEffect(shadow); body->setGraphicsEffect(shadow);
avatar->setMaximumHeight(60);
avatar->setMaximumWidth(60);
QVBoxLayout* aLay = new QVBoxLayout();
aLay->addWidget(avatar);
aLay->addStretch();
if (outgoing) { if (outgoing) {
sender->setAlignment(Qt::AlignRight); sender->setAlignment(Qt::AlignRight);
date->setAlignment(Qt::AlignRight); date->setAlignment(Qt::AlignRight);
addStretch(); addStretch();
addWidget(body); addWidget(body);
addItem(aLay);
} else { } else {
addItem(aLay);
addWidget(body); addWidget(body);
addStretch(); addStretch();
} }
@ -95,6 +104,7 @@ Message::~Message()
delete fileComment; delete fileComment;
} }
delete body; delete body;
delete avatar;
} }
QString Message::getId() const QString Message::getId() const
@ -243,3 +253,7 @@ const Shared::Message & Message::getMessage() const
return msg; return msg;
} }
void Message::setAvatarPath(const QString& p_path)
{
avatar->setPath(p_path);
}

View File

@ -41,7 +41,7 @@ class Message : public QHBoxLayout
{ {
Q_OBJECT Q_OBJECT
public: public:
Message(const Shared::Message& source, bool outgoing, const QString& sender, QWidget* parent = nullptr); Message(const Shared::Message& source, bool outgoing, const QString& sender, const QString& avatarPath = "", QWidget* parent = nullptr);
~Message(); ~Message();
void setSender(const QString& sender); void setSender(const QString& sender);
@ -54,6 +54,7 @@ public:
void hideComment(); void hideComment();
void showFile(const QString& path); void showFile(const QString& path);
void setProgress(qreal value); void setProgress(qreal value);
void setAvatarPath(const QString& p_path);
signals: signals:
void buttonClicked(); void buttonClicked();
@ -70,6 +71,7 @@ private:
QLabel* file; QLabel* file;
QProgressBar* progress; QProgressBar* progress;
QLabel* fileComment; QLabel* fileComment;
Image* avatar;
bool hasButton; bool hasButton;
bool hasProgress; bool hasProgress;
bool hasFile; bool hasFile;

View File

@ -29,6 +29,7 @@ MessageLine::MessageLine(bool p_room, QWidget* parent):
uploadPaths(), uploadPaths(),
layout(new QVBoxLayout(this)), layout(new QVBoxLayout(this)),
myName(), myName(),
myAvatarPath(),
palNames(), palNames(),
uploading(), uploading(),
downloading(), downloading(),
@ -57,15 +58,18 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg, bool forc
} }
QString sender; QString sender;
QString aPath;
bool outgoing; bool outgoing;
if (forceOutgoing) { if (forceOutgoing) {
sender = myName; sender = myName;
aPath = myAvatarPath;
outgoing = true; outgoing = true;
} else { } else {
if (room) { if (room) {
if (msg.getFromResource() == myName) { if (msg.getFromResource() == myName) {
sender = myName; sender = myName;
aPath = myAvatarPath;
outgoing = true; outgoing = true;
} else { } else {
sender = msg.getFromResource(); sender = msg.getFromResource();
@ -74,6 +78,7 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg, bool forc
} else { } else {
if (msg.getOutgoing()) { if (msg.getOutgoing()) {
sender = myName; sender = myName;
aPath = myAvatarPath;
outgoing = true; outgoing = true;
} else { } else {
QString jid = msg.getFromJid(); QString jid = msg.getFromJid();
@ -88,7 +93,7 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg, bool forc
} }
} }
Message* message = new Message(msg, outgoing, sender); Message* message = new Message(msg, outgoing, sender, aPath);
std::pair<Order::const_iterator, bool> result = messageOrder.insert(std::make_pair(msg.getTime(), message)); std::pair<Order::const_iterator, bool> result = messageOrder.insert(std::make_pair(msg.getTime(), message));
if (!result.second) { if (!result.second) {
@ -348,3 +353,13 @@ void MessageLine::onUpload()
{ {
//TODO retry //TODO retry
} }
void MessageLine::setMyAvatarPath(const QString& p_path)
{
if (myAvatarPath != p_path) {
myAvatarPath = p_path;
for (std::pair<QString, Message*> pair : myMessages) {
pair.second->setAvatarPath(myAvatarPath);
}
}
}

View File

@ -54,6 +54,7 @@ public:
void fileProgress(const QString& messageId, qreal progress); void fileProgress(const QString& messageId, qreal progress);
void appendMessageWithUpload(const Shared::Message& msg, const QString& path); void appendMessageWithUpload(const Shared::Message& msg, const QString& path);
void removeMessage(const QString& messageId); void removeMessage(const QString& messageId);
void setMyAvatarPath(const QString& p_path);
signals: signals:
void resize(int amount); void resize(int amount);
@ -87,6 +88,7 @@ private:
QVBoxLayout* layout; QVBoxLayout* layout;
QString myName; QString myName;
QString myAvatarPath;
std::map<QString, QString> palNames; std::map<QString, QString> palNames;
Index uploading; Index uploading;
Index downloading; Index downloading;

View File

@ -18,8 +18,8 @@
#include "chat.h" #include "chat.h"
Chat::Chat(Models::Contact* p_contact, QWidget* parent): Chat::Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent):
Conversation(false, p_contact->getAccountJid(), p_contact->getAccountResource(), p_contact->getJid(), "", p_contact->getAccountName(), parent), Conversation(false, acc, p_contact->getJid(), "", parent),
contact(p_contact) contact(p_contact)
{ {
setName(p_contact->getContactName()); setName(p_contact->getContactName());
@ -27,8 +27,6 @@ Chat::Chat(Models::Contact* p_contact, QWidget* parent):
setStatus(p_contact->getStatus()); setStatus(p_contact->getStatus());
connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged); connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged);
line->setMyName(p_contact->getAccountName());
} }
Chat::~Chat() Chat::~Chat()
@ -62,8 +60,7 @@ void Chat::updateState()
void Chat::handleSendMessage(const QString& text) void Chat::handleSendMessage(const QString& text)
{ {
Shared::Message msg(Shared::Message::chat); Shared::Message msg(Shared::Message::chat);
msg.setFromJid(myJid); msg.setFrom(account->getFullJid());
msg.setFromResource(myResource);
msg.setToJid(palJid); msg.setToJid(palJid);
msg.setToResource(activePalResource); msg.setToResource(activePalResource);
msg.setBody(text); msg.setBody(text);

View File

@ -30,7 +30,7 @@ class Chat : public Conversation
{ {
Q_OBJECT Q_OBJECT
public: public:
Chat(Models::Contact* p_contact, QWidget* parent = 0); Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent = 0);
~Chat(); ~Chat();
void addMessage(const Shared::Message & data) override; void addMessage(const Shared::Message & data) override;

View File

@ -26,14 +26,12 @@
#include <QMimeDatabase> #include <QMimeDatabase>
#include <unistd.h> #include <unistd.h>
Conversation::Conversation(bool muc, const QString& mJid, const QString mRes, const QString pJid, const QString pRes, const QString& acc, QWidget* parent): Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, const QString pRes, QWidget* parent):
QWidget(parent), QWidget(parent),
isMuc(muc), isMuc(muc),
myJid(mJid), account(acc),
myResource(mRes),
palJid(pJid), palJid(pJid),
activePalResource(pRes), activePalResource(pRes),
account(acc),
line(new MessageLine(muc)), line(new MessageLine(muc)),
m_ui(new Ui::Conversation()), m_ui(new Ui::Conversation()),
ker(), ker(),
@ -85,6 +83,9 @@ Conversation::Conversation(bool muc, const QString& mJid, const QString mRes, co
m_ui->scrollArea->installEventFilter(&scrollResizeCatcher); m_ui->scrollArea->installEventFilter(&scrollResizeCatcher);
m_ui->filesPanel->installEventFilter(&attachResizeCatcher); m_ui->filesPanel->installEventFilter(&attachResizeCatcher);
line->setMyAvatarPath(acc->getAvatarPath());
line->setMyName(acc->getName());
applyVisualEffects(); applyVisualEffects();
} }
@ -124,7 +125,7 @@ void Conversation::setName(const QString& name)
QString Conversation::getAccount() const QString Conversation::getAccount() const
{ {
return account; return account->getName();
} }
QString Conversation::getJid() const QString Conversation::getJid() const
@ -199,8 +200,7 @@ void Conversation::onEnterPressed()
msg.setType(Shared::Message::chat); msg.setType(Shared::Message::chat);
msg.setToResource(activePalResource); msg.setToResource(activePalResource);
} }
msg.setFromJid(myJid); msg.setFrom(account->getFullJid());
msg.setFromResource(myResource);
msg.setToJid(palJid); msg.setToJid(palJid);
msg.setOutgoing(true); msg.setOutgoing(true);
msg.generateRandomId(); msg.generateRandomId();

View File

@ -21,8 +21,9 @@
#include <QWidget> #include <QWidget>
#include <QScopedPointer> #include <QScopedPointer>
#include "../../global.h" #include "global.h"
#include "../../order.h" #include "order.h"
#include "../models/account.h"
#include "../utils/messageline.h" #include "../utils/messageline.h"
#include "../utils/resizer.h" #include "../utils/resizer.h"
#include "../utils/flowlayout.h" #include "../utils/flowlayout.h"
@ -63,7 +64,7 @@ class Conversation : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
Conversation(bool muc, const QString& mJid, const QString mRes, const QString pJid, const QString pRes, const QString& acc, QWidget* parent = 0); Conversation(bool muc, Models::Account* acc, const QString pJid, const QString pRes, QWidget* parent = 0);
~Conversation(); ~Conversation();
QString getJid() const; QString getJid() const;
@ -115,11 +116,9 @@ protected:
keep, keep,
down down
}; };
QString myJid; Models::Account* account;
QString myResource;
QString palJid; QString palJid;
QString activePalResource; QString activePalResource;
QString account;
MessageLine* line; MessageLine* line;
QScopedPointer<Ui::Conversation> m_ui; QScopedPointer<Ui::Conversation> m_ui;
KeyEnterReceiver ker; KeyEnterReceiver ker;

View File

@ -18,8 +18,8 @@
#include "room.h" #include "room.h"
Room::Room(Models::Room* p_room, QWidget* parent): Room::Room(Models::Account* acc, Models::Room* p_room, QWidget* parent):
Conversation(true, p_room->getAccountJid(), p_room->getAccountResource(), p_room->getJid(), "", p_room->getAccountName(), parent), Conversation(true, acc, p_room->getJid(), "", parent),
room(p_room) room(p_room)
{ {
setName(p_room->getName()); setName(p_room->getName());
@ -36,8 +36,7 @@ Room::~Room()
void Room::handleSendMessage(const QString& text) void Room::handleSendMessage(const QString& text)
{ {
Shared::Message msg(Shared::Message::groupChat); Shared::Message msg(Shared::Message::groupChat);
msg.setFromJid(myJid); msg.setFrom(account->getFullJid());
msg.setFromResource(myResource);
msg.setToJid(palJid); msg.setToJid(palJid);
//msg.setToResource(activePalResource); //msg.setToResource(activePalResource);
msg.setBody(text); msg.setBody(text);

View File

@ -29,7 +29,7 @@ class Room : public Conversation
{ {
Q_OBJECT Q_OBJECT
public: public:
Room(Models::Room* p_room, QWidget* parent = 0); Room(Models::Account* acc, Models::Room* p_room, QWidget* parent = 0);
~Room(); ~Room();
bool autoJoined() const; bool autoJoined() const;