21 #include "downloaddialog.h"
22 #include "downloaddialog.moc"
25 #include <klistview.h>
28 #include <kio/netaccess.h>
29 #include <kmessagebox.h>
32 #include <kapplication.h>
33 #include <kiconloader.h>
35 #include <knewstuff/entry.h>
36 #include <knewstuff/knewstuffgeneric.h>
37 #include <knewstuff/engine.h>
40 #include <tqpushbutton.h>
43 #include <tqtextbrowser.h>
44 #include <tqtabwidget.h>
49 struct DownloadDialog::Private
51 TQString m_providerlist;
53 KListView *m_lvtmp_r, *m_lvtmp_d, *m_lvtmp_l;
54 TQPtrList<Entry> m_installlist;
55 TQMap<KIO::Job*, Provider*> m_variantjobs;
56 TQMap<KIO::Job*, TQStringList> m_variants;
57 TQMap<Provider*, Provider*> m_newproviders;
60 class NumSortListViewItem :
public KListViewItem
63 NumSortListViewItem( TQListView * parent, TQString label1, TQString label2 = TQString::null, TQString label3 = TQString::null, TQString label4 = TQString::null, TQString label5 = TQString::null, TQString label6 = TQString::null, TQString label7 = TQString::null, TQString label8 = TQString::null ) :
64 KListViewItem( parent, label1, label2, label3, label4, label5, label6, label7, label8 )
68 TQString key(
int col,
bool asc)
const {
72 s.sprintf(
"%08d", text(col).toInt());
75 return KListViewItem::key( col, asc );
79 class DateSortListViewItem :
public KListViewItem
82 DateSortListViewItem( TQListView * parent, TQString label1, TQString label2 = TQString::null, TQString label3 = TQString::null, TQString label4 = TQString::null, TQString label5 = TQString::null, TQString label6 = TQString::null, TQString label7 = TQString::null, TQString label8 = TQString::null ) :
83 KListViewItem( parent, label1, label2, label3, label4, label5, label6, label7, label8 )
87 TQString key(
int col,
bool asc)
const {
91 TQDate date = KGlobal::locale()->readDate(text(col));
92 s.sprintf(
"%08d", date.year() * 366 + date.dayOfYear());
95 return KListViewItem::key( col, asc );
101 : KDialogBase(KDialogBase::IconList, i18n(
"Get Hot New Stuff"),
102 KDialogBase::Close, KDialogBase::Close)
108 : KDialogBase(KDialogBase::IconList, i18n(
"Get Hot New Stuff"),
109 KDialogBase::Close, KDialogBase::Close)
124 : KDialogBase(KDialogBase::IconList, (caption.isNull() ? i18n(
"Get Hot New Stuff") : caption),
125 KDialogBase::Close, KDialogBase::Close)
131 : KDialogBase(KDialogBase::IconList, (caption.isNull() ? i18n(
"Get Hot New Stuff") : caption),
132 KDialogBase::Close, KDialogBase::Close)
137 void DownloadDialog::init(
Engine *engine)
145 connect(
this, TQT_SIGNAL(aboutToShowPage(TQWidget*)), TQT_SLOT(slotPage(TQWidget*)));
150 connect(m_loader, TQT_SIGNAL(providersLoaded(Provider::List*)), TQT_SLOT(
slotProviders(Provider::List*)));
153 m_entries.setAutoDelete(
true);
158 for (TQMap<TQWidget *, TQValueList<TQPushButton *>* >::const_iterator it = m_buttons.constBegin(); it != m_buttons.constEnd(); ++it)
160 for (TQMap<TQWidget *, TQValueList<KListView *>* >::const_iterator it = m_map.constBegin(); it != m_map.constEnd(); ++it)
167 m_loader->
load(m_filter, d->m_providerlist);
172 m_loader->
load(m_filter, providerList);
177 TQMap<TQWidget*, TQValueList<KListView*>* >::Iterator it;
178 TQMap<TQWidget*, TQValueList<KListView*>* >::Iterator end(m_map.end());
179 for(it = m_map.begin(); it != end; ++it)
181 TQValueList<KListView*> *v = it.data();
182 kdDebug() <<
"clear listviews in " << v << endl;
185 (*(v->at(0)))->clear();
186 (*(v->at(1)))->clear();
187 (*(v->at(2)))->clear();
202 for(p = list->first(); p; p = list->next())
204 kdDebug() <<
"++ provider ++ " << p->
name() << endl;
206 if(!m_filter.isEmpty())
219 TQWidget *w_d, *w_r, *w_l;
226 if(m_map.count() == 0)
228 frame = addPage(i18n(
"Welcome"), i18n(
"Welcome"), TQPixmap(TQString(
"")));
232 kdDebug() <<
"addProvider()/begin" << endl;
235 if(p->
icon().path().isEmpty()) ret =
false;
238 if(!p->
icon().protocol().isEmpty())
240 ret = KIO::NetAccess::download(p->
icon(), tmp,
this);
241 if(ret) pix = TQPixmap(tmp);
245 pix = KGlobal::iconLoader()->loadIcon(p->
icon().path(), KIcon::Panel);
249 if(!ret) pix = KGlobal::iconLoader()->loadIcon(
"knewstuff", KIcon::Panel);
250 frame = addPage(p->
name(), p->
name(), pix);
253 w2 =
new TQWidget(frame);
254 w_d =
new TQWidget(frame);
255 w_r =
new TQWidget(frame);
256 w_l =
new TQWidget(frame);
258 ctl =
new TQTabWidget(frame);
259 ctl->addTab(w_r, i18n(
"Highest Rated"));
260 ctl->addTab(w_d, i18n(
"Most Downloads"));
261 ctl->addTab(w_l, i18n(
"Latest"));
264 connect(ctl, TQT_SIGNAL(currentChanged(TQWidget *)), TQT_SLOT(slotTab()));
266 TQHBoxLayout *box =
new TQHBoxLayout(frame);
269 d->m_lvtmp_r =
new KListView(w_r);
270 d->m_lvtmp_r->addColumn(i18n(
"Name"));
271 d->m_lvtmp_r->addColumn(i18n(
"Version"));
272 d->m_lvtmp_r->addColumn(i18n(
"Rating"));
273 d->m_lvtmp_r->setSorting(2,
false);
275 d->m_lvtmp_d =
new KListView(w_d);
276 d->m_lvtmp_d->addColumn(i18n(
"Name"));
277 d->m_lvtmp_d->addColumn(i18n(
"Version"));
278 d->m_lvtmp_d->addColumn(i18n(
"Downloads"));
279 d->m_lvtmp_d->setSorting(2,
false);
281 d->m_lvtmp_l =
new KListView(w_l);
282 d->m_lvtmp_l->addColumn(i18n(
"Name"));
283 d->m_lvtmp_l->addColumn(i18n(
"Version"));
284 d->m_lvtmp_l->addColumn(i18n(
"Release Date"));
285 d->m_lvtmp_l->setSorting(2,
false);
287 connect(d->m_lvtmp_r, TQT_SIGNAL(clicked(TQListViewItem*)), TQT_SLOT(slotSelected()));
288 connect(d->m_lvtmp_d, TQT_SIGNAL(clicked(TQListViewItem*)), TQT_SLOT(slotSelected()));
289 connect(d->m_lvtmp_l, TQT_SIGNAL(clicked(TQListViewItem*)), TQT_SLOT(slotSelected()));
291 rt =
new TQTextBrowser(frame);
292 rt->setMinimumWidth(150);
294 TQPushButton *in =
new TQPushButton(i18n(
"Install"), frame);
295 TQPushButton *de =
new TQPushButton(i18n(
"Details"), frame);
296 in->setEnabled(
false);
297 de->setEnabled(
false);
299 box->addSpacing(spacingHint());
300 TQVBoxLayout *vbox =
new TQVBoxLayout(box);
302 vbox->addSpacing(spacingHint());
306 connect(rt, TQT_SIGNAL(linkClicked(
const TQString&)), TQT_SLOT(slotEmail(
const TQString&)));
308 connect(in, TQT_SIGNAL(clicked()), TQT_SLOT(slotInstall()));
309 connect(de, TQT_SIGNAL(clicked()), TQT_SLOT(slotDetails()));
311 TQVBoxLayout *box2 =
new TQVBoxLayout(w_r);
312 box2->add(d->m_lvtmp_r);
313 TQVBoxLayout *box3 =
new TQVBoxLayout(w_d);
314 box3->add(d->m_lvtmp_d);
315 TQVBoxLayout *box4 =
new TQVBoxLayout(w_l);
316 box4->add(d->m_lvtmp_l);
318 TQValueList<KListView*> *v =
new TQValueList<KListView*>;
319 *v << d->m_lvtmp_r << d->m_lvtmp_d << d->m_lvtmp_l;
322 TQValueList<TQPushButton*> *vb =
new TQValueList<TQPushButton*>;
324 m_buttons[frame] = vb;
325 m_providers[frame] = p;
327 kdDebug() <<
"addProvider()/end; d->m_lvtmp_r = " << d->m_lvtmp_r << endl;
329 if(m_engine) slotPage(frame);
331 TQTimer::singleShot(100,
this, TQT_SLOT(slotFinish()));
334 void DownloadDialog::slotResult(KIO::Job *job)
337 TQDomElement knewstuff;
339 kdDebug() <<
"got data: " << m_data[job] << endl;
341 kapp->config()->setGroup(
"KNewStuffStatus");
343 dom.setContent(m_data[job]);
344 knewstuff = dom.documentElement();
346 for(TQDomNode pn = knewstuff.firstChild(); !pn.isNull(); pn = pn.nextSibling())
348 TQDomElement stuff = pn.toElement();
350 kdDebug() <<
"element: " << stuff.tagName() << endl;
352 if(stuff.tagName() ==
"stuff")
355 kdDebug() <<
"TYPE::" << entry->
type() <<
" FILTER::" << m_filter << endl;
356 if(!entry->
type().isEmpty())
358 if((!m_filter.isEmpty()) && (entry->
type() != m_filter))
continue;
371 if((!m_filter.isEmpty()) && (d->m_variantjobs[job]))
373 Provider *p = d->m_variantjobs[job];
374 if(d->m_newproviders[p])
378 d->m_newproviders[p] = 0;
384 if(d->m_variantjobs[job])
addEntry(entry, d->m_variants[job]);
389 int DownloadDialog::installStatus(
Entry *entry)
395 TQString lang = KGlobal::locale()->language();
397 kapp->config()->setGroup(
"KNewStuffStatus");
398 datestring = kapp->config()->readEntry(entry->
name(lang));
399 if(datestring.isNull()) installed = 0;
402 date = TQT_TQDATE_OBJECT(TQDate::fromString(datestring, Qt::ISODate));
403 if(!date.isValid()) installed = 0;
404 else if(date < entry->releaseDate()) installed = -1;
416 installed = installStatus(entry);
418 if(installed > 0) pix = KGlobal::iconLoader()->loadIcon(
"ok", KIcon::Small);
419 else if(installed < 0) pix = KGlobal::iconLoader()->loadIcon(
"history", KIcon::Small);
420 else pix = TQPixmap();
422 TQString lang = KGlobal::locale()->language();
424 if(variants.contains(
"score"))
426 KListViewItem *tmp_r =
new NumSortListViewItem(lv_r,
428 tmp_r->setPixmap(0, pix);
430 if(variants.contains(
"downloads"))
432 KListViewItem *tmp_d =
new NumSortListViewItem(lv_d,
434 tmp_d->setPixmap(0, pix);
436 if(variants.contains(
"latest"))
438 KListViewItem *tmp_l =
new DateSortListViewItem(lv_l,
440 tmp_l->setPixmap(0, pix);
443 m_entries.append(entry);
445 kdDebug() <<
"added entry " << entry->
name() <<
" for variants " << variants << endl;
450 TQStringList variants;
453 variants <<
"downloads";
454 variants <<
"latest";
459 kdDebug() <<
"added entry " << entry->
name() << endl;
462 void DownloadDialog::slotData(KIO::Job *job,
const TQByteArray &a)
464 TQCString tmp(a, a.size() + 1);
465 m_data[job].append(TQString::fromUtf8(tmp));
468 void DownloadDialog::slotDetails()
470 Entry *e = getEntry();
473 TQString lang = KGlobal::locale()->language();
493 ).arg(KGlobal::locale()->formatDate(e->
releaseDate())
505 KMessageBox::information(
this, info, i18n(
"Details"));
508 TQListViewItem *DownloadDialog::currentEntryItem()
510 if((m_curtab == 0) && (lv_r->selectedItem()))
return lv_r->selectedItem();
511 if((m_curtab == 1) && (lv_d->selectedItem()))
return lv_d->selectedItem();
512 if((m_curtab == 2) && (lv_l->selectedItem()))
return lv_l->selectedItem();
517 void DownloadDialog::slotInstall()
519 Entry *e = getEntry();
522 d->m_lvtmp_r->setEnabled(
false );
523 d->m_lvtmp_l->setEnabled(
false );
524 d->m_lvtmp_d->setEnabled(
false );
525 m_entryitem = currentEntryItem();
526 m_entryname = m_entryitem->text(0);
528 kdDebug() <<
"download entry now" << endl;
542 KIO::FileCopyJob *job = KIO::file_copy(source, dest, -1,
true);
543 connect(job, TQT_SIGNAL(result(KIO::Job*)), TQT_SLOT(slotInstalled(KIO::Job*)));
547 void DownloadDialog::install(
Entry *e)
549 kapp->config()->setGroup(
"KNewStuffStatus");
550 kapp->config()->writeEntry(m_entryname, TQString(e->
releaseDate().toString(Qt::ISODate)));
551 kapp->config()->sync();
553 TQPixmap pix = KGlobal::iconLoader()->loadIcon(
"ok", KIcon::Small);
555 TQString lang = KGlobal::locale()->language();
559 m_entryitem->setPixmap(0, pix);
561 TQListViewItem *item;
562 item = lv_r->findItem(e->
name(lang), 0);
563 if(item) item->setPixmap(0, pix);
564 item = lv_d->findItem(e->
name(lang), 0);
565 if(item) item->setPixmap(0, pix);
566 item = lv_l->findItem(e->
name(lang), 0);
567 if(item) item->setPixmap(0, pix);
570 if(currentEntryItem() == m_entryitem)
573 in = *(m_buttons[d->m_page]->at(0));
574 if(in) in->setEnabled(
false);
577 d->m_installlist.append(e);
578 d->m_lvtmp_r->setEnabled(
true );
579 d->m_lvtmp_l->setEnabled(
true );
580 d->m_lvtmp_d->setEnabled(
true );
583 void DownloadDialog::slotInstalled(KIO::Job *job)
585 bool ret = job && (job->error() == 0);
588 KIO::FileCopyJob *cjob = ::tqqt_cast<KIO::FileCopyJob*>(job);
591 ret = m_s->
install(cjob->destURL().path());
600 KMessageBox::information(
this, i18n(
"Installation successful."), i18n(
"Installation"));
602 else KMessageBox::error(
this, i18n(
"Installation failed."), i18n(
"Installation"));
603 d->m_lvtmp_r->setEnabled(
true );
604 d->m_lvtmp_l->setEnabled(
true );
605 d->m_lvtmp_d->setEnabled(
true );
610 void DownloadDialog::slotTab()
612 int tab =
static_cast<const TQTabWidget *
>(sender())->currentPageIndex();
613 kdDebug() <<
"switch tab to: " << tab << endl;
615 Entry *eold = getEntry();
617 Entry *e = getEntry();
619 if(e == eold)
return;
627 TQPushButton *de, *in;
628 in = *(m_buttons[d->m_page]->at(0));
629 de = *(m_buttons[d->m_page]->at(1));
631 if(in) in->setEnabled(
false);
632 if(de) de->setEnabled(
false);
638 void DownloadDialog::slotSelected()
642 Entry *e = getEntry();
643 TQString lang = KGlobal::locale()->language();
648 TQString lang = KGlobal::locale()->language();
650 TQListViewItem *item;
653 lv_r->clearSelection();
654 item = lv_r->findItem(e->
name(lang), 0);
655 if(item) lv_r->setSelected(item,
true);
659 lv_d->clearSelection();
660 item = lv_d->findItem(e->
name(lang), 0);
661 if(item) lv_d->setSelected(item,
true);
665 lv_l->clearSelection();
666 item = lv_l->findItem(e->
name(lang), 0);
667 if(item) lv_l->setSelected(item,
true);
670 if(!e->
preview(lang).isValid())
676 ret = KIO::NetAccess::download(e->
preview(lang), tmp,
this);
679 TQString desc = TQString(
"<b>%1</b><br>").arg(e->
name(lang));
682 desc += TQString(
"<a href='mailto:" + e->
authorEmail() +
"'>" + e->
author() +
"</a>");
686 desc += TQString(
"%1").arg(e->
author());
688 desc += TQString(
"<br>%1").arg(KGlobal::locale()->formatDate(e->
releaseDate()));
689 desc += TQString(
"<br><br>");
692 desc += TQString(
"<img src='%1'>").arg(tmp);
696 desc += i18n(
"Preview not available.");
698 desc += TQString(
"<br><i>%1</i>").arg(e->
summary(lang));
699 desc += TQString(
"<br>(%1)").arg(e->
license());
704 if(installStatus(e) == 1) enabled =
false;
707 TQPushButton *de, *in;
708 in = *(m_buttons[d->m_page]->at(0));
709 de = *(m_buttons[d->m_page]->at(1));
710 if(in) in->setEnabled(enabled);
711 if(de) de->setEnabled(
true);
715 void DownloadDialog::slotEmail(
const TQString& link)
717 kdDebug() <<
"EMAIL: " << link << endl;
718 kapp->invokeMailer(link);
722 Entry *DownloadDialog::getEntry()
724 TQListViewItem *entryItem = currentEntryItem();
729 TQString entryName = entryItem->text(0);
731 TQString lang = KGlobal::locale()->language();
733 for(
Entry *e = m_entries.first(); e; e = m_entries.next())
734 if(e->
name(lang) == entryName)
740 void DownloadDialog::slotPage(TQWidget *w)
744 kdDebug() <<
"changed widget!!!" << endl;
746 if(m_map.find(w) == m_map.end())
return;
750 lv_r = *(m_map[w]->at(0));
751 lv_d = *(m_map[w]->at(1));
752 lv_l = *(m_map[w]->at(2));
756 kdDebug() <<
"valid change!!!; lv_r = " << lv_r << endl;
760 if(!m_filter.isEmpty())
return;
766 kdDebug() <<
"-- fetch -- " << p->
downloadUrl() << endl;
771 void DownloadDialog::loadProvider(
Provider *p)
773 TQMap<KIO::Job*, Provider*>::Iterator it;
775 for(it = d->m_variantjobs.begin(); it != d->m_variantjobs.end(); it++)
779 kdDebug() <<
"-- found provider data in cache" << endl;
780 slotResult(it.key());
785 TQStringList variants;
787 variants <<
"downloads";
788 variants <<
"latest";
792 TQMap<TQString, TQStringList> urls;
794 for(TQStringList::Iterator it = variants.begin(); it != variants.end(); it++)
797 if(!urls.contains(url))
799 urls[url] = TQStringList();
803 it = variants.remove(it);
808 for(TQMap<TQString, TQStringList>::Iterator it = urls.begin(); it != urls.end(); it++)
810 TQString url = it.key();
811 TQStringList urlvariants = it.data();
813 KIO::TransferJob *variantjob = KIO::get(url);
814 d->m_newproviders[p] = p;
815 d->m_variantjobs[variantjob] = p;
816 d->m_variants[variantjob] = urlvariants;
817 m_data[variantjob] =
"";
819 connect(variantjob, TQT_SIGNAL(result(KIO::Job*)), TQT_SLOT(slotResult(KIO::Job*)));
820 connect(variantjob, TQT_SIGNAL(data(KIO::Job*,
const TQByteArray&)),
821 TQT_SLOT(slotData(KIO::Job*,
const TQByteArray&)));
824 if(variants.count() == 0)
return;
828 kdDebug() <<
"-- reached old downloadurl section; variants left: " << variants.count() << endl;
830 KIO::TransferJob *job = KIO::get(p->
downloadUrl());
832 d->m_newproviders[p] = p;
833 d->m_variantjobs[job] = p;
834 d->m_variants[job] = variants;
838 connect(job, TQT_SIGNAL(result(KIO::Job*)), TQT_SLOT(slotResult(KIO::Job*)));
839 connect(job, TQT_SIGNAL(data(KIO::Job*,
const TQByteArray&)),
840 TQT_SLOT(slotData(KIO::Job*,
const TQByteArray&)));
850 d->m_providerlist = providerList;
853 void DownloadDialog::slotOk()
857 void DownloadDialog::slotApply()
869 void DownloadDialog::slotFinish()
877 return d->m_installlist;