/* Вид истории сообщений: фон, выделение строк/текста, копирование и прокрутка вниз. * MessageDelegate рисует содержимое; ChatView обрабатывает мышь и клавиатуру. */ #pragma once #include #include #include #include #include #include struct ChatTextSelection { QPersistentModelIndex index; QPoint clickPos; QPoint dragPos; int startChar = -1; int endChar = -1; bool active = false; }; class ChatView : public QListView { Q_OBJECT public: explicit ChatView(QWidget *parent = nullptr); void setBackgroundImage(const QString &path); void setHistoricalWindow(bool enabled); bool hasSelection() const { return m_selStart.isValid(); } QModelIndex selStart() const { return QModelIndex(m_selStart); } QModelIndex selEnd() const { return QModelIndex(m_selEnd); } bool isSelecting() const { return m_selecting; } const ChatTextSelection &textSelection() const { return m_textSel; } bool isRowSelected(const QModelIndex &idx) const; void setTextSelChars(int start, int end) { m_textSel.startChar = start; m_textSel.endChar = end; } void setLinkHitTest(std::function fn) { m_linkHitTest = std::move(fn); } signals: void animationTriggered(); void linkActivated(const QString& link); void latestRequested(); protected: bool viewportEvent(QEvent *event) override; void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent *event) override; void scrollContentsBy(int dx, int dy) override; void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void keyPressEvent(QKeyEvent *event) override; private: void copySelection(); void updateScrollDownBtn(); QPixmap m_background; QPersistentModelIndex m_selStart; QPersistentModelIndex m_selEnd; ChatTextSelection m_textSel; QPersistentModelIndex m_lastHovered; QSet m_visibleAnimations; QPersistentModelIndex m_pressIndex; QPoint m_pressPos; bool m_selecting = false; bool m_historicalWindow = false; std::function m_linkHitTest; QPushButton *m_scrollDownBtn = nullptr; };