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

KNewStuff

itemsview.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Enrico Ros <eros.kde@email.it>                  *
00003  *   Copyright (C) 2005 - 2007 Josef Spillner <spillner@kde.org>           *
00004  *             (C) 2007 Dirk Mueller <mueller@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 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, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // own include
00023 #include "itemsview.h"
00024 
00025 // qt/kde includes
00026 #include <QtCore/QFile>
00027 #include <QtGui/QWidget>
00028 #include <QtCore/QTimer>
00029 #include <QtGui/QLayout>
00030 #include <QtGui/QPixmap>
00031 #include <QtGui/QFont>
00032 #include <QtGui/QComboBox>
00033 #include <QtGui/QPushButton>
00034 #include <QtCore/QMutableVectorIterator>
00035 #include <QtCore/QRect>
00036 #include <QtGui/QPainter>
00037 #include <QtGui/QScrollArea>
00038 #include <QtGui/QApplication>
00039 #include <QtGui/QTextDocument>
00040 #include <kaboutdata.h>
00041 #include <kapplication.h>
00042 #include <kcomponentdata.h>
00043 #include <kglobalsettings.h>
00044 #include <klocale.h>
00045 #include <klineedit.h>
00046 #include <kconfig.h>
00047 #include <kstandarddirs.h>
00048 #include <kmessagebox.h>
00049 #include <kdebug.h>
00050 #include <kiconloader.h>
00051 #include <kio/job.h>
00052 #include <kio/netaccess.h>
00053 #include <ktitlewidget.h>
00054 #include <ktoolinvocation.h>
00055 
00056 #include "knewstuff2/core/provider.h"
00057 #include "knewstuff2/core/providerhandler.h"
00058 #include "knewstuff2/core/entry.h"
00059 #include "knewstuff2/core/entryhandler.h"
00060 #include "knewstuff2/core/category.h"
00061 
00062 #include "knewstuff2/dxs/dxs.h"
00063 
00064 #include "knewstuff2/ui/qprogressindicator.h"
00065 
00066 // local includes
00067 #include "ui_DownloadDialog.h"
00068 #include "kdxsbutton.h"
00069 #include "qasyncpixmap.h"
00070 
00071 using namespace KNS;
00072 
00073 static bool NameSorter(const Entry* e1, const Entry* e2)
00074 {
00075     return e1->name().representation() < e2->name().representation();
00076 }
00077 
00078 static bool RatingSorter(const Entry* e1, const Entry* e2)
00079 {
00080     return e1->rating() < e2->rating();
00081 }
00082 
00083 static bool RecentSorter(const Entry* e1, const Entry* e2)
00084 {
00085     // return > instead of < to sort in reverse order
00086     return e1->releaseDate() > e2->releaseDate();
00087 }
00088 
00089 static bool DownloadsSorter(const Entry* e1, const Entry* e2)
00090 {
00091     // return > instead of < to sort most downloads at the top
00092     return e1->downloads() > e2->downloads();
00093 }
00094 
00095 ItemsView::ItemsView(QWidget* _parent)
00096         : QListView(_parent),
00097         m_currentProvider(0), m_currentFeed(0), m_root(0), m_sorting(0), m_engine(0)
00098 {
00099     m_root = new QWidget(this);
00100     setFrameStyle(QFrame::Plain | QFrame::StyledPanel);
00101     setVerticalScrollMode(ScrollPerPixel);
00102     //setWidgetResizable(true);
00103 }
00104 
00105 ItemsView::~ItemsView()
00106 {
00107 }
00108 
00109 void ItemsView::setEngine(DxsEngine *engine)
00110 {
00111     m_engine = engine;
00112 }
00113 
00114 void ItemsView::setProvider(const Provider * provider, const Feed * feed)
00115 {
00116     m_currentProvider = provider;
00117     m_currentFeed = feed;
00118     buildContents();
00119 }
00120 
00121 void ItemsView::setSorting(int sortType)
00122 {
00123     m_sorting = sortType;
00124     buildContents();
00125 }
00126 
00127 void ItemsView::setFeed(const Feed * feed)
00128 {
00129     m_currentFeed = feed;
00130     buildContents();
00131 }
00132 
00133 void ItemsView::setSearchText(const QString & text)
00134 {
00135     m_searchText = text;
00136     buildContents();
00137 }
00138 
00139 void ItemsView::updateItem(Entry *entry)
00140 {
00141     // FIXME: change this to call updateEntry once it is complete
00142 //   if (m_views.contains(entry)) {
00143 //        m_views[entry]->setEntry(entry);
00144     //  }
00145 }
00146 
00147 void ItemsView::buildContents()
00148 {
00149     m_views.clear();
00150 
00151     m_root->setBackgroundRole(QPalette::Base);
00152     QVBoxLayout* _layout = new QVBoxLayout(m_root);
00153     _layout->setSpacing(10);
00154 
00155     if (m_currentFeed != NULL) {
00156         Entry::List entries = m_currentFeed->entries();
00157         //switch (m_sorting)
00158         //{
00159         //    case 0:
00160         //        qSort(entries.begin(), entries.end(), NameSorter);
00161         //        break;
00162         //    case 1:
00163         //        qSort(entries.begin(), entries.end(), RatingSorter);
00164         //        break;
00165         //    case 2:
00166         //        qSort(entries.begin(), entries.end(), RecentSorter);
00167         //        break;
00168         //    case 3:
00169         //        qSort(entries.begin(), entries.end(), DownloadsSorter);
00170         //        break;
00171         //}
00172 
00173         Entry::List::iterator it = entries.begin(), iEnd = entries.end();
00174         for (unsigned row = 0; it != iEnd; ++it) {
00175             Entry* entry = (*it);
00176 
00177             if (entry->name().representation().toLower().contains(m_searchText.toLower())) {
00178                 QHBoxLayout * itemLayout = new QHBoxLayout;
00179                 _layout->addLayout(itemLayout);
00180 
00181                 EntryView *part = new EntryView(m_root);
00182                 part->setBackgroundRole(row & 1 ? QPalette::AlternateBase : QPalette::Base);
00183                 itemLayout->addWidget(part);
00184 
00185                 QVBoxLayout * previewLayout = new QVBoxLayout;
00186                 itemLayout->insertLayout(0, previewLayout);
00187 
00188                 KDXSButton *dxsbutton = new KDXSButton(m_root);
00189                 dxsbutton->setEntry(entry);
00190                 dxsbutton->setProvider(m_currentProvider);
00191                 dxsbutton->setEngine(m_engine);
00192 
00193                 QString imageurl = entry->preview().representation();
00194                 if (!imageurl.isEmpty()) {
00195                     QLabel *f = new QLabel(m_root);
00196                     f->setFrameStyle(QFrame::Panel | QFrame::Sunken);
00197                     QAsyncPixmap *pix = new QAsyncPixmap(imageurl, m_root);
00198                     f->setFixedSize(64, 64);
00199                     //connect(pix, SIGNAL(signalLoaded(const QPixmap&)),
00200                     //        f, SLOT(setPixmap(const QPixmap&)));
00201                     previewLayout->addWidget(f);
00202                 }
00203                 //previewLayout->addWidget(dxsbutton);
00204 
00205                 part->setEntry(entry);
00206                 m_views.insert(entry, part);
00207                 ++row;
00208             }
00209         }
00210     }
00211 
00212     //setWidget(m_root);
00213 }
00214 
00215 EntryView::EntryView(QWidget * _parent)
00216         : QLabel(_parent)
00217 {
00218     connect(this, SIGNAL(linkActivated(const QString&)), SLOT(urlSelected(const QString&)));
00219 }
00220 
00221 void EntryView::setEntry(Entry *entry)
00222 {
00223     m_entry = entry;
00224     buildContents();
00225 }
00226 
00227 void EntryView::updateEntry(Entry *entry)
00228 {
00229     // get item id string and iformations
00230     QString idString = QString::number((unsigned long)entry);
00231     //            AvailableItem::State state = item->state();
00232     //            bool showProgress = state != AvailableItem::Normal;
00233     //            int pixelProgress = showProgress ? (int)(item->progress() * 80.0) : 0;
00234 
00235     // perform internal scripting operations over the element
00236     //            executeScript( "document.getElementById('" + idString + "').style.color='red'" );
00237     //            executeScript( "document.getElementById('bar" + idString + "').style.width='" +
00238     //                           QString::number( pixelProgress ) + "px'" );
00239     //            executeScript( "document.getElementById('bc" + idString + "').style.backgroundColor='" +
00240     //                           (showProgress ? "gray" : "transparent") + "'" );
00241     //            executeScript( "document.getElementById('btn" + idString + "').value='" +
00242     //                           (item->installed() ? i18n( "Uninstall" ) : i18n( "Install" )) + "'" );
00243 }
00244 
00245 void EntryView::buildContents()
00246 {
00247     // write the html header and contents manipulation scripts
00248     QString t;
00249 
00250     t += "<html><body>";
00251 
00252     //t += setTheAaronnesqueStyle();
00253     // precalc the status icon
00254     Entry::Status status = m_entry->status();
00255     QString statusIcon;
00256     KIconLoader *loader = KIconLoader::global();
00257 
00258     switch (status) {
00259     case Entry::Invalid:
00260         statusIcon = "<img src='" + loader->iconPath("dialog-error", -KIconLoader::SizeSmall) + "' />";
00261         break;
00262     case Entry::Downloadable:
00263         // find a good icon to represent downloadable data
00264         //statusIcon = "<img src='" + loader->iconPath("network-server", -KIconLoader::SizeSmall) + "' />";
00265         break;
00266     case Entry::Installed:
00267         statusIcon = "<img src='" + loader->iconPath("dialog-ok", -KIconLoader::SizeSmall) + "' />";
00268         break;
00269     case Entry::Updateable:
00270         statusIcon = "<img src='" + loader->iconPath("software-update-available", -KIconLoader::SizeSmall) + "' />";
00271         break;
00272     case Entry::Deleted:
00273         statusIcon = "<img src='" + loader->iconPath("user-trash", -KIconLoader::SizeSmall) + "' />";
00274         break;
00275     }
00276 
00277     // precalc the title string
00278     QString titleString = m_entry->name().representation();
00279     if (!m_entry->version().isEmpty()) titleString += " v." + Qt::escape(m_entry->version());
00280 
00281     // precalc the string for displaying stars (normal+grayed)
00282     QString starIconPath = KStandardDirs::locate("data", "knewstuff/pics/ghns_star.png");
00283     QString starBgIconPath = KStandardDirs::locate("data", "knewstuff/pics/ghns_star_gray.png");
00284 
00285     int starPixels = 11 + 11 * (m_entry->rating() / 10);
00286     QString starsString = "<div style='width: " + QString::number(starPixels) + "px; background-image: url(" + starIconPath + "); background-repeat: repeat-x;'>&nbsp;</div>";
00287     int grayPixels = 22 + 22 * (m_entry->rating() / 20);
00288     starsString = "<div style='width: " + QString::number(grayPixels) + "px;background-image: url(" + starBgIconPath + "); background-repeat: repeat-x;'>" + starsString + "&nbsp;</div>";
00289 
00290     // precalc the string for displaying author (parsing email)
00291     KNS::Author author = m_entry->author();
00292     QString authorString = author.name();
00293 
00294     QString emailString = author.email();
00295     if (!emailString.isEmpty()) {
00296         authorString = "<a href='mailto:" + Qt::escape(emailString) + "'>"
00297                        + Qt::escape(authorString) + "</a>";
00298     }
00299 
00300     // write the HTML code for the current item
00301     t += //QLatin1String("<table class='contentsHeader' cellspacing='2' cellpadding='0'>")
00302         statusIcon + Qt::escape(titleString) + "<br />"
00303         //+   "<span align='right'>" + starsString +  "</span><br />"
00304         +      Qt::escape(m_entry->summary().representation())
00305         +   "<br />";
00306 
00307     if (m_entry->rating() > 0) {
00308         t += i18n("Rating: ") + QString::number(m_entry->rating())
00309              +   "<br />";
00310     }
00311 
00312     if (m_entry->downloads() > 0) {
00313         t += i18n("Downloads: ") + QString::number(m_entry->downloads())
00314              +   "<br />";
00315     }
00316 
00317     if (!authorString.isEmpty()) {
00318         t += "<em>" + authorString + "</em>, ";
00319     }
00320     t += KGlobal::locale()->formatDate(m_entry->releaseDate(), KLocale::ShortDate)
00321          + "<br />" + "</body></html>";
00322 
00323     setText(t);
00324 }
00325 
00326 void EntryView::setTheAaronnesqueStyle()
00327 {
00328     QString hoverColor = "#000000"; //QApplication::palette().active().highlightedText().name();
00329     QString hoverBackground = "#f8f8f8"; //QApplication::palette().active().highlight().name();
00330     QString starIconPath = KStandardDirs::locate("data", "knewstuff/pics/ghns_star.png");
00331     QString starBgIconPath = KStandardDirs::locate("data", "knewstuff/pics/ghns_star_gray.png");
00332 
00333     // default elements style
00334     QString s;
00335     s += "body { background-color: white; color: black; padding: 0; margin: 0; }";
00336     s += "table, td, th { padding: 0; margin: 0; text-align: left; }";
00337     s += "input { color: #000080; font-size:120%; }";
00338 
00339     // the main item container (custom element)
00340     s += ".itemBox { background-color: white; color: black; width: 100%;  border-bottom: 1px solid gray; margin: 0px 0px; }";
00341     s += ".itemBox:hover { background-color: " + hoverBackground + "; color: " + hoverColor + "; }";
00342 
00343     // s of the item elements (4 cells with multiple containers)
00344     s += ".leftColumn { width: 100px; height:100%; text-align: center; }";
00345     s += ".leftImage {}";
00346     s += ".leftButton {}";
00347     s += ".leftProgressContainer { width: 82px; height: 10px; background-color: transparent; }";
00348     s += ".leftProgressBar { left: 1px; width: 0px; top: 1px; height: 8px; background-color: red; }";
00349     s += ".contentsColumn { vertical-align: top; }";
00350     s += ".contentsHeader { width: 100%; font-size: 120%; font-weight: bold; border-bottom: 1px solid #c8c8c8; }";
00351     s += ".contentsBody {}";
00352     s += ".contentsFooter {}";
00353     s += ".star { width: 0px; height: 24px; background-image: url(" + starIconPath + "); background-repeat: repeat-x; }";
00354     s += ".starbg { width: 110px; height: 24px; background-image: url(" + starBgIconPath + "); background-repeat: repeat-x; }";
00355     setStyleSheet(s);
00356 }
00357 
00358 void EntryView::urlSelected(const QString &link)
00359 {
00360     //kDebug() << "Clicked on URL " << link;
00361 
00362     KUrl url(link);
00363     QString urlProtocol = url.protocol();
00364     QString urlPath = url.path();
00365 
00366     if (urlProtocol == "mailto") {
00367         // clicked over a mail address
00368         // FIXME: if clicked with MRB, show context menu with IM etc.
00369         // FIXME: but RMB never reaches this method?!
00370         KToolInvocation::invokeMailer(url);
00371     } else if (urlProtocol == "item") {
00372         // clicked over an item
00373         bool ok;
00374         unsigned long itemPointer = urlPath.toULong(&ok);
00375         if (!ok) {
00376             kWarning() << "ItemsView: error converting item pointer.";
00377             return;
00378         }
00379 
00380         // I love to cast pointers
00381         Entry *entry = (Entry*)itemPointer;
00382         if (entry != m_entry) {
00383             kWarning() << "ItemsView: error retrieving item pointer.";
00384             return;
00385         }
00386 
00387         // XXX ???
00388         // install/uninstall the item
00389         //                if ( item->installed() )
00390         //                    m_newStuffDialog->removeItem( item );   // synchronous
00391         //                else
00392         //                    m_newStuffDialog->installItem( item );  // asynchronous
00393     }
00394 }
00395 
00396 #include "itemsview.moc"
00397 

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