KNewStuff
downloaddialog.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of KNewStuff2. 00003 Copyright (C) 2005 by Enrico Ros <eros.kde@email.it> 00004 Copyright (C) 2005 - 2007 Josef Spillner <spillner@kde.org> 00005 Copyright (C) 2007 Dirk Mueller <mueller@kde.org> 00006 Copyright (C) 2007 Jeremy Whiting <jpwhiting@kde.org> 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2.1 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library. If not, see <http://www.gnu.org/licenses/>. 00020 */ 00021 00022 // own include 00023 #include "downloaddialog.h" 00024 00025 // qt/kde includes 00026 #include <QtCore/QTimer> 00027 #include <QtGui/QPixmap> 00028 #include <QtGui/QSortFilterProxyModel> 00029 #include <kaboutdata.h> 00030 #include <kcomponentdata.h> 00031 #include <kmessagebox.h> 00032 #include <ktoolinvocation.h> 00033 00034 #include <kdebug.h> 00035 00036 #include "knewstuff2/core/provider.h" 00037 #include "knewstuff2/core/providerhandler.h" 00038 #include "knewstuff2/core/entry.h" 00039 #include "knewstuff2/core/entryhandler.h" 00040 #include "knewstuff2/core/category.h" 00041 00042 #include "knewstuff2/dxs/dxs.h" 00043 00044 // local includes 00045 #include "ui_DownloadDialog.h" 00046 #include "itemsmodel.h" 00047 #include "itemsviewdelegate.h" 00048 #include "kdxsrating.h" 00049 #include "kdxscomment.h" 00050 #include "kdxscomments.h" 00051 00052 const char * ConfigGroup = "DownloadDialog Settings"; 00053 00054 using namespace KNS; 00055 00056 DownloadDialog::DownloadDialog(DxsEngine* _engine, QWidget * _parent) 00057 : KDialog(_parent) 00058 { 00059 setButtons(0); 00060 00061 m_engine = _engine; 00062 connect(m_engine, SIGNAL(signalProgress(QString, int)), SLOT(slotProgress(QString, int))); 00063 connect(m_engine, SIGNAL(signalEntryChanged(KNS::Entry*)), SLOT(slotEntryChanged(KNS::Entry*))); 00064 connect(m_engine, SIGNAL(signalPayloadFailed(KNS::Entry*)), SLOT(slotPayloadFailed(KNS::Entry*))); 00065 connect(m_engine, SIGNAL(signalPayloadLoaded(KUrl)), SLOT(slotPayloadLoaded(KUrl))); 00066 connect(m_engine, SIGNAL(signalProvidersFailed()), SLOT(slotProvidersFailed())); 00067 connect(m_engine, SIGNAL(signalEntriesFailed()), SLOT(slotEntriesFailed())); 00068 00069 connect(m_engine, SIGNAL(signalEntryLoaded(KNS::Entry*, const KNS::Feed*, const KNS::Provider*)), 00070 this, SLOT(slotEntryLoaded(KNS::Entry*, const KNS::Feed*, const KNS::Provider*))); 00071 connect(m_engine, SIGNAL(signalEntryRemoved(KNS::Entry*, const KNS::Feed*)), 00072 this, SLOT(slotEntryRemoved(KNS::Entry *, const KNS::Feed *))); 00073 00074 // initialize the private classes 00075 messageTimer = new QTimer(this); 00076 messageTimer->setSingleShot(true); 00077 connect(messageTimer, SIGNAL(timeout()), SLOT(slotResetMessage())); 00078 00079 networkTimer = new QTimer(this); 00080 connect(networkTimer, SIGNAL(timeout()), SLOT(slotNetworkTimeout())); 00081 00082 m_searchTimer = new QTimer(this); 00083 m_searchTimer->setSingleShot(true); 00084 m_searchTimer->setInterval(1000); // timeout after 30 seconds 00085 connect(m_searchTimer, SIGNAL(timeout()), SLOT(slotUpdateSearch())); 00086 00087 // popuplate dialog with stuff 00088 QWidget* _mainWidget = new QWidget(this); 00089 setMainWidget(_mainWidget); 00090 setupUi(_mainWidget); 00091 00092 // create the delegate 00093 mDelegate = new ItemsViewDelegate(m_listView, this); 00094 m_listView->setItemDelegate(mDelegate); 00095 connect(mDelegate, SIGNAL(performAction(DownloadDialog::EntryAction, KNS::Entry *)), 00096 SLOT(slotPerformAction(DownloadDialog::EntryAction, KNS::Entry *))); 00097 00098 // create the filter model 00099 m_filteredModel = new QSortFilterProxyModel(this); 00100 m_filteredModel->setFilterRole(ItemsModel::kNameRole); 00101 m_filteredModel->setFilterCaseSensitivity(Qt::CaseInsensitive); 00102 m_listView->setModel(m_filteredModel); 00103 connect(m_listView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), 00104 this, SLOT(slotListIndexChanged(const QModelIndex &, const QModelIndex &))); 00105 00106 // create left picture widget (if picture found) 00107 //QPixmap p( KStandardDirs::locate( "data", "knewstuff/pics/ghns.png" ) ); 00108 //if ( !p.isNull() ) 00109 // horLay->addWidget( new ExtendImageWidget( p, this ) ); 00110 // FIXME KDE4PORT: if we use a left bar image, find a better way 00111 00112 00113 connect(m_sourceCombo, SIGNAL(currentIndexChanged(int)), SLOT(slotLoadProviderDXS())); 00114 connect(m_sortCombo, SIGNAL(currentIndexChanged(int)), SLOT(slotSortingSelected(int))); 00115 connect(m_searchEdit, SIGNAL(textChanged(const QString &)), SLOT(slotSearchTextChanged())); 00116 connect(m_searchEdit, SIGNAL(editingFinished()), SLOT(slotUpdateSearch())); 00117 00118 // FIXME: not sure if this is better, or setting openExternalLinks 00119 //connect( m_providerLinkLabel, SIGNAL( linkActivated(const QString &)), 00120 // KToolInvocation::self(), SLOT(invokeBrowser(const QString &))); 00121 00122 // load the last size from config 00123 KConfigGroup group(KGlobal::config(), ConfigGroup); 00124 restoreDialogSize(group); 00125 setMinimumSize(700, 400); 00126 00127 setCaption(i18n("Get Hot New Stuff")); 00128 m_titleWidget->setText(i18nc("Program name followed by 'Add On Installer'", 00129 "%1 Add-On Installer", 00130 KGlobal::activeComponent().aboutData()->programName())); 00131 m_titleWidget->setPixmap(KIcon(KGlobal::activeComponent().aboutData()->programIconName())); 00132 00133 connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(accept())); 00134 00135 KMenu * collabMenu = new KMenu(m_collaborationButton); 00136 QAction * action_collabrating = collabMenu->addAction(i18n("Add Rating")); 00137 action_collabrating->setData(DownloadDialog::kCollabRate); 00138 00139 QAction * action_collabcomment = collabMenu->addAction(i18n("Add Comment")); 00140 action_collabcomment->setData(DownloadDialog::kCollabComment); 00141 00142 QAction * action_comment = collabMenu->addAction(SmallIcon("help-about"), i18n("View Comments")); 00143 action_comment->setData(DownloadDialog::kComments); 00144 00145 /* TODO: Re-enable when implemented 00146 QAction * action_collabtranslation = collabMenu->addAction(i18n("Translate")); 00147 action_collabtranslation->setData(DownloadDialog::kCollabTranslate); 00148 00149 QAction * action_collabsubscribe = collabMenu->addAction(i18n("Subscribe")); 00150 action_collabsubscribe->setData(DownloadDialog::kCollabSubscribe); 00151 00152 QAction * action_collabremoval = collabMenu->addAction(i18n("Report bad entry")); 00153 action_collabremoval->setData(DownloadDialog::kCollabRemoval); 00154 */ 00155 00156 m_collaborationButton->setMenu(collabMenu); 00157 connect(m_collaborationButton, SIGNAL(triggered(QAction*)), this, SLOT(slotCollabAction(QAction*))); 00158 } 00159 00160 DownloadDialog::~DownloadDialog() 00161 { 00162 KConfigGroup group(KGlobal::config(), ConfigGroup); 00163 saveDialogSize(group, KConfigBase::Persistent); 00164 } 00165 00166 void DownloadDialog::slotPerformAction(DownloadDialog::EntryAction action, KNS::Entry * entry) 00167 { 00168 kDebug(551) << "perform action: " << action; 00169 const Provider * provider = m_providers.contains(entry) ? m_providers[entry] : NULL; 00170 Dxs * dxs = m_engine->dxsObject(provider); 00171 switch (action) { 00172 case kViewInfo: 00173 if (provider && dxs) { 00174 if (provider->webService().isValid()) { 00175 dxs->call_info(); 00176 } else { 00177 slotInfo(provider->name().representation(), 00178 provider->webAccess().pathOrUrl(), 00179 QString()); 00180 } 00181 } 00182 break; 00183 case kComments: 00184 // show the entry's comments 00185 if (provider && dxs) { 00186 connect(dxs, SIGNAL(signalComments(QStringList)), this, SLOT(slotComments(QStringList))); 00187 dxs->call_comments(entry->idNumber()); 00188 } 00189 break; 00190 case kChanges: 00191 // show the entry's changelog 00192 break; 00193 case kContactEmail: 00194 // invoke mail with the address of the author 00195 KToolInvocation::invokeMailer(entry->author().email(), i18n("Re: %1", entry->name().representation())); 00196 break; 00197 case kContactJabber: 00198 // start jabber with author's info 00199 break; 00200 case kCollabTranslate: 00201 // open translation dialog 00202 break; 00203 case kCollabRemoval: 00204 // verify removal, maybe authenticate? 00205 break; 00206 case kCollabSubscribe: 00207 // subscribe to changes 00208 break; 00209 case kUninstall: 00210 // uninstall 00211 setCursor(Qt::WaitCursor); 00212 m_engine->uninstall(entry); 00213 setCursor(Qt::ArrowCursor); 00214 break; 00215 case kInstall: 00216 // install 00217 setCursor(Qt::WaitCursor); 00218 m_engine->downloadPayload(entry); 00219 break; 00220 case kCollabComment: { 00221 // open comment dialog 00222 QPointer<KDXSComment> commentDialog = new KDXSComment(this); 00223 int ret = commentDialog->exec(); 00224 if (ret == QDialog::Accepted) { 00225 QString s = commentDialog->comment(); 00226 if (dxs && !s.isEmpty()) { 00227 dxs->call_comment(entry->idNumber(), s); 00228 } 00229 } 00230 delete commentDialog; 00231 } 00232 break; 00233 case kCollabRate: { 00234 // prompt for rating, and send to provider 00235 QPointer<KDXSRating> ratingDialog = new KDXSRating(this); 00236 int ret = ratingDialog->exec(); 00237 if (ret == QDialog::Accepted) { 00238 int rating = ratingDialog->rating(); 00239 if (dxs) { 00240 dxs->call_rating(entry->idNumber(), rating); 00241 } 00242 } 00243 delete ratingDialog; 00244 } 00245 break; 00246 } 00247 } 00248 00249 void DownloadDialog::slotCollabAction(QAction * action) 00250 { 00251 DownloadDialog::EntryAction entryAction = (DownloadDialog::EntryAction)action->data().toInt(); 00252 QModelIndex currentIndex = m_listView->currentIndex(); 00253 const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(m_filteredModel->sourceModel()); 00254 QModelIndex index = m_filteredModel->mapToSource(currentIndex); 00255 KNS::Entry * entry = realmodel->entryForIndex(index); 00256 slotPerformAction(entryAction, entry); 00257 } 00258 00259 void DownloadDialog::slotListIndexChanged(const QModelIndex &index, const QModelIndex &/*old */) 00260 { 00261 //kDebug() << "slotListIndexChanged called"; 00262 00263 m_collaborationButton->setEnabled(m_hasDxs && index.isValid()); 00264 } 00265 00266 void DownloadDialog::hideEvent(QHideEvent * event) 00267 { 00268 KConfigGroup group(KGlobal::config(), ConfigGroup); 00269 saveDialogSize(group, KConfigBase::Persistent); 00270 KDialog::hideEvent(event); 00271 } 00272 00273 void DownloadDialog::displayMessage(const QString & msg, KTitleWidget::MessageType type, int timeOutMs) 00274 { 00275 // stop the pending timer if present 00276 messageTimer->stop(); 00277 00278 // set text to messageLabel 00279 m_titleWidget->setComment(msg, type); 00280 00281 // single shot the resetColors timer (and create it if null) 00282 if (timeOutMs > 0) { 00283 //kDebug(551) << "starting the message timer for " << timeOutMs; 00284 messageTimer->start(timeOutMs); 00285 } 00286 } 00287 00288 void DownloadDialog::installItem(Entry *entry) 00289 { 00290 // safety check 00291 // if ( item->url().isEmpty() || item->destinationPath().isEmpty() ) 00292 // { 00293 // displayMessage( i18n("I don't know how to install this. Sorry, my fault."), Info ); 00294 // return; 00295 // } 00296 00297 //TODO check for AvailableItem deletion! (avoid broken pointers) -> cancel old jobs 00298 slotEntryChanged(entry); 00299 } 00300 00301 void DownloadDialog::removeItem(Entry *entry) 00302 { 00303 Q_UNUSED(entry); 00304 // displayMessage( i18n("%1 is no more installed.").arg( item->name().representation() ) ); 00305 } 00306 00307 void DownloadDialog::slotResetMessage() // SLOT 00308 { 00309 m_titleWidget->setComment(QString()); 00310 } 00311 00312 void DownloadDialog::slotNetworkTimeout() // SLOT 00313 { 00314 displayMessage(i18n("Timeout. Check Internet connection."), KTitleWidget::ErrorMessage); 00315 } 00316 00317 void DownloadDialog::slotSortingSelected(int sortType) // SLOT 00318 { 00319 if (sortType >= 0) { 00320 //kDebug(551) << "sorting Selected, setting the sourcemodel for the view"; 00321 QString feedName = m_sortCombo->currentText(); 00322 QString feedType = m_sortCombo->itemData(sortType).toString(); 00323 00324 const Provider * currentProvider = m_entriesByProvider.keys()[m_sourceCombo->currentIndex()]; 00325 Feed * selectedFeed = currentProvider->downloadUrlFeed(feedType); 00326 m_filteredModel->setSourceModel(m_models.value(selectedFeed)); 00327 m_collaborationButton->setEnabled(false); 00328 } 00329 } 00330 00331 00333 00334 void DownloadDialog::slotLoadProviderDXS() 00335 { 00336 kDebug(551) << "slotLoadProviderDXS called"; 00337 //QString category = m_sourceCombo->currentText(); 00338 //QString categoryname = categorymap[category]; 00339 QString providerName = m_sourceCombo->currentText(); 00340 00341 QList<const Provider*> providers = m_entriesByProvider.keys(); 00342 const Provider * provider = 0; 00343 00344 for (int i = 0; i < providers.size(); ++i) { 00345 if (providers[i]->name().representation() == providerName) { 00346 provider = providers[i]; 00347 // update the sortCombo with this provider's feeds 00348 populateSortCombo(providers[i]); 00349 00350 Feed * selectedFeed = providers[i]->downloadUrlFeed(m_sortCombo->itemData(m_sortCombo->currentIndex()).toString()); 00351 m_filteredModel->setSourceModel(m_models.value(selectedFeed)); 00352 //m_list->setProvider(providers[i], 00353 // providers[i]->downloadUrlFeed(m_sortCombo->itemData(m_sortCombo->currentIndex()).toString())); 00354 break; 00355 } 00356 } 00357 m_hasDxs = (provider && m_engine->dxsObject(provider) != NULL); 00358 m_collaborationButton->setEnabled(m_hasDxs); 00359 } 00360 00361 void DownloadDialog::slotUpdateSearch() 00362 { 00363 m_searchTimer->stop(); 00364 m_filteredModel->setFilterFixedString(m_searchEdit->text()); 00365 m_filteredModel->invalidate(); 00366 } 00367 00368 void DownloadDialog::slotLoadProvidersListDXS() 00369 { 00370 } 00371 00372 void DownloadDialog::slotSearchTextChanged() 00373 { 00374 m_searchTimer->start(); 00375 } 00376 00377 void DownloadDialog::slotCategories(QList<KNS::Category*> categories) 00378 { 00379 categorymap.clear(); 00380 00381 for (QList<KNS::Category*>::Iterator it = categories.begin(); it != categories.end(); ++it) { 00382 KNS::Category *category = (*it); 00383 //kDebug(551) << "Category: " << category->name().representation(); 00384 QPixmap icon = DesktopIcon(category->icon().url(), 16); 00385 // FIXME: use icon from remote URLs (see non-DXS providers as well) 00386 m_sourceCombo->addItem(icon, category->name().representation()); 00387 categorymap[category->name().representation()] = category->id(); 00388 // FIXME: better use global id, since names are not guaranteed 00389 // to be unique 00390 } 00391 00392 //m_sourceCombo->setEnabled(true); 00393 00394 slotLoadProviderDXS(); 00395 } 00396 00397 void DownloadDialog::slotEntries(QList<KNS::Entry*> _entries) 00398 { 00399 Q_UNUSED(_entries); 00400 00401 //d->itemsView->setItems( entries ); 00402 // FIXME: old API here 00403 } 00404 00405 void DownloadDialog::slotEntriesFailed() 00406 { 00407 displayMessage(i18n("Entries failed to load")); 00408 } 00409 // FIXME: below here, those are for traditional GHNS 00410 00411 void DownloadDialog::slotEntryLoaded(Entry *entry, const Feed *feed, const Provider *provider) 00412 { 00413 Entry::List e = entries[feed]; 00414 e.append(entry); 00415 entries[feed] = e; 00416 00417 if (!m_entriesByProvider.contains(provider)) { 00418 kDebug(551) << "adding provider " << provider->name().representation() << " to combobox"; 00419 m_sourceCombo->addItem(provider->name().representation()); 00420 } 00421 m_entriesByProvider[provider].append(entry); 00422 00423 // FIXME: what if entry belongs to more than one provider at once? 00424 m_providers[entry] = provider; 00425 00426 mMutex.lock(); 00427 00428 if (!m_models.value(feed)) { 00429 // new feed 00430 kDebug(551) << "making a new model for this feed" << feed; 00431 m_models[feed] = new KNS::ItemsModel(this, provider->webService().isValid()); 00432 connect(m_engine, SIGNAL(signalEntryChanged(KNS::Entry*)), 00433 m_models[feed], SLOT(slotEntryChanged(KNS::Entry*))); 00434 if (provider->name().representation() == m_sourceCombo->currentText()) { 00435 // this provider is selected, so refresh the feed combobox 00436 populateSortCombo(provider); 00437 } 00438 } 00439 mMutex.unlock(); 00440 00441 KNS::ItemsModel* thisModel = m_models.value(feed); 00442 00443 Q_ASSERT(thisModel != NULL); 00444 thisModel->addEntry(entry); 00445 } 00446 00447 void DownloadDialog::slotEntryRemoved(KNS::Entry *entry, const KNS::Feed *feed) 00448 { 00449 Q_ASSERT(m_models[feed] != NULL); 00450 00451 m_models[feed]->removeEntry(entry); 00452 } 00453 00454 void DownloadDialog::refresh() 00455 { 00456 m_sourceCombo->clear(); 00457 00458 Q_ASSERT(m_entriesByProvider.keys().size() > 0); 00459 00460 for (int i = 0; i < m_entriesByProvider.keys().count(); i++) { 00461 const Provider *provider = m_entriesByProvider.keys().at(i); 00462 if (!provider) { 00463 //kDebug(551) << "INVALID FEED?!"; 00464 continue; 00465 } 00466 //QPixmap icon = DesktopIcon(QString(), 16); 00467 //d->m_typeCombo->addItem(icon, feed->name().representation()); 00468 m_sourceCombo->addItem(provider->name().representation()); 00469 // FIXME: see DXS categories 00470 } 00471 00472 slotLoadProviderDXS(); 00473 00475 //const Provider * selectedProvider = m_entriesByProvider.keys()[0]; 00476 00477 //populateSortCombo(selectedProvider); 00478 00479 //m_sourceCombo->setEnabled(true); 00480 //m_sortCombo->setEnabled(true); 00481 //m_searchEdit->setEnabled(true); 00482 } 00483 00484 void DownloadDialog::populateSortCombo(const Provider * provider) 00485 { 00486 QString url = provider->webAccess().pathOrUrl(); 00487 if (url.isEmpty()) { 00488 m_providerLinkLabel->hide(); 00489 } else { 00490 m_providerLinkLabel->setText(QString("<a href=\"%1\">?</a>").arg(url)); 00491 } 00492 00493 QStringList feeds = provider->feeds(); 00494 m_sortCombo->clear(); 00495 for (int i = 0; i < feeds.size(); ++i) { 00496 QString feedName = provider->downloadUrlFeed(feeds[i])->name().representation(); 00497 kDebug(551) << "adding feed " << feeds[i] << " to combobox"; 00498 m_sortCombo->addItem(feedName, feeds[i]); // put in the name for the text, and feeds[i] for the userData 00499 } 00500 } 00501 00502 void DownloadDialog::slotInfo(QString provider, QString server, QString version) 00503 { 00504 QString link = QString("<a href=\"%1\">%1</a>").arg(server); 00505 QString infostring = i18n("Server: %1", link); 00506 infostring += i18n("<br />Provider: %1", provider); 00507 infostring += i18n("<br />Version: %1", version); 00508 00509 KMessageBox::information(this, 00510 infostring, 00511 i18n("Provider information")); 00512 } 00513 00514 void DownloadDialog::slotComments(QStringList comments) 00515 { 00516 QPointer<KDXSComments> commentsdlg = new KDXSComments(this); 00517 00518 for (QStringList::const_iterator it = comments.constBegin(); it != comments.constEnd(); ++it) { 00519 //kDebug() << "Comment: " << (*it); 00520 commentsdlg->addComment("foo", (*it)); 00521 } 00522 00523 commentsdlg->exec(); 00524 delete commentsdlg; 00525 } 00526 00528 00529 void DownloadDialog::slotEntryChanged(KNS::Entry * entry) 00530 { 00531 Q_UNUSED(entry) 00532 setCursor(Qt::ArrowCursor); 00533 } 00534 00535 void DownloadDialog::slotPayloadFailed(KNS::Entry * entry) 00536 { 00537 setCursor(Qt::ArrowCursor); 00538 KMessageBox::error(this, i18n("Could not install %1", entry->name().representation()), 00539 i18n("Get Hot New Stuff!")); 00540 } 00541 00542 void DownloadDialog::slotPayloadLoaded(KUrl url) 00543 { 00544 Q_UNUSED(url) 00545 setCursor(Qt::ArrowCursor); 00546 } 00547 00548 void DownloadDialog::slotProgress(const QString & text, int percentage) 00549 { 00550 m_progress->addProgress(text, percentage); 00551 } 00552 00553 void DownloadDialog::slotProvidersFailed() 00554 { 00555 kDebug(551) << "slotProvidersFailed"; 00556 KMessageBox::error(this, 00557 i18n("There was an error loading data providers."), 00558 i18n("Get Hot New Stuff")); 00559 } 00560 00561 /*void DownloadDialog::slotItemMessage( KJob * job, const QString & message ) 00562 { 00563 AvailableItem * item = d->transferJobs[ job ].item; 00564 kDebug(551) << "Name: " << item->name().representation() << " msg: '" << message << "'."; 00565 d->itemsView->updateItem( item ); 00566 } 00567 00568 void DownloadDialog::slotItemPercentage( KJob * job, unsigned long percent ) 00569 { 00570 AvailableItem * item = d->transferJobs[ job ].item; 00571 item->setProgress( (float)percent / 100.0 ); 00572 d->itemsView->updateItem( item ); 00573 } 00574 00575 void DownloadDialog::slotItemResult( KJob * job ) 00576 { 00577 item->setState( AvailableItem::Normal ); 00578 item->setProgress( 100.0 ); 00579 d->itemsView->updateItem( item ); 00580 00581 }*/ 00582 //END File(s) Transferring 00583 00584 // fault/error from kdxsbutton 00585 void DownloadDialog::slotFault() 00586 { 00587 KMessageBox::error(this, 00588 i18n("A protocol fault has occurred. The request has failed."), 00589 i18n("Desktop Exchange Service")); 00590 } 00591 00592 void DownloadDialog::slotError() 00593 { 00594 KMessageBox::error(this, 00595 i18n("A network error has occurred. The request has failed."), 00596 i18n("Desktop Exchange Service")); 00597 } 00598 00599 #include "downloaddialog.moc"
KDE 4.6 API Reference