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

KNewStuff

itemsviewdelegate.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2008 Jeremy Whiting <jeremy@scitools.com>               *
00003  *                                                                         *
00004  *   This library is free software; you can redistribute it and/or         *
00005  *   modify it under the terms of the GNU Lesser General Public            *
00006  *   License as published by the Free Software Foundation; either          *
00007  *   version 2 of the License, or (at your option) any later version.      *
00008  *                                                                         *
00009  *   This library is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00012  *   Lesser General Public License for more details.                       *
00013  *                                                                         *
00014  *   You should have received a copy of the GNU Lesser General Public      *
00015  *   License along with this library; if not, write to the                 *
00016  *   Free Software Foundation, Inc.,                                       *
00017  ***************************************************************************/
00018 
00019 #include "itemsviewdelegate.h"
00020 #include "itemsmodel.h"
00021 
00022 #include <QtGui/QPainter>
00023 #include <QtGui/QSortFilterProxyModel>
00024 
00025 #include <kdebug.h>
00026 #include <kstandarddirs.h>
00027 #include <kicon.h>
00028 #include <klocale.h>
00029 #include <kmenu.h>
00030 #include <krun.h>
00031 
00032 static const int kLabel = 0;
00033 static const int kInstall = 1;
00034 static const int kCollaborate = 2;
00035 
00036 namespace KNS
00037 {
00038 ItemsViewDelegate::ItemsViewDelegate(QAbstractItemView *itemView, QObject * parent)
00039         : KWidgetItemDelegate(itemView, parent)
00040 {
00041     QString framefile = KStandardDirs::locate("data", "knewstuff/pics/thumb_frame.png");
00042 
00043     m_frameImage = QPixmap(framefile).toImage();
00044 
00045     // Invalid
00046     m_statusicons << KIcon("dialog-error");
00047     // Downloadable
00048     m_statusicons << KIcon();
00049     //Installed
00050     m_statusicons << KIcon("dialog-ok");
00051     //Updateable
00052     m_statusicons << KIcon("system-software-update");
00053     //Deleted
00054     m_statusicons << KIcon("edit-delete");
00055 }
00056 
00057 ItemsViewDelegate::~ItemsViewDelegate()
00058 {
00059 }
00060 
00061 KMenu * ItemsViewDelegate::InstallMenu(const QToolButton* button, Entry::Status status) const
00062 {
00063     KMenu * installMenu = new KMenu(NULL);
00064     QAction * action_install = installMenu->addAction(m_statusicons[Entry::Installed], i18n("Install"));
00065     QAction * action_uninstall = installMenu->addAction(m_statusicons[Entry::Deleted], i18n("Uninstall"));
00066     action_install->setData(DownloadDialog::kInstall);
00067     action_uninstall->setData(DownloadDialog::kUninstall);
00068 
00069     action_install->setVisible(status != Entry::Installed);
00070     action_uninstall->setVisible(status == Entry::Installed);
00071     return installMenu;
00072 }
00073 
00074 QList<QWidget*> ItemsViewDelegate::createItemWidgets() const
00075 {
00076     QList<QWidget*> list;
00077 
00078     QLabel * infoLabel = new QLabel();
00079     infoLabel->setOpenExternalLinks(true);
00080     list << infoLabel;
00081 
00082     QToolButton * installButton = new QToolButton();
00083     list << installButton;
00084     setBlockedEventTypes(installButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
00085                          << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
00086     connect(installButton, SIGNAL(triggered(QAction *)), this, SLOT(slotActionTriggered(QAction *)));
00087     connect(installButton, SIGNAL(clicked()), this, SLOT(slotInstallClicked()));
00088 
00089     return list;
00090 }
00091 
00092 void ItemsViewDelegate::updateItemWidgets(const QList<QWidget*> widgets,
00093         const QStyleOptionViewItem &option,
00094         const QPersistentModelIndex &index) const
00095 {
00096     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00097     if (model == NULL) {
00098         return;
00099     }
00100 
00101     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00102     if (realmodel == NULL || !index.isValid()) {
00103         return;
00104     }
00105 
00106     // setup the install button
00107     int margin = option.fontMetrics.height() / 2;
00108 
00109     int right = option.rect.width();
00110     //int bottom = option.rect.height();
00111 
00112     QSize size(option.fontMetrics.height() * 7, widgets.at(kInstall)->sizeHint().height());
00113 
00114     QLabel * infoLabel = qobject_cast<QLabel*>(widgets.at(kLabel));
00115     if (infoLabel != NULL) {
00116         if (realmodel->hasPreviewImages()) {
00117             // move the text right by 64 + margin pixels to fit the preview
00118             infoLabel->move(64 + margin * 2, 0);
00119             infoLabel->resize(QSize(option.rect.width() - 64 - (margin * 4) - size.width(), option.fontMetrics.height() * 5));
00120         } else {
00121             infoLabel->move(margin, 0);
00122             infoLabel->resize(QSize(option.rect.width() - margin - size.width(), option.fontMetrics.height() * 5));
00123         }
00124 
00125         QString text = "<b>" + index.data(ItemsModel::kNameRole).toString() + "</b><br />";
00126 
00127         QString summary = option.fontMetrics.elidedText(index.data(ItemsModel::kSummary).toString(),
00128                           Qt::ElideRight, infoLabel->width());
00129         QStringList summarylines = summary.split('\n');
00130         summary = summarylines[0];
00131         text += summary + "<br />";
00132 
00133         QString authorName = index.data(ItemsModel::kAuthorName).toString();
00134         QString email = index.data(ItemsModel::kAuthorEmail).toString();
00135         if (!authorName.isEmpty()) {
00136             if (email.isEmpty()) {
00137                 text += "<i>" + authorName + "</i>";
00138             } else {
00139                 text += "<i>" + authorName + "</i> <a href=\"mailto:" + email + "\">" + email + "</a>";
00140             }
00141             text += "<br />";
00142         }
00143 
00144         unsigned int downloads = index.data(ItemsModel::kDownloads).toUInt();
00145         text += downloads == 0 ? i18n("No Downloads") : i18n("Downloads: %1", downloads);
00146 
00147         infoLabel->setText(text);
00148     }
00149 
00150     QToolButton * button = qobject_cast<QToolButton*>(widgets.at(kInstall));
00151     if (button != NULL) {
00152         Entry::Status status = Entry::Status(model->data(index, ItemsModel::kStatus).toUInt());
00153         if (!button->menu()) {
00154             button->setMenu(InstallMenu(button, status));
00155             button->setIconSize(QSize(16, 16));
00156             button->resize(size);
00157         }
00158         button->move(right - button->width() - margin, option.rect.height() / 2 - button->height() / 2);
00159         button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
00160         button->setPopupMode(QToolButton::MenuButtonPopup);
00161 
00162         // validate our assumptions
00163         Q_ASSERT(button->menu());
00164         Q_ASSERT(button->menu()->actions().count() == 2);
00165 
00166         // get the two actions
00167         QAction * action_install = button->menu()->actions()[0];
00168         QAction * action_uninstall = button->menu()->actions()[1];
00169         switch (status) {
00170         case Entry::Installed:
00171             button->setText(i18n("Uninstall"));
00172             action_install->setVisible(false);
00173             action_uninstall->setVisible(true);
00174             button->setIcon(QIcon(m_statusicons[Entry::Deleted]));
00175             break;
00176         case Entry::Updateable:
00177             button->setText(i18n("Update"));
00178             action_uninstall->setVisible(false);
00179             action_install->setText(i18n("Update"));
00180             action_install->setVisible(true);
00181             action_install->setIcon(QIcon(m_statusicons[Entry::Updateable]));
00182             button->setIcon(QIcon(m_statusicons[Entry::Updateable]));
00183             break;
00184         case Entry::Deleted:
00186             button->setText(i18n("Install"));
00187             action_uninstall->setVisible(false);
00188             action_install->setText(i18n("Install"));
00189             action_install->setVisible(true);
00190             action_install->setIcon(QIcon(m_statusicons[Entry::Installed]));
00191             button->setIcon(QIcon(m_statusicons[Entry::Installed]));
00192             break;
00193         default:
00194             button->setText(i18n("Install"));
00195             action_uninstall->setVisible(false);
00196             action_install->setVisible(true);
00197             action_install->setIcon(QIcon(m_statusicons[Entry::Installed]));
00198             button->setIcon(QIcon(m_statusicons[Entry::Installed]));
00199         }
00200     }
00201 }
00202 
00203 // draw the entry based on what
00204 // paint the item at index with all it's attributes shown
00205 void ItemsViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
00206 {
00207     int margin = option.fontMetrics.height() / 2;
00208 
00209     painter->save();
00210 
00211     if (option.state & QStyle::State_Selected) {
00212         painter->fillRect(option.rect, option.palette.highlight());
00213     } else {
00214         painter->fillRect(option.rect, (index.row() % 2 == 0 ? option.palette.base() : option.palette.alternateBase()));
00215         painter->setPen(QPen(option.palette.window().color()));
00216         painter->drawRect(option.rect);
00217     }
00218 
00219     if (option.state & QStyle::State_Selected) {
00220         painter->setPen(QPen(option.palette.highlightedText().color()));
00221     } else {
00222         painter->setPen(QPen(option.palette.text().color()));
00223     }
00224 
00225     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00226     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00227 
00228     if (realmodel->hasPreviewImages()) {
00229 
00230         int height = option.rect.height();
00231         QPoint point(option.rect.left() + margin, option.rect.top() + ((height - 64) / 2));
00232 
00233         if (index.data(ItemsModel::kPreview).toString().isEmpty()) {
00234             QRect rect(point, QSize(64, 64));
00235             painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("No Preview"));
00236         } else {
00237             QImage image = index.data(ItemsModel::kPreviewPixmap).value<QImage>();
00238             if (!image.isNull()) {
00239                 point.setY(option.rect.top() + ((height - image.height()) / 2));
00240                 painter->drawImage(point, image);
00241                 QPoint framePoint(point.x() - 5, point.y() - 5);
00242                 painter->drawImage(framePoint, m_frameImage.scaled(image.width() + 10, image.height() + 10));
00243             } else {
00244                 QRect rect(point, QSize(64, 64));
00245                 painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("Loading Preview"));
00246             }
00247         }
00248     }
00249 
00250     painter->restore();
00251 
00252     KWidgetItemDelegate::paintWidgets(painter, option, index);
00253 }
00254 
00255 //bool ItemsViewDelegate::eventFilter(QObject *watched, QEvent *event)
00256 //{
00257 //    if (event->type() == QEvent::ToolTip) {
00258 //
00259 //    }
00260 
00261 //    return KWidgetItemDelegate::eventFilter(watched, event);
00262 //}
00263 
00264 QSize ItemsViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
00265 {
00266     Q_UNUSED(option);
00267     Q_UNUSED(index);
00268 
00269     QSize size;
00270 
00271     size.setWidth(option.fontMetrics.height() * 4);
00272     size.setHeight(option.fontMetrics.height() * 5); // up to 4 lines of text, and two margins
00273 
00274     return size;
00275 }
00276 
00277 void ItemsViewDelegate::slotLinkClicked(const QString & url)
00278 {
00279     QModelIndex index = focusedIndex();
00280     Q_ASSERT(index.isValid());
00281 
00282     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00283     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00284     KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
00285     emit performAction(DownloadDialog::kContactEmail, entry);
00286 }
00287 
00288 void ItemsViewDelegate::slotActionTriggered(QAction *action)
00289 {
00290     QModelIndex index = focusedIndex();
00291     Q_ASSERT(index.isValid());
00292 
00293     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00294     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00295     KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
00296     emit performAction(DownloadDialog::EntryAction(action->data().toInt()), entry);
00297 }
00298 
00299 void ItemsViewDelegate::slotInstallClicked()
00300 {
00301     QModelIndex index = focusedIndex();
00302 
00303     if (index.isValid()) {
00304         const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00305         const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00306         KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
00307         if ( !entry )
00308             return;
00309 
00310         if (entry->status() == Entry::Installed) {
00311             emit performAction(DownloadDialog::kUninstall, entry);
00312         } else {
00313             emit performAction(DownloadDialog::kInstall, entry);
00314         }
00315     }
00316 }
00317 }

KNewStuff

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal