knewstuff Library API Documentation

downloaddialog.cpp

00001 /*
00002     This file is part of KNewStuff.
00003     Copyright (c) 2003 Josef Spillner <spillner@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018     Boston, MA 02111-1307, USA.
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> // hack
00046 
00047 using namespace KNS;
00048 
00049 struct DownloadDialog::Private
00050 {
00051     QString m_providerlist;
00052     QWidget *m_page;
00053     KListView *m_lvtmp_r, *m_lvtmp_d, *m_lvtmp_l;
00054 };
00055 
00056 class NumSortListViewItem : public KListViewItem
00057 {
00058   public:
00059   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 )  :
00060   KListViewItem( parent, label1, label2, label3, label4, label5, label6, label7, label8 )
00061   {
00062   }
00063 
00064   QString key(int col, bool asc) const {
00065     if (col == 2)
00066     {
00067       QString s;
00068       s.sprintf("%08d", text(col).toInt());
00069       return s;
00070     }
00071     return KListViewItem::key( col, asc );
00072   }
00073 };
00074 
00075 class DateSortListViewItem : public KListViewItem
00076 {
00077   public:
00078   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 )  :
00079   KListViewItem( parent, label1, label2, label3, label4, label5, label6, label7, label8 )
00080   {
00081   }
00082 
00083   QString key(int col, bool asc) const {
00084     if (col == 2)
00085     {
00086       QString s;
00087       QDate date = KGlobal::locale()->readDate(text(col));
00088       s.sprintf("%08d", date.year() * 366 + date.dayOfYear());
00089       return s;
00090     }
00091     return KListViewItem::key( col, asc );
00092   }
00093 };
00094 
00095 // BEGIN deprecated for KDE 4
00096 DownloadDialog::DownloadDialog(Engine *engine, QWidget *)
00097 : KDialogBase(KDialogBase::IconList, i18n("Get Hot New Stuff"),
00098   KDialogBase::Close, KDialogBase::Close)
00099 {
00100   init(engine);
00101 }
00102 
00103 DownloadDialog::DownloadDialog(QWidget *)
00104 : KDialogBase(KDialogBase::IconList, i18n("Get Hot New Stuff"),
00105   KDialogBase::Close, KDialogBase::Close)
00106 {
00107   init(0);
00108 }
00109 
00110 void DownloadDialog::open(QString type)
00111 {
00112   DownloadDialog d;
00113   d.setType(type);
00114   d.load();
00115   d.exec();
00116 }
00117 // END deprecated for KDE 4
00118 
00119 DownloadDialog::DownloadDialog(Engine *engine, QWidget *, const QString& caption)
00120 : KDialogBase(KDialogBase::IconList, (caption.isNull() ? i18n("Get Hot New Stuff") : caption),
00121   KDialogBase::Close, KDialogBase::Close)
00122 {
00123   init(engine);
00124 }
00125 
00126 DownloadDialog::DownloadDialog(QWidget *, const QString& caption)
00127 : KDialogBase(KDialogBase::IconList, (caption.isNull() ? i18n("Get Hot New Stuff") : caption),
00128   KDialogBase::Close, KDialogBase::Close)
00129 {
00130   init(0);
00131 }
00132 
00133 void DownloadDialog::init(Engine *engine)
00134 {
00135   resize(700, 400);
00136   d = new Private();
00137 
00138   m_engine = engine;
00139   d->m_page = NULL;
00140 
00141   connect(this, SIGNAL(aboutToShowPage(QWidget*)), SLOT(slotPage(QWidget*)));
00142 
00143   if(!engine)
00144   {
00145     m_loader = new ProviderLoader(this);
00146     connect(m_loader, SIGNAL(providersLoaded(Provider::List*)), SLOT(slotProviders(Provider::List*)));
00147   }
00148 }
00149 
00150 DownloadDialog::~DownloadDialog()
00151 {
00152     delete d;
00153 }
00154 
00155 void DownloadDialog::load()
00156 {
00157   m_loader->load(m_filter, d->m_providerlist);
00158 }
00159 
00160 void DownloadDialog::load(QString providerList)
00161 {
00162   m_loader->load(m_filter, providerList);
00163 }
00164 
00165 void DownloadDialog::clear()
00166 {
00167   QMap<QWidget*, QValueList<KListView*>* >::Iterator it;
00168   for(it = m_map.begin(); it != m_map.end(); it++)
00169   {
00170     QValueList<KListView*> *v = it.data();
00171     kdDebug() << "clear listviews in " << v << endl;
00172     if(v)
00173     {
00174       (*(v->at(0)))->clear();
00175       (*(v->at(1)))->clear();
00176       (*(v->at(2)))->clear();
00177 
00178       //delete (*it);
00179     }
00180 
00181     delete it.key();
00182   }
00183   m_map.clear();
00184 }
00185 
00186 void DownloadDialog::slotProviders(Provider::List *list)
00187 {
00188   Provider *p;
00189   /*QFrame *frame;*/
00190 
00191   for(p = list->first(); p; p = list->next())
00192   {
00193     kdDebug() << "++ provider ++ " << p->name() << endl;
00194 
00195     if(!m_filter.isEmpty())
00196       loadProvider(p);
00197     else
00198       addProvider(p);
00199     /*if(p == list->getFirst())
00200       slotPage(m_frame);*/ // only if !qtbug
00201   }
00202 }
00203 
00204 void DownloadDialog::addProvider(Provider *p)
00205 {
00206   QFrame *frame;
00207   KTabCtl *ctl;
00208   QWidget *w_d, *w_r, *w_l;
00209   QWidget *w2;
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   d->m_lvtmp_r = new KListView(w_r);
00248   d->m_lvtmp_r->addColumn(i18n("Name"));
00249   d->m_lvtmp_r->addColumn(i18n("Version"));
00250   d->m_lvtmp_r->addColumn(i18n("Rating"));
00251   d->m_lvtmp_r->setSorting(2, false);
00252 
00253   d->m_lvtmp_d = new KListView(w_d);
00254   d->m_lvtmp_d->addColumn(i18n("Name"));
00255   d->m_lvtmp_d->addColumn(i18n("Version"));
00256   d->m_lvtmp_d->addColumn(i18n("Downloads"));
00257   d->m_lvtmp_d->setSorting(2, false);
00258 
00259   d->m_lvtmp_l = new KListView(w_l);
00260   d->m_lvtmp_l->addColumn(i18n("Name"));
00261   d->m_lvtmp_l->addColumn(i18n("Version"));
00262   d->m_lvtmp_l->addColumn(i18n("Release Date"));
00263   d->m_lvtmp_l->setSorting(2, false);
00264 
00265   connect(d->m_lvtmp_r, SIGNAL(selectionChanged()), SLOT(slotSelected()));
00266   connect(d->m_lvtmp_d, SIGNAL(selectionChanged()), SLOT(slotSelected()));
00267   connect(d->m_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(d->m_lvtmp_r);
00289   QVBoxLayout *box3 = new QVBoxLayout(w_d);
00290   box3->add(d->m_lvtmp_d);
00291   QVBoxLayout *box4 = new QVBoxLayout(w_l);
00292   box4->add(d->m_lvtmp_l);
00293 
00294   QValueList<KListView*> *v = new QValueList<KListView*>;
00295   *v << d->m_lvtmp_r << d->m_lvtmp_d << d->m_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; d->m_lvtmp_r = " << d->m_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   /*if(m_engine)
00377   {
00378     if(m_map.count() == 0)
00379     {
00380       m_frame = addPage(i18n("Welcome"), i18n("Welcome"), QPixmap(""));
00381       Provider *p = new Provider();
00382       p->setName(i18n("Generic"));
00383       addProvider(p);
00384       slotPage(m_frame);
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   d->m_lvtmp_r->setEnabled( false );
00460   d->m_lvtmp_l->setEnabled( false );
00461   d->m_lvtmp_d->setEnabled( false );
00462 
00463   kdDebug() << "download entry now" << endl;
00464 
00465   if(m_engine)
00466   {
00467     m_engine->download(e);
00468     install(e);
00469   }
00470   else
00471   {
00472     m_s = new KNewStuffGeneric(e->type(), this);
00473     m_entry = e;
00474     KURL source = e->payload();
00475     KURL dest = KURL(m_s->downloadDestination(e));
00476 
00477     KIO::FileCopyJob *job = KIO::file_copy(source, dest, -1, true);
00478     connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotInstalled(KIO::Job*)));
00479   }
00480 }
00481 
00482 void DownloadDialog::install(Entry *e)
00483 {
00484   kapp->config()->setGroup("KNewStuffStatus");
00485   kapp->config()->writeEntry(m_entryname, e->releaseDate().toString(Qt::ISODate));
00486   kapp->config()->sync();
00487 
00488   QPixmap pix = KGlobal::iconLoader()->loadIcon("ok", KIcon::Small);
00489   m_entryitem = lv_r->findItem(m_entryname, 0);
00490   if(m_entryitem) m_entryitem->setPixmap(0, pix);
00491   m_entryitem = lv_d->findItem(m_entryname, 0);
00492   if(m_entryitem) m_entryitem->setPixmap(0, pix);
00493   m_entryitem = lv_l->findItem(m_entryname, 0);
00494   if(m_entryitem) m_entryitem->setPixmap(0, pix);
00495 
00496 
00497   QPushButton *in;
00498   in = *(m_buttons[d->m_page]->at(0));
00499   if(in) in->setEnabled(false);
00500 }
00501 
00502 void DownloadDialog::slotInstalled(KIO::Job *job)
00503 {
00504   bool ret = (job->error() == 0);
00505   KIO::FileCopyJob *cjob;
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   d->m_lvtmp_r->setEnabled( true );
00524   d->m_lvtmp_l->setEnabled( true );
00525   d->m_lvtmp_d->setEnabled( true );
00526 
00527   delete m_s;
00528 }
00529 
00530 void DownloadDialog::slotTab(int tab)
00531 {
00532   kdDebug() << "switch tab to: " << tab << endl;
00533   m_curtab = tab;
00534 }
00535 
00536 void DownloadDialog::slotSelected()
00537 {
00538   QString tmp;
00539   bool enabled;
00540   Entry *e = getEntry();
00541   QString lang = KGlobal::locale()->language();
00542 
00543   if(e)
00544   {
00545     if(!e->preview(lang).isValid())
00546     {
00547       m_rt->setText(QString("<b>%1</b><br>%2<br>%3<br><br><i>%4</i><br>(%5)").arg(
00548         e->name()).arg(e->author()).arg(KGlobal::locale()->formatDate(e->releaseDate())).arg(e->summary(lang)).arg(e->license()));
00549     }
00550     else
00551     {
00552       KIO::NetAccess::download(e->preview(lang), tmp, this);
00553       m_rt->setText(QString("<b>%1</b><br>%2<br>%3<br><br><img src='%4'><br><i>%5</i><br>(%6)").arg(
00554         e->name()).arg(e->author()).arg(KGlobal::locale()->formatDate(e->releaseDate())).arg(tmp).arg(e->summary(lang)).arg(e->license()));
00555     }
00556 
00557     if(installStatus(e) == 1) enabled = false;
00558     else enabled = true;
00559 
00560     QPushButton *de, *in;
00561     in = *(m_buttons[d->m_page]->at(0));
00562     de = *(m_buttons[d->m_page]->at(1));
00563     if(in) in->setEnabled(enabled);
00564     if(de) de->setEnabled(true);
00565   }
00566 }
00567 
00568 Entry *DownloadDialog::getEntry()
00569 {
00570   if(m_curtab == 0) m_entryitem = lv_r->currentItem();
00571   else if(m_curtab == 1) m_entryitem = lv_d->currentItem();
00572   else if(m_curtab == 2) m_entryitem = lv_l->currentItem();
00573   else return 0;
00574 
00575   m_entryname = m_entryitem->text(0);
00576 
00577   for(Entry *e = m_entries.first(); e; e = m_entries.next())
00578   {
00579     if(e->name() == m_entryname) return e;
00580   }
00581 
00582   return 0;
00583 }
00584 
00585 void DownloadDialog::slotPage(QWidget *w)
00586 {
00587   Provider *p;
00588 
00589   kdDebug() << "changed widget!!!" << endl;
00590 
00591   if(m_map.find(w) == m_map.end()) return;
00592 
00593   d->m_page = w;
00594 
00595   lv_r = *(m_map[w]->at(0));
00596   lv_d = *(m_map[w]->at(1));
00597   lv_l = *(m_map[w]->at(2));
00598   p = m_providers[w];
00599   m_rt = m_rts[w];
00600 
00601   kdDebug() << "valid change!!!; lv_r = " << lv_r << endl;
00602 
00603   if(m_engine) return;
00604 
00605   if(!m_filter.isEmpty()) return;
00606 
00607   lv_r->clear();
00608   lv_d->clear();
00609   lv_l->clear();
00610 
00611   kdDebug() << "-- fetch -- " << p->downloadUrl() << endl;
00612 
00613   loadProvider(p);
00614 }
00615 
00616 void DownloadDialog::loadProvider(Provider *p)
00617 {
00618   KIO::TransferJob *job = KIO::get(p->downloadUrl());
00619 
00620   m_jobs[job] = p;
00621 
00622   connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)));
00623   connect(job, SIGNAL(data(KIO::Job*, const QByteArray&)),
00624     SLOT(slotData(KIO::Job*, const QByteArray&)));
00625 }
00626 
00627 void DownloadDialog::setType(QString type)
00628 {
00629   m_filter = type;
00630 }
00631 
00632 void DownloadDialog::setProviderList(const QString& providerList)
00633 {
00634   d->m_providerlist = providerList;
00635 }
00636 
00637 void DownloadDialog::slotOk()
00638 {
00639 }
00640 
00641 void DownloadDialog::slotApply()
00642 {
00643 }
00644 
00645 void DownloadDialog::open(const QString& type, const QString& caption)
00646 {
00647   DownloadDialog d(0, caption);
00648   d.setType(type);
00649   d.load();
00650   d.exec();
00651 }
00652 
00653 void DownloadDialog::slotFinish()
00654 {
00655   showPage(1);
00656   //updateBackground();
00657 }
00658 
KDE Logo
This file is part of the documentation for knewstuff Library Version 3.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 15 10:51:58 2005 by doxygen 1.4.4 written by Dimitri van Heesch, © 1997-2003