Fix segfault when leaving certain rooms.
This commit is contained in:
parent
6e44347efd
commit
06983a506c
|
@ -24,7 +24,7 @@ class AccountListModel : public QAbstractListModel {
|
||||||
void setController(Controller* value);
|
void setController(Controller* value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Controller* m_controller;
|
Controller* m_controller = nullptr;
|
||||||
QVector<Connection*> m_connections;
|
QVector<Connection*> m_connections;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -40,13 +40,6 @@ Controller::Controller(QObject* parent)
|
||||||
QTimer::singleShot(0, this, SLOT(invokeLogin()));
|
QTimer::singleShot(0, this, SLOT(invokeLogin()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller::~Controller() {
|
|
||||||
for (auto c : qAsConst(m_connections)) {
|
|
||||||
c->saveState();
|
|
||||||
c->stopSync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QString accessTokenFileName(const AccountSettings& account) {
|
inline QString accessTokenFileName(const AccountSettings& account) {
|
||||||
QString fileName = account.userId();
|
QString fileName = account.userId();
|
||||||
fileName.replace(':', '_');
|
fileName.replace(':', '_');
|
||||||
|
@ -109,7 +102,10 @@ void Controller::addConnection(Connection* c) {
|
||||||
|
|
||||||
m_connections.push_back(c);
|
m_connections.push_back(c);
|
||||||
|
|
||||||
connect(c, &Connection::syncDone, this, [=] { c->sync(30000); });
|
connect(c, &Connection::syncDone, this, [=] {
|
||||||
|
c->saveState();
|
||||||
|
c->sync(30000);
|
||||||
|
});
|
||||||
connect(c, &Connection::loggedOut, this, [=] { dropConnection(c); });
|
connect(c, &Connection::loggedOut, this, [=] { dropConnection(c); });
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace QMatrixClient;
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Controller : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Controller(QObject* parent = nullptr);
|
explicit Controller(QObject* parent = nullptr);
|
||||||
~Controller();
|
~Controller(){};
|
||||||
|
|
||||||
// All the Q_INVOKABLEs.
|
// All the Q_INVOKABLEs.
|
||||||
Q_INVOKABLE void loginWithCredentials(QString, QString, QString);
|
Q_INVOKABLE void loginWithCredentials(QString, QString, QString);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
ImageItem::ImageItem(QQuickItem *parent) : QQuickPaintedItem(parent) {}
|
ImageItem::ImageItem(QQuickItem *parent) : QQuickPaintedItem(parent) {}
|
||||||
|
|
||||||
inline QString stringtoColor(QString string) {
|
inline static QString stringtoColor(QString string) {
|
||||||
int hash = 0;
|
int hash = 0;
|
||||||
for (int i = 0; i < string.length(); i++)
|
for (int i = 0; i < string.length(); i++)
|
||||||
hash = string.at(i).unicode() + ((hash << 5) - hash);
|
hash = string.at(i).unicode() + ((hash << 5) - hash);
|
||||||
|
@ -16,42 +16,21 @@ inline QString stringtoColor(QString string) {
|
||||||
return colour;
|
return colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static QImage getImageFromPaintable(QPointer<Paintable> p, QRectF b) {
|
||||||
|
if (p.isNull()) return {};
|
||||||
|
QImage image(p->image(int(b.width()), int(b.height())));
|
||||||
|
if (image.isNull()) return {};
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
void ImageItem::paint(QPainter *painter) {
|
void ImageItem::paint(QPainter *painter) {
|
||||||
QRectF bounding_rect = boundingRect();
|
QRectF bounding_rect = boundingRect();
|
||||||
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
|
||||||
if (!m_paintable) {
|
QImage image(getImageFromPaintable(m_paintable, bounding_rect));
|
||||||
paintHint(painter, bounding_rect);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage image = m_paintable->image(int(bounding_rect.width()),
|
|
||||||
int(bounding_rect.height()));
|
|
||||||
|
|
||||||
if (image.isNull()) {
|
if (image.isNull()) {
|
||||||
paintHint(painter, bounding_rect);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage scaled = image.scaled(
|
|
||||||
int(bounding_rect.width()) + 1, int(bounding_rect.height()) + 1,
|
|
||||||
Qt::KeepAspectRatioByExpanding, Qt::FastTransformation);
|
|
||||||
|
|
||||||
QPointF center = bounding_rect.center() - scaled.rect().center();
|
|
||||||
|
|
||||||
if (m_round) {
|
|
||||||
QPainterPath clip;
|
|
||||||
clip.addEllipse(
|
|
||||||
0, 0, bounding_rect.width(),
|
|
||||||
bounding_rect.height()); // this is the shape we want to clip to
|
|
||||||
painter->setClipPath(clip);
|
|
||||||
}
|
|
||||||
|
|
||||||
painter->drawImage(center, scaled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageItem::paintHint(QPainter *painter, QRectF bounding_rect) {
|
|
||||||
painter->setPen(Qt::NoPen);
|
painter->setPen(Qt::NoPen);
|
||||||
if (m_color.isEmpty())
|
if (m_color.isEmpty())
|
||||||
painter->setBrush(QColor(stringtoColor(m_hint)));
|
painter->setBrush(QColor(stringtoColor(m_hint)));
|
||||||
|
@ -73,11 +52,28 @@ void ImageItem::paintHint(QPainter *painter, QRectF bounding_rect) {
|
||||||
painter->drawText(
|
painter->drawText(
|
||||||
QRect(0, 0, int(bounding_rect.width()), int(bounding_rect.height())),
|
QRect(0, 0, int(bounding_rect.width()), int(bounding_rect.height())),
|
||||||
Qt::AlignCenter, m_hint.at(0).toUpper());
|
Qt::AlignCenter, m_hint.at(0).toUpper());
|
||||||
|
} else {
|
||||||
|
QImage scaled = image.scaled(
|
||||||
|
int(bounding_rect.width()) + 1, int(bounding_rect.height()) + 1,
|
||||||
|
Qt::KeepAspectRatioByExpanding, Qt::FastTransformation);
|
||||||
|
|
||||||
|
QPointF center = bounding_rect.center() - scaled.rect().center();
|
||||||
|
|
||||||
|
if (m_round) {
|
||||||
|
QPainterPath clip;
|
||||||
|
clip.addEllipse(
|
||||||
|
0, 0, bounding_rect.width(),
|
||||||
|
bounding_rect.height()); // this is the shape we want to clip to
|
||||||
|
painter->setClipPath(clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->drawImage(center, scaled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageItem::setPaintable(Paintable *paintable) {
|
void ImageItem::setPaintable(Paintable *paintable) {
|
||||||
if (!paintable) return;
|
if (!paintable) return;
|
||||||
disconnect(m_paintable);
|
if (!m_paintable.isNull()) m_paintable->disconnect(this);
|
||||||
m_paintable = paintable;
|
m_paintable = paintable;
|
||||||
connect(m_paintable, &Paintable::paintableChanged, this,
|
connect(m_paintable, &Paintable::paintableChanged, this,
|
||||||
[=] { this->update(); });
|
[=] { this->update(); });
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef IMAGEITEM_H
|
#ifndef IMAGEITEM_H
|
||||||
#define IMAGEITEM_H
|
#define IMAGEITEM_H
|
||||||
|
|
||||||
|
#include <QPointer>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
@ -42,12 +43,10 @@ class ImageItem : public QQuickPaintedItem {
|
||||||
void roundChanged();
|
void roundChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Paintable* m_paintable = nullptr;
|
QPointer<Paintable> m_paintable;
|
||||||
QString m_hint = "H";
|
QString m_hint = "H";
|
||||||
QString m_color;
|
QString m_color;
|
||||||
bool m_round = true;
|
bool m_round = true;
|
||||||
|
|
||||||
void paintHint(QPainter* painter, QRectF bounding_rect);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMAGEITEM_H
|
#endif // IMAGEITEM_H
|
||||||
|
|
|
@ -32,7 +32,7 @@ class ImageProvider : public QObject, public QQuickImageProvider {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QReadWriteLock m_lock;
|
QReadWriteLock m_lock;
|
||||||
QMatrixClient::Connection* m_connection;
|
QMatrixClient::Connection* m_connection = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMAGEPROVIDER_H
|
#endif // IMAGEPROVIDER_H
|
||||||
|
|
|
@ -23,9 +23,7 @@
|
||||||
using namespace QMatrixClient;
|
using namespace QMatrixClient;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
#endif
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,6 @@ void RoomListModel::connectRoomSignals(SpectralRoom* room) {
|
||||||
[=] { unreadMessagesChanged(room); });
|
[=] { unreadMessagesChanged(room); });
|
||||||
connect(room, &Room::tagsChanged, this, [=] { refresh(room); });
|
connect(room, &Room::tagsChanged, this, [=] { refresh(room); });
|
||||||
connect(room, &Room::joinStateChanged, this, [=] { refresh(room); });
|
connect(room, &Room::joinStateChanged, this, [=] { refresh(room); });
|
||||||
connect(room, &Room::avatarChanged, this,
|
|
||||||
[=] { refresh(room, {PaintableRole}); });
|
|
||||||
connect(room, &Room::addedMessages, this,
|
connect(room, &Room::addedMessages, this,
|
||||||
[=] { refresh(room, {LastEventRole}); });
|
[=] { refresh(room, {LastEventRole}); });
|
||||||
connect(room, &Room::aboutToAddNewMessages, this,
|
connect(room, &Room::aboutToAddNewMessages, this,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
SpectralRoom::SpectralRoom(Connection* connection, QString roomId,
|
SpectralRoom::SpectralRoom(Connection* connection, QString roomId,
|
||||||
JoinState joinState)
|
JoinState joinState)
|
||||||
: Room(connection, std::move(roomId), joinState) {
|
: Room(connection, std::move(roomId), joinState), m_paintable(this) {
|
||||||
connect(this, &SpectralRoom::notificationCountChanged, this,
|
connect(this, &SpectralRoom::notificationCountChanged, this,
|
||||||
&SpectralRoom::countChanged);
|
&SpectralRoom::countChanged);
|
||||||
connect(this, &SpectralRoom::highlightCountChanged, this,
|
connect(this, &SpectralRoom::highlightCountChanged, this,
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "spectraluser.h"
|
#include "spectraluser.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace QMatrixClient;
|
||||||
|
@ -18,16 +19,11 @@ class RoomPaintable : public Paintable {
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage image(int dimension) override {
|
QImage image(int dimension) override {
|
||||||
if (!m_room) {
|
if (!m_room) return QImage();
|
||||||
qDebug() << "Room is null";
|
|
||||||
return QImage();
|
|
||||||
}
|
|
||||||
return m_room->avatar(dimension);
|
return m_room->avatar(dimension);
|
||||||
}
|
}
|
||||||
QImage image(int width, int height) override {
|
QImage image(int width, int height) override {
|
||||||
if (!m_room) {
|
if (!m_room) return QImage();
|
||||||
return QImage();
|
|
||||||
}
|
|
||||||
return m_room->avatar(width, height);
|
return m_room->avatar(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +48,7 @@ class SpectralRoom : public Room {
|
||||||
explicit SpectralRoom(Connection* connection, QString roomId,
|
explicit SpectralRoom(Connection* connection, QString roomId,
|
||||||
JoinState joinState = {});
|
JoinState joinState = {});
|
||||||
|
|
||||||
Paintable* paintable() { return new RoomPaintable(this); }
|
Paintable* paintable() { return &m_paintable; }
|
||||||
|
|
||||||
const QString& cachedInput() const { return m_cachedInput; }
|
const QString& cachedInput() const { return m_cachedInput; }
|
||||||
void setCachedInput(const QString& input) {
|
void setCachedInput(const QString& input) {
|
||||||
|
@ -110,7 +106,7 @@ class SpectralRoom : public Room {
|
||||||
bool m_hasFileUploading = false;
|
bool m_hasFileUploading = false;
|
||||||
int m_fileUploadingProgress = 0;
|
int m_fileUploadingProgress = 0;
|
||||||
|
|
||||||
bool m_busy;
|
bool m_busy = false;
|
||||||
|
|
||||||
QString getMIME(const QUrl& fileUrl) const;
|
QString getMIME(const QUrl& fileUrl) const;
|
||||||
void postFile(const QUrl& localFile, const QUrl& mxcUrl);
|
void postFile(const QUrl& localFile, const QUrl& mxcUrl);
|
||||||
|
@ -137,6 +133,9 @@ class SpectralRoom : public Room {
|
||||||
void sendTypingNotification(bool isTyping);
|
void sendTypingNotification(bool isTyping);
|
||||||
void sendReply(QString userId, QString eventId, QString replyContent,
|
void sendReply(QString userId, QString eventId, QString replyContent,
|
||||||
QString sendContent);
|
QString sendContent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RoomPaintable m_paintable;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SpectralRoom_H
|
#endif // SpectralRoom_H
|
||||||
|
|
|
@ -6,15 +6,14 @@
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace QMatrixClient;
|
||||||
|
|
||||||
class UserPaintable : public Paintable {
|
class UserPaintable : public Paintable {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
UserPaintable(User* parent) : Paintable(parent), m_user(parent) {
|
UserPaintable(User* parent) : Paintable(parent), m_user(parent) {}
|
||||||
connect(m_user, &User::avatarChanged, [=] { emit paintableChanged(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage image(int dimension) override {
|
QImage image(int dimension) override {
|
||||||
if (!m_user) return QImage();
|
if (!m_user) return QImage();
|
||||||
|
@ -34,9 +33,12 @@ class SpectralUser : public User {
|
||||||
Q_PROPERTY(Paintable* paintable READ paintable CONSTANT)
|
Q_PROPERTY(Paintable* paintable READ paintable CONSTANT)
|
||||||
public:
|
public:
|
||||||
SpectralUser(QString userId, Connection* connection)
|
SpectralUser(QString userId, Connection* connection)
|
||||||
: User(userId, connection) {}
|
: User(userId, connection), m_paintable(this) {}
|
||||||
|
|
||||||
Paintable* paintable() { return new UserPaintable(this); }
|
Paintable* paintable() { return &m_paintable; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
UserPaintable m_paintable;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SpectralUser_H
|
#endif // SpectralUser_H
|
||||||
|
|
|
@ -18,9 +18,9 @@ void UserListModel::setRoom(QMatrixClient::Room* room) {
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace QMatrixClient;
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
if (m_currentRoom && m_currentRoom->connection()) {
|
if (m_currentRoom) {
|
||||||
m_currentRoom->connection()->disconnect(this);
|
|
||||||
m_currentRoom->disconnect(this);
|
m_currentRoom->disconnect(this);
|
||||||
|
// m_currentRoom->connection()->disconnect(this);
|
||||||
for (User* user : m_users) user->disconnect(this);
|
for (User* user : m_users) user->disconnect(this);
|
||||||
m_users.clear();
|
m_users.clear();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue