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
00023 #include "itemsview.h"
00024
00025
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
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
00086 return e1->releaseDate() > e2->releaseDate();
00087 }
00088
00089 static bool DownloadsSorter(const Entry* e1, const Entry* e2)
00090 {
00091
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
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
00142
00143
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
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
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
00200
00201 previewLayout->addWidget(f);
00202 }
00203
00204
00205 part->setEntry(entry);
00206 m_views.insert(entry, part);
00207 ++row;
00208 }
00209 }
00210 }
00211
00212
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
00230 QString idString = QString::number((unsigned long)entry);
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 }
00244
00245 void EntryView::buildContents()
00246 {
00247
00248 QString t;
00249
00250 t += "<html><body>";
00251
00252
00253
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
00264
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
00278 QString titleString = m_entry->name().representation();
00279 if (!m_entry->version().isEmpty()) titleString += " v." + Qt::escape(m_entry->version());
00280
00281
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;'> </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 + " </div>";
00289
00290
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
00301 t +=
00302 statusIcon + Qt::escape(titleString) + "<br />"
00303
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";
00329 QString hoverBackground = "#f8f8f8";
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
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
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
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
00361
00362 KUrl url(link);
00363 QString urlProtocol = url.protocol();
00364 QString urlPath = url.path();
00365
00366 if (urlProtocol == "mailto") {
00367
00368
00369
00370 KToolInvocation::invokeMailer(url);
00371 } else if (urlProtocol == "item") {
00372
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
00381 Entry *entry = (Entry*)itemPointer;
00382 if (entry != m_entry) {
00383 kWarning() << "ItemsView: error retrieving item pointer.";
00384 return;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393 }
00394 }
00395
00396 #include "itemsview.moc"
00397