• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KNewStuff

engine.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of KNewStuff2.
00003     Copyright (c) 2008 Jeremy Whiting <jpwhiting@kde.org>
00004     Copyright (c) 2007 Josef Spillner <spillner@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2.1 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public
00017     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
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" // tmp
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, QPointer<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 public Q_SLOTS:
00075     void slotDownloadDialogDestroyed();
00076 
00077 private Q_SLOTS:
00079     void stopLoop();
00080 
00081     void slotProviderLoaded(KNS::Provider *provider);
00082 
00085     void slotEntryChanged(KNS::Entry *entry);
00086 
00087     void slotHandleUpload();
00088     void slotEntriesFinished();
00089 
00090     void slotDownloadDialogClosed();
00091 };
00092 
00093 
00094 QHash<QString, QPointer<KDialog> > KNS::EnginePrivate::s_dialogs;
00095 
00096 Engine::Engine(QWidget* parent)
00097         : d(new EnginePrivate(parent))
00098 {
00099 }
00100 
00101 Engine::~Engine()
00102 {
00103     //kDebug() << d->m_downloaddialog;
00104     if (d->m_downloaddialog) {
00105         d->slotDownloadDialogDestroyed();
00106     }
00107 
00108     delete d;
00109 }
00110 
00111 void EnginePrivate::workflow()
00112 {
00113     disconnect(this, 0, this, 0);
00114     if ((m_command == command_upload) || (m_command == command_download)) {
00115         connect(this,
00116                 SIGNAL(signalProviderLoaded(KNS::Provider*)),
00117                 SLOT(slotProviderLoaded(KNS::Provider*)));
00118     }
00119 
00120     if (m_command == command_upload) {
00121         connect(this,
00122                 SIGNAL(signalProvidersFinished()),
00123                 SLOT(slotHandleUpload()));
00124         connect(this,
00125                 SIGNAL(signalProvidersFailed()),
00126                 SLOT(stopLoop()));
00127 
00128         m_uploadedEntry = NULL;
00129     }
00130 
00131     if (m_command == command_download) {
00132         m_downloaddialog = new DownloadDialog(this, m_parent);
00133         //kDebug() << "adding!";
00134         s_dialogs.insert(componentName(), m_downloaddialog);
00135 
00136         connect(this, SIGNAL(signalEntriesFinished()),
00137                 SLOT(slotEntriesFinished()));
00138         connect(this,
00139                 SIGNAL(signalEntryChanged(KNS::Entry *)),
00140                 SLOT(slotEntryChanged(KNS::Entry *)));
00141         connect(this,
00142                 SIGNAL(signalProvidersFailed()),
00143                 SLOT(slotDownloadDialogClosed()));
00144         connect(m_downloaddialog,
00145                 SIGNAL(destroyed(QObject*)),
00146                 SLOT(slotDownloadDialogDestroyed()));
00147         connect(m_downloaddialog, SIGNAL(finished()), SLOT(slotDownloadDialogClosed()));
00148         //kDebug() << "done adding!";
00149 
00150         m_downloaddialog->show();
00151     }
00152 
00153     start();
00154 
00155     if (m_modal) {
00156         QEventLoop loop;
00157         m_loop = &loop;
00158         loop.exec();
00159     }
00160 }
00161 
00162 void EnginePrivate::stopLoop()
00163 {
00164     m_command = command_none;
00165 
00166     if (m_loop) {
00167         m_loop->exit();
00168         m_loop = 0;
00169 
00170         if (m_downloaddialog) {
00171             slotDownloadDialogDestroyed();
00172         }
00173     }
00174 }
00175 
00176 KNS::Entry::List Engine::download()
00177 {
00178     KNS::Entry::List entries;
00179 
00180     Engine *engine = new Engine(0);
00181 
00182     KComponentData component = KGlobal::activeComponent();
00183     QString name = component.componentName();
00184 
00185     bool ret = engine->init(name + ".knsrc");
00186     if (!ret) {
00187         delete engine;
00188         return entries;
00189     }
00190 
00191     KNS::Entry::List tempList = engine->downloadDialogModal(0);
00192 
00193     // copy the list since the entries will be deleted when we delete the engine
00194     foreach(Entry * entry, tempList) {
00195         entries << new Entry(*entry);
00196     }
00197     delete engine;
00198 
00199     return entries;
00200 }
00201 
00202 KNS::Entry::List Engine::downloadDialogModal(QWidget* parent)
00203 {
00204     //kDebug() << "Engine: downloadDialogModal";
00205     KDialog *existingDialog = EnginePrivate::s_dialogs.value(d->componentName());
00206     if (existingDialog) {
00207         existingDialog->show();
00208         KWindowSystem::setOnDesktop(existingDialog->winId(), KWindowSystem::currentDesktop());
00209         KWindowSystem::activateWindow(existingDialog->winId());
00210         return QList<KNS::Entry*>();
00211     }
00212 
00213     d->m_command = EnginePrivate::command_download;
00214     d->m_modal = true;
00215     if (parent) {
00216         d->m_parent = parent;
00217     }
00218 
00219     d->workflow();
00220 
00221     return QList<KNS::Entry*>::fromSet(d->m_changedEntries);
00222 }
00223 
00224 void Engine::downloadDialog()
00225 {
00226     //kDebug() << "Engine: downloadDialog";
00227     KDialog *existingDialog = EnginePrivate::s_dialogs.value(d->componentName());
00228     if (existingDialog) {
00229         //kDebug() << "got an existing dialog";
00230         existingDialog->show();
00231         KWindowSystem::setOnDesktop(existingDialog->winId(), KWindowSystem::currentDesktop());
00232         KWindowSystem::activateWindow(existingDialog->winId());
00233         return;
00234     }
00235 
00236     if (d->m_command != EnginePrivate::command_none) {
00237         kError() << "Engine: asynchronous workflow already going on" << endl;
00238         return;
00239     }
00240 
00241     d->m_command = EnginePrivate::command_download;
00242     d->m_modal = false;
00243 
00244     d->workflow();
00245 }
00246 
00247 void Engine::downloadDialog(QObject * receiver, const char * slot)
00248 {
00249     QObject::disconnect(d, SIGNAL(signalDownloadDialogDone(KNS::Entry::List)), receiver, slot);
00250     QObject::connect(d, SIGNAL(signalDownloadDialogDone(KNS::Entry::List)), receiver, slot);
00251     downloadDialog();
00252 }
00253 
00254 KNS::Entry *EnginePrivate::upload(const QString& file)
00255 {
00256     KNS::Entry *entry = NULL;
00257 
00258     Engine engine(0);
00259 
00260     KComponentData component = KGlobal::activeComponent();
00261     QString name = component.componentName();
00262 
00263     bool ret = engine.init(name + ".knsrc");
00264     if (!ret) return entry;
00265 
00266     entry = engine.uploadDialogModal(file);
00267 
00268     // FIXME: refcounting?
00269     return entry;
00270 }
00271 
00272 bool Engine::init(const QString& config)
00273 {
00274     return d->init(config);
00275 }
00276 
00277 
00278 KNS::Entry *Engine::upload(const QString& file)
00279 {
00280 #ifdef __GNUC__
00281 #warning KNS::Engine::upload() not implemented!
00282 #endif
00283 #if 0
00284     return d->upload(file);
00285 #else
00286     Q_UNUSED(file);
00287 #endif
00288     Q_ASSERT(false);
00289     return 0;
00290 }
00291 
00292 KNS::Entry *Engine::uploadDialogModal(const QString& file)
00293 {
00294     //kDebug() << "Engine: uploadDialogModal";
00295 
00296     d->m_command = EnginePrivate::command_upload;
00297     d->m_modal = true;
00298     d->m_uploadfile = file;
00299 
00300     d->workflow();
00301 
00302     return d->m_uploadedEntry;
00303 }
00304 
00305 void Engine::uploadDialog(const QString& file)
00306 {
00307     //kDebug() << "Engine: uploadDialog";
00308 
00309     if (d->m_command != EnginePrivate::command_none) {
00310         kError() << "Engine: asynchronous workflow already going on" << endl;
00311         return;
00312     }
00313 
00314     d->m_command = EnginePrivate::command_upload;
00315     d->m_modal = false;
00316     d->m_uploadfile = file;
00317 
00318     d->workflow();
00319 }
00320 
00321 void EnginePrivate::slotProviderLoaded(KNS::Provider *provider)
00322 {
00323     if (m_command == command_download) {
00324         loadEntries(provider);
00325     } else if (m_command == command_upload) {
00326         // FIXME: inject into upload dialog
00327         // FIXME: dialog could do this by itself!
00328 
00329         // FIXME: for the modal dialog, do nothing here
00330         // ... and wait for slotProvidersFinished()
00331         m_providers.append(provider);
00332     } else {
00333         kError() << "Engine: invalid command" << endl;
00334     }
00335 }
00336 
00337 void EnginePrivate::slotHandleUpload()
00338 {
00339     // NOTE: this is only connected when we are doing an upload
00340     //kDebug() << "Engine: slotProvidersFinished";
00341 
00342     //Provider *fakeprovider = new Provider();
00343     //fakeprovider->setName(QString("Fake Provider"));
00344     //fakeprovider->setUploadUrl(KUrl("http://localhost/dav/"));
00345     //fakeprovider->setUploadUrl(KUrl("webdav://localhost/uploads/"));
00346     
00347     
00348     // let the user select the provider
00349     QPointer<ProviderDialog> provdialog = new ProviderDialog(NULL);
00350     for (Provider::List::Iterator it = m_providers.begin(); it != m_providers.end(); ++it) {
00351         Provider *provider = (*it);
00352         provdialog->addProvider(provider);
00353     }
00354     //provdialog.addProvider(fakeprovider);
00355     if (provdialog->exec() == QDialog::Rejected) {
00356         stopLoop();
00357         return;
00358     }
00359 
00360     KNS::Provider *provider = provdialog->provider();
00361 
00362     // fill in the details of the upload (name, author...)
00363     QPointer<UploadDialog> uploaddialog = new UploadDialog(NULL);
00364     uploaddialog->setPayloadFile(KUrl(m_uploadfile));
00365     if (uploaddialog->exec() == QDialog::Rejected) {
00366         stopLoop();
00367         return;
00368     }
00369 
00370     Entry *entry = uploaddialog->entry();
00371     if (!entry) {
00372         stopLoop();
00373         return;
00374     }
00375     
00376     KTranslatable payload;
00377     // add all the translations to the payload
00378     QStringList langs = entry->name().languages();
00379     for (QStringList::const_iterator it = langs.constBegin(); it != langs.constEnd(); ++it) {
00380         payload.addString(*it, m_uploadfile);
00381     }
00382     entry->setPayload(payload);
00383 
00384     EntryHandler eh(*entry);
00385     QDomElement xml = eh.entryXML();
00386     QByteArray ar;
00387     QTextStream txt(&ar);
00388     txt << xml;
00389     //kDebug() << "Upload: " << QString(ar);
00390 
00391     connect(this, SIGNAL(signalEntryUploaded()), SLOT(stopLoop()));
00392     connect(this, SIGNAL(signalEntryFailed()), SLOT(stopLoop()));
00393 
00394     uploadEntry(provider, entry);
00395     m_uploadedEntry=entry;
00396 }
00397 
00398 void EnginePrivate::slotEntryChanged(KNS::Entry * entry)
00399 {
00400     //kDebug() << "adding entries to list of changed entries";
00401     m_changedEntries << entry;
00402 }
00403 
00404 // BIGFIXME: make this method go away when we are using goya
00405 void EnginePrivate::slotEntriesFinished()
00406 {
00407     //m_downloaddialog->refresh();
00408 }
00409 
00410 void EnginePrivate::slotDownloadDialogDestroyed()
00411 {
00412     //kDebug() << m_downloaddialog << "is destroyed!" << s_dialogs.count() << s_dialogs.keys();
00413     QHash<QString, QPointer<KDialog> >::iterator it = s_dialogs.begin();
00414     while (it != s_dialogs.end()) {
00415         if (it.value() == m_downloaddialog) {
00416             //kDebug() << "found it!";
00417             it = s_dialogs.erase(it);
00418         }
00419 
00420         if (it != s_dialogs.end()) {
00421             ++it;
00422         }
00423     }
00424 
00425     //kDebug() << s_dialogs.count() << s_dialogs.keys();
00426 }
00427 
00428 void EnginePrivate::slotDownloadDialogClosed()
00429 {
00430     //kDebug() << sender() << m_downloaddialog;
00431     disconnect(m_downloaddialog, SIGNAL(destroyed(QObject*)),
00432                this, SLOT(slotDownloadDialogDestroyed()));
00433     slotDownloadDialogDestroyed();
00434     m_downloaddialog->deleteLater();
00435     m_downloaddialog = NULL;
00436     stopLoop();
00437     emit signalDownloadDialogDone(QList<KNS::Entry*>::fromSet(m_changedEntries));
00438 }
00439 
00440 #include "engine.moc"

KNewStuff

Skip menu "KNewStuff"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal