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

KNewStuff

itemsviewdelegate.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of KNewStuff2.
00003     Copyright (C) 2008 Jeremy Whiting <jeremy@scitools.com>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
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     Q_UNUSED(button)
00064     KMenu * installMenu = new KMenu(NULL);
00065     QAction * action_install = installMenu->addAction(m_statusicons[Entry::Installed], i18n("Install"));
00066     QAction * action_uninstall = installMenu->addAction(m_statusicons[Entry::Deleted], i18n("Uninstall"));
00067     action_install->setData(DownloadDialog::kInstall);
00068     action_uninstall->setData(DownloadDialog::kUninstall);
00069 
00070     action_install->setVisible(status != Entry::Installed);
00071     action_uninstall->setVisible(status == Entry::Installed);
00072     return installMenu;
00073 }
00074 
00075 QList<QWidget*> ItemsViewDelegate::createItemWidgets() const
00076 {
00077     QList<QWidget*> list;
00078 
00079     QLabel * infoLabel = new QLabel();
00080     infoLabel->setOpenExternalLinks(true);
00081     list << infoLabel;
00082 
00083     QToolButton * installButton = new QToolButton();
00084     list << installButton;
00085     setBlockedEventTypes(installButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
00086                          << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
00087     connect(installButton, SIGNAL(triggered(QAction *)), this, SLOT(slotActionTriggered(QAction *)));
00088     connect(installButton, SIGNAL(clicked()), this, SLOT(slotInstallClicked()));
00089 
00090     return list;
00091 }
00092 
00093 void ItemsViewDelegate::updateItemWidgets(const QList<QWidget*> widgets,
00094         const QStyleOptionViewItem &option,
00095         const QPersistentModelIndex &index) const
00096 {
00097     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00098     if (model == NULL) {
00099         return;
00100     }
00101 
00102     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00103     if (realmodel == NULL || !index.isValid()) {
00104         return;
00105     }
00106 
00107     // setup the install button
00108     int margin = option.fontMetrics.height() / 2;
00109 
00110     int right = option.rect.width();
00111     //int bottom = option.rect.height();
00112 
00113     QSize size(option.fontMetrics.height() * 7, widgets.at(kInstall)->sizeHint().height());
00114 
00115     QLabel * infoLabel = qobject_cast<QLabel*>(widgets.at(kLabel));
00116     if (infoLabel != NULL) {
00117         if (realmodel->hasPreviewImages()) {
00118             // move the text right by 64 + margin pixels to fit the preview
00119             infoLabel->move(64 + margin * 2, 0);
00120             infoLabel->resize(QSize(option.rect.width() - 64 - (margin * 4) - size.width(), option.fontMetrics.height() * 5));
00121         } else {
00122             infoLabel->move(margin, 0);
00123             infoLabel->resize(QSize(option.rect.width() - margin - size.width(), option.fontMetrics.height() * 5));
00124         }
00125 
00126         QString text = "<b>" + index.data(ItemsModel::kNameRole).toString() + "</b><br />";
00127 
00128         QString summary = option.fontMetrics.elidedText(index.data(ItemsModel::kSummary).toString(),
00129                           Qt::ElideRight, infoLabel->width());
00130         QStringList summarylines = summary.split('\n');
00131         summary = summarylines[0];
00132         text += summary + "<br />";
00133 
00134         QString authorName = index.data(ItemsModel::kAuthorName).toString();
00135         QString email = index.data(ItemsModel::kAuthorEmail).toString();
00136         if (!authorName.isEmpty()) {
00137             if (email.isEmpty()) {
00138                 text += "<i>" + authorName + "</i>";
00139             } else {
00140                 text += "<i>" + authorName + "</i> <a href=\"mailto:" + email + "\">" + email + "</a>";
00141             }
00142             text += "<br />";
00143         }
00144 
00145         unsigned int downloads = index.data(ItemsModel::kDownloads).toUInt();
00146         text += downloads == 0 ? i18n("No Downloads") : i18n("Downloads: %1", downloads);
00147 
00148         infoLabel->setText(text);
00149     }
00150 
00151     QToolButton * button = qobject_cast<QToolButton*>(widgets.at(kInstall));
00152     if (button != NULL) {
00153         Entry::Status status = Entry::Status(model->data(index, ItemsModel::kStatus).toUInt());
00154         //if (!button->menu()) {
00155         //    button->setMenu(InstallMenu(button, status));
00156         //    button->setIconSize(QSize(16, 16));
00157             button->resize(size);
00158         //}
00159         button->move(right - button->width() - margin, option.rect.height() / 2 - button->height() / 2);
00160         button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
00161         //button->setPopupMode(QToolButton::MenuButtonPopup);
00162 
00163         // validate our assumptions
00164         //Q_ASSERT(button->menu());
00165         //Q_ASSERT(button->menu()->actions().count() == 2);
00166 
00167         // get the two actions
00168         //QAction * action_install = button->menu()->actions()[0];
00169         //QAction * action_uninstall = button->menu()->actions()[1];
00170         switch (status) {
00171         case Entry::Installed:
00172             button->setText(i18n("Uninstall"));
00173             //action_install->setVisible(false);
00174             //action_uninstall->setVisible(true);
00175             button->setIcon(QIcon(m_statusicons[Entry::Deleted]));
00176             break;
00177         case Entry::Updateable:
00178             button->setText(i18n("Update"));
00179             //action_uninstall->setVisible(false);
00180             //action_install->setText(i18n("Update"));
00181             //action_install->setVisible(true);
00182             //action_install->setIcon(QIcon(m_statusicons[Entry::Updateable]));
00183             button->setIcon(QIcon(m_statusicons[Entry::Updateable]));
00184             break;
00185         case Entry::Deleted:
00187             button->setText(i18n("Install"));
00188             //action_uninstall->setVisible(false);
00189             //action_install->setText(i18n("Install"));
00190             //action_install->setVisible(true);
00191             //action_install->setIcon(QIcon(m_statusicons[Entry::Installed]));
00192             button->setIcon(QIcon(m_statusicons[Entry::Installed]));
00193             break;
00194         default:
00195             button->setText(i18n("Install"));
00196             //action_uninstall->setVisible(false);
00197             //action_install->setVisible(true);
00198             //action_install->setIcon(QIcon(m_statusicons[Entry::Installed]));
00199             button->setIcon(QIcon(m_statusicons[Entry::Installed]));
00200         }
00201     }
00202 }
00203 
00204 // draw the entry based on what
00205 // paint the item at index with all it's attributes shown
00206 void ItemsViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
00207 {
00208     int margin = option.fontMetrics.height() / 2;
00209 
00210     painter->save();
00211 
00212     if (option.state & QStyle::State_Selected) {
00213         painter->fillRect(option.rect, option.palette.highlight());
00214     } else {
00215         painter->fillRect(option.rect, (index.row() % 2 == 0 ? option.palette.base() : option.palette.alternateBase()));
00216         painter->setPen(QPen(option.palette.window().color()));
00217         painter->drawRect(option.rect);
00218     }
00219 
00220     if (option.state & QStyle::State_Selected) {
00221         painter->setPen(QPen(option.palette.highlightedText().color()));
00222     } else {
00223         painter->setPen(QPen(option.palette.text().color()));
00224     }
00225 
00226     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00227     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00228 
00229     if (realmodel->hasPreviewImages()) {
00230 
00231         int height = option.rect.height();
00232         QPoint point(option.rect.left() + margin, option.rect.top() + ((height - 64) / 2));
00233 
00234         if (index.data(ItemsModel::kPreview).toString().isEmpty()) {
00235             QRect rect(point, QSize(64, 64));
00236             painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("No Preview"));
00237         } else {
00238             QImage image = index.data(ItemsModel::kPreviewPixmap).value<QImage>();
00239             if (!image.isNull()) {
00240                 point.setY(option.rect.top() + ((height - image.height()) / 2));
00241                 painter->drawImage(point, image);
00242                 QPoint framePoint(point.x() - 5, point.y() - 5);
00243                 painter->drawImage(framePoint, m_frameImage.scaled(image.width() + 10, image.height() + 10));
00244             } else {
00245                 QRect rect(point, QSize(64, 64));
00246                 painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("Loading Preview"));
00247             }
00248         }
00249     }
00250 
00251     painter->restore();
00252 }
00253 
00254 //bool ItemsViewDelegate::eventFilter(QObject *watched, QEvent *event)
00255 //{
00256 //    if (event->type() == QEvent::ToolTip) {
00257 //
00258 //    }
00259 
00260 //    return KWidgetItemDelegate::eventFilter(watched, event);
00261 //}
00262 
00263 QSize ItemsViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
00264 {
00265     Q_UNUSED(option);
00266     Q_UNUSED(index);
00267 
00268     QSize size;
00269 
00270     size.setWidth(option.fontMetrics.height() * 4);
00271     size.setHeight(option.fontMetrics.height() * 5); // up to 4 lines of text, and two margins
00272 
00273     return size;
00274 }
00275 
00276 void ItemsViewDelegate::slotLinkClicked(const QString & url)
00277 {
00278     Q_UNUSED(url)
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
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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