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
struct DownloadDialog::Private
00050 {
00051
QString m_providerlist;
00052
QWidget *m_page;
00053 };
00054
00055
class NumSortListViewItem :
public KListViewItem
00056 {
00057
public:
00058 NumSortListViewItem(
QListView * parent,
QString label1,
QString label2 = QString::null,
QString label3 = QString::null,
QString label4 = QString::null,
QString label5 = QString::null,
QString label6 = QString::null,
QString label7 = QString::null,
QString label8 = QString::null ) :
00059 KListViewItem( parent, label1, label2, label3, label4, label5, label6, label7, label8 )
00060 {
00061 }
00062
00063
QString key(
int col,
bool asc)
const {
00064
if (col == 2)
00065 {
00066
QString s;
00067 s.sprintf(
"%08d", text(col).toInt());
00068
return s;
00069 }
00070
return KListViewItem::key( col, asc );
00071 }
00072 };
00073
00074
class DateSortListViewItem :
public KListViewItem
00075 {
00076
public:
00077 DateSortListViewItem(
QListView * parent,
QString label1,
QString label2 = QString::null,
QString label3 = QString::null,
QString label4 = QString::null,
QString label5 = QString::null,
QString label6 = QString::null,
QString label7 = QString::null,
QString label8 = QString::null ) :
00078 KListViewItem( parent, label1, label2, label3, label4, label5, label6, label7, label8 )
00079 {
00080 }
00081
00082
QString key(
int col,
bool asc)
const {
00083
if (col == 2)
00084 {
00085
QString s;
00086
QDate date = KGlobal::locale()->readDate(text(col));
00087 s.sprintf(
"%08d", date.year() * 366 + date.dayOfYear());
00088
return s;
00089 }
00090
return KListViewItem::key( col, asc );
00091 }
00092 };
00093
00094
00095 DownloadDialog::DownloadDialog(
Engine *engine,
QWidget *)
00096 : KDialogBase(KDialogBase::IconList, i18n("Get Hot New Stuff"),
00097 KDialogBase::Close, KDialogBase::Close)
00098 {
00099 init(engine);
00100 }
00101
00102 DownloadDialog::DownloadDialog(
QWidget *)
00103 : KDialogBase(KDialogBase::IconList, i18n("Get Hot New Stuff"),
00104 KDialogBase::Close, KDialogBase::Close)
00105 {
00106 init(0);
00107 }
00108
00109
void DownloadDialog::open(
QString type)
00110 {
00111 DownloadDialog d;
00112 d.setType(type);
00113 d.load();
00114 d.exec();
00115 }
00116
00117
00118 DownloadDialog::DownloadDialog(
Engine *engine,
QWidget *,
const QString& caption)
00119 : KDialogBase(KDialogBase::IconList, (caption.isNull() ? i18n("Get Hot New Stuff") : caption),
00120 KDialogBase::Close, KDialogBase::Close)
00121 {
00122 init(engine);
00123 }
00124
00125 DownloadDialog::DownloadDialog(
QWidget *,
const QString& caption)
00126 : KDialogBase(KDialogBase::IconList, (caption.isNull() ? i18n("Get Hot New Stuff") : caption),
00127 KDialogBase::Close, KDialogBase::Close)
00128 {
00129 init(0);
00130 }
00131
00132
void DownloadDialog::init(
Engine *engine)
00133 {
00134 resize(700, 400);
00135 d =
new Private();
00136
00137 m_engine = engine;
00138 d->m_page = NULL;
00139
00140 connect(
this, SIGNAL(aboutToShowPage(
QWidget*)), SLOT(slotPage(
QWidget*)));
00141
00142
if(!engine)
00143 {
00144 m_loader =
new ProviderLoader(
this);
00145 connect(m_loader, SIGNAL(providersLoaded(
Provider::List*)), SLOT(slotProviders(
Provider::List*)));
00146 }
00147 }
00148
00149 DownloadDialog::~DownloadDialog()
00150 {
00151
delete d;
00152 }
00153
00154
void DownloadDialog::load()
00155 {
00156 m_loader->load(m_filter, d->m_providerlist);
00157 }
00158
00159
void DownloadDialog::load(
QString providerList)
00160 {
00161 m_loader->load(m_filter, providerList);
00162 }
00163
00164
void DownloadDialog::clear()
00165 {
00166
QMap<QWidget*, QValueList<KListView*>* >::Iterator it;
00167
for(it = m_map.begin(); it != m_map.end(); it++)
00168 {
00169
QValueList<KListView*> *v = it.data();
00170 kdDebug() <<
"clear listviews in " << v << endl;
00171
if(v)
00172 {
00173 (*(v->at(0)))->clear();
00174 (*(v->at(1)))->clear();
00175 (*(v->at(2)))->clear();
00176
00177
00178 }
00179
00180
delete it.key();
00181 }
00182 m_map.clear();
00183 }
00184
00185
void DownloadDialog::slotProviders(
Provider::List *list)
00186 {
00187
Provider *p;
00188
00189
00190
for(p = list->first(); p; p = list->next())
00191 {
00192 kdDebug() <<
"++ provider ++ " << p->
name() << endl;
00193
00194
if(!m_filter.isEmpty())
00195 loadProvider(p);
00196
else
00197 addProvider(p);
00198
00199
00200 }
00201 }
00202
00203
void DownloadDialog::addProvider(
Provider *p)
00204 {
00205
QFrame *frame;
00206 KTabCtl *ctl;
00207
QWidget *w_d, *w_r, *w_l;
00208
QWidget *w2;
00209 KListView *lvtmp_r, *lvtmp_d, *lvtmp_l;
00210
QTextBrowser *rt;
00211
QString tmp;
00212
int ret;
00213
QPixmap pix;
00214
00215
if(m_map.count() == 0)
00216 {
00217 frame = addPage(i18n(
"Welcome"), i18n(
"Welcome"),
QPixmap(
""));
00218
delete frame;
00219 }
00220
00221 kdDebug() <<
"addProvider()/begin" << endl;
00222
00223 ret =
true;
00224
if(!p->
icon().isValid()) ret =
false;
00225
else ret = KIO::NetAccess::download(p->
icon(), tmp,
this);
00226
if(ret) pix =
QPixmap(tmp);
00227
else pix = KGlobal::iconLoader()->loadIcon(
"knewstuff", KIcon::Panel);
00228 frame = addPage(p->
name(), p->
name(), pix);
00229 m_frame = frame;
00230
00231 w2 =
new QWidget(frame);
00232 w_d =
new QWidget(frame);
00233 w_r =
new QWidget(frame);
00234 w_l =
new QWidget(frame);
00235
00236 ctl =
new KTabCtl(frame);
00237 ctl->addTab(w_r, i18n(
"Highest Rated"));
00238 ctl->addTab(w_d, i18n(
"Most Downloads"));
00239 ctl->addTab(w_l, i18n(
"Latest"));
00240
00241 m_curtab = 0;
00242 connect(ctl, SIGNAL(tabSelected(
int)), SLOT(slotTab(
int)));
00243
00244
QHBoxLayout *box =
new QHBoxLayout(frame);
00245 box->add(ctl);
00246
00247 lvtmp_r =
new KListView(w_r);
00248 lvtmp_r->addColumn(i18n(
"Name"));
00249 lvtmp_r->addColumn(i18n(
"Version"));
00250 lvtmp_r->addColumn(i18n(
"Rating"));
00251 lvtmp_r->setSorting(2,
false);
00252
00253 lvtmp_d =
new KListView(w_d);
00254 lvtmp_d->addColumn(i18n(
"Name"));
00255 lvtmp_d->addColumn(i18n(
"Version"));
00256 lvtmp_d->addColumn(i18n(
"Downloads"));
00257 lvtmp_d->setSorting(2,
false);
00258
00259 lvtmp_l =
new KListView(w_l);
00260 lvtmp_l->addColumn(i18n(
"Name"));
00261 lvtmp_l->addColumn(i18n(
"Version"));
00262 lvtmp_l->addColumn(i18n(
"Release Date"));
00263 lvtmp_l->setSorting(2,
false);
00264
00265 connect(lvtmp_r, SIGNAL(selectionChanged()), SLOT(slotSelected()));
00266 connect(lvtmp_d, SIGNAL(selectionChanged()), SLOT(slotSelected()));
00267 connect(lvtmp_l, SIGNAL(selectionChanged()), SLOT(slotSelected()));
00268
00269 rt =
new QTextBrowser(frame);
00270 rt->setMinimumWidth(150);
00271
00272
QPushButton *in =
new QPushButton(i18n(
"Install"), frame);
00273 QPushButton *de =
new QPushButton(i18n(
"Details"), frame);
00274 in->setEnabled(
false);
00275 de->setEnabled(
false);
00276
00277 box->addSpacing(spacingHint());
00278
QVBoxLayout *vbox =
new QVBoxLayout(box);
00279 vbox->add(rt);
00280 vbox->addSpacing(spacingHint());
00281 vbox->add(de);
00282 vbox->add(in);
00283
00284 connect(in, SIGNAL(clicked()), SLOT(slotInstall()));
00285 connect(de, SIGNAL(clicked()), SLOT(slotDetails()));
00286
00287 QVBoxLayout *box2 =
new QVBoxLayout(w_r);
00288 box2->add(lvtmp_r);
00289 QVBoxLayout *box3 =
new QVBoxLayout(w_d);
00290 box3->add(lvtmp_d);
00291 QVBoxLayout *box4 =
new QVBoxLayout(w_l);
00292 box4->add(lvtmp_l);
00293
00294
QValueList<KListView*> *v =
new QValueList<KListView*>;
00295 *v << lvtmp_r << lvtmp_d << lvtmp_l;
00296 m_map[frame] = v;
00297 m_rts[frame] = rt;
00298
QValueList<QPushButton*> *vb =
new QValueList<QPushButton*>;
00299 *vb << in << de;
00300 m_buttons[frame] = vb;
00301 m_providers[frame] = p;
00302
00303 kdDebug() <<
"addProvider()/end; lvtmp_r = " << lvtmp_r << endl;
00304
00305
if(m_engine) slotPage(frame);
00306
00307 QTimer::singleShot(100,
this, SLOT(slotFinish()));
00308 }
00309
00310
void DownloadDialog::slotResult(KIO::Job *job)
00311 {
00312
QDomDocument dom;
00313
QDomElement knewstuff;
00314
00315 kdDebug() <<
"got data: " << m_data[job] << endl;
00316
00317 kapp->config()->setGroup(
"KNewStuffStatus");
00318
00319 dom.setContent(m_data[job]);
00320 knewstuff = dom.documentElement();
00321
00322
for(
QDomNode pn = knewstuff.firstChild(); !pn.isNull(); pn = pn.nextSibling())
00323 {
00324
QDomElement stuff = pn.toElement();
00325
00326 kdDebug() <<
"element: " << stuff.tagName() << endl;
00327
00328
if(stuff.tagName() ==
"stuff")
00329 {
00330
Entry *entry =
new Entry(stuff);
00331 kdDebug() <<
"TYPE::" << entry->
type() <<
" FILTER::" << m_filter << endl;
00332
if(!entry->
type().isEmpty())
00333 {
00334
if((!m_filter.isEmpty()) && (entry->
type() != m_filter))
continue;
00335 }
00336
00337
if((!m_filter.isEmpty()) && (m_jobs[job]))
00338 {
00339
Provider *p = m_jobs[job];
00340 addProvider(p);
00341 slotPage(m_frame);
00342 m_jobs[job] = 0;
00343 }
00344 addEntry(entry);
00345 }
00346 }
00347
00348 m_data[job] =
"";
00349 }
00350
00351
int DownloadDialog::installStatus(
Entry *entry)
00352 {
00353
QDate date;
00354
QString datestring;
00355
int installed;
00356
00357 kapp->config()->setGroup(
"KNewStuffStatus");
00358 datestring = kapp->config()->readEntry(entry->
name());
00359
if(datestring.isNull()) installed = 0;
00360
else
00361 {
00362 date = QDate::fromString(datestring, Qt::ISODate);
00363
if(!date.isValid()) installed = 0;
00364
else if(date < entry->
releaseDate()) installed = -1;
00365
else installed = 1;
00366 }
00367
00368
return installed;
00369 }
00370
00371
void DownloadDialog::addEntry(
Entry *entry)
00372 {
00373 QPixmap pix;
00374
int installed;
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 installed = installStatus(entry);
00388
00389
if(installed > 0) pix = KGlobal::iconLoader()->loadIcon(
"ok", KIcon::Small);
00390
else if(installed < 0) pix = KGlobal::iconLoader()->loadIcon(
"history", KIcon::Small);
00391
else pix = QPixmap();
00392
00393 KListViewItem *tmp_r =
new NumSortListViewItem(lv_r,
00394 entry->
name(), entry->
version(),
QString(
"%1").arg(entry->
rating()));
00395 KListViewItem *tmp_d =
new NumSortListViewItem(lv_d,
00396 entry->
name(), entry->
version(),
QString(
"%1").arg(entry->
downloads()));
00397 KListViewItem *tmp_l =
new DateSortListViewItem(lv_l,
00398 entry->
name(), entry->
version(), KGlobal::locale()->formatDate(entry->
releaseDate()));
00399
00400 tmp_r->setPixmap(0, pix);
00401 tmp_d->setPixmap(0, pix);
00402 tmp_l->setPixmap(0, pix);
00403
00404 m_entries.append(entry);
00405
00406 kdDebug() <<
"added entry " << entry->
name() << endl;
00407 }
00408
00409
void DownloadDialog::slotData(KIO::Job *job,
const QByteArray &a)
00410 {
00411
QCString tmp(a, a.size() + 1);
00412 m_data[job].append(QString::fromUtf8(tmp));
00413 }
00414
00415
void DownloadDialog::slotDetails()
00416 {
00417
Entry *e = getEntry();
00418
if(!e)
return;
00419
00420
QString lang = KGlobal::locale()->language();
00421
00422
QString info = i18n
00423 (
00424
"Name: %1\n"
00425
"Author: %2\n"
00426
"License: %3\n"
00427
"Version: %4\n"
00428
"Release: %5\n"
00429
"Rating: %6\n"
00430
"Downloads: %7\n"
00431
"Release date: %8\n"
00432
"Summary: %9\n"
00433 ).arg(e->
name()
00434 ).arg(e->
author()
00435 ).arg(e->
license()
00436 ).arg(e->
version()
00437 ).arg(e->
release()
00438 ).arg(e->
rating()
00439 ).arg(e->
downloads()
00440 ).arg(KGlobal::locale()->formatDate(e->
releaseDate())
00441 ).arg(e->
summary(lang)
00442 );
00443
00444 info.append(i18n
00445 (
00446
"Preview: %1\n"
00447
"Payload: %2\n"
00448 ).arg(e->
preview().url()
00449 ).arg(e->
payload().url()
00450 ));
00451
00452 KMessageBox::information(
this, info, i18n(
"Details"));
00453 }
00454
00455
void DownloadDialog::slotInstall()
00456 {
00457
Entry *e = getEntry();
00458
if(!e)
return;
00459
00460 kdDebug() <<
"download entry now" << endl;
00461
00462
if(m_engine)
00463 {
00464 m_engine->download(e);
00465 install(e);
00466 }
00467
else
00468 {
00469 m_s =
new KNewStuffGeneric(e->
type(),
this);
00470
00471 m_entry = e;
00472
00473 KURL source = e->
payload();
00474 KURL dest = KURL(m_s->downloadDestination(e));
00475
00476 KIO::FileCopyJob *job = KIO::file_copy(source, dest, -1,
true);
00477 connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotInstalled(KIO::Job*)));
00478 }
00479 }
00480
00481
void DownloadDialog::install(
Entry *e)
00482 {
00483 kapp->config()->setGroup(
"KNewStuffStatus");
00484 kapp->config()->writeEntry(m_entryname, e->
releaseDate().toString(Qt::ISODate));
00485 kapp->config()->sync();
00486
00487 QPixmap pix = KGlobal::iconLoader()->loadIcon(
"ok", KIcon::Small);
00488 m_entryitem = lv_r->findItem(m_entryname, 0);
00489
if(m_entryitem) m_entryitem->setPixmap(0, pix);
00490 m_entryitem = lv_d->findItem(m_entryname, 0);
00491
if(m_entryitem) m_entryitem->setPixmap(0, pix);
00492 m_entryitem = lv_l->findItem(m_entryname, 0);
00493
if(m_entryitem) m_entryitem->setPixmap(0, pix);
00494
00495
00496 QPushButton *in;
00497 in = *(m_buttons[d->m_page]->at(0));
00498
if(in) in->setEnabled(
false);
00499 }
00500
00501
void DownloadDialog::slotInstalled(KIO::Job *job)
00502 {
00503
bool ret = (job->error() == 0);
00504 KIO::FileCopyJob *cjob;
00505
00506
if(ret)
00507 {
00508 cjob = static_cast<KIO::FileCopyJob*>(job);
00509
if(cjob)
00510 {
00511 ret = m_s->install(cjob->destURL().path());
00512 }
00513
else ret =
false;
00514 }
00515
00516
if(ret)
00517 {
00518 install(m_entry);
00519
00520 KMessageBox::information(
this, i18n(
"Installation successful."), i18n(
"Installation"));
00521 }
00522
else KMessageBox::error(
this, i18n(
"Installation failed."), i18n(
"Installation"));
00523
00524
delete m_s;
00525 }
00526
00527
void DownloadDialog::slotTab(
int tab)
00528 {
00529 kdDebug() <<
"switch tab to: " << tab << endl;
00530 m_curtab = tab;
00531 }
00532
00533
void DownloadDialog::slotSelected()
00534 {
00535
QString tmp;
00536
bool enabled;
00537
Entry *e = getEntry();
00538
QString lang = KGlobal::locale()->language();
00539
00540
if(e)
00541 {
00542
if(!e->
preview(lang).isValid())
00543 {
00544 m_rt->setText(
QString(
"<b>%1</b><br>%2<br>%3<br><br><i>%4</i><br>(%5)").arg(
00545 e->
name()).arg(e->
author()).arg(KGlobal::locale()->formatDate(e->
releaseDate())).arg(e->
summary(lang)).arg(e->
license()));
00546 }
00547
else
00548 {
00549 KIO::NetAccess::download(e->
preview(lang), tmp,
this);
00550 m_rt->setText(
QString(
"<b>%1</b><br>%2<br>%3<br><br><img src='%4'><br><i>%5</i><br>(%6)").arg(
00551 e->
name()).arg(e->
author()).arg(KGlobal::locale()->formatDate(e->
releaseDate())).arg(tmp).arg(e->
summary(lang)).arg(e->
license()));
00552 }
00553
00554
if(installStatus(e) == 1) enabled =
false;
00555
else enabled =
true;
00556
00557 QPushButton *de, *in;
00558 in = *(m_buttons[d->m_page]->at(0));
00559 de = *(m_buttons[d->m_page]->at(1));
00560
if(in) in->setEnabled(enabled);
00561
if(de) de->setEnabled(
true);
00562 }
00563 }
00564
00565
Entry *DownloadDialog::getEntry()
00566 {
00567
if(m_curtab == 0) m_entryitem = lv_r->currentItem();
00568
else if(m_curtab == 1) m_entryitem = lv_d->currentItem();
00569
else if(m_curtab == 2) m_entryitem = lv_l->currentItem();
00570
else return 0;
00571
00572 m_entryname = m_entryitem->text(0);
00573
00574
for(
Entry *e = m_entries.first(); e; e = m_entries.next())
00575 {
00576
if(e->
name() == m_entryname)
return e;
00577 }
00578
00579
return 0;
00580 }
00581
00582
void DownloadDialog::slotPage(QWidget *w)
00583 {
00584
Provider *p;
00585
00586 kdDebug() <<
"changed widget!!!" << endl;
00587
00588
if(m_map.find(w) == m_map.end())
return;
00589
00590 d->m_page = w;
00591
00592 lv_r = *(m_map[w]->at(0));
00593 lv_d = *(m_map[w]->at(1));
00594 lv_l = *(m_map[w]->at(2));
00595 p = m_providers[w];
00596 m_rt = m_rts[w];
00597
00598 kdDebug() <<
"valid change!!!; lv_r = " << lv_r << endl;
00599
00600
if(m_engine)
return;
00601
00602
if(!m_filter.isEmpty())
return;
00603
00604 lv_r->clear();
00605 lv_d->clear();
00606 lv_l->clear();
00607
00608 kdDebug() <<
"-- fetch -- " << p->
downloadUrl() << endl;
00609
00610 loadProvider(p);
00611 }
00612
00613
void DownloadDialog::loadProvider(
Provider *p)
00614 {
00615 KIO::TransferJob *job = KIO::get(p->
downloadUrl());
00616
00617 m_jobs[job] = p;
00618
00619 connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)));
00620 connect(job, SIGNAL(data(KIO::Job*,
const QByteArray&)),
00621 SLOT(slotData(KIO::Job*,
const QByteArray&)));
00622 }
00623
00624
void DownloadDialog::setType(
QString type)
00625 {
00626 m_filter = type;
00627 }
00628
00629
void DownloadDialog::setProviderList(
const QString& providerList)
00630 {
00631 d->m_providerlist = providerList;
00632 }
00633
00634
void DownloadDialog::slotOk()
00635 {
00636 }
00637
00638
void DownloadDialog::slotApply()
00639 {
00640 }
00641
00642
void DownloadDialog::open(
const QString& type,
const QString& caption)
00643 {
00644 DownloadDialog d(0, caption);
00645 d.setType(type);
00646 d.load();
00647 d.exec();
00648 }
00649
00650
void DownloadDialog::slotFinish()
00651 {
00652 showPage(1);
00653
00654 }
00655