File indexing completed on 2024-05-12 04:51:08

0001 /*
0002     SPDX-FileCopyrightText: 2003 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-FileCopyrightText: 2009 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
0004     SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 
0010 #include "k3bmovixdoc.h"
0011 #include "k3bmovixjob.h"
0012 #include "k3bmovixfileitem.h"
0013 #include "k3bdiritem.h"
0014 #include "k3bfileitem.h"
0015 #include "k3bglobals.h"
0016 #include "k3b_i18n.h"
0017 
0018 #include <KMessageBox>
0019 
0020 #include <QDebug>
0021 #include <QFileInfo>
0022 #include <QInputDialog>
0023 #include <QDomElement>
0024 
0025 
0026 K3b::MovixDoc::MovixDoc( QObject* parent )
0027     : K3b::DataDoc( parent )
0028 {
0029 }
0030 
0031 
0032 K3b::MovixDoc::~MovixDoc()
0033 {
0034 }
0035 
0036 
0037 K3b::BurnJob* K3b::MovixDoc::newBurnJob( K3b::JobHandler* hdl, QObject* parent )
0038 {
0039     return new K3b::MovixJob( this, hdl, parent );
0040 }
0041 
0042 
0043 bool K3b::MovixDoc::newDocument()
0044 {
0045     m_loopPlaylist = 1;
0046     m_ejectDisk = false;
0047     m_reboot = false;
0048     m_shutdown = false;
0049     m_randomPlay = false;
0050 
0051     return K3b::DataDoc::newDocument();
0052 }
0053 
0054 
0055 int K3b::MovixDoc::indexOf( K3b::MovixFileItem* item )
0056 {
0057     return m_movixFiles.lastIndexOf(item);
0058 }
0059 
0060 
0061 void K3b::MovixDoc::addUrls( const QList<QUrl>& urls )
0062 {
0063     addUrlsAt(urls, -1);
0064 }
0065 
0066 void K3b::MovixDoc::addUrlsAt( const QList<QUrl>& urls, int pos )
0067 {
0068     QList<K3b::MovixFileItem*> items;
0069 
0070     for( QList<QUrl>::ConstIterator it = urls.begin(); it != urls.end(); ++it ) {
0071         QUrl url = K3b::convertToLocalUrl( *it );
0072 
0073         QFileInfo f( url.toLocalFile() );
0074         if( !f.isFile() || !url.isLocalFile() )
0075             continue;
0076 
0077         QString newName = f.fileName();
0078 
0079         bool ok = true;
0080         while( ok && nameAlreadyInDir( newName, root() ) ) {
0081             newName = QInputDialog::getText( view(),
0082                                              i18n("Enter New Filename"),
0083                                              i18n("A file with that name already exists. Please enter a new name:"),
0084                                              QLineEdit::Normal, newName, &ok );
0085         }
0086 
0087         if( ok ) {
0088             MovixFileItem* newItem = new MovixFileItem( f.absoluteFilePath(), *this, newName );
0089             root()->addDataItem( newItem );
0090             items.append( newItem );
0091         }
0092     }
0093 
0094     addMovixItems( items, pos );
0095 }
0096 
0097 
0098 void K3b::MovixDoc::addMovixItems( QList<K3b::MovixFileItem*>& items, int pos )
0099 {
0100     if( !items.isEmpty() ) {
0101         if( pos < 0 || pos > m_movixFiles.count() )
0102             pos = m_movixFiles.count();
0103 
0104         emit itemsAboutToBeInserted( pos, items.count() );
0105 
0106         Q_FOREACH( K3b::MovixFileItem* newItem, items )
0107         {
0108             m_movixFiles.insert( pos, newItem );
0109             pos++;
0110         }
0111 
0112         emit itemsInserted();
0113     }
0114 }
0115 
0116 void K3b::MovixDoc::removeMovixItem( K3b::MovixFileItem* item )
0117 {
0118     while( m_movixFiles.contains( item ) )
0119     {
0120         int removedPos = m_movixFiles.lastIndexOf( item );
0121 
0122         emit itemsAboutToBeRemoved( removedPos, 1 );
0123 
0124         K3b::MovixFileItem *removedItem = m_movixFiles.takeAt( removedPos );
0125         delete removedItem;
0126 
0127         emit itemsRemoved();
0128     }
0129 }
0130 
0131 
0132 void K3b::MovixDoc::moveMovixItem( K3b::MovixFileItem* item, K3b::MovixFileItem* itemAfter )
0133 {
0134     if( item == itemAfter )
0135         return;
0136 
0137     // take the current item
0138     int removedPos = m_movixFiles.lastIndexOf( item );
0139 
0140     emit itemsAboutToBeRemoved( removedPos, 1 );
0141 
0142     item = m_movixFiles.takeAt( removedPos );
0143 
0144     emit itemsRemoved();
0145 
0146     // if after == 0 lastIndexOf returns -1
0147     int pos = m_movixFiles.lastIndexOf( itemAfter ) + 1;
0148 
0149     emit itemsAboutToBeInserted( pos, 1 );
0150 
0151     m_movixFiles.insert( pos, item );
0152 
0153     emit itemsInserted();
0154 
0155     setModified(true);
0156 }
0157 
0158 
0159 void K3b::MovixDoc::addSubTitleItem( K3b::MovixFileItem* item, const QUrl& url )
0160 {
0161     if( !item )
0162         return;
0163 
0164     QFileInfo f( url.toLocalFile() );
0165     if( !f.isFile() || !url.isLocalFile() )
0166         return;
0167 
0168     if( item->subTitleItem() )
0169         removeSubTitleItem( item );
0170 
0171     // check if there already is a file named like we want to name the subTitle file
0172     QString name = K3b::MovixFileItem::subTitleFileName( item->k3bName() );
0173 
0174     if( nameAlreadyInDir( name, root() ) ) {
0175         KMessageBox::error( 0, i18n("Could not rename subtitle file. File with requested name %1 already exists.",name) );
0176         return;
0177     }
0178 
0179     emit subTitleAboutToBeInserted( item );
0180 
0181     K3b::MovixSubtitleItem* subItem = new K3b::MovixSubtitleItem( f.absoluteFilePath(), *this, item, name );
0182     item->setSubTitleItem( subItem );
0183     root()->addDataItem( subItem );
0184 
0185     emit subTitleInserted();
0186 
0187     setModified(true);
0188 }
0189 
0190 
0191 void K3b::MovixDoc::removeSubTitleItem( K3b::MovixFileItem* item )
0192 {
0193     if( item->subTitleItem() ) {
0194         emit subTitleAboutToBeRemoved( item );
0195 
0196         delete item->subTitleItem();
0197         item->setSubTitleItem(0);
0198 
0199         emit subTitleRemoved();
0200 
0201         setModified(true);
0202     }
0203 }
0204 
0205 
0206 bool K3b::MovixDoc::loadDocumentData( QDomElement* rootElem )
0207 {
0208     if( !root() )
0209         newDocument();
0210 
0211     QDomNodeList nodes = rootElem->childNodes();
0212 
0213     if( nodes.item(0).nodeName() != "general" ) {
0214         qDebug() << "(K3b::MovixDoc) could not find 'general' section.";
0215         return false;
0216     }
0217     if( !readGeneralDocumentData( nodes.item(0).toElement() ) )
0218         return false;
0219 
0220 
0221     // parse options
0222     // -----------------------------------------------------------------
0223     if( nodes.item(1).nodeName() != "data_options" ) {
0224         qDebug() << "(K3b::MovixDoc) could not find 'data_options' section.";
0225         return false;
0226     }
0227     if( !loadDocumentDataOptions( nodes.item(1).toElement() ) )
0228         return false;
0229     // -----------------------------------------------------------------
0230 
0231 
0232 
0233     // parse header
0234     // -----------------------------------------------------------------
0235     if( nodes.item(2).nodeName() != "data_header" ) {
0236         qDebug() << "(K3b::MovixDoc) could not find 'data_header' section.";
0237         return false;
0238     }
0239     if( !loadDocumentDataHeader( nodes.item(2).toElement() ) )
0240         return false;
0241     // -----------------------------------------------------------------
0242 
0243 
0244 
0245     // parse movix options
0246     // -----------------------------------------------------------------
0247     if( nodes.item(3).nodeName() != "movix_options" ) {
0248         qDebug() << "(K3b::MovixDoc) could not find 'movix_options' section.";
0249         return false;
0250     }
0251 
0252     // load the options
0253     QDomNodeList optionList = nodes.item(3).childNodes();
0254     for( int i = 0; i < optionList.count(); i++ ) {
0255 
0256         QDomElement e = optionList.item(i).toElement();
0257         if( e.isNull() )
0258             return false;
0259 
0260         if( e.nodeName() == "shutdown")
0261             setShutdown( e.attributeNode( "activated" ).value() == "yes" );
0262         else if( e.nodeName() == "reboot")
0263             setReboot( e.attributeNode( "activated" ).value() == "yes" );
0264         else if( e.nodeName() == "eject_disk")
0265             setEjectDisk( e.attributeNode( "activated" ).value() == "yes" );
0266         else if( e.nodeName() == "random_play")
0267             setRandomPlay( e.attributeNode( "activated" ).value() == "yes" );
0268         else if( e.nodeName() == "no_dma")
0269             setNoDma( e.attributeNode( "activated" ).value() == "yes" );
0270         else if( e.nodeName() == "subtitle_fontset")
0271             setSubtitleFontset( e.text() );
0272         else if( e.nodeName() == "boot_message_language")
0273             setBootMessageLanguage( e.text() );
0274         else if( e.nodeName() == "audio_background")
0275             setAudioBackground( e.text() );
0276         else if( e.nodeName() == "keyboard_language")
0277             setKeyboardLayout( e.text() );
0278         else if( e.nodeName() == "codecs")
0279             setCodecs( e.text().split( ',' ) );
0280         else if( e.nodeName() == "default_boot_label")
0281             setDefaultBootLabel( e.text() );
0282         else if( e.nodeName() == "additional_mplayer_options")
0283             setAdditionalMPlayerOptions( e.text() );
0284         else if( e.nodeName() == "unwanted_mplayer_options")
0285             setUnwantedMPlayerOptions( e.text() );
0286         else if( e.nodeName() == "loop_playlist")
0287             setLoopPlaylist( e.text().toInt() );
0288         else
0289             qDebug() << "(K3b::MovixDoc) unknown movix option: " << e.nodeName();
0290     }
0291     // -----------------------------------------------------------------
0292 
0293     // parse files
0294     // -----------------------------------------------------------------
0295     if( nodes.item(4).nodeName() != "movix_files" ) {
0296         qDebug() << "(K3b::MovixDoc) could not find 'movix_files' section.";
0297         return false;
0298     }
0299 
0300     // load file items
0301     QDomNodeList fileList = nodes.item(4).childNodes();
0302     for( int i = 0; i < fileList.count(); i++ ) {
0303 
0304         QDomElement e = fileList.item(i).toElement();
0305         if( e.isNull() )
0306             return false;
0307 
0308         if( e.nodeName() == "file" ) {
0309             if( !e.hasAttribute( "name" ) ) {
0310                 qDebug() << "(K3b::MovixDoc) found file tag without name attribute.";
0311                 return false;
0312             }
0313 
0314             QDomElement urlElem = e.firstChild().toElement();
0315             if( urlElem.isNull() ) {
0316                 qDebug() << "(K3b::MovixDoc) found file tag without url child.";
0317                 return false;
0318             }
0319 
0320             // emit the signal telling the item is going to be added
0321             emit itemsAboutToBeInserted( m_movixFiles.count(), 1 );
0322 
0323             // create the item
0324             K3b::MovixFileItem* newK3bItem = new K3b::MovixFileItem( urlElem.text(),
0325                                                                  *this,
0326                                                                  e.attributeNode("name").value() );
0327             root()->addDataItem( newK3bItem );
0328             m_movixFiles.append( newK3bItem );
0329 
0330             // tell the item was already added
0331             emit itemsInserted();
0332 
0333             // subtitle file?
0334             QDomElement subTitleElem = e.childNodes().item(1).toElement();
0335             if( !subTitleElem.isNull() && subTitleElem.nodeName() == "subtitle_file" ) {
0336                 urlElem = subTitleElem.firstChild().toElement();
0337                 if( urlElem.isNull() ) {
0338                     qDebug() << "(K3b::MovixDoc) found subtitle_file tag without url child.";
0339                     return false;
0340                 }
0341 
0342                 QString name = K3b::MovixFileItem::subTitleFileName( newK3bItem->k3bName() );
0343 
0344                 emit subTitleAboutToBeInserted( newK3bItem );
0345 
0346                 K3b::MovixSubtitleItem* subItem = new K3b::MovixSubtitleItem( urlElem.text(), *this, newK3bItem, name );
0347                 root()->addDataItem( subItem );
0348                 newK3bItem->setSubTitleItem( subItem );
0349 
0350                 emit subTitleInserted();
0351             }
0352         }
0353         else {
0354             qDebug() << "(K3b::MovixDoc) found " << e.nodeName() << " node where 'file' was expected.";
0355             return false;
0356         }
0357     }
0358     // -----------------------------------------------------------------
0359 
0360     return true;
0361 }
0362 
0363 
0364 bool K3b::MovixDoc::saveDocumentData( QDomElement* docElem )
0365 {
0366     QDomDocument doc = docElem->ownerDocument();
0367 
0368     saveGeneralDocumentData( docElem );
0369 
0370     QDomElement optionsElem = doc.createElement( "data_options" );
0371     saveDocumentDataOptions( optionsElem );
0372 
0373     QDomElement headerElem = doc.createElement( "data_header" );
0374     saveDocumentDataHeader( headerElem );
0375 
0376     QDomElement movixOptElem = doc.createElement( "movix_options" );
0377     QDomElement movixFilesElem = doc.createElement( "movix_files" );
0378 
0379 
0380     // save the movix options
0381     QDomElement propElem = doc.createElement( "shutdown" );
0382     propElem.setAttribute( "activated", shutdown() ? "yes" : "no" );
0383     movixOptElem.appendChild( propElem );
0384 
0385     propElem = doc.createElement( "reboot" );
0386     propElem.setAttribute( "activated", reboot() ? "yes" : "no" );
0387     movixOptElem.appendChild( propElem );
0388 
0389     propElem = doc.createElement( "eject_disk" );
0390     propElem.setAttribute( "activated", ejectDisk() ? "yes" : "no" );
0391     movixOptElem.appendChild( propElem );
0392 
0393     propElem = doc.createElement( "random_play" );
0394     propElem.setAttribute( "activated", randomPlay() ? "yes" : "no" );
0395     movixOptElem.appendChild( propElem );
0396 
0397     propElem = doc.createElement( "no_dma" );
0398     propElem.setAttribute( "activated", noDma() ? "yes" : "no" );
0399     movixOptElem.appendChild( propElem );
0400 
0401     propElem = doc.createElement( "subtitle_fontset" );
0402     propElem.appendChild( doc.createTextNode( subtitleFontset() ) );
0403     movixOptElem.appendChild( propElem );
0404 
0405     propElem = doc.createElement( "boot_message_language" );
0406     propElem.appendChild( doc.createTextNode( bootMessageLanguage() ) );
0407     movixOptElem.appendChild( propElem );
0408 
0409     propElem = doc.createElement( "audio_background" );
0410     propElem.appendChild( doc.createTextNode( audioBackground() ) );
0411     movixOptElem.appendChild( propElem );
0412 
0413     propElem = doc.createElement( "keyboard_language" );
0414     propElem.appendChild( doc.createTextNode( keyboardLayout() ) );
0415     movixOptElem.appendChild( propElem );
0416 
0417     propElem = doc.createElement( "codecs" );
0418     propElem.appendChild( doc.createTextNode( codecs().join(",") ) );
0419     movixOptElem.appendChild( propElem );
0420 
0421     propElem = doc.createElement( "default_boot_label" );
0422     propElem.appendChild( doc.createTextNode( defaultBootLabel() ) );
0423     movixOptElem.appendChild( propElem );
0424 
0425     propElem = doc.createElement( "additional_mplayer_options" );
0426     propElem.appendChild( doc.createTextNode( additionalMPlayerOptions() ) );
0427     movixOptElem.appendChild( propElem );
0428 
0429     propElem = doc.createElement( "unwanted_mplayer_options" );
0430     propElem.appendChild( doc.createTextNode( unwantedMPlayerOptions() ) );
0431     movixOptElem.appendChild( propElem );
0432 
0433     propElem = doc.createElement( "loop_playlist" );
0434     propElem.appendChild( doc.createTextNode( QString::number(loopPlaylist()) ) );
0435     movixOptElem.appendChild( propElem );
0436 
0437 
0438     // save the movix items
0439     Q_FOREACH( K3b::MovixFileItem* item, m_movixFiles ) {
0440         QDomElement topElem = doc.createElement( "file" );
0441         topElem.setAttribute( "name", item->k3bName() );
0442         QDomElement urlElem = doc.createElement( "url" );
0443         urlElem.appendChild( doc.createTextNode( item->localPath() ) );
0444         topElem.appendChild( urlElem );
0445         if( item->subTitleItem() ) {
0446             QDomElement subElem = doc.createElement( "subtitle_file" );
0447             urlElem = doc.createElement( "url" );
0448             urlElem.appendChild( doc.createTextNode( item->subTitleItem()->localPath() ) );
0449             subElem.appendChild( urlElem );
0450             topElem.appendChild( subElem );
0451         }
0452 
0453         movixFilesElem.appendChild( topElem );
0454     }
0455 
0456     docElem->appendChild( optionsElem );
0457     docElem->appendChild( headerElem );
0458     docElem->appendChild( movixOptElem );
0459     docElem->appendChild( movixFilesElem );
0460 
0461     return true;
0462 }
0463 
0464 #include "moc_k3bmovixdoc.cpp"