00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "downloaddialog.h"
00022 #include "downloaddialog.moc"
00023
00024 #include <klocale.h>
00025 #include <ktabctl.h>
00026 #include <klistview.h>
00027 #include <kdebug.h>
00028 #include <kio/job.h>
00029 #include <kio/netaccess.h>
00030 #include <kmessagebox.h>
00031 #include <kurl.h>
00032 #include <kconfig.h>
00033 #include <kapplication.h>
00034 #include <kiconloader.h>
00035
00036 #include <knewstuff/entry.h>
00037 #include <knewstuff/knewstuffgeneric.h>
00038 #include <knewstuff/engine.h>
00039
00040 #include <qlayout.h>
00041 #include <qpushbutton.h>
00042 #include <qdom.h>
00043 #include <qlabel.h>
00044 #include <qtextbrowser.h>
00045 #include <qtimer.h>
00046
00047 using namespace KNS;
00048
00049 DownloadDialog::DownloadDialog(Engine *engine, QWidget *)
00050 : KDialogBase(KDialogBase::IconList, i18n("Get Hot New Stuff!"),
00051 KDialogBase::Close, KDialogBase::Close)
00052 {
00053 init(engine);
00054 }
00055
00056 DownloadDialog::DownloadDialog(QWidget *)
00057 : KDialogBase(KDialogBase::IconList, i18n("Get Hot New Stuff!"),
00058 KDialogBase::Close, KDialogBase::Close)
00059 {
00060 init(0);
00061 }
00062
00063 void DownloadDialog::init(Engine *engine)
00064 {
00065 resize(700, 400);
00066
00067 m_engine = engine;
00068
00069 connect(this, SIGNAL(aboutToShowPage(QWidget*)), SLOT(slotPage(QWidget*)));
00070
00071 if(!engine)
00072 {
00073 m_loader = new ProviderLoader(this);
00074 connect(m_loader, SIGNAL(providersLoaded(Provider::List*)), SLOT(slotProviders(Provider::List*)));
00075 }
00076 }
00077
00078 DownloadDialog::~DownloadDialog()
00079 {
00080 }
00081
00082 void DownloadDialog::load()
00083 {
00084 m_loader->load(m_filter);
00085 }
00086
00087 void DownloadDialog::clear()
00088 {
00089 QMap<QWidget*, QValueList<KListView*>* >::Iterator it;
00090 for(it = m_map.begin(); it != m_map.end(); it++)
00091 {
00092 QValueList<KListView*> *v = it.data();
00093 kdDebug() << "clear listviews in " << v << endl;
00094 if(v)
00095 {
00096 (*(v->at(0)))->clear();
00097 (*(v->at(1)))->clear();
00098 (*(v->at(2)))->clear();
00099
00100
00101 }
00102
00103 delete it.key();
00104 }
00105 m_map.clear();
00106 }
00107
00108 void DownloadDialog::slotProviders(Provider::List *list)
00109 {
00110 Provider *p;
00111
00112
00113 for(p = list->first(); p; p = list->next())
00114 {
00115 kdDebug() << "++ provider ++ " << p->name() << endl;
00116
00117 if(!m_filter.isEmpty())
00118 loadProvider(p);
00119 else
00120 addProvider(p);
00121
00122
00123 }
00124 }
00125
00126 void DownloadDialog::addProvider(Provider *p)
00127 {
00128 QFrame *frame;
00129 KTabCtl *ctl;
00130 QWidget *w_d, *w_r, *w_l;
00131 QWidget *w2;
00132 KListView *lvtmp_r, *lvtmp_d, *lvtmp_l;
00133 QTextBrowser *rt;
00134 QString tmp;
00135
00136 if(m_map.count() == 0)
00137 {
00138 frame = addPage(i18n("Welcome"), i18n("Welcome"), QPixmap(""));
00139 delete frame;
00140 }
00141
00142 kdDebug() << "addProvider()/begin" << endl;
00143
00144 KIO::NetAccess::download(p->icon(), tmp, this);
00145 frame = addPage(p->name(), p->name(), QPixmap(tmp));
00146 m_frame = frame;
00147
00148 w2 = new QWidget(frame);
00149 w_d = new QWidget(frame);
00150 w_r = new QWidget(frame);
00151 w_l = new QWidget(frame);
00152
00153 ctl = new KTabCtl(frame);
00154 ctl->addTab(w_r, i18n("Highest Rated"));
00155 ctl->addTab(w_d, i18n("Most Downloads"));
00156 ctl->addTab(w_l, i18n("Latest"));
00157
00158 m_curtab = 0;
00159 connect(ctl, SIGNAL(tabSelected(int)), SLOT(slotTab(int)));
00160
00161 QHBoxLayout *box = new QHBoxLayout(frame);
00162 box->add(ctl);
00163
00164 lvtmp_r = new KListView(w_r);
00165 lvtmp_r->addColumn(i18n("Name"));
00166 lvtmp_r->addColumn(i18n("Version"));
00167 lvtmp_r->addColumn(i18n("Rating"));
00168 lvtmp_r->setSorting(2, false);
00169
00170 lvtmp_d = new KListView(w_d);
00171 lvtmp_d->addColumn(i18n("Name"));
00172 lvtmp_d->addColumn(i18n("Version"));
00173 lvtmp_d->addColumn(i18n("Downloads"));
00174 lvtmp_d->setSorting(2, false);
00175
00176 lvtmp_l = new KListView(w_l);
00177 lvtmp_l->addColumn(i18n("Name"));
00178 lvtmp_l->addColumn(i18n("Version"));
00179 lvtmp_l->addColumn(i18n("Release Date"));
00180 lvtmp_l->setSorting(2, false);
00181
00182 connect(lvtmp_r, SIGNAL(selectionChanged()), SLOT(slotSelected()));
00183 connect(lvtmp_d, SIGNAL(selectionChanged()), SLOT(slotSelected()));
00184 connect(lvtmp_l, SIGNAL(selectionChanged()), SLOT(slotSelected()));
00185
00186 rt = new QTextBrowser(frame);
00187 rt->setMinimumWidth(150);
00188
00189 QPushButton *in = new QPushButton(i18n("Install"), frame);
00190 QPushButton *de = new QPushButton(i18n("Details"), frame);
00191
00192 box->addSpacing(spacingHint());
00193 QVBoxLayout *vbox = new QVBoxLayout(box);
00194 vbox->add(rt);
00195 vbox->addSpacing(spacingHint());
00196 vbox->add(de);
00197 vbox->add(in);
00198
00199 connect(in, SIGNAL(clicked()), SLOT(slotInstall()));
00200 connect(de, SIGNAL(clicked()), SLOT(slotDetails()));
00201
00202 QVBoxLayout *box2 = new QVBoxLayout(w_r);
00203 box2->add(lvtmp_r);
00204 QVBoxLayout *box3 = new QVBoxLayout(w_d);
00205 box3->add(lvtmp_d);
00206 QVBoxLayout *box4 = new QVBoxLayout(w_l);
00207 box4->add(lvtmp_l);
00208
00209 QValueList<KListView*> *v = new QValueList<KListView*>;
00210 *v << lvtmp_r << lvtmp_d << lvtmp_l;
00211 m_map[frame] = v;
00212 m_rts[frame] = rt;
00213 m_providers[frame] = p;
00214
00215 kdDebug() << "addProvider()/end; lvtmp_r = " << lvtmp_r << endl;
00216
00217 if(m_engine) slotPage(frame);
00218
00219 QTimer::singleShot(100, this, SLOT(slotFinish()));
00220 }
00221
00222 void DownloadDialog::slotResult(KIO::Job *job)
00223 {
00224 QDomDocument dom;
00225 QDomElement knewstuff;
00226
00227 kdDebug() << "got data: " << m_data[job] << endl;
00228
00229 kapp->config()->setGroup("KNewStuffStatus");
00230
00231 dom.setContent(m_data[job]);
00232 knewstuff = dom.documentElement();
00233
00234 for(QDomNode pn = knewstuff.firstChild(); !pn.isNull(); pn = pn.nextSibling())
00235 {
00236 QDomElement stuff = pn.toElement();
00237
00238 kdDebug() << "element: " << stuff.tagName() << endl;
00239
00240 if(stuff.tagName() == "stuff")
00241 {
00242 Entry *entry = new Entry(stuff);
00243 kdDebug() << "TYPE::" << entry->type() << " FILTER::" << m_filter << endl;
00244 if(!entry->type().isEmpty())
00245 {
00246 if((!m_filter.isEmpty()) && (entry->type() != m_filter)) continue;
00247 }
00248
00249 if((!m_filter.isEmpty()) && (m_jobs[job]))
00250 {
00251 Provider *p = m_jobs[job];
00252 addProvider(p);
00253 slotPage(m_frame);
00254 m_jobs[job] = 0;
00255 }
00256 addEntry(entry);
00257 }
00258 }
00259
00260 m_data[job] = "";
00261 }
00262
00263 void DownloadDialog::addEntry(Entry *entry)
00264 {
00265 QPixmap pix;
00266 QDate date;
00267 int installed;
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 kapp->config()->setGroup("KNewStuffStatus");
00281 date = QDate::fromString(kapp->config()->readEntry(entry->name()));
00282 if(!date.isValid()) installed = 0;
00283 else if(date < entry->releaseDate()) installed = -1;
00284 else installed = 1;
00285
00286 if(installed > 0) pix = KGlobal::iconLoader()->loadIcon("ok", KIcon::Small);
00287 else if(installed < 0) pix = KGlobal::iconLoader()->loadIcon("history", KIcon::Small);
00288 else pix = QPixmap();
00289
00290 KListViewItem *tmp_r = new KListViewItem(lv_r,
00291 entry->name(), entry->version(), QString("%1").arg(entry->rating()));
00292 KListViewItem *tmp_d = new KListViewItem(lv_d,
00293 entry->name(), entry->version(), QString("%1").arg(entry->downloads()));
00294 KListViewItem *tmp_l = new KListViewItem(lv_l,
00295 entry->name(), entry->version(), entry->releaseDate().toString());
00296
00297 tmp_r->setPixmap(0, pix);
00298 tmp_d->setPixmap(0, pix);
00299 tmp_l->setPixmap(0, pix);
00300
00301 m_entries.append(entry);
00302
00303 kdDebug() << "added entry " << entry->name() << endl;
00304 }
00305
00306 void DownloadDialog::slotData(KIO::Job *job, const QByteArray &a)
00307 {
00308 QCString tmp(a, a.size() + 1);
00309 m_data[job].append(QString::fromUtf8(tmp));
00310 }
00311
00312 void DownloadDialog::slotDetails()
00313 {
00314 Entry *e = getEntry();
00315 if(!e) return;
00316
00317 QString info = i18n
00318 (
00319 "Name: %1\n"
00320 "Author: %2\n"
00321 "License: %3\n"
00322 "Version: %4\n"
00323 "Release: %5\n"
00324 "Rating: %6\n"
00325 "Downloads: %7\n"
00326 "Release date: %8\n"
00327 "Summary: %9\n"
00328 ).arg(e->name()
00329 ).arg(e->author()
00330 ).arg(e->license()
00331 ).arg(e->version()
00332 ).arg(e->release()
00333 ).arg(e->rating()
00334 ).arg(e->downloads()
00335 ).arg(e->releaseDate().toString()
00336 ).arg(e->summary()
00337 );
00338
00339 info.append(i18n
00340 (
00341 "Preview: %1\n"
00342 "Payload: %2\n"
00343 ).arg(e->preview().url()
00344 ).arg(e->payload().url()
00345 ));
00346
00347 KMessageBox::information(this, info, i18n("Details"));
00348 }
00349
00350 void DownloadDialog::slotInstall()
00351 {
00352 Entry *e = getEntry();
00353 if(!e) return;
00354
00355 kdDebug() << "download entry now" << endl;
00356
00357 if(m_engine)
00358 {
00359 install(e);
00360 m_engine->download(e);
00361 }
00362 else
00363 {
00364 m_s = new KNewStuffGeneric(e->type(), this);
00365
00366 m_entry = e;
00367
00368 KURL source = e->payload();
00369 KURL dest = KURL(m_s->downloadDestination(e));
00370
00371 KIO::FileCopyJob *job = KIO::file_copy(source, dest, -1, true);
00372 connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotInstalled(KIO::Job*)));
00373 }
00374 }
00375
00376 void DownloadDialog::install(Entry *e)
00377 {
00378 kapp->config()->setGroup("KNewStuffStatus");
00379 kapp->config()->writeEntry(m_entryname, e->releaseDate().toString());
00380 kapp->config()->sync();
00381
00382 QPixmap pix = KGlobal::iconLoader()->loadIcon("ok", KIcon::Small);
00383 m_entryitem = lv_r->findItem(m_entryname, 0);
00384 if(m_entryitem) m_entryitem->setPixmap(0, pix);
00385 m_entryitem = lv_d->findItem(m_entryname, 0);
00386 if(m_entryitem) m_entryitem->setPixmap(0, pix);
00387 m_entryitem = lv_l->findItem(m_entryname, 0);
00388 if(m_entryitem) m_entryitem->setPixmap(0, pix);
00389 }
00390
00391 void DownloadDialog::slotInstalled(KIO::Job *job)
00392 {
00393 bool ret = (job->error() == 0);
00394 KIO::FileCopyJob *cjob;
00395
00396 if(ret)
00397 {
00398 cjob = static_cast<KIO::FileCopyJob*>(job);
00399 if(cjob)
00400 {
00401 ret = m_s->install(cjob->destURL().path());
00402 }
00403 else ret = false;
00404 }
00405
00406 if(ret)
00407 {
00408 install(m_entry);
00409
00410 KMessageBox::information(this, i18n("Installation successful."), i18n("Installation"));
00411 }
00412 else KMessageBox::error(this, i18n("Installation failed."), i18n("Installation"));
00413
00414 delete m_s;
00415 }
00416
00417 void DownloadDialog::slotTab(int tab)
00418 {
00419 kdDebug() << "switch tab to: " << tab << endl;
00420 m_curtab = tab;
00421 }
00422
00423 void DownloadDialog::slotSelected()
00424 {
00425 QString tmp;
00426 Entry *e = getEntry();
00427 if(e)
00428 {
00429 if(!e->preview().isValid())
00430 {
00431 m_rt->setText(QString("<b>%1</b><br>%2<br>%3<br><br><i>%4</i><br>(%5)").arg(
00432 e->name()).arg(e->author()).arg(e->releaseDate().toString()).arg(e->summary()).arg(e->license()));
00433 }
00434 else
00435 {
00436 KIO::NetAccess::download(e->preview(), tmp, this);
00437 m_rt->setText(QString("<b>%1</b><br>%2<br>%3<br><br><img src='%4'><br><i>%5</i><br>(%6)").arg(
00438 e->name()).arg(e->author()).arg(e->releaseDate().toString()).arg(tmp).arg(e->summary()).arg(e->license()));
00439 }
00440 }
00441 }
00442
00443 Entry *DownloadDialog::getEntry()
00444 {
00445 if(m_curtab == 0) m_entryitem = lv_r->currentItem();
00446 else if(m_curtab == 1) m_entryitem = lv_d->currentItem();
00447 else if(m_curtab == 2) m_entryitem = lv_l->currentItem();
00448 else return 0;
00449
00450 m_entryname = m_entryitem->text(0);
00451
00452 for(Entry *e = m_entries.first(); e; e = m_entries.next())
00453 {
00454 if(e->name() == m_entryname) return e;
00455 }
00456
00457 return 0;
00458 }
00459
00460 void DownloadDialog::slotPage(QWidget *w)
00461 {
00462 Provider *p;
00463
00464 kdDebug() << "changed widget!!!" << endl;
00465
00466 if(m_map.find(w) == m_map.end()) return;
00467
00468 lv_r = *(m_map[w]->at(0));
00469 lv_d = *(m_map[w]->at(1));
00470 lv_l = *(m_map[w]->at(2));
00471 p = m_providers[w];
00472 m_rt = m_rts[w];
00473
00474 kdDebug() << "valid change!!!; lv_r = " << lv_r << endl;
00475
00476 if(m_engine) return;
00477
00478 if(!m_filter.isEmpty()) return;
00479
00480 lv_r->clear();
00481 lv_d->clear();
00482 lv_l->clear();
00483
00484 kdDebug() << "-- fetch -- " << p->downloadUrl() << endl;
00485
00486 loadProvider(p);
00487 }
00488
00489 void DownloadDialog::loadProvider(Provider *p)
00490 {
00491 KIO::TransferJob *job = KIO::get(p->downloadUrl());
00492
00493 m_jobs[job] = p;
00494
00495 connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)));
00496 connect(job, SIGNAL(data(KIO::Job*, const QByteArray&)),
00497 SLOT(slotData(KIO::Job*, const QByteArray&)));
00498 }
00499
00500 void DownloadDialog::setType(QString type)
00501 {
00502 m_filter = type;
00503 }
00504
00505 void DownloadDialog::slotOk()
00506 {
00507 }
00508
00509 void DownloadDialog::slotApply()
00510 {
00511 }
00512
00513 void DownloadDialog::open(QString type)
00514 {
00515 DownloadDialog d;
00516 d.setType(type);
00517 d.load();
00518 d.exec();
00519 }
00520
00521 void DownloadDialog::slotFinish()
00522 {
00523 showPage(1);
00524
00525 }
00526