KTextAddons

textautogeneratelistview.cpp
1/*
2 SPDX-FileCopyrightText: 2025 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6#include "textautogeneratelistview.h"
7#include "core/textautogeneratechatmodel.h"
8#include "core/textautogeneratemanager.h"
9#include "textautogeneratelistviewdelegate.h"
10#include <KLocalizedString>
11#include <QApplication>
12#include <QClipboard>
13#include <QMenu>
14#include <QMouseEvent>
15#include <QScrollBar>
16
17using namespace TextAutogenerateText;
18TextAutogenerateListView::TextAutogenerateListView(QWidget *parent)
19 : QListView(parent)
20 , mDelegate(new TextAutogenerateListViewDelegate(this))
21{
22 setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); // nicer in case of huge messages
23 setItemDelegate(mDelegate);
24 setModel(TextAutogenerateManager::self()->textAutoGenerateChatModel());
25
26 connect(TextAutogenerateManager::self()->textAutoGenerateChatModel(), &TextAutoGenerateChatModel::conversationCleared, this, [this]() {
27 mDelegate->clearCache();
28 });
29
30 connect(mDelegate, &TextAutogenerateListViewDelegate::updateView, this, [this](const QModelIndex &index) {
31 update(index);
32 });
33
34 connect(TextAutogenerateManager::self()->textAutoGenerateChatModel(),
36 this,
37 [this](const QModelIndex &topLeft, const QModelIndex &, const QList<int> &roles) {
38 if (roles.contains(TextAutoGenerateChatModel::MessageRole) || roles.contains(TextAutoGenerateChatModel::FinishedRole)) {
39 const QByteArray uuid = topLeft.data(TextAutoGenerateChatModel::UuidRole).toByteArray();
40 if (!uuid.isEmpty()) {
41 mDelegate->removeMessageCache(uuid);
42 }
43 }
44 });
45}
46
47TextAutogenerateListView::~TextAutogenerateListView()
48{
49 TextAutogenerateManager::self()->textAutoGenerateChatModel()->resetConversation();
50}
51
52void TextAutogenerateListView::setMessages(const QList<TextAutoGenerateMessage> &msg)
53{
54 TextAutogenerateManager::self()->textAutoGenerateChatModel()->setMessages(msg);
55}
56
57void TextAutogenerateListView::contextMenuEvent(QContextMenuEvent *event)
58{
59 QMenu menu(this);
60 const QModelIndex index = indexAt(event->pos());
61 if (index.isValid()) {
62 auto copyAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-copy")),
63 mDelegate->hasSelection() ? i18nc("@action", "Copy Selection") : i18nc("@action", "Copy"),
64 &menu);
65 copyAction->setShortcut(QKeySequence::Copy);
66 connect(copyAction, &QAction::triggered, this, [index]() {
67 const QString currentValue = index.data().toString();
68 QClipboard *clip = QApplication::clipboard();
69 clip->setText(currentValue, QClipboard::Clipboard);
70 clip->setText(currentValue, QClipboard::Selection);
71 });
72 menu.addAction(copyAction);
73 menu.addSeparator();
74 auto selectAllAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-select-all")), i18nc("@action", "Select All"), &menu);
75 connect(selectAllAction, &QAction::triggered, this, [this, index]() {
76 slotSelectAll(index);
77 });
78 selectAllAction->setShortcut(QKeySequence::SelectAll);
79 menu.addAction(selectAllAction);
80 }
81 if (!menu.actions().isEmpty()) {
82 menu.exec(event->globalPos());
83 }
84}
85
86void TextAutogenerateListView::slotSelectAll(const QModelIndex &index)
87{
88 mDelegate->selectAll(listViewOptions(), index);
89}
90
91void TextAutogenerateListView::resizeEvent(QResizeEvent *ev)
92{
94
95 // Fix not being really at bottom when the view gets reduced by the header widget becoming taller
96 checkIfAtBottom();
97 maybeScrollToBottom(); // this forces a layout in QAIV, which then changes the vbar max value
98 updateVerticalPageStep();
99 mDelegate->clearSizeHintCache();
100}
101
102void TextAutogenerateListView::checkIfAtBottom()
103{
104 auto *vbar = verticalScrollBar();
105 mAtBottom = vbar->value() == vbar->maximum();
106}
107
108void TextAutogenerateListView::maybeScrollToBottom()
109{
110 if (mAtBottom) {
112 }
113}
114
115void TextAutogenerateListView::updateVerticalPageStep()
116{
118}
119
120void TextAutogenerateListView::mouseReleaseEvent(QMouseEvent *event)
121{
122 handleMouseEvent(event);
123}
124
125void TextAutogenerateListView::mouseDoubleClickEvent(QMouseEvent *event)
126{
127 handleMouseEvent(event);
128}
129
130void TextAutogenerateListView::mousePressEvent(QMouseEvent *event)
131{
132 mPressedPosition = event->pos();
133 handleMouseEvent(event);
134}
135
136void TextAutogenerateListView::mouseMoveEvent(QMouseEvent *event)
137{
138 // Drag support
139 const int distance = (event->pos() - mPressedPosition).manhattanLength();
140 if (distance > QApplication::startDragDistance()) {
141 mPressedPosition = {};
142 const QPersistentModelIndex index = indexAt(event->pos());
143 if (index.isValid()) {
144 QStyleOptionViewItem options = listViewOptions();
145 options.rect = visualRect(index);
146 if (maybeStartDrag(event, options, index)) {
147 return;
148 }
149 }
150 }
151 handleMouseEvent(event);
152}
153
154QStyleOptionViewItem TextAutogenerateListView::listViewOptions() const
155{
156 QStyleOptionViewItem option;
157 initViewItemOption(&option);
158 return option;
159}
160
161void TextAutogenerateListView::handleMouseEvent(QMouseEvent *event)
162{
163 const QPersistentModelIndex index = indexAt(event->pos());
164 if (index.isValid()) {
165 if (mCurrentIndex != index) {
166 mCurrentIndex = index;
167 }
168
169 QStyleOptionViewItem options = listViewOptions();
170 options.rect = visualRect(mCurrentIndex);
171 if (mouseEvent(event, options, mCurrentIndex)) {
172 update(mCurrentIndex);
173 }
174 }
175}
176
177bool TextAutogenerateListView::maybeStartDrag(QMouseEvent *event, const QStyleOptionViewItem &option, const QModelIndex &index)
178{
179 return mDelegate->maybeStartDrag(event, option, index);
180}
181
182bool TextAutogenerateListView::mouseEvent(QMouseEvent *event, const QStyleOptionViewItem &option, const QModelIndex &index)
183{
184 return mDelegate->mouseEvent(event, option, index);
185}
186
187#include "moc_textautogeneratelistview.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void update(Part *part, const QByteArray &data, qint64 dataSize)
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
virtual bool event(QEvent *event) override
QScrollBar * verticalScrollBar() const const
QWidget * viewport() const const
void setPageStep(int)
void triggered(bool checked)
bool isEmpty() const const
void setText(const QString &text, Mode mode)
QClipboard * clipboard()
QIcon fromTheme(const QString &name)
bool contains(const AT &value) const const
virtual QModelIndex indexAt(const QPoint &p) const const override
virtual void initViewItemOption(QStyleOptionViewItem *option) const const override
virtual void resizeEvent(QResizeEvent *e) override
virtual QRect visualRect(const QModelIndex &index) const const override
QVariant data(int role) const const
bool isValid() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool isValid() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QByteArray toByteArray() const const
QString toString() const const
void update()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 12:06:13 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.