/** * @file chat_view.h * @ingroup NetworkingWidgets * @ingroup Lobby */ //! \todo Document this file. #ifndef CHATVIEW_H #define CHATVIEW_H #include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class AbstractGame; class UserContextMenu; class UserListProxy; class QAction; class QPoint; class QUrl; class QWidget; class TabSupervisor; struct CardRef; template class QFlags; class UserMessagePosition { public: UserMessagePosition(QTextCursor &cursor); int relativePosition; QTextBlock block; }; struct ChatLogEntry { QString userName; QString message; QDateTime timestamp; }; class ChatView : public QTextBrowser { Q_OBJECT protected: TabSupervisor *const tabSupervisor; AbstractGame *const game; private: enum HoveredItemType { HoveredNothing, HoveredUrl, HoveredCard, HoveredUser }; const UserListProxy *const userListProxy; UserContextMenu *userContextMenu; QString lastSender; QString ownUserName; QString mention; QTextCharFormat mentionFormat; QTextCharFormat highlightFormat; QTextCharFormat mentionFormatOtherUser; QTextCharFormat defaultFormat; QStringList highlightedWords; bool evenNumber; bool showTimestamps; bool stickToBottom = false; HoveredItemType hoveredItemType; QString hoveredContent; QAction *messageClicked; QMap> userMessagePositions; QList chatHistory; static constexpr int MAX_CHAT_HISTORY = 200; [[nodiscard]] QTextFragment getFragmentUnderMouse(const QPoint &pos) const; QTextCursor prepareBlock(bool same = false); void scrollToBottom(); void appendCardTag(QTextCursor &cursor, const QString &cardName); void appendUrlTag(QTextCursor &cursor, QString url); void appendGameLinkTag(QTextCursor &cursor, const QString &url); static QColor getCustomMentionColor(); static QColor getCustomHighlightColor(); void showSystemPopup(const QString &userName); bool isModeratorSendingGlobal(QFlags userLevelFlag, QString message); void checkTag(QTextCursor &cursor, QString &message); void checkMention(QTextCursor &cursor, QString &message, const QString &userName, UserLevelFlags userLevel); void checkWord(QTextCursor &cursor, QString &message); QString extractNextWord(QString &message, QString &rest); QColor otherUserColor = QColor(0, 65, 255); // dark blue QColor serverMessageColor = QColor(0x85, 0x15, 0x15); QColor linkColor; QColor unresolvedCardTagColor; private slots: void openLink(const QUrl &link); void actMessageClicked(); void adjustColorsToPalette(); void applyChatFont(); void refreshBlockColors(); void onScrollBarRangeChanged(); void onScrollBarValueChanged(int value); public: ChatView(TabSupervisor *_tabSupervisor, AbstractGame *_game, bool _showTimestamps, QWidget *parent = nullptr); void retranslateUi(); void appendHtml(const QString &html); virtual void appendHtmlServerMessage(const QString &html, bool optionalIsBold = false, QString optionalFontColor = QString()); void appendMessage(QString message, RoomMessageTypeFlags messageType = {}, const ServerInfo_User &userInfo = {}, bool playerBold = false); void clearChat(); void redactMessages(const QString &userName, int amount); QString getRecentChatLog(int maxMessages = 50) const; protected: [[nodiscard]] virtual QString getCurrentTime() const; void enterEvent(QEnterEvent *event) override; void leaveEvent(QEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; signals: void openMessageDialog(const QString &userName, bool focus); void cardNameHovered(QString cardName); void showCardInfoPopup(const QPoint &pos, const CardRef &cardRef); void deleteCardInfoPopup(QString cardName); void addMentionTag(QString mentionTag); void messageClickedSignal(); void showMentionPopup(const QString &userName); void cockatriceLinkActivated(const QString &url); }; #endif