• Skip to content
  • Skip to link menu
KDE 4.3 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 kRating = 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     QLabel * ratingLabel = new QLabel();
00091     list << ratingLabel;
00092 
00093     return list;
00094 }
00095 
00096 void ItemsViewDelegate::updateItemWidgets(const QList<QWidget*> widgets,
00097         const QStyleOptionViewItem &option,
00098         const QPersistentModelIndex &index) const
00099 {
00100     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00101     if (model == NULL) {
00102         return;
00103     }
00104 
00105     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00106     if (realmodel == NULL || !index.isValid()) {
00107         return;
00108     }
00109 
00110     // setup the install button
00111     int margin = option.fontMetrics.height() / 2;
00112 
00113     int right = option.rect.width();
00114     //int bottom = option.rect.height();
00115 
00116     QSize size(option.fontMetrics.height() * 7, widgets.at(kInstall)->sizeHint().height());
00117 
00118     QLabel * infoLabel = qobject_cast<QLabel*>(widgets.at(kLabel));
00119     infoLabel->setWordWrap(true);
00120     if (infoLabel != NULL) {
00121         if (realmodel->hasPreviewImages()) {
00122             // move the text right by kPreviewWidth + margin pixels to fit the preview
00123             infoLabel->move(kPreviewWidth + margin * 2, 0);
00124             infoLabel->resize(QSize(option.rect.width() - kPreviewWidth - (margin * 6) - size.width(), option.fontMetrics.height() * 7));
00125         } else {
00126             infoLabel->move(margin, 0);
00127             infoLabel->resize(QSize(option.rect.width() - (margin * 4) - size.width(), option.fontMetrics.height() * 7));
00128         }
00129 
00130         QString text = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
00131             "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">p, li { white-space: pre-wrap; margin:0 0 0 0;}\n"
00132             "</style></head><body><p><b>" +
00133             index.data(ItemsModel::kNameRole).toString() + "</b></p>\n";
00134 
00135         QString summary = "<p>" + option.fontMetrics.elidedText(index.data(ItemsModel::kSummary).toString(),
00136           Qt::ElideRight, infoLabel->width() * 3) + "</p>\n";
00137         text += summary;
00138 
00139         QString authorName = index.data(ItemsModel::kAuthorName).toString();
00140         QString email = index.data(ItemsModel::kAuthorEmail).toString();
00141         if (!authorName.isEmpty()) {
00142             if (email.isEmpty()) {
00143                 text += "<p><i>" + authorName + "</i></p>\n";
00144             } else {
00145                 text += "<p><i>" + authorName + "</i> <a href=\"mailto:" + email + "\">" + email + "</a></p>\n";
00146             }
00147         }
00148 
00149         unsigned int downloads = index.data(ItemsModel::kDownloads).toUInt();
00150         text += downloads == 0 ? i18n("<p>No Downloads</p>") : i18n("<p>Downloads: %1</p>\n", downloads);
00151 
00152         text += "</body></html>";
00153         text.replace("[b]", "<b>");
00154         text.replace("[/b]", "</b>");
00155         text.replace("[i]", "<i>");
00156         text.replace("[/i]", "</i>");
00157         text.replace("[u]", "<i>");
00158         text.replace("[/u]", "</i>");
00159         text.remove("[url]");
00160         text.remove("[/url]");
00161         text.replace("\\\'", "\'");
00162         infoLabel->setText(text.simplified());
00163     }
00164 
00165     QToolButton * button = qobject_cast<QToolButton*>(widgets.at(kInstall));
00166     if (button != NULL) {
00167         Entry::Status status = Entry::Status(model->data(index, ItemsModel::kStatus).toUInt());
00168         //if (!button->menu()) {
00169         //    button->setMenu(InstallMenu(button, status));
00170         //    button->setIconSize(QSize(16, 16));
00171             button->resize(size);
00172         //}
00173         button->move(right - button->width() - margin, option.rect.height() / 2 - button->height());
00174         button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
00175         //button->setPopupMode(QToolButton::MenuButtonPopup);
00176 
00177         // validate our assumptions
00178         //Q_ASSERT(button->menu());
00179         //Q_ASSERT(button->menu()->actions().count() == 2);
00180 
00181         // get the two actions
00182         //QAction * action_install = button->menu()->actions()[0];
00183         //QAction * action_uninstall = button->menu()->actions()[1];
00184         switch (status) {
00185         case Entry::Installed:
00186             button->setText(i18n("Uninstall"));
00187             //action_install->setVisible(false);
00188             //action_uninstall->setVisible(true);
00189             button->setIcon(QIcon(m_statusicons[Entry::Deleted]));
00190             break;
00191         case Entry::Updateable:
00192             button->setText(i18n("Update"));
00193             //action_uninstall->setVisible(false);
00194             //action_install->setText(i18n("Update"));
00195             //action_install->setVisible(true);
00196             //action_install->setIcon(QIcon(m_statusicons[Entry::Updateable]));
00197             button->setIcon(QIcon(m_statusicons[Entry::Updateable]));
00198             break;
00199         case Entry::Deleted:
00201             button->setText(i18n("Install"));
00202             //action_uninstall->setVisible(false);
00203             //action_install->setText(i18n("Install"));
00204             //action_install->setVisible(true);
00205             //action_install->setIcon(QIcon(m_statusicons[Entry::Installed]));
00206             button->setIcon(QIcon(m_statusicons[Entry::Installed]));
00207             break;
00208         default:
00209             button->setText(i18n("Install"));
00210             //action_uninstall->setVisible(false);
00211             //action_install->setVisible(true);
00212             //action_install->setIcon(QIcon(m_statusicons[Entry::Installed]));
00213             button->setIcon(QIcon(m_statusicons[Entry::Installed]));
00214         }
00215     }
00216 
00217     QLabel * ratingLabel = qobject_cast<QLabel*>(widgets.at(kRating));
00218     if (ratingLabel != NULL) {
00219         ratingLabel->setText(i18n("Rating: %1", model->data(index, ItemsModel::kRating).toString()));
00220 
00221         // put the rating label below the install button
00222         ratingLabel->move(right - button->width() - margin, option.rect.height() / 2 + button->height()/2);
00223         ratingLabel->resize(size);
00224     }
00225 }
00226 
00227 // draw the entry based on what
00228 // paint the item at index with all it's attributes shown
00229 void ItemsViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
00230 {
00231     int margin = option.fontMetrics.height() / 2;
00232 
00233     QStyle *style = QApplication::style();
00234     style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0);
00235 
00236     painter->save();
00237 
00238     if (option.state & QStyle::State_Selected) {
00239         painter->setPen(QPen(option.palette.highlightedText().color()));
00240     } else {
00241         painter->setPen(QPen(option.palette.text().color()));
00242     }
00243 
00244     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00245     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00246 
00247     if (realmodel->hasPreviewImages()) {
00248 
00249         int height = option.rect.height();
00250         QPoint point(option.rect.left() + margin, option.rect.top() + ((height - kPreviewHeight) / 2));
00251 
00252         if (index.data(ItemsModel::kPreview).toString().isEmpty()) {
00253             QRect rect(point, QSize(kPreviewWidth, kPreviewHeight));
00254             painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("No Preview"));
00255         } else {
00256             QImage image = index.data(ItemsModel::kPreviewPixmap).value<QImage>();
00257             if (!image.isNull()) {
00258                 point.setY(option.rect.top() + ((height - image.height()) / 2));
00259                 painter->drawImage(point, image);
00260                 QPoint framePoint(point.x() - 5, point.y() - 5);
00261                 painter->drawImage(framePoint, m_frameImage.scaled(image.width() + 10, image.height() + 10));
00262             } else {
00263                 QRect rect(point, QSize(kPreviewWidth, kPreviewHeight));
00264                 painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("Loading Preview"));
00265             }
00266         }
00267     }
00268 
00269     painter->restore();
00270 }
00271 
00272 //bool ItemsViewDelegate::eventFilter(QObject *watched, QEvent *event)
00273 //{
00274 //    if (event->type() == QEvent::ToolTip) {
00275 //
00276 //    }
00277 
00278 //    return KWidgetItemDelegate::eventFilter(watched, event);
00279 //}
00280 
00281 QSize ItemsViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
00282 {
00283     Q_UNUSED(option);
00284     Q_UNUSED(index);
00285 
00286     QSize size;
00287 
00288     size.setWidth(option.fontMetrics.height() * 4);
00289     size.setHeight(qMax(option.fontMetrics.height() * 7, kPreviewHeight)); // up to 6 lines of text, and two margins
00290 
00291     return size;
00292 }
00293 
00294 void ItemsViewDelegate::slotLinkClicked(const QString & url)
00295 {
00296     Q_UNUSED(url)
00297     QModelIndex index = focusedIndex();
00298     Q_ASSERT(index.isValid());
00299 
00300     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00301     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00302     KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
00303     emit performAction(DownloadDialog::kContactEmail, entry);
00304 }
00305 
00306 void ItemsViewDelegate::slotActionTriggered(QAction *action)
00307 {
00308     QModelIndex index = focusedIndex();
00309     Q_ASSERT(index.isValid());
00310 
00311     const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00312     const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00313     KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
00314     emit performAction(DownloadDialog::EntryAction(action->data().toInt()), entry);
00315 }
00316 
00317 void ItemsViewDelegate::slotInstallClicked()
00318 {
00319     QModelIndex index = focusedIndex();
00320 
00321     if (index.isValid()) {
00322         const QSortFilterProxyModel * model = qobject_cast<const QSortFilterProxyModel*>(index.model());
00323         const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(model->sourceModel());
00324         KNS::Entry * entry = realmodel->entryForIndex(model->mapToSource(index));
00325         if ( !entry )
00326             return;
00327 
00328         if (entry->status() == Entry::Installed) {
00329             emit performAction(DownloadDialog::kUninstall, entry);
00330         } else {
00331             emit performAction(DownloadDialog::kInstall, entry);
00332         }
00333     }
00334 }
00335 }

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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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