• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KNewStuff

  • knewstuff
  • knewstuff2
  • ui
knewstuff2/ui/itemsviewdelegate.cpp
Go to the documentation of this file.
1/*
2 This file is part of KNewStuff2.
3 Copyright (C) 2008 Jeremy Whiting <jpwhiting@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include "itemsviewdelegate.h"
20#include "itemsmodel.h"
21
22#include <QtGui/QPainter>
23#include <QtGui/QSortFilterProxyModel>
24
25#include <kdebug.h>
26#include <kstandarddirs.h>
27#include <kicon.h>
28#include <klocale.h>
29#include <kmenu.h>
30#include <krun.h>
31
32static const int kLabel = 0;
33static const int kInstall = 1;
34static const int kRating = 2;
35
36namespace KNS
37{
38ItemsViewDelegate::ItemsViewDelegate(QAbstractItemView *itemView, QObject * parent)
39 : KWidgetItemDelegate(itemView, parent)
40{
41 QString framefile = KStandardDirs::locate("data", "knewstuff/pics/thumb_frame.png");
42
43 m_frameImage = QPixmap(framefile).toImage();
44
45 // Invalid
46 m_statusicons << KIcon("dialog-error");
47 // Downloadable
48 m_statusicons << KIcon();
49 //Installed
50 m_statusicons << KIcon("dialog-ok");
51 //Updateable
52 m_statusicons << KIcon("system-software-update");
53 //Deleted
54 m_statusicons << KIcon("edit-delete");
55}
56
57ItemsViewDelegate::~ItemsViewDelegate()
58{
59}
60
61KMenu * ItemsViewDelegate::InstallMenu(const QToolButton* button, Entry::Status status) const
62{
63 Q_UNUSED(button)
64 KMenu * installMenu = new KMenu(NULL);
65 QAction * action_install = installMenu->addAction(m_statusicons[Entry::Installed], i18n("Install"));
66 QAction * action_uninstall = installMenu->addAction(m_statusicons[Entry::Deleted], i18n("Uninstall"));
67 action_install->setData(DownloadDialog::kInstall);
68 action_uninstall->setData(DownloadDialog::kUninstall);
69
70 action_install->setVisible(status != Entry::Installed);
71 action_uninstall->setVisible(status == Entry::Installed);
72 return installMenu;
73}
74
75QList<QWidget*> ItemsViewDelegate::createItemWidgets() const
76{
77 QList<QWidget*> list;
78
79 QLabel * infoLabel = new QLabel();
80 infoLabel->setOpenExternalLinks(true);
81 list << infoLabel;
82
83 QToolButton * installButton = new QToolButton();
84 list << installButton;
85 setBlockedEventTypes(installButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
86 << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
87 connect(installButton, SIGNAL(triggered(QAction*)), this, SLOT(slotActionTriggered(QAction*)));
88 connect(installButton, SIGNAL(clicked()), this, SLOT(slotInstallClicked()));
89
90 QLabel * ratingLabel = new QLabel();
91 list << ratingLabel;
92
93 return list;
94}
95
96void ItemsViewDelegate::updateItemWidgets(const QList<QWidget*> widgets,
97 const QStyleOptionViewItem &option,
98 const QPersistentModelIndex &index) const
99{
100 const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
101 if (model == NULL) {
102 return;
103 }
104
105 const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
106 if (realmodel == NULL || !index.isValid()) {
107 return;
108 }
109
110 // setup the install button
111 int margin = option.fontMetrics.height() / 2;
112
113 int right = option.rect.width();
114 //int bottom = option.rect.height();
115
116 QSize size(option.fontMetrics.height() * 7, widgets.at(kInstall)->sizeHint().height());
117
118 QLabel * infoLabel = qobject_cast<QLabel*>(widgets.at(kLabel));
119 infoLabel->setWordWrap(true);
120 if (infoLabel != NULL) {
121 if (realmodel->hasPreviewImages()) {
122 // move the text right by kPreviewWidth + margin pixels to fit the preview
123 infoLabel->move(kPreviewWidth + margin * 2, 0);
124 infoLabel->resize(QSize(option.rect.width() - kPreviewWidth - (margin * 6) - size.width(), option.fontMetrics.height() * 7));
125 } else {
126 infoLabel->move(margin, 0);
127 infoLabel->resize(QSize(option.rect.width() - (margin * 4) - size.width(), option.fontMetrics.height() * 7));
128 }
129
130 QString text = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
131 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">p, li { white-space: pre-wrap; margin:0 0 0 0;}\n"
132 "</style></head><body><p><b>" +
133 index.data(ItemsModel::kNameRole).toString() + "</b></p>\n";
134
135 QString summary = "<p>" + option.fontMetrics.elidedText(index.data(ItemsModel::kSummary).toString(),
136 Qt::ElideRight, infoLabel->width() * 3) + "</p>\n";
137 text += summary;
138
139 QString authorName = index.data(ItemsModel::kAuthorName).toString();
140 QString email = index.data(ItemsModel::kAuthorEmail).toString();
141 if (!authorName.isEmpty()) {
142 if (email.isEmpty()) {
143 text += "<p><i>" + authorName + "</i></p>\n";
144 } else {
145 text += "<p><i>" + authorName + "</i> <a href=\"mailto:" + email + "\">" + email + "</a></p>\n";
146 }
147 }
148
149 unsigned int downloads = index.data(ItemsModel::kDownloads).toUInt();
150 text += downloads == 0 ? i18n("<p>No Downloads</p>") : i18n("<p>Downloads: %1</p>\n", downloads);
151
152 text += "</body></html>";
153 text.replace("[b]", "<b>");
154 text.replace("[/b]", "</b>");
155 text.replace("[i]", "<i>");
156 text.replace("[/i]", "</i>");
157 text.replace("[u]", "<i>");
158 text.replace("[/u]", "</i>");
159 text.remove("[url]");
160 text.remove("[/url]");
161 text.replace("\\\'", "\'");
162 infoLabel->setText(text.simplified());
163 }
164
165 QToolButton * button = qobject_cast<QToolButton*>(widgets.at(kInstall));
166 if (button != NULL) {
167 Entry::Status status = Entry::Status(model->data(index, ItemsModel::kStatus).toUInt());
168 //if (!button->menu()) {
169 // button->setMenu(InstallMenu(button, status));
170 // button->setIconSize(QSize(16, 16));
171 button->resize(size);
172 //}
173 button->move(right - button->width() - margin, option.rect.height() / 2 - button->height());
174 button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
175 //button->setPopupMode(QToolButton::MenuButtonPopup);
176
177 // validate our assumptions
178 //Q_ASSERT(button->menu());
179 //Q_ASSERT(button->menu()->actions().count() == 2);
180
181 // get the two actions
182 //QAction * action_install = button->menu()->actions()[0];
183 //QAction * action_uninstall = button->menu()->actions()[1];
184 switch (status) {
185 case Entry::Installed:
186 button->setText(i18n("Uninstall"));
187 //action_install->setVisible(false);
188 //action_uninstall->setVisible(true);
189 button->setIcon(QIcon(m_statusicons[Entry::Deleted]));
190 break;
191 case Entry::Updateable:
192 button->setText(i18n("Update"));
193 //action_uninstall->setVisible(false);
194 //action_install->setText(i18n("Update"));
195 //action_install->setVisible(true);
196 //action_install->setIcon(QIcon(m_statusicons[Entry::Updateable]));
197 button->setIcon(QIcon(m_statusicons[Entry::Updateable]));
198 break;
199 case Entry::Deleted:
201 button->setText(i18n("Install"));
202 //action_uninstall->setVisible(false);
203 //action_install->setText(i18n("Install"));
204 //action_install->setVisible(true);
205 //action_install->setIcon(QIcon(m_statusicons[Entry::Installed]));
206 button->setIcon(QIcon(m_statusicons[Entry::Installed]));
207 break;
208 default:
209 button->setText(i18n("Install"));
210 //action_uninstall->setVisible(false);
211 //action_install->setVisible(true);
212 //action_install->setIcon(QIcon(m_statusicons[Entry::Installed]));
213 button->setIcon(QIcon(m_statusicons[Entry::Installed]));
214 }
215 }
216
217 QLabel * ratingLabel = qobject_cast<QLabel*>(widgets.at(kRating));
218 if (ratingLabel != NULL) {
219 ratingLabel->setText(i18n("Rating: %1", model->data(index, ItemsModel::kRating).toString()));
220
221 // put the rating label below the install button
222 ratingLabel->move(right - button->width() - margin, option.rect.height() / 2 + button->height()/2);
223 ratingLabel->resize(size);
224 }
225}
226
227// draw the entry based on what
228// paint the item at index with all it's attributes shown
229void ItemsViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
230{
231 int margin = option.fontMetrics.height() / 2;
232
233 QStyle *style = QApplication::style();
234 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0);
235
236 painter->save();
237
238 if (option.state & QStyle::State_Selected) {
239 painter->setPen(QPen(option.palette.highlightedText().color()));
240 } else {
241 painter->setPen(QPen(option.palette.text().color()));
242 }
243
244 const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
245 const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
246
247 if (realmodel->hasPreviewImages()) {
248
249 int height = option.rect.height();
250 QPoint point(option.rect.left() + margin, option.rect.top() + ((height - kPreviewHeight) / 2));
251
252 if (index.data(ItemsModel::kPreview).toString().isEmpty()) {
253 QRect rect(point, QSize(kPreviewWidth, kPreviewHeight));
254 painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("No Preview"));
255 } else {
256 QImage image = index.data(ItemsModel::kPreviewPixmap).value<QImage>();
257 if (!image.isNull()) {
258 point.setY(option.rect.top() + ((height - image.height()) / 2));
259 painter->drawImage(point, image);
260 QPoint framePoint(point.x() - 5, point.y() - 5);
261 painter->drawImage(framePoint, m_frameImage.scaled(image.width() + 10, image.height() + 10));
262 } else {
263 QRect rect(point, QSize(kPreviewWidth, kPreviewHeight));
264 painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("Loading Preview"));
265 }
266 }
267 }
268
269 painter->restore();
270}
271
272//bool ItemsViewDelegate::eventFilter(QObject *watched, QEvent *event)
273//{
274// if (event->type() == QEvent::ToolTip) {
275//
276// }
277
278// return KWidgetItemDelegate::eventFilter(watched, event);
279//}
280
281QSize ItemsViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
282{
283 Q_UNUSED(option);
284 Q_UNUSED(index);
285
286 QSize size;
287
288 size.setWidth(option.fontMetrics.height() * 4);
289 size.setHeight(qMax(option.fontMetrics.height() * 7, kPreviewHeight)); // up to 6 lines of text, and two margins
290
291 return size;
292}
293
294void ItemsViewDelegate::slotLinkClicked(const QString & url)
295{
296 Q_UNUSED(url)
297 QModelIndex index = focusedIndex();
298 Q_ASSERT(index.isValid());
299
300 const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
301 const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
302 KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
303 emit performAction(DownloadDialog::kContactEmail, entry);
304}
305
306void ItemsViewDelegate::slotActionTriggered(QAction *action)
307{
308 QModelIndex index = focusedIndex();
309 Q_ASSERT(index.isValid());
310
311 const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
312 const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
313 KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
314 emit performAction(DownloadDialog::EntryAction(action->data().toInt()), entry);
315}
316
317void ItemsViewDelegate::slotInstallClicked()
318{
319 QModelIndex index = focusedIndex();
320
321 if (index.isValid()) {
322 const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
323 const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
324 KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
325 if ( !entry )
326 return;
327
328 if (entry->status() == Entry::Installed) {
329 emit performAction(DownloadDialog::kUninstall, entry);
330 } else {
331 emit performAction(DownloadDialog::kInstall, entry);
332 }
333 }
334}
335}
KIcon
KMenu
KNS::DownloadDialog::EntryAction
EntryAction
Definition: knewstuff2/ui/downloaddialog.h:76
KNS::DownloadDialog::kInstall
@ kInstall
Definition: knewstuff2/ui/downloaddialog.h:86
KNS::DownloadDialog::kUninstall
@ kUninstall
Definition: knewstuff2/ui/downloaddialog.h:85
KNS::DownloadDialog::kContactEmail
@ kContactEmail
Definition: knewstuff2/ui/downloaddialog.h:80
KNS::Entry
KNewStuff data entry container.
Definition: knewstuff2/core/entry.h:47
KNS::Entry::status
Status status()
Retrieves the entry's status.
Definition: knewstuff2/core/entry.cpp:216
KNS::Entry::Status
Status
Status of the entry.
Definition: knewstuff2/core/entry.h:290
KNS::Entry::Installed
@ Installed
Definition: knewstuff2/core/entry.h:293
KNS::Entry::Deleted
@ Deleted
Definition: knewstuff2/core/entry.h:295
KNS::Entry::Updateable
@ Updateable
Definition: knewstuff2/core/entry.h:294
KNS::ItemsModel
Definition: knewstuff2/ui/itemsmodel.h:34
KNS::ItemsModel::entryForIndex
KNS::Entry * entryForIndex(const QModelIndex &index) const
Definition: knewstuff2/ui/itemsmodel.cpp:108
KNS::ItemsModel::kStatus
@ kStatus
the status of this entry
Definition: knewstuff2/ui/itemsmodel.h:76
KNS::ItemsModel::kDownloads
@ kDownloads
the number of downloads for the entry
Definition: knewstuff2/ui/itemsmodel.h:74
KNS::ItemsModel::kNameRole
@ kNameRole
the name of the entry
Definition: knewstuff2/ui/itemsmodel.h:42
KNS::ItemsModel::kRating
@ kRating
the rating of the entry
Definition: knewstuff2/ui/itemsmodel.h:72
KNS::ItemsModel::kAuthorEmail
@ kAuthorEmail
the e-mail address of the author
Definition: knewstuff2/ui/itemsmodel.h:48
KNS::ItemsModel::kPreview
@ kPreview
the preview url
Definition: knewstuff2/ui/itemsmodel.h:66
KNS::ItemsModel::kPreviewPixmap
@ kPreviewPixmap
the preview image
Definition: knewstuff2/ui/itemsmodel.h:68
KNS::ItemsModel::kSummary
@ kSummary
a summary of the entry
Definition: knewstuff2/ui/itemsmodel.h:56
KNS::ItemsModel::kAuthorName
@ kAuthorName
the name of the author of the entry
Definition: knewstuff2/ui/itemsmodel.h:46
KNS::ItemsModel::hasPreviewImages
bool hasPreviewImages() const
Definition: knewstuff2/ui/itemsmodel.cpp:178
KNS::ItemsViewDelegate::performAction
void performAction(DownloadDialog::EntryAction action, KNS::Entry *entry)
KNS::ItemsViewDelegate::sizeHint
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: knewstuff2/ui/itemsviewdelegate.cpp:281
KNS::ItemsViewDelegate::ItemsViewDelegate
ItemsViewDelegate(QAbstractItemView *itemView, QObject *parent=0)
Definition: knewstuff2/ui/itemsviewdelegate.cpp:38
KNS::ItemsViewDelegate::createItemWidgets
virtual QList< QWidget * > createItemWidgets() const
Definition: knewstuff2/ui/itemsviewdelegate.cpp:75
KNS::ItemsViewDelegate::paint
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: knewstuff2/ui/itemsviewdelegate.cpp:229
KNS::ItemsViewDelegate::updateItemWidgets
virtual void updateItemWidgets(const QList< QWidget * > widgets, const QStyleOptionViewItem &option, const QPersistentModelIndex &index) const
Definition: knewstuff2/ui/itemsviewdelegate.cpp:96
KNS::ItemsViewDelegate::~ItemsViewDelegate
~ItemsViewDelegate()
Definition: knewstuff2/ui/itemsviewdelegate.cpp:57
KStandardDirs::locate
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
KWidgetItemDelegate
KWidgetItemDelegate::setBlockedEventTypes
void setBlockedEventTypes(QWidget *widget, QList< QEvent::Type > types) const
KWidgetItemDelegate::focusedIndex
QPersistentModelIndex focusedIndex() const
QAction
QLabel
QList
QObject
QSortFilterProxyModel
QToolButton
kdebug.h
kicon.h
klocale.h
i18n
QString i18n(const char *text)
kmenu.h
kInstall
static const int kInstall
Definition: knewstuff2/ui/itemsviewdelegate.cpp:33
kLabel
static const int kLabel
Definition: knewstuff2/ui/itemsviewdelegate.cpp:32
kRating
static const int kRating
Definition: knewstuff2/ui/itemsviewdelegate.cpp:34
itemsmodel.h
itemsviewdelegate.h
krun.h
kstandarddirs.h
KNS
Definition: knewstuff2/core/author.h:27
KNS::kPreviewWidth
static const int kPreviewWidth
Definition: knewstuff2/ui/itemsmodel.h:29
KNS::kPreviewHeight
static const int kPreviewHeight
Definition: knewstuff2/ui/itemsmodel.h:30
list
QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KNewStuff

Skip menu "KNewStuff"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal