You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
k3b/libk3b/projects/videocd/k3bvcddoc.cpp

895 lines
32 KiB

/*
*
* $Id: k3bvcddoc.cpp 619556 2007-01-03 17:38:12Z trueg $
* Copyright (C) 2003-2005 Christian Kvasny <chris@k3b.org>
*
* This file is part of the K3b project.
* Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
*
* 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.
*/
// QT-includes
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqfile.h>
#include <tqdatastream.h>
#include <tqdom.h>
#include <tqdatetime.h>
#include <tqtimer.h>
#include <tqtextstream.h>
// KDE-includes
#include <kprocess.h>
#include <kurl.h>
#include <kapplication.h>
#include <kmessagebox.h>
#include <kconfig.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kio/global.h>
#include <kdebug.h>
#include <kstdguiitem.h>
// K3b-includes
#include "k3bvcddoc.h"
#include "k3bvcdtrack.h"
#include "k3bvcdjob.h"
#include <k3bglobals.h>
#include <k3bmsf.h>
bool desperate_mode = false;
bool preserve_header = false;
bool print_progress = true;
bool aspect_correction = false;
byte forced_sequence_header = 0;
K3bVcdDoc::K3bVcdDoc( TQObject* parent )
: K3bDoc( parent )
{
m_tracks = 0L;
m_vcdOptions = new K3bVcdOptions();
m_docType = VCD;
m_vcdType = NONE;
m_urlAddingTimer = new TQTimer( this );
connect( m_urlAddingTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotWorkUrlQueue() ) );
// FIXME: remove the newTracks() signal and replace it with the changed signal
connect( this, TQT_SIGNAL( newTracks() ), this, TQT_SIGNAL( changed() ) );
connect( this, TQT_SIGNAL( trackRemoved( K3bVcdTrack* ) ), this, TQT_SIGNAL( changed() ) );
}
K3bVcdDoc::~K3bVcdDoc()
{
if ( m_tracks ) {
m_tracks->setAutoDelete( true );
delete m_tracks;
}
delete m_vcdOptions;
}
bool K3bVcdDoc::newDocument()
{
if ( m_tracks )
while ( m_tracks->first() )
removeTrack( m_tracks->first() );
else
m_tracks = new TQPtrList<K3bVcdTrack>;
m_tracks->setAutoDelete( false );
return K3bDoc::newDocument();
}
TQString K3bVcdDoc::name() const
{
return m_vcdOptions->volumeId();
}
KIO::filesize_t K3bVcdDoc::calcTotalSize() const
{
unsigned long long sum = 0;
if ( m_tracks ) {
for ( K3bVcdTrack * track = m_tracks->first(); track; track = m_tracks->next() ) {
sum += track->size();
}
}
return sum;
}
KIO::filesize_t K3bVcdDoc::size() const
{
// mode2 -> mode1 int(( n+2047 ) / 2048) * 2352
// mode1 -> mode2 int(( n+2351 ) / 2352) * 2048
long tracksize = long( ( calcTotalSize() + 2351 ) / 2352 ) * 2048;
return tracksize + ISOsize();
}
KIO::filesize_t K3bVcdDoc::ISOsize() const
{
// 136000b for vcd iso reseved
long long iso_size = 136000;
if ( vcdOptions() ->CdiSupport() ) {
iso_size += vcdOptions() ->CDIsize();
}
return iso_size;
}
K3b::Msf K3bVcdDoc::length() const
{
return K3b::Msf( size() / 2048 );
}
bool K3bVcdDoc::isImage( const KURL& url )
{
TQImage p;
return p.load( TQFile::encodeName( url.path() ) );
}
void K3bVcdDoc::addUrls( const KURL::List& urls )
{
// make sure we add them at the end even if urls are in the queue
addTracks( urls, 99 );
}
void K3bVcdDoc::addTracks( const KURL::List& urls, uint position )
{
KURL::List::ConstIterator end( urls.end() );
for ( KURL::List::ConstIterator it = urls.begin(); it != end; ++it ) {
urlsToAdd.enqueue( new PrivateUrlToAdd( K3b::convertToLocalUrl(*it), position++ ) );
}
m_urlAddingTimer->start( 0 );
}
void K3bVcdDoc::slotWorkUrlQueue()
{
if ( !urlsToAdd.isEmpty() ) {
PrivateUrlToAdd * item = urlsToAdd.dequeue();
lastAddedPosition = item->position;
// append at the end by default
if ( lastAddedPosition > m_tracks->count() )
lastAddedPosition = m_tracks->count();
if ( !item->url.isLocalFile() ) {
kdDebug() << item->url.path() << " no local file" << endl;
return ;
}
if ( !TQFile::exists( item->url.path() ) ) {
kdDebug() << "(K3bVcdDoc) file not found: " << item->url.path() << endl;
m_notFoundFiles.append( item->url.path() );
return ;
}
if ( K3bVcdTrack * newTrack = createTrack( item->url ) )
addTrack( newTrack, lastAddedPosition );
delete item;
emit newTracks();
} else {
m_urlAddingTimer->stop();
emit newTracks();
// reorder pbc tracks
setPbcTracks();
informAboutNotFoundFiles();
}
}
K3bVcdTrack* K3bVcdDoc::createTrack( const KURL& url )
{
char filename[ 255 ];
TQString error_string = "";
strcpy( filename, TQFile::encodeName( url.path() ) );
K3bMpegInfo* Mpeg = new K3bMpegInfo( filename );
if ( Mpeg ) {
int mpegVersion = Mpeg->version();
if ( mpegVersion > 0 ) {
if ( vcdType() == NONE && mpegVersion < 2 ) {
m_urlAddingTimer->stop();
setVcdType( vcdTypes( mpegVersion ) );
vcdOptions() ->setMpegVersion( mpegVersion );
KMessageBox::information( kapp->mainWidget(),
i18n( "K3b will create a %1 image from the given MPEG "
"files, but these files must already be in %2 "
"format. K3b does not yet resample MPEG files." )
.arg( i18n( "VCD" ) )
.arg( i18n( "VCD" ) ),
i18n( "Information" ) );
m_urlAddingTimer->start( 0 );
} else if ( vcdType() == NONE ) {
m_urlAddingTimer->stop();
vcdOptions() ->setMpegVersion( mpegVersion );
bool force = false;
force = ( KMessageBox::questionYesNo( kapp->mainWidget(),
i18n( "K3b will create a %1 image from the given MPEG "
"files, but these files must already be in %2 "
"format. K3b does not yet resample MPEG files." )
.arg( i18n( "SVCD" ) )
.arg( i18n( "SVCD" ) )
+ "\n\n"
+ i18n( "Note: Forcing MPEG2 as VCD is not supported by "
"some standalone DVD players." ),
i18n( "Information" ),
KStdGuiItem::ok().text(),
i18n( "Forcing VCD" ) ) == KMessageBox::No );
if ( force ) {
setVcdType( vcdTypes( 1 ) );
vcdOptions() ->setAutoDetect( false );
} else
setVcdType( vcdTypes( mpegVersion ) );
m_urlAddingTimer->start( 0 );
}
if ( numOfTracks() > 0 && vcdOptions() ->mpegVersion() != mpegVersion ) {
KMessageBox::error( kapp->mainWidget(), "(" + url.path() + ")\n" +
i18n( "You cannot mix MPEG1 and MPEG2 video files.\nPlease start a new Project for this filetype.\nResample not implemented in K3b yet." ),
i18n( "Wrong File Type for This Project" ) );
delete Mpeg;
return 0;
}
K3bVcdTrack* newTrack = new K3bVcdTrack( m_tracks, url.path() );
*( newTrack->mpeg_info ) = *( Mpeg->mpeg_info );
if ( newTrack->isSegment() && !vcdOptions()->PbcEnabled() ) {
KMessageBox::information( kapp->mainWidget(),
i18n( "PBC (Playback control) enabled.\n"
"Videoplayers can not reach Segments (Mpeg Still Pictures) without Playback control ." ) ,
i18n( "Information" ) );
vcdOptions()->setPbcEnabled( true );
}
// set defaults;
newTrack->setPlayTime( vcdOptions() ->PbcPlayTime() );
newTrack->setWaitTime( vcdOptions() ->PbcWaitTime() );
newTrack->setPbcNumKeys( vcdOptions() ->PbcNumkeysEnabled() );
delete Mpeg;
// debugging output
newTrack->PrintInfo();
return newTrack;
}
} else if ( isImage( url ) ) { // image track
// woking on ...
// for future use
// photoalbum starts here
// return here the new photoalbum track
}
if ( Mpeg ) {
error_string = Mpeg->error_string();
delete Mpeg;
}
// error (unsupported files)
KMessageBox::error( kapp->mainWidget(), "(" + url.path() + ")\n" +
i18n( "Only MPEG1 and MPEG2 video files are supported.\n" ) + error_string ,
i18n( "Wrong File Format" ) );
return 0;
}
void K3bVcdDoc::addTrack( const KURL& url, uint position )
{
urlsToAdd.enqueue( new PrivateUrlToAdd( url, position ) );
m_urlAddingTimer->start( 0 );
}
void K3bVcdDoc::addTrack( K3bVcdTrack* track, uint position )
{
if ( m_tracks->count() >= 98 ) {
kdDebug() << "(K3bVcdDoc) VCD Green Book only allows 98 tracks." << endl;
// TODO: show some messagebox
delete track;
return ;
}
lastAddedPosition = position;
if ( !m_tracks->insert( position, track ) ) {
lastAddedPosition = m_tracks->count();
m_tracks->insert( m_tracks->count(), track );
}
if ( track->isSegment() )
vcdOptions() ->increaseSegments( );
else
vcdOptions() ->increaseSequence( );
emit newTracks();
setModified( true );
}
void K3bVcdDoc::removeTrack( K3bVcdTrack* track )
{
if ( !track ) {
return ;
}
// set the current item to track
if ( m_tracks->findRef( track ) >= 0 ) {
// take the current item
track = m_tracks->take();
// remove all pbc references to us?
if ( track->hasRevRef() )
track->delRefToUs();
// remove all pbc references from us?
track->delRefFromUs();
// emit signal before deleting the track to avoid crashes
// when the view tries to call some of the tracks' methods
emit trackRemoved( track );
if ( track->isSegment() )
vcdOptions() ->decreaseSegments( );
else
vcdOptions() ->decreaseSequence( );
delete track;
if ( numOfTracks() == 0 ) {
setVcdType( NONE );
vcdOptions() ->setAutoDetect( true );
}
// reorder pbc tracks
setPbcTracks();
}
}
void K3bVcdDoc::moveTrack( const K3bVcdTrack* track, const K3bVcdTrack* after )
{
if ( track == after )
return ;
// set the current item to track
m_tracks->findRef( track );
// take the current item
track = m_tracks->take();
// if after == 0 findRef returnes -1
int pos = m_tracks->findRef( after );
m_tracks->insert( pos + 1, track );
// reorder pbc tracks
setPbcTracks();
emit changed();
}
TQString K3bVcdDoc::typeString() const
{
return "vcd";
}
K3bBurnJob* K3bVcdDoc::newBurnJob( K3bJobHandler* hdl, TQObject* parent )
{
return new K3bVcdJob( this, hdl, parent );
}
void K3bVcdDoc::informAboutNotFoundFiles()
{
if ( !m_notFoundFiles.isEmpty() ) {
KMessageBox::informationList( view(), i18n( "Could not find the following files:" ),
m_notFoundFiles, i18n( "Not Found" ) );
m_notFoundFiles.clear();
}
}
void K3bVcdDoc::setVcdType( int type )
{
m_vcdType = type;
switch ( type ) {
case 0:
//vcd 1.1
vcdOptions() ->setVcdClass( "vcd" );
vcdOptions() ->setVcdVersion( "1.1" );
break;
case 1:
//vcd 2.0
vcdOptions() ->setVcdClass( "vcd" );
vcdOptions() ->setVcdVersion( "2.0" );
break;
case 2:
//svcd 1.0
vcdOptions() ->setVcdClass( "svcd" );
vcdOptions() ->setVcdVersion( "1.0" );
break;
case 3:
//hqvcd 1.0
vcdOptions() ->setVcdClass( "hqvcd" );
vcdOptions() ->setVcdVersion( "1.0" );
break;
}
}
void K3bVcdDoc::setPbcTracks()
{
// reorder pbc tracks
/*
if ( !vcdOptions()->PbcEnabled() )
return;
*/
if ( m_tracks ) {
int count = m_tracks->count();
kdDebug() << TQString( "K3bVcdDoc::setPbcTracks() - we have %1 tracks in list." ).arg( count ) << endl;
TQPtrListIterator<K3bVcdTrack> iterTrack( *m_tracks );
K3bVcdTrack* track;
while ( ( track = iterTrack.current() ) != 0 ) {
++iterTrack;
for ( int i = 0; i < K3bVcdTrack::_maxPbcTracks; i++ ) {
// do not change userdefined tracks
if ( !track->isPbcUserDefined( i ) ) {
if ( track->getPbcTrack( i ) )
track->getPbcTrack( i ) ->delFromRevRefList( track );
K3bVcdTrack* t = 0L;
int index = track->index();
// we are the last track
if ( index == count - 1 ) {
switch ( i ) {
case K3bVcdTrack::PREVIOUS:
// we are not alone :)
if ( count > 1 ) {
t = at( index - 1 );
t->addToRevRefList( track );
track->setPbcTrack( i, t );
} else {
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::VIDEOEND );
}
break;
case K3bVcdTrack::AFTERTIMEOUT:
case K3bVcdTrack::NEXT:
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::VIDEOEND );
break;
case K3bVcdTrack::RETURN:
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::VIDEOEND );
break;
case K3bVcdTrack::DEFAULT:
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::DISABLED );
break;
}
}
// we are the first track
else if ( index == 0 ) {
switch ( i ) {
case K3bVcdTrack::PREVIOUS:
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::VIDEOEND );
break;
case K3bVcdTrack::AFTERTIMEOUT:
case K3bVcdTrack::NEXT:
t = at( index + 1 );
t->addToRevRefList( track );
track->setPbcTrack( i, t );
break;
case K3bVcdTrack::RETURN:
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::VIDEOEND );
break;
case K3bVcdTrack::DEFAULT:
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::DISABLED );
break;
}
}
// we are one of the other tracks and have PREVIOUS and NEXT Track
else {
switch ( i ) {
case K3bVcdTrack::PREVIOUS:
t = at( index - 1 );
t->addToRevRefList( track );
track->setPbcTrack( i, t );
break;
case K3bVcdTrack::AFTERTIMEOUT:
case K3bVcdTrack::NEXT:
t = at( index + 1 );
t->addToRevRefList( track );
track->setPbcTrack( i, t );
break;
case K3bVcdTrack::RETURN:
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::VIDEOEND );
break;
case K3bVcdTrack::DEFAULT:
track->setPbcTrack( i );
track->setPbcNonTrack( i, K3bVcdTrack::DISABLED );
break;
}
}
}
}
}
}
}
bool K3bVcdDoc::loadDocumentData( TQDomElement* root )
{
newDocument();
TQDomNodeList nodes = root->childNodes();
if ( nodes.length() < 3 )
return false;
if ( nodes.item( 0 ).nodeName() != "general" )
return false;
if ( !readGeneralDocumentData( nodes.item( 0 ).toElement() ) )
return false;
if ( nodes.item( 1 ).nodeName() != "vcd" )
return false;
if ( nodes.item( 2 ).nodeName() != "contents" )
return false;
// vcd Label
TQDomNodeList vcdNodes = nodes.item( 1 ).childNodes();
for ( uint i = 0; i < vcdNodes.count(); i++ ) {
TQDomNode item = vcdNodes.item( i );
TQString name = item.nodeName();
kdDebug() << TQString( "(K3bVcdDoc::loadDocumentData) nodeName = '%1'" ).arg( name ) << endl;
if ( name == "volumeId" )
vcdOptions() ->setVolumeId( item.toElement().text() );
else if ( name == "albumId" )
vcdOptions() ->setAlbumId( item.toElement().text() );
else if ( name == "volumeSetId" )
vcdOptions() ->setVolumeSetId( item.toElement().text() );
else if ( name == "preparer" )
vcdOptions() ->setPreparer( item.toElement().text() );
else if ( name == "publisher" )
vcdOptions() ->setPublisher( item.toElement().text() );
else if ( name == "vcdType" )
setVcdType( vcdTypes( item.toElement().text().toInt() ) );
else if ( name == "mpegVersion" )
vcdOptions() ->setMpegVersion( item.toElement().text().toInt() );
else if ( name == "PreGapLeadout" )
vcdOptions() ->setPreGapLeadout( item.toElement().text().toInt() );
else if ( name == "PreGapTrack" )
vcdOptions() ->setPreGapTrack( item.toElement().text().toInt() );
else if ( name == "FrontMarginTrack" )
vcdOptions() ->setFrontMarginTrack( item.toElement().text().toInt() );
else if ( name == "RearMarginTrack" )
vcdOptions() ->setRearMarginTrack( item.toElement().text().toInt() );
else if ( name == "FrontMarginTrackSVCD" )
vcdOptions() ->setFrontMarginTrackSVCD( item.toElement().text().toInt() );
else if ( name == "RearMarginTrackSVCD" )
vcdOptions() ->setRearMarginTrackSVCD( item.toElement().text().toInt() );
else if ( name == "volumeCount" )
vcdOptions() ->setVolumeCount( item.toElement().text().toInt() );
else if ( name == "volumeNumber" )
vcdOptions() ->setVolumeNumber( item.toElement().text().toInt() );
else if ( name == "AutoDetect" )
vcdOptions() ->setAutoDetect( item.toElement().text().toInt() );
else if ( name == "CdiSupport" )
vcdOptions() ->setCdiSupport( item.toElement().text().toInt() );
else if ( name == "NonCompliantMode" )
vcdOptions() ->setNonCompliantMode( item.toElement().text().toInt() );
else if ( name == "Sector2336" )
vcdOptions() ->setSector2336( item.toElement().text().toInt() );
else if ( name == "UpdateScanOffsets" )
vcdOptions() ->setUpdateScanOffsets( item.toElement().text().toInt() );
else if ( name == "RelaxedAps" )
vcdOptions() ->setRelaxedAps( item.toElement().text().toInt() );
else if ( name == "UseGaps" )
vcdOptions() ->setUseGaps( item.toElement().text().toInt() );
else if ( name == "PbcEnabled" )
vcdOptions() ->setPbcEnabled( item.toElement().text().toInt() );
else if ( name == "SegmentFolder" )
vcdOptions() ->setSegmentFolder( item.toElement().text().toInt() );
else if ( name == "Restriction" )
vcdOptions() ->setRestriction( item.toElement().text().toInt() );
}
// vcd Tracks
TQDomNodeList trackNodes = nodes.item( 2 ).childNodes();
for ( uint i = 0; i < trackNodes.length(); i++ ) {
// check if url is available
TQDomElement trackElem = trackNodes.item( i ).toElement();
TQString url = trackElem.attributeNode( "url" ).value();
if ( !TQFile::exists( url ) )
m_notFoundFiles.append( url );
else {
KURL k;
k.setPath( url );
if ( K3bVcdTrack * track = createTrack( k ) ) {
track ->setPlayTime( trackElem.attribute( "playtime", "1" ).toInt() );
track ->setWaitTime( trackElem.attribute( "waittime", "2" ).toInt() );
track ->setReactivity( trackElem.attribute( "reactivity", "0" ).toInt() );
track -> setPbcNumKeys( ( trackElem.attribute( "numkeys", "yes" ).contains( "yes" ) ) ? true : false );
track -> setPbcNumKeysUserdefined( ( trackElem.attribute( "userdefinednumkeys", "no" ).contains( "yes" ) ) ? true : false );
addTrack( track, m_tracks->count() );
}
}
}
emit newTracks();
// do not add saved pbcTrack links when one ore more files missing.
// TODO: add info message to informAboutNotFoundFiles();
if ( m_notFoundFiles.isEmpty() ) {
int type;
int val;
bool pbctrack;
for ( uint trackId = 0; trackId < trackNodes.length(); trackId++ ) {
TQDomElement trackElem = trackNodes.item( trackId ).toElement();
TQDomNodeList trackNodes = trackElem.childNodes();
for ( uint i = 0; i < trackNodes.length(); i++ ) {
TQDomElement trackElem = trackNodes.item( i ).toElement();
TQString name = trackElem.tagName();
if ( name.contains( "pbc" ) ) {
if ( trackElem.hasAttribute ( "type" ) ) {
type = trackElem.attribute ( "type" ).toInt();
if ( trackElem.hasAttribute ( "pbctrack" ) ) {
pbctrack = ( trackElem.attribute ( "pbctrack" ) == "yes" );
if ( trackElem.hasAttribute ( "val" ) ) {
val = trackElem.attribute ( "val" ).toInt();
K3bVcdTrack* track = m_tracks->at( trackId );
K3bVcdTrack* pbcTrack = m_tracks->at( val );
if ( pbctrack ) {
pbcTrack->addToRevRefList( track );
track->setPbcTrack( type, pbcTrack );
track->setUserDefined( type, true );
} else {
track->setPbcTrack( type );
track->setPbcNonTrack( type, val );
track->setUserDefined( type, true );
}
}
}
}
} else if ( name.contains( "numkeys" ) ) {
if ( trackElem.hasAttribute ( "key" ) ) {
int key = trackElem.attribute ( "key" ).toInt();
if ( trackElem.hasAttribute ( "val" ) ) {
int val = trackElem.attribute ( "val" ).toInt() - 1;
K3bVcdTrack* track = m_tracks->at( trackId );
if ( val >= 0 ) {
K3bVcdTrack * numkeyTrack = m_tracks->at( val );
track->setDefinedNumKey( key, numkeyTrack );
} else {
track->setDefinedNumKey( key, 0L );
}
}
}
}
}
}
setPbcTracks();
setModified( false );
}
informAboutNotFoundFiles();
return true;
}
bool K3bVcdDoc::saveDocumentData( TQDomElement * docElem )
{
TQDomDocument doc = docElem->ownerDocument();
saveGeneralDocumentData( docElem );
// save Vcd Label
TQDomElement vcdMain = doc.createElement( "vcd" );
TQDomElement vcdElem = doc.createElement( "volumeId" );
vcdElem.appendChild( doc.createTextNode( vcdOptions() ->volumeId() ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "albumId" );
vcdElem.appendChild( doc.createTextNode( vcdOptions() ->albumId() ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "volumeSetId" );
vcdElem.appendChild( doc.createTextNode( vcdOptions() ->volumeSetId() ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "preparer" );
vcdElem.appendChild( doc.createTextNode( vcdOptions() ->preparer() ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "publisher" );
vcdElem.appendChild( doc.createTextNode( vcdOptions() ->publisher() ) );
vcdMain.appendChild( vcdElem );
// applicationId()
// systemId()
vcdElem = doc.createElement( "vcdType" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdType() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "mpegVersion" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->mpegVersion() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "PreGapLeadout" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->PreGapLeadout() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "PreGapTrack" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->PreGapTrack() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "FrontMarginTrack" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->FrontMarginTrack() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "RearMarginTrack" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->RearMarginTrack() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "FrontMarginTrackSVCD" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->FrontMarginTrackSVCD() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "RearMarginTrackSVCD" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->RearMarginTrackSVCD() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "volumeCount" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->volumeCount() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "volumeNumber" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->volumeNumber() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "AutoDetect" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->AutoDetect() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "CdiSupport" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->CdiSupport() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "NonCompliantMode" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->NonCompliantMode() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "Sector2336" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->Sector2336() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "UpdateScanOffsets" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->UpdateScanOffsets() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "RelaxedAps" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->RelaxedAps() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "UseGaps" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->UseGaps() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "PbcEnabled" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->PbcEnabled() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "SegmentFolder" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->SegmentFolder() ) ) );
vcdMain.appendChild( vcdElem );
vcdElem = doc.createElement( "Restriction" );
vcdElem.appendChild( doc.createTextNode( TQString::number( vcdOptions() ->Restriction() ) ) );
vcdMain.appendChild( vcdElem );
docElem->appendChild( vcdMain );
// save the tracks
// -------------------------------------------------------------
TQDomElement contentsElem = doc.createElement( "contents" );
TQPtrListIterator<K3bVcdTrack> iterTrack( *m_tracks );
K3bVcdTrack* track;
while ( ( track = iterTrack.current() ) != 0 ) {
++iterTrack;
TQDomElement trackElem = doc.createElement( "track" );
trackElem.setAttribute( "url", KIO::decodeFileName( track->absPath() ) );
trackElem.setAttribute( "playtime", track->getPlayTime() );
trackElem.setAttribute( "waittime", track->getWaitTime() );
trackElem.setAttribute( "reactivity", track->Reactivity() );
trackElem.setAttribute( "numkeys", ( track->PbcNumKeys() ) ? "yes" : "no" );
trackElem.setAttribute( "userdefinednumkeys", ( track->PbcNumKeysUserdefined() ) ? "yes" : "no" );
for ( int i = 0;
i < K3bVcdTrack::_maxPbcTracks;
i++ ) {
if ( track->isPbcUserDefined( i ) ) {
// save pbcTracks
TQDomElement pbcElem = doc.createElement( "pbc" );
pbcElem.setAttribute( "type", i );
if ( track->getPbcTrack( i ) ) {
pbcElem.setAttribute( "pbctrack", "yes" );
pbcElem.setAttribute( "val", track->getPbcTrack( i ) ->index() );
} else {
pbcElem.setAttribute( "pbctrack", "no" );
pbcElem.setAttribute( "val", track->getNonPbcTrack( i ) );
}
trackElem.appendChild( pbcElem );
}
}
TQMap<int, K3bVcdTrack*> numKeyMap = track->DefinedNumKey();
TQMap<int, K3bVcdTrack*>::const_iterator trackIt;
for ( trackIt = numKeyMap.begin();
trackIt != numKeyMap.end();
++trackIt ) {
TQDomElement numElem = doc.createElement( "numkeys" );
if ( trackIt.data() ) {
numElem.setAttribute( "key", trackIt.key() );
numElem.setAttribute( "val", trackIt.data() ->index() + 1 );
} else {
numElem.setAttribute( "key", trackIt.key() );
numElem.setAttribute( "val", 0 );
}
trackElem.appendChild( numElem );
}
contentsElem.appendChild( trackElem );
}
// -------------------------------------------------------------
docElem->appendChild( contentsElem );
return true;
}
#include "k3bvcddoc.moc"