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"