Akonadi

agenttypewidget.cpp
1/*
2 SPDX-FileCopyrightText: 2006-2008 Tobias Koenig <tokoe@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "agenttypewidget.h"
8
9#include <QApplication>
10#include <QHBoxLayout>
11#include <QListView>
12#include <QPainter>
13
14#include "agentfilterproxymodel.h"
15#include "agenttype.h"
16#include "agenttypemodel.h"
17
18namespace Akonadi
19{
20namespace Internal
21{
22/**
23 * @internal
24 */
25class AgentTypeWidgetDelegate : public QAbstractItemDelegate
26{
28public:
29 explicit AgentTypeWidgetDelegate(QObject *parent = nullptr);
30
31 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
32 QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
33
34private:
35 void drawFocus(QPainter * /*painter*/, const QStyleOptionViewItem & /*option*/, QRect /*rect*/) const;
36};
37
38} // namespace Internal
39
40using Akonadi::Internal::AgentTypeWidgetDelegate;
41
42/**
43 * @internal
44 */
45class AgentTypeWidgetPrivate
46{
47public:
48 explicit AgentTypeWidgetPrivate(AgentTypeWidget *parent)
49 : mParent(parent)
50 {
51 }
52
53 void currentAgentTypeChanged(const QModelIndex & /*currentIndex*/, const QModelIndex & /*previousIndex*/);
54
55 void typeActivated(const QModelIndex &index)
56 {
58 Q_EMIT mParent->activated();
59 }
60 }
61
62 AgentTypeWidget *const mParent;
63 QListView *mView = nullptr;
64 AgentTypeModel *mModel = nullptr;
65 AgentFilterProxyModel *proxyModel = nullptr;
66};
67
68void AgentTypeWidgetPrivate::currentAgentTypeChanged(const QModelIndex &currentIndex, const QModelIndex &previousIndex)
69{
70 AgentType currentType;
71 if (currentIndex.isValid()) {
72 currentType = currentIndex.data(AgentTypeModel::TypeRole).value<AgentType>();
73 }
74
75 AgentType previousType;
76 if (previousIndex.isValid()) {
77 previousType = previousIndex.data(AgentTypeModel::TypeRole).value<AgentType>();
78 }
79
80 Q_EMIT mParent->currentChanged(currentType, previousType);
81}
82
84 : QWidget(parent)
85 , d(new AgentTypeWidgetPrivate(this))
86{
87 auto layout = new QHBoxLayout(this);
89
90 d->mView = new QListView(this);
91 d->mView->setItemDelegate(new AgentTypeWidgetDelegate(d->mView));
92 d->mView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
93 d->mView->setAlternatingRowColors(true);
94 layout->addWidget(d->mView);
95
96 d->mModel = new AgentTypeModel(d->mView);
97 d->proxyModel = new AgentFilterProxyModel(this);
98 d->proxyModel->setSourceModel(d->mModel);
99 d->proxyModel->sort(0);
100 d->mView->setModel(d->proxyModel);
101
102 d->mView->selectionModel()->setCurrentIndex(d->mView->model()->index(0, 0), QItemSelectionModel::Select);
103 d->mView->scrollTo(d->mView->model()->index(0, 0));
104 connect(d->mView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex &start, const QModelIndex &end) {
105 d->currentAgentTypeChanged(start, end);
106 });
107 connect(d->mView, qOverload<const QModelIndex &>(&QListView::activated), this, [this](const QModelIndex &index) {
108 d->typeActivated(index);
109 });
110}
111
113
115{
116 QItemSelectionModel *selectionModel = d->mView->selectionModel();
117 if (!selectionModel) {
118 return AgentType();
119 }
120
121 const QModelIndex index = selectionModel->currentIndex();
122 if (!index.isValid()) {
123 return AgentType();
124 }
125
127}
128
130{
131 return d->proxyModel;
132}
133
134/**
135 * AgentTypeWidgetDelegate
136 */
137
138AgentTypeWidgetDelegate::AgentTypeWidgetDelegate(QObject *parent)
139 : QAbstractItemDelegate(parent)
140{
141}
142
143void AgentTypeWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
144{
145 if (!index.isValid()) {
146 return;
147 }
148
150
151 const QString name = index.model()->data(index, Qt::DisplayRole).toString();
152 const QString comment = index.model()->data(index, AgentTypeModel::DescriptionRole).toString();
153
154 const QVariant data = index.model()->data(index, Qt::DecorationRole);
155
156 QPixmap pixmap;
157 if (data.isValid() && data.typeId() == QMetaType::QIcon) {
158 pixmap = qvariant_cast<QIcon>(data).pixmap(64, 64);
159 }
160
161 const QFont oldFont = painter->font();
162 QFont boldFont(oldFont);
163 boldFont.setBold(true);
164 painter->setFont(boldFont);
165 QFontMetrics fm = painter->fontMetrics();
166 int hn = fm.boundingRect(0, 0, 0, 0, Qt::AlignLeft, name).height();
167 int wn = fm.boundingRect(0, 0, 0, 0, Qt::AlignLeft, name).width();
168 painter->setFont(oldFont);
169
170 fm = painter->fontMetrics();
171 int hc = fm.boundingRect(0, 0, 0, 0, Qt::AlignLeft, comment).height();
172 int wc = fm.boundingRect(0, 0, 0, 0, Qt::AlignLeft, comment).width();
173 int wp = pixmap.width();
174
175 QStyleOptionViewItem opt(option);
176 opt.showDecorationSelected = true;
178
179 QPen pen = painter->pen();
180 QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled;
181 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) {
183 }
184 if (option.state & QStyle::State_Selected) {
185 painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
186 } else {
187 painter->setPen(option.palette.color(cg, QPalette::Text));
188 }
189
190 painter->setFont(option.font);
191
192 painter->drawPixmap(option.rect.x() + 5, option.rect.y() + 5, pixmap);
193
194 painter->setFont(boldFont);
195 if (!name.isEmpty()) {
196 painter->drawText(option.rect.x() + 5 + wp + 5, option.rect.y() + 7, wn, hn, Qt::AlignLeft, name);
197 }
198 painter->setFont(oldFont);
199
200 if (!comment.isEmpty()) {
201 painter->drawText(option.rect.x() + 5 + wp + 5, option.rect.y() + 7 + hn, wc, hc, Qt::AlignLeft, comment);
202 }
203
204 painter->setPen(pen);
205
206 drawFocus(painter, option, option.rect);
207}
208
209QSize AgentTypeWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
210{
211 if (!index.isValid()) {
212 return QSize(0, 0);
213 }
214
215 const QString name = index.model()->data(index, Qt::DisplayRole).toString();
216 const QString comment = index.model()->data(index, AgentTypeModel::DescriptionRole).toString();
217
218 const QFontMetrics fm = option.fontMetrics;
219 int hn = fm.boundingRect(0, 0, 0, 0, Qt::AlignLeft, name).height();
220 int wn = fm.boundingRect(0, 0, 0, 0, Qt::AlignLeft, name).width();
221 int hc = fm.boundingRect(0, 0, 0, 0, Qt::AlignLeft, comment).height();
222 int wc = fm.boundingRect(0, 0, 0, 0, Qt::AlignLeft, comment).width();
223
224 int width = 0;
225 int height = 0;
226
227 if (!name.isEmpty()) {
228 height += hn;
229 width = qMax(width, wn);
230 }
231
232 if (!comment.isEmpty()) {
233 height += hc;
234 width = qMax(width, wc);
235 }
236
237 height = qMax(height, 64) + 10;
238 width += 64 + 15;
239
240 return QSize(width, height);
241}
242
243void AgentTypeWidgetDelegate::drawFocus(QPainter *painter, const QStyleOptionViewItem &option, QRect rect) const
244{
245 if (option.state & QStyle::State_HasFocus) {
247 o.QStyleOption::operator=(option);
248 o.rect = rect;
250 QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled;
251 o.backgroundColor = option.palette.color(cg, (option.state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Window);
253 }
254}
255
256} // namespace Akonadi
257
258#include "agenttypewidget.moc"
259
260#include "moc_agenttypewidget.cpp"
A proxy model for filtering AgentType or AgentInstance.
Provides a data model for agent types.
@ TypeRole
The agent type itself.
@ DescriptionRole
A description of the agent type.
~AgentTypeWidget() override
Destroys the agent type widget.
AgentType currentAgentType() const
Returns the current agent type or an invalid agent type if no agent type is selected.
void currentChanged(const Akonadi::AgentType &current, const Akonadi::AgentType &previous)
This signal is emitted whenever the current agent type changes.
AgentFilterProxyModel * agentFilterProxyModel() const
Returns the agent filter proxy model, use this to filter by agent mimetype or capabilities.
void activated()
This signal is emitted whenever the user activates an agent.
AgentTypeWidget(QWidget *parent=nullptr)
Creates a new agent type widget.
A representation of an agent type.
Q_SCRIPTABLE Q_NOREPLY void start()
Helper integration between Akonadi and Qt.
QString name(GameStandardAction id)
virtual QVariant data(const QModelIndex &index, int role) const const=0
void activated(const QModelIndex &index)
QStyle * style()
QRect boundingRect(QChar ch) const const
void currentChanged(const QModelIndex &current, const QModelIndex &previous)
QModelIndex currentIndex() const const
void addWidget(QWidget *w)
void setContentsMargins(const QMargins &margins)
QVariant data(int role) const const
Qt::ItemFlags flags() const const
bool isValid() const const
const QAbstractItemModel * model() const const
Q_OBJECTQ_OBJECT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
void drawText(const QPoint &position, const QString &text)
const QFont & font() const const
QFontMetrics fontMetrics() const const
const QPen & pen() const const
void setFont(const QFont &font)
void setPen(Qt::PenStyle style)
void setRenderHint(RenderHint hint, bool on)
int width() const const
int height() const const
int width() const const
bool isEmpty() const const
PE_PanelItemViewItem
virtual void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
AlignLeft
DisplayRole
ItemIsSelectable
bool isValid() const const
QString toString() const const
int typeId() const const
T value() const const
QLayout * layout() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:31:59 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.