KNewStuff
engine.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "knewstuff2/engine.h"
00020
00021 #include "knewstuff2/ui/downloaddialog.h"
00022 #include "knewstuff2/ui/uploaddialog.h"
00023 #include "knewstuff2/ui/providerdialog.h"
00024
00025 #include "knewstuff2/core/entryhandler.h"
00026
00027 #include <kcomponentdata.h>
00028 #include <kdebug.h>
00029 #include <kglobal.h>
00030 #include <kwindowsystem.h>
00031
00032 #include <qeventloop.h>
00033
00034 using namespace KNS;
00035
00036 class KNS::EnginePrivate : public DxsEngine
00037 {
00038 Q_OBJECT
00039
00040 public:
00041 EnginePrivate(QWidget* parent)
00042 : DxsEngine(parent) {
00043 m_command = EnginePrivate::command_none;
00044 m_uploaddialog = NULL;
00045 m_downloaddialog = NULL;
00046 m_uploadedEntry = NULL;
00047 m_modal = false;
00048 m_parent = parent;
00049 m_loop = 0;
00050 }
00051
00052 enum Command {
00053 command_none,
00054 command_upload,
00055 command_download
00056 };
00057
00058 void workflow();
00059 KNS::Entry* upload(const QString& file);
00060
00061 static QHash<QString, KDialog *> s_dialogs;
00062
00063 Command m_command;
00064 UploadDialog *m_uploaddialog;
00065 DownloadDialog *m_downloaddialog;
00066 QString m_uploadfile;
00067 KNS::Entry *m_uploadedEntry;
00068 KNS::Provider::List m_providers;
00069 bool m_modal;
00070 QWidget * m_parent;
00071 QSet<KNS::Entry*> m_changedEntries;
00072 QEventLoop* m_loop;
00073
00074 private Q_SLOTS:
00076 void stopLoop();
00077
00078 void slotProviderLoaded(KNS::Provider *provider);
00079
00082 void slotEntryChanged(KNS::Entry *entry);
00083
00084 void slotProvidersFinished();
00085 void slotEntriesFinished();
00086
00087 void slotDownloadDialogClosed();
00088 };
00089
00090
00091 QHash<QString, KDialog *> KNS::EnginePrivate::s_dialogs;
00092
00093 Engine::Engine(QWidget* parent)
00094 : d(new EnginePrivate(parent))
00095 {
00096 }
00097
00098 Engine::~Engine()
00099 {
00100 delete d;
00101 }
00102
00103 void EnginePrivate::workflow()
00104 {
00105 if ((m_command == command_upload) || (m_command == command_download)) {
00106 connect(this,
00107 SIGNAL(signalProviderLoaded(KNS::Provider*)),
00108 SLOT(slotProviderLoaded(KNS::Provider*)));
00109 }
00110
00111 if (m_command == command_upload) {
00112 connect(this,
00113 SIGNAL(signalProvidersFinished()),
00114 SLOT(slotProvidersFinished()));
00115 connect(this,
00116 SIGNAL(signalProvidersFailed()),
00117 SLOT(stopLoop()));
00118
00119 m_uploadedEntry = NULL;
00120 }
00121
00122 if (m_command == command_download) {
00123 m_downloaddialog = new DownloadDialog(this, m_parent);
00124 s_dialogs.insert(componentName(), m_downloaddialog);
00125
00126 connect(this, SIGNAL(signalEntriesFinished()),
00127 SLOT(slotEntriesFinished()));
00128 connect(this,
00129 SIGNAL(signalEntryChanged(KNS::Entry *)),
00130 SLOT(slotEntryChanged(KNS::Entry *)));
00131 connect(this,
00132 SIGNAL(signalProvidersFailed()),
00133 SLOT(slotDownloadDialogClosed()));
00134
00135 m_downloaddialog->show();
00136
00137 connect(m_downloaddialog, SIGNAL(finished()), SLOT(slotDownloadDialogClosed()));
00138 }
00139
00140 start();
00141
00142 if (m_modal) {
00143 QEventLoop loop;
00144 m_loop = &loop;
00145 loop.exec();
00146 }
00147 }
00148
00149 void EnginePrivate::stopLoop()
00150 {
00151 m_command = command_none;
00152
00153 if (m_loop) {
00154 m_loop->exit();
00155 m_loop = 0;
00156 }
00157 }
00158
00159 KNS::Entry::List Engine::download()
00160 {
00161 KNS::Entry::List entries;
00162
00163 Engine *engine = new Engine(0);
00164
00165 KComponentData component = KGlobal::activeComponent();
00166 QString name = component.componentName();
00167
00168 bool ret = engine->init(name + ".knsrc");
00169 if (!ret) {
00170 delete engine;
00171 return entries;
00172 }
00173
00174 KNS::Entry::List tempList = engine->downloadDialogModal(0);
00175
00176
00177 foreach(Entry * entry, tempList) {
00178 entries << new Entry(*entry);
00179 }
00180 delete engine;
00181
00182 return entries;
00183 }
00184
00185 KNS::Entry::List Engine::downloadDialogModal(QWidget*)
00186 {
00187
00188 KDialog *existingDialog = EnginePrivate::s_dialogs.value(d->componentName());
00189 if (existingDialog) {
00190 existingDialog->show();
00191 KWindowSystem::setOnDesktop(existingDialog->winId(), KWindowSystem::currentDesktop());
00192 KWindowSystem::activateWindow(existingDialog->winId());
00193 return QList<KNS::Entry*>();
00194 }
00195
00196 d->m_command = EnginePrivate::command_download;
00197 d->m_modal = true;
00198
00199 d->workflow();
00200
00201 return QList<KNS::Entry*>::fromSet(d->m_changedEntries);
00202 }
00203
00204 void Engine::downloadDialog()
00205 {
00206
00207 KDialog *existingDialog = EnginePrivate::s_dialogs.value(d->componentName());
00208 if (existingDialog) {
00209 existingDialog->show();
00210 KWindowSystem::setOnDesktop(existingDialog->winId(), KWindowSystem::currentDesktop());
00211 KWindowSystem::activateWindow(existingDialog->winId());
00212 return;
00213 }
00214
00215
00216 if (d->m_command != EnginePrivate::command_none) {
00217 kError() << "Engine: asynchronous workflow already going on" << endl;
00218 return;
00219 }
00220
00221 d->m_command = EnginePrivate::command_download;
00222 d->m_modal = false;
00223
00224 d->workflow();
00225 }
00226
00227 void Engine::downloadDialog(QObject * receiver, const char * slot)
00228 {
00229 QObject::connect(d, SIGNAL(signalDownloadDialogDone(KNS::Entry::List)), receiver, slot);
00230 downloadDialog();
00231 }
00232
00233 KNS::Entry *EnginePrivate::upload(const QString& file)
00234 {
00235 KNS::Entry *entry = NULL;
00236
00237 Engine engine(0);
00238
00239 KComponentData component = KGlobal::activeComponent();
00240 QString name = component.componentName();
00241
00242 bool ret = engine.init(name + ".knsrc");
00243 if (!ret) return entry;
00244
00245 entry = engine.uploadDialogModal(file);
00246
00247
00248 return entry;
00249 }
00250
00251 bool Engine::init(const QString& config)
00252 {
00253 return d->init(config);
00254 }
00255
00256
00257 KNS::Entry *Engine::upload(const QString& file)
00258 {
00259 #ifdef __GNUC__
00260 #warning KNS::Engine::upload() not implemented!
00261 #endif
00262 #if 0
00263 return d->upload(file);
00264 #else
00265 Q_UNUSED(file);
00266 #endif
00267 Q_ASSERT(false);
00268 return 0;
00269 }
00270
00271 KNS::Entry *Engine::uploadDialogModal(const QString& file)
00272 {
00273
00274
00275 d->m_command = EnginePrivate::command_upload;
00276 d->m_modal = true;
00277 d->m_uploadfile = file;
00278
00279 d->workflow();
00280
00281 return d->m_uploadedEntry;
00282 }
00283
00284 void Engine::uploadDialog(const QString& file)
00285 {
00286
00287
00288 if (d->m_command != EnginePrivate::command_none) {
00289 kError() << "Engine: asynchronous workflow already going on" << endl;
00290 return;
00291 }
00292
00293 d->m_command = EnginePrivate::command_upload;
00294 d->m_modal = false;
00295 d->m_uploadfile = file;
00296
00297 d->workflow();
00298 }
00299
00300 void EnginePrivate::slotProviderLoaded(KNS::Provider *provider)
00301 {
00302 if (m_command == command_download) {
00303 loadEntries(provider);
00304 } else if (m_command == command_upload) {
00305
00306
00307
00308
00309
00310 m_providers.append(provider);
00311 } else {
00312 kError() << "Engine: invalid command" << endl;
00313 }
00314 }
00315
00316 void EnginePrivate::slotProvidersFinished()
00317 {
00318
00319
00320
00321 int ret;
00322
00323
00324
00325
00326
00327
00328 QPointer<ProviderDialog> provdialog = new ProviderDialog(NULL);
00329 for (Provider::List::Iterator it = m_providers.begin(); it != m_providers.end(); ++it) {
00330 Provider *provider = (*it);
00331 provdialog->addProvider(provider);
00332 }
00333
00334 ret = provdialog->exec();
00335 if (ret == QDialog::Rejected) {
00336 stopLoop();
00337 return;
00338 }
00339
00340 KNS::Provider *provider = provdialog->provider();
00341
00342 QPointer<UploadDialog> uploaddialog = new UploadDialog(NULL);
00343 uploaddialog->setPayloadFile(KUrl(m_uploadfile));
00344 ret = uploaddialog->exec();
00345 if (ret == QDialog::Rejected) {
00346 stopLoop();
00347 return;
00348 }
00349
00350 Entry *entry = uploaddialog->entry();
00351 entry->setPayload(m_uploadfile);
00352 if (!entry) {
00353 stopLoop();
00354 return;
00355 }
00356
00357 EntryHandler eh(*entry);
00358 QDomElement xml = eh.entryXML();
00359 QByteArray ar;
00360 QTextStream txt(&ar);
00361 txt << xml;
00362
00363
00364 connect(this,
00365 SIGNAL(signalEntryUploaded()),
00366 SLOT(stopLoop()));
00367 connect(this,
00368 SIGNAL(signalEntryFailed()),
00369 SLOT(stopLoop()));
00370
00371 uploadEntry(provider, entry);
00372 }
00373
00374 void EnginePrivate::slotEntryChanged(KNS::Entry * entry)
00375 {
00376
00377 m_changedEntries << entry;
00378 }
00379
00380
00381 void EnginePrivate::slotEntriesFinished()
00382 {
00383
00384 }
00385
00386 void EnginePrivate::slotDownloadDialogClosed()
00387 {
00388 QHash<QString, KDialog *>::iterator it = s_dialogs.begin();
00389 while (it != s_dialogs.end()) {
00390 if (it.value() == m_downloaddialog) {
00391 it = s_dialogs.erase(it);
00392 }
00393
00394 if (it != s_dialogs.end()) {
00395 ++it;
00396 }
00397 }
00398
00399 m_downloaddialog->deleteLater();
00400 m_downloaddialog = NULL;
00401
00402 stopLoop();
00403 emit signalDownloadDialogDone(QList<KNS::Entry*>::fromSet(m_changedEntries));
00404 }
00405
00406 #include "engine.moc"