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

KNewStuff

  • sources
  • kde-4.14
  • kdelibs
  • 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 
32 static const int kLabel = 0;
33 static const int kInstall = 1;
34 static const int kRating = 2;
35 
36 namespace KNS
37 {
38 ItemsViewDelegate::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 
57 ItemsViewDelegate::~ItemsViewDelegate()
58 {
59 }
60 
61 KMenu * 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 
75 QList<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 
96 void 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
229 void 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 
281 QSize 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 
294 void 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 
306 void 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 
317 void 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 }
i18n
QString i18n(const char *text)
QModelIndex
QWidget
QSize::setHeight
void setHeight(int height)
KWidgetItemDelegate::focusedIndex
QPersistentModelIndex focusedIndex() const
KNS::ItemsModel
Definition: knewstuff2/ui/itemsmodel.h:33
kdebug.h
QAbstractItemView
KNS::ItemsModel::kDownloads
the number of downloads for the entry
Definition: knewstuff2/ui/itemsmodel.h:74
KNS::ItemsModel::kAuthorEmail
the e-mail address of the author
Definition: knewstuff2/ui/itemsmodel.h:48
KNS::ItemsViewDelegate::ItemsViewDelegate
ItemsViewDelegate(QAbstractItemView *itemView, QObject *parent=0)
Definition: knewstuff2/ui/itemsviewdelegate.cpp:38
KNS::Entry
KNewStuff data entry container.
Definition: knewstuff2/core/entry.h:46
KNS::ItemsModel::kNameRole
the name of the entry
Definition: knewstuff2/ui/itemsmodel.h:42
QLabel::setOpenExternalLinks
void setOpenExternalLinks(bool open)
KMenu
KStandardDirs::locate
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
QList::at
const T & at(int i) const
QString::simplified
QString simplified() const
kLabel
static const int kLabel
Definition: knewstuff2/ui/itemsviewdelegate.cpp:32
QPainter::save
void save()
QVariant::value
T value() const
QPoint
QImage::isNull
bool isNull() const
QString::remove
QString & remove(int position, int n)
KNS::ItemsViewDelegate
Definition: knewstuff2/ui/itemsviewdelegate.h:39
QPersistentModelIndex::model
const QAbstractItemModel * model() const
KNS::Entry::Status
Status
Status of the entry.
Definition: knewstuff2/core/entry.h:290
klocale.h
QAbstractButton::setIcon
void setIcon(const QIcon &icon)
KNS::kPreviewHeight
static const int kPreviewHeight
Definition: knewstuff2/ui/itemsmodel.h:30
KWidgetItemDelegate::setBlockedEventTypes
void setBlockedEventTypes(QWidget *widget, QList< QEvent::Type > types) const
KNS::Entry::Deleted
Definition: knewstuff2/core/entry.h:295
KNS::ItemsModel::hasPreviewImages
bool hasPreviewImages() const
Definition: knewstuff2/ui/itemsmodel.cpp:178
KNS::DownloadDialog::EntryAction
EntryAction
Definition: knewstuff2/ui/downloaddialog.h:76
kRating
static const int kRating
Definition: knewstuff2/ui/itemsviewdelegate.cpp:34
KWidgetItemDelegate
QWidget::width
width
QWidget::resize
void resize(int w, int h)
QRect
QModelIndex::isValid
bool isValid() const
QPersistentModelIndex::isValid
bool isValid() const
QVariant::toUInt
uint toUInt(bool *ok) const
kmenu.h
QStyleOptionViewItem
QObject
QStyle
QPainter::setPen
void setPen(const QColor &color)
QImage::width
int width() const
QSize::setWidth
void setWidth(int width)
QPainter
QString::isEmpty
bool isEmpty() const
QPersistentModelIndex::data
QVariant data(int role) const
KNS::ItemsModel::kStatus
the status of this entry
Definition: knewstuff2/ui/itemsmodel.h:76
KIcon
QWidget::move
void move(int x, int y)
QPainter::drawText
void drawText(const QPointF &position, const QString &text)
QLabel::setText
void setText(const QString &)
KNS::ItemsViewDelegate::updateItemWidgets
virtual void updateItemWidgets(const QList< QWidget * > widgets, const QStyleOptionViewItem &option, const QPersistentModelIndex &index) const
Definition: knewstuff2/ui/itemsviewdelegate.cpp:96
QString
QList
KNS::ItemsViewDelegate::createItemWidgets
virtual QList< QWidget * > createItemWidgets() const
Definition: knewstuff2/ui/itemsviewdelegate.cpp:75
QPixmap
itemsmodel.h
QToolButton
QSize
KNS::Entry::Installed
Definition: knewstuff2/core/entry.h:293
QSortFilterProxyModel
QImage
KNS::DownloadDialog::kUninstall
Definition: knewstuff2/ui/downloaddialog.h:85
QPainter::restore
void restore()
KNS::ItemsModel::kSummary
a summary of the entry
Definition: knewstuff2/ui/itemsmodel.h:56
QString::replace
QString & replace(int position, int n, QChar after)
krun.h
QPersistentModelIndex
QAbstractProxyModel::sourceModel
QAbstractItemModel * sourceModel() const
QSortFilterProxyModel::mapToSource
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const
KNS::ItemsViewDelegate::~ItemsViewDelegate
~ItemsViewDelegate()
Definition: knewstuff2/ui/itemsviewdelegate.cpp:57
QPainter::drawImage
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, QFlags< Qt::ImageConversionFlag > flags)
QModelIndex::model
const QAbstractItemModel * model() const
KNS::ItemsModel::kPreview
the preview url
Definition: knewstuff2/ui/itemsmodel.h:66
QModelIndex::data
QVariant data(int role) const
KNS::ItemsModel::kPreviewPixmap
the preview image
Definition: knewstuff2/ui/itemsmodel.h:68
KNS::ItemsViewDelegate::paint
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: knewstuff2/ui/itemsviewdelegate.cpp:229
QApplication::style
QStyle * style()
KNS::DownloadDialog::kInstall
Definition: knewstuff2/ui/downloaddialog.h:86
kstandarddirs.h
KNS::kPreviewWidth
static const int kPreviewWidth
Definition: knewstuff2/ui/itemsmodel.h:29
QAction
itemsviewdelegate.h
KNS::ItemsViewDelegate::performAction
void performAction(DownloadDialog::EntryAction action, KNS::Entry *entry)
QStyle::drawPrimitive
virtual void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const =0
QAbstractButton::setText
void setText(const QString &text)
KNS::ItemsModel::kRating
the rating of the entry
Definition: knewstuff2/ui/itemsmodel.h:72
QPen
QImage::height
int height() const
QPixmap::toImage
QImage toImage() const
KNS::ItemsModel::kAuthorName
the name of the author of the entry
Definition: knewstuff2/ui/itemsmodel.h:46
kicon.h
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KNS::ItemsViewDelegate::sizeHint
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: knewstuff2/ui/itemsviewdelegate.cpp:281
QLabel
QToolButton::setToolButtonStyle
void setToolButtonStyle(Qt::ToolButtonStyle style)
QVariant::toString
QString toString() const
QLabel::setWordWrap
void setWordWrap(bool on)
QWidget::height
height
KNS::DownloadDialog
KNewStuff download dialog.
Definition: knewstuff2/ui/downloaddialog.h:68
QImage::scaled
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
QSortFilterProxyModel::data
virtual QVariant data(const QModelIndex &index, int role) const
kInstall
static const int kInstall
Definition: knewstuff2/ui/itemsviewdelegate.cpp:33
QIcon
KNS::Entry::Updateable
Definition: knewstuff2/core/entry.h:294
list
QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:25:43 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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