KNewStuff
downloadwidget.cpp
Go to the documentation of this file.
00001 /* 00002 knewstuff3/ui/downloaddialog.cpp. 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-2009 Jeremy Whiting <jpwhiting@kde.org> 00007 Copyright (C) 2009-2010 Frederik Gladhorn <gladhorn@kde.org> 00008 Copyright (C) 2010 Reza Fatahilah Shah <rshah0385@kireihana.com> 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Lesser General Public 00012 License as published by the Free Software Foundation; either 00013 version 2.1 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this library. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 00024 #include "downloadwidget.h" 00025 #include "downloadwidget_p.h" 00026 00027 #include <QtCore/QTimer> 00028 #include <QtGui/QScrollBar> 00029 #include <QtGui/QKeyEvent> 00030 00031 #include <kmessagebox.h> 00032 #include <kcomponentdata.h> 00033 #include <kaboutdata.h> 00034 #include <kdebug.h> 00035 00036 #include "ui/itemsmodel.h" 00037 #include "ui/itemsviewdelegate.h" 00038 #include "ui/itemsgridviewdelegate.h" 00039 00040 using namespace KNS3; 00041 00042 DownloadWidget::DownloadWidget(QWidget* parent) 00043 : QWidget(parent) 00044 , d(new DownloadWidgetPrivate(this)) 00045 { 00046 KComponentData component = KGlobal::activeComponent(); 00047 QString name = component.componentName(); 00048 init(name + ".knsrc"); 00049 } 00050 00051 DownloadWidget::DownloadWidget(const QString& configFile, QWidget * parent) 00052 : QWidget(parent) 00053 , d(new DownloadWidgetPrivate(this)) 00054 { 00055 init(configFile); 00056 } 00057 00058 void DownloadWidget::init(const QString& configFile) 00059 { 00060 d->init(configFile); 00061 } 00062 00063 DownloadWidget::~DownloadWidget() 00064 { 00065 delete d; 00066 } 00067 00068 Entry::List DownloadWidget::changedEntries() 00069 { 00070 Entry::List entries; 00071 foreach (const EntryInternal &e, d->changedEntries) { 00072 entries.append(e.toEntry()); 00073 } 00074 return entries; 00075 } 00076 00077 Entry::List DownloadWidget::installedEntries() 00078 { 00079 Entry::List entries; 00080 foreach (const EntryInternal &e, d->changedEntries) { 00081 if (e.status() == Entry::Installed) { 00082 entries.append(e.toEntry()); 00083 } 00084 } 00085 return entries; 00086 } 00087 00088 00089 DownloadWidgetPrivate::DownloadWidgetPrivate(DownloadWidget* q) 00090 : q(q) 00091 , engine(new Engine) 00092 , model(new ItemsModel(engine)) 00093 , messageTimer(0) 00094 , dialogMode(false) 00095 { 00096 } 00097 00098 DownloadWidgetPrivate::~DownloadWidgetPrivate() 00099 { 00100 delete messageTimer; 00101 delete delegate; 00102 delete model; 00103 delete engine; 00104 } 00105 00106 void DownloadWidgetPrivate::slotResetMessage() // SLOT 00107 { 00108 ui.m_titleWidget->setComment(QString()); 00109 } 00110 00111 void DownloadWidgetPrivate::slotNetworkTimeout() // SLOT 00112 { 00113 displayMessage(i18n("Timeout. Check Internet connection."), KTitleWidget::ErrorMessage); 00114 } 00115 00116 void DownloadWidgetPrivate::sortingChanged() 00117 { 00118 Provider::SortMode sortMode = Provider::Newest; 00119 if (ui.ratingRadio->isChecked()) { 00120 sortMode = Provider::Rating; 00121 } else if (ui.mostDownloadsRadio->isChecked()) { 00122 sortMode = Provider::Downloads; 00123 } else if (ui.installedRadio->isChecked()) { 00124 sortMode = Provider::Installed; 00125 } 00126 00127 model->clearEntries(); 00128 if (sortMode == Provider::Installed) { 00129 ui.m_searchEdit->clear(); 00130 } 00131 ui.m_searchEdit->setEnabled(sortMode != Provider::Installed); 00132 00133 engine->setSortMode(sortMode); 00134 } 00135 00136 void DownloadWidgetPrivate::slotUpdateSearch() 00137 { 00138 if (searchTerm == ui.m_searchEdit->text().trimmed()) { 00139 return; 00140 } 00141 searchTerm = ui.m_searchEdit->text().trimmed(); 00142 } 00143 00144 void DownloadWidgetPrivate::slotSearchTextChanged() 00145 { 00146 if (searchTerm == ui.m_searchEdit->text().trimmed()) { 00147 return; 00148 } 00149 searchTerm = ui.m_searchEdit->text().trimmed(); 00150 engine->setSearchTerm(ui.m_searchEdit->text().trimmed()); 00151 } 00152 00153 void DownloadWidgetPrivate::slotCategoryChanged(int idx) 00154 { 00155 if (idx == 0) { 00156 // All Categories item selected, reset filter 00157 engine->setCategoriesFilter(QStringList()); 00158 00159 } else { 00160 QString category = ui.m_categoryCombo->currentText(); 00161 if (!category.isEmpty()) { 00162 QStringList filter(category); 00163 engine->setCategoriesFilter(filter); 00164 } 00165 } 00166 } 00167 00168 void DownloadWidgetPrivate::slotInfo(QString provider, QString server, QString version) 00169 { 00170 QString link = QString("<a href=\"%1\">%1</a>").arg(server); 00171 QString infostring = i18n("Server: %1", link); 00172 infostring += i18n("<br />Provider: %1", provider); 00173 infostring += i18n("<br />Version: %1", version); 00174 00175 KMessageBox::information(0, 00176 infostring, 00177 i18n("Provider information")); 00178 } 00179 00180 void DownloadWidgetPrivate::slotEntryChanged(const EntryInternal& entry) 00181 { 00182 changedEntries.insert(entry); 00183 model->slotEntryChanged(entry); 00184 } 00185 00186 void DownloadWidgetPrivate::slotPayloadFailed(const EntryInternal& entry) 00187 { 00188 KMessageBox::error(0, i18n("Could not install %1", entry.name()), 00189 i18n("Get Hot New Stuff!")); 00190 } 00191 00192 void DownloadWidgetPrivate::slotPayloadLoaded(KUrl url) 00193 { 00194 Q_UNUSED(url) 00195 } 00196 00197 void DownloadWidgetPrivate::slotError(const QString& message) 00198 { 00199 KMessageBox::error(0, message, i18n("Get Hot New Stuff")); 00200 } 00201 00202 void DownloadWidgetPrivate::scrollbarValueChanged(int value) 00203 { 00204 if ((double)value/ui.m_listView->verticalScrollBar()->maximum() > 0.9) { 00205 engine->requestMoreData(); 00206 } 00207 } 00208 00209 void DownloadWidgetPrivate::init(const QString& configFile) 00210 { 00211 m_configFile = configFile; 00212 ui.setupUi(q); 00213 ui.m_titleWidget->setVisible(false); 00214 ui.closeButton->setVisible(dialogMode); 00215 ui.backButton->setVisible(false); 00216 ui.backButton->setGuiItem(KStandardGuiItem::Back); 00217 q->connect(ui.backButton, SIGNAL(clicked()), q, SLOT(slotShowOverview())); 00218 00219 q->connect(engine, SIGNAL(signalBusy(const QString&)), ui.progressIndicator, SLOT(busy(const QString&))); 00220 q->connect(engine, SIGNAL(signalError(const QString&)), ui.progressIndicator, SLOT(error(const QString&))); 00221 q->connect(engine, SIGNAL(signalIdle(const QString&)), ui.progressIndicator, SLOT(idle(const QString&))); 00222 00223 q->connect(engine, SIGNAL(signalProvidersLoaded()), q, SLOT(slotProvidersLoaded())); 00224 // Entries have been fetched and should be shown: 00225 q->connect(engine, SIGNAL(signalEntriesLoaded(KNS3::EntryInternal::List)), q, SLOT(slotEntriesLoaded(KNS3::EntryInternal::List))); 00226 00227 // An entry has changes - eg because it was installed 00228 q->connect(engine, SIGNAL(signalEntryChanged(KNS3::EntryInternal)), q, SLOT(slotEntryChanged(KNS3::EntryInternal))); 00229 00230 q->connect(engine, SIGNAL(signalResetView()), model, SLOT(clearEntries())); 00231 q->connect(engine, SIGNAL(signalEntryPreviewLoaded(KNS3::EntryInternal,KNS3::EntryInternal::PreviewType)), 00232 model, SLOT(slotEntryPreviewLoaded(KNS3::EntryInternal,KNS3::EntryInternal::PreviewType))); 00233 00234 engine->init(configFile); 00235 00236 delegate = new ItemsViewDelegate(ui.m_listView, engine, q); 00237 ui.m_listView->setItemDelegate(delegate); 00238 ui.m_listView->setModel(model); 00239 00240 ui.iconViewButton->setIcon(KIcon("view-list-icons")); 00241 ui.iconViewButton->setToolTip(i18n("Icons view mode")); 00242 ui.listViewButton->setIcon(KIcon("view-list-details")); 00243 ui.listViewButton->setToolTip(i18n("Details view mode")); 00244 00245 q->connect(ui.listViewButton, SIGNAL(clicked()), q, SLOT(slotListViewListMode())); 00246 q->connect(ui.iconViewButton, SIGNAL(clicked()), q, SLOT(slotListViewIconMode())); 00247 00248 q->connect(ui.newestRadio, SIGNAL(clicked()), q, SLOT(sortingChanged())); 00249 q->connect(ui.ratingRadio, SIGNAL(clicked()), q, SLOT(sortingChanged())); 00250 q->connect(ui.mostDownloadsRadio, SIGNAL(clicked()), q, SLOT(sortingChanged())); 00251 q->connect(ui.installedRadio, SIGNAL(clicked()), q, SLOT(sortingChanged())); 00252 00253 q->connect(ui.m_searchEdit, SIGNAL(textChanged(const QString &)), q, SLOT(slotSearchTextChanged())); 00254 q->connect(ui.m_searchEdit, SIGNAL(editingFinished()), q, SLOT(slotUpdateSearch())); 00255 00256 ui.m_providerLabel->setVisible(false); 00257 ui.m_providerCombo->setVisible(false); 00258 ui.m_providerCombo->addItem(i18n("All Providers")); 00259 00260 QStringList categories = engine->categories(); 00261 if (categories.size() < 2) { 00262 ui.m_categoryLabel->setVisible(false); 00263 ui.m_categoryCombo->setVisible(false); 00264 } else { 00265 ui.m_categoryCombo->addItem(i18n("All Categories")); 00266 foreach(const QString& category, categories) { 00267 ui.m_categoryCombo->addItem(category); 00268 } 00269 } 00270 00271 ui.detailsStack->widget(0)->layout()->setMargin(0); 00272 ui.detailsStack->widget(1)->layout()->setMargin(0); 00273 00274 q->connect(ui.m_categoryCombo, SIGNAL(activated(int)), q, SLOT(slotCategoryChanged(int))); 00275 00276 // let the search line edit trap the enter key, otherwise it closes the dialog 00277 ui.m_searchEdit->setTrapReturnKey(true); 00278 00279 q->connect(ui.m_listView->verticalScrollBar(), SIGNAL(valueChanged(int)), q, SLOT(scrollbarValueChanged(int))); 00280 q->connect(ui.m_listView, SIGNAL(doubleClicked(QModelIndex)), delegate, SLOT(slotDetailsClicked(QModelIndex))); 00281 00282 details = new EntryDetails(engine, &ui); 00283 q->connect(delegate, SIGNAL(signalShowDetails(KNS3::EntryInternal)), q, SLOT(slotShowDetails(KNS3::EntryInternal))); 00284 00285 slotShowOverview(); 00286 } 00287 00288 void DownloadWidgetPrivate::slotListViewListMode() 00289 { 00290 ui.listViewButton->setChecked(true); 00291 ui.iconViewButton->setChecked(false); 00292 setListViewMode(QListView::ListMode); 00293 } 00294 00295 void DownloadWidgetPrivate::slotListViewIconMode() 00296 { 00297 ui.listViewButton->setChecked(false); 00298 ui.iconViewButton->setChecked(true); 00299 setListViewMode(QListView::IconMode); 00300 } 00301 00302 void DownloadWidgetPrivate::setListViewMode(QListView::ViewMode mode) 00303 { 00304 if (ui.m_listView->viewMode() == mode) { 00305 return; 00306 } 00307 00308 ItemsViewBaseDelegate* oldDelegate = delegate; 00309 if (mode == QListView::ListMode) { 00310 delegate = new ItemsViewDelegate(ui.m_listView, engine, q); 00311 ui.m_listView->setViewMode(QListView::ListMode); 00312 ui.m_listView->setResizeMode(QListView::Fixed); 00313 } else { 00314 delegate = new ItemsGridViewDelegate(ui.m_listView, engine, q); 00315 ui.m_listView->setViewMode(QListView::IconMode); 00316 ui.m_listView->setResizeMode(QListView::Adjust); 00317 } 00318 ui.m_listView->setItemDelegate(delegate); 00319 delete oldDelegate; 00320 00321 q->connect(ui.m_listView, SIGNAL(doubleClicked(QModelIndex)), delegate, SLOT(slotDetailsClicked(QModelIndex))); 00322 q->connect(delegate, SIGNAL(signalShowDetails(KNS3::EntryInternal)), q, SLOT(slotShowDetails(KNS3::EntryInternal))); 00323 } 00324 00325 void DownloadWidgetPrivate::slotProvidersLoaded() 00326 { 00327 kDebug() << "providers loaded"; 00328 engine->reloadEntries(); 00329 } 00330 00331 void DownloadWidgetPrivate::slotEntriesLoaded(const EntryInternal::List& entries) 00332 { 00333 foreach(const KNS3::EntryInternal &entry, entries) { 00334 if (!categories.contains(entry.category())) { 00335 kDebug() << "Found category: " << entry.category(); 00336 categories.insert(entry.category()); 00337 } 00338 } 00339 model->slotEntriesLoaded(entries); 00340 } 00341 00342 void DownloadWidgetPrivate::displayMessage(const QString & msg, KTitleWidget::MessageType type, int timeOutMs) 00343 { 00344 if (!messageTimer) { 00345 messageTimer = new QTimer; 00346 messageTimer->setSingleShot(true); 00347 q->connect(messageTimer, SIGNAL(timeout()), q, SLOT(slotResetMessage())); 00348 } 00349 // stop the pending timer if present 00350 messageTimer->stop(); 00351 00352 // set text to messageLabel 00353 ui.m_titleWidget->setComment(msg, type); 00354 00355 // single shot the resetColors timer (and create it if null) 00356 if (timeOutMs > 0) { 00357 //kDebug(551) << "starting the message timer for " << timeOutMs; 00358 messageTimer->start(timeOutMs); 00359 } 00360 } 00361 00362 void DownloadWidgetPrivate::slotShowDetails(const KNS3::EntryInternal& entry) 00363 { 00364 if (!entry.isValid()) { 00365 kDebug() << "invalid entry"; 00366 return; 00367 } 00368 titleText = ui.m_titleWidget->text(); 00369 00370 ui.backButton->setVisible(true); 00371 ui.detailsStack->setCurrentIndex(1); 00372 ui.descriptionScrollArea->verticalScrollBar()->setValue(0); 00373 ui.preview1->setImage(QImage()); 00374 ui.preview2->setImage(QImage()); 00375 ui.preview3->setImage(QImage()); 00376 ui.previewBig->setImage(QImage()); 00377 details->setEntry(entry); 00378 } 00379 00380 void DownloadWidgetPrivate::slotShowOverview() 00381 { 00382 ui.backButton->setVisible(false); 00383 00384 ui.updateButton->setVisible(false); 00385 ui.installButton->setVisible(false); 00386 ui.becomeFanButton->setVisible(false); 00387 ui.uninstallButton->setVisible(false); 00388 00389 ui.detailsStack->setCurrentIndex(0); 00390 ui.m_titleWidget->setText(titleText); 00391 } 00392 00393 00394 #include "downloadwidget.moc"
KDE 4.6 API Reference