File indexing completed on 2024-10-06 04:25:57

0001 /*
0002     SPDX-FileCopyrightText: 2003-2008 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-FileCopyrightText: 2010-2011 Michal Malek <michalm@jabster.pl>
0004     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 
0009 #include "k3bapplication.h"
0010 #include "k3b.h"
0011 #include "k3bsplash.h"
0012 #include "k3bprojectmanager.h"
0013 #include "k3bappdevicemanager.h"
0014 #include "k3blsofwrapperdialog.h"
0015 #include "config-k3b.h"
0016 
0017 #include "k3bcore.h"
0018 #include "k3bdevicemanager.h"
0019 #include "k3bthread.h"
0020 #ifdef ENABLE_HAL_SUPPORT
0021 #include "k3bhalconnection.h"
0022 #endif
0023 #include "k3bexternalbinmanager.h"
0024 #include "k3bdefaultexternalprograms.h"
0025 #include "k3bglobals.h"
0026 #include "k3bversion.h"
0027 #include "k3bdoc.h"
0028 #include "k3bsystemproblemdialog.h"
0029 #include "k3bpluginmanager.h"
0030 #include "k3bthememanager.h"
0031 #include "k3bmsf.h"
0032 #include "k3bmovixprogram.h"
0033 #include "k3bview.h"
0034 #include "k3bjob.h"
0035 #include "k3bmediacache.h"
0036 
0037 #include <KConfig>
0038 #include <KSharedConfig>
0039 #include <KNotification>
0040 #include <KLocalizedString>
0041 
0042 #include <QCommandLineParser>
0043 #include <QDebug>
0044 #include <QTimer>
0045 
0046 
0047 K3b::Application::Core* K3b::Application::Core::s_k3bAppCore = 0;
0048 
0049 
0050 K3b::Application::Application( int& argc, char** argv )
0051     : QApplication( argc, argv ),
0052       m_core( nullptr ),
0053       m_mainWindow( nullptr )
0054 {
0055     KLocalizedString::setApplicationDomain( "k3b" );
0056 }
0057 
0058 void K3b::Application::init( QCommandLineParser* commandLineParser )
0059 {
0060     m_cmdLine.reset( commandLineParser );
0061 
0062     m_core = new Core( this );
0063     
0064     KConfigGroup generalOptions( KSharedConfig::openConfig(), QStringLiteral("General Options") );
0065 
0066     Splash* splash = 0;
0067     if( !isSessionRestored() ) {
0068         if( generalOptions.readEntry("Show splash", true) && !m_cmdLine->isSet( "nosplash" ) ) {
0069             // we need the correct splash pic
0070             m_core->m_themeManager->readConfig( generalOptions );
0071 
0072             splash = new Splash( 0 );
0073             splash->show();
0074         }
0075     }
0076 
0077     m_mainWindow = new MainWindow();
0078     m_core->m_mainWindow = m_mainWindow;
0079 
0080     if( isSessionRestored() ) {
0081         // we only have one single mainwindow to restore
0082         m_mainWindow->restore(1);
0083     }
0084     else {
0085         m_mainWindow->show();
0086     }
0087 
0088     if (splash) {
0089         QTimer::singleShot(0, splash, &QWidget::close);
0090     }
0091 
0092     qRegisterMetaType<KSharedConfig::Ptr>( "KSharedConfig::Ptr" );
0093     //
0094     // Load device, external programs, and stuff.
0095     //
0096     QMetaObject::invokeMethod( m_core, "init", Qt::QueuedConnection );
0097     QMetaObject::invokeMethod( m_core, "readSettings", Qt::QueuedConnection, Q_ARG( KSharedConfig::Ptr, KSharedConfig::openConfig() ) );
0098     QMetaObject::invokeMethod( m_core->deviceManager(), "printDevices", Qt::QueuedConnection );
0099     QMetaObject::invokeMethod( this, "checkSystemConfig", Qt::QueuedConnection );
0100 
0101     connect( this, SIGNAL(aboutToQuit()), SLOT(slotShutDown()) );
0102 }
0103 
0104 
0105 K3b::Application::~Application()
0106 {
0107     // we must not delete m_mainWindow here, QApplication takes care of it
0108 }
0109 
0110 
0111 void K3b::Application::checkSystemConfig()
0112 {
0113     if( !isSessionRestored() ) {
0114         
0115         if( SystemProblemDialog::readCheckSystemConfig() ) {
0116             SystemProblemDialog::checkSystem( m_mainWindow );
0117         }
0118         
0119         QMetaObject::invokeMethod( this, "processCmdLineArgs", Qt::QueuedConnection );
0120     }
0121 
0122     // write the current version to make sure checks such as SystemProblemDialog::readCheckSystemConfig
0123     // use a proper value
0124     KConfigGroup generalOptions( KSharedConfig::openConfig(), QStringLiteral("General Options") );
0125     generalOptions.writeEntry( "config version", QString(m_core->version()) );
0126 }
0127 
0128 
0129 void K3b::Application::processCmdLineArgs()
0130 {
0131     if( !m_cmdLine || !m_mainWindow )
0132         return;
0133 
0134     bool dialogOpen = false;
0135 
0136     if( k3bcore->jobsRunning() > 0 ) {
0137         KNotification::event( "Busy",
0138                               i18n("K3b is busy"),
0139                               i18n("K3b is currently busy and cannot start any other operations.") );
0140         return;
0141     }
0142 
0143     Doc* doc = 0;
0144     if( m_cmdLine->isSet( "data" ) ) {
0145         doc = m_mainWindow->slotNewDataDoc();
0146     }
0147     else if( m_cmdLine->isSet( "audiocd" ) ) {
0148         doc = m_mainWindow->slotNewAudioDoc();
0149     }
0150     else if( m_cmdLine->isSet( "mixedcd" ) ) {
0151         doc = m_mainWindow->slotNewMixedDoc();
0152     }
0153     else if( m_cmdLine->isSet( "videocd" ) ) {
0154         doc = m_mainWindow->slotNewVcdDoc();
0155     }
0156     else if( m_cmdLine->isSet( "emovix" ) ) {
0157         doc = m_mainWindow->slotNewMovixDoc();
0158     }
0159     else if( m_cmdLine->isSet( "videodvd" ) ) {
0160         doc = m_mainWindow->slotNewVideoDvdDoc();
0161     }
0162 
0163     // if we created a doc the urls are used to populate it
0164     if( doc ) {
0165         QList<QUrl> urls;
0166         for( QString url : m_cmdLine->positionalArguments() ) {
0167             urls.append( QUrl::fromUserInput( url ) );
0168         }
0169         dynamic_cast<View*>( doc->view() )->addUrls( urls );
0170     }
0171     // otherwise we open them as documents
0172     else {
0173         for( QString url : m_cmdLine->positionalArguments() ) {
0174             m_mainWindow->openDocument( QUrl::fromUserInput( url ) );
0175         }
0176     }
0177 
0178     // we only allow one dialog to be opened
0179     if( m_cmdLine->isSet( "image" ) ) {
0180         dialogOpen = true;
0181         if( k3bcore->jobsRunning() == 0 ) {
0182             m_mainWindow->slotWriteImage( QUrl::fromUserInput(m_cmdLine->value( "image" ) ) );
0183         }
0184     }
0185     else if( m_cmdLine->isSet("copy") ) {
0186         dialogOpen = true;
0187         m_mainWindow->mediaCopy( m_core->deviceManager()->findDeviceByUdi( m_cmdLine->value( "copy"  ) ) );
0188     }
0189     else if( m_cmdLine->isSet("format") ) {
0190         dialogOpen = true;
0191         m_mainWindow->formatMedium( m_core->deviceManager()->findDeviceByUdi( m_cmdLine->value( "format" ) ) );
0192     }
0193 
0194     // no dialog used here
0195     if( m_cmdLine->isSet( "cddarip" ) ) {
0196         m_mainWindow->cddaRip( m_core->deviceManager()->findDeviceByUdi( m_cmdLine->value( "cddarip" ) ) );
0197     }
0198     else if( m_cmdLine->isSet( "videodvdrip" ) ) {
0199         m_mainWindow->videoDvdRip( m_core->deviceManager()->findDeviceByUdi( m_cmdLine->value( "videodvdrip" ) ) );
0200     }
0201     else if( m_cmdLine->isSet( "videocdrip" ) ) {
0202         m_mainWindow->videoCdRip( m_core->deviceManager()->findDeviceByUdi(  m_cmdLine->value( "videocdrip" ) ) );
0203     }
0204 
0205     if( !dialogOpen && m_cmdLine->isSet( "burn" ) ) {
0206         if( m_core->projectManager()->activeDoc() ) {
0207             dialogOpen = true;
0208             static_cast<View*>( m_core->projectManager()->activeDoc()->view() )->slotBurn();
0209         }
0210     }
0211 
0212     m_cmdLine.reset();
0213 }
0214 
0215 
0216 void K3b::Application::slotShutDown()
0217 {
0218     k3bcore->mediaCache()->clearDeviceList();
0219     Thread::waitUntilFinished();
0220 }
0221 
0222 
0223 
0224 K3b::Application::Core::Core( QObject* parent )
0225     : K3b::Core( parent )
0226 {
0227     s_k3bAppCore = this;
0228     m_themeManager = new ThemeManager( this );
0229     m_projectManager = new ProjectManager( this );
0230     // we need the themes on startup (loading them is fast anyway :)
0231     m_themeManager->loadThemes();
0232 }
0233 
0234 
0235 K3b::Application::Core::~Core()
0236 {
0237 }
0238 
0239 
0240 void K3b::Application::Core::init()
0241 {
0242     //
0243     // The eMovix program is a special case which is not part of
0244     // the default programs handled by K3b::Core
0245     //
0246     externalBinManager()->addProgram( new MovixProgram() );
0247     externalBinManager()->addProgram( new NormalizeProgram() );
0248     addTranscodePrograms( externalBinManager() );
0249     addVcdimagerPrograms( externalBinManager() );
0250 
0251     K3b::Core::init();
0252 
0253     connect( deviceManager(), SIGNAL(changed(K3b::Device::DeviceManager*)),
0254              mediaCache(), SLOT(buildDeviceList(K3b::Device::DeviceManager*)) );
0255     // FIXME: move this to libk3b
0256     appDeviceManager()->setMediaCache( mediaCache() );
0257 }
0258 
0259 
0260 void K3b::Application::Core::readSettings( KSharedConfig::Ptr cnf )
0261 {
0262     K3b::Core::readSettings( cnf );
0263     m_themeManager->readConfig( cnf->group( QStringLiteral("General Options") ) );
0264 }
0265 
0266 
0267 void K3b::Application::Core::saveSettings( KSharedConfig::Ptr cnf )
0268 {
0269     K3b::Core::saveSettings( cnf );
0270     m_themeManager->saveConfig( cnf->group( QStringLiteral("General Options") ) );
0271 }
0272 
0273 
0274 K3b::AppDeviceManager* K3b::Application::Core::appDeviceManager() const
0275 {
0276     return static_cast<AppDeviceManager*>( deviceManager() );
0277 }
0278 
0279 
0280 K3b::Device::DeviceManager* K3b::Application::Core::createDeviceManager() const
0281 {
0282     // our very own special device manager
0283     return new AppDeviceManager( const_cast<Application::Core*>( this ) );
0284 }
0285 
0286 
0287 bool K3b::Application::Core::internalBlockDevice( K3b::Device::Device* dev )
0288 {
0289     if( K3b::Core::internalBlockDevice( dev ) ) {
0290         if( mediaCache() ) {
0291             m_deviceBlockMap[dev] = mediaCache()->blockDevice( dev );
0292         }
0293 
0294 #ifdef ENABLE_HAL_SUPPORT
0295         if( Device::HalConnection::instance()->lock( dev ) != Device::HalConnection::org_freedesktop_Hal_Success )
0296             qDebug() << "(K3b::InterferingSystemsHandler) HAL lock failed.";
0297 #endif
0298 
0299         //
0300         // Check if the device is in use
0301         //
0302         // FIXME: Use the top level widget as parent
0303         LsofWrapperDialog::checkDevice( dev );
0304 
0305         return true;
0306     }
0307     else
0308         return false;
0309 }
0310 
0311 
0312 void K3b::Application::Core::internalUnblockDevice( K3b::Device::Device* dev )
0313 {
0314     if( mediaCache() ) {
0315         mediaCache()->unblockDevice( dev, m_deviceBlockMap[dev] );
0316         m_deviceBlockMap.remove( dev );
0317     }
0318 
0319 #ifdef ENABLE_HAL_SUPPORT
0320     Device::HalConnection::instance()->unlock( dev );
0321 #endif
0322 
0323     K3b::Core::internalUnblockDevice( dev );
0324 }
0325 
0326 #include "moc_k3bapplication.cpp"