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

KNewStuff

itemsgridviewdelegate.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2008 Jeremy Whiting <jpwhiting@kde.org>
00003     Copyright (C) 2010 Reza Fatahilah Shah <rshah0385@kireihana.com>
00004     Copyright (C) 2010 Frederik Gladhorn <gladhorn@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2.1 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public
00017     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 #include "itemsgridviewdelegate.h"
00021 
00022 #include <QtGui/QPainter>
00023 #include <QtGui/QSortFilterProxyModel>
00024 #include <QtGui/QApplication>
00025 #include <QLabel>
00026 #include <QToolButton>
00027 #include <QMenu>
00028 #include <QHBoxLayout>
00029 #include <QAbstractItemView>
00030 
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <kmenu.h>
00034 #include <kratingwidget.h>
00035 #include <ksqueezedtextlabel.h>
00036 
00037 #include "itemsmodel.h"
00038 
00039 namespace KNS3
00040 {
00041     enum { DelegateTitleLabel, DelegateAuthorLabel, DelegateDownloadCounterLabel,
00042         DelegateGridRatingWidget };
00043 
00044 ItemsGridViewDelegate::ItemsGridViewDelegate(QAbstractItemView *itemView, Engine* engine, QObject * parent)
00045         : ItemsViewBaseDelegate(itemView, engine, parent)
00046         ,m_elementYPos(0)
00047 {
00048     createOperationBar();
00049 }
00050 
00051 ItemsGridViewDelegate::~ItemsGridViewDelegate()
00052 {
00053 }
00054 
00055 QList<QWidget*> ItemsGridViewDelegate::createItemWidgets() const
00056 {
00057     QList<QWidget*> m_widgetList;
00058     KSqueezedTextLabel * titleLabel = new KSqueezedTextLabel();
00059     titleLabel->setOpenExternalLinks(true);
00060     titleLabel->setTextElideMode(Qt::ElideRight);
00061     // not so nice - work around constness to install the event filter
00062     ItemsGridViewDelegate* delegate = const_cast<ItemsGridViewDelegate*>(this);
00063     titleLabel->installEventFilter(delegate);
00064     m_widgetList << titleLabel;
00065 
00066     KSqueezedTextLabel * authorLabel = new KSqueezedTextLabel();
00067     authorLabel->setTextElideMode(Qt::ElideRight);
00068     m_widgetList << authorLabel;
00069     
00070     KSqueezedTextLabel * downloadCounterLabel = new KSqueezedTextLabel();
00071     downloadCounterLabel->setTextElideMode(Qt::ElideRight);
00072     m_widgetList << downloadCounterLabel;
00073     
00074     KRatingWidget* rating = new KRatingWidget();
00075     rating->setMaxRating(10);
00076     rating->setHalfStepsEnabled(true);
00077     m_widgetList << rating;
00078     
00079     return m_widgetList;
00080 }
00081 
00082 void ItemsGridViewDelegate::updateItemWidgets(const QList<QWidget*> widgets,
00083         const QStyleOptionViewItem &option,
00084         const QPersistentModelIndex &index) const
00085 {
00086     const ItemsModel * model = qobject_cast<const ItemsModel*>(index.model());
00087     if (!model) {
00088         kDebug() << "WARNING - INVALID MODEL!";
00089         return;
00090     }
00091     
00092     EntryInternal entry = index.data(Qt::UserRole).value<KNS3::EntryInternal>();
00093     int elementXPos = ItemMargin;
00094     int elementYPos = PreviewHeight + ItemMargin + FrameThickness*2;
00095     
00096     //setup rating widget
00097     KRatingWidget * rating = qobject_cast<KRatingWidget*>(widgets.at(DelegateGridRatingWidget));
00098     if (rating) {
00099         if (entry.rating() > 0) {
00100             rating->setToolTip(i18n("Rating: %1%", entry.rating()));
00101             // assume all entries come with rating 0..100 but most are in the range 20 - 80, so 20 is 0 stars, 80 is 5 stars
00102             rating->setRating((entry.rating()-20)*10/60);
00103             //make the rating widget smaller than the one at list view
00104             int newWidth = 68;
00105             QSize size(newWidth, 15);
00106             rating->resize(size);
00107             //put rating widget under image rectangle
00108             rating->move((ItemGridWidth-newWidth)/2, elementYPos);
00109             elementYPos += rating->height();
00110         } else {
00111             //is it better to stay visible?
00112             rating->setVisible(false);
00113         }
00114     }
00115     elementYPos += ItemMargin;
00116     
00117     //setup title label
00118     QLabel * titleLabel = qobject_cast<QLabel*>(widgets.at(DelegateTitleLabel));
00119     if (titleLabel != NULL) {
00120         titleLabel->setWordWrap(true);
00121         titleLabel->setAlignment(Qt::AlignHCenter);
00122         //titleLabel->setFrameStyle(QFrame::Panel);
00123         titleLabel->resize(QSize(option.rect.width() - (ItemMargin * 2), option.fontMetrics.height() * 2));
00124         titleLabel->move((ItemGridWidth-titleLabel->width())/2, elementYPos);
00125         
00126         QString title;
00127         KUrl link = qvariant_cast<KUrl>(entry.homepage());
00128         if (!link.isEmpty()) {
00129             title += "<b><a href=\"" + link.url() + "\">" + entry.name() + "</a></b>\n";
00130         } else {
00131             title += "<b>" + entry.name() + "</b>";
00132         }
00133         titleLabel->setText(title);
00134         elementYPos += titleLabel->height();
00135     }
00136     //setup author label
00137     QLabel * authorLabel = qobject_cast<QLabel*>(widgets.at(DelegateAuthorLabel));
00138     if (authorLabel != NULL) {
00139         authorLabel->setWordWrap(true);
00140         authorLabel->setAlignment(Qt::AlignHCenter);
00141         authorLabel->resize(QSize(option.rect.width() - (ItemMargin * 2), option.fontMetrics.height()));
00142         authorLabel->move((ItemGridWidth-authorLabel->width())/2,elementYPos);
00143         
00144         QString text;
00145         QString authorName = entry.author().name();
00146         QString email = entry.author().email();
00147         QString authorPage = entry.author().homepage();
00148 
00149         if (!authorName.isEmpty()) {
00150             if (!authorPage.isEmpty()) {
00151                 text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", " <a href=\"" + authorPage + "\">" + authorName + "</a>") + "</p>\n";
00152             } else if (!email.isEmpty()) {
00153                 text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", authorName) + " <a href=\"mailto:" + email + "\">" + email + "</a></p>\n";
00154             } else {
00155                 text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", authorName) + "</p>\n";
00156             }
00157         }
00158         authorLabel->setText(text);
00159         elementYPos += authorLabel->height();
00160     }
00161     elementYPos += ItemMargin;
00162     
00163     //setup download label
00164     QLabel * downloadLabel = qobject_cast<QLabel*>(widgets.at(DelegateDownloadCounterLabel));
00165     if (downloadLabel != NULL) {
00166         downloadLabel->setWordWrap(true);
00167         downloadLabel->setAlignment(Qt::AlignHCenter);
00168         downloadLabel->resize(QSize(option.rect.width() - (ItemMargin * 2), option.fontMetrics.height()));
00169         downloadLabel->move((ItemGridWidth-downloadLabel->width())/2,elementYPos);
00170         
00171         unsigned int fans = entry.numberFans();
00172         unsigned int downloads = entry.downloadCount();
00173         
00174         QString text;
00175         QString fanString;
00176         QString downloadString;
00177         if (fans > 0) {
00178             fanString = i18ncp("fan as in supporter", "1 fan", "%1 fans", fans);
00179         }
00180         if (downloads > 0) {
00181             downloadString = i18np("1 download", "%1 downloads", downloads);
00182         }
00183         if (downloads > 0 || fans > 0) {
00184             text += "<p>" + downloadString;
00185             if (downloads > 0 && fans > 0) {
00186                 text += ", ";
00187             }
00188             text += fanString + QLatin1String("</p>");
00189         }
00190         downloadLabel->setText(text);
00191         elementYPos += downloadLabel->height();
00192     }
00193     elementYPos += ItemMargin;
00194     m_elementYPos = elementYPos;
00195 }
00196 
00197 void ItemsGridViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
00198 {    
00199     if (option.state & QStyle::State_MouseOver) {
00200         QModelIndex focIndex = focusedIndex();
00201         if (m_oldIndex != focIndex || !m_operationBar->isVisible()) {
00202             ItemsGridViewDelegate* delegate = const_cast<ItemsGridViewDelegate*>(this);
00203             
00204             delegate->displayOperationBar(option.rect,index);
00205             delegate->m_oldIndex = focIndex;
00206         }
00207     } else {
00208         QModelIndex focindex = focusedIndex();
00209         if(!focindex.isValid()){
00210             //kDebug() << "INVALID hide selection";
00211             m_operationBar->hide();
00212         }
00213     }
00214     
00215     QStyle *style = QApplication::style();
00216     style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0);
00217     
00218     painter->save();    
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 ItemsModel * realmodel = qobject_cast<const ItemsModel*>(index.model());
00227 
00228     if (realmodel->hasPreviewImages()) {
00229         int height = option.rect.height();
00230         int width = option.rect.width();
00231 
00232         KNS3::EntryInternal entry = index.data(Qt::UserRole).value<KNS3::EntryInternal>();
00233         if (entry.previewUrl(EntryInternal::PreviewSmall1).isEmpty()) {
00234             ;
00235         } else {
00236             QPoint centralPoint(option.rect.left() + width/2,option.rect.top() + ItemMargin + FrameThickness + PreviewHeight/2);
00237             QImage image = entry.previewImage(EntryInternal::PreviewSmall1);
00238             if (!image.isNull()) {
00239                 QPoint previewPoint(centralPoint.x() - image.width()/2, centralPoint.y() - image.height()/2);
00240                 painter->drawImage(previewPoint, image);                
00241                 
00242                 QPixmap frameImageScaled = m_frameImage.scaled(image.width() + FrameThickness*2, image.height() + FrameThickness*2);
00243                 QPoint framePoint(centralPoint.x() - frameImageScaled.width()/2, centralPoint.y() - frameImageScaled.height()/2);
00244                 painter->drawPixmap(framePoint, frameImageScaled);
00245             } else {
00246                 QPoint thumbnailPoint(option.rect.left() + ((width - PreviewWidth - FrameThickness*2) / 2), option.rect.top() + ItemMargin);
00247                 QRect rect(thumbnailPoint, QSize(PreviewWidth + FrameThickness*2, PreviewHeight + FrameThickness*2));
00248                 painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("Loading Preview"));
00249             }
00250         }
00251     }
00252 
00253     painter->restore();
00254 }
00255 
00256 QSize ItemsGridViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
00257 {
00258     Q_UNUSED(option);
00259     Q_UNUSED(index);
00260 
00261     QSize size;
00262 
00263     size.setWidth(ItemGridWidth);
00264     size.setHeight(qMax(option.fontMetrics.height() * 13, ItemGridHeight)); // up to 6 lines of text, and two margins
00265     return size;
00266 }
00267 
00268 void ItemsGridViewDelegate::createOperationBar()
00269 {
00270     m_operationBar = new QWidget(this->itemView()->viewport());
00271     
00272     m_detailsButton = new QToolButton();
00273     m_detailsButton->setToolButtonStyle(Qt::ToolButtonFollowStyle);
00274     m_detailsButton->setPopupMode(QToolButton::InstantPopup);
00275     m_detailsButton->setToolTip(i18n("Details"));
00276     m_detailsButton->setIcon(KIcon("documentinfo"));
00277     setBlockedEventTypes(m_detailsButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
00278                          << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
00279     connect(m_detailsButton, SIGNAL(clicked()), this, SLOT(slotDetailsClicked()));
00280 
00281     m_installButton = new QToolButton();
00282     m_installButton->setToolButtonStyle(Qt::ToolButtonFollowStyle);
00283     m_installButton->setPopupMode(QToolButton::InstantPopup);
00284     
00285     setBlockedEventTypes(m_installButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
00286                          << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
00287     connect(m_installButton, SIGNAL(clicked()), this, SLOT(slotInstallClicked()));
00288     connect(m_installButton, SIGNAL(triggered(QAction *)), this, SLOT(slotInstallActionTriggered(QAction *)));
00289 
00290     
00291     if (m_installButton->menu()) {
00292         QMenu* buttonMenu = m_installButton->menu();
00293         buttonMenu->clear();
00294         m_installButton->setMenu(0);
00295         buttonMenu->deleteLater();
00296     }
00297     
00298     QHBoxLayout* layout = new QHBoxLayout(m_operationBar);
00299     
00300     layout->setSpacing(1);
00301     layout->addWidget(m_installButton);
00302     layout->addWidget(m_detailsButton);
00303     
00304     m_operationBar->adjustSize();
00305     m_operationBar->hide();
00306 }
00307 
00308 void ItemsGridViewDelegate::displayOperationBar(const QRect &rect,const QModelIndex & index)
00309 {
00310     KNS3::EntryInternal entry = index.data(Qt::UserRole).value<KNS3::EntryInternal>();
00311     if (m_installButton != 0) {
00312         if (m_installButton->menu() != 0) {
00313             QMenu* buttonMenu = m_installButton->menu();
00314             buttonMenu->clear();
00315             m_installButton->setMenu(0);
00316             buttonMenu->deleteLater();
00317         }
00318         
00319         bool installable = false;
00320         bool enabled = true;
00321         QString text;
00322         KIcon icon;
00323 
00324         switch (entry.status()) {
00325         case Entry::Installed:
00326             text = i18n("Uninstall");
00327             icon = m_iconDelete;
00328             break;
00329         case Entry::Updateable:
00330             text = i18n("Update");
00331             icon = m_iconUpdate;
00332             installable = true;
00333             break;
00334         case Entry::Installing:
00335             text = i18n("Installing");
00336             enabled = false;
00337             icon = m_iconUpdate;
00338             break;
00339         case Entry::Updating:
00340             text = i18n("Updating");
00341             enabled = false;
00342             icon = m_iconUpdate;
00343             break;
00344         case Entry::Downloadable:
00345             text = i18n("Install");
00346             icon = m_iconInstall;
00347             installable = true;
00348             break;
00349         case Entry::Deleted:
00350             text = i18n("Install Again");
00351             icon = m_iconInstall;
00352             installable = true;
00353             break;
00354         default:
00355             text = i18n("Install");
00356         }
00357         m_installButton->setToolTip(text);
00358         m_installButton->setIcon(icon);
00359         m_installButton->setEnabled(enabled);
00360         if (installable && entry.downloadLinkCount() > 1) {
00361             KMenu * installMenu = new KMenu(m_installButton);
00362             foreach (EntryInternal::DownloadLinkInformation info, entry.downloadLinkInformationList()) {
00363                 QString text = info.name;
00364                 if (!info.distributionType.trimmed().isEmpty()) {
00365                     text + " (" + info.distributionType.trimmed() + ")";
00366                 }
00367                 QAction* installAction = installMenu->addAction(m_iconInstall, text);
00368                 installAction->setData(QPoint(index.row(), info.id));
00369             }
00370             m_installButton->setMenu(installMenu);
00371         }
00372         
00373         m_operationBar->move(rect.left()+(ItemGridWidth-m_operationBar->width())/2,rect.top() + m_elementYPos);
00374         m_operationBar->show();
00375     }
00376 }
00377 }
00378 
00379 #include "itemsgridviewdelegate.moc"

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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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