mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 03:00:46 +03:00
Style change again
This commit is contained in:
parent
ed36bdb037
commit
1bfe48de75
130 changed files with 6039 additions and 5940 deletions
|
@ -27,21 +27,21 @@
|
|||
|
||||
class AvatarProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static void init(QSharedPointer<MatrixClient> client);
|
||||
static void resolve(const QString &userId, TimelineItem *item);
|
||||
static void setAvatarUrl(const QString &userId, const QUrl &url);
|
||||
static void init(QSharedPointer<MatrixClient> client);
|
||||
static void resolve(const QString &userId, TimelineItem *item);
|
||||
static void setAvatarUrl(const QString &userId, const QUrl &url);
|
||||
|
||||
static void clear();
|
||||
static void clear();
|
||||
|
||||
private:
|
||||
static void updateAvatar(const QString &uid, const QImage &img);
|
||||
static void updateAvatar(const QString &uid, const QImage &img);
|
||||
|
||||
static QSharedPointer<MatrixClient> client_;
|
||||
static QMap<QString, QList<TimelineItem *>> toBeResolved_;
|
||||
static QSharedPointer<MatrixClient> client_;
|
||||
static QMap<QString, QList<TimelineItem *>> toBeResolved_;
|
||||
|
||||
static QMap<QString, QImage> userAvatars_;
|
||||
static QMap<QString, QUrl> avatarUrls_;
|
||||
static QMap<QString, QImage> userAvatars_;
|
||||
static QMap<QString, QUrl> avatarUrls_;
|
||||
};
|
||||
|
|
|
@ -7,24 +7,24 @@
|
|||
namespace conf
|
||||
{
|
||||
// Global settings.
|
||||
static const int fontSize = 12;
|
||||
static const int emojiSize = 14;
|
||||
static const int fontSize = 12;
|
||||
static const int emojiSize = 14;
|
||||
static const int headerFontSize = 21;
|
||||
|
||||
// Window geometry.
|
||||
namespace window
|
||||
{
|
||||
static const int height = 600;
|
||||
static const int width = 1066;
|
||||
static const int width = 1066;
|
||||
|
||||
static const int minHeight = 600;
|
||||
static const int minWidth = 950;
|
||||
static const int minWidth = 950;
|
||||
}
|
||||
|
||||
// Button settings.
|
||||
namespace btn
|
||||
{
|
||||
static const int fontSize = 20;
|
||||
static const int fontSize = 20;
|
||||
static const int cornerRadius = 3;
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,8 @@ namespace roomlist
|
|||
namespace fonts
|
||||
{
|
||||
static const int heading = 13;
|
||||
static const int badge = 10;
|
||||
static const int bubble = 20;
|
||||
static const int badge = 10;
|
||||
static const int bubble = 20;
|
||||
} // namespace fonts
|
||||
} // namespace roomlist
|
||||
|
||||
|
@ -44,7 +44,7 @@ namespace userInfoWidget
|
|||
namespace fonts
|
||||
{
|
||||
static const int displayName = 16;
|
||||
static const int userid = 14;
|
||||
static const int userid = 14;
|
||||
} // namespace fonts
|
||||
} // namespace userInfoWidget
|
||||
|
||||
|
@ -52,16 +52,16 @@ namespace topRoomBar
|
|||
{
|
||||
namespace fonts
|
||||
{
|
||||
static const int roomName = 15;
|
||||
static const int roomName = 15;
|
||||
static const int roomDescription = 13;
|
||||
} // namespace fonts
|
||||
} // namespace topRoomBar
|
||||
|
||||
namespace timeline
|
||||
{
|
||||
static const int msgMargin = 11;
|
||||
static const int avatarSize = 36;
|
||||
static const int headerSpacing = 5;
|
||||
static const int msgMargin = 11;
|
||||
static const int avatarSize = 36;
|
||||
static const int headerSpacing = 5;
|
||||
static const int headerLeftMargin = 15;
|
||||
|
||||
namespace fonts
|
||||
|
|
|
@ -26,36 +26,36 @@
|
|||
class DeserializationException : public std::exception
|
||||
{
|
||||
public:
|
||||
explicit DeserializationException(const std::string &msg);
|
||||
virtual const char *what() const noexcept;
|
||||
explicit DeserializationException(const std::string &msg);
|
||||
virtual const char *what() const noexcept;
|
||||
|
||||
private:
|
||||
std::string msg_;
|
||||
std::string msg_;
|
||||
};
|
||||
|
||||
// JSON response structs need to implement the interface.
|
||||
class Deserializable
|
||||
{
|
||||
public:
|
||||
virtual void deserialize(const QJsonValue &)
|
||||
{
|
||||
}
|
||||
virtual void deserialize(const QJsonObject &)
|
||||
{
|
||||
}
|
||||
virtual void deserialize(const QJsonDocument &)
|
||||
{
|
||||
}
|
||||
virtual ~Deserializable()
|
||||
{
|
||||
}
|
||||
virtual void deserialize(const QJsonValue &)
|
||||
{
|
||||
}
|
||||
virtual void deserialize(const QJsonObject &)
|
||||
{
|
||||
}
|
||||
virtual void deserialize(const QJsonDocument &)
|
||||
{
|
||||
}
|
||||
virtual ~Deserializable()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class Serializable
|
||||
{
|
||||
public:
|
||||
virtual QJsonObject serialize() const = 0;
|
||||
virtual ~Serializable()
|
||||
{
|
||||
}
|
||||
virtual QJsonObject serialize() const = 0;
|
||||
virtual ~Serializable()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -29,32 +29,32 @@
|
|||
|
||||
class EmojiCategory : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EmojiCategory(QString category, QList<Emoji> emoji, QWidget *parent = nullptr);
|
||||
~EmojiCategory();
|
||||
EmojiCategory(QString category, QList<Emoji> emoji, QWidget *parent = nullptr);
|
||||
~EmojiCategory();
|
||||
|
||||
signals:
|
||||
void emojiSelected(const QString &emoji);
|
||||
void emojiSelected(const QString &emoji);
|
||||
|
||||
private slots:
|
||||
inline void clickIndex(const QModelIndex &);
|
||||
inline void clickIndex(const QModelIndex &);
|
||||
|
||||
private:
|
||||
QVBoxLayout *mainLayout_;
|
||||
QVBoxLayout *mainLayout_;
|
||||
|
||||
QStandardItemModel *itemModel_;
|
||||
QListView *emojiListView_;
|
||||
QStandardItemModel *itemModel_;
|
||||
QListView *emojiListView_;
|
||||
|
||||
Emoji *data_;
|
||||
EmojiItemDelegate *delegate_;
|
||||
Emoji *data_;
|
||||
EmojiItemDelegate *delegate_;
|
||||
|
||||
QLabel *category_;
|
||||
QLabel *category_;
|
||||
};
|
||||
|
||||
inline void
|
||||
EmojiCategory::clickIndex(const QModelIndex &index)
|
||||
{
|
||||
emit emojiSelected(index.data(Qt::UserRole).toString());
|
||||
emit emojiSelected(index.data(Qt::UserRole).toString());
|
||||
}
|
||||
|
|
|
@ -25,14 +25,16 @@
|
|||
|
||||
class EmojiItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EmojiItemDelegate(QObject *parent = nullptr);
|
||||
~EmojiItemDelegate();
|
||||
explicit EmojiItemDelegate(QObject *parent = nullptr);
|
||||
~EmojiItemDelegate();
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
void paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
Emoji *data_;
|
||||
Emoji *data_;
|
||||
};
|
||||
|
|
|
@ -27,38 +27,38 @@
|
|||
|
||||
class EmojiPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EmojiPanel(QWidget *parent = nullptr);
|
||||
EmojiPanel(QWidget *parent = nullptr);
|
||||
|
||||
void fadeOut();
|
||||
void fadeIn();
|
||||
void fadeOut();
|
||||
void fadeIn();
|
||||
|
||||
signals:
|
||||
void mouseLeft();
|
||||
void emojiSelected(const QString &emoji);
|
||||
void mouseLeft();
|
||||
void emojiSelected(const QString &emoji);
|
||||
|
||||
protected:
|
||||
void leaveEvent(QEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void leaveEvent(QEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
void showEmojiCategory(const EmojiCategory *category);
|
||||
void showEmojiCategory(const EmojiCategory *category);
|
||||
|
||||
QPropertyAnimation *animation_;
|
||||
QGraphicsOpacityEffect *opacity_;
|
||||
QPropertyAnimation *animation_;
|
||||
QGraphicsOpacityEffect *opacity_;
|
||||
|
||||
EmojiProvider emoji_provider_;
|
||||
EmojiProvider emoji_provider_;
|
||||
|
||||
QScrollArea *scrollArea_;
|
||||
QScrollArea *scrollArea_;
|
||||
|
||||
int shadowMargin_;
|
||||
int shadowMargin_;
|
||||
|
||||
// Panel dimensions.
|
||||
int width_;
|
||||
int height_;
|
||||
// Panel dimensions.
|
||||
int width_;
|
||||
int height_;
|
||||
|
||||
int animationDuration_;
|
||||
int categoryIconSize_;
|
||||
int animationDuration_;
|
||||
int categoryIconSize_;
|
||||
};
|
||||
|
|
|
@ -25,23 +25,23 @@
|
|||
|
||||
class EmojiPickButton : public FlatButton
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EmojiPickButton(QWidget *parent = nullptr);
|
||||
explicit EmojiPickButton(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void emojiSelected(const QString &emoji);
|
||||
void emojiSelected(const QString &emoji);
|
||||
|
||||
protected:
|
||||
void enterEvent(QEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
void enterEvent(QEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
|
||||
private:
|
||||
// Vertical distance from panel's bottom.
|
||||
int vertical_distance_ = 10;
|
||||
// Vertical distance from panel's bottom.
|
||||
int vertical_distance_ = 10;
|
||||
|
||||
// Horizontal distance from panel's bottom right corner.
|
||||
int horizontal_distance_ = 70;
|
||||
// Horizontal distance from panel's bottom right corner.
|
||||
int horizontal_distance_ = 70;
|
||||
|
||||
EmojiPanel *panel_;
|
||||
EmojiPanel *panel_;
|
||||
};
|
||||
|
|
|
@ -22,21 +22,21 @@
|
|||
#include <QMap>
|
||||
|
||||
struct Emoji {
|
||||
// Unicode code.
|
||||
QString unicode;
|
||||
// Keyboard shortcut e.g :emoji:
|
||||
QString shortname;
|
||||
// Unicode code.
|
||||
QString unicode;
|
||||
// Keyboard shortcut e.g :emoji:
|
||||
QString shortname;
|
||||
};
|
||||
|
||||
class EmojiProvider
|
||||
{
|
||||
public:
|
||||
static const QList<Emoji> people;
|
||||
static const QList<Emoji> nature;
|
||||
static const QList<Emoji> food;
|
||||
static const QList<Emoji> activity;
|
||||
static const QList<Emoji> travel;
|
||||
static const QList<Emoji> objects;
|
||||
static const QList<Emoji> symbols;
|
||||
static const QList<Emoji> flags;
|
||||
static const QList<Emoji> people;
|
||||
static const QList<Emoji> nature;
|
||||
static const QList<Emoji> food;
|
||||
static const QList<Emoji> activity;
|
||||
static const QList<Emoji> travel;
|
||||
static const QList<Emoji> objects;
|
||||
static const QList<Emoji> symbols;
|
||||
static const QList<Emoji> flags;
|
||||
};
|
||||
|
|
|
@ -26,47 +26,47 @@
|
|||
#include "MatrixClient.h"
|
||||
|
||||
namespace events = matrix::events;
|
||||
namespace msgs = matrix::events::messages;
|
||||
namespace msgs = matrix::events::messages;
|
||||
|
||||
class ImageItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
ImageItem(QSharedPointer<MatrixClient> client,
|
||||
const events::MessageEvent<msgs::Image> &event,
|
||||
QWidget *parent = nullptr);
|
||||
ImageItem(QSharedPointer<MatrixClient> client,
|
||||
const events::MessageEvent<msgs::Image> &event,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
void setImage(const QPixmap &image);
|
||||
void setImage(const QPixmap &image);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void imageDownloaded(const QString &event_id, const QPixmap &img);
|
||||
void imageDownloaded(const QString &event_id, const QPixmap &img);
|
||||
|
||||
private:
|
||||
void scaleImage();
|
||||
void openUrl();
|
||||
void scaleImage();
|
||||
void openUrl();
|
||||
|
||||
int max_width_ = 500;
|
||||
int max_height_ = 300;
|
||||
int max_width_ = 500;
|
||||
int max_height_ = 300;
|
||||
|
||||
int width_;
|
||||
int height_;
|
||||
int width_;
|
||||
int height_;
|
||||
|
||||
QPixmap scaled_image_;
|
||||
QPixmap image_;
|
||||
QPixmap scaled_image_;
|
||||
QPixmap image_;
|
||||
|
||||
QUrl url_;
|
||||
QString text_;
|
||||
QUrl url_;
|
||||
QString text_;
|
||||
|
||||
int bottom_height_ = 30;
|
||||
int bottom_height_ = 30;
|
||||
|
||||
events::MessageEvent<msgs::Image> event_;
|
||||
events::MessageEvent<msgs::Image> event_;
|
||||
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
};
|
||||
|
|
|
@ -23,24 +23,24 @@
|
|||
|
||||
class ImageOverlayDialog : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
ImageOverlayDialog(QPixmap image, QWidget *parent = nullptr);
|
||||
ImageOverlayDialog(QPixmap image, QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
signals:
|
||||
void closing();
|
||||
void closing();
|
||||
|
||||
private:
|
||||
void scaleImage(int width, int height);
|
||||
void scaleImage(int width, int height);
|
||||
|
||||
QPixmap originalImage_;
|
||||
QPixmap image_;
|
||||
QPixmap originalImage_;
|
||||
QPixmap image_;
|
||||
|
||||
QRect content_;
|
||||
QRect close_button_;
|
||||
QRect screen_;
|
||||
QRect content_;
|
||||
QRect close_button_;
|
||||
QRect screen_;
|
||||
};
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
class InputValidator
|
||||
{
|
||||
public:
|
||||
// Validators for the different types of input.
|
||||
static QRegExpValidator Id;
|
||||
static QRegExpValidator Localpart;
|
||||
static QRegExpValidator Password;
|
||||
static QRegExpValidator Domain;
|
||||
// Validators for the different types of input.
|
||||
static QRegExpValidator Id;
|
||||
static QRegExpValidator Localpart;
|
||||
static QRegExpValidator Password;
|
||||
static QRegExpValidator Domain;
|
||||
};
|
||||
|
|
|
@ -24,60 +24,60 @@
|
|||
class LoginRequest
|
||||
{
|
||||
public:
|
||||
LoginRequest();
|
||||
LoginRequest(QString username, QString password);
|
||||
LoginRequest();
|
||||
LoginRequest(QString username, QString password);
|
||||
|
||||
QByteArray serialize() noexcept;
|
||||
QByteArray serialize() noexcept;
|
||||
|
||||
inline void setPassword(QString password);
|
||||
inline void setUser(QString username);
|
||||
inline void setPassword(QString password);
|
||||
inline void setUser(QString username);
|
||||
|
||||
private:
|
||||
QString user_;
|
||||
QString password_;
|
||||
QString user_;
|
||||
QString password_;
|
||||
};
|
||||
|
||||
inline void
|
||||
LoginRequest::setPassword(QString password)
|
||||
{
|
||||
password_ = password;
|
||||
password_ = password;
|
||||
}
|
||||
|
||||
inline void
|
||||
LoginRequest::setUser(QString username)
|
||||
{
|
||||
user_ = username;
|
||||
user_ = username;
|
||||
}
|
||||
|
||||
class LoginResponse : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
|
||||
inline QString getAccessToken();
|
||||
inline QString getHomeServer();
|
||||
inline QString getUserId();
|
||||
inline QString getAccessToken();
|
||||
inline QString getHomeServer();
|
||||
inline QString getUserId();
|
||||
|
||||
private:
|
||||
QString access_token_;
|
||||
QString home_server_;
|
||||
QString user_id_;
|
||||
QString access_token_;
|
||||
QString home_server_;
|
||||
QString user_id_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
LoginResponse::getAccessToken()
|
||||
{
|
||||
return access_token_;
|
||||
return access_token_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
LoginResponse::getHomeServer()
|
||||
{
|
||||
return home_server_;
|
||||
return home_server_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
LoginResponse::getUserId()
|
||||
{
|
||||
return user_id_;
|
||||
return user_id_;
|
||||
}
|
||||
|
|
|
@ -32,68 +32,68 @@
|
|||
|
||||
class LoginPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LoginPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0);
|
||||
~LoginPage();
|
||||
LoginPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0);
|
||||
~LoginPage();
|
||||
|
||||
void reset();
|
||||
void reset();
|
||||
|
||||
signals:
|
||||
void backButtonClicked();
|
||||
void backButtonClicked();
|
||||
|
||||
private slots:
|
||||
// Callback for the back button.
|
||||
void onBackButtonClicked();
|
||||
// Callback for the back button.
|
||||
void onBackButtonClicked();
|
||||
|
||||
// Callback for the login button.
|
||||
void onLoginButtonClicked();
|
||||
// Callback for the login button.
|
||||
void onLoginButtonClicked();
|
||||
|
||||
// Callback for probing the server found in the mxid
|
||||
void onMatrixIdEntered();
|
||||
// Callback for probing the server found in the mxid
|
||||
void onMatrixIdEntered();
|
||||
|
||||
// Callback for probing the manually entered server
|
||||
void onServerAddressEntered();
|
||||
// Callback for probing the manually entered server
|
||||
void onServerAddressEntered();
|
||||
|
||||
// Displays errors produced during the login.
|
||||
void loginError(QString error_message);
|
||||
// Displays errors produced during the login.
|
||||
void loginError(QString error_message);
|
||||
|
||||
// Callback for errors produced during server probing
|
||||
void versionError(QString error_message);
|
||||
// Callback for errors produced during server probing
|
||||
void versionError(QString error_message);
|
||||
|
||||
// Callback for successful server probing
|
||||
void versionSuccess();
|
||||
// Callback for successful server probing
|
||||
void versionSuccess();
|
||||
|
||||
private:
|
||||
bool isMatrixIdValid();
|
||||
bool isMatrixIdValid();
|
||||
|
||||
QVBoxLayout *top_layout_;
|
||||
QVBoxLayout *top_layout_;
|
||||
|
||||
QHBoxLayout *top_bar_layout_;
|
||||
QHBoxLayout *logo_layout_;
|
||||
QHBoxLayout *button_layout_;
|
||||
QHBoxLayout *top_bar_layout_;
|
||||
QHBoxLayout *logo_layout_;
|
||||
QHBoxLayout *button_layout_;
|
||||
|
||||
QLabel *logo_;
|
||||
QLabel *error_label_;
|
||||
QLabel *logo_;
|
||||
QLabel *error_label_;
|
||||
|
||||
QHBoxLayout *serverLayout_;
|
||||
QHBoxLayout *matrixidLayout_;
|
||||
CircularProgress *spinner_;
|
||||
QLabel *errorIcon_;
|
||||
QString inferredServerAddress_;
|
||||
QHBoxLayout *serverLayout_;
|
||||
QHBoxLayout *matrixidLayout_;
|
||||
CircularProgress *spinner_;
|
||||
QLabel *errorIcon_;
|
||||
QString inferredServerAddress_;
|
||||
|
||||
FlatButton *back_button_;
|
||||
RaisedButton *login_button_;
|
||||
FlatButton *back_button_;
|
||||
RaisedButton *login_button_;
|
||||
|
||||
QWidget *form_widget_;
|
||||
QHBoxLayout *form_wrapper_;
|
||||
QVBoxLayout *form_layout_;
|
||||
QWidget *form_widget_;
|
||||
QHBoxLayout *form_wrapper_;
|
||||
QVBoxLayout *form_layout_;
|
||||
|
||||
TextField *matrixid_input_;
|
||||
TextField *password_input_;
|
||||
TextField *serverInput_;
|
||||
TextField *matrixid_input_;
|
||||
TextField *password_input_;
|
||||
TextField *serverInput_;
|
||||
|
||||
// Matrix client API provider.
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
// Matrix client API provider.
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
};
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
|
||||
class LogoutDialog : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LogoutDialog(QWidget *parent = nullptr);
|
||||
explicit LogoutDialog(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void closing(bool isLoggingOut);
|
||||
void closing(bool isLoggingOut);
|
||||
|
||||
private:
|
||||
FlatButton *confirmBtn_;
|
||||
FlatButton *cancelBtn_;
|
||||
FlatButton *confirmBtn_;
|
||||
FlatButton *cancelBtn_;
|
||||
};
|
||||
|
|
|
@ -32,64 +32,64 @@
|
|||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
static MainWindow *instance();
|
||||
void saveCurrentWindowSize();
|
||||
static MainWindow *instance();
|
||||
void saveCurrentWindowSize();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
private slots:
|
||||
// Handle interaction with the tray icon.
|
||||
void iconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
// Handle interaction with the tray icon.
|
||||
void iconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
// Show the welcome page in the main window.
|
||||
void showWelcomePage();
|
||||
// Show the welcome page in the main window.
|
||||
void showWelcomePage();
|
||||
|
||||
// Show the login page in the main window.
|
||||
void showLoginPage();
|
||||
// Show the login page in the main window.
|
||||
void showLoginPage();
|
||||
|
||||
// Show the register page in the main window.
|
||||
void showRegisterPage();
|
||||
// Show the register page in the main window.
|
||||
void showRegisterPage();
|
||||
|
||||
// Show the chat page and start communicating with the given access token.
|
||||
void showChatPage(QString user_id, QString home_server, QString token);
|
||||
// Show the chat page and start communicating with the given access token.
|
||||
void showChatPage(QString user_id, QString home_server, QString token);
|
||||
|
||||
void removeOverlayProgressBar();
|
||||
void removeOverlayProgressBar();
|
||||
|
||||
private:
|
||||
bool hasActiveUser();
|
||||
void restoreWindowSize();
|
||||
bool hasActiveUser();
|
||||
void restoreWindowSize();
|
||||
|
||||
static MainWindow *instance_;
|
||||
static MainWindow *instance_;
|
||||
|
||||
// The initial welcome screen.
|
||||
WelcomePage *welcome_page_;
|
||||
// The initial welcome screen.
|
||||
WelcomePage *welcome_page_;
|
||||
|
||||
// The login screen.
|
||||
LoginPage *login_page_;
|
||||
// The login screen.
|
||||
LoginPage *login_page_;
|
||||
|
||||
// The register page.
|
||||
RegisterPage *register_page_;
|
||||
// The register page.
|
||||
RegisterPage *register_page_;
|
||||
|
||||
// A stacked widget that handles the transitions between widgets.
|
||||
SlidingStackWidget *sliding_stack_;
|
||||
// A stacked widget that handles the transitions between widgets.
|
||||
SlidingStackWidget *sliding_stack_;
|
||||
|
||||
// The main chat area.
|
||||
ChatPage *chat_page_;
|
||||
// The main chat area.
|
||||
ChatPage *chat_page_;
|
||||
|
||||
// Used to hide undefined states between page transitions.
|
||||
OverlayModal *progress_modal_;
|
||||
CircularProgress *spinner_;
|
||||
// Used to hide undefined states between page transitions.
|
||||
OverlayModal *progress_modal_;
|
||||
CircularProgress *spinner_;
|
||||
|
||||
// Matrix Client API provider.
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
// Matrix Client API provider.
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
|
||||
// Tray icon that shows the unread message count.
|
||||
TrayIcon *trayIcon_;
|
||||
// Tray icon that shows the unread message count.
|
||||
TrayIcon *trayIcon_;
|
||||
};
|
||||
|
|
|
@ -25,24 +25,24 @@
|
|||
class ProfileResponse : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
|
||||
inline QUrl getAvatarUrl();
|
||||
inline QString getDisplayName();
|
||||
inline QUrl getAvatarUrl();
|
||||
inline QString getDisplayName();
|
||||
|
||||
private:
|
||||
QUrl avatar_url_;
|
||||
QString display_name_;
|
||||
QUrl avatar_url_;
|
||||
QString display_name_;
|
||||
};
|
||||
|
||||
inline QUrl
|
||||
ProfileResponse::getAvatarUrl()
|
||||
{
|
||||
return avatar_url_;
|
||||
return avatar_url_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
ProfileResponse::getDisplayName()
|
||||
{
|
||||
return display_name_;
|
||||
return display_name_;
|
||||
}
|
||||
|
|
|
@ -26,44 +26,44 @@
|
|||
|
||||
class RoomSearchInput : public TextField
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RoomSearchInput(QWidget *parent = nullptr);
|
||||
explicit RoomSearchInput(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void selectNextCompletion();
|
||||
void selectPreviousCompletion();
|
||||
void hiding();
|
||||
void selectNextCompletion();
|
||||
void selectPreviousCompletion();
|
||||
void hiding();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void hideEvent(QHideEvent *event) override;
|
||||
bool focusNextPrevChild(bool next) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void hideEvent(QHideEvent *event) override;
|
||||
bool focusNextPrevChild(bool next) override;
|
||||
};
|
||||
|
||||
class QuickSwitcher : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QuickSwitcher(QWidget *parent = nullptr);
|
||||
explicit QuickSwitcher(QWidget *parent = nullptr);
|
||||
|
||||
void setRoomList(const QMap<QString, QString> &rooms);
|
||||
void setRoomList(const QMap<QString, QString> &rooms);
|
||||
|
||||
signals:
|
||||
void closing();
|
||||
void roomSelected(const QString &roomid);
|
||||
void closing();
|
||||
void roomSelected(const QString &roomid);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
private:
|
||||
// Current highlighted selection from the completer.
|
||||
int selection_ = -1;
|
||||
// Current highlighted selection from the completer.
|
||||
int selection_ = -1;
|
||||
|
||||
QVBoxLayout *topLayout_;
|
||||
RoomSearchInput *roomSearch_;
|
||||
QCompleter *completer_;
|
||||
QVBoxLayout *topLayout_;
|
||||
RoomSearchInput *roomSearch_;
|
||||
QCompleter *completer_;
|
||||
|
||||
QMap<QString, QString> rooms_;
|
||||
QMap<QString, QString> rooms_;
|
||||
};
|
||||
|
|
|
@ -24,60 +24,60 @@
|
|||
class RegisterRequest
|
||||
{
|
||||
public:
|
||||
RegisterRequest();
|
||||
RegisterRequest(const QString &username, const QString &password);
|
||||
RegisterRequest();
|
||||
RegisterRequest(const QString &username, const QString &password);
|
||||
|
||||
QByteArray serialize() noexcept;
|
||||
QByteArray serialize() noexcept;
|
||||
|
||||
inline void setPassword(QString password);
|
||||
inline void setUser(QString username);
|
||||
inline void setPassword(QString password);
|
||||
inline void setUser(QString username);
|
||||
|
||||
private:
|
||||
QString user_;
|
||||
QString password_;
|
||||
QString user_;
|
||||
QString password_;
|
||||
};
|
||||
|
||||
inline void
|
||||
RegisterRequest::setPassword(QString password)
|
||||
{
|
||||
password_ = password;
|
||||
password_ = password;
|
||||
}
|
||||
|
||||
inline void
|
||||
RegisterRequest::setUser(QString username)
|
||||
{
|
||||
user_ = username;
|
||||
user_ = username;
|
||||
}
|
||||
|
||||
class RegisterResponse : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
|
||||
inline QString getAccessToken();
|
||||
inline QString getHomeServer();
|
||||
inline QString getUserId();
|
||||
inline QString getAccessToken();
|
||||
inline QString getHomeServer();
|
||||
inline QString getUserId();
|
||||
|
||||
private:
|
||||
QString access_token_;
|
||||
QString home_server_;
|
||||
QString user_id_;
|
||||
QString access_token_;
|
||||
QString home_server_;
|
||||
QString user_id_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
RegisterResponse::getAccessToken()
|
||||
{
|
||||
return access_token_;
|
||||
return access_token_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
RegisterResponse::getHomeServer()
|
||||
{
|
||||
return home_server_;
|
||||
return home_server_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
RegisterResponse::getUserId()
|
||||
{
|
||||
return user_id_;
|
||||
return user_id_;
|
||||
}
|
||||
|
|
|
@ -31,44 +31,44 @@
|
|||
|
||||
class RegisterPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RegisterPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0);
|
||||
~RegisterPage();
|
||||
RegisterPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0);
|
||||
~RegisterPage();
|
||||
|
||||
signals:
|
||||
void backButtonClicked();
|
||||
void backButtonClicked();
|
||||
|
||||
private slots:
|
||||
void onBackButtonClicked();
|
||||
void onRegisterButtonClicked();
|
||||
void onBackButtonClicked();
|
||||
void onRegisterButtonClicked();
|
||||
|
||||
// Display registration specific errors to the user.
|
||||
void registerError(const QString &msg);
|
||||
// Display registration specific errors to the user.
|
||||
void registerError(const QString &msg);
|
||||
|
||||
private:
|
||||
QVBoxLayout *top_layout_;
|
||||
QVBoxLayout *top_layout_;
|
||||
|
||||
QHBoxLayout *back_layout_;
|
||||
QHBoxLayout *logo_layout_;
|
||||
QHBoxLayout *button_layout_;
|
||||
QHBoxLayout *back_layout_;
|
||||
QHBoxLayout *logo_layout_;
|
||||
QHBoxLayout *button_layout_;
|
||||
|
||||
Avatar *logo_;
|
||||
QLabel *error_label_;
|
||||
Avatar *logo_;
|
||||
QLabel *error_label_;
|
||||
|
||||
FlatButton *back_button_;
|
||||
RaisedButton *register_button_;
|
||||
FlatButton *back_button_;
|
||||
RaisedButton *register_button_;
|
||||
|
||||
QWidget *form_widget_;
|
||||
QHBoxLayout *form_wrapper_;
|
||||
QVBoxLayout *form_layout_;
|
||||
QWidget *form_widget_;
|
||||
QHBoxLayout *form_wrapper_;
|
||||
QVBoxLayout *form_layout_;
|
||||
|
||||
TextField *username_input_;
|
||||
TextField *password_input_;
|
||||
TextField *password_confirmation_;
|
||||
TextField *server_input_;
|
||||
TextField *username_input_;
|
||||
TextField *password_input_;
|
||||
TextField *password_confirmation_;
|
||||
TextField *server_input_;
|
||||
|
||||
// Matrix client API provider.
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
// Matrix client API provider.
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
};
|
||||
|
|
|
@ -27,99 +27,102 @@
|
|||
#include "RoomState.h"
|
||||
|
||||
struct DescInfo {
|
||||
QString username;
|
||||
QString userid;
|
||||
QString body;
|
||||
QString timestamp;
|
||||
QString username;
|
||||
QString userid;
|
||||
QString body;
|
||||
QString timestamp;
|
||||
};
|
||||
|
||||
class RoomInfoListItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RoomInfoListItem(QSharedPointer<RoomSettings> settings, RoomState state, QString room_id, QWidget *parent = 0);
|
||||
RoomInfoListItem(QSharedPointer<RoomSettings> settings,
|
||||
RoomState state,
|
||||
QString room_id,
|
||||
QWidget *parent = 0);
|
||||
|
||||
~RoomInfoListItem();
|
||||
~RoomInfoListItem();
|
||||
|
||||
void updateUnreadMessageCount(int count);
|
||||
void clearUnreadMessageCount();
|
||||
void setState(const RoomState &state);
|
||||
void updateUnreadMessageCount(int count);
|
||||
void clearUnreadMessageCount();
|
||||
void setState(const RoomState &state);
|
||||
|
||||
inline bool isPressed() const;
|
||||
inline RoomState state() const;
|
||||
inline void setAvatar(const QImage &avatar_image);
|
||||
inline int unreadMessageCount() const;
|
||||
inline void setDescriptionMessage(const DescInfo &info);
|
||||
inline bool isPressed() const;
|
||||
inline RoomState state() const;
|
||||
inline void setAvatar(const QImage &avatar_image);
|
||||
inline int unreadMessageCount() const;
|
||||
inline void setDescriptionMessage(const DescInfo &info);
|
||||
|
||||
signals:
|
||||
void clicked(const QString &room_id);
|
||||
void clicked(const QString &room_id);
|
||||
|
||||
public slots:
|
||||
void setPressedState(bool state);
|
||||
void setPressedState(bool state);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
|
||||
private:
|
||||
QString notificationText();
|
||||
QString notificationText();
|
||||
|
||||
const int Padding = 7;
|
||||
const int IconSize = 48;
|
||||
const int Padding = 7;
|
||||
const int IconSize = 48;
|
||||
|
||||
RippleOverlay *ripple_overlay_;
|
||||
RippleOverlay *ripple_overlay_;
|
||||
|
||||
RoomState state_;
|
||||
RoomState state_;
|
||||
|
||||
QString roomId_;
|
||||
QString roomName_;
|
||||
QString roomId_;
|
||||
QString roomName_;
|
||||
|
||||
DescInfo lastMsgInfo_;
|
||||
DescInfo lastMsgInfo_;
|
||||
|
||||
QPixmap roomAvatar_;
|
||||
QPixmap roomAvatar_;
|
||||
|
||||
Menu *menu_;
|
||||
QAction *toggleNotifications_;
|
||||
Menu *menu_;
|
||||
QAction *toggleNotifications_;
|
||||
|
||||
QSharedPointer<RoomSettings> roomSettings_;
|
||||
QSharedPointer<RoomSettings> roomSettings_;
|
||||
|
||||
bool isPressed_ = false;
|
||||
bool isPressed_ = false;
|
||||
|
||||
int maxHeight_;
|
||||
int unreadMsgCount_ = 0;
|
||||
int maxHeight_;
|
||||
int unreadMsgCount_ = 0;
|
||||
};
|
||||
|
||||
inline int
|
||||
RoomInfoListItem::unreadMessageCount() const
|
||||
{
|
||||
return unreadMsgCount_;
|
||||
return unreadMsgCount_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
RoomInfoListItem::isPressed() const
|
||||
{
|
||||
return isPressed_;
|
||||
return isPressed_;
|
||||
}
|
||||
|
||||
inline RoomState
|
||||
RoomInfoListItem::state() const
|
||||
{
|
||||
return state_;
|
||||
return state_;
|
||||
}
|
||||
|
||||
inline void
|
||||
RoomInfoListItem::setAvatar(const QImage &img)
|
||||
{
|
||||
roomAvatar_ =
|
||||
QPixmap::fromImage(img.scaled(IconSize, IconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
update();
|
||||
roomAvatar_ = QPixmap::fromImage(
|
||||
img.scaled(IconSize, IconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
update();
|
||||
}
|
||||
|
||||
inline void
|
||||
RoomInfoListItem::setDescriptionMessage(const DescInfo &info)
|
||||
{
|
||||
lastMsgInfo_ = info;
|
||||
lastMsgInfo_ = info;
|
||||
}
|
||||
|
|
|
@ -29,37 +29,37 @@
|
|||
|
||||
class RoomList : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RoomList(QSharedPointer<MatrixClient> client, QWidget *parent = 0);
|
||||
~RoomList();
|
||||
RoomList(QSharedPointer<MatrixClient> client, QWidget *parent = 0);
|
||||
~RoomList();
|
||||
|
||||
void setInitialRooms(const QMap<QString, QSharedPointer<RoomSettings>> &settings,
|
||||
const QMap<QString, RoomState> &states);
|
||||
void sync(const QMap<QString, RoomState> &states);
|
||||
void setInitialRooms(const QMap<QString, QSharedPointer<RoomSettings>> &settings,
|
||||
const QMap<QString, RoomState> &states);
|
||||
void sync(const QMap<QString, RoomState> &states);
|
||||
|
||||
void clear();
|
||||
void clear();
|
||||
|
||||
signals:
|
||||
void roomChanged(const QString &room_id);
|
||||
void totalUnreadMessageCountUpdated(int count);
|
||||
void roomChanged(const QString &room_id);
|
||||
void totalUnreadMessageCountUpdated(int count);
|
||||
|
||||
public slots:
|
||||
void updateRoomAvatar(const QString &roomid, const QPixmap &img);
|
||||
void highlightSelectedRoom(const QString &room_id);
|
||||
void updateUnreadMessageCount(const QString &roomid, int count);
|
||||
void updateRoomDescription(const QString &roomid, const DescInfo &info);
|
||||
void updateRoomAvatar(const QString &roomid, const QPixmap &img);
|
||||
void highlightSelectedRoom(const QString &room_id);
|
||||
void updateUnreadMessageCount(const QString &roomid, int count);
|
||||
void updateRoomDescription(const QString &roomid, const DescInfo &info);
|
||||
|
||||
private:
|
||||
void calculateUnreadMessageCount();
|
||||
void calculateUnreadMessageCount();
|
||||
|
||||
QVBoxLayout *topLayout_;
|
||||
QVBoxLayout *contentsLayout_;
|
||||
QScrollArea *scrollArea_;
|
||||
QWidget *scrollAreaContents_;
|
||||
QVBoxLayout *topLayout_;
|
||||
QVBoxLayout *contentsLayout_;
|
||||
QScrollArea *scrollArea_;
|
||||
QWidget *scrollAreaContents_;
|
||||
|
||||
QMap<QString, QSharedPointer<RoomInfoListItem>> rooms_;
|
||||
QMap<QString, QSharedPointer<RoomInfoListItem>> rooms_;
|
||||
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
QSharedPointer<MatrixClient> client_;
|
||||
};
|
||||
|
|
|
@ -25,32 +25,32 @@
|
|||
class RoomMessages : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
|
||||
inline QString start() const;
|
||||
inline QString end() const;
|
||||
inline QJsonArray chunk() const;
|
||||
inline QString start() const;
|
||||
inline QString end() const;
|
||||
inline QJsonArray chunk() const;
|
||||
|
||||
private:
|
||||
QString start_;
|
||||
QString end_;
|
||||
QJsonArray chunk_;
|
||||
QString start_;
|
||||
QString end_;
|
||||
QJsonArray chunk_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
RoomMessages::start() const
|
||||
{
|
||||
return start_;
|
||||
return start_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
RoomMessages::end() const
|
||||
{
|
||||
return end_;
|
||||
return end_;
|
||||
}
|
||||
|
||||
inline QJsonArray
|
||||
RoomMessages::chunk() const
|
||||
{
|
||||
return chunk_;
|
||||
return chunk_;
|
||||
}
|
||||
|
|
|
@ -22,34 +22,34 @@
|
|||
class RoomSettings
|
||||
{
|
||||
public:
|
||||
RoomSettings(QString room_id)
|
||||
{
|
||||
path_ = QString("notifications/%1").arg(room_id);
|
||||
isNotificationsEnabled_ = true;
|
||||
RoomSettings(QString room_id)
|
||||
{
|
||||
path_ = QString("notifications/%1").arg(room_id);
|
||||
isNotificationsEnabled_ = true;
|
||||
|
||||
QSettings settings;
|
||||
QSettings settings;
|
||||
|
||||
if (settings.contains(path_))
|
||||
isNotificationsEnabled_ = settings.value(path_).toBool();
|
||||
else
|
||||
settings.setValue(path_, isNotificationsEnabled_);
|
||||
};
|
||||
if (settings.contains(path_))
|
||||
isNotificationsEnabled_ = settings.value(path_).toBool();
|
||||
else
|
||||
settings.setValue(path_, isNotificationsEnabled_);
|
||||
};
|
||||
|
||||
bool isNotificationsEnabled()
|
||||
{
|
||||
return isNotificationsEnabled_;
|
||||
};
|
||||
bool isNotificationsEnabled()
|
||||
{
|
||||
return isNotificationsEnabled_;
|
||||
};
|
||||
|
||||
void toggleNotifications()
|
||||
{
|
||||
isNotificationsEnabled_ = !isNotificationsEnabled_;
|
||||
void toggleNotifications()
|
||||
{
|
||||
isNotificationsEnabled_ = !isNotificationsEnabled_;
|
||||
|
||||
QSettings settings;
|
||||
settings.setValue(path_, isNotificationsEnabled_);
|
||||
}
|
||||
QSettings settings;
|
||||
settings.setValue(path_, isNotificationsEnabled_);
|
||||
}
|
||||
|
||||
private:
|
||||
QString path_;
|
||||
QString path_;
|
||||
|
||||
bool isNotificationsEnabled_;
|
||||
bool isNotificationsEnabled_;
|
||||
};
|
||||
|
|
|
@ -32,56 +32,57 @@
|
|||
|
||||
class SlidingStackWidget : public QStackedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Defines the animation direction.
|
||||
enum class AnimationDirection { LEFT_TO_RIGHT, RIGHT_TO_LEFT, AUTOMATIC };
|
||||
// Defines the animation direction.
|
||||
enum class AnimationDirection { LEFT_TO_RIGHT, RIGHT_TO_LEFT, AUTOMATIC };
|
||||
|
||||
SlidingStackWidget(QWidget *parent);
|
||||
~SlidingStackWidget();
|
||||
SlidingStackWidget(QWidget *parent);
|
||||
~SlidingStackWidget();
|
||||
|
||||
public slots:
|
||||
// Move to the next widget.
|
||||
void slideInNext();
|
||||
// Move to the next widget.
|
||||
void slideInNext();
|
||||
|
||||
// Move to the previous widget.
|
||||
void slideInPrevious();
|
||||
// Move to the previous widget.
|
||||
void slideInPrevious();
|
||||
|
||||
// Move to a widget by index.
|
||||
void slideInIndex(int index, AnimationDirection direction = AnimationDirection::AUTOMATIC);
|
||||
// Move to a widget by index.
|
||||
void slideInIndex(int index, AnimationDirection direction = AnimationDirection::AUTOMATIC);
|
||||
|
||||
int getWidgetIndex(QWidget *widget);
|
||||
int getWidgetIndex(QWidget *widget);
|
||||
signals:
|
||||
// Internal signal to alert the engine for the animation's end.
|
||||
void animationFinished();
|
||||
// Internal signal to alert the engine for the animation's end.
|
||||
void animationFinished();
|
||||
|
||||
protected slots:
|
||||
// Internal slot to handle the end of the animation.
|
||||
void onAnimationFinished();
|
||||
// Internal slot to handle the end of the animation.
|
||||
void onAnimationFinished();
|
||||
|
||||
protected:
|
||||
// The method that does the main work for the widget transition.
|
||||
void slideInWidget(QWidget *widget, AnimationDirection direction = AnimationDirection::AUTOMATIC);
|
||||
// The method that does the main work for the widget transition.
|
||||
void slideInWidget(QWidget *widget,
|
||||
AnimationDirection direction = AnimationDirection::AUTOMATIC);
|
||||
|
||||
// Indicates whether or not the animation is active.
|
||||
bool active_;
|
||||
// Indicates whether or not the animation is active.
|
||||
bool active_;
|
||||
|
||||
// The widget currently displayed.
|
||||
QWidget *window_;
|
||||
// The widget currently displayed.
|
||||
QWidget *window_;
|
||||
|
||||
// The speed of the animation in milliseconds.
|
||||
int speed_;
|
||||
// The speed of the animation in milliseconds.
|
||||
int speed_;
|
||||
|
||||
// The animation type.
|
||||
QEasingCurve::Type animation_type_;
|
||||
// The animation type.
|
||||
QEasingCurve::Type animation_type_;
|
||||
|
||||
// Current widget's index.
|
||||
int now_;
|
||||
// Current widget's index.
|
||||
int now_;
|
||||
|
||||
// Reference point.
|
||||
QPoint current_position_;
|
||||
// Reference point.
|
||||
QPoint current_position_;
|
||||
|
||||
// Next widget's to show index.
|
||||
int next_;
|
||||
// Next widget's to show index.
|
||||
int next_;
|
||||
};
|
||||
|
|
|
@ -21,15 +21,15 @@
|
|||
|
||||
class Splitter : public QSplitter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Splitter(QWidget *parent = nullptr);
|
||||
explicit Splitter(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void onSplitterMoved(int pos, int index);
|
||||
void onSplitterMoved(int pos, int index);
|
||||
|
||||
int moveEventLimit_ = 50;
|
||||
int moveEventLimit_ = 50;
|
||||
|
||||
int leftMoveCount_ = 0;
|
||||
int rightMoveCount_ = 0;
|
||||
int leftMoveCount_ = 0;
|
||||
int rightMoveCount_ = 0;
|
||||
};
|
||||
|
|
114
include/Sync.h
114
include/Sync.h
|
@ -27,187 +27,187 @@
|
|||
class Event : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline QJsonObject content() const;
|
||||
inline QJsonObject unsigned_content() const;
|
||||
inline QJsonObject content() const;
|
||||
inline QJsonObject unsigned_content() const;
|
||||
|
||||
inline QString sender() const;
|
||||
inline QString state_key() const;
|
||||
inline QString type() const;
|
||||
inline QString eventId() const;
|
||||
inline QString sender() const;
|
||||
inline QString state_key() const;
|
||||
inline QString type() const;
|
||||
inline QString eventId() const;
|
||||
|
||||
inline uint64_t timestamp() const;
|
||||
inline uint64_t timestamp() const;
|
||||
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
|
||||
private:
|
||||
QJsonObject content_;
|
||||
QJsonObject unsigned_;
|
||||
QJsonObject content_;
|
||||
QJsonObject unsigned_;
|
||||
|
||||
QString sender_;
|
||||
QString state_key_;
|
||||
QString type_;
|
||||
QString event_id_;
|
||||
QString sender_;
|
||||
QString state_key_;
|
||||
QString type_;
|
||||
QString event_id_;
|
||||
|
||||
uint64_t origin_server_ts_;
|
||||
uint64_t origin_server_ts_;
|
||||
};
|
||||
|
||||
inline QJsonObject
|
||||
Event::content() const
|
||||
{
|
||||
return content_;
|
||||
return content_;
|
||||
}
|
||||
|
||||
inline QJsonObject
|
||||
Event::unsigned_content() const
|
||||
{
|
||||
return unsigned_;
|
||||
return unsigned_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
Event::sender() const
|
||||
{
|
||||
return sender_;
|
||||
return sender_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
Event::state_key() const
|
||||
{
|
||||
return state_key_;
|
||||
return state_key_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
Event::type() const
|
||||
{
|
||||
return type_;
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
Event::eventId() const
|
||||
{
|
||||
return event_id_;
|
||||
return event_id_;
|
||||
}
|
||||
|
||||
inline uint64_t
|
||||
Event::timestamp() const
|
||||
{
|
||||
return origin_server_ts_;
|
||||
return origin_server_ts_;
|
||||
}
|
||||
|
||||
class State : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
inline QJsonArray events() const;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
inline QJsonArray events() const;
|
||||
|
||||
private:
|
||||
QJsonArray events_;
|
||||
QJsonArray events_;
|
||||
};
|
||||
|
||||
inline QJsonArray
|
||||
State::events() const
|
||||
{
|
||||
return events_;
|
||||
return events_;
|
||||
}
|
||||
|
||||
class Timeline : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline QJsonArray events() const;
|
||||
inline QString previousBatch() const;
|
||||
inline bool limited() const;
|
||||
inline QJsonArray events() const;
|
||||
inline QString previousBatch() const;
|
||||
inline bool limited() const;
|
||||
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
|
||||
private:
|
||||
QJsonArray events_;
|
||||
QString prev_batch_;
|
||||
bool limited_;
|
||||
QJsonArray events_;
|
||||
QString prev_batch_;
|
||||
bool limited_;
|
||||
};
|
||||
|
||||
inline QJsonArray
|
||||
Timeline::events() const
|
||||
{
|
||||
return events_;
|
||||
return events_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
Timeline::previousBatch() const
|
||||
{
|
||||
return prev_batch_;
|
||||
return prev_batch_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Timeline::limited() const
|
||||
{
|
||||
return limited_;
|
||||
return limited_;
|
||||
}
|
||||
|
||||
// TODO: Add support for ehpmeral, account_data, undread_notifications
|
||||
class JoinedRoom : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline State state() const;
|
||||
inline Timeline timeline() const;
|
||||
inline State state() const;
|
||||
inline Timeline timeline() const;
|
||||
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
|
||||
private:
|
||||
State state_;
|
||||
Timeline timeline_;
|
||||
/* Ephemeral ephemeral_; */
|
||||
/* AccountData account_data_; */
|
||||
/* UnreadNotifications unread_notifications_; */
|
||||
State state_;
|
||||
Timeline timeline_;
|
||||
/* Ephemeral ephemeral_; */
|
||||
/* AccountData account_data_; */
|
||||
/* UnreadNotifications unread_notifications_; */
|
||||
};
|
||||
|
||||
inline State
|
||||
JoinedRoom::state() const
|
||||
{
|
||||
return state_;
|
||||
return state_;
|
||||
}
|
||||
|
||||
inline Timeline
|
||||
JoinedRoom::timeline() const
|
||||
{
|
||||
return timeline_;
|
||||
return timeline_;
|
||||
}
|
||||
|
||||
// TODO: Add support for invited and left rooms.
|
||||
class Rooms : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline QMap<QString, JoinedRoom> join() const;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
inline QMap<QString, JoinedRoom> join() const;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
|
||||
private:
|
||||
QMap<QString, JoinedRoom> join_;
|
||||
QMap<QString, JoinedRoom> join_;
|
||||
};
|
||||
|
||||
inline QMap<QString, JoinedRoom>
|
||||
Rooms::join() const
|
||||
{
|
||||
return join_;
|
||||
return join_;
|
||||
}
|
||||
|
||||
class SyncResponse : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
inline QString nextBatch() const;
|
||||
inline Rooms rooms() const;
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
inline QString nextBatch() const;
|
||||
inline Rooms rooms() const;
|
||||
|
||||
private:
|
||||
QString next_batch_;
|
||||
Rooms rooms_;
|
||||
QString next_batch_;
|
||||
Rooms rooms_;
|
||||
};
|
||||
|
||||
inline Rooms
|
||||
SyncResponse::rooms() const
|
||||
{
|
||||
return rooms_;
|
||||
return rooms_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
SyncResponse::nextBatch() const
|
||||
{
|
||||
return next_batch_;
|
||||
return next_batch_;
|
||||
}
|
||||
|
|
|
@ -28,31 +28,31 @@
|
|||
class MsgCountComposedIcon : public QIconEngine
|
||||
{
|
||||
public:
|
||||
MsgCountComposedIcon(const QString &filename);
|
||||
MsgCountComposedIcon(const QString &filename);
|
||||
|
||||
virtual void paint(QPainter *p, const QRect &rect, QIcon::Mode mode, QIcon::State state);
|
||||
virtual QIconEngine *clone() const;
|
||||
virtual void paint(QPainter *p, const QRect &rect, QIcon::Mode mode, QIcon::State state);
|
||||
virtual QIconEngine *clone() const;
|
||||
|
||||
int msgCount = 0;
|
||||
int msgCount = 0;
|
||||
|
||||
private:
|
||||
const int BubbleDiameter = 17;
|
||||
const int BubbleDiameter = 17;
|
||||
|
||||
QIcon icon_;
|
||||
QIcon icon_;
|
||||
};
|
||||
|
||||
class TrayIcon : public QSystemTrayIcon
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrayIcon(const QString &filename, QWidget *parent);
|
||||
TrayIcon(const QString &filename, QWidget *parent);
|
||||
|
||||
public slots:
|
||||
void setUnreadCount(int count);
|
||||
void setUnreadCount(int count);
|
||||
|
||||
private:
|
||||
QAction *viewAction_;
|
||||
QAction *quitAction_;
|
||||
QAction *viewAction_;
|
||||
QAction *quitAction_;
|
||||
|
||||
MsgCountComposedIcon *icon_;
|
||||
MsgCountComposedIcon *icon_;
|
||||
};
|
||||
|
|
|
@ -29,47 +29,47 @@
|
|||
|
||||
class UserInfoWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
UserInfoWidget(QWidget *parent = 0);
|
||||
~UserInfoWidget();
|
||||
UserInfoWidget(QWidget *parent = 0);
|
||||
~UserInfoWidget();
|
||||
|
||||
void setAvatar(const QImage &img);
|
||||
void setDisplayName(const QString &name);
|
||||
void setUserId(const QString &userid);
|
||||
void setAvatar(const QImage &img);
|
||||
void setDisplayName(const QString &name);
|
||||
void setUserId(const QString &userid);
|
||||
|
||||
void reset();
|
||||
void reset();
|
||||
|
||||
signals:
|
||||
void logout();
|
||||
void logout();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void closeLogoutDialog(bool isLoggingOut);
|
||||
void closeLogoutDialog(bool isLoggingOut);
|
||||
|
||||
private:
|
||||
Avatar *userAvatar_;
|
||||
Avatar *userAvatar_;
|
||||
|
||||
QHBoxLayout *topLayout_;
|
||||
QHBoxLayout *avatarLayout_;
|
||||
QVBoxLayout *textLayout_;
|
||||
QHBoxLayout *buttonLayout_;
|
||||
QHBoxLayout *topLayout_;
|
||||
QHBoxLayout *avatarLayout_;
|
||||
QVBoxLayout *textLayout_;
|
||||
QHBoxLayout *buttonLayout_;
|
||||
|
||||
FlatButton *logoutButton_;
|
||||
FlatButton *logoutButton_;
|
||||
|
||||
QLabel *displayNameLabel_;
|
||||
QLabel *userIdLabel_;
|
||||
QLabel *displayNameLabel_;
|
||||
QLabel *userIdLabel_;
|
||||
|
||||
QString display_name_;
|
||||
QString user_id_;
|
||||
QString display_name_;
|
||||
QString user_id_;
|
||||
|
||||
QImage avatar_image_;
|
||||
QImage avatar_image_;
|
||||
|
||||
OverlayModal *logoutModal_;
|
||||
LogoutDialog *logoutDialog_;
|
||||
OverlayModal *logoutModal_;
|
||||
LogoutDialog *logoutDialog_;
|
||||
|
||||
int logoutButtonSize_;
|
||||
int logoutButtonSize_;
|
||||
};
|
||||
|
|
|
@ -25,16 +25,16 @@
|
|||
class VersionsResponse : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
void deserialize(const QJsonDocument &data) override;
|
||||
|
||||
bool isVersionSupported(unsigned int major, unsigned int minor, unsigned int patch);
|
||||
bool isVersionSupported(unsigned int major, unsigned int minor, unsigned int patch);
|
||||
|
||||
private:
|
||||
struct Version_ {
|
||||
unsigned int major_;
|
||||
unsigned int minor_;
|
||||
unsigned int patch_;
|
||||
};
|
||||
struct Version_ {
|
||||
unsigned int major_;
|
||||
unsigned int minor_;
|
||||
unsigned int patch_;
|
||||
};
|
||||
|
||||
QVector<Version_> supported_versions_;
|
||||
QVector<Version_> supported_versions_;
|
||||
};
|
||||
|
|
|
@ -27,32 +27,32 @@
|
|||
|
||||
class WelcomePage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WelcomePage(QWidget *parent = 0);
|
||||
~WelcomePage();
|
||||
explicit WelcomePage(QWidget *parent = 0);
|
||||
~WelcomePage();
|
||||
|
||||
signals:
|
||||
// Notify that the user wants to login in.
|
||||
void userLogin();
|
||||
// Notify that the user wants to login in.
|
||||
void userLogin();
|
||||
|
||||
// Notify that the user wants to register.
|
||||
void userRegister();
|
||||
// Notify that the user wants to register.
|
||||
void userRegister();
|
||||
|
||||
private slots:
|
||||
void onLoginButtonClicked();
|
||||
void onRegisterButtonClicked();
|
||||
void onLoginButtonClicked();
|
||||
void onRegisterButtonClicked();
|
||||
|
||||
private:
|
||||
QVBoxLayout *top_layout_;
|
||||
QHBoxLayout *button_layout_;
|
||||
QVBoxLayout *top_layout_;
|
||||
QHBoxLayout *button_layout_;
|
||||
|
||||
QLabel *intro_banner_;
|
||||
QLabel *intro_text_;
|
||||
QLabel *intro_banner_;
|
||||
QLabel *intro_text_;
|
||||
|
||||
QSpacerItem *button_spacer_;
|
||||
QSpacerItem *button_spacer_;
|
||||
|
||||
RaisedButton *register_button_;
|
||||
RaisedButton *login_button_;
|
||||
RaisedButton *register_button_;
|
||||
RaisedButton *login_button_;
|
||||
};
|
||||
|
|
|
@ -31,19 +31,19 @@ class AliasesEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline QList<QString> aliases() const;
|
||||
inline QList<QString> aliases() const;
|
||||
|
||||
private:
|
||||
QList<QString> aliases_;
|
||||
QList<QString> aliases_;
|
||||
};
|
||||
|
||||
inline QList<QString>
|
||||
AliasesEventContent::aliases() const
|
||||
{
|
||||
return aliases_;
|
||||
return aliases_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -35,19 +35,19 @@ class AvatarEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline QUrl url() const;
|
||||
inline QUrl url() const;
|
||||
|
||||
private:
|
||||
QUrl url_;
|
||||
QUrl url_;
|
||||
};
|
||||
|
||||
inline QUrl
|
||||
AvatarEventContent::url() const
|
||||
{
|
||||
return url_;
|
||||
return url_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -37,19 +37,19 @@ class CanonicalAliasEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline QString alias() const;
|
||||
inline QString alias() const;
|
||||
|
||||
private:
|
||||
QString alias_;
|
||||
QString alias_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
CanonicalAliasEventContent::alias() const
|
||||
{
|
||||
return alias_;
|
||||
return alias_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -34,20 +34,20 @@ class CreateEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline QString creator() const;
|
||||
inline QString creator() const;
|
||||
|
||||
private:
|
||||
// The user_id of the room creator. This is set by the homeserver.
|
||||
QString creator_;
|
||||
// The user_id of the room creator. This is set by the homeserver.
|
||||
QString creator_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
CreateEventContent::creator() const
|
||||
{
|
||||
return creator_;
|
||||
return creator_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -27,30 +27,30 @@ namespace matrix
|
|||
namespace events
|
||||
{
|
||||
enum class EventType {
|
||||
/// m.room.aliases
|
||||
RoomAliases,
|
||||
/// m.room.avatar
|
||||
RoomAvatar,
|
||||
/// m.room.canonical_alias
|
||||
RoomCanonicalAlias,
|
||||
/// m.room.create
|
||||
RoomCreate,
|
||||
/// m.room.history_visibility
|
||||
RoomHistoryVisibility,
|
||||
/// m.room.join_rules
|
||||
RoomJoinRules,
|
||||
/// m.room.member
|
||||
RoomMember,
|
||||
/// m.room.message
|
||||
RoomMessage,
|
||||
/// m.room.name
|
||||
RoomName,
|
||||
/// m.room.power_levels
|
||||
RoomPowerLevels,
|
||||
/// m.room.topic
|
||||
RoomTopic,
|
||||
// Unsupported event
|
||||
Unsupported,
|
||||
/// m.room.aliases
|
||||
RoomAliases,
|
||||
/// m.room.avatar
|
||||
RoomAvatar,
|
||||
/// m.room.canonical_alias
|
||||
RoomCanonicalAlias,
|
||||
/// m.room.create
|
||||
RoomCreate,
|
||||
/// m.room.history_visibility
|
||||
RoomHistoryVisibility,
|
||||
/// m.room.join_rules
|
||||
RoomJoinRules,
|
||||
/// m.room.member
|
||||
RoomMember,
|
||||
/// m.room.message
|
||||
RoomMessage,
|
||||
/// m.room.name
|
||||
RoomName,
|
||||
/// m.room.power_levels
|
||||
RoomPowerLevels,
|
||||
/// m.room.topic
|
||||
RoomTopic,
|
||||
// Unsupported event
|
||||
Unsupported,
|
||||
};
|
||||
|
||||
EventType
|
||||
|
@ -67,92 +67,92 @@ class Event
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
inline Content content() const;
|
||||
inline EventType eventType() const;
|
||||
inline Content content() const;
|
||||
inline EventType eventType() const;
|
||||
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
private:
|
||||
Content content_;
|
||||
EventType type_;
|
||||
Content content_;
|
||||
EventType type_;
|
||||
};
|
||||
|
||||
template<class Content>
|
||||
inline Content
|
||||
Event<Content>::content() const
|
||||
{
|
||||
return content_;
|
||||
return content_;
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
inline EventType
|
||||
Event<Content>::eventType() const
|
||||
{
|
||||
return type_;
|
||||
return type_;
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
void
|
||||
Event<Content>::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Event is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Event is not a JSON object");
|
||||
|
||||
auto object = data.toObject();
|
||||
auto object = data.toObject();
|
||||
|
||||
content_.deserialize(object.value("content"));
|
||||
type_ = extractEventType(object);
|
||||
content_.deserialize(object.value("content"));
|
||||
type_ = extractEventType(object);
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
QJsonObject
|
||||
Event<Content>::serialize() const
|
||||
{
|
||||
QJsonObject object;
|
||||
QJsonObject object;
|
||||
|
||||
switch (type_) {
|
||||
case EventType::RoomAliases:
|
||||
object["type"] = "m.room.aliases";
|
||||
break;
|
||||
case EventType::RoomAvatar:
|
||||
object["type"] = "m.room.avatar";
|
||||
break;
|
||||
case EventType::RoomCanonicalAlias:
|
||||
object["type"] = "m.room.canonical_alias";
|
||||
break;
|
||||
case EventType::RoomCreate:
|
||||
object["type"] = "m.room.create";
|
||||
break;
|
||||
case EventType::RoomHistoryVisibility:
|
||||
object["type"] = "m.room.history_visibility";
|
||||
break;
|
||||
case EventType::RoomJoinRules:
|
||||
object["type"] = "m.room.join_rules";
|
||||
break;
|
||||
case EventType::RoomMember:
|
||||
object["type"] = "m.room.member";
|
||||
break;
|
||||
case EventType::RoomMessage:
|
||||
object["type"] = "m.room.message";
|
||||
break;
|
||||
case EventType::RoomName:
|
||||
object["type"] = "m.room.name";
|
||||
break;
|
||||
case EventType::RoomPowerLevels:
|
||||
object["type"] = "m.room.power_levels";
|
||||
break;
|
||||
case EventType::RoomTopic:
|
||||
object["type"] = "m.room.topic";
|
||||
break;
|
||||
case EventType::Unsupported:
|
||||
qWarning() << "Unsupported type to serialize";
|
||||
break;
|
||||
}
|
||||
switch (type_) {
|
||||
case EventType::RoomAliases:
|
||||
object["type"] = "m.room.aliases";
|
||||
break;
|
||||
case EventType::RoomAvatar:
|
||||
object["type"] = "m.room.avatar";
|
||||
break;
|
||||
case EventType::RoomCanonicalAlias:
|
||||
object["type"] = "m.room.canonical_alias";
|
||||
break;
|
||||
case EventType::RoomCreate:
|
||||
object["type"] = "m.room.create";
|
||||
break;
|
||||
case EventType::RoomHistoryVisibility:
|
||||
object["type"] = "m.room.history_visibility";
|
||||
break;
|
||||
case EventType::RoomJoinRules:
|
||||
object["type"] = "m.room.join_rules";
|
||||
break;
|
||||
case EventType::RoomMember:
|
||||
object["type"] = "m.room.member";
|
||||
break;
|
||||
case EventType::RoomMessage:
|
||||
object["type"] = "m.room.message";
|
||||
break;
|
||||
case EventType::RoomName:
|
||||
object["type"] = "m.room.name";
|
||||
break;
|
||||
case EventType::RoomPowerLevels:
|
||||
object["type"] = "m.room.power_levels";
|
||||
break;
|
||||
case EventType::RoomTopic:
|
||||
object["type"] = "m.room.topic";
|
||||
break;
|
||||
case EventType::Unsupported:
|
||||
qWarning() << "Unsupported type to serialize";
|
||||
break;
|
||||
}
|
||||
|
||||
object["content"] = content_.serialize();
|
||||
object["content"] = content_.serialize();
|
||||
|
||||
return object;
|
||||
return object;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -26,10 +26,10 @@ namespace matrix
|
|||
namespace events
|
||||
{
|
||||
enum class HistoryVisibility {
|
||||
Invited,
|
||||
Joined,
|
||||
Shared,
|
||||
WorldReadable,
|
||||
Invited,
|
||||
Joined,
|
||||
Shared,
|
||||
WorldReadable,
|
||||
};
|
||||
|
||||
class HistoryVisibilityEventContent
|
||||
|
@ -37,19 +37,19 @@ class HistoryVisibilityEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
inline HistoryVisibility historyVisibility() const;
|
||||
inline HistoryVisibility historyVisibility() const;
|
||||
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
private:
|
||||
HistoryVisibility history_visibility_;
|
||||
HistoryVisibility history_visibility_;
|
||||
};
|
||||
|
||||
inline HistoryVisibility
|
||||
HistoryVisibilityEventContent::historyVisibility() const
|
||||
{
|
||||
return history_visibility_;
|
||||
return history_visibility_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -26,18 +26,18 @@ namespace matrix
|
|||
namespace events
|
||||
{
|
||||
enum class JoinRule {
|
||||
// A user who wishes to join the room must first receive
|
||||
// an invite to the room from someone already inside of the room.
|
||||
Invite,
|
||||
// A user who wishes to join the room must first receive
|
||||
// an invite to the room from someone already inside of the room.
|
||||
Invite,
|
||||
|
||||
// Reserved but not yet implemented by the Matrix specification.
|
||||
Knock,
|
||||
// Reserved but not yet implemented by the Matrix specification.
|
||||
Knock,
|
||||
|
||||
// Reserved but not yet implemented by the Matrix specification.
|
||||
Private,
|
||||
// Reserved but not yet implemented by the Matrix specification.
|
||||
Private,
|
||||
|
||||
/// Anyone can join the room without any prior action.
|
||||
Public,
|
||||
/// Anyone can join the room without any prior action.
|
||||
Public,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -49,19 +49,19 @@ class JoinRulesEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline JoinRule joinRule() const;
|
||||
inline JoinRule joinRule() const;
|
||||
|
||||
private:
|
||||
JoinRule join_rule_;
|
||||
JoinRule join_rule_;
|
||||
};
|
||||
|
||||
inline JoinRule
|
||||
JoinRulesEventContent::joinRule() const
|
||||
{
|
||||
return join_rule_;
|
||||
return join_rule_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -27,20 +27,20 @@ namespace matrix
|
|||
namespace events
|
||||
{
|
||||
enum class Membership {
|
||||
// The user is banned.
|
||||
Ban,
|
||||
// The user is banned.
|
||||
Ban,
|
||||
|
||||
// The user has been invited.
|
||||
Invite,
|
||||
// The user has been invited.
|
||||
Invite,
|
||||
|
||||
// The user has joined.
|
||||
Join,
|
||||
// The user has joined.
|
||||
Join,
|
||||
|
||||
// The user has requested to join.
|
||||
Knock,
|
||||
// The user has requested to join.
|
||||
Knock,
|
||||
|
||||
// The user has left.
|
||||
Leave,
|
||||
// The user has left.
|
||||
Leave,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -52,35 +52,35 @@ class MemberEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline QUrl avatarUrl() const;
|
||||
inline QString displayName() const;
|
||||
inline Membership membershipState() const;
|
||||
inline QUrl avatarUrl() const;
|
||||
inline QString displayName() const;
|
||||
inline Membership membershipState() const;
|
||||
|
||||
private:
|
||||
QUrl avatar_url_;
|
||||
QString display_name_;
|
||||
Membership membership_state_;
|
||||
QUrl avatar_url_;
|
||||
QString display_name_;
|
||||
Membership membership_state_;
|
||||
};
|
||||
|
||||
inline QUrl
|
||||
MemberEventContent::avatarUrl() const
|
||||
{
|
||||
return avatar_url_;
|
||||
return avatar_url_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
MemberEventContent::displayName() const
|
||||
{
|
||||
return display_name_;
|
||||
return display_name_;
|
||||
}
|
||||
|
||||
inline Membership
|
||||
MemberEventContent::membershipState() const
|
||||
{
|
||||
return membership_state_;
|
||||
return membership_state_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -28,38 +28,38 @@ template<class MsgContent>
|
|||
class MessageEvent : public RoomEvent<MessageEventContent>
|
||||
{
|
||||
public:
|
||||
inline MsgContent msgContent() const;
|
||||
inline MsgContent msgContent() const;
|
||||
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
|
||||
private:
|
||||
MsgContent msg_content_;
|
||||
MsgContent msg_content_;
|
||||
};
|
||||
|
||||
template<class MsgContent>
|
||||
inline MsgContent
|
||||
MessageEvent<MsgContent>::msgContent() const
|
||||
{
|
||||
return msg_content_;
|
||||
return msg_content_;
|
||||
}
|
||||
|
||||
template<class MsgContent>
|
||||
void
|
||||
MessageEvent<MsgContent>::deserialize(const QJsonValue &data)
|
||||
{
|
||||
RoomEvent<MessageEventContent>::deserialize(data);
|
||||
RoomEvent<MessageEventContent>::deserialize(data);
|
||||
|
||||
msg_content_.deserialize(data.toObject().value("content").toObject());
|
||||
msg_content_.deserialize(data.toObject().value("content").toObject());
|
||||
}
|
||||
|
||||
namespace messages
|
||||
{
|
||||
struct ThumbnailInfo {
|
||||
int h;
|
||||
int w;
|
||||
int size;
|
||||
int h;
|
||||
int w;
|
||||
int size;
|
||||
|
||||
QString mimetype;
|
||||
QString mimetype;
|
||||
};
|
||||
} // namespace messages
|
||||
} // namespace events
|
||||
|
|
|
@ -26,32 +26,32 @@ namespace matrix
|
|||
namespace events
|
||||
{
|
||||
enum class MessageEventType {
|
||||
// m.audio
|
||||
Audio,
|
||||
// m.audio
|
||||
Audio,
|
||||
|
||||
// m.emote
|
||||
Emote,
|
||||
// m.emote
|
||||
Emote,
|
||||
|
||||
// m.file
|
||||
File,
|
||||
// m.file
|
||||
File,
|
||||
|
||||
// m.image
|
||||
Image,
|
||||
// m.image
|
||||
Image,
|
||||
|
||||
// m.location
|
||||
Location,
|
||||
// m.location
|
||||
Location,
|
||||
|
||||
// m.notice
|
||||
Notice,
|
||||
// m.notice
|
||||
Notice,
|
||||
|
||||
// m.text
|
||||
Text,
|
||||
// m.text
|
||||
Text,
|
||||
|
||||
// m.video
|
||||
Video,
|
||||
// m.video
|
||||
Video,
|
||||
|
||||
// Unrecognized message type
|
||||
Unknown,
|
||||
// Unrecognized message type
|
||||
Unknown,
|
||||
};
|
||||
|
||||
MessageEventType
|
||||
|
@ -62,19 +62,19 @@ class MessageEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline QString body() const;
|
||||
inline QString body() const;
|
||||
|
||||
private:
|
||||
QString body_;
|
||||
QString body_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
MessageEventContent::body() const
|
||||
{
|
||||
return body_;
|
||||
return body_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -34,19 +34,19 @@ class NameEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline QString name() const;
|
||||
inline QString name() const;
|
||||
|
||||
private:
|
||||
QString name_;
|
||||
QString name_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
NameEventContent::name() const
|
||||
{
|
||||
return name_;
|
||||
return name_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -27,9 +27,9 @@ namespace matrix
|
|||
namespace events
|
||||
{
|
||||
enum class PowerLevels {
|
||||
User = 0,
|
||||
Moderator = 50,
|
||||
Admin = 100,
|
||||
User = 0,
|
||||
Moderator = 50,
|
||||
Admin = 100,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -41,75 +41,75 @@ class PowerLevelsEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline int banLevel() const;
|
||||
inline int inviteLevel() const;
|
||||
inline int kickLevel() const;
|
||||
inline int redactLevel() const;
|
||||
inline int banLevel() const;
|
||||
inline int inviteLevel() const;
|
||||
inline int kickLevel() const;
|
||||
inline int redactLevel() const;
|
||||
|
||||
inline int eventsDefaultLevel() const;
|
||||
inline int stateDefaultLevel() const;
|
||||
inline int usersDefaultLevel() const;
|
||||
inline int eventsDefaultLevel() const;
|
||||
inline int stateDefaultLevel() const;
|
||||
inline int usersDefaultLevel() const;
|
||||
|
||||
int eventLevel(QString event_type) const;
|
||||
int userLevel(QString user_id) const;
|
||||
int eventLevel(QString event_type) const;
|
||||
int userLevel(QString user_id) const;
|
||||
|
||||
private:
|
||||
int ban_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int invite_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int kick_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int redact_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int ban_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int invite_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int kick_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int redact_ = static_cast<int>(PowerLevels::Moderator);
|
||||
|
||||
int events_default_ = static_cast<int>(PowerLevels::User);
|
||||
int state_default_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int users_default_ = static_cast<int>(PowerLevels::User);
|
||||
int events_default_ = static_cast<int>(PowerLevels::User);
|
||||
int state_default_ = static_cast<int>(PowerLevels::Moderator);
|
||||
int users_default_ = static_cast<int>(PowerLevels::User);
|
||||
|
||||
QMap<QString, int> events_;
|
||||
QMap<QString, int> users_;
|
||||
QMap<QString, int> events_;
|
||||
QMap<QString, int> users_;
|
||||
};
|
||||
|
||||
inline int
|
||||
PowerLevelsEventContent::banLevel() const
|
||||
{
|
||||
return ban_;
|
||||
return ban_;
|
||||
}
|
||||
|
||||
inline int
|
||||
PowerLevelsEventContent::inviteLevel() const
|
||||
{
|
||||
return invite_;
|
||||
return invite_;
|
||||
}
|
||||
|
||||
inline int
|
||||
PowerLevelsEventContent::kickLevel() const
|
||||
{
|
||||
return kick_;
|
||||
return kick_;
|
||||
}
|
||||
|
||||
inline int
|
||||
PowerLevelsEventContent::redactLevel() const
|
||||
{
|
||||
return redact_;
|
||||
return redact_;
|
||||
}
|
||||
|
||||
inline int
|
||||
PowerLevelsEventContent::eventsDefaultLevel() const
|
||||
{
|
||||
return events_default_;
|
||||
return events_default_;
|
||||
}
|
||||
|
||||
inline int
|
||||
PowerLevelsEventContent::stateDefaultLevel() const
|
||||
{
|
||||
return state_default_;
|
||||
return state_default_;
|
||||
}
|
||||
|
||||
inline int
|
||||
PowerLevelsEventContent::usersDefaultLevel() const
|
||||
{
|
||||
return users_default_;
|
||||
return users_default_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -30,89 +30,89 @@ template<class Content>
|
|||
class RoomEvent : public Event<Content>
|
||||
{
|
||||
public:
|
||||
inline QString eventId() const;
|
||||
inline QString roomId() const;
|
||||
inline QString sender() const;
|
||||
inline uint64_t timestamp() const;
|
||||
inline QString eventId() const;
|
||||
inline QString roomId() const;
|
||||
inline QString sender() const;
|
||||
inline uint64_t timestamp() const;
|
||||
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
private:
|
||||
QString event_id_;
|
||||
QString room_id_;
|
||||
QString sender_;
|
||||
QString event_id_;
|
||||
QString room_id_;
|
||||
QString sender_;
|
||||
|
||||
uint64_t origin_server_ts_;
|
||||
uint64_t origin_server_ts_;
|
||||
};
|
||||
|
||||
template<class Content>
|
||||
inline QString
|
||||
RoomEvent<Content>::eventId() const
|
||||
{
|
||||
return event_id_;
|
||||
return event_id_;
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
inline QString
|
||||
RoomEvent<Content>::roomId() const
|
||||
{
|
||||
return room_id_;
|
||||
return room_id_;
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
inline QString
|
||||
RoomEvent<Content>::sender() const
|
||||
{
|
||||
return sender_;
|
||||
return sender_;
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
inline uint64_t
|
||||
RoomEvent<Content>::timestamp() const
|
||||
{
|
||||
return origin_server_ts_;
|
||||
return origin_server_ts_;
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
void
|
||||
RoomEvent<Content>::deserialize(const QJsonValue &data)
|
||||
{
|
||||
Event<Content>::deserialize(data);
|
||||
Event<Content>::deserialize(data);
|
||||
|
||||
auto object = data.toObject();
|
||||
auto object = data.toObject();
|
||||
|
||||
if (!object.contains("event_id"))
|
||||
throw DeserializationException("event_id key is missing");
|
||||
if (!object.contains("event_id"))
|
||||
throw DeserializationException("event_id key is missing");
|
||||
|
||||
if (!object.contains("origin_server_ts"))
|
||||
throw DeserializationException("origin_server_ts key is missing");
|
||||
if (!object.contains("origin_server_ts"))
|
||||
throw DeserializationException("origin_server_ts key is missing");
|
||||
|
||||
// FIXME: Synapse doesn't include room id?!
|
||||
/* if (!object.contains("room_id")) */
|
||||
/* throw DeserializationException("room_id key is missing"); */
|
||||
// FIXME: Synapse doesn't include room id?!
|
||||
/* if (!object.contains("room_id")) */
|
||||
/* throw DeserializationException("room_id key is missing"); */
|
||||
|
||||
if (!object.contains("sender"))
|
||||
throw DeserializationException("sender key is missing");
|
||||
if (!object.contains("sender"))
|
||||
throw DeserializationException("sender key is missing");
|
||||
|
||||
event_id_ = object.value("event_id").toString();
|
||||
room_id_ = object.value("room_id").toString();
|
||||
sender_ = object.value("sender").toString();
|
||||
origin_server_ts_ = object.value("origin_server_ts").toDouble();
|
||||
event_id_ = object.value("event_id").toString();
|
||||
room_id_ = object.value("room_id").toString();
|
||||
sender_ = object.value("sender").toString();
|
||||
origin_server_ts_ = object.value("origin_server_ts").toDouble();
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
QJsonObject
|
||||
RoomEvent<Content>::serialize() const
|
||||
{
|
||||
QJsonObject object = Event<Content>::serialize();
|
||||
QJsonObject object = Event<Content>::serialize();
|
||||
|
||||
object["event_id"] = event_id_;
|
||||
object["room_id"] = room_id_;
|
||||
object["sender"] = sender_;
|
||||
object["origin_server_ts"] = QJsonValue(static_cast<qint64>(origin_server_ts_));
|
||||
object["event_id"] = event_id_;
|
||||
object["room_id"] = room_id_;
|
||||
object["sender"] = sender_;
|
||||
object["origin_server_ts"] = QJsonValue(static_cast<qint64>(origin_server_ts_));
|
||||
|
||||
return object;
|
||||
return object;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -29,62 +29,62 @@ template<class Content>
|
|||
class StateEvent : public RoomEvent<Content>
|
||||
{
|
||||
public:
|
||||
inline QString stateKey() const;
|
||||
inline Content previousContent() const;
|
||||
inline QString stateKey() const;
|
||||
inline Content previousContent() const;
|
||||
|
||||
void deserialize(const QJsonValue &data);
|
||||
QJsonObject serialize() const;
|
||||
void deserialize(const QJsonValue &data);
|
||||
QJsonObject serialize() const;
|
||||
|
||||
private:
|
||||
QString state_key_;
|
||||
Content prev_content_;
|
||||
QString state_key_;
|
||||
Content prev_content_;
|
||||
};
|
||||
|
||||
template<class Content>
|
||||
inline QString
|
||||
StateEvent<Content>::stateKey() const
|
||||
{
|
||||
return state_key_;
|
||||
return state_key_;
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
inline Content
|
||||
StateEvent<Content>::previousContent() const
|
||||
{
|
||||
return prev_content_;
|
||||
return prev_content_;
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
void
|
||||
StateEvent<Content>::deserialize(const QJsonValue &data)
|
||||
{
|
||||
RoomEvent<Content>::deserialize(data);
|
||||
RoomEvent<Content>::deserialize(data);
|
||||
|
||||
auto object = data.toObject();
|
||||
auto object = data.toObject();
|
||||
|
||||
if (!object.contains("state_key"))
|
||||
throw DeserializationException("state_key key is missing");
|
||||
if (!object.contains("state_key"))
|
||||
throw DeserializationException("state_key key is missing");
|
||||
|
||||
state_key_ = object.value("state_key").toString();
|
||||
state_key_ = object.value("state_key").toString();
|
||||
|
||||
if (object.contains("prev_content"))
|
||||
prev_content_.deserialize(object.value("prev_content"));
|
||||
if (object.contains("prev_content"))
|
||||
prev_content_.deserialize(object.value("prev_content"));
|
||||
}
|
||||
|
||||
template<class Content>
|
||||
QJsonObject
|
||||
StateEvent<Content>::serialize() const
|
||||
{
|
||||
QJsonObject object = RoomEvent<Content>::serialize();
|
||||
QJsonObject object = RoomEvent<Content>::serialize();
|
||||
|
||||
object["state_key"] = state_key_;
|
||||
object["state_key"] = state_key_;
|
||||
|
||||
auto prev = prev_content_.serialize();
|
||||
auto prev = prev_content_.serialize();
|
||||
|
||||
if (!prev.isEmpty())
|
||||
object["prev_content"] = prev;
|
||||
if (!prev.isEmpty())
|
||||
object["prev_content"] = prev;
|
||||
|
||||
return object;
|
||||
return object;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -34,19 +34,19 @@ class TopicEventContent
|
|||
, public Serializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
void deserialize(const QJsonValue &data) override;
|
||||
QJsonObject serialize() const override;
|
||||
|
||||
inline QString topic() const;
|
||||
inline QString topic() const;
|
||||
|
||||
private:
|
||||
QString topic_;
|
||||
QString topic_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
TopicEventContent::topic() const
|
||||
{
|
||||
return topic_;
|
||||
return topic_;
|
||||
}
|
||||
} // namespace events
|
||||
} // namespace matrix
|
||||
|
|
|
@ -28,35 +28,35 @@ namespace events
|
|||
namespace messages
|
||||
{
|
||||
struct AudioInfo {
|
||||
uint64_t duration;
|
||||
int size;
|
||||
uint64_t duration;
|
||||
int size;
|
||||
|
||||
QString mimetype;
|
||||
QString mimetype;
|
||||
};
|
||||
|
||||
class Audio : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline QString url() const;
|
||||
inline AudioInfo info() const;
|
||||
inline QString url() const;
|
||||
inline AudioInfo info() const;
|
||||
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
|
||||
private:
|
||||
QString url_;
|
||||
AudioInfo info_;
|
||||
QString url_;
|
||||
AudioInfo info_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
Audio::url() const
|
||||
{
|
||||
return url_;
|
||||
return url_;
|
||||
}
|
||||
|
||||
inline AudioInfo
|
||||
Audio::info() const
|
||||
{
|
||||
return info_;
|
||||
return info_;
|
||||
}
|
||||
|
||||
} // namespace messages
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace messages
|
|||
class Emote : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonObject &obj) override;
|
||||
void deserialize(const QJsonObject &obj) override;
|
||||
};
|
||||
} // namespace messages
|
||||
} // namespace events
|
||||
|
|
|
@ -29,46 +29,46 @@ namespace events
|
|||
namespace messages
|
||||
{
|
||||
struct FileInfo {
|
||||
int size;
|
||||
int size;
|
||||
|
||||
QString mimetype;
|
||||
QString thumbnail_url;
|
||||
ThumbnailInfo thumbnail_info;
|
||||
QString mimetype;
|
||||
QString thumbnail_url;
|
||||
ThumbnailInfo thumbnail_info;
|
||||
};
|
||||
|
||||
class File : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline QString url() const;
|
||||
inline QString filename() const;
|
||||
inline QString url() const;
|
||||
inline QString filename() const;
|
||||
|
||||
inline FileInfo info() const;
|
||||
inline FileInfo info() const;
|
||||
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
|
||||
private:
|
||||
QString url_;
|
||||
QString filename_;
|
||||
QString url_;
|
||||
QString filename_;
|
||||
|
||||
FileInfo info_;
|
||||
FileInfo info_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
File::filename() const
|
||||
{
|
||||
return filename_;
|
||||
return filename_;
|
||||
}
|
||||
|
||||
inline QString
|
||||
File::url() const
|
||||
{
|
||||
return url_;
|
||||
return url_;
|
||||
}
|
||||
|
||||
inline FileInfo
|
||||
File::info() const
|
||||
{
|
||||
return info_;
|
||||
return info_;
|
||||
}
|
||||
|
||||
} // namespace messages
|
||||
|
|
|
@ -29,38 +29,38 @@ namespace events
|
|||
namespace messages
|
||||
{
|
||||
struct ImageInfo {
|
||||
int h;
|
||||
int w;
|
||||
int size;
|
||||
int h;
|
||||
int w;
|
||||
int size;
|
||||
|
||||
QString mimetype;
|
||||
QString thumbnail_url;
|
||||
ThumbnailInfo thumbnail_info;
|
||||
QString mimetype;
|
||||
QString thumbnail_url;
|
||||
ThumbnailInfo thumbnail_info;
|
||||
};
|
||||
|
||||
class Image : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline QString url() const;
|
||||
inline ImageInfo info() const;
|
||||
inline QString url() const;
|
||||
inline ImageInfo info() const;
|
||||
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
|
||||
private:
|
||||
QString url_;
|
||||
ImageInfo info_;
|
||||
QString url_;
|
||||
ImageInfo info_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
Image::url() const
|
||||
{
|
||||
return url_;
|
||||
return url_;
|
||||
}
|
||||
|
||||
inline ImageInfo
|
||||
Image::info() const
|
||||
{
|
||||
return info_;
|
||||
return info_;
|
||||
}
|
||||
|
||||
} // namespace messages
|
||||
|
|
|
@ -29,34 +29,34 @@ namespace events
|
|||
namespace messages
|
||||
{
|
||||
struct LocationInfo {
|
||||
QString thumbnail_url;
|
||||
ThumbnailInfo thumbnail_info;
|
||||
QString thumbnail_url;
|
||||
ThumbnailInfo thumbnail_info;
|
||||
};
|
||||
|
||||
class Location : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline QString geoUri() const;
|
||||
inline LocationInfo info() const;
|
||||
inline QString geoUri() const;
|
||||
inline LocationInfo info() const;
|
||||
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
|
||||
private:
|
||||
QString geo_uri_;
|
||||
QString geo_uri_;
|
||||
|
||||
LocationInfo info_;
|
||||
LocationInfo info_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
Location::geoUri() const
|
||||
{
|
||||
return geo_uri_;
|
||||
return geo_uri_;
|
||||
}
|
||||
|
||||
inline LocationInfo
|
||||
Location::info() const
|
||||
{
|
||||
return info_;
|
||||
return info_;
|
||||
}
|
||||
|
||||
} // namespace messages
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace messages
|
|||
class Notice : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonObject &obj) override;
|
||||
void deserialize(const QJsonObject &obj) override;
|
||||
};
|
||||
} // namespace messages
|
||||
} // namespace events
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace messages
|
|||
class Text : public Deserializable
|
||||
{
|
||||
public:
|
||||
void deserialize(const QJsonObject &obj) override;
|
||||
void deserialize(const QJsonObject &obj) override;
|
||||
};
|
||||
} // namespace messages
|
||||
} // namespace events
|
||||
|
|
|
@ -29,39 +29,39 @@ namespace events
|
|||
namespace messages
|
||||
{
|
||||
struct VideoInfo {
|
||||
int h;
|
||||
int w;
|
||||
int size;
|
||||
int duration;
|
||||
int h;
|
||||
int w;
|
||||
int size;
|
||||
int duration;
|
||||
|
||||
QString mimetype;
|
||||
QString thumbnail_url;
|
||||
ThumbnailInfo thumbnail_info;
|
||||
QString mimetype;
|
||||
QString thumbnail_url;
|
||||
ThumbnailInfo thumbnail_info;
|
||||
};
|
||||
|
||||
class Video : public Deserializable
|
||||
{
|
||||
public:
|
||||
inline QString url() const;
|
||||
inline VideoInfo info() const;
|
||||
inline QString url() const;
|
||||
inline VideoInfo info() const;
|
||||
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
void deserialize(const QJsonObject &object) override;
|
||||
|
||||
private:
|
||||
QString url_;
|
||||
VideoInfo info_;
|
||||
QString url_;
|
||||
VideoInfo info_;
|
||||
};
|
||||
|
||||
inline QString
|
||||
Video::url() const
|
||||
{
|
||||
return url_;
|
||||
return url_;
|
||||
}
|
||||
|
||||
inline VideoInfo
|
||||
Video::info() const
|
||||
{
|
||||
return info_;
|
||||
return info_;
|
||||
}
|
||||
|
||||
} // namespace messages
|
||||
|
|
|
@ -9,40 +9,40 @@
|
|||
|
||||
class Avatar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor)
|
||||
Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor)
|
||||
Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor)
|
||||
Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor)
|
||||
|
||||
public:
|
||||
explicit Avatar(QWidget *parent = 0);
|
||||
~Avatar();
|
||||
explicit Avatar(QWidget *parent = 0);
|
||||
~Avatar();
|
||||
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void setIcon(const QIcon &icon);
|
||||
void setImage(const QImage &image);
|
||||
void setLetter(const QChar &letter);
|
||||
void setSize(int size);
|
||||
void setTextColor(const QColor &color);
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void setIcon(const QIcon &icon);
|
||||
void setImage(const QImage &image);
|
||||
void setLetter(const QChar &letter);
|
||||
void setSize(int size);
|
||||
void setTextColor(const QColor &color);
|
||||
|
||||
QColor backgroundColor() const;
|
||||
QColor textColor() const;
|
||||
int size() const;
|
||||
QColor backgroundColor() const;
|
||||
QColor textColor() const;
|
||||
int size() const;
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
void init();
|
||||
void init();
|
||||
|
||||
ui::AvatarType type_;
|
||||
QChar letter_;
|
||||
QColor background_color_;
|
||||
QColor text_color_;
|
||||
QIcon icon_;
|
||||
QImage image_;
|
||||
QPixmap pixmap_;
|
||||
int size_;
|
||||
ui::AvatarType type_;
|
||||
QChar letter_;
|
||||
QColor background_color_;
|
||||
QColor text_color_;
|
||||
QIcon icon_;
|
||||
QImage image_;
|
||||
QPixmap pixmap_;
|
||||
int size_;
|
||||
};
|
||||
|
|
|
@ -9,55 +9,55 @@
|
|||
|
||||
class Badge : public OverlayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor)
|
||||
Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor)
|
||||
Q_PROPERTY(QPointF relativePosition WRITE setRelativePosition READ relativePosition)
|
||||
Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor)
|
||||
Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor)
|
||||
Q_PROPERTY(QPointF relativePosition WRITE setRelativePosition READ relativePosition)
|
||||
|
||||
public:
|
||||
explicit Badge(QWidget *parent = 0);
|
||||
explicit Badge(const QIcon &icon, QWidget *parent = 0);
|
||||
explicit Badge(const QString &text, QWidget *parent = 0);
|
||||
~Badge();
|
||||
explicit Badge(QWidget *parent = 0);
|
||||
explicit Badge(const QIcon &icon, QWidget *parent = 0);
|
||||
explicit Badge(const QString &text, QWidget *parent = 0);
|
||||
~Badge();
|
||||
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void setTextColor(const QColor &color);
|
||||
void setIcon(const QIcon &icon);
|
||||
void setRelativePosition(const QPointF &pos);
|
||||
void setRelativePosition(qreal x, qreal y);
|
||||
void setRelativeXPosition(qreal x);
|
||||
void setRelativeYPosition(qreal y);
|
||||
void setText(const QString &text);
|
||||
void setDiameter(int diameter);
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void setTextColor(const QColor &color);
|
||||
void setIcon(const QIcon &icon);
|
||||
void setRelativePosition(const QPointF &pos);
|
||||
void setRelativePosition(qreal x, qreal y);
|
||||
void setRelativeXPosition(qreal x);
|
||||
void setRelativeYPosition(qreal y);
|
||||
void setText(const QString &text);
|
||||
void setDiameter(int diameter);
|
||||
|
||||
QIcon icon() const;
|
||||
QString text() const;
|
||||
QColor backgroundColor() const;
|
||||
QColor textColor() const;
|
||||
QPointF relativePosition() const;
|
||||
QSize sizeHint() const override;
|
||||
qreal relativeXPosition() const;
|
||||
qreal relativeYPosition() const;
|
||||
QIcon icon() const;
|
||||
QString text() const;
|
||||
QColor backgroundColor() const;
|
||||
QColor textColor() const;
|
||||
QPointF relativePosition() const;
|
||||
QSize sizeHint() const override;
|
||||
qreal relativeXPosition() const;
|
||||
qreal relativeYPosition() const;
|
||||
|
||||
int diameter() const;
|
||||
int diameter() const;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
void init();
|
||||
void init();
|
||||
|
||||
QColor background_color_;
|
||||
QColor text_color_;
|
||||
QColor background_color_;
|
||||
QColor text_color_;
|
||||
|
||||
QIcon icon_;
|
||||
QSize size_;
|
||||
QString text_;
|
||||
QIcon icon_;
|
||||
QSize size_;
|
||||
QString text_;
|
||||
|
||||
int padding_;
|
||||
int diameter_;
|
||||
int padding_;
|
||||
int diameter_;
|
||||
|
||||
qreal x_;
|
||||
qreal y_;
|
||||
qreal x_;
|
||||
qreal y_;
|
||||
};
|
||||
|
|
|
@ -9,112 +9,112 @@ class CircularProgressDelegate;
|
|||
|
||||
class CircularProgress : public QProgressBar
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(qreal lineWidth WRITE setLineWidth READ lineWidth)
|
||||
Q_PROPERTY(qreal size WRITE setSize READ size)
|
||||
Q_PROPERTY(QColor color WRITE setColor READ color)
|
||||
Q_PROPERTY(qreal lineWidth WRITE setLineWidth READ lineWidth)
|
||||
Q_PROPERTY(qreal size WRITE setSize READ size)
|
||||
Q_PROPERTY(QColor color WRITE setColor READ color)
|
||||
|
||||
public:
|
||||
explicit CircularProgress(QWidget *parent = nullptr);
|
||||
~CircularProgress();
|
||||
explicit CircularProgress(QWidget *parent = nullptr);
|
||||
~CircularProgress();
|
||||
|
||||
void setProgressType(ui::ProgressType type);
|
||||
void setLineWidth(qreal width);
|
||||
void setSize(int size);
|
||||
void setColor(const QColor &color);
|
||||
void setProgressType(ui::ProgressType type);
|
||||
void setLineWidth(qreal width);
|
||||
void setSize(int size);
|
||||
void setColor(const QColor &color);
|
||||
|
||||
ui::ProgressType progressType() const;
|
||||
qreal lineWidth() const;
|
||||
int size() const;
|
||||
QColor color() const;
|
||||
ui::ProgressType progressType() const;
|
||||
qreal lineWidth() const;
|
||||
int size() const;
|
||||
QColor color() const;
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
CircularProgressDelegate *delegate_;
|
||||
CircularProgressDelegate *delegate_;
|
||||
|
||||
ui::ProgressType progress_type_;
|
||||
ui::ProgressType progress_type_;
|
||||
|
||||
QColor color_;
|
||||
QColor color_;
|
||||
|
||||
// Circle width.
|
||||
qreal width_;
|
||||
// Circle width.
|
||||
qreal width_;
|
||||
|
||||
// Circle radius.
|
||||
int size_;
|
||||
// Circle radius.
|
||||
int size_;
|
||||
|
||||
// Animation duration.
|
||||
int duration_;
|
||||
// Animation duration.
|
||||
int duration_;
|
||||
};
|
||||
|
||||
class CircularProgressDelegate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(qreal dashOffset WRITE setDashOffset READ dashOffset)
|
||||
Q_PROPERTY(qreal dashLength WRITE setDashLength READ dashLength)
|
||||
Q_PROPERTY(int angle WRITE setAngle READ angle)
|
||||
Q_PROPERTY(qreal dashOffset WRITE setDashOffset READ dashOffset)
|
||||
Q_PROPERTY(qreal dashLength WRITE setDashLength READ dashLength)
|
||||
Q_PROPERTY(int angle WRITE setAngle READ angle)
|
||||
|
||||
public:
|
||||
explicit CircularProgressDelegate(CircularProgress *parent);
|
||||
~CircularProgressDelegate();
|
||||
explicit CircularProgressDelegate(CircularProgress *parent);
|
||||
~CircularProgressDelegate();
|
||||
|
||||
inline void setDashOffset(qreal offset);
|
||||
inline void setDashLength(qreal length);
|
||||
inline void setAngle(int angle);
|
||||
inline void setDashOffset(qreal offset);
|
||||
inline void setDashLength(qreal length);
|
||||
inline void setAngle(int angle);
|
||||
|
||||
inline qreal dashOffset() const;
|
||||
inline qreal dashLength() const;
|
||||
inline int angle() const;
|
||||
inline qreal dashOffset() const;
|
||||
inline qreal dashLength() const;
|
||||
inline int angle() const;
|
||||
|
||||
private:
|
||||
CircularProgress *const progress_;
|
||||
CircularProgress *const progress_;
|
||||
|
||||
qreal dash_offset_;
|
||||
qreal dash_length_;
|
||||
qreal dash_offset_;
|
||||
qreal dash_length_;
|
||||
|
||||
int angle_;
|
||||
int angle_;
|
||||
};
|
||||
|
||||
inline void
|
||||
CircularProgressDelegate::setDashOffset(qreal offset)
|
||||
{
|
||||
dash_offset_ = offset;
|
||||
progress_->update();
|
||||
dash_offset_ = offset;
|
||||
progress_->update();
|
||||
}
|
||||
|
||||
inline void
|
||||
CircularProgressDelegate::setDashLength(qreal length)
|
||||
{
|
||||
dash_length_ = length;
|
||||
progress_->update();
|
||||
dash_length_ = length;
|
||||
progress_->update();
|
||||
}
|
||||
|
||||
inline void
|
||||
CircularProgressDelegate::setAngle(int angle)
|
||||
{
|
||||
angle_ = angle;
|
||||
progress_->update();
|
||||
angle_ = angle;
|
||||
progress_->update();
|
||||
}
|
||||
|
||||
inline qreal
|
||||
CircularProgressDelegate::dashOffset() const
|
||||
{
|
||||
return dash_offset_;
|
||||
return dash_offset_;
|
||||
}
|
||||
|
||||
inline qreal
|
||||
CircularProgressDelegate::dashLength() const
|
||||
{
|
||||
return dash_length_;
|
||||
return dash_length_;
|
||||
}
|
||||
|
||||
inline int
|
||||
CircularProgressDelegate::angle() const
|
||||
{
|
||||
return angle_;
|
||||
return angle_;
|
||||
}
|
||||
|
|
|
@ -7,97 +7,105 @@
|
|||
class DropShadow
|
||||
{
|
||||
public:
|
||||
static void draw(QPainter &painter,
|
||||
qint16 margin,
|
||||
qreal radius,
|
||||
QColor start,
|
||||
QColor end,
|
||||
qreal startPosition,
|
||||
qreal endPosition0,
|
||||
qreal endPosition1,
|
||||
qreal width,
|
||||
qreal height)
|
||||
{
|
||||
painter.setPen(Qt::NoPen);
|
||||
static void draw(QPainter &painter,
|
||||
qint16 margin,
|
||||
qreal radius,
|
||||
QColor start,
|
||||
QColor end,
|
||||
qreal startPosition,
|
||||
qreal endPosition0,
|
||||
qreal endPosition1,
|
||||
qreal width,
|
||||
qreal height)
|
||||
{
|
||||
painter.setPen(Qt::NoPen);
|
||||
|
||||
QLinearGradient gradient;
|
||||
gradient.setColorAt(startPosition, start);
|
||||
gradient.setColorAt(endPosition0, end);
|
||||
QLinearGradient gradient;
|
||||
gradient.setColorAt(startPosition, start);
|
||||
gradient.setColorAt(endPosition0, end);
|
||||
|
||||
// Right
|
||||
QPointF right0(width - margin, height / 2);
|
||||
QPointF right1(width, height / 2);
|
||||
gradient.setStart(right0);
|
||||
gradient.setFinalStop(right1);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(
|
||||
QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)), 0.0, 0.0);
|
||||
// Right
|
||||
QPointF right0(width - margin, height / 2);
|
||||
QPointF right1(width, height / 2);
|
||||
gradient.setStart(right0);
|
||||
gradient.setFinalStop(right1);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(
|
||||
QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)),
|
||||
0.0,
|
||||
0.0);
|
||||
|
||||
// Left
|
||||
QPointF left0(margin, height / 2);
|
||||
QPointF left1(0, height / 2);
|
||||
gradient.setStart(left0);
|
||||
gradient.setFinalStop(left1);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0);
|
||||
// Left
|
||||
QPointF left0(margin, height / 2);
|
||||
QPointF left1(0, height / 2);
|
||||
gradient.setStart(left0);
|
||||
gradient.setFinalStop(left1);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(
|
||||
QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0);
|
||||
|
||||
// Top
|
||||
QPointF top0(width / 2, margin);
|
||||
QPointF top1(width / 2, 0);
|
||||
gradient.setStart(top0);
|
||||
gradient.setFinalStop(top1);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0);
|
||||
// Top
|
||||
QPointF top0(width / 2, margin);
|
||||
QPointF top1(width / 2, 0);
|
||||
gradient.setStart(top0);
|
||||
gradient.setFinalStop(top1);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(
|
||||
QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0);
|
||||
|
||||
// Bottom
|
||||
QPointF bottom0(width / 2, height - margin);
|
||||
QPointF bottom1(width / 2, height);
|
||||
gradient.setStart(bottom0);
|
||||
gradient.setFinalStop(bottom1);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(
|
||||
QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)), 0.0, 0.0);
|
||||
// Bottom
|
||||
QPointF bottom0(width / 2, height - margin);
|
||||
QPointF bottom1(width / 2, height);
|
||||
gradient.setStart(bottom0);
|
||||
gradient.setFinalStop(bottom1);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(
|
||||
QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)),
|
||||
0.0,
|
||||
0.0);
|
||||
|
||||
// BottomRight
|
||||
QPointF bottomright0(width - margin, height - margin);
|
||||
QPointF bottomright1(width, height);
|
||||
gradient.setStart(bottomright0);
|
||||
gradient.setFinalStop(bottomright1);
|
||||
gradient.setColorAt(endPosition1, end);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(bottomright0, bottomright1), 0.0, 0.0);
|
||||
// BottomRight
|
||||
QPointF bottomright0(width - margin, height - margin);
|
||||
QPointF bottomright1(width, height);
|
||||
gradient.setStart(bottomright0);
|
||||
gradient.setFinalStop(bottomright1);
|
||||
gradient.setColorAt(endPosition1, end);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(bottomright0, bottomright1), 0.0, 0.0);
|
||||
|
||||
// BottomLeft
|
||||
QPointF bottomleft0(margin, height - margin);
|
||||
QPointF bottomleft1(0, height);
|
||||
gradient.setStart(bottomleft0);
|
||||
gradient.setFinalStop(bottomleft1);
|
||||
gradient.setColorAt(endPosition1, end);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0);
|
||||
// BottomLeft
|
||||
QPointF bottomleft0(margin, height - margin);
|
||||
QPointF bottomleft1(0, height);
|
||||
gradient.setStart(bottomleft0);
|
||||
gradient.setFinalStop(bottomleft1);
|
||||
gradient.setColorAt(endPosition1, end);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0);
|
||||
|
||||
// TopLeft
|
||||
QPointF topleft0(margin, margin);
|
||||
QPointF topleft1(0, 0);
|
||||
gradient.setStart(topleft0);
|
||||
gradient.setFinalStop(topleft1);
|
||||
gradient.setColorAt(endPosition1, end);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(topleft0, topleft1), 0.0, 0.0);
|
||||
// TopLeft
|
||||
QPointF topleft0(margin, margin);
|
||||
QPointF topleft1(0, 0);
|
||||
gradient.setStart(topleft0);
|
||||
gradient.setFinalStop(topleft1);
|
||||
gradient.setColorAt(endPosition1, end);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(topleft0, topleft1), 0.0, 0.0);
|
||||
|
||||
// TopRight
|
||||
QPointF topright0(width - margin, margin);
|
||||
QPointF topright1(width, 0);
|
||||
gradient.setStart(topright0);
|
||||
gradient.setFinalStop(topright1);
|
||||
gradient.setColorAt(endPosition1, end);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(topright0, topright1), 0.0, 0.0);
|
||||
// TopRight
|
||||
QPointF topright0(width - margin, margin);
|
||||
QPointF topright1(width, 0);
|
||||
gradient.setStart(topright0);
|
||||
gradient.setFinalStop(topright1);
|
||||
gradient.setColorAt(endPosition1, end);
|
||||
painter.setBrush(QBrush(gradient));
|
||||
painter.drawRoundRect(QRectF(topright0, topright1), 0.0, 0.0);
|
||||
|
||||
// Widget
|
||||
painter.setBrush(QBrush("#FFFFFF"));
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.drawRoundRect(
|
||||
QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)), radius, radius);
|
||||
}
|
||||
// Widget
|
||||
painter.setBrush(QBrush("#FFFFFF"));
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.drawRoundRect(
|
||||
QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)),
|
||||
radius,
|
||||
radius);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,167 +12,174 @@ class FlatButton;
|
|||
|
||||
class FlatButtonStateMachine : public QStateMachine
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(qreal overlayOpacity WRITE setOverlayOpacity READ overlayOpacity)
|
||||
Q_PROPERTY(qreal checkedOverlayProgress WRITE setCheckedOverlayProgress READ checkedOverlayProgress)
|
||||
Q_PROPERTY(qreal overlayOpacity WRITE setOverlayOpacity READ overlayOpacity)
|
||||
Q_PROPERTY(
|
||||
qreal checkedOverlayProgress WRITE setCheckedOverlayProgress READ checkedOverlayProgress)
|
||||
|
||||
public:
|
||||
explicit FlatButtonStateMachine(FlatButton *parent);
|
||||
~FlatButtonStateMachine();
|
||||
explicit FlatButtonStateMachine(FlatButton *parent);
|
||||
~FlatButtonStateMachine();
|
||||
|
||||
void setOverlayOpacity(qreal opacity);
|
||||
void setCheckedOverlayProgress(qreal opacity);
|
||||
void setOverlayOpacity(qreal opacity);
|
||||
void setCheckedOverlayProgress(qreal opacity);
|
||||
|
||||
inline qreal overlayOpacity() const;
|
||||
inline qreal checkedOverlayProgress() const;
|
||||
inline qreal overlayOpacity() const;
|
||||
inline qreal checkedOverlayProgress() const;
|
||||
|
||||
void startAnimations();
|
||||
void setupProperties();
|
||||
void updateCheckedStatus();
|
||||
void startAnimations();
|
||||
void setupProperties();
|
||||
void updateCheckedStatus();
|
||||
|
||||
signals:
|
||||
void buttonPressed();
|
||||
void buttonChecked();
|
||||
void buttonUnchecked();
|
||||
void buttonPressed();
|
||||
void buttonChecked();
|
||||
void buttonUnchecked();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void addTransition(QObject *object, const char *signal, QState *fromState, QState *toState);
|
||||
void addTransition(QObject *object, QEvent::Type eventType, QState *fromState, QState *toState);
|
||||
void addTransition(QAbstractTransition *transition, QState *fromState, QState *toState);
|
||||
void addTransition(QObject *object, const char *signal, QState *fromState, QState *toState);
|
||||
void addTransition(QObject *object,
|
||||
QEvent::Type eventType,
|
||||
QState *fromState,
|
||||
QState *toState);
|
||||
void addTransition(QAbstractTransition *transition, QState *fromState, QState *toState);
|
||||
|
||||
FlatButton *const button_;
|
||||
FlatButton *const button_;
|
||||
|
||||
QState *const top_level_state_;
|
||||
QState *const config_state_;
|
||||
QState *const checkable_state_;
|
||||
QState *const checked_state_;
|
||||
QState *const unchecked_state_;
|
||||
QState *const neutral_state_;
|
||||
QState *const neutral_focused_state_;
|
||||
QState *const hovered_state_;
|
||||
QState *const hovered_focused_state_;
|
||||
QState *const pressed_state_;
|
||||
QState *const top_level_state_;
|
||||
QState *const config_state_;
|
||||
QState *const checkable_state_;
|
||||
QState *const checked_state_;
|
||||
QState *const unchecked_state_;
|
||||
QState *const neutral_state_;
|
||||
QState *const neutral_focused_state_;
|
||||
QState *const hovered_state_;
|
||||
QState *const hovered_focused_state_;
|
||||
QState *const pressed_state_;
|
||||
|
||||
qreal overlay_opacity_;
|
||||
qreal checked_overlay_progress_;
|
||||
qreal overlay_opacity_;
|
||||
qreal checked_overlay_progress_;
|
||||
|
||||
bool was_checked_;
|
||||
bool was_checked_;
|
||||
};
|
||||
|
||||
inline qreal
|
||||
FlatButtonStateMachine::overlayOpacity() const
|
||||
{
|
||||
return overlay_opacity_;
|
||||
return overlay_opacity_;
|
||||
}
|
||||
|
||||
inline qreal
|
||||
FlatButtonStateMachine::checkedOverlayProgress() const
|
||||
{
|
||||
return checked_overlay_progress_;
|
||||
return checked_overlay_progress_;
|
||||
}
|
||||
|
||||
class FlatButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor foregroundColor WRITE setForegroundColor READ foregroundColor)
|
||||
Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor)
|
||||
Q_PROPERTY(QColor overlayColor WRITE setOverlayColor READ overlayColor)
|
||||
Q_PROPERTY(QColor disabledForegroundColor WRITE setDisabledForegroundColor READ disabledForegroundColor)
|
||||
Q_PROPERTY(QColor disabledBackgroundColor WRITE setDisabledBackgroundColor READ disabledBackgroundColor)
|
||||
Q_PROPERTY(qreal fontSize WRITE setFontSize READ fontSize)
|
||||
Q_PROPERTY(QColor foregroundColor WRITE setForegroundColor READ foregroundColor)
|
||||
Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor)
|
||||
Q_PROPERTY(QColor overlayColor WRITE setOverlayColor READ overlayColor)
|
||||
Q_PROPERTY(QColor disabledForegroundColor WRITE setDisabledForegroundColor READ
|
||||
disabledForegroundColor)
|
||||
Q_PROPERTY(QColor disabledBackgroundColor WRITE setDisabledBackgroundColor READ
|
||||
disabledBackgroundColor)
|
||||
Q_PROPERTY(qreal fontSize WRITE setFontSize READ fontSize)
|
||||
|
||||
public:
|
||||
explicit FlatButton(QWidget *parent = 0, ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset);
|
||||
explicit FlatButton(const QString &text,
|
||||
QWidget *parent = 0,
|
||||
ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset);
|
||||
FlatButton(const QString &text,
|
||||
ui::Role role,
|
||||
QWidget *parent = 0,
|
||||
ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset);
|
||||
~FlatButton();
|
||||
explicit FlatButton(QWidget *parent = 0,
|
||||
ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset);
|
||||
explicit FlatButton(const QString &text,
|
||||
QWidget *parent = 0,
|
||||
ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset);
|
||||
FlatButton(const QString &text,
|
||||
ui::Role role,
|
||||
QWidget *parent = 0,
|
||||
ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset);
|
||||
~FlatButton();
|
||||
|
||||
void applyPreset(ui::ButtonPreset preset);
|
||||
void applyPreset(ui::ButtonPreset preset);
|
||||
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void setBackgroundMode(Qt::BGMode mode);
|
||||
void setBaseOpacity(qreal opacity);
|
||||
void setCheckable(bool value);
|
||||
void setCornerRadius(qreal radius);
|
||||
void setDisabledBackgroundColor(const QColor &color);
|
||||
void setDisabledForegroundColor(const QColor &color);
|
||||
void setFixedRippleRadius(qreal radius);
|
||||
void setFontSize(qreal size);
|
||||
void setForegroundColor(const QColor &color);
|
||||
void setHasFixedRippleRadius(bool value);
|
||||
void setIconPlacement(ui::ButtonIconPlacement placement);
|
||||
void setOverlayColor(const QColor &color);
|
||||
void setOverlayStyle(ui::OverlayStyle style);
|
||||
void setRippleStyle(ui::RippleStyle style);
|
||||
void setRole(ui::Role role);
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void setBackgroundMode(Qt::BGMode mode);
|
||||
void setBaseOpacity(qreal opacity);
|
||||
void setCheckable(bool value);
|
||||
void setCornerRadius(qreal radius);
|
||||
void setDisabledBackgroundColor(const QColor &color);
|
||||
void setDisabledForegroundColor(const QColor &color);
|
||||
void setFixedRippleRadius(qreal radius);
|
||||
void setFontSize(qreal size);
|
||||
void setForegroundColor(const QColor &color);
|
||||
void setHasFixedRippleRadius(bool value);
|
||||
void setIconPlacement(ui::ButtonIconPlacement placement);
|
||||
void setOverlayColor(const QColor &color);
|
||||
void setOverlayStyle(ui::OverlayStyle style);
|
||||
void setRippleStyle(ui::RippleStyle style);
|
||||
void setRole(ui::Role role);
|
||||
|
||||
QColor foregroundColor() const;
|
||||
QColor backgroundColor() const;
|
||||
QColor overlayColor() const;
|
||||
QColor disabledForegroundColor() const;
|
||||
QColor disabledBackgroundColor() const;
|
||||
QColor foregroundColor() const;
|
||||
QColor backgroundColor() const;
|
||||
QColor overlayColor() const;
|
||||
QColor disabledForegroundColor() const;
|
||||
QColor disabledBackgroundColor() const;
|
||||
|
||||
qreal fontSize() const;
|
||||
qreal cornerRadius() const;
|
||||
qreal baseOpacity() const;
|
||||
qreal fontSize() const;
|
||||
qreal cornerRadius() const;
|
||||
qreal baseOpacity() const;
|
||||
|
||||
bool hasFixedRippleRadius() const;
|
||||
bool hasFixedRippleRadius() const;
|
||||
|
||||
ui::Role role() const;
|
||||
ui::OverlayStyle overlayStyle() const;
|
||||
ui::RippleStyle rippleStyle() const;
|
||||
ui::ButtonIconPlacement iconPlacement() const;
|
||||
ui::Role role() const;
|
||||
ui::OverlayStyle overlayStyle() const;
|
||||
ui::RippleStyle rippleStyle() const;
|
||||
ui::ButtonIconPlacement iconPlacement() const;
|
||||
|
||||
Qt::BGMode backgroundMode() const;
|
||||
Qt::BGMode backgroundMode() const;
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
protected:
|
||||
int IconPadding = 0;
|
||||
int IconPadding = 0;
|
||||
|
||||
void checkStateSet() override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void checkStateSet() override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void paintBackground(QPainter *painter);
|
||||
virtual void paintForeground(QPainter *painter);
|
||||
virtual void updateClipPath();
|
||||
virtual void paintBackground(QPainter *painter);
|
||||
virtual void paintForeground(QPainter *painter);
|
||||
virtual void updateClipPath();
|
||||
|
||||
void init();
|
||||
void init();
|
||||
|
||||
private:
|
||||
RippleOverlay *ripple_overlay_;
|
||||
FlatButtonStateMachine *state_machine_;
|
||||
RippleOverlay *ripple_overlay_;
|
||||
FlatButtonStateMachine *state_machine_;
|
||||
|
||||
ui::Role role_;
|
||||
ui::RippleStyle ripple_style_;
|
||||
ui::ButtonIconPlacement icon_placement_;
|
||||
ui::OverlayStyle overlay_style_;
|
||||
ui::Role role_;
|
||||
ui::RippleStyle ripple_style_;
|
||||
ui::ButtonIconPlacement icon_placement_;
|
||||
ui::OverlayStyle overlay_style_;
|
||||
|
||||
Qt::BGMode bg_mode_;
|
||||
Qt::BGMode bg_mode_;
|
||||
|
||||
QColor background_color_;
|
||||
QColor foreground_color_;
|
||||
QColor overlay_color_;
|
||||
QColor disabled_color_;
|
||||
QColor disabled_background_color_;
|
||||
QColor background_color_;
|
||||
QColor foreground_color_;
|
||||
QColor overlay_color_;
|
||||
QColor disabled_color_;
|
||||
QColor disabled_background_color_;
|
||||
|
||||
qreal fixed_ripple_radius_;
|
||||
qreal corner_radius_;
|
||||
qreal base_opacity_;
|
||||
qreal font_size_;
|
||||
qreal fixed_ripple_radius_;
|
||||
qreal corner_radius_;
|
||||
qreal base_opacity_;
|
||||
qreal font_size_;
|
||||
|
||||
bool use_fixed_ripple_radius_;
|
||||
bool use_fixed_ripple_radius_;
|
||||
};
|
||||
|
|
|
@ -7,24 +7,26 @@
|
|||
class Menu : public QMenu
|
||||
{
|
||||
public:
|
||||
Menu(QWidget *parent = nullptr)
|
||||
: QMenu(parent)
|
||||
{
|
||||
QFont font;
|
||||
font.setPixelSize(conf::fontSize);
|
||||
Menu(QWidget *parent = nullptr)
|
||||
: QMenu(parent)
|
||||
{
|
||||
QFont font;
|
||||
font.setPixelSize(conf::fontSize);
|
||||
|
||||
setFont(font);
|
||||
setStyleSheet("QMenu { color: black; background-color: white; margin: 0px;}"
|
||||
"QMenu::item { color: black; padding: 7px 20px; border: 1px solid transparent; margin: "
|
||||
"2px 0px; }"
|
||||
"QMenu::item:selected { color: black; background: rgba(180, 180, 180, 100); }");
|
||||
};
|
||||
setFont(font);
|
||||
setStyleSheet(
|
||||
"QMenu { color: black; background-color: white; margin: 0px;}"
|
||||
"QMenu::item { color: black; padding: 7px 20px; border: 1px solid transparent; "
|
||||
"margin: "
|
||||
"2px 0px; }"
|
||||
"QMenu::item:selected { color: black; background: rgba(180, 180, 180, 100); }");
|
||||
};
|
||||
|
||||
protected:
|
||||
void leaveEvent(QEvent *e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
void leaveEvent(QEvent *e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
|
||||
hide();
|
||||
}
|
||||
hide();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -26,35 +26,35 @@
|
|||
class OverlayModal : public OverlayWidget
|
||||
{
|
||||
public:
|
||||
explicit OverlayModal(QWidget *parent, QWidget *content);
|
||||
explicit OverlayModal(QWidget *parent, QWidget *content);
|
||||
|
||||
void fadeIn();
|
||||
void fadeOut();
|
||||
void fadeIn();
|
||||
void fadeOut();
|
||||
|
||||
public:
|
||||
inline void setDuration(int duration);
|
||||
inline void setColor(QColor color);
|
||||
inline void setDuration(int duration);
|
||||
inline void setColor(QColor color);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
int duration_;
|
||||
QColor color_;
|
||||
int duration_;
|
||||
QColor color_;
|
||||
|
||||
QGraphicsOpacityEffect *opacity_;
|
||||
QPropertyAnimation *animation_;
|
||||
QGraphicsOpacityEffect *opacity_;
|
||||
QPropertyAnimation *animation_;
|
||||
};
|
||||
|
||||
inline void
|
||||
OverlayModal::setDuration(int duration)
|
||||
{
|
||||
duration_ = duration;
|
||||
animation_->setDuration(duration_);
|
||||
duration_ = duration;
|
||||
animation_->setDuration(duration_);
|
||||
}
|
||||
|
||||
inline void
|
||||
OverlayModal::setColor(QColor color)
|
||||
{
|
||||
color_ = color;
|
||||
color_ = color;
|
||||
}
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
|
||||
class OverlayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OverlayWidget(QWidget *parent = nullptr);
|
||||
explicit OverlayWidget(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
bool event(QEvent *event) override;
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
QRect overlayGeometry() const;
|
||||
QRect overlayGeometry() const;
|
||||
};
|
||||
|
|
|
@ -8,21 +8,21 @@
|
|||
|
||||
class RaisedButton : public FlatButton
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RaisedButton(QWidget *parent = 0);
|
||||
explicit RaisedButton(const QString &text, QWidget *parent = 0);
|
||||
~RaisedButton();
|
||||
explicit RaisedButton(QWidget *parent = 0);
|
||||
explicit RaisedButton(const QString &text, QWidget *parent = 0);
|
||||
~RaisedButton();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
private:
|
||||
void init();
|
||||
void init();
|
||||
|
||||
QStateMachine *shadow_state_machine_;
|
||||
QState *normal_state_;
|
||||
QState *pressed_state_;
|
||||
QGraphicsDropShadowEffect *effect_;
|
||||
QStateMachine *shadow_state_machine_;
|
||||
QState *normal_state_;
|
||||
QState *pressed_state_;
|
||||
QGraphicsDropShadowEffect *effect_;
|
||||
};
|
||||
|
|
|
@ -10,137 +10,137 @@ class RippleOverlay;
|
|||
|
||||
class Ripple : public QParallelAnimationGroup
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(qreal radius WRITE setRadius READ radius)
|
||||
Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity)
|
||||
Q_PROPERTY(qreal radius WRITE setRadius READ radius)
|
||||
Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity)
|
||||
|
||||
public:
|
||||
explicit Ripple(const QPoint ¢er, QObject *parent = 0);
|
||||
Ripple(const QPoint ¢er, RippleOverlay *overlay, QObject *parent = 0);
|
||||
~Ripple();
|
||||
explicit Ripple(const QPoint ¢er, QObject *parent = 0);
|
||||
Ripple(const QPoint ¢er, RippleOverlay *overlay, QObject *parent = 0);
|
||||
~Ripple();
|
||||
|
||||
inline void setOverlay(RippleOverlay *overlay);
|
||||
inline void setOverlay(RippleOverlay *overlay);
|
||||
|
||||
void setRadius(qreal radius);
|
||||
void setOpacity(qreal opacity);
|
||||
void setColor(const QColor &color);
|
||||
void setBrush(const QBrush &brush);
|
||||
void setRadius(qreal radius);
|
||||
void setOpacity(qreal opacity);
|
||||
void setColor(const QColor &color);
|
||||
void setBrush(const QBrush &brush);
|
||||
|
||||
inline qreal radius() const;
|
||||
inline qreal opacity() const;
|
||||
inline QColor color() const;
|
||||
inline QBrush brush() const;
|
||||
inline QPoint center() const;
|
||||
inline qreal radius() const;
|
||||
inline qreal opacity() const;
|
||||
inline QColor color() const;
|
||||
inline QBrush brush() const;
|
||||
inline QPoint center() const;
|
||||
|
||||
inline QPropertyAnimation *radiusAnimation() const;
|
||||
inline QPropertyAnimation *opacityAnimation() const;
|
||||
inline QPropertyAnimation *radiusAnimation() const;
|
||||
inline QPropertyAnimation *opacityAnimation() const;
|
||||
|
||||
inline void setOpacityStartValue(qreal value);
|
||||
inline void setOpacityEndValue(qreal value);
|
||||
inline void setRadiusStartValue(qreal value);
|
||||
inline void setRadiusEndValue(qreal value);
|
||||
inline void setDuration(int msecs);
|
||||
inline void setOpacityStartValue(qreal value);
|
||||
inline void setOpacityEndValue(qreal value);
|
||||
inline void setRadiusStartValue(qreal value);
|
||||
inline void setRadiusEndValue(qreal value);
|
||||
inline void setDuration(int msecs);
|
||||
|
||||
protected slots:
|
||||
void destroy();
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(Ripple)
|
||||
Q_DISABLE_COPY(Ripple)
|
||||
|
||||
QPropertyAnimation *animate(const QByteArray &property,
|
||||
const QEasingCurve &easing = QEasingCurve::OutQuad,
|
||||
int duration = 800);
|
||||
QPropertyAnimation *animate(const QByteArray &property,
|
||||
const QEasingCurve &easing = QEasingCurve::OutQuad,
|
||||
int duration = 800);
|
||||
|
||||
void init();
|
||||
void init();
|
||||
|
||||
RippleOverlay *overlay_;
|
||||
RippleOverlay *overlay_;
|
||||
|
||||
QPropertyAnimation *const radius_anim_;
|
||||
QPropertyAnimation *const opacity_anim_;
|
||||
QPropertyAnimation *const radius_anim_;
|
||||
QPropertyAnimation *const opacity_anim_;
|
||||
|
||||
qreal radius_;
|
||||
qreal opacity_;
|
||||
qreal radius_;
|
||||
qreal opacity_;
|
||||
|
||||
QPoint center_;
|
||||
QBrush brush_;
|
||||
QPoint center_;
|
||||
QBrush brush_;
|
||||
};
|
||||
|
||||
inline void
|
||||
Ripple::setOverlay(RippleOverlay *overlay)
|
||||
{
|
||||
overlay_ = overlay;
|
||||
overlay_ = overlay;
|
||||
}
|
||||
|
||||
inline qreal
|
||||
Ripple::radius() const
|
||||
{
|
||||
return radius_;
|
||||
return radius_;
|
||||
}
|
||||
|
||||
inline qreal
|
||||
Ripple::opacity() const
|
||||
{
|
||||
return opacity_;
|
||||
return opacity_;
|
||||
}
|
||||
|
||||
inline QColor
|
||||
Ripple::color() const
|
||||
{
|
||||
return brush_.color();
|
||||
return brush_.color();
|
||||
}
|
||||
|
||||
inline QBrush
|
||||
Ripple::brush() const
|
||||
{
|
||||
return brush_;
|
||||
return brush_;
|
||||
}
|
||||
|
||||
inline QPoint
|
||||
Ripple::center() const
|
||||
{
|
||||
return center_;
|
||||
return center_;
|
||||
}
|
||||
|
||||
inline QPropertyAnimation *
|
||||
Ripple::radiusAnimation() const
|
||||
{
|
||||
return radius_anim_;
|
||||
return radius_anim_;
|
||||
}
|
||||
|
||||
inline QPropertyAnimation *
|
||||
Ripple::opacityAnimation() const
|
||||
{
|
||||
return opacity_anim_;
|
||||
return opacity_anim_;
|
||||
}
|
||||
|
||||
inline void
|
||||
Ripple::setOpacityStartValue(qreal value)
|
||||
{
|
||||
opacity_anim_->setStartValue(value);
|
||||
opacity_anim_->setStartValue(value);
|
||||
}
|
||||
|
||||
inline void
|
||||
Ripple::setOpacityEndValue(qreal value)
|
||||
{
|
||||
opacity_anim_->setEndValue(value);
|
||||
opacity_anim_->setEndValue(value);
|
||||
}
|
||||
|
||||
inline void
|
||||
Ripple::setRadiusStartValue(qreal value)
|
||||
{
|
||||
radius_anim_->setStartValue(value);
|
||||
radius_anim_->setStartValue(value);
|
||||
}
|
||||
|
||||
inline void
|
||||
Ripple::setRadiusEndValue(qreal value)
|
||||
{
|
||||
radius_anim_->setEndValue(value);
|
||||
radius_anim_->setEndValue(value);
|
||||
}
|
||||
|
||||
inline void
|
||||
Ripple::setDuration(int msecs)
|
||||
{
|
||||
radius_anim_->setDuration(msecs);
|
||||
opacity_anim_->setDuration(msecs);
|
||||
radius_anim_->setDuration(msecs);
|
||||
opacity_anim_->setDuration(msecs);
|
||||
}
|
||||
|
|
|
@ -8,51 +8,51 @@ class Ripple;
|
|||
|
||||
class RippleOverlay : public OverlayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RippleOverlay(QWidget *parent = 0);
|
||||
~RippleOverlay();
|
||||
explicit RippleOverlay(QWidget *parent = 0);
|
||||
~RippleOverlay();
|
||||
|
||||
void addRipple(Ripple *ripple);
|
||||
void addRipple(const QPoint &position, qreal radius = 300);
|
||||
void addRipple(Ripple *ripple);
|
||||
void addRipple(const QPoint &position, qreal radius = 300);
|
||||
|
||||
void removeRipple(Ripple *ripple);
|
||||
void removeRipple(Ripple *ripple);
|
||||
|
||||
inline void setClipping(bool enable);
|
||||
inline bool hasClipping() const;
|
||||
inline void setClipping(bool enable);
|
||||
inline bool hasClipping() const;
|
||||
|
||||
inline void setClipPath(const QPainterPath &path);
|
||||
inline void setClipPath(const QPainterPath &path);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(RippleOverlay)
|
||||
Q_DISABLE_COPY(RippleOverlay)
|
||||
|
||||
void paintRipple(QPainter *painter, Ripple *ripple);
|
||||
void paintRipple(QPainter *painter, Ripple *ripple);
|
||||
|
||||
QList<Ripple *> ripples_;
|
||||
QPainterPath clip_path_;
|
||||
bool use_clip_;
|
||||
QList<Ripple *> ripples_;
|
||||
QPainterPath clip_path_;
|
||||
bool use_clip_;
|
||||
};
|
||||
|
||||
inline void
|
||||
RippleOverlay::setClipping(bool enable)
|
||||
{
|
||||
use_clip_ = enable;
|
||||
update();
|
||||
use_clip_ = enable;
|
||||
update();
|
||||
}
|
||||
|
||||
inline bool
|
||||
RippleOverlay::hasClipping() const
|
||||
{
|
||||
return use_clip_;
|
||||
return use_clip_;
|
||||
}
|
||||
|
||||
inline void
|
||||
RippleOverlay::setClipPath(const QPainterPath &path)
|
||||
{
|
||||
clip_path_ = path;
|
||||
update();
|
||||
clip_path_ = path;
|
||||
update();
|
||||
}
|
||||
|
|
|
@ -25,29 +25,29 @@
|
|||
|
||||
class ScrollBar : public QScrollBar
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScrollBar(QScrollArea *area, QWidget *parent = nullptr);
|
||||
ScrollBar(QScrollArea *area, QWidget *parent = nullptr);
|
||||
|
||||
void fadeIn();
|
||||
void fadeOut();
|
||||
void fadeIn();
|
||||
void fadeOut();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void sliderChange(SliderChange change) override;
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void sliderChange(SliderChange change) override;
|
||||
|
||||
private:
|
||||
int roundRadius_ = 4;
|
||||
int handleWidth_ = 7;
|
||||
int minHandleHeight_ = 20;
|
||||
bool isActive;
|
||||
int roundRadius_ = 4;
|
||||
int handleWidth_ = 7;
|
||||
int minHandleHeight_ = 20;
|
||||
bool isActive;
|
||||
|
||||
const int AnimationDuration = 300;
|
||||
const int Padding = 4;
|
||||
const int AnimationDuration = 300;
|
||||
const int Padding = 4;
|
||||
|
||||
QGraphicsOpacityEffect *eff;
|
||||
QTimer hideTimer_;
|
||||
QGraphicsOpacityEffect *eff;
|
||||
QTimer hideTimer_;
|
||||
|
||||
QScrollArea *area_;
|
||||
QRect handle_;
|
||||
QScrollArea *area_;
|
||||
QRect handle_;
|
||||
};
|
||||
|
|
|
@ -13,163 +13,163 @@ class TextFieldStateMachine;
|
|||
|
||||
class TextField : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor)
|
||||
Q_PROPERTY(QColor inkColor WRITE setInkColor READ inkColor)
|
||||
Q_PROPERTY(QColor underlineColor WRITE setUnderlineColor READ underlineColor)
|
||||
Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor)
|
||||
Q_PROPERTY(QColor inkColor WRITE setInkColor READ inkColor)
|
||||
Q_PROPERTY(QColor underlineColor WRITE setUnderlineColor READ underlineColor)
|
||||
|
||||
public:
|
||||
explicit TextField(QWidget *parent = 0);
|
||||
~TextField();
|
||||
explicit TextField(QWidget *parent = 0);
|
||||
~TextField();
|
||||
|
||||
void setInkColor(const QColor &color);
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void setLabel(const QString &label);
|
||||
void setLabelColor(const QColor &color);
|
||||
void setLabelFontSize(qreal size);
|
||||
void setShowLabel(bool value);
|
||||
void setTextColor(const QColor &color);
|
||||
void setUnderlineColor(const QColor &color);
|
||||
void setInkColor(const QColor &color);
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void setLabel(const QString &label);
|
||||
void setLabelColor(const QColor &color);
|
||||
void setLabelFontSize(qreal size);
|
||||
void setShowLabel(bool value);
|
||||
void setTextColor(const QColor &color);
|
||||
void setUnderlineColor(const QColor &color);
|
||||
|
||||
QColor inkColor() const;
|
||||
QColor labelColor() const;
|
||||
QColor textColor() const;
|
||||
QColor underlineColor() const;
|
||||
QColor backgroundColor() const;
|
||||
QString label() const;
|
||||
bool hasLabel() const;
|
||||
qreal labelFontSize() const;
|
||||
QColor inkColor() const;
|
||||
QColor labelColor() const;
|
||||
QColor textColor() const;
|
||||
QColor underlineColor() const;
|
||||
QColor backgroundColor() const;
|
||||
QString label() const;
|
||||
bool hasLabel() const;
|
||||
qreal labelFontSize() const;
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
bool event(QEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
void init();
|
||||
void init();
|
||||
|
||||
QColor ink_color_;
|
||||
QColor background_color_;
|
||||
QColor label_color_;
|
||||
QColor text_color_;
|
||||
QColor underline_color_;
|
||||
QString label_text_;
|
||||
TextFieldLabel *label_;
|
||||
TextFieldStateMachine *state_machine_;
|
||||
bool show_label_;
|
||||
qreal label_font_size_;
|
||||
QColor ink_color_;
|
||||
QColor background_color_;
|
||||
QColor label_color_;
|
||||
QColor text_color_;
|
||||
QColor underline_color_;
|
||||
QString label_text_;
|
||||
TextFieldLabel *label_;
|
||||
TextFieldStateMachine *state_machine_;
|
||||
bool show_label_;
|
||||
qreal label_font_size_;
|
||||
};
|
||||
|
||||
class TextFieldLabel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(qreal scale WRITE setScale READ scale)
|
||||
Q_PROPERTY(QPointF offset WRITE setOffset READ offset)
|
||||
Q_PROPERTY(QColor color WRITE setColor READ color)
|
||||
Q_PROPERTY(qreal scale WRITE setScale READ scale)
|
||||
Q_PROPERTY(QPointF offset WRITE setOffset READ offset)
|
||||
Q_PROPERTY(QColor color WRITE setColor READ color)
|
||||
|
||||
public:
|
||||
TextFieldLabel(TextField *parent);
|
||||
~TextFieldLabel();
|
||||
TextFieldLabel(TextField *parent);
|
||||
~TextFieldLabel();
|
||||
|
||||
inline void setColor(const QColor &color);
|
||||
inline void setOffset(const QPointF &pos);
|
||||
inline void setScale(qreal scale);
|
||||
inline void setColor(const QColor &color);
|
||||
inline void setOffset(const QPointF &pos);
|
||||
inline void setScale(qreal scale);
|
||||
|
||||
inline QColor color() const;
|
||||
inline QPointF offset() const;
|
||||
inline qreal scale() const;
|
||||
inline QColor color() const;
|
||||
inline QPointF offset() const;
|
||||
inline qreal scale() const;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
TextField *const text_field_;
|
||||
TextField *const text_field_;
|
||||
|
||||
QColor color_;
|
||||
qreal scale_;
|
||||
qreal x_;
|
||||
qreal y_;
|
||||
QColor color_;
|
||||
qreal scale_;
|
||||
qreal x_;
|
||||
qreal y_;
|
||||
};
|
||||
|
||||
inline void
|
||||
TextFieldLabel::setColor(const QColor &color)
|
||||
{
|
||||
color_ = color;
|
||||
update();
|
||||
color_ = color;
|
||||
update();
|
||||
}
|
||||
|
||||
inline void
|
||||
TextFieldLabel::setOffset(const QPointF &pos)
|
||||
{
|
||||
x_ = pos.x();
|
||||
y_ = pos.y();
|
||||
update();
|
||||
x_ = pos.x();
|
||||
y_ = pos.y();
|
||||
update();
|
||||
}
|
||||
|
||||
inline void
|
||||
TextFieldLabel::setScale(qreal scale)
|
||||
{
|
||||
scale_ = scale;
|
||||
update();
|
||||
scale_ = scale;
|
||||
update();
|
||||
}
|
||||
|
||||
inline QPointF
|
||||
TextFieldLabel::offset() const
|
||||
{
|
||||
return QPointF(x_, y_);
|
||||
return QPointF(x_, y_);
|
||||
}
|
||||
inline qreal
|
||||
TextFieldLabel::scale() const
|
||||
{
|
||||
return scale_;
|
||||
return scale_;
|
||||
}
|
||||
inline QColor
|
||||
TextFieldLabel::color() const
|
||||
{
|
||||
return color_;
|
||||
return color_;
|
||||
}
|
||||
|
||||
class TextFieldStateMachine : public QStateMachine
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(qreal progress WRITE setProgress READ progress)
|
||||
Q_PROPERTY(qreal progress WRITE setProgress READ progress)
|
||||
|
||||
public:
|
||||
TextFieldStateMachine(TextField *parent);
|
||||
~TextFieldStateMachine();
|
||||
TextFieldStateMachine(TextField *parent);
|
||||
~TextFieldStateMachine();
|
||||
|
||||
inline void setProgress(qreal progress);
|
||||
void setLabel(TextFieldLabel *label);
|
||||
inline void setProgress(qreal progress);
|
||||
void setLabel(TextFieldLabel *label);
|
||||
|
||||
inline qreal progress() const;
|
||||
inline qreal progress() const;
|
||||
|
||||
public slots:
|
||||
void setupProperties();
|
||||
void setupProperties();
|
||||
|
||||
private:
|
||||
QPropertyAnimation *color_anim_;
|
||||
QPropertyAnimation *offset_anim_;
|
||||
QPropertyAnimation *color_anim_;
|
||||
QPropertyAnimation *offset_anim_;
|
||||
|
||||
QState *focused_state_;
|
||||
QState *normal_state_;
|
||||
QState *focused_state_;
|
||||
QState *normal_state_;
|
||||
|
||||
TextField *text_field_;
|
||||
TextFieldLabel *label_;
|
||||
TextField *text_field_;
|
||||
TextFieldLabel *label_;
|
||||
|
||||
qreal progress_;
|
||||
qreal progress_;
|
||||
};
|
||||
|
||||
inline void
|
||||
TextFieldStateMachine::setProgress(qreal progress)
|
||||
{
|
||||
progress_ = progress;
|
||||
text_field_->update();
|
||||
progress_ = progress;
|
||||
text_field_->update();
|
||||
}
|
||||
|
||||
inline qreal
|
||||
TextFieldStateMachine::progress() const
|
||||
{
|
||||
return progress_;
|
||||
return progress_;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ enum class AvatarType { Icon, Image, Letter };
|
|||
|
||||
namespace sidebar
|
||||
{
|
||||
static const int SmallSize = 60;
|
||||
static const int SmallSize = 60;
|
||||
static const int NormalSize = 300;
|
||||
}
|
||||
// Default font size.
|
||||
|
@ -32,35 +32,35 @@ enum class ButtonIconPlacement { LeftIcon, RightIcon };
|
|||
enum class ProgressType { DeterminateProgress, IndeterminateProgress };
|
||||
|
||||
enum class Color {
|
||||
Black,
|
||||
BrightWhite,
|
||||
FadedWhite,
|
||||
MediumWhite,
|
||||
DarkGreen,
|
||||
LightGreen,
|
||||
BrightGreen,
|
||||
Gray,
|
||||
Red,
|
||||
Blue,
|
||||
Transparent
|
||||
Black,
|
||||
BrightWhite,
|
||||
FadedWhite,
|
||||
MediumWhite,
|
||||
DarkGreen,
|
||||
LightGreen,
|
||||
BrightGreen,
|
||||
Gray,
|
||||
Red,
|
||||
Blue,
|
||||
Transparent
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
class Theme : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Theme(QObject *parent = 0);
|
||||
~Theme();
|
||||
explicit Theme(QObject *parent = 0);
|
||||
~Theme();
|
||||
|
||||
QColor getColor(const QString &key) const;
|
||||
QColor getColor(const QString &key) const;
|
||||
|
||||
void setColor(const QString &key, const QColor &color);
|
||||
void setColor(const QString &key, ui::Color color);
|
||||
void setColor(const QString &key, const QColor &color);
|
||||
void setColor(const QString &key, ui::Color color);
|
||||
|
||||
private:
|
||||
QColor rgba(int r, int g, int b, qreal a) const;
|
||||
QColor rgba(int r, int g, int b, qreal a) const;
|
||||
|
||||
QHash<QString, QColor> colors_;
|
||||
QHash<QString, QColor> colors_;
|
||||
};
|
||||
|
|
|
@ -6,26 +6,26 @@
|
|||
|
||||
class ThemeManager : public QCommonStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
inline static ThemeManager &instance();
|
||||
inline static ThemeManager &instance();
|
||||
|
||||
void setTheme(Theme *theme);
|
||||
QColor themeColor(const QString &key) const;
|
||||
void setTheme(Theme *theme);
|
||||
QColor themeColor(const QString &key) const;
|
||||
|
||||
private:
|
||||
ThemeManager();
|
||||
ThemeManager();
|
||||
|
||||
ThemeManager(ThemeManager const &);
|
||||
void operator=(ThemeManager const &);
|
||||
ThemeManager(ThemeManager const &);
|
||||
void operator=(ThemeManager const &);
|
||||
|
||||
Theme *theme_;
|
||||
Theme *theme_;
|
||||
};
|
||||
|
||||
inline ThemeManager &
|
||||
ThemeManager::instance()
|
||||
{
|
||||
static ThemeManager instance;
|
||||
return instance;
|
||||
static ThemeManager instance;
|
||||
return instance;
|
||||
}
|
||||
|
|
|
@ -26,63 +26,63 @@ QMap<QString, QList<TimelineItem *>> AvatarProvider::toBeResolved_;
|
|||
void
|
||||
AvatarProvider::init(QSharedPointer<MatrixClient> client)
|
||||
{
|
||||
client_ = client;
|
||||
client_ = client;
|
||||
|
||||
connect(client_.data(), &MatrixClient::userAvatarRetrieved, &AvatarProvider::updateAvatar);
|
||||
connect(client_.data(), &MatrixClient::userAvatarRetrieved, &AvatarProvider::updateAvatar);
|
||||
}
|
||||
|
||||
void
|
||||
AvatarProvider::updateAvatar(const QString &uid, const QImage &img)
|
||||
{
|
||||
if (toBeResolved_.contains(uid)) {
|
||||
auto items = toBeResolved_[uid];
|
||||
if (toBeResolved_.contains(uid)) {
|
||||
auto items = toBeResolved_[uid];
|
||||
|
||||
// Update all the timeline items with the resolved avatar.
|
||||
for (const auto item : items)
|
||||
item->setUserAvatar(img);
|
||||
// Update all the timeline items with the resolved avatar.
|
||||
for (const auto item : items)
|
||||
item->setUserAvatar(img);
|
||||
|
||||
toBeResolved_.remove(uid);
|
||||
}
|
||||
toBeResolved_.remove(uid);
|
||||
}
|
||||
|
||||
userAvatars_.insert(uid, img);
|
||||
userAvatars_.insert(uid, img);
|
||||
}
|
||||
|
||||
void
|
||||
AvatarProvider::resolve(const QString &userId, TimelineItem *item)
|
||||
{
|
||||
if (userAvatars_.contains(userId)) {
|
||||
auto img = userAvatars_[userId];
|
||||
if (userAvatars_.contains(userId)) {
|
||||
auto img = userAvatars_[userId];
|
||||
|
||||
item->setUserAvatar(img);
|
||||
item->setUserAvatar(img);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (avatarUrls_.contains(userId)) {
|
||||
// Add the current timeline item to the waiting list for this avatar.
|
||||
if (!toBeResolved_.contains(userId)) {
|
||||
client_->fetchUserAvatar(userId, avatarUrls_[userId]);
|
||||
if (avatarUrls_.contains(userId)) {
|
||||
// Add the current timeline item to the waiting list for this avatar.
|
||||
if (!toBeResolved_.contains(userId)) {
|
||||
client_->fetchUserAvatar(userId, avatarUrls_[userId]);
|
||||
|
||||
QList<TimelineItem *> timelineItems;
|
||||
timelineItems.push_back(item);
|
||||
QList<TimelineItem *> timelineItems;
|
||||
timelineItems.push_back(item);
|
||||
|
||||
toBeResolved_.insert(userId, timelineItems);
|
||||
} else {
|
||||
toBeResolved_[userId].push_back(item);
|
||||
}
|
||||
}
|
||||
toBeResolved_.insert(userId, timelineItems);
|
||||
} else {
|
||||
toBeResolved_[userId].push_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AvatarProvider::setAvatarUrl(const QString &userId, const QUrl &url)
|
||||
{
|
||||
avatarUrls_.insert(userId, url);
|
||||
avatarUrls_.insert(userId, url);
|
||||
}
|
||||
|
||||
void
|
||||
AvatarProvider::clear()
|
||||
{
|
||||
userAvatars_.clear();
|
||||
avatarUrls_.clear();
|
||||
toBeResolved_.clear();
|
||||
userAvatars_.clear();
|
||||
avatarUrls_.clear();
|
||||
toBeResolved_.clear();
|
||||
}
|
||||
|
|
|
@ -29,5 +29,5 @@ DeserializationException::DeserializationException(const std::string &msg)
|
|||
const char *
|
||||
DeserializationException::what() const noexcept
|
||||
{
|
||||
return msg_.c_str();
|
||||
return msg_.c_str();
|
||||
}
|
||||
|
|
|
@ -24,60 +24,60 @@
|
|||
EmojiCategory::EmojiCategory(QString category, QList<Emoji> emoji, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
mainLayout_ = new QVBoxLayout(this);
|
||||
mainLayout_->setMargin(0);
|
||||
mainLayout_ = new QVBoxLayout(this);
|
||||
mainLayout_->setMargin(0);
|
||||
|
||||
emojiListView_ = new QListView();
|
||||
itemModel_ = new QStandardItemModel(this);
|
||||
emojiListView_ = new QListView();
|
||||
itemModel_ = new QStandardItemModel(this);
|
||||
|
||||
delegate_ = new EmojiItemDelegate(this);
|
||||
data_ = new Emoji;
|
||||
delegate_ = new EmojiItemDelegate(this);
|
||||
data_ = new Emoji;
|
||||
|
||||
emojiListView_->setItemDelegate(delegate_);
|
||||
emojiListView_->setSpacing(5);
|
||||
emojiListView_->setModel(itemModel_);
|
||||
emojiListView_->setViewMode(QListView::IconMode);
|
||||
emojiListView_->setFlow(QListView::LeftToRight);
|
||||
emojiListView_->setResizeMode(QListView::Adjust);
|
||||
emojiListView_->verticalScrollBar()->setEnabled(false);
|
||||
emojiListView_->horizontalScrollBar()->setEnabled(false);
|
||||
emojiListView_->setItemDelegate(delegate_);
|
||||
emojiListView_->setSpacing(5);
|
||||
emojiListView_->setModel(itemModel_);
|
||||
emojiListView_->setViewMode(QListView::IconMode);
|
||||
emojiListView_->setFlow(QListView::LeftToRight);
|
||||
emojiListView_->setResizeMode(QListView::Adjust);
|
||||
emojiListView_->verticalScrollBar()->setEnabled(false);
|
||||
emojiListView_->horizontalScrollBar()->setEnabled(false);
|
||||
|
||||
const int cols = 7;
|
||||
const int rows = emoji.size() / 7;
|
||||
const int cols = 7;
|
||||
const int rows = emoji.size() / 7;
|
||||
|
||||
// TODO: Be precise here. Take the parent into consideration.
|
||||
emojiListView_->setFixedSize(cols * 50 + 20, rows * 50 + 20);
|
||||
emojiListView_->setGridSize(QSize(50, 50));
|
||||
emojiListView_->setDragEnabled(false);
|
||||
emojiListView_->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
// TODO: Be precise here. Take the parent into consideration.
|
||||
emojiListView_->setFixedSize(cols * 50 + 20, rows * 50 + 20);
|
||||
emojiListView_->setGridSize(QSize(50, 50));
|
||||
emojiListView_->setDragEnabled(false);
|
||||
emojiListView_->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
|
||||
for (const auto &e : emoji) {
|
||||
data_->unicode = e.unicode;
|
||||
for (const auto &e : emoji) {
|
||||
data_->unicode = e.unicode;
|
||||
|
||||
auto item = new QStandardItem;
|
||||
item->setSizeHint(QSize(24, 24));
|
||||
auto item = new QStandardItem;
|
||||
item->setSizeHint(QSize(24, 24));
|
||||
|
||||
QVariant unicode(data_->unicode);
|
||||
item->setData(unicode.toString(), Qt::UserRole);
|
||||
QVariant unicode(data_->unicode);
|
||||
item->setData(unicode.toString(), Qt::UserRole);
|
||||
|
||||
itemModel_->appendRow(item);
|
||||
}
|
||||
itemModel_->appendRow(item);
|
||||
}
|
||||
|
||||
QFont font("Open Sans SemiBold");
|
||||
font.setPixelSize(conf::fontSize);
|
||||
QFont font("Open Sans SemiBold");
|
||||
font.setPixelSize(conf::fontSize);
|
||||
|
||||
category_ = new QLabel(category, this);
|
||||
category_->setFont(font);
|
||||
category_->setStyleSheet("color: #ccc; margin: 20px 0px 15px 8px;");
|
||||
category_ = new QLabel(category, this);
|
||||
category_->setFont(font);
|
||||
category_->setStyleSheet("color: #ccc; margin: 20px 0px 15px 8px;");
|
||||
|
||||
auto labelLayout_ = new QHBoxLayout();
|
||||
labelLayout_->addWidget(category_);
|
||||
labelLayout_->addStretch(1);
|
||||
auto labelLayout_ = new QHBoxLayout();
|
||||
labelLayout_->addWidget(category_);
|
||||
labelLayout_->addStretch(1);
|
||||
|
||||
mainLayout_->addLayout(labelLayout_);
|
||||
mainLayout_->addWidget(emojiListView_);
|
||||
mainLayout_->addLayout(labelLayout_);
|
||||
mainLayout_->addWidget(emojiListView_);
|
||||
|
||||
connect(emojiListView_, &QListView::clicked, this, &EmojiCategory::clickIndex);
|
||||
connect(emojiListView_, &QListView::clicked, this, &EmojiCategory::clickIndex);
|
||||
}
|
||||
|
||||
EmojiCategory::~EmojiCategory()
|
||||
|
|
|
@ -23,26 +23,28 @@
|
|||
EmojiItemDelegate::EmojiItemDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
data_ = new Emoji;
|
||||
data_ = new Emoji;
|
||||
}
|
||||
|
||||
EmojiItemDelegate::~EmojiItemDelegate()
|
||||
{
|
||||
delete data_;
|
||||
delete data_;
|
||||
}
|
||||
|
||||
void
|
||||
EmojiItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
EmojiItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
Q_UNUSED(index);
|
||||
|
||||
QStyleOptionViewItem viewOption(option);
|
||||
QStyleOptionViewItem viewOption(option);
|
||||
|
||||
auto emoji = index.data(Qt::UserRole).toString();
|
||||
auto emoji = index.data(Qt::UserRole).toString();
|
||||
|
||||
QFont font("Emoji One");
|
||||
font.setPixelSize(19);
|
||||
QFont font("Emoji One");
|
||||
font.setPixelSize(19);
|
||||
|
||||
painter->setFont(font);
|
||||
painter->drawText(viewOption.rect, Qt::AlignCenter, emoji);
|
||||
painter->setFont(font);
|
||||
painter->drawText(viewOption.rect, Qt::AlignCenter, emoji);
|
||||
}
|
||||
|
|
|
@ -34,225 +34,238 @@ EmojiPanel::EmojiPanel(QWidget *parent)
|
|||
, animationDuration_{ 100 }
|
||||
, categoryIconSize_{ 20 }
|
||||
{
|
||||
setStyleSheet("QWidget {background: #f8fbfe; color: #e8e8e8; border: none;}"
|
||||
"QScrollBar:vertical { background-color: #f8fbfe; width: 8px; margin: 0px 2px 0 2px; }"
|
||||
"QScrollBar::handle:vertical { background-color: #d6dde3; min-height: 20px; }"
|
||||
"QScrollBar::add-line:vertical { border: none; background: none; }"
|
||||
"QScrollBar::sub-line:vertical { border: none; background: none; }");
|
||||
setStyleSheet(
|
||||
"QWidget {background: #f8fbfe; color: #e8e8e8; border: none;}"
|
||||
"QScrollBar:vertical { background-color: #f8fbfe; width: 8px; margin: 0px 2px 0 2px; }"
|
||||
"QScrollBar::handle:vertical { background-color: #d6dde3; min-height: 20px; }"
|
||||
"QScrollBar::add-line:vertical { border: none; background: none; }"
|
||||
"QScrollBar::sub-line:vertical { border: none; background: none; }");
|
||||
|
||||
setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
setAttribute(Qt::WA_ShowWithoutActivating, true);
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);
|
||||
setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
setAttribute(Qt::WA_ShowWithoutActivating, true);
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);
|
||||
|
||||
auto mainWidget = new QWidget(this);
|
||||
mainWidget->setMaximumSize(width_, height_);
|
||||
auto mainWidget = new QWidget(this);
|
||||
mainWidget->setMaximumSize(width_, height_);
|
||||
|
||||
auto topLayout = new QVBoxLayout(this);
|
||||
topLayout->addWidget(mainWidget);
|
||||
topLayout->setMargin(shadowMargin_);
|
||||
auto topLayout = new QVBoxLayout(this);
|
||||
topLayout->addWidget(mainWidget);
|
||||
topLayout->setMargin(shadowMargin_);
|
||||
|
||||
auto contentLayout = new QVBoxLayout(mainWidget);
|
||||
contentLayout->setMargin(0);
|
||||
auto contentLayout = new QVBoxLayout(mainWidget);
|
||||
contentLayout->setMargin(0);
|
||||
|
||||
auto emojiCategories = new QFrame(mainWidget);
|
||||
emojiCategories->setStyleSheet("background-color: #f2f2f2");
|
||||
auto emojiCategories = new QFrame(mainWidget);
|
||||
emojiCategories->setStyleSheet("background-color: #f2f2f2");
|
||||
|
||||
auto categoriesLayout = new QHBoxLayout(emojiCategories);
|
||||
categoriesLayout->setSpacing(6);
|
||||
categoriesLayout->setMargin(5);
|
||||
auto categoriesLayout = new QHBoxLayout(emojiCategories);
|
||||
categoriesLayout->setSpacing(6);
|
||||
categoriesLayout->setMargin(5);
|
||||
|
||||
auto peopleCategory = new FlatButton(emojiCategories);
|
||||
peopleCategory->setIcon(QIcon(":/icons/icons/emoji-categories/people.png"));
|
||||
peopleCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
peopleCategory->setForegroundColor("gray");
|
||||
auto peopleCategory = new FlatButton(emojiCategories);
|
||||
peopleCategory->setIcon(QIcon(":/icons/icons/emoji-categories/people.png"));
|
||||
peopleCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
peopleCategory->setForegroundColor("gray");
|
||||
|
||||
auto natureCategory_ = new FlatButton(emojiCategories);
|
||||
natureCategory_->setIcon(QIcon(":/icons/icons/emoji-categories/nature.png"));
|
||||
natureCategory_->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
natureCategory_->setForegroundColor("gray");
|
||||
auto natureCategory_ = new FlatButton(emojiCategories);
|
||||
natureCategory_->setIcon(QIcon(":/icons/icons/emoji-categories/nature.png"));
|
||||
natureCategory_->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
natureCategory_->setForegroundColor("gray");
|
||||
|
||||
auto foodCategory_ = new FlatButton(emojiCategories);
|
||||
foodCategory_->setIcon(QIcon(":/icons/icons/emoji-categories/foods.png"));
|
||||
foodCategory_->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
foodCategory_->setForegroundColor("gray");
|
||||
auto foodCategory_ = new FlatButton(emojiCategories);
|
||||
foodCategory_->setIcon(QIcon(":/icons/icons/emoji-categories/foods.png"));
|
||||
foodCategory_->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
foodCategory_->setForegroundColor("gray");
|
||||
|
||||
auto activityCategory = new FlatButton(emojiCategories);
|
||||
activityCategory->setIcon(QIcon(":/icons/icons/emoji-categories/activity.png"));
|
||||
activityCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
activityCategory->setForegroundColor("gray");
|
||||
auto activityCategory = new FlatButton(emojiCategories);
|
||||
activityCategory->setIcon(QIcon(":/icons/icons/emoji-categories/activity.png"));
|
||||
activityCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
activityCategory->setForegroundColor("gray");
|
||||
|
||||
auto travelCategory = new FlatButton(emojiCategories);
|
||||
travelCategory->setIcon(QIcon(":/icons/icons/emoji-categories/travel.png"));
|
||||
travelCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
travelCategory->setForegroundColor("gray");
|
||||
auto travelCategory = new FlatButton(emojiCategories);
|
||||
travelCategory->setIcon(QIcon(":/icons/icons/emoji-categories/travel.png"));
|
||||
travelCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
travelCategory->setForegroundColor("gray");
|
||||
|
||||
auto objectsCategory = new FlatButton(emojiCategories);
|
||||
objectsCategory->setIcon(QIcon(":/icons/icons/emoji-categories/objects.png"));
|
||||
objectsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
objectsCategory->setForegroundColor("gray");
|
||||
auto objectsCategory = new FlatButton(emojiCategories);
|
||||
objectsCategory->setIcon(QIcon(":/icons/icons/emoji-categories/objects.png"));
|
||||
objectsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
objectsCategory->setForegroundColor("gray");
|
||||
|
||||
auto symbolsCategory = new FlatButton(emojiCategories);
|
||||
symbolsCategory->setIcon(QIcon(":/icons/icons/emoji-categories/symbols.png"));
|
||||
symbolsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
symbolsCategory->setForegroundColor("gray");
|
||||
auto symbolsCategory = new FlatButton(emojiCategories);
|
||||
symbolsCategory->setIcon(QIcon(":/icons/icons/emoji-categories/symbols.png"));
|
||||
symbolsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
symbolsCategory->setForegroundColor("gray");
|
||||
|
||||
auto flagsCategory = new FlatButton(emojiCategories);
|
||||
flagsCategory->setIcon(QIcon(":/icons/icons/emoji-categories/flags.png"));
|
||||
flagsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
flagsCategory->setForegroundColor("gray");
|
||||
auto flagsCategory = new FlatButton(emojiCategories);
|
||||
flagsCategory->setIcon(QIcon(":/icons/icons/emoji-categories/flags.png"));
|
||||
flagsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
flagsCategory->setForegroundColor("gray");
|
||||
|
||||
categoriesLayout->addWidget(peopleCategory);
|
||||
categoriesLayout->addWidget(natureCategory_);
|
||||
categoriesLayout->addWidget(foodCategory_);
|
||||
categoriesLayout->addWidget(activityCategory);
|
||||
categoriesLayout->addWidget(travelCategory);
|
||||
categoriesLayout->addWidget(objectsCategory);
|
||||
categoriesLayout->addWidget(symbolsCategory);
|
||||
categoriesLayout->addWidget(flagsCategory);
|
||||
categoriesLayout->addWidget(peopleCategory);
|
||||
categoriesLayout->addWidget(natureCategory_);
|
||||
categoriesLayout->addWidget(foodCategory_);
|
||||
categoriesLayout->addWidget(activityCategory);
|
||||
categoriesLayout->addWidget(travelCategory);
|
||||
categoriesLayout->addWidget(objectsCategory);
|
||||
categoriesLayout->addWidget(symbolsCategory);
|
||||
categoriesLayout->addWidget(flagsCategory);
|
||||
|
||||
scrollArea_ = new QScrollArea(this);
|
||||
scrollArea_->setWidgetResizable(true);
|
||||
scrollArea_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
scrollArea_ = new QScrollArea(this);
|
||||
scrollArea_->setWidgetResizable(true);
|
||||
scrollArea_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
auto scrollWidget = new QWidget(this);
|
||||
auto scrollLayout = new QVBoxLayout(scrollWidget);
|
||||
auto scrollWidget = new QWidget(this);
|
||||
auto scrollLayout = new QVBoxLayout(scrollWidget);
|
||||
|
||||
scrollLayout->setMargin(0);
|
||||
scrollArea_->setWidget(scrollWidget);
|
||||
scrollLayout->setMargin(0);
|
||||
scrollArea_->setWidget(scrollWidget);
|
||||
|
||||
auto peopleEmoji = new EmojiCategory(tr("Smileys & People"), emoji_provider_.people, scrollWidget);
|
||||
scrollLayout->addWidget(peopleEmoji);
|
||||
auto peopleEmoji =
|
||||
new EmojiCategory(tr("Smileys & People"), emoji_provider_.people, scrollWidget);
|
||||
scrollLayout->addWidget(peopleEmoji);
|
||||
|
||||
auto natureEmoji = new EmojiCategory(tr("Animals & Nature"), emoji_provider_.nature, scrollWidget);
|
||||
scrollLayout->addWidget(natureEmoji);
|
||||
auto natureEmoji =
|
||||
new EmojiCategory(tr("Animals & Nature"), emoji_provider_.nature, scrollWidget);
|
||||
scrollLayout->addWidget(natureEmoji);
|
||||
|
||||
auto foodEmoji = new EmojiCategory(tr("Food & Drink"), emoji_provider_.food, scrollWidget);
|
||||
scrollLayout->addWidget(foodEmoji);
|
||||
auto foodEmoji = new EmojiCategory(tr("Food & Drink"), emoji_provider_.food, scrollWidget);
|
||||
scrollLayout->addWidget(foodEmoji);
|
||||
|
||||
auto activityEmoji = new EmojiCategory(tr("Activity"), emoji_provider_.activity, scrollWidget);
|
||||
scrollLayout->addWidget(activityEmoji);
|
||||
auto activityEmoji =
|
||||
new EmojiCategory(tr("Activity"), emoji_provider_.activity, scrollWidget);
|
||||
scrollLayout->addWidget(activityEmoji);
|
||||
|
||||
auto travelEmoji = new EmojiCategory(tr("Travel & Places"), emoji_provider_.travel, scrollWidget);
|
||||
scrollLayout->addWidget(travelEmoji);
|
||||
auto travelEmoji =
|
||||
new EmojiCategory(tr("Travel & Places"), emoji_provider_.travel, scrollWidget);
|
||||
scrollLayout->addWidget(travelEmoji);
|
||||
|
||||
auto objectsEmoji = new EmojiCategory(tr("Objects"), emoji_provider_.objects, scrollWidget);
|
||||
scrollLayout->addWidget(objectsEmoji);
|
||||
auto objectsEmoji = new EmojiCategory(tr("Objects"), emoji_provider_.objects, scrollWidget);
|
||||
scrollLayout->addWidget(objectsEmoji);
|
||||
|
||||
auto symbolsEmoji = new EmojiCategory(tr("Symbols"), emoji_provider_.symbols, scrollWidget);
|
||||
scrollLayout->addWidget(symbolsEmoji);
|
||||
auto symbolsEmoji = new EmojiCategory(tr("Symbols"), emoji_provider_.symbols, scrollWidget);
|
||||
scrollLayout->addWidget(symbolsEmoji);
|
||||
|
||||
auto flagsEmoji = new EmojiCategory(tr("Flags"), emoji_provider_.flags, scrollWidget);
|
||||
scrollLayout->addWidget(flagsEmoji);
|
||||
auto flagsEmoji = new EmojiCategory(tr("Flags"), emoji_provider_.flags, scrollWidget);
|
||||
scrollLayout->addWidget(flagsEmoji);
|
||||
|
||||
contentLayout->addStretch(1);
|
||||
contentLayout->addWidget(scrollArea_);
|
||||
contentLayout->addWidget(emojiCategories);
|
||||
contentLayout->addStretch(1);
|
||||
contentLayout->addWidget(scrollArea_);
|
||||
contentLayout->addWidget(emojiCategories);
|
||||
|
||||
opacity_ = new QGraphicsOpacityEffect(this);
|
||||
opacity_->setOpacity(1.0);
|
||||
opacity_ = new QGraphicsOpacityEffect(this);
|
||||
opacity_->setOpacity(1.0);
|
||||
|
||||
setGraphicsEffect(opacity_);
|
||||
setGraphicsEffect(opacity_);
|
||||
|
||||
animation_ = new QPropertyAnimation(opacity_, "opacity", this);
|
||||
animation_->setDuration(animationDuration_);
|
||||
animation_->setStartValue(1);
|
||||
animation_->setEndValue(0);
|
||||
animation_ = new QPropertyAnimation(opacity_, "opacity", this);
|
||||
animation_->setDuration(animationDuration_);
|
||||
animation_->setStartValue(1);
|
||||
animation_->setEndValue(0);
|
||||
|
||||
connect(peopleEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(peopleCategory, &QPushButton::clicked, [this, peopleEmoji]() { this->showEmojiCategory(peopleEmoji); });
|
||||
connect(peopleEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(peopleCategory, &QPushButton::clicked, [this, peopleEmoji]() {
|
||||
this->showEmojiCategory(peopleEmoji);
|
||||
});
|
||||
|
||||
connect(natureEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(natureCategory_, &QPushButton::clicked, [this, natureEmoji]() {
|
||||
this->showEmojiCategory(natureEmoji);
|
||||
});
|
||||
connect(natureEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(natureCategory_, &QPushButton::clicked, [this, natureEmoji]() {
|
||||
this->showEmojiCategory(natureEmoji);
|
||||
});
|
||||
|
||||
connect(foodEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(foodCategory_, &QPushButton::clicked, [this, foodEmoji]() { this->showEmojiCategory(foodEmoji); });
|
||||
connect(foodEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(foodCategory_, &QPushButton::clicked, [this, foodEmoji]() {
|
||||
this->showEmojiCategory(foodEmoji);
|
||||
});
|
||||
|
||||
connect(activityEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(activityCategory, &QPushButton::clicked, [this, activityEmoji]() {
|
||||
this->showEmojiCategory(activityEmoji);
|
||||
});
|
||||
connect(activityEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(activityCategory, &QPushButton::clicked, [this, activityEmoji]() {
|
||||
this->showEmojiCategory(activityEmoji);
|
||||
});
|
||||
|
||||
connect(travelEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(travelCategory, &QPushButton::clicked, [this, travelEmoji]() { this->showEmojiCategory(travelEmoji); });
|
||||
connect(travelEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(travelCategory, &QPushButton::clicked, [this, travelEmoji]() {
|
||||
this->showEmojiCategory(travelEmoji);
|
||||
});
|
||||
|
||||
connect(objectsEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(objectsCategory, &QPushButton::clicked, [this, objectsEmoji]() {
|
||||
this->showEmojiCategory(objectsEmoji);
|
||||
});
|
||||
connect(objectsEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(objectsCategory, &QPushButton::clicked, [this, objectsEmoji]() {
|
||||
this->showEmojiCategory(objectsEmoji);
|
||||
});
|
||||
|
||||
connect(symbolsEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(symbolsCategory, &QPushButton::clicked, [this, symbolsEmoji]() {
|
||||
this->showEmojiCategory(symbolsEmoji);
|
||||
});
|
||||
connect(symbolsEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(symbolsCategory, &QPushButton::clicked, [this, symbolsEmoji]() {
|
||||
this->showEmojiCategory(symbolsEmoji);
|
||||
});
|
||||
|
||||
connect(flagsEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(flagsCategory, &QPushButton::clicked, [this, flagsEmoji]() { this->showEmojiCategory(flagsEmoji); });
|
||||
connect(flagsEmoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||
connect(flagsCategory, &QPushButton::clicked, [this, flagsEmoji]() {
|
||||
this->showEmojiCategory(flagsEmoji);
|
||||
});
|
||||
|
||||
connect(animation_, &QAbstractAnimation::finished, [this]() {
|
||||
if (animation_->direction() == QAbstractAnimation::Forward)
|
||||
this->hide();
|
||||
});
|
||||
connect(animation_, &QAbstractAnimation::finished, [this]() {
|
||||
if (animation_->direction() == QAbstractAnimation::Forward)
|
||||
this->hide();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
EmojiPanel::showEmojiCategory(const EmojiCategory *category)
|
||||
{
|
||||
auto posToGo = category->mapToParent(QPoint()).y();
|
||||
auto current = scrollArea_->verticalScrollBar()->value();
|
||||
auto posToGo = category->mapToParent(QPoint()).y();
|
||||
auto current = scrollArea_->verticalScrollBar()->value();
|
||||
|
||||
if (current == posToGo)
|
||||
return;
|
||||
if (current == posToGo)
|
||||
return;
|
||||
|
||||
// HACK
|
||||
// If we want to go to a previous category and position the label at the top
|
||||
// the 6*50 offset won't work because not all the categories have the same height.
|
||||
// To ensure the category is at the top, we move to the top
|
||||
// and go as normal to the next category.
|
||||
if (current > posToGo)
|
||||
this->scrollArea_->ensureVisible(0, 0, 0, 0);
|
||||
// HACK
|
||||
// If we want to go to a previous category and position the label at the top
|
||||
// the 6*50 offset won't work because not all the categories have the same height.
|
||||
// To ensure the category is at the top, we move to the top
|
||||
// and go as normal to the next category.
|
||||
if (current > posToGo)
|
||||
this->scrollArea_->ensureVisible(0, 0, 0, 0);
|
||||
|
||||
posToGo += 6 * 50;
|
||||
this->scrollArea_->ensureVisible(0, posToGo, 0, 0);
|
||||
posToGo += 6 * 50;
|
||||
this->scrollArea_->ensureVisible(0, posToGo, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
EmojiPanel::leaveEvent(QEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(event);
|
||||
|
||||
fadeOut();
|
||||
fadeOut();
|
||||
}
|
||||
|
||||
void
|
||||
EmojiPanel::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter p(this);
|
||||
DropShadow::draw(p,
|
||||
shadowMargin_,
|
||||
4.0,
|
||||
QColor(120, 120, 120, 92),
|
||||
QColor(255, 255, 255, 0),
|
||||
0.0,
|
||||
1.0,
|
||||
0.6,
|
||||
width(),
|
||||
height());
|
||||
QPainter p(this);
|
||||
DropShadow::draw(p,
|
||||
shadowMargin_,
|
||||
4.0,
|
||||
QColor(120, 120, 120, 92),
|
||||
QColor(255, 255, 255, 0),
|
||||
0.0,
|
||||
1.0,
|
||||
0.6,
|
||||
width(),
|
||||
height());
|
||||
|
||||
QWidget::paintEvent(event);
|
||||
QWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
void
|
||||
EmojiPanel::fadeOut()
|
||||
{
|
||||
animation_->setDirection(QAbstractAnimation::Forward);
|
||||
animation_->start();
|
||||
animation_->setDirection(QAbstractAnimation::Forward);
|
||||
animation_->start();
|
||||
}
|
||||
|
||||
void
|
||||
EmojiPanel::fadeIn()
|
||||
{
|
||||
animation_->setDirection(QAbstractAnimation::Backward);
|
||||
animation_->start();
|
||||
animation_->setDirection(QAbstractAnimation::Backward);
|
||||
animation_->start();
|
||||
}
|
||||
|
|
|
@ -28,40 +28,40 @@ EmojiPickButton::EmojiPickButton(QWidget *parent)
|
|||
void
|
||||
EmojiPickButton::enterEvent(QEvent *e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
Q_UNUSED(e);
|
||||
|
||||
if (panel_ == nullptr) {
|
||||
panel_ = new EmojiPanel(this);
|
||||
connect(panel_, &EmojiPanel::emojiSelected, this, &EmojiPickButton::emojiSelected);
|
||||
}
|
||||
if (panel_ == nullptr) {
|
||||
panel_ = new EmojiPanel(this);
|
||||
connect(panel_, &EmojiPanel::emojiSelected, this, &EmojiPickButton::emojiSelected);
|
||||
}
|
||||
|
||||
QPoint pos(rect().x(), rect().y());
|
||||
pos = this->mapToGlobal(pos);
|
||||
QPoint pos(rect().x(), rect().y());
|
||||
pos = this->mapToGlobal(pos);
|
||||
|
||||
auto panel_size = panel_->sizeHint();
|
||||
auto panel_size = panel_->sizeHint();
|
||||
|
||||
auto x = pos.x() - panel_size.width() + horizontal_distance_;
|
||||
auto y = pos.y() - panel_size.height() - vertical_distance_;
|
||||
auto x = pos.x() - panel_size.width() + horizontal_distance_;
|
||||
auto y = pos.y() - panel_size.height() - vertical_distance_;
|
||||
|
||||
panel_->move(x, y);
|
||||
panel_->fadeIn();
|
||||
panel_->show();
|
||||
panel_->move(x, y);
|
||||
panel_->fadeIn();
|
||||
panel_->show();
|
||||
}
|
||||
|
||||
void
|
||||
EmojiPickButton::leaveEvent(QEvent *e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
Q_UNUSED(e);
|
||||
|
||||
if (panel_->underMouse())
|
||||
return;
|
||||
if (panel_->underMouse())
|
||||
return;
|
||||
|
||||
auto pos = QCursor::pos();
|
||||
auto panel_geometry = panel_->geometry();
|
||||
panel_geometry.adjust(0, 0, 0, vertical_distance_);
|
||||
auto pos = QCursor::pos();
|
||||
auto panel_geometry = panel_->geometry();
|
||||
panel_geometry.adjust(0, 0, 0, vertical_distance_);
|
||||
|
||||
if (panel_geometry.contains(pos))
|
||||
return;
|
||||
if (panel_geometry.contains(pos))
|
||||
return;
|
||||
|
||||
panel_->fadeOut();
|
||||
panel_->fadeOut();
|
||||
}
|
||||
|
|
2847
src/EmojiProvider.cc
2847
src/EmojiProvider.cc
File diff suppressed because it is too large
Load diff
182
src/ImageItem.cc
182
src/ImageItem.cc
|
@ -26,169 +26,171 @@
|
|||
#include "ImageOverlayDialog.h"
|
||||
|
||||
namespace events = matrix::events;
|
||||
namespace msgs = matrix::events::messages;
|
||||
namespace msgs = matrix::events::messages;
|
||||
|
||||
ImageItem::ImageItem(QSharedPointer<MatrixClient> client,
|
||||
const events::MessageEvent<msgs::Image> &event,
|
||||
QWidget *parent)
|
||||
const events::MessageEvent<msgs::Image> &event,
|
||||
QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, event_{ event }
|
||||
, client_{ client }
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setAttribute(Qt::WA_Hover, true);
|
||||
setMouseTracking(true);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setAttribute(Qt::WA_Hover, true);
|
||||
|
||||
url_ = event.msgContent().url();
|
||||
text_ = event.content().body();
|
||||
url_ = event.msgContent().url();
|
||||
text_ = event.content().body();
|
||||
|
||||
QList<QString> url_parts = url_.toString().split("mxc://");
|
||||
QList<QString> url_parts = url_.toString().split("mxc://");
|
||||
|
||||
if (url_parts.size() != 2) {
|
||||
qDebug() << "Invalid format for image" << url_.toString();
|
||||
return;
|
||||
}
|
||||
if (url_parts.size() != 2) {
|
||||
qDebug() << "Invalid format for image" << url_.toString();
|
||||
return;
|
||||
}
|
||||
|
||||
QString media_params = url_parts[1];
|
||||
url_ = QString("%1/_matrix/media/r0/download/%2").arg(client_.data()->getHomeServer().toString(), media_params);
|
||||
QString media_params = url_parts[1];
|
||||
url_ = QString("%1/_matrix/media/r0/download/%2")
|
||||
.arg(client_.data()->getHomeServer().toString(), media_params);
|
||||
|
||||
client_.data()->downloadImage(event.eventId(), url_);
|
||||
client_.data()->downloadImage(event.eventId(), url_);
|
||||
|
||||
connect(client_.data(),
|
||||
SIGNAL(imageDownloaded(const QString &, const QPixmap &)),
|
||||
this,
|
||||
SLOT(imageDownloaded(const QString &, const QPixmap &)));
|
||||
connect(client_.data(),
|
||||
SIGNAL(imageDownloaded(const QString &, const QPixmap &)),
|
||||
this,
|
||||
SLOT(imageDownloaded(const QString &, const QPixmap &)));
|
||||
}
|
||||
|
||||
void
|
||||
ImageItem::imageDownloaded(const QString &event_id, const QPixmap &img)
|
||||
{
|
||||
if (event_id != event_.eventId())
|
||||
return;
|
||||
if (event_id != event_.eventId())
|
||||
return;
|
||||
|
||||
setImage(img);
|
||||
setImage(img);
|
||||
}
|
||||
|
||||
void
|
||||
ImageItem::openUrl()
|
||||
{
|
||||
if (url_.toString().isEmpty())
|
||||
return;
|
||||
if (url_.toString().isEmpty())
|
||||
return;
|
||||
|
||||
if (!QDesktopServices::openUrl(url_))
|
||||
qWarning() << "Could not open url" << url_.toString();
|
||||
if (!QDesktopServices::openUrl(url_))
|
||||
qWarning() << "Could not open url" << url_.toString();
|
||||
}
|
||||
|
||||
void
|
||||
ImageItem::scaleImage()
|
||||
{
|
||||
if (image_.isNull())
|
||||
return;
|
||||
if (image_.isNull())
|
||||
return;
|
||||
|
||||
auto width_ratio = (double)max_width_ / (double)image_.width();
|
||||
auto height_ratio = (double)max_height_ / (double)image_.height();
|
||||
auto width_ratio = (double)max_width_ / (double)image_.width();
|
||||
auto height_ratio = (double)max_height_ / (double)image_.height();
|
||||
|
||||
auto min_aspect_ratio = std::min(width_ratio, height_ratio);
|
||||
auto min_aspect_ratio = std::min(width_ratio, height_ratio);
|
||||
|
||||
if (min_aspect_ratio > 1) {
|
||||
width_ = image_.width();
|
||||
height_ = image_.height();
|
||||
} else {
|
||||
width_ = image_.width() * min_aspect_ratio;
|
||||
height_ = image_.height() * min_aspect_ratio;
|
||||
}
|
||||
if (min_aspect_ratio > 1) {
|
||||
width_ = image_.width();
|
||||
height_ = image_.height();
|
||||
} else {
|
||||
width_ = image_.width() * min_aspect_ratio;
|
||||
height_ = image_.height() * min_aspect_ratio;
|
||||
}
|
||||
|
||||
setFixedSize(width_, height_);
|
||||
scaled_image_ = image_.scaled(width_, height_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
setFixedSize(width_, height_);
|
||||
scaled_image_ =
|
||||
image_.scaled(width_, height_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
QSize
|
||||
ImageItem::sizeHint() const
|
||||
{
|
||||
if (image_.isNull())
|
||||
return QSize(max_width_, bottom_height_);
|
||||
if (image_.isNull())
|
||||
return QSize(max_width_, bottom_height_);
|
||||
|
||||
return QSize(width_, height_);
|
||||
return QSize(width_, height_);
|
||||
}
|
||||
|
||||
void
|
||||
ImageItem::setImage(const QPixmap &image)
|
||||
{
|
||||
image_ = image;
|
||||
scaleImage();
|
||||
update();
|
||||
image_ = image;
|
||||
scaleImage();
|
||||
update();
|
||||
}
|
||||
|
||||
void
|
||||
ImageItem::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return;
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
if (image_.isNull()) {
|
||||
openUrl();
|
||||
return;
|
||||
}
|
||||
if (image_.isNull()) {
|
||||
openUrl();
|
||||
return;
|
||||
}
|
||||
|
||||
auto point = event->pos();
|
||||
auto point = event->pos();
|
||||
|
||||
// Click on the text box.
|
||||
if (QRect(0, height_ - bottom_height_, width_, bottom_height_).contains(point)) {
|
||||
openUrl();
|
||||
} else {
|
||||
auto image_dialog = new ImageOverlayDialog(image_, this);
|
||||
image_dialog->show();
|
||||
}
|
||||
// Click on the text box.
|
||||
if (QRect(0, height_ - bottom_height_, width_, bottom_height_).contains(point)) {
|
||||
openUrl();
|
||||
} else {
|
||||
auto image_dialog = new ImageOverlayDialog(image_, this);
|
||||
image_dialog->show();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageItem::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(event);
|
||||
|
||||
scaleImage();
|
||||
scaleImage();
|
||||
}
|
||||
|
||||
void
|
||||
ImageItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(event);
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QFont font("Open Sans");
|
||||
font.setPixelSize(12);
|
||||
QFont font("Open Sans");
|
||||
font.setPixelSize(12);
|
||||
|
||||
QFontMetrics metrics(font);
|
||||
int fontHeight = metrics.height();
|
||||
QFontMetrics metrics(font);
|
||||
int fontHeight = metrics.height();
|
||||
|
||||
if (image_.isNull()) {
|
||||
int height = fontHeight + 10;
|
||||
if (image_.isNull()) {
|
||||
int height = fontHeight + 10;
|
||||
|
||||
QString elidedText = metrics.elidedText(text_, Qt::ElideRight, max_width_ - 10);
|
||||
QString elidedText = metrics.elidedText(text_, Qt::ElideRight, max_width_ - 10);
|
||||
|
||||
setFixedSize(metrics.width(elidedText), fontHeight + 10);
|
||||
setFixedSize(metrics.width(elidedText), fontHeight + 10);
|
||||
|
||||
painter.setFont(font);
|
||||
painter.setPen(QPen(QColor(66, 133, 244)));
|
||||
painter.drawText(QPoint(0, height / 2 + 2), elidedText);
|
||||
painter.setFont(font);
|
||||
painter.setPen(QPen(QColor(66, 133, 244)));
|
||||
painter.drawText(QPoint(0, height / 2 + 2), elidedText);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
painter.fillRect(QRect(0, 0, width_, height_), scaled_image_);
|
||||
painter.fillRect(QRect(0, 0, width_, height_), scaled_image_);
|
||||
|
||||
if (underMouse()) {
|
||||
// Bottom text section
|
||||
painter.fillRect(QRect(0, height_ - bottom_height_, width_, bottom_height_),
|
||||
QBrush(QColor(33, 33, 33, 128)));
|
||||
if (underMouse()) {
|
||||
// Bottom text section
|
||||
painter.fillRect(QRect(0, height_ - bottom_height_, width_, bottom_height_),
|
||||
QBrush(QColor(33, 33, 33, 128)));
|
||||
|
||||
QString elidedText = metrics.elidedText(text_, Qt::ElideRight, width_ - 10);
|
||||
QString elidedText = metrics.elidedText(text_, Qt::ElideRight, width_ - 10);
|
||||
|
||||
font.setWeight(500);
|
||||
painter.setFont(font);
|
||||
painter.setPen(QPen(QColor("white")));
|
||||
painter.drawText(QPoint(5, height_ - fontHeight / 2), elidedText);
|
||||
}
|
||||
font.setWeight(500);
|
||||
painter.setFont(font);
|
||||
painter.setPen(QPen(QColor("white")));
|
||||
painter.drawText(QPoint(5, height_ - fontHeight / 2), elidedText);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,103 +28,105 @@ ImageOverlayDialog::ImageOverlayDialog(QPixmap image, QWidget *parent)
|
|||
: QWidget{ parent }
|
||||
, originalImage_{ image }
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setParent(0);
|
||||
setMouseTracking(true);
|
||||
setParent(0);
|
||||
|
||||
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||
|
||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
setWindowState(Qt::WindowFullScreen);
|
||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
setWindowState(Qt::WindowFullScreen);
|
||||
|
||||
screen_ = QApplication::desktop()->availableGeometry();
|
||||
screen_ = QApplication::desktop()->availableGeometry();
|
||||
|
||||
move(QApplication::desktop()->mapToGlobal(screen_.topLeft()));
|
||||
resize(screen_.size());
|
||||
move(QApplication::desktop()->mapToGlobal(screen_.topLeft()));
|
||||
resize(screen_.size());
|
||||
|
||||
connect(this, SIGNAL(closing()), this, SLOT(close()));
|
||||
connect(this, SIGNAL(closing()), this, SLOT(close()));
|
||||
|
||||
raise();
|
||||
raise();
|
||||
}
|
||||
|
||||
// TODO: Move this into Utils
|
||||
void
|
||||
ImageOverlayDialog::scaleImage(int max_width, int max_height)
|
||||
{
|
||||
if (originalImage_.isNull())
|
||||
return;
|
||||
if (originalImage_.isNull())
|
||||
return;
|
||||
|
||||
auto width_ratio = (double)max_width / (double)originalImage_.width();
|
||||
auto height_ratio = (double)max_height / (double)originalImage_.height();
|
||||
auto width_ratio = (double)max_width / (double)originalImage_.width();
|
||||
auto height_ratio = (double)max_height / (double)originalImage_.height();
|
||||
|
||||
auto min_aspect_ratio = std::min(width_ratio, height_ratio);
|
||||
auto min_aspect_ratio = std::min(width_ratio, height_ratio);
|
||||
|
||||
int final_width = 0;
|
||||
int final_height = 0;
|
||||
int final_width = 0;
|
||||
int final_height = 0;
|
||||
|
||||
if (min_aspect_ratio > 1) {
|
||||
final_width = originalImage_.width();
|
||||
final_height = originalImage_.height();
|
||||
} else {
|
||||
final_width = originalImage_.width() * min_aspect_ratio;
|
||||
final_height = originalImage_.height() * min_aspect_ratio;
|
||||
}
|
||||
if (min_aspect_ratio > 1) {
|
||||
final_width = originalImage_.width();
|
||||
final_height = originalImage_.height();
|
||||
} else {
|
||||
final_width = originalImage_.width() * min_aspect_ratio;
|
||||
final_height = originalImage_.height() * min_aspect_ratio;
|
||||
}
|
||||
|
||||
image_ = originalImage_.scaled(final_width, final_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
image_ = originalImage_.scaled(
|
||||
final_width, final_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
void
|
||||
ImageOverlayDialog::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(event);
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
// Full screen overlay.
|
||||
painter.fillRect(QRect(0, 0, screen_.width(), screen_.height()), QColor(55, 55, 55, 170));
|
||||
// Full screen overlay.
|
||||
painter.fillRect(QRect(0, 0, screen_.width(), screen_.height()), QColor(55, 55, 55, 170));
|
||||
|
||||
// Left and Right margins
|
||||
int outer_margin = screen_.width() * 0.12;
|
||||
int buttonSize = 36;
|
||||
int margin = outer_margin * 0.1;
|
||||
// Left and Right margins
|
||||
int outer_margin = screen_.width() * 0.12;
|
||||
int buttonSize = 36;
|
||||
int margin = outer_margin * 0.1;
|
||||
|
||||
int max_width = screen_.width() - 2 * outer_margin;
|
||||
int max_height = screen_.height();
|
||||
int max_width = screen_.width() - 2 * outer_margin;
|
||||
int max_height = screen_.height();
|
||||
|
||||
scaleImage(max_width, max_height);
|
||||
scaleImage(max_width, max_height);
|
||||
|
||||
int diff_x = max_width - image_.width();
|
||||
int diff_y = max_height - image_.height();
|
||||
int diff_x = max_width - image_.width();
|
||||
int diff_y = max_height - image_.height();
|
||||
|
||||
content_ = QRect(outer_margin + diff_x / 2, diff_y / 2, image_.width(), image_.height());
|
||||
close_button_ = QRect(screen_.width() - margin - buttonSize, margin, buttonSize, buttonSize);
|
||||
content_ = QRect(outer_margin + diff_x / 2, diff_y / 2, image_.width(), image_.height());
|
||||
close_button_ =
|
||||
QRect(screen_.width() - margin - buttonSize, margin, buttonSize, buttonSize);
|
||||
|
||||
// Draw main content_.
|
||||
painter.drawPixmap(content_, image_);
|
||||
// Draw main content_.
|
||||
painter.drawPixmap(content_, image_);
|
||||
|
||||
// Draw top right corner X.
|
||||
QPen pen;
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
pen.setWidthF(5);
|
||||
pen.setColor("gray");
|
||||
// Draw top right corner X.
|
||||
QPen pen;
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
pen.setWidthF(5);
|
||||
pen.setColor("gray");
|
||||
|
||||
auto center = close_button_.center();
|
||||
auto center = close_button_.center();
|
||||
|
||||
painter.setPen(pen);
|
||||
painter.drawLine(center - QPointF(15, 15), center + QPointF(15, 15));
|
||||
painter.drawLine(center + QPointF(15, -15), center - QPointF(15, -15));
|
||||
painter.setPen(pen);
|
||||
painter.drawLine(center - QPointF(15, 15), center + QPointF(15, 15));
|
||||
painter.drawLine(center + QPointF(15, -15), center - QPointF(15, -15));
|
||||
}
|
||||
|
||||
void
|
||||
ImageOverlayDialog::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return;
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
if (close_button_.contains(event->pos()))
|
||||
emit closing();
|
||||
else if (!content_.contains(event->pos()))
|
||||
emit closing();
|
||||
if (close_button_.contains(event->pos()))
|
||||
emit closing();
|
||||
else if (!content_.contains(event->pos()))
|
||||
emit closing();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
const QRegExp MXID_REGEX("@[A-Za-z0-9._%+-]+:[A-Za-z0-9.-]{1,126}\\.[A-Za-z]{1,63}");
|
||||
const QRegExp LOCALPART_REGEX("[A-za-z0-9._%+-]{3,}");
|
||||
const QRegExp PASSWORD_REGEX(".{8,}");
|
||||
const QRegExp DOMAIN_REGEX("(?!\\-)(?:[a-zA-Z\\d\\-]{0,62}[a-zA-Z\\d]\\.){1,126}(?!\\d+)[a-zA-Z\\d]{1,63}");
|
||||
const QRegExp DOMAIN_REGEX(
|
||||
"(?!\\-)(?:[a-zA-Z\\d\\-]{0,62}[a-zA-Z\\d]\\.){1,126}(?!\\d+)[a-zA-Z\\d]{1,63}");
|
||||
|
||||
QRegExpValidator InputValidator::Id(MXID_REGEX);
|
||||
QRegExpValidator InputValidator::Localpart(LOCALPART_REGEX);
|
||||
|
|
46
src/Login.cc
46
src/Login.cc
|
@ -36,43 +36,43 @@ QByteArray
|
|||
LoginRequest::serialize() noexcept
|
||||
{
|
||||
#if defined(Q_OS_MAC)
|
||||
QString initialDeviceName("nheko on Mac OS");
|
||||
QString initialDeviceName("nheko on Mac OS");
|
||||
#elif defined(Q_OS_LINUX)
|
||||
QString initialDeviceName("nheko on Linux");
|
||||
QString initialDeviceName("nheko on Linux");
|
||||
#elif defined(Q_OS_WIN)
|
||||
QString initialDeviceName("nheko on Windows");
|
||||
QString initialDeviceName("nheko on Windows");
|
||||
#else
|
||||
QString initialDeviceName("nheko");
|
||||
QString initialDeviceName("nheko");
|
||||
#endif
|
||||
|
||||
QJsonObject body{
|
||||
{ "type", "m.login.password" },
|
||||
{ "user", user_ },
|
||||
{ "password", password_ },
|
||||
{ "initial_device_display_name", initialDeviceName },
|
||||
};
|
||||
QJsonObject body{
|
||||
{ "type", "m.login.password" },
|
||||
{ "user", user_ },
|
||||
{ "password", password_ },
|
||||
{ "initial_device_display_name", initialDeviceName },
|
||||
};
|
||||
|
||||
return QJsonDocument(body).toJson(QJsonDocument::Compact);
|
||||
return QJsonDocument(body).toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
void
|
||||
LoginResponse::deserialize(const QJsonDocument &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Login response is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Login response is not a JSON object");
|
||||
|
||||
QJsonObject object = data.object();
|
||||
QJsonObject object = data.object();
|
||||
|
||||
if (object.value("access_token") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Login: missing access_token param");
|
||||
if (object.value("access_token") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Login: missing access_token param");
|
||||
|
||||
if (object.value("home_server") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Login: missing home_server param");
|
||||
if (object.value("home_server") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Login: missing home_server param");
|
||||
|
||||
if (object.value("user_id") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Login: missing user_id param");
|
||||
if (object.value("user_id") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Login: missing user_id param");
|
||||
|
||||
access_token_ = object.value("access_token").toString();
|
||||
home_server_ = object.value("home_server").toString();
|
||||
user_id_ = object.value("user_id").toString();
|
||||
access_token_ = object.value("access_token").toString();
|
||||
home_server_ = object.value("home_server").toString();
|
||||
user_id_ = object.value("user_id").toString();
|
||||
}
|
||||
|
|
369
src/LoginPage.cc
369
src/LoginPage.cc
|
@ -26,274 +26,275 @@ LoginPage::LoginPage(QSharedPointer<MatrixClient> client, QWidget *parent)
|
|||
, inferredServerAddress_()
|
||||
, client_{ client }
|
||||
{
|
||||
setStyleSheet("background-color: #f9f9f9");
|
||||
setStyleSheet("background-color: #f9f9f9");
|
||||
|
||||
top_layout_ = new QVBoxLayout();
|
||||
top_layout_ = new QVBoxLayout();
|
||||
|
||||
top_bar_layout_ = new QHBoxLayout();
|
||||
top_bar_layout_->setSpacing(0);
|
||||
top_bar_layout_->setMargin(0);
|
||||
top_bar_layout_ = new QHBoxLayout();
|
||||
top_bar_layout_->setSpacing(0);
|
||||
top_bar_layout_->setMargin(0);
|
||||
|
||||
back_button_ = new FlatButton(this);
|
||||
back_button_->setMinimumSize(QSize(30, 30));
|
||||
back_button_->setForegroundColor("#333333");
|
||||
back_button_ = new FlatButton(this);
|
||||
back_button_->setMinimumSize(QSize(30, 30));
|
||||
back_button_->setForegroundColor("#333333");
|
||||
|
||||
top_bar_layout_->addWidget(back_button_, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
top_bar_layout_->addStretch(1);
|
||||
top_bar_layout_->addWidget(back_button_, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
top_bar_layout_->addStretch(1);
|
||||
|
||||
QIcon icon;
|
||||
icon.addFile(":/icons/icons/left-angle.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
QIcon icon;
|
||||
icon.addFile(":/icons/icons/left-angle.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
|
||||
back_button_->setIcon(icon);
|
||||
back_button_->setIconSize(QSize(24, 24));
|
||||
back_button_->setIcon(icon);
|
||||
back_button_->setIconSize(QSize(24, 24));
|
||||
|
||||
QIcon advanced_settings_icon;
|
||||
advanced_settings_icon.addFile(":/icons/icons/cog.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
QIcon advanced_settings_icon;
|
||||
advanced_settings_icon.addFile(":/icons/icons/cog.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
|
||||
logo_ = new QLabel(this);
|
||||
logo_->setPixmap(QPixmap(":/logos/nheko-128.png"));
|
||||
logo_ = new QLabel(this);
|
||||
logo_->setPixmap(QPixmap(":/logos/nheko-128.png"));
|
||||
|
||||
logo_layout_ = new QHBoxLayout();
|
||||
logo_layout_->setContentsMargins(0, 0, 0, 20);
|
||||
logo_layout_->addWidget(logo_, 0, Qt::AlignHCenter);
|
||||
logo_layout_ = new QHBoxLayout();
|
||||
logo_layout_->setContentsMargins(0, 0, 0, 20);
|
||||
logo_layout_->addWidget(logo_, 0, Qt::AlignHCenter);
|
||||
|
||||
form_wrapper_ = new QHBoxLayout();
|
||||
form_widget_ = new QWidget();
|
||||
form_widget_->setMinimumSize(QSize(350, 200));
|
||||
form_wrapper_ = new QHBoxLayout();
|
||||
form_widget_ = new QWidget();
|
||||
form_widget_->setMinimumSize(QSize(350, 200));
|
||||
|
||||
form_layout_ = new QVBoxLayout();
|
||||
form_layout_->setSpacing(20);
|
||||
form_layout_->setContentsMargins(0, 0, 0, 30);
|
||||
form_widget_->setLayout(form_layout_);
|
||||
form_layout_ = new QVBoxLayout();
|
||||
form_layout_->setSpacing(20);
|
||||
form_layout_->setContentsMargins(0, 0, 0, 30);
|
||||
form_widget_->setLayout(form_layout_);
|
||||
|
||||
form_wrapper_->addStretch(1);
|
||||
form_wrapper_->addWidget(form_widget_);
|
||||
form_wrapper_->addStretch(1);
|
||||
form_wrapper_->addStretch(1);
|
||||
form_wrapper_->addWidget(form_widget_);
|
||||
form_wrapper_->addStretch(1);
|
||||
|
||||
matrixid_input_ = new TextField(this);
|
||||
matrixid_input_->setTextColor("#333333");
|
||||
matrixid_input_->setLabel(tr("Matrix ID"));
|
||||
matrixid_input_->setInkColor("#555459");
|
||||
matrixid_input_->setBackgroundColor("#f9f9f9");
|
||||
matrixid_input_->setPlaceholderText(tr("e.g @joe:matrix.org"));
|
||||
matrixid_input_ = new TextField(this);
|
||||
matrixid_input_->setTextColor("#333333");
|
||||
matrixid_input_->setLabel(tr("Matrix ID"));
|
||||
matrixid_input_->setInkColor("#555459");
|
||||
matrixid_input_->setBackgroundColor("#f9f9f9");
|
||||
matrixid_input_->setPlaceholderText(tr("e.g @joe:matrix.org"));
|
||||
|
||||
spinner_ = new CircularProgress(this);
|
||||
spinner_->setColor("#acc7dc");
|
||||
spinner_->setSize(32);
|
||||
spinner_->setMaximumWidth(spinner_->width());
|
||||
spinner_->hide();
|
||||
spinner_ = new CircularProgress(this);
|
||||
spinner_->setColor("#acc7dc");
|
||||
spinner_->setSize(32);
|
||||
spinner_->setMaximumWidth(spinner_->width());
|
||||
spinner_->hide();
|
||||
|
||||
errorIcon_ = new QLabel(this);
|
||||
errorIcon_->setPixmap(QPixmap(":/icons/icons/error.png"));
|
||||
errorIcon_->hide();
|
||||
errorIcon_ = new QLabel(this);
|
||||
errorIcon_->setPixmap(QPixmap(":/icons/icons/error.png"));
|
||||
errorIcon_->hide();
|
||||
|
||||
matrixidLayout_ = new QHBoxLayout();
|
||||
matrixidLayout_->addWidget(matrixid_input_, 0, Qt::AlignVCenter);
|
||||
matrixidLayout_ = new QHBoxLayout();
|
||||
matrixidLayout_->addWidget(matrixid_input_, 0, Qt::AlignVCenter);
|
||||
|
||||
password_input_ = new TextField(this);
|
||||
password_input_->setTextColor("#333333");
|
||||
password_input_->setLabel(tr("Password"));
|
||||
password_input_->setInkColor("#555459");
|
||||
password_input_->setBackgroundColor("#f9f9f9");
|
||||
password_input_->setEchoMode(QLineEdit::Password);
|
||||
password_input_ = new TextField(this);
|
||||
password_input_->setTextColor("#333333");
|
||||
password_input_->setLabel(tr("Password"));
|
||||
password_input_->setInkColor("#555459");
|
||||
password_input_->setBackgroundColor("#f9f9f9");
|
||||
password_input_->setEchoMode(QLineEdit::Password);
|
||||
|
||||
serverInput_ = new TextField(this);
|
||||
serverInput_->setTextColor("#333333");
|
||||
serverInput_->setLabel("Homeserver address");
|
||||
serverInput_->setInkColor("#555459");
|
||||
serverInput_->setBackgroundColor("#f9f9f9");
|
||||
serverInput_->setPlaceholderText("matrix.org");
|
||||
serverInput_->hide();
|
||||
serverInput_ = new TextField(this);
|
||||
serverInput_->setTextColor("#333333");
|
||||
serverInput_->setLabel("Homeserver address");
|
||||
serverInput_->setInkColor("#555459");
|
||||
serverInput_->setBackgroundColor("#f9f9f9");
|
||||
serverInput_->setPlaceholderText("matrix.org");
|
||||
serverInput_->hide();
|
||||
|
||||
serverLayout_ = new QHBoxLayout();
|
||||
serverLayout_->addWidget(serverInput_, 0, Qt::AlignVCenter);
|
||||
serverLayout_ = new QHBoxLayout();
|
||||
serverLayout_->addWidget(serverInput_, 0, Qt::AlignVCenter);
|
||||
|
||||
form_layout_->addLayout(matrixidLayout_);
|
||||
form_layout_->addWidget(password_input_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addLayout(serverLayout_);
|
||||
form_layout_->addLayout(matrixidLayout_);
|
||||
form_layout_->addWidget(password_input_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addLayout(serverLayout_);
|
||||
|
||||
button_layout_ = new QHBoxLayout();
|
||||
button_layout_->setSpacing(0);
|
||||
button_layout_->setContentsMargins(0, 0, 0, 30);
|
||||
button_layout_ = new QHBoxLayout();
|
||||
button_layout_->setSpacing(0);
|
||||
button_layout_->setContentsMargins(0, 0, 0, 30);
|
||||
|
||||
login_button_ = new RaisedButton(tr("LOGIN"), this);
|
||||
login_button_->setBackgroundColor(QColor("#333333"));
|
||||
login_button_->setForegroundColor(QColor("white"));
|
||||
login_button_->setMinimumSize(350, 65);
|
||||
login_button_->setFontSize(20);
|
||||
login_button_->setCornerRadius(3);
|
||||
login_button_ = new RaisedButton(tr("LOGIN"), this);
|
||||
login_button_->setBackgroundColor(QColor("#333333"));
|
||||
login_button_->setForegroundColor(QColor("white"));
|
||||
login_button_->setMinimumSize(350, 65);
|
||||
login_button_->setFontSize(20);
|
||||
login_button_->setCornerRadius(3);
|
||||
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addWidget(login_button_);
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addWidget(login_button_);
|
||||
button_layout_->addStretch(1);
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(conf::fontSize);
|
||||
QFont font;
|
||||
font.setPixelSize(conf::fontSize);
|
||||
|
||||
error_label_ = new QLabel(this);
|
||||
error_label_->setFont(font);
|
||||
error_label_->setStyleSheet("color: #E22826");
|
||||
error_label_ = new QLabel(this);
|
||||
error_label_->setFont(font);
|
||||
error_label_->setStyleSheet("color: #E22826");
|
||||
|
||||
top_layout_->addLayout(top_bar_layout_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addLayout(logo_layout_);
|
||||
top_layout_->addLayout(form_wrapper_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addLayout(button_layout_);
|
||||
top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addLayout(top_bar_layout_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addLayout(logo_layout_);
|
||||
top_layout_->addLayout(form_wrapper_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addLayout(button_layout_);
|
||||
top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter);
|
||||
top_layout_->addStretch(1);
|
||||
|
||||
setLayout(top_layout_);
|
||||
setLayout(top_layout_);
|
||||
|
||||
connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked()));
|
||||
connect(login_button_, SIGNAL(clicked()), this, SLOT(onLoginButtonClicked()));
|
||||
connect(matrixid_input_, SIGNAL(returnPressed()), login_button_, SLOT(click()));
|
||||
connect(password_input_, SIGNAL(returnPressed()), login_button_, SLOT(click()));
|
||||
connect(serverInput_, SIGNAL(returnPressed()), login_button_, SLOT(click()));
|
||||
connect(client_.data(), SIGNAL(loginError(QString)), this, SLOT(loginError(QString)));
|
||||
connect(matrixid_input_, SIGNAL(editingFinished()), this, SLOT(onMatrixIdEntered()));
|
||||
connect(client_.data(), SIGNAL(versionError(QString)), this, SLOT(versionError(QString)));
|
||||
connect(client_.data(), SIGNAL(versionSuccess()), this, SLOT(versionSuccess()));
|
||||
connect(serverInput_, SIGNAL(editingFinished()), this, SLOT(onServerAddressEntered()));
|
||||
connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked()));
|
||||
connect(login_button_, SIGNAL(clicked()), this, SLOT(onLoginButtonClicked()));
|
||||
connect(matrixid_input_, SIGNAL(returnPressed()), login_button_, SLOT(click()));
|
||||
connect(password_input_, SIGNAL(returnPressed()), login_button_, SLOT(click()));
|
||||
connect(serverInput_, SIGNAL(returnPressed()), login_button_, SLOT(click()));
|
||||
connect(client_.data(), SIGNAL(loginError(QString)), this, SLOT(loginError(QString)));
|
||||
connect(matrixid_input_, SIGNAL(editingFinished()), this, SLOT(onMatrixIdEntered()));
|
||||
connect(client_.data(), SIGNAL(versionError(QString)), this, SLOT(versionError(QString)));
|
||||
connect(client_.data(), SIGNAL(versionSuccess()), this, SLOT(versionSuccess()));
|
||||
connect(serverInput_, SIGNAL(editingFinished()), this, SLOT(onServerAddressEntered()));
|
||||
}
|
||||
|
||||
void
|
||||
LoginPage::loginError(QString error)
|
||||
{
|
||||
error_label_->setText(error);
|
||||
error_label_->setText(error);
|
||||
}
|
||||
|
||||
bool
|
||||
LoginPage::isMatrixIdValid()
|
||||
{
|
||||
int pos = 0;
|
||||
auto matrix_id = matrixid_input_->text();
|
||||
int pos = 0;
|
||||
auto matrix_id = matrixid_input_->text();
|
||||
|
||||
return InputValidator::Id.validate(matrix_id, pos) == QValidator::Acceptable;
|
||||
return InputValidator::Id.validate(matrix_id, pos) == QValidator::Acceptable;
|
||||
}
|
||||
|
||||
void
|
||||
LoginPage::onMatrixIdEntered()
|
||||
{
|
||||
error_label_->setText("");
|
||||
error_label_->setText("");
|
||||
|
||||
if (!isMatrixIdValid()) {
|
||||
loginError("You have entered an invalid Matrix ID e.g @joe:matrix.org");
|
||||
return;
|
||||
} else if (password_input_->text().isEmpty()) {
|
||||
loginError(tr("Empty password"));
|
||||
}
|
||||
if (!isMatrixIdValid()) {
|
||||
loginError("You have entered an invalid Matrix ID e.g @joe:matrix.org");
|
||||
return;
|
||||
} else if (password_input_->text().isEmpty()) {
|
||||
loginError(tr("Empty password"));
|
||||
}
|
||||
|
||||
QString homeServer = matrixid_input_->text().split(":").at(1);
|
||||
if (homeServer != inferredServerAddress_) {
|
||||
serverInput_->hide();
|
||||
serverLayout_->removeWidget(errorIcon_);
|
||||
errorIcon_->hide();
|
||||
if (serverInput_->isVisible()) {
|
||||
matrixidLayout_->removeWidget(spinner_);
|
||||
serverLayout_->addWidget(spinner_, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
spinner_->show();
|
||||
} else {
|
||||
serverLayout_->removeWidget(spinner_);
|
||||
matrixidLayout_->addWidget(spinner_, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
spinner_->show();
|
||||
}
|
||||
QString homeServer = matrixid_input_->text().split(":").at(1);
|
||||
if (homeServer != inferredServerAddress_) {
|
||||
serverInput_->hide();
|
||||
serverLayout_->removeWidget(errorIcon_);
|
||||
errorIcon_->hide();
|
||||
if (serverInput_->isVisible()) {
|
||||
matrixidLayout_->removeWidget(spinner_);
|
||||
serverLayout_->addWidget(spinner_, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
spinner_->show();
|
||||
} else {
|
||||
serverLayout_->removeWidget(spinner_);
|
||||
matrixidLayout_->addWidget(spinner_, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
spinner_->show();
|
||||
}
|
||||
|
||||
inferredServerAddress_ = homeServer;
|
||||
serverInput_->setText(homeServer);
|
||||
client_->setServer(homeServer);
|
||||
client_->versions();
|
||||
}
|
||||
inferredServerAddress_ = homeServer;
|
||||
serverInput_->setText(homeServer);
|
||||
client_->setServer(homeServer);
|
||||
client_->versions();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LoginPage::onServerAddressEntered()
|
||||
{
|
||||
error_label_->setText("");
|
||||
client_->setServer(serverInput_->text());
|
||||
client_->versions();
|
||||
error_label_->setText("");
|
||||
client_->setServer(serverInput_->text());
|
||||
client_->versions();
|
||||
|
||||
serverLayout_->removeWidget(errorIcon_);
|
||||
errorIcon_->hide();
|
||||
serverLayout_->addWidget(spinner_, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
spinner_->show();
|
||||
serverLayout_->removeWidget(errorIcon_);
|
||||
errorIcon_->hide();
|
||||
serverLayout_->addWidget(spinner_, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
spinner_->show();
|
||||
}
|
||||
|
||||
void
|
||||
LoginPage::versionError(QString error)
|
||||
{
|
||||
// Matrix homeservers are often kept on a subdomain called 'matrix'
|
||||
// so let's try that next, unless the address was set explicitly or the domain part of the username already
|
||||
// points to this subdomain
|
||||
QUrl currentServer = client_->getHomeServer();
|
||||
QString mxidAddress = matrixid_input_->text().split(":").at(1);
|
||||
if (currentServer.host() == inferredServerAddress_ && !currentServer.host().startsWith("matrix")) {
|
||||
error_label_->setText("");
|
||||
currentServer.setHost(QString("matrix.") + currentServer.host());
|
||||
serverInput_->setText(currentServer.host());
|
||||
client_->setServer(currentServer.host());
|
||||
client_->versions();
|
||||
return;
|
||||
}
|
||||
// Matrix homeservers are often kept on a subdomain called 'matrix'
|
||||
// so let's try that next, unless the address was set explicitly or the domain part of the
|
||||
// username already points to this subdomain
|
||||
QUrl currentServer = client_->getHomeServer();
|
||||
QString mxidAddress = matrixid_input_->text().split(":").at(1);
|
||||
if (currentServer.host() == inferredServerAddress_ &&
|
||||
!currentServer.host().startsWith("matrix")) {
|
||||
error_label_->setText("");
|
||||
currentServer.setHost(QString("matrix.") + currentServer.host());
|
||||
serverInput_->setText(currentServer.host());
|
||||
client_->setServer(currentServer.host());
|
||||
client_->versions();
|
||||
return;
|
||||
}
|
||||
|
||||
error_label_->setText(error);
|
||||
serverInput_->show();
|
||||
error_label_->setText(error);
|
||||
serverInput_->show();
|
||||
|
||||
spinner_->hide();
|
||||
serverLayout_->removeWidget(spinner_);
|
||||
serverLayout_->addWidget(errorIcon_, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
errorIcon_->show();
|
||||
matrixidLayout_->removeWidget(spinner_);
|
||||
spinner_->hide();
|
||||
serverLayout_->removeWidget(spinner_);
|
||||
serverLayout_->addWidget(errorIcon_, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
errorIcon_->show();
|
||||
matrixidLayout_->removeWidget(spinner_);
|
||||
}
|
||||
|
||||
void
|
||||
LoginPage::versionSuccess()
|
||||
{
|
||||
serverLayout_->removeWidget(spinner_);
|
||||
matrixidLayout_->removeWidget(spinner_);
|
||||
spinner_->hide();
|
||||
serverLayout_->removeWidget(spinner_);
|
||||
matrixidLayout_->removeWidget(spinner_);
|
||||
spinner_->hide();
|
||||
|
||||
if (serverInput_->isVisible())
|
||||
serverInput_->hide();
|
||||
if (serverInput_->isVisible())
|
||||
serverInput_->hide();
|
||||
}
|
||||
|
||||
void
|
||||
LoginPage::onLoginButtonClicked()
|
||||
{
|
||||
error_label_->setText("");
|
||||
error_label_->setText("");
|
||||
|
||||
if (!isMatrixIdValid()) {
|
||||
loginError("You have entered an invalid Matrix ID e.g @joe:matrix.org");
|
||||
} else if (password_input_->text().isEmpty()) {
|
||||
loginError("Empty password");
|
||||
} else {
|
||||
QString user = matrixid_input_->text().split(":").at(0).split("@").at(1);
|
||||
QString password = password_input_->text();
|
||||
client_->setServer(serverInput_->text());
|
||||
client_->login(user, password);
|
||||
}
|
||||
if (!isMatrixIdValid()) {
|
||||
loginError("You have entered an invalid Matrix ID e.g @joe:matrix.org");
|
||||
} else if (password_input_->text().isEmpty()) {
|
||||
loginError("Empty password");
|
||||
} else {
|
||||
QString user = matrixid_input_->text().split(":").at(0).split("@").at(1);
|
||||
QString password = password_input_->text();
|
||||
client_->setServer(serverInput_->text());
|
||||
client_->login(user, password);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LoginPage::reset()
|
||||
{
|
||||
matrixid_input_->clear();
|
||||
password_input_->clear();
|
||||
serverInput_->clear();
|
||||
matrixid_input_->clear();
|
||||
password_input_->clear();
|
||||
serverInput_->clear();
|
||||
|
||||
spinner_->hide();
|
||||
errorIcon_->hide();
|
||||
serverLayout_->removeWidget(spinner_);
|
||||
serverLayout_->removeWidget(errorIcon_);
|
||||
matrixidLayout_->removeWidget(spinner_);
|
||||
spinner_->hide();
|
||||
errorIcon_->hide();
|
||||
serverLayout_->removeWidget(spinner_);
|
||||
serverLayout_->removeWidget(errorIcon_);
|
||||
matrixidLayout_->removeWidget(spinner_);
|
||||
|
||||
inferredServerAddress_.clear();
|
||||
inferredServerAddress_.clear();
|
||||
}
|
||||
|
||||
void
|
||||
LoginPage::onBackButtonClicked()
|
||||
{
|
||||
emit backButtonClicked();
|
||||
emit backButtonClicked();
|
||||
}
|
||||
|
||||
LoginPage::~LoginPage()
|
||||
|
|
|
@ -25,37 +25,37 @@
|
|||
LogoutDialog::LogoutDialog(QWidget *parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
setMaximumSize(400, 400);
|
||||
setStyleSheet("background-color: #f9f9f9");
|
||||
setMaximumSize(400, 400);
|
||||
setStyleSheet("background-color: #f9f9f9");
|
||||
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->setSpacing(30);
|
||||
layout->setMargin(20);
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->setSpacing(30);
|
||||
layout->setMargin(20);
|
||||
|
||||
auto buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->setSpacing(0);
|
||||
buttonLayout->setMargin(0);
|
||||
auto buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->setSpacing(0);
|
||||
buttonLayout->setMargin(0);
|
||||
|
||||
confirmBtn_ = new FlatButton("OK", this);
|
||||
confirmBtn_->setFontSize(conf::btn::fontSize);
|
||||
confirmBtn_ = new FlatButton("OK", this);
|
||||
confirmBtn_->setFontSize(conf::btn::fontSize);
|
||||
|
||||
cancelBtn_ = new FlatButton(tr("CANCEL"), this);
|
||||
cancelBtn_->setFontSize(conf::btn::fontSize);
|
||||
cancelBtn_ = new FlatButton(tr("CANCEL"), this);
|
||||
cancelBtn_->setFontSize(conf::btn::fontSize);
|
||||
|
||||
buttonLayout->addStretch(1);
|
||||
buttonLayout->addWidget(confirmBtn_);
|
||||
buttonLayout->addWidget(cancelBtn_);
|
||||
buttonLayout->addStretch(1);
|
||||
buttonLayout->addWidget(confirmBtn_);
|
||||
buttonLayout->addWidget(cancelBtn_);
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(conf::headerFontSize);
|
||||
QFont font;
|
||||
font.setPixelSize(conf::headerFontSize);
|
||||
|
||||
auto label = new QLabel(tr("Logout. Are you sure?"), this);
|
||||
label->setFont(font);
|
||||
label->setStyleSheet("color: #333333");
|
||||
auto label = new QLabel(tr("Logout. Are you sure?"), this);
|
||||
label->setFont(font);
|
||||
label->setStyleSheet("color: #333333");
|
||||
|
||||
layout->addWidget(label);
|
||||
layout->addLayout(buttonLayout);
|
||||
layout->addWidget(label);
|
||||
layout->addLayout(buttonLayout);
|
||||
|
||||
connect(confirmBtn_, &QPushButton::clicked, [=]() { emit closing(true); });
|
||||
connect(cancelBtn_, &QPushButton::clicked, [=]() { emit closing(false); });
|
||||
connect(confirmBtn_, &QPushButton::clicked, [=]() { emit closing(true); });
|
||||
connect(cancelBtn_, &QPushButton::clicked, [=]() { emit closing(false); });
|
||||
}
|
||||
|
|
|
@ -30,217 +30,221 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
, progress_modal_{ nullptr }
|
||||
, spinner_{ nullptr }
|
||||
{
|
||||
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
setSizePolicy(sizePolicy);
|
||||
setWindowTitle("nheko");
|
||||
setObjectName("MainWindow");
|
||||
setStyleSheet("QWidget#MainWindow {background-color: #f9f9f9}");
|
||||
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
setSizePolicy(sizePolicy);
|
||||
setWindowTitle("nheko");
|
||||
setObjectName("MainWindow");
|
||||
setStyleSheet("QWidget#MainWindow {background-color: #f9f9f9}");
|
||||
|
||||
restoreWindowSize();
|
||||
setMinimumSize(QSize(conf::window::minWidth, conf::window::minHeight));
|
||||
restoreWindowSize();
|
||||
setMinimumSize(QSize(conf::window::minWidth, conf::window::minHeight));
|
||||
|
||||
QFont font("Open Sans");
|
||||
font.setPixelSize(conf::fontSize);
|
||||
font.setStyleStrategy(QFont::PreferAntialias);
|
||||
setFont(font);
|
||||
QFont font("Open Sans");
|
||||
font.setPixelSize(conf::fontSize);
|
||||
font.setStyleStrategy(QFont::PreferAntialias);
|
||||
setFont(font);
|
||||
|
||||
client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org"));
|
||||
trayIcon_ = new TrayIcon(":/logos/nheko-32.png", this);
|
||||
client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org"));
|
||||
trayIcon_ = new TrayIcon(":/logos/nheko-32.png", this);
|
||||
|
||||
welcome_page_ = new WelcomePage(this);
|
||||
login_page_ = new LoginPage(client_, this);
|
||||
register_page_ = new RegisterPage(client_, this);
|
||||
chat_page_ = new ChatPage(client_, this);
|
||||
welcome_page_ = new WelcomePage(this);
|
||||
login_page_ = new LoginPage(client_, this);
|
||||
register_page_ = new RegisterPage(client_, this);
|
||||
chat_page_ = new ChatPage(client_, this);
|
||||
|
||||
// Initialize sliding widget manager.
|
||||
sliding_stack_ = new SlidingStackWidget(this);
|
||||
sliding_stack_->addWidget(welcome_page_);
|
||||
sliding_stack_->addWidget(login_page_);
|
||||
sliding_stack_->addWidget(register_page_);
|
||||
sliding_stack_->addWidget(chat_page_);
|
||||
// Initialize sliding widget manager.
|
||||
sliding_stack_ = new SlidingStackWidget(this);
|
||||
sliding_stack_->addWidget(welcome_page_);
|
||||
sliding_stack_->addWidget(login_page_);
|
||||
sliding_stack_->addWidget(register_page_);
|
||||
sliding_stack_->addWidget(chat_page_);
|
||||
|
||||
setCentralWidget(sliding_stack_);
|
||||
setCentralWidget(sliding_stack_);
|
||||
|
||||
connect(welcome_page_, SIGNAL(userLogin()), this, SLOT(showLoginPage()));
|
||||
connect(welcome_page_, SIGNAL(userRegister()), this, SLOT(showRegisterPage()));
|
||||
connect(welcome_page_, SIGNAL(userLogin()), this, SLOT(showLoginPage()));
|
||||
connect(welcome_page_, SIGNAL(userRegister()), this, SLOT(showRegisterPage()));
|
||||
|
||||
connect(login_page_, SIGNAL(backButtonClicked()), this, SLOT(showWelcomePage()));
|
||||
connect(register_page_, SIGNAL(backButtonClicked()), this, SLOT(showWelcomePage()));
|
||||
connect(login_page_, SIGNAL(backButtonClicked()), this, SLOT(showWelcomePage()));
|
||||
connect(register_page_, SIGNAL(backButtonClicked()), this, SLOT(showWelcomePage()));
|
||||
|
||||
connect(chat_page_, SIGNAL(close()), this, SLOT(showWelcomePage()));
|
||||
connect(chat_page_, SIGNAL(changeWindowTitle(QString)), this, SLOT(setWindowTitle(QString)));
|
||||
connect(chat_page_, SIGNAL(unreadMessages(int)), trayIcon_, SLOT(setUnreadCount(int)));
|
||||
connect(chat_page_, SIGNAL(close()), this, SLOT(showWelcomePage()));
|
||||
connect(
|
||||
chat_page_, SIGNAL(changeWindowTitle(QString)), this, SLOT(setWindowTitle(QString)));
|
||||
connect(chat_page_, SIGNAL(unreadMessages(int)), trayIcon_, SLOT(setUnreadCount(int)));
|
||||
|
||||
connect(trayIcon_,
|
||||
SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||
this,
|
||||
SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
|
||||
connect(trayIcon_,
|
||||
SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||
this,
|
||||
SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
|
||||
|
||||
connect(chat_page_, SIGNAL(contentLoaded()), this, SLOT(removeOverlayProgressBar()));
|
||||
connect(chat_page_, SIGNAL(contentLoaded()), this, SLOT(removeOverlayProgressBar()));
|
||||
|
||||
connect(client_.data(),
|
||||
SIGNAL(loginSuccess(QString, QString, QString)),
|
||||
this,
|
||||
SLOT(showChatPage(QString, QString, QString)));
|
||||
connect(client_.data(),
|
||||
SIGNAL(loginSuccess(QString, QString, QString)),
|
||||
this,
|
||||
SLOT(showChatPage(QString, QString, QString)));
|
||||
|
||||
QSettings settings;
|
||||
QSettings settings;
|
||||
|
||||
if (hasActiveUser()) {
|
||||
QString token = settings.value("auth/access_token").toString();
|
||||
QString home_server = settings.value("auth/home_server").toString();
|
||||
QString user_id = settings.value("auth/user_id").toString();
|
||||
if (hasActiveUser()) {
|
||||
QString token = settings.value("auth/access_token").toString();
|
||||
QString home_server = settings.value("auth/home_server").toString();
|
||||
QString user_id = settings.value("auth/user_id").toString();
|
||||
|
||||
showChatPage(user_id, home_server, token);
|
||||
}
|
||||
showChatPage(user_id, home_server, token);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::restoreWindowSize()
|
||||
{
|
||||
QSettings settings;
|
||||
int savedWidth = settings.value("window/width").toInt();
|
||||
int savedheight = settings.value("window/height").toInt();
|
||||
QSettings settings;
|
||||
int savedWidth = settings.value("window/width").toInt();
|
||||
int savedheight = settings.value("window/height").toInt();
|
||||
|
||||
if (savedWidth == 0 || savedheight == 0)
|
||||
resize(conf::window::width, conf::window::height);
|
||||
else
|
||||
resize(savedWidth, savedheight);
|
||||
if (savedWidth == 0 || savedheight == 0)
|
||||
resize(conf::window::width, conf::window::height);
|
||||
else
|
||||
resize(savedWidth, savedheight);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::saveCurrentWindowSize()
|
||||
{
|
||||
QSettings settings;
|
||||
QSize current = size();
|
||||
QSettings settings;
|
||||
QSize current = size();
|
||||
|
||||
settings.setValue("window/width", current.width());
|
||||
settings.setValue("window/height", current.height());
|
||||
settings.setValue("window/width", current.width());
|
||||
settings.setValue("window/height", current.height());
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::removeOverlayProgressBar()
|
||||
{
|
||||
QTimer *timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
QTimer *timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
|
||||
connect(timer, &QTimer::timeout, [=]() {
|
||||
timer->deleteLater();
|
||||
connect(timer, &QTimer::timeout, [=]() {
|
||||
timer->deleteLater();
|
||||
|
||||
if (progress_modal_ != nullptr) {
|
||||
progress_modal_->deleteLater();
|
||||
progress_modal_->fadeOut();
|
||||
}
|
||||
if (progress_modal_ != nullptr) {
|
||||
progress_modal_->deleteLater();
|
||||
progress_modal_->fadeOut();
|
||||
}
|
||||
|
||||
if (spinner_ != nullptr)
|
||||
spinner_->deleteLater();
|
||||
if (spinner_ != nullptr)
|
||||
spinner_->deleteLater();
|
||||
|
||||
progress_modal_ = nullptr;
|
||||
spinner_ = nullptr;
|
||||
});
|
||||
progress_modal_ = nullptr;
|
||||
spinner_ = nullptr;
|
||||
});
|
||||
|
||||
timer->start(500);
|
||||
timer->start(500);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::showChatPage(QString userid, QString homeserver, QString token)
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("auth/access_token", token);
|
||||
settings.setValue("auth/home_server", homeserver);
|
||||
settings.setValue("auth/user_id", userid);
|
||||
QSettings settings;
|
||||
settings.setValue("auth/access_token", token);
|
||||
settings.setValue("auth/home_server", homeserver);
|
||||
settings.setValue("auth/user_id", userid);
|
||||
|
||||
int index = sliding_stack_->getWidgetIndex(chat_page_);
|
||||
int modalOpacityDuration = 300;
|
||||
int index = sliding_stack_->getWidgetIndex(chat_page_);
|
||||
int modalOpacityDuration = 300;
|
||||
|
||||
// If we go directly from the welcome page don't show an animation.
|
||||
if (sliding_stack_->currentIndex() == 0) {
|
||||
sliding_stack_->setCurrentIndex(index);
|
||||
modalOpacityDuration = 0;
|
||||
} else {
|
||||
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::LEFT_TO_RIGHT);
|
||||
}
|
||||
// If we go directly from the welcome page don't show an animation.
|
||||
if (sliding_stack_->currentIndex() == 0) {
|
||||
sliding_stack_->setCurrentIndex(index);
|
||||
modalOpacityDuration = 0;
|
||||
} else {
|
||||
sliding_stack_->slideInIndex(index,
|
||||
SlidingStackWidget::AnimationDirection::LEFT_TO_RIGHT);
|
||||
}
|
||||
|
||||
if (spinner_ == nullptr) {
|
||||
spinner_ = new CircularProgress(this);
|
||||
spinner_->setColor("#acc7dc");
|
||||
spinner_->setSize(100);
|
||||
}
|
||||
if (spinner_ == nullptr) {
|
||||
spinner_ = new CircularProgress(this);
|
||||
spinner_->setColor("#acc7dc");
|
||||
spinner_->setSize(100);
|
||||
}
|
||||
|
||||
if (progress_modal_ == nullptr) {
|
||||
progress_modal_ = new OverlayModal(this, spinner_);
|
||||
progress_modal_->fadeIn();
|
||||
progress_modal_->setDuration(modalOpacityDuration);
|
||||
}
|
||||
if (progress_modal_ == nullptr) {
|
||||
progress_modal_ = new OverlayModal(this, spinner_);
|
||||
progress_modal_->fadeIn();
|
||||
progress_modal_->setDuration(modalOpacityDuration);
|
||||
}
|
||||
|
||||
login_page_->reset();
|
||||
chat_page_->bootstrap(userid, homeserver, token);
|
||||
login_page_->reset();
|
||||
chat_page_->bootstrap(userid, homeserver, token);
|
||||
|
||||
instance_ = this;
|
||||
instance_ = this;
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::showWelcomePage()
|
||||
{
|
||||
int index = sliding_stack_->getWidgetIndex(welcome_page_);
|
||||
int index = sliding_stack_->getWidgetIndex(welcome_page_);
|
||||
|
||||
if (sliding_stack_->currentIndex() == sliding_stack_->getWidgetIndex(login_page_))
|
||||
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::RIGHT_TO_LEFT);
|
||||
else
|
||||
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::LEFT_TO_RIGHT);
|
||||
if (sliding_stack_->currentIndex() == sliding_stack_->getWidgetIndex(login_page_))
|
||||
sliding_stack_->slideInIndex(index,
|
||||
SlidingStackWidget::AnimationDirection::RIGHT_TO_LEFT);
|
||||
else
|
||||
sliding_stack_->slideInIndex(index,
|
||||
SlidingStackWidget::AnimationDirection::LEFT_TO_RIGHT);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::showLoginPage()
|
||||
{
|
||||
int index = sliding_stack_->getWidgetIndex(login_page_);
|
||||
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::LEFT_TO_RIGHT);
|
||||
int index = sliding_stack_->getWidgetIndex(login_page_);
|
||||
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::LEFT_TO_RIGHT);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::showRegisterPage()
|
||||
{
|
||||
int index = sliding_stack_->getWidgetIndex(register_page_);
|
||||
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::RIGHT_TO_LEFT);
|
||||
int index = sliding_stack_->getWidgetIndex(register_page_);
|
||||
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::RIGHT_TO_LEFT);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (isVisible()) {
|
||||
event->ignore();
|
||||
hide();
|
||||
}
|
||||
if (isVisible()) {
|
||||
event->ignore();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case QSystemTrayIcon::Trigger:
|
||||
if (!isVisible()) {
|
||||
show();
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (reason) {
|
||||
case QSystemTrayIcon::Trigger:
|
||||
if (!isVisible()) {
|
||||
show();
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MainWindow::hasActiveUser()
|
||||
{
|
||||
QSettings settings;
|
||||
QSettings settings;
|
||||
|
||||
return settings.contains("auth/access_token") && settings.contains("auth/home_server") &&
|
||||
settings.contains("auth/user_id");
|
||||
return settings.contains("auth/access_token") && settings.contains("auth/home_server") &&
|
||||
settings.contains("auth/user_id");
|
||||
}
|
||||
|
||||
MainWindow *
|
||||
MainWindow::instance()
|
||||
{
|
||||
return instance_;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
void
|
||||
ProfileResponse::deserialize(const QJsonDocument &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Response is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Response is not a JSON object");
|
||||
|
||||
QJsonObject object = data.object();
|
||||
QJsonObject object = data.object();
|
||||
|
||||
if (object.contains("avatar_url"))
|
||||
avatar_url_ = QUrl(object.value("avatar_url").toString());
|
||||
if (object.contains("avatar_url"))
|
||||
avatar_url_ = QUrl(object.value("avatar_url").toString());
|
||||
|
||||
if (object.contains("displayname"))
|
||||
display_name_ = object.value("displayname").toString();
|
||||
if (object.contains("displayname"))
|
||||
display_name_ = object.value("displayname").toString();
|
||||
}
|
||||
|
|
|
@ -30,126 +30,127 @@ RoomSearchInput::RoomSearchInput(QWidget *parent)
|
|||
bool
|
||||
RoomSearchInput::focusNextPrevChild(bool next)
|
||||
{
|
||||
Q_UNUSED(next);
|
||||
Q_UNUSED(next);
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
RoomSearchInput::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Down) {
|
||||
emit selectNextCompletion();
|
||||
event->accept();
|
||||
return;
|
||||
} else if (event->key() == Qt::Key_Up) {
|
||||
emit selectPreviousCompletion();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
if (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Down) {
|
||||
emit selectNextCompletion();
|
||||
event->accept();
|
||||
return;
|
||||
} else if (event->key() == Qt::Key_Up) {
|
||||
emit selectPreviousCompletion();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
TextField::keyPressEvent(event);
|
||||
TextField::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void
|
||||
RoomSearchInput::hideEvent(QHideEvent *event)
|
||||
{
|
||||
emit hiding();
|
||||
TextField::hideEvent(event);
|
||||
emit hiding();
|
||||
TextField::hideEvent(event);
|
||||
}
|
||||
|
||||
QuickSwitcher::QuickSwitcher(QWidget *parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
setMaximumWidth(450);
|
||||
setStyleSheet("background-color: white");
|
||||
setMaximumWidth(450);
|
||||
setStyleSheet("background-color: white");
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(20);
|
||||
QFont font;
|
||||
font.setPixelSize(20);
|
||||
|
||||
roomSearch_ = new RoomSearchInput(this);
|
||||
roomSearch_->setFont(font);
|
||||
roomSearch_->setPlaceholderText(tr("Find a room..."));
|
||||
roomSearch_ = new RoomSearchInput(this);
|
||||
roomSearch_->setFont(font);
|
||||
roomSearch_->setPlaceholderText(tr("Find a room..."));
|
||||
|
||||
completer_ = new QCompleter();
|
||||
completer_->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
completer_->setCompletionMode(QCompleter::PopupCompletion);
|
||||
completer_->setWidget(this);
|
||||
completer_ = new QCompleter();
|
||||
completer_->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
completer_->setCompletionMode(QCompleter::PopupCompletion);
|
||||
completer_->setWidget(this);
|
||||
|
||||
topLayout_ = new QVBoxLayout(this);
|
||||
topLayout_->addWidget(roomSearch_);
|
||||
topLayout_ = new QVBoxLayout(this);
|
||||
topLayout_->addWidget(roomSearch_);
|
||||
|
||||
connect(completer_, SIGNAL(highlighted(QString)), roomSearch_, SLOT(setText(QString)));
|
||||
connect(roomSearch_, &QLineEdit::textEdited, this, [=](const QString &prefix) {
|
||||
if (prefix.isEmpty()) {
|
||||
completer_->popup()->hide();
|
||||
selection_ = -1;
|
||||
return;
|
||||
}
|
||||
connect(completer_, SIGNAL(highlighted(QString)), roomSearch_, SLOT(setText(QString)));
|
||||
connect(roomSearch_, &QLineEdit::textEdited, this, [=](const QString &prefix) {
|
||||
if (prefix.isEmpty()) {
|
||||
completer_->popup()->hide();
|
||||
selection_ = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (prefix != completer_->completionPrefix()) {
|
||||
completer_->setCompletionPrefix(prefix);
|
||||
selection_ = -1;
|
||||
}
|
||||
if (prefix != completer_->completionPrefix()) {
|
||||
completer_->setCompletionPrefix(prefix);
|
||||
selection_ = -1;
|
||||
}
|
||||
|
||||
completer_->popup()->setWindowFlags(completer_->popup()->windowFlags() | Qt::ToolTip |
|
||||
Qt::NoDropShadowWindowHint);
|
||||
completer_->popup()->setAttribute(Qt::WA_ShowWithoutActivating);
|
||||
completer_->complete();
|
||||
});
|
||||
completer_->popup()->setWindowFlags(completer_->popup()->windowFlags() |
|
||||
Qt::ToolTip | Qt::NoDropShadowWindowHint);
|
||||
completer_->popup()->setAttribute(Qt::WA_ShowWithoutActivating);
|
||||
completer_->complete();
|
||||
});
|
||||
|
||||
connect(roomSearch_, &RoomSearchInput::selectNextCompletion, this, [=]() {
|
||||
selection_ += 1;
|
||||
connect(roomSearch_, &RoomSearchInput::selectNextCompletion, this, [=]() {
|
||||
selection_ += 1;
|
||||
|
||||
if (!completer_->setCurrentRow(selection_)) {
|
||||
selection_ = 0;
|
||||
completer_->setCurrentRow(selection_);
|
||||
}
|
||||
if (!completer_->setCurrentRow(selection_)) {
|
||||
selection_ = 0;
|
||||
completer_->setCurrentRow(selection_);
|
||||
}
|
||||
|
||||
completer_->popup()->setCurrentIndex(completer_->currentIndex());
|
||||
});
|
||||
completer_->popup()->setCurrentIndex(completer_->currentIndex());
|
||||
});
|
||||
|
||||
connect(roomSearch_, &RoomSearchInput::selectPreviousCompletion, this, [=]() {
|
||||
selection_ -= 1;
|
||||
connect(roomSearch_, &RoomSearchInput::selectPreviousCompletion, this, [=]() {
|
||||
selection_ -= 1;
|
||||
|
||||
if (!completer_->setCurrentRow(selection_)) {
|
||||
selection_ = completer_->completionCount() - 1;
|
||||
completer_->setCurrentRow(selection_);
|
||||
}
|
||||
if (!completer_->setCurrentRow(selection_)) {
|
||||
selection_ = completer_->completionCount() - 1;
|
||||
completer_->setCurrentRow(selection_);
|
||||
}
|
||||
|
||||
completer_->popup()->setCurrentIndex(completer_->currentIndex());
|
||||
});
|
||||
completer_->popup()->setCurrentIndex(completer_->currentIndex());
|
||||
});
|
||||
|
||||
connect(roomSearch_, &RoomSearchInput::hiding, this, [=]() { completer_->popup()->hide(); });
|
||||
connect(roomSearch_, &QLineEdit::returnPressed, this, [=]() {
|
||||
emit closing();
|
||||
emit roomSelected(rooms_[this->roomSearch_->text().trimmed()]);
|
||||
connect(
|
||||
roomSearch_, &RoomSearchInput::hiding, this, [=]() { completer_->popup()->hide(); });
|
||||
connect(roomSearch_, &QLineEdit::returnPressed, this, [=]() {
|
||||
emit closing();
|
||||
emit roomSelected(rooms_[this->roomSearch_->text().trimmed()]);
|
||||
|
||||
roomSearch_->clear();
|
||||
});
|
||||
roomSearch_->clear();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
QuickSwitcher::setRoomList(const QMap<QString, QString> &rooms)
|
||||
{
|
||||
rooms_ = rooms;
|
||||
QStringList items = rooms.keys();
|
||||
rooms_ = rooms;
|
||||
QStringList items = rooms.keys();
|
||||
|
||||
completer_->setModel(new QStringListModel(items));
|
||||
completer_->setModel(new QStringListModel(items));
|
||||
}
|
||||
|
||||
void
|
||||
QuickSwitcher::showEvent(QShowEvent *)
|
||||
{
|
||||
roomSearch_->setFocus();
|
||||
roomSearch_->setFocus();
|
||||
}
|
||||
|
||||
void
|
||||
QuickSwitcher::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
roomSearch_->clear();
|
||||
event->accept();
|
||||
emit closing();
|
||||
}
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
roomSearch_->clear();
|
||||
event->accept();
|
||||
emit closing();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,29 +31,29 @@ RegisterRequest::RegisterRequest(const QString &username, const QString &passwor
|
|||
QByteArray
|
||||
RegisterRequest::serialize() noexcept
|
||||
{
|
||||
QJsonObject body{ { "username", user_ }, { "password", password_ } };
|
||||
QJsonObject body{ { "username", user_ }, { "password", password_ } };
|
||||
|
||||
return QJsonDocument(body).toJson(QJsonDocument::Compact);
|
||||
return QJsonDocument(body).toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
void
|
||||
RegisterResponse::deserialize(const QJsonDocument &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Response is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Response is not a JSON object");
|
||||
|
||||
QJsonObject object = data.object();
|
||||
QJsonObject object = data.object();
|
||||
|
||||
if (!object.contains("access_token"))
|
||||
throw DeserializationException("Missing access_token param");
|
||||
if (!object.contains("access_token"))
|
||||
throw DeserializationException("Missing access_token param");
|
||||
|
||||
if (!object.contains("home_server"))
|
||||
throw DeserializationException("Missing home_server param");
|
||||
if (!object.contains("home_server"))
|
||||
throw DeserializationException("Missing home_server param");
|
||||
|
||||
if (!object.contains("user_id"))
|
||||
throw DeserializationException("Missing user_id param");
|
||||
if (!object.contains("user_id"))
|
||||
throw DeserializationException("Missing user_id param");
|
||||
|
||||
access_token_ = object.value("access_token").toString();
|
||||
home_server_ = object.value("home_server").toString();
|
||||
user_id_ = object.value("user_id").toString();
|
||||
access_token_ = object.value("access_token").toString();
|
||||
home_server_ = object.value("home_server").toString();
|
||||
user_id_ = object.value("user_id").toString();
|
||||
}
|
||||
|
|
|
@ -26,156 +26,159 @@ RegisterPage::RegisterPage(QSharedPointer<MatrixClient> client, QWidget *parent)
|
|||
: QWidget(parent)
|
||||
, client_(client)
|
||||
{
|
||||
setStyleSheet("background-color: #f9f9f9");
|
||||
setStyleSheet("background-color: #f9f9f9");
|
||||
|
||||
top_layout_ = new QVBoxLayout();
|
||||
top_layout_ = new QVBoxLayout();
|
||||
|
||||
back_layout_ = new QHBoxLayout();
|
||||
back_layout_->setSpacing(0);
|
||||
back_layout_->setContentsMargins(5, 5, -1, -1);
|
||||
back_layout_ = new QHBoxLayout();
|
||||
back_layout_->setSpacing(0);
|
||||
back_layout_->setContentsMargins(5, 5, -1, -1);
|
||||
|
||||
back_button_ = new FlatButton(this);
|
||||
back_button_->setMinimumSize(QSize(30, 30));
|
||||
back_button_ = new FlatButton(this);
|
||||
back_button_->setMinimumSize(QSize(30, 30));
|
||||
|
||||
QIcon icon;
|
||||
icon.addFile(":/icons/icons/left-angle.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
QIcon icon;
|
||||
icon.addFile(":/icons/icons/left-angle.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
|
||||
back_button_->setIcon(icon);
|
||||
back_button_->setIconSize(QSize(24, 24));
|
||||
back_button_->setIcon(icon);
|
||||
back_button_->setIconSize(QSize(24, 24));
|
||||
|
||||
back_layout_->addWidget(back_button_, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
back_layout_->addStretch(1);
|
||||
back_layout_->addWidget(back_button_, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
back_layout_->addStretch(1);
|
||||
|
||||
logo_ = new Avatar(this);
|
||||
logo_->setImage(QImage(":/logos/nheko-128.png"));
|
||||
logo_->setSize(80);
|
||||
logo_ = new Avatar(this);
|
||||
logo_->setImage(QImage(":/logos/nheko-128.png"));
|
||||
logo_->setSize(80);
|
||||
|
||||
logo_layout_ = new QHBoxLayout();
|
||||
logo_layout_->setMargin(0);
|
||||
logo_layout_->addWidget(logo_, 0, Qt::AlignHCenter);
|
||||
logo_layout_ = new QHBoxLayout();
|
||||
logo_layout_->setMargin(0);
|
||||
logo_layout_->addWidget(logo_, 0, Qt::AlignHCenter);
|
||||
|
||||
form_wrapper_ = new QHBoxLayout();
|
||||
form_widget_ = new QWidget();
|
||||
form_widget_->setMinimumSize(QSize(350, 300));
|
||||
form_wrapper_ = new QHBoxLayout();
|
||||
form_widget_ = new QWidget();
|
||||
form_widget_->setMinimumSize(QSize(350, 300));
|
||||
|
||||
form_layout_ = new QVBoxLayout();
|
||||
form_layout_->setSpacing(20);
|
||||
form_layout_->setContentsMargins(0, 0, 0, 40);
|
||||
form_widget_->setLayout(form_layout_);
|
||||
form_layout_ = new QVBoxLayout();
|
||||
form_layout_->setSpacing(20);
|
||||
form_layout_->setContentsMargins(0, 0, 0, 40);
|
||||
form_widget_->setLayout(form_layout_);
|
||||
|
||||
form_wrapper_->addStretch(1);
|
||||
form_wrapper_->addWidget(form_widget_);
|
||||
form_wrapper_->addStretch(1);
|
||||
form_wrapper_->addStretch(1);
|
||||
form_wrapper_->addWidget(form_widget_);
|
||||
form_wrapper_->addStretch(1);
|
||||
|
||||
username_input_ = new TextField();
|
||||
username_input_->setTextColor("#333333");
|
||||
username_input_->setLabel(tr("Username"));
|
||||
username_input_->setInkColor("#555459");
|
||||
username_input_->setBackgroundColor("#f9f9f9");
|
||||
username_input_ = new TextField();
|
||||
username_input_->setTextColor("#333333");
|
||||
username_input_->setLabel(tr("Username"));
|
||||
username_input_->setInkColor("#555459");
|
||||
username_input_->setBackgroundColor("#f9f9f9");
|
||||
|
||||
password_input_ = new TextField();
|
||||
password_input_->setTextColor("#333333");
|
||||
password_input_->setLabel(tr("Password"));
|
||||
password_input_->setInkColor("#555459");
|
||||
password_input_->setBackgroundColor("#f9f9f9");
|
||||
password_input_->setEchoMode(QLineEdit::Password);
|
||||
password_input_ = new TextField();
|
||||
password_input_->setTextColor("#333333");
|
||||
password_input_->setLabel(tr("Password"));
|
||||
password_input_->setInkColor("#555459");
|
||||
password_input_->setBackgroundColor("#f9f9f9");
|
||||
password_input_->setEchoMode(QLineEdit::Password);
|
||||
|
||||
password_confirmation_ = new TextField();
|
||||
password_confirmation_->setTextColor("#333333");
|
||||
password_confirmation_->setLabel(tr("Password confirmation"));
|
||||
password_confirmation_->setInkColor("#555459");
|
||||
password_confirmation_->setBackgroundColor("#f9f9f9");
|
||||
password_confirmation_->setEchoMode(QLineEdit::Password);
|
||||
password_confirmation_ = new TextField();
|
||||
password_confirmation_->setTextColor("#333333");
|
||||
password_confirmation_->setLabel(tr("Password confirmation"));
|
||||
password_confirmation_->setInkColor("#555459");
|
||||
password_confirmation_->setBackgroundColor("#f9f9f9");
|
||||
password_confirmation_->setEchoMode(QLineEdit::Password);
|
||||
|
||||
server_input_ = new TextField();
|
||||
server_input_->setTextColor("#333333");
|
||||
server_input_->setLabel(tr("Home Server"));
|
||||
server_input_->setInkColor("#555459");
|
||||
server_input_->setBackgroundColor("#f9f9f9");
|
||||
server_input_ = new TextField();
|
||||
server_input_->setTextColor("#333333");
|
||||
server_input_->setLabel(tr("Home Server"));
|
||||
server_input_->setInkColor("#555459");
|
||||
server_input_->setBackgroundColor("#f9f9f9");
|
||||
|
||||
form_layout_->addWidget(username_input_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addWidget(password_input_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addWidget(server_input_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addWidget(username_input_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addWidget(password_input_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter, 0);
|
||||
form_layout_->addWidget(server_input_, Qt::AlignHCenter, 0);
|
||||
|
||||
button_layout_ = new QHBoxLayout();
|
||||
button_layout_->setSpacing(0);
|
||||
button_layout_->setMargin(0);
|
||||
button_layout_ = new QHBoxLayout();
|
||||
button_layout_->setSpacing(0);
|
||||
button_layout_->setMargin(0);
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(conf::fontSize);
|
||||
QFont font;
|
||||
font.setPixelSize(conf::fontSize);
|
||||
|
||||
error_label_ = new QLabel(this);
|
||||
error_label_->setFont(font);
|
||||
error_label_->setStyleSheet("color: #E22826");
|
||||
error_label_ = new QLabel(this);
|
||||
error_label_->setFont(font);
|
||||
error_label_->setStyleSheet("color: #E22826");
|
||||
|
||||
register_button_ = new RaisedButton(tr("REGISTER"), this);
|
||||
register_button_->setBackgroundColor(QColor("#333333"));
|
||||
register_button_->setForegroundColor(QColor("white"));
|
||||
register_button_->setMinimumSize(350, 65);
|
||||
register_button_->setFontSize(conf::btn::fontSize);
|
||||
register_button_->setCornerRadius(conf::btn::cornerRadius);
|
||||
register_button_ = new RaisedButton(tr("REGISTER"), this);
|
||||
register_button_->setBackgroundColor(QColor("#333333"));
|
||||
register_button_->setForegroundColor(QColor("white"));
|
||||
register_button_->setMinimumSize(350, 65);
|
||||
register_button_->setFontSize(conf::btn::fontSize);
|
||||
register_button_->setCornerRadius(conf::btn::cornerRadius);
|
||||
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addWidget(register_button_);
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addWidget(register_button_);
|
||||
button_layout_->addStretch(1);
|
||||
|
||||
top_layout_->addLayout(back_layout_);
|
||||
top_layout_->addLayout(logo_layout_);
|
||||
top_layout_->addLayout(form_wrapper_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addLayout(button_layout_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter);
|
||||
top_layout_->addLayout(back_layout_);
|
||||
top_layout_->addLayout(logo_layout_);
|
||||
top_layout_->addLayout(form_wrapper_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addLayout(button_layout_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter);
|
||||
|
||||
connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked()));
|
||||
connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked()));
|
||||
connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked()));
|
||||
connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked()));
|
||||
|
||||
connect(username_input_, SIGNAL(returnPressed()), register_button_, SLOT(click()));
|
||||
connect(password_input_, SIGNAL(returnPressed()), register_button_, SLOT(click()));
|
||||
connect(password_confirmation_, SIGNAL(returnPressed()), register_button_, SLOT(click()));
|
||||
connect(server_input_, SIGNAL(returnPressed()), register_button_, SLOT(click()));
|
||||
connect(client_.data(), SIGNAL(registerError(const QString &)), this, SLOT(registerError(const QString &)));
|
||||
connect(username_input_, SIGNAL(returnPressed()), register_button_, SLOT(click()));
|
||||
connect(password_input_, SIGNAL(returnPressed()), register_button_, SLOT(click()));
|
||||
connect(password_confirmation_, SIGNAL(returnPressed()), register_button_, SLOT(click()));
|
||||
connect(server_input_, SIGNAL(returnPressed()), register_button_, SLOT(click()));
|
||||
connect(client_.data(),
|
||||
SIGNAL(registerError(const QString &)),
|
||||
this,
|
||||
SLOT(registerError(const QString &)));
|
||||
|
||||
username_input_->setValidator(&InputValidator::Localpart);
|
||||
password_input_->setValidator(&InputValidator::Password);
|
||||
server_input_->setValidator(&InputValidator::Domain);
|
||||
username_input_->setValidator(&InputValidator::Localpart);
|
||||
password_input_->setValidator(&InputValidator::Password);
|
||||
server_input_->setValidator(&InputValidator::Domain);
|
||||
|
||||
setLayout(top_layout_);
|
||||
setLayout(top_layout_);
|
||||
}
|
||||
|
||||
void
|
||||
RegisterPage::onBackButtonClicked()
|
||||
{
|
||||
emit backButtonClicked();
|
||||
emit backButtonClicked();
|
||||
}
|
||||
|
||||
void
|
||||
RegisterPage::registerError(const QString &msg)
|
||||
{
|
||||
error_label_->setText(msg);
|
||||
error_label_->setText(msg);
|
||||
}
|
||||
|
||||
void
|
||||
RegisterPage::onRegisterButtonClicked()
|
||||
{
|
||||
error_label_->setText("");
|
||||
error_label_->setText("");
|
||||
|
||||
if (!username_input_->hasAcceptableInput()) {
|
||||
registerError(tr("Invalid username"));
|
||||
} else if (!password_input_->hasAcceptableInput()) {
|
||||
registerError(tr("Password is not long enough (min 8 chars)"));
|
||||
} else if (password_input_->text() != password_confirmation_->text()) {
|
||||
registerError(tr("Passwords don't match"));
|
||||
} else if (!server_input_->hasAcceptableInput()) {
|
||||
registerError(tr("Invalid server name"));
|
||||
} else {
|
||||
QString username = username_input_->text();
|
||||
QString password = password_input_->text();
|
||||
QString server = server_input_->text();
|
||||
if (!username_input_->hasAcceptableInput()) {
|
||||
registerError(tr("Invalid username"));
|
||||
} else if (!password_input_->hasAcceptableInput()) {
|
||||
registerError(tr("Password is not long enough (min 8 chars)"));
|
||||
} else if (password_input_->text() != password_confirmation_->text()) {
|
||||
registerError(tr("Passwords don't match"));
|
||||
} else if (!server_input_->hasAcceptableInput()) {
|
||||
registerError(tr("Invalid server name"));
|
||||
} else {
|
||||
QString username = username_input_->text();
|
||||
QString password = password_input_->text();
|
||||
QString server = server_input_->text();
|
||||
|
||||
client_->registerUser(username, password, server);
|
||||
}
|
||||
client_->registerUser(username, password, server);
|
||||
}
|
||||
}
|
||||
|
||||
RegisterPage::~RegisterPage()
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
#include "Theme.h"
|
||||
|
||||
RoomInfoListItem::RoomInfoListItem(QSharedPointer<RoomSettings> settings,
|
||||
RoomState state,
|
||||
QString room_id,
|
||||
QWidget *parent)
|
||||
RoomState state,
|
||||
QString room_id,
|
||||
QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, state_(state)
|
||||
, roomId_(room_id)
|
||||
|
@ -37,264 +37,277 @@ RoomInfoListItem::RoomInfoListItem(QSharedPointer<RoomSettings> settings,
|
|||
, maxHeight_(IconSize + 2 * Padding)
|
||||
, unreadMsgCount_(0)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setMouseTracking(true);
|
||||
setAttribute(Qt::WA_Hover);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setMouseTracking(true);
|
||||
setAttribute(Qt::WA_Hover);
|
||||
|
||||
setFixedHeight(maxHeight_);
|
||||
setFixedHeight(maxHeight_);
|
||||
|
||||
QPainterPath path;
|
||||
path.addRect(0, 0, parent->width(), height());
|
||||
QPainterPath path;
|
||||
path.addRect(0, 0, parent->width(), height());
|
||||
|
||||
ripple_overlay_ = new RippleOverlay(this);
|
||||
ripple_overlay_->setClipPath(path);
|
||||
ripple_overlay_->setClipping(true);
|
||||
ripple_overlay_ = new RippleOverlay(this);
|
||||
ripple_overlay_->setClipPath(path);
|
||||
ripple_overlay_->setClipping(true);
|
||||
|
||||
menu_ = new Menu(this);
|
||||
menu_ = new Menu(this);
|
||||
|
||||
toggleNotifications_ = new QAction(notificationText(), this);
|
||||
toggleNotifications_ = new QAction(notificationText(), this);
|
||||
|
||||
connect(toggleNotifications_, &QAction::triggered, this, [=]() { roomSettings_->toggleNotifications(); });
|
||||
connect(toggleNotifications_, &QAction::triggered, this, [=]() {
|
||||
roomSettings_->toggleNotifications();
|
||||
});
|
||||
|
||||
menu_->addAction(toggleNotifications_);
|
||||
menu_->addAction(toggleNotifications_);
|
||||
}
|
||||
|
||||
QString
|
||||
RoomInfoListItem::notificationText()
|
||||
{
|
||||
if (roomSettings_.isNull() || roomSettings_->isNotificationsEnabled())
|
||||
return QString(tr("Disable notifications"));
|
||||
if (roomSettings_.isNull() || roomSettings_->isNotificationsEnabled())
|
||||
return QString(tr("Disable notifications"));
|
||||
|
||||
return tr("Enable notifications");
|
||||
return tr("Enable notifications");
|
||||
}
|
||||
|
||||
void
|
||||
RoomInfoListItem::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
// Update ripple's clipping path.
|
||||
QPainterPath path;
|
||||
path.addRect(0, 0, width(), height());
|
||||
// Update ripple's clipping path.
|
||||
QPainterPath path;
|
||||
path.addRect(0, 0, width(), height());
|
||||
|
||||
ripple_overlay_->setClipPath(path);
|
||||
ripple_overlay_->setClipping(true);
|
||||
ripple_overlay_->setClipPath(path);
|
||||
ripple_overlay_->setClipping(true);
|
||||
}
|
||||
|
||||
void
|
||||
RoomInfoListItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(event);
|
||||
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::TextAntialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::TextAntialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
if (isPressed_)
|
||||
p.fillRect(rect(), QColor("#38A3D8"));
|
||||
else if (underMouse())
|
||||
p.fillRect(rect(), QColor(200, 200, 200, 128));
|
||||
else
|
||||
p.fillRect(rect(), QColor("#F8FBFE"));
|
||||
if (isPressed_)
|
||||
p.fillRect(rect(), QColor("#38A3D8"));
|
||||
else if (underMouse())
|
||||
p.fillRect(rect(), QColor(200, 200, 200, 128));
|
||||
else
|
||||
p.fillRect(rect(), QColor("#F8FBFE"));
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(conf::fontSize);
|
||||
QFontMetrics metrics(font);
|
||||
QFont font;
|
||||
font.setPixelSize(conf::fontSize);
|
||||
QFontMetrics metrics(font);
|
||||
|
||||
p.setPen(QColor("#333"));
|
||||
p.setPen(QColor("#333"));
|
||||
|
||||
QRect avatarRegion(Padding, Padding, IconSize, IconSize);
|
||||
QRect avatarRegion(Padding, Padding, IconSize, IconSize);
|
||||
|
||||
// Description line with the default font.
|
||||
int bottom_y = maxHeight_ - Padding - Padding / 3 - metrics.ascent() / 2;
|
||||
// Description line with the default font.
|
||||
int bottom_y = maxHeight_ - Padding - Padding / 3 - metrics.ascent() / 2;
|
||||
|
||||
if (width() > ui::sidebar::SmallSize) {
|
||||
if (isPressed_) {
|
||||
QPen pen(QColor("white"));
|
||||
p.setPen(pen);
|
||||
}
|
||||
if (width() > ui::sidebar::SmallSize) {
|
||||
if (isPressed_) {
|
||||
QPen pen(QColor("white"));
|
||||
p.setPen(pen);
|
||||
}
|
||||
|
||||
font.setPixelSize(conf::roomlist::fonts::heading);
|
||||
p.setFont(font);
|
||||
font.setPixelSize(conf::roomlist::fonts::heading);
|
||||
p.setFont(font);
|
||||
|
||||
// Name line.
|
||||
QFontMetrics fontNameMetrics(font);
|
||||
int top_y = 2 * Padding + fontNameMetrics.ascent() / 2;
|
||||
// Name line.
|
||||
QFontMetrics fontNameMetrics(font);
|
||||
int top_y = 2 * Padding + fontNameMetrics.ascent() / 2;
|
||||
|
||||
auto name =
|
||||
metrics.elidedText(state_.getName(), Qt::ElideRight, (width() - IconSize - 2 * Padding) * 0.8);
|
||||
p.drawText(QPoint(2 * Padding + IconSize, top_y), name);
|
||||
auto name = metrics.elidedText(
|
||||
state_.getName(), Qt::ElideRight, (width() - IconSize - 2 * Padding) * 0.8);
|
||||
p.drawText(QPoint(2 * Padding + IconSize, top_y), name);
|
||||
|
||||
if (!isPressed_) {
|
||||
QPen pen(QColor("#5d6565"));
|
||||
p.setPen(pen);
|
||||
}
|
||||
if (!isPressed_) {
|
||||
QPen pen(QColor("#5d6565"));
|
||||
p.setPen(pen);
|
||||
}
|
||||
|
||||
font.setPixelSize(conf::fontSize);
|
||||
p.setFont(font);
|
||||
font.setPixelSize(conf::fontSize);
|
||||
p.setFont(font);
|
||||
|
||||
auto msgStampWidth = QFontMetrics(font).width(lastMsgInfo_.timestamp) + 5;
|
||||
auto msgStampWidth = QFontMetrics(font).width(lastMsgInfo_.timestamp) + 5;
|
||||
|
||||
// The limit is the space between the end of the avatar and the start of the timestamp.
|
||||
int usernameLimit = std::max(0, width() - 3 * Padding - msgStampWidth - IconSize - 20);
|
||||
auto userName = metrics.elidedText(lastMsgInfo_.username, Qt::ElideRight, usernameLimit);
|
||||
// The limit is the space between the end of the avatar and the start of the
|
||||
// timestamp.
|
||||
int usernameLimit =
|
||||
std::max(0, width() - 3 * Padding - msgStampWidth - IconSize - 20);
|
||||
auto userName =
|
||||
metrics.elidedText(lastMsgInfo_.username, Qt::ElideRight, usernameLimit);
|
||||
|
||||
font.setBold(true);
|
||||
p.setFont(font);
|
||||
p.drawText(QPoint(2 * Padding + IconSize, bottom_y), userName);
|
||||
font.setBold(true);
|
||||
p.setFont(font);
|
||||
p.drawText(QPoint(2 * Padding + IconSize, bottom_y), userName);
|
||||
|
||||
int nameWidth = QFontMetrics(font).width(userName);
|
||||
int nameWidth = QFontMetrics(font).width(userName);
|
||||
|
||||
font.setBold(false);
|
||||
p.setFont(font);
|
||||
font.setBold(false);
|
||||
p.setFont(font);
|
||||
|
||||
// The limit is the space between the end of the username and the start of the timestamp.
|
||||
int descriptionLimit = std::max(0, width() - 3 * Padding - msgStampWidth - IconSize - nameWidth - 5);
|
||||
auto description = metrics.elidedText(lastMsgInfo_.body, Qt::ElideRight, descriptionLimit);
|
||||
p.drawText(QPoint(2 * Padding + IconSize + nameWidth, bottom_y), description);
|
||||
// The limit is the space between the end of the username and the start of the
|
||||
// timestamp.
|
||||
int descriptionLimit =
|
||||
std::max(0, width() - 3 * Padding - msgStampWidth - IconSize - nameWidth - 5);
|
||||
auto description =
|
||||
metrics.elidedText(lastMsgInfo_.body, Qt::ElideRight, descriptionLimit);
|
||||
p.drawText(QPoint(2 * Padding + IconSize + nameWidth, bottom_y), description);
|
||||
|
||||
// We either show the bubble or the last message timestamp.
|
||||
if (unreadMsgCount_ == 0) {
|
||||
font.setBold(true);
|
||||
p.drawText(QPoint(width() - Padding - msgStampWidth, bottom_y), lastMsgInfo_.timestamp);
|
||||
}
|
||||
}
|
||||
// We either show the bubble or the last message timestamp.
|
||||
if (unreadMsgCount_ == 0) {
|
||||
font.setBold(true);
|
||||
p.drawText(QPoint(width() - Padding - msgStampWidth, bottom_y),
|
||||
lastMsgInfo_.timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
font.setBold(false);
|
||||
p.setPen(Qt::NoPen);
|
||||
font.setBold(false);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
// We using the first letter of room's name.
|
||||
if (roomAvatar_.isNull()) {
|
||||
QBrush brush;
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
brush.setColor("#eee");
|
||||
// We using the first letter of room's name.
|
||||
if (roomAvatar_.isNull()) {
|
||||
QBrush brush;
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
brush.setColor("#eee");
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(brush);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(brush);
|
||||
|
||||
p.drawEllipse(avatarRegion.center(), IconSize / 2, IconSize / 2);
|
||||
p.drawEllipse(avatarRegion.center(), IconSize / 2, IconSize / 2);
|
||||
|
||||
font.setPixelSize(conf::roomlist::fonts::bubble);
|
||||
p.setFont(font);
|
||||
p.setPen(QColor("#333"));
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawText(avatarRegion.translated(0, -1), Qt::AlignCenter, QChar(state_.getName()[0]));
|
||||
} else {
|
||||
p.save();
|
||||
font.setPixelSize(conf::roomlist::fonts::bubble);
|
||||
p.setFont(font);
|
||||
p.setPen(QColor("#333"));
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawText(
|
||||
avatarRegion.translated(0, -1), Qt::AlignCenter, QChar(state_.getName()[0]));
|
||||
} else {
|
||||
p.save();
|
||||
|
||||
QPainterPath path;
|
||||
path.addEllipse(Padding, Padding, IconSize, IconSize);
|
||||
p.setClipPath(path);
|
||||
QPainterPath path;
|
||||
path.addEllipse(Padding, Padding, IconSize, IconSize);
|
||||
p.setClipPath(path);
|
||||
|
||||
p.drawPixmap(avatarRegion, roomAvatar_);
|
||||
p.restore();
|
||||
}
|
||||
p.drawPixmap(avatarRegion, roomAvatar_);
|
||||
p.restore();
|
||||
}
|
||||
|
||||
if (unreadMsgCount_ > 0) {
|
||||
QColor textColor("white");
|
||||
QColor backgroundColor("#38A3D8");
|
||||
if (unreadMsgCount_ > 0) {
|
||||
QColor textColor("white");
|
||||
QColor backgroundColor("#38A3D8");
|
||||
|
||||
QBrush brush;
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
brush.setColor(backgroundColor);
|
||||
QBrush brush;
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
brush.setColor(backgroundColor);
|
||||
|
||||
if (isPressed_)
|
||||
brush.setColor(textColor);
|
||||
if (isPressed_)
|
||||
brush.setColor(textColor);
|
||||
|
||||
QFont unreadCountFont;
|
||||
unreadCountFont.setPixelSize(conf::roomlist::fonts::badge);
|
||||
unreadCountFont.setBold(true);
|
||||
QFont unreadCountFont;
|
||||
unreadCountFont.setPixelSize(conf::roomlist::fonts::badge);
|
||||
unreadCountFont.setBold(true);
|
||||
|
||||
p.setBrush(brush);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setFont(unreadCountFont);
|
||||
p.setBrush(brush);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setFont(unreadCountFont);
|
||||
|
||||
int diameter = 20;
|
||||
int diameter = 20;
|
||||
|
||||
QRectF r(width() - diameter - Padding, bottom_y - diameter / 2 - 5, diameter, diameter);
|
||||
QRectF r(
|
||||
width() - diameter - Padding, bottom_y - diameter / 2 - 5, diameter, diameter);
|
||||
|
||||
if (width() == ui::sidebar::SmallSize)
|
||||
r = QRectF(width() - diameter - 5, height() - diameter - 5, diameter, diameter);
|
||||
if (width() == ui::sidebar::SmallSize)
|
||||
r = QRectF(
|
||||
width() - diameter - 5, height() - diameter - 5, diameter, diameter);
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(r);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(r);
|
||||
|
||||
p.setPen(QPen(textColor));
|
||||
p.setPen(QPen(textColor));
|
||||
|
||||
if (isPressed_)
|
||||
p.setPen(QPen(backgroundColor));
|
||||
if (isPressed_)
|
||||
p.setPen(QPen(backgroundColor));
|
||||
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawText(r.translated(0, -0.5), Qt::AlignCenter, QString::number(unreadMsgCount_));
|
||||
}
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawText(
|
||||
r.translated(0, -0.5), Qt::AlignCenter, QString::number(unreadMsgCount_));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoomInfoListItem::updateUnreadMessageCount(int count)
|
||||
{
|
||||
unreadMsgCount_ += count;
|
||||
update();
|
||||
unreadMsgCount_ += count;
|
||||
update();
|
||||
}
|
||||
|
||||
void
|
||||
RoomInfoListItem::clearUnreadMessageCount()
|
||||
{
|
||||
unreadMsgCount_ = 0;
|
||||
update();
|
||||
unreadMsgCount_ = 0;
|
||||
update();
|
||||
}
|
||||
|
||||
void
|
||||
RoomInfoListItem::setPressedState(bool state)
|
||||
{
|
||||
if (!isPressed_ && state) {
|
||||
isPressed_ = state;
|
||||
update();
|
||||
} else if (isPressed_ && !state) {
|
||||
isPressed_ = state;
|
||||
update();
|
||||
}
|
||||
if (!isPressed_ && state) {
|
||||
isPressed_ = state;
|
||||
update();
|
||||
} else if (isPressed_ && !state) {
|
||||
isPressed_ = state;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoomInfoListItem::setState(const RoomState &new_state)
|
||||
{
|
||||
state_ = new_state;
|
||||
update();
|
||||
state_ = new_state;
|
||||
update();
|
||||
}
|
||||
|
||||
void
|
||||
RoomInfoListItem::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(event);
|
||||
|
||||
toggleNotifications_->setText(notificationText());
|
||||
menu_->popup(event->globalPos());
|
||||
toggleNotifications_->setText(notificationText());
|
||||
menu_->popup(event->globalPos());
|
||||
}
|
||||
|
||||
void
|
||||
RoomInfoListItem::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->buttons() == Qt::RightButton) {
|
||||
QWidget::mousePressEvent(event);
|
||||
return;
|
||||
}
|
||||
if (event->buttons() == Qt::RightButton) {
|
||||
QWidget::mousePressEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
emit clicked(roomId_);
|
||||
emit clicked(roomId_);
|
||||
|
||||
setPressedState(true);
|
||||
setPressedState(true);
|
||||
|
||||
// Ripple on mouse position by default.
|
||||
QPoint pos = event->pos();
|
||||
qreal radiusEndValue = static_cast<qreal>(width()) / 3;
|
||||
// Ripple on mouse position by default.
|
||||
QPoint pos = event->pos();
|
||||
qreal radiusEndValue = static_cast<qreal>(width()) / 3;
|
||||
|
||||
Ripple *ripple = new Ripple(pos);
|
||||
Ripple *ripple = new Ripple(pos);
|
||||
|
||||
ripple->setRadiusEndValue(radiusEndValue);
|
||||
ripple->setOpacityStartValue(0.15);
|
||||
ripple->setColor(QColor("white"));
|
||||
ripple->radiusAnimation()->setDuration(200);
|
||||
ripple->opacityAnimation()->setDuration(400);
|
||||
ripple->setRadiusEndValue(radiusEndValue);
|
||||
ripple->setOpacityStartValue(0.15);
|
||||
ripple->setColor(QColor("white"));
|
||||
ripple->radiusAnimation()->setDuration(200);
|
||||
ripple->opacityAnimation()->setDuration(400);
|
||||
|
||||
ripple_overlay_->addRipple(ripple);
|
||||
ripple_overlay_->addRipple(ripple);
|
||||
}
|
||||
|
||||
RoomInfoListItem::~RoomInfoListItem()
|
||||
|
|
201
src/RoomList.cc
201
src/RoomList.cc
|
@ -27,38 +27,38 @@ RoomList::RoomList(QSharedPointer<MatrixClient> client, QWidget *parent)
|
|||
: QWidget(parent)
|
||||
, client_(client)
|
||||
{
|
||||
setStyleSheet("QWidget { border: none; }");
|
||||
setStyleSheet("QWidget { border: none; }");
|
||||
|
||||
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
setSizePolicy(sizePolicy);
|
||||
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
setSizePolicy(sizePolicy);
|
||||
|
||||
topLayout_ = new QVBoxLayout(this);
|
||||
topLayout_->setSpacing(0);
|
||||
topLayout_->setMargin(0);
|
||||
topLayout_ = new QVBoxLayout(this);
|
||||
topLayout_->setSpacing(0);
|
||||
topLayout_->setMargin(0);
|
||||
|
||||
scrollArea_ = new QScrollArea(this);
|
||||
scrollArea_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
scrollArea_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
scrollArea_->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
||||
scrollArea_->setWidgetResizable(true);
|
||||
scrollArea_->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
|
||||
scrollArea_ = new QScrollArea(this);
|
||||
scrollArea_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
scrollArea_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
scrollArea_->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
||||
scrollArea_->setWidgetResizable(true);
|
||||
scrollArea_->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
scrollAreaContents_ = new QWidget();
|
||||
scrollAreaContents_ = new QWidget();
|
||||
|
||||
contentsLayout_ = new QVBoxLayout(scrollAreaContents_);
|
||||
contentsLayout_->setSpacing(0);
|
||||
contentsLayout_->setMargin(0);
|
||||
contentsLayout_->addStretch(1);
|
||||
contentsLayout_ = new QVBoxLayout(scrollAreaContents_);
|
||||
contentsLayout_->setSpacing(0);
|
||||
contentsLayout_->setMargin(0);
|
||||
contentsLayout_->addStretch(1);
|
||||
|
||||
scrollArea_->setWidget(scrollAreaContents_);
|
||||
topLayout_->addWidget(scrollArea_);
|
||||
scrollArea_->setWidget(scrollAreaContents_);
|
||||
topLayout_->addWidget(scrollArea_);
|
||||
|
||||
connect(client_.data(),
|
||||
SIGNAL(roomAvatarRetrieved(const QString &, const QPixmap &)),
|
||||
this,
|
||||
SLOT(updateRoomAvatar(const QString &, const QPixmap &)));
|
||||
connect(client_.data(),
|
||||
SIGNAL(roomAvatarRetrieved(const QString &, const QPixmap &)),
|
||||
this,
|
||||
SLOT(updateRoomAvatar(const QString &, const QPixmap &)));
|
||||
}
|
||||
|
||||
RoomList::~RoomList()
|
||||
|
@ -68,137 +68,140 @@ RoomList::~RoomList()
|
|||
void
|
||||
RoomList::clear()
|
||||
{
|
||||
rooms_.clear();
|
||||
rooms_.clear();
|
||||
}
|
||||
|
||||
void
|
||||
RoomList::updateUnreadMessageCount(const QString &roomid, int count)
|
||||
{
|
||||
if (!rooms_.contains(roomid)) {
|
||||
qWarning() << "UpdateUnreadMessageCount: Unknown roomid";
|
||||
return;
|
||||
}
|
||||
if (!rooms_.contains(roomid)) {
|
||||
qWarning() << "UpdateUnreadMessageCount: Unknown roomid";
|
||||
return;
|
||||
}
|
||||
|
||||
rooms_[roomid]->updateUnreadMessageCount(count);
|
||||
rooms_[roomid]->updateUnreadMessageCount(count);
|
||||
|
||||
calculateUnreadMessageCount();
|
||||
calculateUnreadMessageCount();
|
||||
}
|
||||
|
||||
void
|
||||
RoomList::calculateUnreadMessageCount()
|
||||
{
|
||||
int total_unread_msgs = 0;
|
||||
int total_unread_msgs = 0;
|
||||
|
||||
for (const auto &room : rooms_)
|
||||
total_unread_msgs += room->unreadMessageCount();
|
||||
for (const auto &room : rooms_)
|
||||
total_unread_msgs += room->unreadMessageCount();
|
||||
|
||||
emit totalUnreadMessageCountUpdated(total_unread_msgs);
|
||||
emit totalUnreadMessageCountUpdated(total_unread_msgs);
|
||||
}
|
||||
|
||||
void
|
||||
RoomList::setInitialRooms(const QMap<QString, QSharedPointer<RoomSettings>> &settings,
|
||||
const QMap<QString, RoomState> &states)
|
||||
const QMap<QString, RoomState> &states)
|
||||
{
|
||||
rooms_.clear();
|
||||
rooms_.clear();
|
||||
|
||||
if (settings.size() != states.size()) {
|
||||
qWarning() << "Initializing room list";
|
||||
qWarning() << "Different number of room states and room settings";
|
||||
return;
|
||||
}
|
||||
if (settings.size() != states.size()) {
|
||||
qWarning() << "Initializing room list";
|
||||
qWarning() << "Different number of room states and room settings";
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = states.constBegin(); it != states.constEnd(); it++) {
|
||||
auto room_id = it.key();
|
||||
auto state = it.value();
|
||||
for (auto it = states.constBegin(); it != states.constEnd(); it++) {
|
||||
auto room_id = it.key();
|
||||
auto state = it.value();
|
||||
|
||||
if (!state.getAvatar().toString().isEmpty())
|
||||
client_->fetchRoomAvatar(room_id, state.getAvatar());
|
||||
if (!state.getAvatar().toString().isEmpty())
|
||||
client_->fetchRoomAvatar(room_id, state.getAvatar());
|
||||
|
||||
RoomInfoListItem *room_item = new RoomInfoListItem(settings[room_id], state, room_id, scrollArea_);
|
||||
connect(room_item, &RoomInfoListItem::clicked, this, &RoomList::highlightSelectedRoom);
|
||||
RoomInfoListItem *room_item =
|
||||
new RoomInfoListItem(settings[room_id], state, room_id, scrollArea_);
|
||||
connect(
|
||||
room_item, &RoomInfoListItem::clicked, this, &RoomList::highlightSelectedRoom);
|
||||
|
||||
rooms_.insert(room_id, QSharedPointer<RoomInfoListItem>(room_item));
|
||||
rooms_.insert(room_id, QSharedPointer<RoomInfoListItem>(room_item));
|
||||
|
||||
int pos = contentsLayout_->count() - 1;
|
||||
contentsLayout_->insertWidget(pos, room_item);
|
||||
}
|
||||
int pos = contentsLayout_->count() - 1;
|
||||
contentsLayout_->insertWidget(pos, room_item);
|
||||
}
|
||||
|
||||
if (rooms_.isEmpty())
|
||||
return;
|
||||
if (rooms_.isEmpty())
|
||||
return;
|
||||
|
||||
auto first_room = rooms_.first();
|
||||
first_room->setPressedState(true);
|
||||
auto first_room = rooms_.first();
|
||||
first_room->setPressedState(true);
|
||||
|
||||
emit roomChanged(rooms_.firstKey());
|
||||
emit roomChanged(rooms_.firstKey());
|
||||
}
|
||||
|
||||
void
|
||||
RoomList::sync(const QMap<QString, RoomState> &states)
|
||||
{
|
||||
for (auto it = states.constBegin(); it != states.constEnd(); it++) {
|
||||
auto room_id = it.key();
|
||||
auto state = it.value();
|
||||
for (auto it = states.constBegin(); it != states.constEnd(); it++) {
|
||||
auto room_id = it.key();
|
||||
auto state = it.value();
|
||||
|
||||
// TODO: Add the new room to the list.
|
||||
if (!rooms_.contains(room_id))
|
||||
continue;
|
||||
// TODO: Add the new room to the list.
|
||||
if (!rooms_.contains(room_id))
|
||||
continue;
|
||||
|
||||
auto room = rooms_[room_id];
|
||||
auto room = rooms_[room_id];
|
||||
|
||||
auto current_avatar = room->state().getAvatar();
|
||||
auto new_avatar = state.getAvatar();
|
||||
auto current_avatar = room->state().getAvatar();
|
||||
auto new_avatar = state.getAvatar();
|
||||
|
||||
if (current_avatar != new_avatar && !new_avatar.toString().isEmpty())
|
||||
client_->fetchRoomAvatar(room_id, new_avatar);
|
||||
if (current_avatar != new_avatar && !new_avatar.toString().isEmpty())
|
||||
client_->fetchRoomAvatar(room_id, new_avatar);
|
||||
|
||||
room->setState(state);
|
||||
}
|
||||
room->setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoomList::highlightSelectedRoom(const QString &room_id)
|
||||
{
|
||||
emit roomChanged(room_id);
|
||||
emit roomChanged(room_id);
|
||||
|
||||
if (!rooms_.contains(room_id)) {
|
||||
qDebug() << "RoomList: clicked unknown roomid";
|
||||
return;
|
||||
}
|
||||
if (!rooms_.contains(room_id)) {
|
||||
qDebug() << "RoomList: clicked unknown roomid";
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Send a read receipt for the last event.
|
||||
auto room = rooms_[room_id];
|
||||
room->clearUnreadMessageCount();
|
||||
// TODO: Send a read receipt for the last event.
|
||||
auto room = rooms_[room_id];
|
||||
room->clearUnreadMessageCount();
|
||||
|
||||
calculateUnreadMessageCount();
|
||||
calculateUnreadMessageCount();
|
||||
|
||||
for (auto it = rooms_.constBegin(); it != rooms_.constEnd(); it++) {
|
||||
if (it.key() != room_id) {
|
||||
it.value()->setPressedState(false);
|
||||
} else {
|
||||
it.value()->setPressedState(true);
|
||||
scrollArea_->ensureWidgetVisible(qobject_cast<QWidget *>(it.value().data()));
|
||||
}
|
||||
}
|
||||
for (auto it = rooms_.constBegin(); it != rooms_.constEnd(); it++) {
|
||||
if (it.key() != room_id) {
|
||||
it.value()->setPressedState(false);
|
||||
} else {
|
||||
it.value()->setPressedState(true);
|
||||
scrollArea_->ensureWidgetVisible(
|
||||
qobject_cast<QWidget *>(it.value().data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoomList::updateRoomAvatar(const QString &roomid, const QPixmap &img)
|
||||
{
|
||||
if (!rooms_.contains(roomid)) {
|
||||
qWarning() << "Avatar update on non existent room" << roomid;
|
||||
return;
|
||||
}
|
||||
if (!rooms_.contains(roomid)) {
|
||||
qWarning() << "Avatar update on non existent room" << roomid;
|
||||
return;
|
||||
}
|
||||
|
||||
rooms_.value(roomid)->setAvatar(img.toImage());
|
||||
rooms_.value(roomid)->setAvatar(img.toImage());
|
||||
}
|
||||
|
||||
void
|
||||
RoomList::updateRoomDescription(const QString &roomid, const DescInfo &info)
|
||||
{
|
||||
if (!rooms_.contains(roomid)) {
|
||||
qWarning() << "Description update on non existent room" << roomid << info.body;
|
||||
return;
|
||||
}
|
||||
if (!rooms_.contains(roomid)) {
|
||||
qWarning() << "Description update on non existent room" << roomid << info.body;
|
||||
return;
|
||||
}
|
||||
|
||||
rooms_.value(roomid)->setDescriptionMessage(info);
|
||||
rooms_.value(roomid)->setDescriptionMessage(info);
|
||||
}
|
||||
|
|
|
@ -20,24 +20,24 @@
|
|||
void
|
||||
RoomMessages::deserialize(const QJsonDocument &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("response is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("response is not a JSON object");
|
||||
|
||||
QJsonObject object = data.object();
|
||||
QJsonObject object = data.object();
|
||||
|
||||
if (!object.contains("start"))
|
||||
throw DeserializationException("start key is missing");
|
||||
if (!object.contains("start"))
|
||||
throw DeserializationException("start key is missing");
|
||||
|
||||
if (!object.contains("end"))
|
||||
throw DeserializationException("end key is missing");
|
||||
if (!object.contains("end"))
|
||||
throw DeserializationException("end key is missing");
|
||||
|
||||
if (!object.contains("chunk"))
|
||||
throw DeserializationException("chunk key is missing");
|
||||
if (!object.contains("chunk"))
|
||||
throw DeserializationException("chunk key is missing");
|
||||
|
||||
if (!object.value("chunk").isArray())
|
||||
throw DeserializationException("chunk isn't a JSON array");
|
||||
if (!object.value("chunk").isArray())
|
||||
throw DeserializationException("chunk isn't a JSON array");
|
||||
|
||||
start_ = object.value("start").toString();
|
||||
end_ = object.value("end").toString();
|
||||
chunk_ = object.value("chunk").toArray();
|
||||
start_ = object.value("start").toString();
|
||||
end_ = object.value("end").toString();
|
||||
chunk_ = object.value("chunk").toArray();
|
||||
}
|
||||
|
|
|
@ -20,19 +20,19 @@
|
|||
SlidingStackWidget::SlidingStackWidget(QWidget *parent)
|
||||
: QStackedWidget(parent)
|
||||
{
|
||||
window_ = parent;
|
||||
window_ = parent;
|
||||
|
||||
if (parent == Q_NULLPTR) {
|
||||
qDebug() << "Using nullptr for parent";
|
||||
window_ = this;
|
||||
}
|
||||
if (parent == Q_NULLPTR) {
|
||||
qDebug() << "Using nullptr for parent";
|
||||
window_ = this;
|
||||
}
|
||||
|
||||
current_position_ = QPoint(0, 0);
|
||||
speed_ = 400;
|
||||
now_ = 0;
|
||||
next_ = 0;
|
||||
active_ = false;
|
||||
animation_type_ = QEasingCurve::InOutCirc;
|
||||
current_position_ = QPoint(0, 0);
|
||||
speed_ = 400;
|
||||
now_ = 0;
|
||||
next_ = 0;
|
||||
active_ = false;
|
||||
animation_type_ = QEasingCurve::InOutCirc;
|
||||
}
|
||||
|
||||
SlidingStackWidget::~SlidingStackWidget()
|
||||
|
@ -42,116 +42,116 @@ SlidingStackWidget::~SlidingStackWidget()
|
|||
void
|
||||
SlidingStackWidget::slideInNext()
|
||||
{
|
||||
int now = currentIndex();
|
||||
int now = currentIndex();
|
||||
|
||||
if (now < count() - 1)
|
||||
slideInIndex(now + 1);
|
||||
if (now < count() - 1)
|
||||
slideInIndex(now + 1);
|
||||
}
|
||||
|
||||
void
|
||||
SlidingStackWidget::slideInPrevious()
|
||||
{
|
||||
int now = currentIndex();
|
||||
int now = currentIndex();
|
||||
|
||||
if (now > 0)
|
||||
slideInIndex(now - 1);
|
||||
if (now > 0)
|
||||
slideInIndex(now - 1);
|
||||
}
|
||||
|
||||
void
|
||||
SlidingStackWidget::slideInIndex(int index, AnimationDirection direction)
|
||||
{
|
||||
// Take into consideration possible index overflow/undeflow.
|
||||
if (index > count() - 1) {
|
||||
direction = AnimationDirection::RIGHT_TO_LEFT;
|
||||
index = index % count();
|
||||
} else if (index < 0) {
|
||||
direction = AnimationDirection::LEFT_TO_RIGHT;
|
||||
index = (index + count()) % count();
|
||||
}
|
||||
// Take into consideration possible index overflow/undeflow.
|
||||
if (index > count() - 1) {
|
||||
direction = AnimationDirection::RIGHT_TO_LEFT;
|
||||
index = index % count();
|
||||
} else if (index < 0) {
|
||||
direction = AnimationDirection::LEFT_TO_RIGHT;
|
||||
index = (index + count()) % count();
|
||||
}
|
||||
|
||||
slideInWidget(widget(index), direction);
|
||||
slideInWidget(widget(index), direction);
|
||||
}
|
||||
|
||||
void
|
||||
SlidingStackWidget::slideInWidget(QWidget *next_widget, AnimationDirection direction)
|
||||
{
|
||||
// If an animation is currenlty executing we should wait for it to finish before
|
||||
// another transition can start.
|
||||
if (active_)
|
||||
return;
|
||||
// If an animation is currenlty executing we should wait for it to finish before
|
||||
// another transition can start.
|
||||
if (active_)
|
||||
return;
|
||||
|
||||
active_ = true;
|
||||
active_ = true;
|
||||
|
||||
int now = currentIndex();
|
||||
int next = indexOf(next_widget);
|
||||
int now = currentIndex();
|
||||
int next = indexOf(next_widget);
|
||||
|
||||
if (now == next) {
|
||||
active_ = false;
|
||||
return;
|
||||
}
|
||||
if (now == next) {
|
||||
active_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int offset_x = frameRect().width();
|
||||
int offset_x = frameRect().width();
|
||||
|
||||
next_widget->setGeometry(0, 0, offset_x, 0);
|
||||
next_widget->setGeometry(0, 0, offset_x, 0);
|
||||
|
||||
if (direction == AnimationDirection::LEFT_TO_RIGHT) {
|
||||
offset_x = -offset_x;
|
||||
}
|
||||
if (direction == AnimationDirection::LEFT_TO_RIGHT) {
|
||||
offset_x = -offset_x;
|
||||
}
|
||||
|
||||
QPoint pnext = next_widget->pos();
|
||||
QPoint pnow = widget(now)->pos();
|
||||
current_position_ = pnow;
|
||||
QPoint pnext = next_widget->pos();
|
||||
QPoint pnow = widget(now)->pos();
|
||||
current_position_ = pnow;
|
||||
|
||||
// Reposition the next widget outside of the display area.
|
||||
next_widget->move(pnext.x() - offset_x, pnext.y());
|
||||
// Reposition the next widget outside of the display area.
|
||||
next_widget->move(pnext.x() - offset_x, pnext.y());
|
||||
|
||||
// Make the widget visible.
|
||||
next_widget->show();
|
||||
next_widget->raise();
|
||||
// Make the widget visible.
|
||||
next_widget->show();
|
||||
next_widget->raise();
|
||||
|
||||
// Animate both the next and now widget.
|
||||
QPropertyAnimation *animation_now = new QPropertyAnimation(widget(now), "pos", this);
|
||||
// Animate both the next and now widget.
|
||||
QPropertyAnimation *animation_now = new QPropertyAnimation(widget(now), "pos", this);
|
||||
|
||||
animation_now->setDuration(speed_);
|
||||
animation_now->setEasingCurve(animation_type_);
|
||||
animation_now->setStartValue(QPoint(pnow.x(), pnow.y()));
|
||||
animation_now->setEndValue(QPoint(pnow.x() + offset_x, pnow.y()));
|
||||
animation_now->setDuration(speed_);
|
||||
animation_now->setEasingCurve(animation_type_);
|
||||
animation_now->setStartValue(QPoint(pnow.x(), pnow.y()));
|
||||
animation_now->setEndValue(QPoint(pnow.x() + offset_x, pnow.y()));
|
||||
|
||||
QPropertyAnimation *animation_next = new QPropertyAnimation(next_widget, "pos", this);
|
||||
QPropertyAnimation *animation_next = new QPropertyAnimation(next_widget, "pos", this);
|
||||
|
||||
animation_next->setDuration(speed_);
|
||||
animation_next->setEasingCurve(animation_type_);
|
||||
animation_next->setStartValue(QPoint(pnext.x() - offset_x, pnext.y()));
|
||||
animation_next->setEndValue(QPoint(pnext.x(), pnext.y()));
|
||||
animation_next->setDuration(speed_);
|
||||
animation_next->setEasingCurve(animation_type_);
|
||||
animation_next->setStartValue(QPoint(pnext.x() - offset_x, pnext.y()));
|
||||
animation_next->setEndValue(QPoint(pnext.x(), pnext.y()));
|
||||
|
||||
QParallelAnimationGroup *animation_group = new QParallelAnimationGroup(this);
|
||||
QParallelAnimationGroup *animation_group = new QParallelAnimationGroup(this);
|
||||
|
||||
animation_group->addAnimation(animation_now);
|
||||
animation_group->addAnimation(animation_next);
|
||||
animation_group->addAnimation(animation_now);
|
||||
animation_group->addAnimation(animation_next);
|
||||
|
||||
connect(animation_group, SIGNAL(finished()), this, SLOT(onAnimationFinished()));
|
||||
connect(animation_group, SIGNAL(finished()), this, SLOT(onAnimationFinished()));
|
||||
|
||||
next_ = next;
|
||||
now_ = now;
|
||||
animation_group->start();
|
||||
next_ = next;
|
||||
now_ = now;
|
||||
animation_group->start();
|
||||
}
|
||||
|
||||
void
|
||||
SlidingStackWidget::onAnimationFinished()
|
||||
{
|
||||
setCurrentIndex(next_);
|
||||
setCurrentIndex(next_);
|
||||
|
||||
// The old widget is no longer necessary so we can hide it and
|
||||
// move it back to its original position.
|
||||
widget(now_)->hide();
|
||||
widget(now_)->move(current_position_);
|
||||
// The old widget is no longer necessary so we can hide it and
|
||||
// move it back to its original position.
|
||||
widget(now_)->hide();
|
||||
widget(now_)->move(current_position_);
|
||||
|
||||
active_ = false;
|
||||
emit animationFinished();
|
||||
active_ = false;
|
||||
emit animationFinished();
|
||||
}
|
||||
|
||||
int
|
||||
SlidingStackWidget::getWidgetIndex(QWidget *widget)
|
||||
{
|
||||
return indexOf(widget);
|
||||
return indexOf(widget);
|
||||
}
|
||||
|
|
|
@ -23,59 +23,59 @@
|
|||
Splitter::Splitter(QWidget *parent)
|
||||
: QSplitter(parent)
|
||||
{
|
||||
connect(this, &QSplitter::splitterMoved, this, &Splitter::onSplitterMoved);
|
||||
setChildrenCollapsible(false);
|
||||
connect(this, &QSplitter::splitterMoved, this, &Splitter::onSplitterMoved);
|
||||
setChildrenCollapsible(false);
|
||||
}
|
||||
|
||||
void
|
||||
Splitter::onSplitterMoved(int pos, int index)
|
||||
{
|
||||
Q_UNUSED(pos);
|
||||
Q_UNUSED(index);
|
||||
Q_UNUSED(pos);
|
||||
Q_UNUSED(index);
|
||||
|
||||
auto s = sizes();
|
||||
auto s = sizes();
|
||||
|
||||
if (s.count() < 2) {
|
||||
qWarning() << "Splitter needs at least two children";
|
||||
return;
|
||||
}
|
||||
if (s.count() < 2) {
|
||||
qWarning() << "Splitter needs at least two children";
|
||||
return;
|
||||
}
|
||||
|
||||
if (s[0] == ui::sidebar::NormalSize) {
|
||||
rightMoveCount_ += 1;
|
||||
if (s[0] == ui::sidebar::NormalSize) {
|
||||
rightMoveCount_ += 1;
|
||||
|
||||
if (rightMoveCount_ > moveEventLimit_) {
|
||||
auto left = widget(0);
|
||||
auto pos = left->mapFromGlobal(QCursor::pos());
|
||||
if (rightMoveCount_ > moveEventLimit_) {
|
||||
auto left = widget(0);
|
||||
auto pos = left->mapFromGlobal(QCursor::pos());
|
||||
|
||||
// if we are coming from the right, the cursor should
|
||||
// end up on the first widget.
|
||||
if (left->rect().contains(pos)) {
|
||||
left->setMinimumWidth(ui::sidebar::SmallSize);
|
||||
left->setMaximumWidth(ui::sidebar::SmallSize);
|
||||
// if we are coming from the right, the cursor should
|
||||
// end up on the first widget.
|
||||
if (left->rect().contains(pos)) {
|
||||
left->setMinimumWidth(ui::sidebar::SmallSize);
|
||||
left->setMaximumWidth(ui::sidebar::SmallSize);
|
||||
|
||||
rightMoveCount_ = 0;
|
||||
}
|
||||
}
|
||||
} else if (s[0] == ui::sidebar::SmallSize) {
|
||||
leftMoveCount_ += 1;
|
||||
rightMoveCount_ = 0;
|
||||
}
|
||||
}
|
||||
} else if (s[0] == ui::sidebar::SmallSize) {
|
||||
leftMoveCount_ += 1;
|
||||
|
||||
if (leftMoveCount_ > moveEventLimit_) {
|
||||
auto left = widget(0);
|
||||
auto right = widget(1);
|
||||
auto pos = right->mapFromGlobal(QCursor::pos());
|
||||
if (leftMoveCount_ > moveEventLimit_) {
|
||||
auto left = widget(0);
|
||||
auto right = widget(1);
|
||||
auto pos = right->mapFromGlobal(QCursor::pos());
|
||||
|
||||
// We move the start a little further so the transition isn't so abrupt.
|
||||
auto extended = right->rect();
|
||||
extended.translate(100, 0);
|
||||
// We move the start a little further so the transition isn't so abrupt.
|
||||
auto extended = right->rect();
|
||||
extended.translate(100, 0);
|
||||
|
||||
// if we are coming from the left, the cursor should
|
||||
// end up on the second widget.
|
||||
if (extended.contains(pos)) {
|
||||
left->setMinimumWidth(ui::sidebar::NormalSize);
|
||||
left->setMaximumWidth(2 * ui::sidebar::NormalSize);
|
||||
// if we are coming from the left, the cursor should
|
||||
// end up on the second widget.
|
||||
if (extended.contains(pos)) {
|
||||
left->setMinimumWidth(ui::sidebar::NormalSize);
|
||||
left->setMaximumWidth(2 * ui::sidebar::NormalSize);
|
||||
|
||||
leftMoveCount_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
leftMoveCount_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
190
src/Sync.cc
190
src/Sync.cc
|
@ -27,166 +27,166 @@
|
|||
void
|
||||
SyncResponse::deserialize(const QJsonDocument &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Sync response is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Sync response is not a JSON object");
|
||||
|
||||
QJsonObject object = data.object();
|
||||
QJsonObject object = data.object();
|
||||
|
||||
if (object.value("next_batch") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Sync: missing next_batch parameter");
|
||||
if (object.value("next_batch") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Sync: missing next_batch parameter");
|
||||
|
||||
if (object.value("rooms") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Sync: missing rooms parameter");
|
||||
if (object.value("rooms") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Sync: missing rooms parameter");
|
||||
|
||||
rooms_.deserialize(object.value("rooms"));
|
||||
next_batch_ = object.value("next_batch").toString();
|
||||
rooms_.deserialize(object.value("rooms"));
|
||||
next_batch_ = object.value("next_batch").toString();
|
||||
}
|
||||
|
||||
void
|
||||
Rooms::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Rooms value is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Rooms value is not a JSON object");
|
||||
|
||||
QJsonObject object = data.toObject();
|
||||
QJsonObject object = data.toObject();
|
||||
|
||||
if (!object.contains("join"))
|
||||
throw DeserializationException("rooms/join is missing");
|
||||
if (!object.contains("join"))
|
||||
throw DeserializationException("rooms/join is missing");
|
||||
|
||||
if (!object.contains("invite"))
|
||||
throw DeserializationException("rooms/invite is missing");
|
||||
if (!object.contains("invite"))
|
||||
throw DeserializationException("rooms/invite is missing");
|
||||
|
||||
if (!object.contains("leave"))
|
||||
throw DeserializationException("rooms/leave is missing");
|
||||
if (!object.contains("leave"))
|
||||
throw DeserializationException("rooms/leave is missing");
|
||||
|
||||
if (!object.value("join").isObject())
|
||||
throw DeserializationException("rooms/join must be a JSON object");
|
||||
if (!object.value("join").isObject())
|
||||
throw DeserializationException("rooms/join must be a JSON object");
|
||||
|
||||
if (!object.value("invite").isObject())
|
||||
throw DeserializationException("rooms/invite must be a JSON object");
|
||||
if (!object.value("invite").isObject())
|
||||
throw DeserializationException("rooms/invite must be a JSON object");
|
||||
|
||||
if (!object.value("leave").isObject())
|
||||
throw DeserializationException("rooms/leave must be a JSON object");
|
||||
if (!object.value("leave").isObject())
|
||||
throw DeserializationException("rooms/leave must be a JSON object");
|
||||
|
||||
auto join = object.value("join").toObject();
|
||||
auto join = object.value("join").toObject();
|
||||
|
||||
for (auto it = join.constBegin(); it != join.constEnd(); it++) {
|
||||
JoinedRoom tmp_room;
|
||||
for (auto it = join.constBegin(); it != join.constEnd(); it++) {
|
||||
JoinedRoom tmp_room;
|
||||
|
||||
try {
|
||||
tmp_room.deserialize(it.value());
|
||||
join_.insert(it.key(), tmp_room);
|
||||
} catch (DeserializationException &e) {
|
||||
qWarning() << e.what();
|
||||
qWarning() << "Skipping malformed object for room" << it.key();
|
||||
}
|
||||
}
|
||||
try {
|
||||
tmp_room.deserialize(it.value());
|
||||
join_.insert(it.key(), tmp_room);
|
||||
} catch (DeserializationException &e) {
|
||||
qWarning() << e.what();
|
||||
qWarning() << "Skipping malformed object for room" << it.key();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JoinedRoom::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("JoinedRoom is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("JoinedRoom is not a JSON object");
|
||||
|
||||
QJsonObject object = data.toObject();
|
||||
QJsonObject object = data.toObject();
|
||||
|
||||
if (!object.contains("state"))
|
||||
throw DeserializationException("join/state is missing");
|
||||
if (!object.contains("state"))
|
||||
throw DeserializationException("join/state is missing");
|
||||
|
||||
if (!object.contains("timeline"))
|
||||
throw DeserializationException("join/timeline is missing");
|
||||
if (!object.contains("timeline"))
|
||||
throw DeserializationException("join/timeline is missing");
|
||||
|
||||
if (!object.contains("account_data"))
|
||||
throw DeserializationException("join/account_data is missing");
|
||||
if (!object.contains("account_data"))
|
||||
throw DeserializationException("join/account_data is missing");
|
||||
|
||||
if (!object.contains("unread_notifications"))
|
||||
throw DeserializationException("join/unread_notifications is missing");
|
||||
if (!object.contains("unread_notifications"))
|
||||
throw DeserializationException("join/unread_notifications is missing");
|
||||
|
||||
if (!object.value("state").isObject())
|
||||
throw DeserializationException("join/state should be an object");
|
||||
if (!object.value("state").isObject())
|
||||
throw DeserializationException("join/state should be an object");
|
||||
|
||||
QJsonObject state = object.value("state").toObject();
|
||||
QJsonObject state = object.value("state").toObject();
|
||||
|
||||
if (!state.contains("events"))
|
||||
throw DeserializationException("join/state/events is missing");
|
||||
if (!state.contains("events"))
|
||||
throw DeserializationException("join/state/events is missing");
|
||||
|
||||
state_.deserialize(state.value("events"));
|
||||
timeline_.deserialize(object.value("timeline"));
|
||||
state_.deserialize(state.value("events"));
|
||||
timeline_.deserialize(object.value("timeline"));
|
||||
}
|
||||
|
||||
void
|
||||
Event::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Event is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Event is not a JSON object");
|
||||
|
||||
QJsonObject object = data.toObject();
|
||||
QJsonObject object = data.toObject();
|
||||
|
||||
if (!object.contains("content"))
|
||||
throw DeserializationException("event/content is missing");
|
||||
if (!object.contains("content"))
|
||||
throw DeserializationException("event/content is missing");
|
||||
|
||||
if (!object.contains("unsigned"))
|
||||
throw DeserializationException("event/content is missing");
|
||||
if (!object.contains("unsigned"))
|
||||
throw DeserializationException("event/content is missing");
|
||||
|
||||
if (!object.contains("sender"))
|
||||
throw DeserializationException("event/sender is missing");
|
||||
if (!object.contains("sender"))
|
||||
throw DeserializationException("event/sender is missing");
|
||||
|
||||
if (!object.contains("event_id"))
|
||||
throw DeserializationException("event/event_id is missing");
|
||||
if (!object.contains("event_id"))
|
||||
throw DeserializationException("event/event_id is missing");
|
||||
|
||||
// TODO: Make this optional
|
||||
/* if (!object.contains("state_key")) */
|
||||
/* throw DeserializationException("event/state_key is missing"); */
|
||||
// TODO: Make this optional
|
||||
/* if (!object.contains("state_key")) */
|
||||
/* throw DeserializationException("event/state_key is missing"); */
|
||||
|
||||
if (!object.contains("type"))
|
||||
throw DeserializationException("event/type is missing");
|
||||
if (!object.contains("type"))
|
||||
throw DeserializationException("event/type is missing");
|
||||
|
||||
if (!object.contains("origin_server_ts"))
|
||||
throw DeserializationException("event/origin_server_ts is missing");
|
||||
if (!object.contains("origin_server_ts"))
|
||||
throw DeserializationException("event/origin_server_ts is missing");
|
||||
|
||||
content_ = object.value("content").toObject();
|
||||
unsigned_ = object.value("unsigned").toObject();
|
||||
content_ = object.value("content").toObject();
|
||||
unsigned_ = object.value("unsigned").toObject();
|
||||
|
||||
sender_ = object.value("sender").toString();
|
||||
state_key_ = object.value("state_key").toString();
|
||||
type_ = object.value("type").toString();
|
||||
event_id_ = object.value("event_id").toString();
|
||||
sender_ = object.value("sender").toString();
|
||||
state_key_ = object.value("state_key").toString();
|
||||
type_ = object.value("type").toString();
|
||||
event_id_ = object.value("event_id").toString();
|
||||
|
||||
origin_server_ts_ = object.value("origin_server_ts").toDouble();
|
||||
origin_server_ts_ = object.value("origin_server_ts").toDouble();
|
||||
}
|
||||
|
||||
void
|
||||
State::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isArray())
|
||||
throw DeserializationException("State is not a JSON array");
|
||||
if (!data.isArray())
|
||||
throw DeserializationException("State is not a JSON array");
|
||||
|
||||
events_ = data.toArray();
|
||||
events_ = data.toArray();
|
||||
}
|
||||
|
||||
void
|
||||
Timeline::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Timeline is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Timeline is not a JSON object");
|
||||
|
||||
auto object = data.toObject();
|
||||
auto object = data.toObject();
|
||||
|
||||
if (!object.contains("events"))
|
||||
throw DeserializationException("timeline/events is missing");
|
||||
if (!object.contains("events"))
|
||||
throw DeserializationException("timeline/events is missing");
|
||||
|
||||
if (!object.contains("prev_batch"))
|
||||
throw DeserializationException("timeline/prev_batch is missing");
|
||||
if (!object.contains("prev_batch"))
|
||||
throw DeserializationException("timeline/prev_batch is missing");
|
||||
|
||||
if (!object.contains("limited"))
|
||||
throw DeserializationException("timeline/limited is missing");
|
||||
if (!object.contains("limited"))
|
||||
throw DeserializationException("timeline/limited is missing");
|
||||
|
||||
prev_batch_ = object.value("prev_batch").toString();
|
||||
limited_ = object.value("limited").toBool();
|
||||
prev_batch_ = object.value("prev_batch").toString();
|
||||
limited_ = object.value("limited").toBool();
|
||||
|
||||
if (!object.value("events").isArray())
|
||||
throw DeserializationException("timeline/events is not a JSON array");
|
||||
if (!object.value("events").isArray())
|
||||
throw DeserializationException("timeline/events is not a JSON array");
|
||||
|
||||
events_ = object.value("events").toArray();
|
||||
events_ = object.value("events").toArray();
|
||||
}
|
||||
|
|
|
@ -27,69 +27,75 @@
|
|||
MsgCountComposedIcon::MsgCountComposedIcon(const QString &filename)
|
||||
: QIconEngine()
|
||||
{
|
||||
icon_ = QIcon(filename);
|
||||
icon_ = QIcon(filename);
|
||||
}
|
||||
|
||||
void
|
||||
MsgCountComposedIcon::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state)
|
||||
MsgCountComposedIcon::paint(QPainter *painter,
|
||||
const QRect &rect,
|
||||
QIcon::Mode mode,
|
||||
QIcon::State state)
|
||||
{
|
||||
painter->setRenderHint(QPainter::TextAntialiasing);
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setRenderHint(QPainter::TextAntialiasing);
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
icon_.paint(painter, rect, Qt::AlignCenter, mode, state);
|
||||
icon_.paint(painter, rect, Qt::AlignCenter, mode, state);
|
||||
|
||||
if (msgCount <= 0)
|
||||
return;
|
||||
if (msgCount <= 0)
|
||||
return;
|
||||
|
||||
QColor backgroundColor("red");
|
||||
QColor textColor("white");
|
||||
QColor backgroundColor("red");
|
||||
QColor textColor("white");
|
||||
|
||||
QBrush brush;
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
brush.setColor(backgroundColor);
|
||||
QBrush brush;
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
brush.setColor(backgroundColor);
|
||||
|
||||
painter->setBrush(brush);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setFont(QFont("Open Sans", 8, QFont::Black));
|
||||
painter->setBrush(brush);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setFont(QFont("Open Sans", 8, QFont::Black));
|
||||
|
||||
QRectF bubble(rect.width() - BubbleDiameter, rect.height() - BubbleDiameter, BubbleDiameter, BubbleDiameter);
|
||||
painter->drawEllipse(bubble);
|
||||
painter->setPen(QPen(textColor));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawText(bubble, Qt::AlignCenter, QString::number(msgCount));
|
||||
QRectF bubble(rect.width() - BubbleDiameter,
|
||||
rect.height() - BubbleDiameter,
|
||||
BubbleDiameter,
|
||||
BubbleDiameter);
|
||||
painter->drawEllipse(bubble);
|
||||
painter->setPen(QPen(textColor));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawText(bubble, Qt::AlignCenter, QString::number(msgCount));
|
||||
}
|
||||
|
||||
QIconEngine *
|
||||
MsgCountComposedIcon::clone() const
|
||||
{
|
||||
return new MsgCountComposedIcon(*this);
|
||||
return new MsgCountComposedIcon(*this);
|
||||
}
|
||||
|
||||
TrayIcon::TrayIcon(const QString &filename, QWidget *parent)
|
||||
: QSystemTrayIcon(parent)
|
||||
{
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
setIcon(QIcon(filename));
|
||||
setIcon(QIcon(filename));
|
||||
#else
|
||||
icon_ = new MsgCountComposedIcon(filename);
|
||||
setIcon(QIcon(icon_));
|
||||
icon_ = new MsgCountComposedIcon(filename);
|
||||
setIcon(QIcon(icon_));
|
||||
#endif
|
||||
|
||||
QMenu *menu = new QMenu(parent);
|
||||
viewAction_ = new QAction(tr("Show"), parent);
|
||||
quitAction_ = new QAction(tr("Quit"), parent);
|
||||
QMenu *menu = new QMenu(parent);
|
||||
viewAction_ = new QAction(tr("Show"), parent);
|
||||
quitAction_ = new QAction(tr("Quit"), parent);
|
||||
|
||||
connect(viewAction_, SIGNAL(triggered()), parent, SLOT(show()));
|
||||
connect(quitAction_, &QAction::triggered, this, [=]() { QApplication::quit(); });
|
||||
connect(viewAction_, SIGNAL(triggered()), parent, SLOT(show()));
|
||||
connect(quitAction_, &QAction::triggered, this, [=]() { QApplication::quit(); });
|
||||
|
||||
menu->addAction(viewAction_);
|
||||
menu->addAction(quitAction_);
|
||||
menu->addAction(viewAction_);
|
||||
menu->addAction(quitAction_);
|
||||
|
||||
setContextMenu(menu);
|
||||
setContextMenu(menu);
|
||||
|
||||
// We wait a little for the icon to load.
|
||||
QTimer::singleShot(500, this, [=]() { show(); });
|
||||
// We wait a little for the icon to load.
|
||||
QTimer::singleShot(500, this, [=]() { show(); });
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -97,20 +103,20 @@ TrayIcon::setUnreadCount(int count)
|
|||
{
|
||||
// Use the native badge counter in MacOS.
|
||||
#if defined(Q_OS_MAC)
|
||||
if (count == 0)
|
||||
QtMac::setBadgeLabelText("");
|
||||
else
|
||||
QtMac::setBadgeLabelText(QString::number(count));
|
||||
if (count == 0)
|
||||
QtMac::setBadgeLabelText("");
|
||||
else
|
||||
QtMac::setBadgeLabelText(QString::number(count));
|
||||
#elif defined(Q_OS_WIN)
|
||||
// FIXME: Find a way to use Windows apis for the badge counter (if any).
|
||||
#else
|
||||
// Custom drawing on Linux.
|
||||
// FIXME: It doesn't seem to work on KDE.
|
||||
MsgCountComposedIcon *tmp = static_cast<MsgCountComposedIcon *>(icon_->clone());
|
||||
tmp->msgCount = count;
|
||||
// Custom drawing on Linux.
|
||||
// FIXME: It doesn't seem to work on KDE.
|
||||
MsgCountComposedIcon *tmp = static_cast<MsgCountComposedIcon *>(icon_->clone());
|
||||
tmp->msgCount = count;
|
||||
|
||||
setIcon(QIcon(tmp));
|
||||
setIcon(QIcon(tmp));
|
||||
|
||||
icon_ = tmp;
|
||||
icon_ = tmp;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -31,92 +31,95 @@ UserInfoWidget::UserInfoWidget(QWidget *parent)
|
|||
, logoutDialog_{ nullptr }
|
||||
, logoutButtonSize_{ 32 }
|
||||
{
|
||||
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
setSizePolicy(sizePolicy);
|
||||
setMinimumSize(QSize(0, 65));
|
||||
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
setSizePolicy(sizePolicy);
|
||||
setMinimumSize(QSize(0, 65));
|
||||
|
||||
topLayout_ = new QHBoxLayout(this);
|
||||
topLayout_->setSpacing(0);
|
||||
topLayout_->setMargin(5);
|
||||
topLayout_ = new QHBoxLayout(this);
|
||||
topLayout_->setSpacing(0);
|
||||
topLayout_->setMargin(5);
|
||||
|
||||
avatarLayout_ = new QHBoxLayout();
|
||||
textLayout_ = new QVBoxLayout();
|
||||
avatarLayout_ = new QHBoxLayout();
|
||||
textLayout_ = new QVBoxLayout();
|
||||
|
||||
userAvatar_ = new Avatar(this);
|
||||
userAvatar_->setLetter(QChar('?'));
|
||||
userAvatar_->setSize(55);
|
||||
userAvatar_->setBackgroundColor("#f9f9f9");
|
||||
userAvatar_->setTextColor("#333333");
|
||||
userAvatar_ = new Avatar(this);
|
||||
userAvatar_->setLetter(QChar('?'));
|
||||
userAvatar_->setSize(55);
|
||||
userAvatar_->setBackgroundColor("#f9f9f9");
|
||||
userAvatar_->setTextColor("#333333");
|
||||
|
||||
QFont nameFont("Open Sans SemiBold");
|
||||
nameFont.setPixelSize(conf::userInfoWidget::fonts::displayName);
|
||||
QFont nameFont("Open Sans SemiBold");
|
||||
nameFont.setPixelSize(conf::userInfoWidget::fonts::displayName);
|
||||
|
||||
displayNameLabel_ = new QLabel(this);
|
||||
displayNameLabel_->setFont(nameFont);
|
||||
displayNameLabel_->setStyleSheet("padding: 0 9px; color: #171919; margin-bottom: -10px;");
|
||||
displayNameLabel_->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
|
||||
displayNameLabel_ = new QLabel(this);
|
||||
displayNameLabel_->setFont(nameFont);
|
||||
displayNameLabel_->setStyleSheet("padding: 0 9px; color: #171919; margin-bottom: -10px;");
|
||||
displayNameLabel_->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
|
||||
|
||||
QFont useridFont("Open Sans");
|
||||
useridFont.setPixelSize(conf::userInfoWidget::fonts::userid);
|
||||
QFont useridFont("Open Sans");
|
||||
useridFont.setPixelSize(conf::userInfoWidget::fonts::userid);
|
||||
|
||||
userIdLabel_ = new QLabel(this);
|
||||
userIdLabel_->setFont(useridFont);
|
||||
userIdLabel_->setStyleSheet("padding: 0 8px 8px 8px; color: #555459;");
|
||||
userIdLabel_->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
|
||||
userIdLabel_ = new QLabel(this);
|
||||
userIdLabel_->setFont(useridFont);
|
||||
userIdLabel_->setStyleSheet("padding: 0 8px 8px 8px; color: #555459;");
|
||||
userIdLabel_->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
avatarLayout_->addWidget(userAvatar_);
|
||||
textLayout_->addWidget(displayNameLabel_);
|
||||
textLayout_->addWidget(userIdLabel_);
|
||||
avatarLayout_->addWidget(userAvatar_);
|
||||
textLayout_->addWidget(displayNameLabel_);
|
||||
textLayout_->addWidget(userIdLabel_);
|
||||
|
||||
topLayout_->addLayout(avatarLayout_);
|
||||
topLayout_->addLayout(textLayout_);
|
||||
topLayout_->addStretch(1);
|
||||
topLayout_->addLayout(avatarLayout_);
|
||||
topLayout_->addLayout(textLayout_);
|
||||
topLayout_->addStretch(1);
|
||||
|
||||
buttonLayout_ = new QHBoxLayout();
|
||||
buttonLayout_->setSpacing(0);
|
||||
buttonLayout_->setMargin(0);
|
||||
buttonLayout_ = new QHBoxLayout();
|
||||
buttonLayout_->setSpacing(0);
|
||||
buttonLayout_->setMargin(0);
|
||||
|
||||
logoutButton_ = new FlatButton(this);
|
||||
logoutButton_->setForegroundColor(QColor("#555459"));
|
||||
logoutButton_->setFixedSize(logoutButtonSize_, logoutButtonSize_);
|
||||
logoutButton_->setCornerRadius(logoutButtonSize_ / 2);
|
||||
logoutButton_ = new FlatButton(this);
|
||||
logoutButton_->setForegroundColor(QColor("#555459"));
|
||||
logoutButton_->setFixedSize(logoutButtonSize_, logoutButtonSize_);
|
||||
logoutButton_->setCornerRadius(logoutButtonSize_ / 2);
|
||||
|
||||
QIcon icon;
|
||||
icon.addFile(":/icons/icons/power-button-off.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
QIcon icon;
|
||||
icon.addFile(":/icons/icons/power-button-off.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
|
||||
logoutButton_->setIcon(icon);
|
||||
logoutButton_->setIconSize(QSize(logoutButtonSize_ / 2, logoutButtonSize_ / 2));
|
||||
logoutButton_->setIcon(icon);
|
||||
logoutButton_->setIconSize(QSize(logoutButtonSize_ / 2, logoutButtonSize_ / 2));
|
||||
|
||||
buttonLayout_->addWidget(logoutButton_);
|
||||
buttonLayout_->addWidget(logoutButton_);
|
||||
|
||||
topLayout_->addLayout(buttonLayout_);
|
||||
topLayout_->addLayout(buttonLayout_);
|
||||
|
||||
// Show the confirmation dialog.
|
||||
connect(logoutButton_, &QPushButton::clicked, this, [=]() {
|
||||
if (logoutDialog_ == nullptr) {
|
||||
logoutDialog_ = new LogoutDialog(this);
|
||||
connect(logoutDialog_, SIGNAL(closing(bool)), this, SLOT(closeLogoutDialog(bool)));
|
||||
}
|
||||
// Show the confirmation dialog.
|
||||
connect(logoutButton_, &QPushButton::clicked, this, [=]() {
|
||||
if (logoutDialog_ == nullptr) {
|
||||
logoutDialog_ = new LogoutDialog(this);
|
||||
connect(logoutDialog_,
|
||||
SIGNAL(closing(bool)),
|
||||
this,
|
||||
SLOT(closeLogoutDialog(bool)));
|
||||
}
|
||||
|
||||
if (logoutModal_ == nullptr) {
|
||||
logoutModal_ = new OverlayModal(MainWindow::instance(), logoutDialog_);
|
||||
logoutModal_->setDuration(100);
|
||||
logoutModal_->setColor(QColor(55, 55, 55, 170));
|
||||
}
|
||||
if (logoutModal_ == nullptr) {
|
||||
logoutModal_ = new OverlayModal(MainWindow::instance(), logoutDialog_);
|
||||
logoutModal_->setDuration(100);
|
||||
logoutModal_->setColor(QColor(55, 55, 55, 170));
|
||||
}
|
||||
|
||||
logoutModal_->fadeIn();
|
||||
});
|
||||
logoutModal_->fadeIn();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
UserInfoWidget::closeLogoutDialog(bool isLoggingOut)
|
||||
{
|
||||
logoutModal_->fadeOut();
|
||||
logoutModal_->fadeOut();
|
||||
|
||||
if (isLoggingOut) {
|
||||
// Waiting for the modal to fade out.
|
||||
QTimer::singleShot(100, this, [=]() { emit logout(); });
|
||||
}
|
||||
if (isLoggingOut) {
|
||||
// Waiting for the modal to fade out.
|
||||
QTimer::singleShot(100, this, [=]() { emit logout(); });
|
||||
}
|
||||
}
|
||||
|
||||
UserInfoWidget::~UserInfoWidget()
|
||||
|
@ -126,52 +129,52 @@ UserInfoWidget::~UserInfoWidget()
|
|||
void
|
||||
UserInfoWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(event);
|
||||
|
||||
if (width() <= ui::sidebar::SmallSize) {
|
||||
topLayout_->setContentsMargins(0, 0, logoutButtonSize_ / 2 - 5 / 2, 0);
|
||||
if (width() <= ui::sidebar::SmallSize) {
|
||||
topLayout_->setContentsMargins(0, 0, logoutButtonSize_ / 2 - 5 / 2, 0);
|
||||
|
||||
userAvatar_->hide();
|
||||
displayNameLabel_->hide();
|
||||
userIdLabel_->hide();
|
||||
} else {
|
||||
topLayout_->setMargin(5);
|
||||
userAvatar_->show();
|
||||
displayNameLabel_->show();
|
||||
userIdLabel_->show();
|
||||
}
|
||||
userAvatar_->hide();
|
||||
displayNameLabel_->hide();
|
||||
userIdLabel_->hide();
|
||||
} else {
|
||||
topLayout_->setMargin(5);
|
||||
userAvatar_->show();
|
||||
displayNameLabel_->show();
|
||||
userIdLabel_->show();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UserInfoWidget::reset()
|
||||
{
|
||||
displayNameLabel_->setText("");
|
||||
userIdLabel_->setText("");
|
||||
userAvatar_->setLetter(QChar('?'));
|
||||
displayNameLabel_->setText("");
|
||||
userIdLabel_->setText("");
|
||||
userAvatar_->setLetter(QChar('?'));
|
||||
}
|
||||
|
||||
void
|
||||
UserInfoWidget::setAvatar(const QImage &img)
|
||||
{
|
||||
avatar_image_ = img;
|
||||
userAvatar_->setImage(img);
|
||||
avatar_image_ = img;
|
||||
userAvatar_->setImage(img);
|
||||
}
|
||||
|
||||
void
|
||||
UserInfoWidget::setDisplayName(const QString &name)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
display_name_ = user_id_.split(':')[0].split('@')[1];
|
||||
else
|
||||
display_name_ = name;
|
||||
if (name.isEmpty())
|
||||
display_name_ = user_id_.split(':')[0].split('@')[1];
|
||||
else
|
||||
display_name_ = name;
|
||||
|
||||
displayNameLabel_->setText(display_name_);
|
||||
userAvatar_->setLetter(QChar(display_name_[0]));
|
||||
displayNameLabel_->setText(display_name_);
|
||||
userAvatar_->setLetter(QChar(display_name_[0]));
|
||||
}
|
||||
|
||||
void
|
||||
UserInfoWidget::setUserId(const QString &userid)
|
||||
{
|
||||
user_id_ = userid;
|
||||
userIdLabel_->setText(userid);
|
||||
user_id_ = userid;
|
||||
userIdLabel_->setText(userid);
|
||||
}
|
||||
|
|
|
@ -27,38 +27,39 @@
|
|||
void
|
||||
VersionsResponse::deserialize(const QJsonDocument &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Versions response is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("Versions response is not a JSON object");
|
||||
|
||||
QJsonObject object = data.object();
|
||||
QJsonObject object = data.object();
|
||||
|
||||
if (object.value("versions") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Versions: missing version list");
|
||||
if (object.value("versions") == QJsonValue::Undefined)
|
||||
throw DeserializationException("Versions: missing version list");
|
||||
|
||||
auto versions = object.value("versions").toArray();
|
||||
for (auto const &elem : versions) {
|
||||
QString str = elem.toString();
|
||||
QRegExp rx("r(\\d+)\\.(\\d+)\\.(\\d+)");
|
||||
auto versions = object.value("versions").toArray();
|
||||
for (auto const &elem : versions) {
|
||||
QString str = elem.toString();
|
||||
QRegExp rx("r(\\d+)\\.(\\d+)\\.(\\d+)");
|
||||
|
||||
if (rx.indexIn(str) == -1)
|
||||
throw DeserializationException("Invalid version string in versions response");
|
||||
if (rx.indexIn(str) == -1)
|
||||
throw DeserializationException(
|
||||
"Invalid version string in versions response");
|
||||
|
||||
struct Version_ v;
|
||||
v.major_ = rx.cap(1).toUInt();
|
||||
v.minor_ = rx.cap(2).toUInt();
|
||||
v.patch_ = rx.cap(3).toUInt();
|
||||
struct Version_ v;
|
||||
v.major_ = rx.cap(1).toUInt();
|
||||
v.minor_ = rx.cap(2).toUInt();
|
||||
v.patch_ = rx.cap(3).toUInt();
|
||||
|
||||
supported_versions_.push_back(v);
|
||||
}
|
||||
supported_versions_.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
VersionsResponse::isVersionSupported(unsigned int major, unsigned int minor, unsigned int patch)
|
||||
{
|
||||
for (auto &v : supported_versions_) {
|
||||
if (v.major_ == major && v.minor_ == minor && v.patch_ >= patch)
|
||||
return true;
|
||||
}
|
||||
for (auto &v : supported_versions_) {
|
||||
if (v.major_ == major && v.minor_ == minor && v.patch_ >= patch)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,78 +24,79 @@
|
|||
WelcomePage::WelcomePage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
top_layout_ = new QVBoxLayout(this);
|
||||
top_layout_->setSpacing(0);
|
||||
top_layout_->setMargin(0);
|
||||
top_layout_ = new QVBoxLayout(this);
|
||||
top_layout_->setSpacing(0);
|
||||
top_layout_->setMargin(0);
|
||||
|
||||
intro_banner_ = new QLabel(this);
|
||||
intro_banner_->setPixmap(QPixmap(":/logos/nheko-256.png"));
|
||||
intro_banner_->setAlignment(Qt::AlignCenter);
|
||||
intro_banner_ = new QLabel(this);
|
||||
intro_banner_->setPixmap(QPixmap(":/logos/nheko-256.png"));
|
||||
intro_banner_->setAlignment(Qt::AlignCenter);
|
||||
|
||||
intro_text_ = new QLabel(this);
|
||||
intro_text_ = new QLabel(this);
|
||||
|
||||
QString heading(tr("Welcome to nheko! The desktop client for the Matrix protocol."));
|
||||
QString main(tr("Enjoy your stay!"));
|
||||
QString heading(tr("Welcome to nheko! The desktop client for the Matrix protocol."));
|
||||
QString main(tr("Enjoy your stay!"));
|
||||
|
||||
intro_text_->setText(QString("<p align=\"center\" style=\"margin: 0; line-height: 2pt\">"
|
||||
" <span style=\" font-size:18px; color:#515151;\"> %1 </span>"
|
||||
"</p>"
|
||||
"<p align=\"center\" style=\"margin: 1pt; line-height: 2pt;\">"
|
||||
" <span style=\" font-size:18px; color:#515151;\"> %2 </span>"
|
||||
"</p>")
|
||||
.arg(heading)
|
||||
.arg(main));
|
||||
intro_text_->setText(QString("<p align=\"center\" style=\"margin: 0; line-height: 2pt\">"
|
||||
" <span style=\" font-size:18px; color:#515151;\"> %1 </span>"
|
||||
"</p>"
|
||||
"<p align=\"center\" style=\"margin: 1pt; line-height: 2pt;\">"
|
||||
" <span style=\" font-size:18px; color:#515151;\"> %2 </span>"
|
||||
"</p>")
|
||||
.arg(heading)
|
||||
.arg(main));
|
||||
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addWidget(intro_banner_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addWidget(intro_text_, 0, Qt::AlignCenter);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addWidget(intro_banner_);
|
||||
top_layout_->addStretch(1);
|
||||
top_layout_->addWidget(intro_text_, 0, Qt::AlignCenter);
|
||||
top_layout_->addStretch(1);
|
||||
|
||||
button_layout_ = new QHBoxLayout();
|
||||
button_layout_->setSpacing(0);
|
||||
button_layout_->setContentsMargins(0, 20, 0, 80);
|
||||
button_layout_ = new QHBoxLayout();
|
||||
button_layout_->setSpacing(0);
|
||||
button_layout_->setContentsMargins(0, 20, 0, 80);
|
||||
|
||||
register_button_ = new RaisedButton(tr("REGISTER"), this);
|
||||
register_button_->setBackgroundColor(QColor("#333333"));
|
||||
register_button_->setForegroundColor(QColor("white"));
|
||||
register_button_->setMinimumSize(240, 60);
|
||||
register_button_->setFontSize(conf::btn::fontSize);
|
||||
register_button_->setCornerRadius(conf::btn::cornerRadius);
|
||||
register_button_ = new RaisedButton(tr("REGISTER"), this);
|
||||
register_button_->setBackgroundColor(QColor("#333333"));
|
||||
register_button_->setForegroundColor(QColor("white"));
|
||||
register_button_->setMinimumSize(240, 60);
|
||||
register_button_->setFontSize(conf::btn::fontSize);
|
||||
register_button_->setCornerRadius(conf::btn::cornerRadius);
|
||||
|
||||
login_button_ = new RaisedButton(tr("LOGIN"), this);
|
||||
login_button_->setBackgroundColor(QColor("#333333"));
|
||||
login_button_->setForegroundColor(QColor("white"));
|
||||
login_button_->setMinimumSize(240, 60);
|
||||
login_button_->setFontSize(conf::btn::fontSize);
|
||||
login_button_->setCornerRadius(conf::btn::cornerRadius);
|
||||
login_button_ = new RaisedButton(tr("LOGIN"), this);
|
||||
login_button_->setBackgroundColor(QColor("#333333"));
|
||||
login_button_->setForegroundColor(QColor("white"));
|
||||
login_button_->setMinimumSize(240, 60);
|
||||
login_button_->setFontSize(conf::btn::fontSize);
|
||||
login_button_->setCornerRadius(conf::btn::cornerRadius);
|
||||
|
||||
button_spacer_ = new QSpacerItem(20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
button_spacer_ =
|
||||
new QSpacerItem(20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addWidget(register_button_);
|
||||
button_layout_->addItem(button_spacer_);
|
||||
button_layout_->addWidget(login_button_);
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addStretch(1);
|
||||
button_layout_->addWidget(register_button_);
|
||||
button_layout_->addItem(button_spacer_);
|
||||
button_layout_->addWidget(login_button_);
|
||||
button_layout_->addStretch(1);
|
||||
|
||||
top_layout_->addLayout(button_layout_);
|
||||
top_layout_->addLayout(button_layout_);
|
||||
|
||||
connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked()));
|
||||
connect(login_button_, SIGNAL(clicked()), this, SLOT(onLoginButtonClicked()));
|
||||
connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked()));
|
||||
connect(login_button_, SIGNAL(clicked()), this, SLOT(onLoginButtonClicked()));
|
||||
}
|
||||
|
||||
void
|
||||
WelcomePage::onLoginButtonClicked()
|
||||
{
|
||||
emit userLogin();
|
||||
emit userLogin();
|
||||
}
|
||||
|
||||
void
|
||||
WelcomePage::onRegisterButtonClicked()
|
||||
{
|
||||
emit userRegister();
|
||||
emit userRegister();
|
||||
}
|
||||
|
||||
WelcomePage::~WelcomePage()
|
||||
|
|
|
@ -24,32 +24,32 @@ using namespace matrix::events;
|
|||
void
|
||||
AliasesEventContent::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("AliasesEventContent is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("AliasesEventContent is not a JSON object");
|
||||
|
||||
auto object = data.toObject();
|
||||
auto object = data.toObject();
|
||||
|
||||
if (object.value("aliases") == QJsonValue::Undefined)
|
||||
throw DeserializationException("aliases key is missing");
|
||||
if (object.value("aliases") == QJsonValue::Undefined)
|
||||
throw DeserializationException("aliases key is missing");
|
||||
|
||||
auto aliases = object.value("aliases").toArray();
|
||||
auto aliases = object.value("aliases").toArray();
|
||||
|
||||
for (const auto &alias : aliases)
|
||||
aliases_.push_back(alias.toString());
|
||||
for (const auto &alias : aliases)
|
||||
aliases_.push_back(alias.toString());
|
||||
}
|
||||
|
||||
QJsonObject
|
||||
AliasesEventContent::serialize() const
|
||||
{
|
||||
QJsonObject object;
|
||||
QJsonObject object;
|
||||
|
||||
QJsonArray aliases;
|
||||
QJsonArray aliases;
|
||||
|
||||
for (const auto &alias : aliases_)
|
||||
aliases.push_back(alias);
|
||||
for (const auto &alias : aliases_)
|
||||
aliases.push_back(alias);
|
||||
|
||||
if (aliases.size() > 0)
|
||||
object["aliases"] = aliases;
|
||||
if (aliases.size() > 0)
|
||||
object["aliases"] = aliases;
|
||||
|
||||
return object;
|
||||
return object;
|
||||
}
|
||||
|
|
|
@ -24,27 +24,27 @@ using namespace matrix::events;
|
|||
void
|
||||
AvatarEventContent::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("AvatarEventContent is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("AvatarEventContent is not a JSON object");
|
||||
|
||||
auto object = data.toObject();
|
||||
auto object = data.toObject();
|
||||
|
||||
if (object.value("url") == QJsonValue::Undefined)
|
||||
throw DeserializationException("url key is missing");
|
||||
if (object.value("url") == QJsonValue::Undefined)
|
||||
throw DeserializationException("url key is missing");
|
||||
|
||||
url_ = QUrl(object.value("url").toString());
|
||||
url_ = QUrl(object.value("url").toString());
|
||||
|
||||
if (!url_.isValid())
|
||||
qWarning() << "Invalid avatar url" << url_;
|
||||
if (!url_.isValid())
|
||||
qWarning() << "Invalid avatar url" << url_;
|
||||
}
|
||||
|
||||
QJsonObject
|
||||
AvatarEventContent::serialize() const
|
||||
{
|
||||
QJsonObject object;
|
||||
QJsonObject object;
|
||||
|
||||
if (!url_.isEmpty())
|
||||
object["url"] = url_.toString();
|
||||
if (!url_.isEmpty())
|
||||
object["url"] = url_.toString();
|
||||
|
||||
return object;
|
||||
return object;
|
||||
}
|
||||
|
|
|
@ -22,24 +22,24 @@ using namespace matrix::events;
|
|||
void
|
||||
CanonicalAliasEventContent::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("CanonicalAliasEventContent is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("CanonicalAliasEventContent is not a JSON object");
|
||||
|
||||
auto object = data.toObject();
|
||||
auto object = data.toObject();
|
||||
|
||||
if (object.value("alias") == QJsonValue::Undefined)
|
||||
throw DeserializationException("alias key is missing");
|
||||
if (object.value("alias") == QJsonValue::Undefined)
|
||||
throw DeserializationException("alias key is missing");
|
||||
|
||||
alias_ = object.value("alias").toString();
|
||||
alias_ = object.value("alias").toString();
|
||||
}
|
||||
|
||||
QJsonObject
|
||||
CanonicalAliasEventContent::serialize() const
|
||||
{
|
||||
QJsonObject object;
|
||||
QJsonObject object;
|
||||
|
||||
if (!alias_.isEmpty())
|
||||
object["alias"] = alias_;
|
||||
if (!alias_.isEmpty())
|
||||
object["alias"] = alias_;
|
||||
|
||||
return object;
|
||||
return object;
|
||||
}
|
||||
|
|
|
@ -22,24 +22,24 @@ using namespace matrix::events;
|
|||
void
|
||||
CreateEventContent::deserialize(const QJsonValue &data)
|
||||
{
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("CreateEventContent is not a JSON object");
|
||||
if (!data.isObject())
|
||||
throw DeserializationException("CreateEventContent is not a JSON object");
|
||||
|
||||
auto object = data.toObject();
|
||||
auto object = data.toObject();
|
||||
|
||||
if (object.value("creator") == QJsonValue::Undefined)
|
||||
throw DeserializationException("creator key is missing");
|
||||
if (object.value("creator") == QJsonValue::Undefined)
|
||||
throw DeserializationException("creator key is missing");
|
||||
|
||||
creator_ = object.value("creator").toString();
|
||||
creator_ = object.value("creator").toString();
|
||||
}
|
||||
|
||||
QJsonObject
|
||||
CreateEventContent::serialize() const
|
||||
{
|
||||
QJsonObject object;
|
||||
QJsonObject object;
|
||||
|
||||
if (!creator_.isEmpty())
|
||||
object["creator"] = creator_;
|
||||
if (!creator_.isEmpty())
|
||||
object["creator"] = creator_;
|
||||
|
||||
return object;
|
||||
return object;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue