File indexing completed on 2024-05-12 04:51:11
0001 /* 0002 SPDX-FileCopyrightText: 1998-2007 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "k3bvideodvdimager.h" 0007 #include "k3bvideodvddoc.h" 0008 #include "k3bdiritem.h" 0009 #include "k3bfileitem.h" 0010 #include "k3bprocess.h" 0011 #include "k3bglobals.h" 0012 #include "k3bisooptions.h" 0013 #include "k3b_i18n.h" 0014 0015 #include <QDebug> 0016 #include <QDir> 0017 #include <QFile> 0018 #include <QList> 0019 #include <QTemporaryDir> 0020 #include <QTextStream> 0021 0022 #include <unistd.h> 0023 0024 0025 class K3b::VideoDvdImager::Private 0026 { 0027 public: 0028 K3b::VideoDvdDoc* doc; 0029 0030 QScopedPointer<QTemporaryDir> tempDir; 0031 }; 0032 0033 0034 K3b::VideoDvdImager::VideoDvdImager( K3b::VideoDvdDoc* doc, K3b::JobHandler* jh, QObject* parent ) 0035 : K3b::IsoImager( doc, jh, parent ), 0036 d( new Private ) 0037 { 0038 d->doc = doc; 0039 } 0040 0041 0042 K3b::VideoDvdImager::~VideoDvdImager() 0043 { 0044 } 0045 0046 0047 void K3b::VideoDvdImager::start() 0048 { 0049 fixVideoDVDSettings(); 0050 K3b::IsoImager::start(); 0051 } 0052 0053 0054 void K3b::VideoDvdImager::init() 0055 { 0056 fixVideoDVDSettings(); 0057 K3b::IsoImager::init(); 0058 } 0059 0060 0061 void K3b::VideoDvdImager::fixVideoDVDSettings() 0062 { 0063 // Video DVD defaults, we cannot set these in K3b::VideoDvdDoc since they 0064 // will be overwritten in the burn dialog unless we create some K3b::VideoDVDIsoOptions 0065 // class with different defaults. But since the whole Video DVD project is a hack we 0066 // go the easy road. 0067 K3b::IsoOptions o = d->doc->isoOptions(); 0068 o.setISOLevel(1); 0069 o.setISOallow31charFilenames(false); 0070 o.setCreateJoliet(false); 0071 o.setJolietLong(false); 0072 o.setCreateRockRidge(false); 0073 o.setCreateUdf(true); 0074 d->doc->setIsoOptions( o ); 0075 } 0076 0077 0078 void K3b::VideoDvdImager::calculateSize() 0079 { 0080 fixVideoDVDSettings(); 0081 K3b::IsoImager::calculateSize(); 0082 } 0083 0084 0085 int K3b::VideoDvdImager::writePathSpec() 0086 { 0087 // 0088 // Create a temp dir and link all contents of the VIDEO_TS dir to make mkisofs 0089 // able to handle the VideoDVD stuff. 0090 // 0091 // mkisofs is not able to create VideoDVDs from graft-points. 0092 // 0093 // We do this here since K3b::IsoImager::start calls cleanup which deletes the temp files 0094 // 0095 d->tempDir.reset(new QTemporaryDir(QDir::tempPath() + "/k3bVideoDvdXXXXXX")); 0096 if (!d->tempDir->isValid()) { 0097 emit infoMessage(xi18n("Unable to create Invalid temporary folder <filename>%1</filename>.", 0098 d->tempDir->path()), MessageError); 0099 return -1; 0100 } 0101 0102 const auto videoDir = 0103 #if QT_VERSION < 0x050900 0104 d->tempDir->path() + "/VIDEO_TS"; 0105 #else 0106 d->tempDir->filePath("VIDEO_TS"); 0107 #endif 0108 if (!QDir().mkpath(videoDir)) { 0109 emit infoMessage(xi18n("Unable to create temporary folder <filename>%1</filename>.", 0110 videoDir), MessageError); 0111 return -1; 0112 } 0113 0114 Q_FOREACH(const K3b::DataItem* item, d->doc->videoTsDir()->children()) { 0115 if (item->isDir()) { 0116 emit infoMessage(xi18n("Found invalid entry in the VIDEO_TS folder <filename>%1</filename>.", 0117 item->k3bName()), MessageError); 0118 return -1; 0119 } 0120 0121 // convert to upper case names 0122 if (::symlink(QFile::encodeName(item->localPath()), 0123 QFile::encodeName(videoDir + '/' + item->k3bName().toUpper())) == -1) { 0124 emit infoMessage(xi18n("Unable to link temporary file in folder <filename>%1</filename>.", 0125 d->tempDir->path()), MessageError); 0126 return -1; 0127 } 0128 } 0129 0130 0131 return K3b::IsoImager::writePathSpec(); 0132 } 0133 0134 0135 int K3b::VideoDvdImager::writePathSpecForDir( K3b::DirItem* dirItem, QTextStream& stream ) 0136 { 0137 // 0138 // We handle the VIDEO_TS dir differently since otherwise mkisofs is not able to 0139 // open the VideoDVD structures (see addMkisofsParameters) 0140 // 0141 if( dirItem == d->doc->videoTsDir() ) { 0142 return 0; 0143 } 0144 0145 int num = 0; 0146 Q_FOREACH( K3b::DataItem* item, dirItem->children() ) { 0147 num++; 0148 0149 if( item->isDir() ) { 0150 // we cannot add the video_ts dir twice 0151 if( item != d->doc->videoTsDir() ) { 0152 stream << escapeGraftPoint( item->writtenPath() ) 0153 << "=" 0154 << escapeGraftPoint( dummyDir( static_cast<K3b::DirItem*>(item) ) ) << "\n"; 0155 } 0156 0157 int x = writePathSpecForDir( dynamic_cast<K3b::DirItem*>(item), stream ); 0158 if( x >= 0 ) 0159 num += x; 0160 else 0161 return -1; 0162 } 0163 else { 0164 writePathSpecForFile( static_cast<K3b::FileItem*>(item), stream ); 0165 } 0166 } 0167 0168 return num; 0169 } 0170 0171 0172 bool K3b::VideoDvdImager::addMkisofsParameters( bool printSize ) 0173 { 0174 // Here is another bad design: we assume that K3b::IsoImager::start does not add additional 0175 // parameters to the process. :( 0176 if( K3b::IsoImager::addMkisofsParameters( printSize ) ) { 0177 *m_process << "-dvd-video"; 0178 *m_process << "-f"; // follow symlinks 0179 *m_process << (d->tempDir ? d->tempDir->path() : QString()); 0180 return true; 0181 } 0182 else 0183 return false; 0184 } 0185 0186 0187 void K3b::VideoDvdImager::cleanup() 0188 { 0189 d->tempDir.reset(); 0190 0191 K3b::IsoImager::cleanup(); 0192 } 0193 0194 0195 void K3b::VideoDvdImager::slotReceivedStderr( const QString& line ) 0196 { 0197 if( line.contains( "Unable to make a DVD-Video image" ) ) { 0198 emit infoMessage( i18n("The project does not contain all necessary Video DVD files."), MessageWarning ); 0199 emit infoMessage( i18n("The resulting DVD will most likely not be playable on a Hifi DVD player."), MessageWarning ); 0200 } 0201 else 0202 K3b::IsoImager::slotReceivedStderr( line ); 0203 } 0204 0205 #include "moc_k3bvideodvdimager.cpp"