/* * * $Id: k3bcore.cpp 619556 2007-01-03 17:38:12Z trueg $ * Copyright (C) 2003 Sebastian Trueg * * This file is part of the K3b project. * Copyright (C) 1998-2007 Sebastian Trueg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * See the file "COPYING" for the exact licensing terms. */ #include #include "k3bcore.h" #include "k3bjob.h" #include #ifdef HAVE_HAL #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static TQt::HANDLE s_guiThreadHandle = TQThread::currentThread(); // We cannot use TQWaitCondition here since the event might be handled faster // than the thread starts the waiting class DeviceBlockingEventDoneCondition { public: DeviceBlockingEventDoneCondition() : m_done(false) { } void done() { m_doneMutex.lock(); m_done = true; m_doneMutex.unlock(); } void wait() { while( true ) { m_doneMutex.lock(); bool done = m_done; m_doneMutex.unlock(); if( done ) return; } } private: TQMutex m_doneMutex; bool m_done; }; class DeviceBlockingEvent : public TQCustomEvent { public: DeviceBlockingEvent( bool block_, K3bDevice::Device* dev, DeviceBlockingEventDoneCondition* cond_, bool* success_ ) : TQCustomEvent( TQEvent::User + 33 ), block(block_), device(dev), cond(cond_), success(success_) { } bool block; K3bDevice::Device* device; DeviceBlockingEventDoneCondition* cond; bool* success; }; class K3bCore::Private { public: Private() : version( LIBK3B_VERSION ), config(0), deleteConfig(false), deviceManager(0), externalBinManager(0), pluginManager(0), globalSettings(0) { } K3bVersion version; KConfig* config; bool deleteConfig; K3bDevice::DeviceManager* deviceManager; K3bExternalBinManager* externalBinManager; K3bPluginManager* pluginManager; K3bGlobalSettings* globalSettings; TQValueList runningJobs; TQValueList blockedDevices; }; K3bCore* K3bCore::s_k3bCore = 0; K3bCore::K3bCore( TQObject* tqparent, const char* name ) : TQObject( tqparent, name ) { d = new Private(); if( s_k3bCore ) qFatal("ONLY ONE INSTANCE OF K3BCORE ALLOWED!"); s_k3bCore = this; // create the thread widget instance in the GUI thread K3bThreadWidget::instance(); } K3bCore::~K3bCore() { s_k3bCore = 0; delete d->globalSettings; delete d; } K3bDevice::DeviceManager* K3bCore::deviceManager() const { const_cast(this)->initDeviceManager(); return d->deviceManager; } K3bExternalBinManager* K3bCore::externalBinManager() const { const_cast(this)->initExternalBinManager(); return d->externalBinManager; } K3bPluginManager* K3bCore::pluginManager() const { const_cast(this)->initPluginManager(); return d->pluginManager; } K3bGlobalSettings* K3bCore::globalSettings() const { const_cast(this)->initGlobalSettings(); return d->globalSettings; } const K3bVersion& K3bCore::version() const { return d->version; } KConfig* K3bCore::config() const { if( !d->config ) { kdDebug() << "(K3bCore) opening k3b config file." << endl; kdDebug() << "(K3bCore) while I am a " << className() << endl; d->deleteConfig = true; d->config = new KConfig( "k3brc" ); } return d->config; } void K3bCore::init() { initGlobalSettings(); initExternalBinManager(); initDeviceManager(); initPluginManager(); // load the plugins before doing anything else // they might add external bins pluginManager()->loadAll(); externalBinManager()->search(); #ifdef HAVE_HAL connect( K3bDevice::HalConnection::instance(), TQT_SIGNAL(deviceAdded(const TQString&)), deviceManager(), TQT_SLOT(addDevice(const TQString&)) ); connect( K3bDevice::HalConnection::instance(), TQT_SIGNAL(deviceRemoved(const TQString&)), deviceManager(), TQT_SLOT(removeDevice(const TQString&)) ); TQStringList devList = K3bDevice::HalConnection::instance()->devices(); if( devList.isEmpty() ) deviceManager()->scanBus(); else for( unsigned int i = 0; i < devList.count(); ++i ) deviceManager()->addDevice( devList[i] ); #else deviceManager()->scanBus(); #endif } void K3bCore::initGlobalSettings() { if( !d->globalSettings ) d->globalSettings = new K3bGlobalSettings(); } void K3bCore::initExternalBinManager() { if( !d->externalBinManager ) { d->externalBinManager = new K3bExternalBinManager( this ); K3b::addDefaultPrograms( d->externalBinManager ); } } void K3bCore::initDeviceManager() { if( !d->deviceManager ) d->deviceManager = new K3bDevice::DeviceManager( this ); } void K3bCore::initPluginManager() { if( !d->pluginManager ) d->pluginManager = new K3bPluginManager( this ); } void K3bCore::readSettings( KConfig* cnf ) { KConfig* c = cnf; if( !c ) c = config(); TQString oldGrp = c->group(); globalSettings()->readSettings( c ); deviceManager()->readConfig( c ); externalBinManager()->readConfig( c ); c->setGroup( oldGrp ); } void K3bCore::saveSettings( KConfig* cnf ) { KConfig* c = cnf; if( !c ) c = config(); TQString oldGrp = c->group(); c->setGroup( "General Options" ); c->writeEntry( "config version", version() ); deviceManager()->saveConfig( c ); externalBinManager()->saveConfig( c ); d->globalSettings->saveSettings( c ); c->setGroup( oldGrp ); } void K3bCore::registerJob( K3bJob* job ) { d->runningJobs.append( job ); emit jobStarted( job ); if( K3bBurnJob* bj = dynamic_cast( job ) ) emit burnJobStarted( bj ); } void K3bCore::unregisterJob( K3bJob* job ) { d->runningJobs.remove( job ); emit jobFinished( job ); if( K3bBurnJob* bj = dynamic_cast( job ) ) emit burnJobFinished( bj ); } bool K3bCore::jobsRunning() const { return !d->runningJobs.isEmpty(); } const TQValueList& K3bCore::runningJobs() const { return d->runningJobs; } bool K3bCore::blockDevice( K3bDevice::Device* dev ) { if( TQThread::currentThread() == s_guiThreadHandle ) { return internalBlockDevice( dev ); } else { bool success = false; DeviceBlockingEventDoneCondition w; TQApplication::postEvent( this, new DeviceBlockingEvent( true, dev, &w, &success ) ); w.wait(); return success; } } void K3bCore::unblockDevice( K3bDevice::Device* dev ) { if( TQThread::currentThread() == s_guiThreadHandle ) { internalUnblockDevice( dev ); } else { DeviceBlockingEventDoneCondition w; TQApplication::postEvent( this, new DeviceBlockingEvent( false, dev, &w, 0 ) ); w.wait(); } } bool K3bCore::internalBlockDevice( K3bDevice::Device* dev ) { if( !d->blockedDevices.tqcontains( dev ) ) { d->blockedDevices.append( dev ); return true; } else return false; } void K3bCore::internalUnblockDevice( K3bDevice::Device* dev ) { d->blockedDevices.remove( dev ); } void K3bCore::customEvent( TQCustomEvent* e ) { if( DeviceBlockingEvent* de = dynamic_cast(e) ) { if( de->block ) *de->success = internalBlockDevice( de->device ); else internalUnblockDevice( de->device ); de->cond->done(); } } #include "k3bcore.moc"