KNewStuff
itemsview.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "itemsview.h"
00023
00024
00025 #include <QtCore/QFile>
00026 #include <QtGui/QWidget>
00027 #include <QtCore/QTimer>
00028 #include <QtGui/QLayout>
00029 #include <QtGui/QImage>
00030 #include <QtGui/QFont>
00031 #include <QtGui/QComboBox>
00032 #include <QtGui/QPushButton>
00033 #include <QtCore/QMutableVectorIterator>
00034 #include <QtCore/QRect>
00035 #include <QtGui/QPainter>
00036 #include <QtGui/QScrollArea>
00037 #include <QtGui/QApplication>
00038 #include <QtGui/QTextDocument>
00039 #include <kaboutdata.h>
00040 #include <kapplication.h>
00041 #include <kcomponentdata.h>
00042 #include <kglobalsettings.h>
00043 #include <klocale.h>
00044 #include <klineedit.h>
00045 #include <kconfig.h>
00046 #include <kstandarddirs.h>
00047 #include <kmessagebox.h>
00048 #include <kdebug.h>
00049 #include <kiconloader.h>
00050 #include <kio/job.h>
00051 #include <kio/netaccess.h>
00052 #include <ktitlewidget.h>
00053 #include <ktoolinvocation.h>
00054
00055 #include "knewstuff2/core/provider.h"
00056 #include "knewstuff2/core/providerhandler.h"
00057 #include "knewstuff2/core/entry.h"
00058 #include "knewstuff2/core/entryhandler.h"
00059 #include "knewstuff2/core/category.h"
00060
00061 #include "knewstuff2/dxs/dxs.h"
00062
00063 #include "knewstuff2/ui/qprogressindicator.h"
00064
00065
00066 #include "ui_DownloadDialog.h"
00067 #include "kdxsbutton.h"
00068 #include "qasyncimage_p.h"
00069
00070 using namespace KNS;
00071
00072 static bool NameSorter(const Entry* e1, const Entry* e2)
00073 {
00074 return e1->name().representation() < e2->name().representation();
00075 }
00076
00077 static bool RatingSorter(const Entry* e1, const Entry* e2)
00078 {
00079 return e1->rating() < e2->rating();
00080 }
00081
00082 static bool RecentSorter(const Entry* e1, const Entry* e2)
00083 {
00084
00085 return e1->releaseDate() > e2->releaseDate();
00086 }
00087
00088 static bool DownloadsSorter(const Entry* e1, const Entry* e2)
00089 {
00090
00091 return e1->downloads() > e2->downloads();
00092 }
00093
00094 ItemsView::ItemsView(QWidget* _parent)
00095 : QListView(_parent),
00096 m_currentProvider(0), m_currentFeed(0), m_root(0), m_sorting(0), m_engine(0)
00097 {
00098 m_root = new QWidget(this);
00099 setFrameStyle(QFrame::Plain | QFrame::StyledPanel);
00100 setVerticalScrollMode(ScrollPerPixel);
00101
00102 }
00103
00104 ItemsView::~ItemsView()
00105 {
00106 }
00107
00108 void ItemsView::setEngine(DxsEngine *engine)
00109 {
00110 m_engine = engine;
00111 }
00112
00113 void ItemsView::setProvider(const Provider * provider, const Feed * feed)
00114 {
00115 m_currentProvider = provider;
00116 m_currentFeed = feed;
00117 buildContents();
00118 }
00119
00120 void ItemsView::setSorting(int sortType)
00121 {
00122 m_sorting = sortType;
00123 buildContents();
00124 }
00125
00126 void ItemsView::setFeed(const Feed * feed)
00127 {
00128 m_currentFeed = feed;
00129 buildContents();
00130 }
00131
00132 void ItemsView::setSearchText(const QString & text)
00133 {
00134 m_searchText = text;
00135 buildContents();
00136 }
00137
00138 void ItemsView::updateItem(Entry *entry)
00139 {
00140
00141
00142
00143
00144 }
00145
00146 void ItemsView::buildContents()
00147 {
00148 m_views.clear();
00149
00150 m_root->setBackgroundRole(QPalette::Base);
00151 QVBoxLayout* _layout = new QVBoxLayout(m_root);
00152
00153 if (m_currentFeed != NULL) {
00154 Entry::List entries = m_currentFeed->entries();
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 Entry::List::iterator it = entries.begin(), iEnd = entries.end();
00172 for (unsigned row = 0; it != iEnd; ++it) {
00173 Entry* entry = (*it);
00174
00175 if (entry->name().representation().toLower().contains(m_searchText.toLower())) {
00176 QHBoxLayout * itemLayout = new QHBoxLayout;
00177 _layout->addLayout(itemLayout);
00178
00179 EntryView *part = new EntryView(m_root);
00180 part->setBackgroundRole(row & 1 ? QPalette::AlternateBase : QPalette::Base);
00181 itemLayout->addWidget(part);
00182
00183 QVBoxLayout * previewLayout = new QVBoxLayout;
00184 itemLayout->insertLayout(0, previewLayout);
00185
00186 KDXSButton *dxsbutton = new KDXSButton(m_root);
00187 dxsbutton->setEntry(entry);
00188 dxsbutton->setProvider(m_currentProvider);
00189 dxsbutton->setEngine(m_engine);
00190
00191 QString imageurl = entry->preview().representation();
00192 if (!imageurl.isEmpty()) {
00193 QLabel *f = new QLabel(m_root);
00194 f->setFrameStyle(QFrame::Panel | QFrame::Sunken);
00195 QAsyncImage *pix = new QAsyncImage(imageurl, m_root);
00196 f->setFixedSize(64, 64);
00197
00198
00199 previewLayout->addWidget(f);
00200 }
00201
00202
00203 part->setEntry(entry);
00204 m_views.insert(entry, part);
00205 ++row;
00206 }
00207 }
00208 }
00209
00210
00211 }
00212
00213 EntryView::EntryView(QWidget * _parent)
00214 : QLabel(_parent)
00215 {
00216 connect(this, SIGNAL(linkActivated(const QString&)), SLOT(urlSelected(const QString&)));
00217 }
00218
00219 void EntryView::setEntry(Entry *entry)
00220 {
00221 m_entry = entry;
00222 buildContents();
00223 }
00224
00225 void EntryView::updateEntry(Entry *entry)
00226 {
00227
00228 QString idString = QString::number((unsigned long)entry);
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 }
00242
00243 void EntryView::buildContents()
00244 {
00245
00246 QString t;
00247
00248 t += "<html><body>";
00249
00250
00251
00252 Entry::Status status = m_entry->status();
00253 QString statusIcon;
00254 KIconLoader *loader = KIconLoader::global();
00255
00256 switch (status) {
00257 case Entry::Invalid:
00258 statusIcon = "<img src='" + loader->iconPath("dialog-error", -KIconLoader::SizeSmall) + "' />";
00259 break;
00260 case Entry::Downloadable:
00261
00262
00263 break;
00264 case Entry::Installed:
00265 statusIcon = "<img src='" + loader->iconPath("dialog-ok", -KIconLoader::SizeSmall) + "' />";
00266 break;
00267 case Entry::Updateable:
00268 statusIcon = "<img src='" + loader->iconPath("software-update-available", -KIconLoader::SizeSmall) + "' />";
00269 break;
00270 case Entry::Deleted:
00271 statusIcon = "<img src='" + loader->iconPath("user-trash", -KIconLoader::SizeSmall) + "' />";
00272 break;
00273 }
00274
00275
00276 QString titleString = m_entry->name().representation();
00277 if (!m_entry->version().isEmpty()) titleString += " v." + Qt::escape(m_entry->version());
00278
00279
00280 QString starIconPath = KStandardDirs::locate("data", "knewstuff/pics/ghns_star.png");
00281 QString starBgIconPath = KStandardDirs::locate("data", "knewstuff/pics/ghns_star_gray.png");
00282
00283 int starPixels = 11 + 11 * (m_entry->rating() / 10);
00284 QString starsString = "<div style='width: " + QString::number(starPixels) + "px; background-image: url(" + starIconPath + "); background-repeat: repeat-x;'> </div>";
00285 int grayPixels = 22 + 22 * (m_entry->rating() / 20);
00286 starsString = "<div style='width: " + QString::number(grayPixels) + "px;background-image: url(" + starBgIconPath + "); background-repeat: repeat-x;'>" + starsString + " </div>";
00287
00288
00289 KNS::Author author = m_entry->author();
00290 QString authorString = author.name();
00291
00292 QString emailString = author.email();
00293 if (!emailString.isEmpty()) {
00294 authorString = "<a href='mailto:" + Qt::escape(emailString) + "'>"
00295 + Qt::escape(authorString) + "</a>";
00296 }
00297
00298
00299 t +=
00300 statusIcon + Qt::escape(titleString) + "<br />"
00301
00302 + Qt::escape(m_entry->summary().representation())
00303 + "<br />";
00304
00305 if (m_entry->rating() > 0) {
00306 t += i18n("Rating: ") + QString::number(m_entry->rating())
00307 + "<br />";
00308 }
00309
00310 if (m_entry->downloads() > 0) {
00311 t += i18n("Downloads: ") + QString::number(m_entry->downloads())
00312 + "<br />";
00313 }
00314
00315 if (!authorString.isEmpty()) {
00316 t += "<em>" + authorString + "</em>, ";
00317 }
00318 t += KGlobal::locale()->formatDate(m_entry->releaseDate(), KLocale::ShortDate)
00319 + "<br />" + "</body></html>";
00320
00321 setText(t);
00322 }
00323
00324 void EntryView::setTheAaronnesqueStyle()
00325 {
00326 QString hoverColor = "#000000";
00327 QString hoverBackground = "#f8f8f8";
00328 QString starIconPath = KStandardDirs::locate("data", "knewstuff/pics/ghns_star.png");
00329 QString starBgIconPath = KStandardDirs::locate("data", "knewstuff/pics/ghns_star_gray.png");
00330
00331
00332 QString s;
00333 s += "body { background-color: white; color: black; padding: 0; margin: 0; }";
00334 s += "table, td, th { padding: 0; margin: 0; text-align: left; }";
00335 s += "input { color: #000080; font-size:120%; }";
00336
00337
00338 s += ".itemBox { background-color: white; color: black; width: 100%; border-bottom: 1px solid gray; margin: 0px 0px; }";
00339 s += ".itemBox:hover { background-color: " + hoverBackground + "; color: " + hoverColor + "; }";
00340
00341
00342 s += ".leftColumn { width: 100px; height:100%; text-align: center; }";
00343 s += ".leftImage {}";
00344 s += ".leftButton {}";
00345 s += ".leftProgressContainer { width: 82px; height: 10px; background-color: transparent; }";
00346 s += ".leftProgressBar { left: 1px; width: 0px; top: 1px; height: 8px; background-color: red; }";
00347 s += ".contentsColumn { vertical-align: top; }";
00348 s += ".contentsHeader { width: 100%; font-size: 120%; font-weight: bold; border-bottom: 1px solid #c8c8c8; }";
00349 s += ".contentsBody {}";
00350 s += ".contentsFooter {}";
00351 s += ".star { width: 0px; height: 24px; background-image: url(" + starIconPath + "); background-repeat: repeat-x; }";
00352 s += ".starbg { width: 110px; height: 24px; background-image: url(" + starBgIconPath + "); background-repeat: repeat-x; }";
00353 setStyleSheet(s);
00354 }
00355
00356 void EntryView::urlSelected(const QString &link)
00357 {
00358
00359
00360 KUrl url(link);
00361 QString urlProtocol = url.protocol();
00362 QString urlPath = url.path();
00363
00364 if (urlProtocol == "mailto") {
00365
00366
00367
00368 KToolInvocation::invokeMailer(url);
00369 } else if (urlProtocol == "item") {
00370
00371 bool ok;
00372 unsigned long itemPointer = urlPath.toULong(&ok);
00373 if (!ok) {
00374 kWarning() << "ItemsView: error converting item pointer.";
00375 return;
00376 }
00377
00378
00379 Entry *entry = (Entry*)itemPointer;
00380 if (entry != m_entry) {
00381 kWarning() << "ItemsView: error retrieving item pointer.";
00382 return;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391 }
00392 }
00393
00394 #include "itemsview.moc"
00395