File indexing completed on 2025-03-16 04:29:30
0001 /* 0002 SPDX-FileCopyrightText: 1998-2010 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "k3bdvdbooktypejob.h" 0007 0008 #include "k3bglobals.h" 0009 #include "k3bprocess.h" 0010 #include "k3bdevice.h" 0011 #include "k3bdeviceglobals.h" 0012 #include "k3bdevicehandler.h" 0013 #include "k3bdiskinfo.h" 0014 #include "k3bexternalbinmanager.h" 0015 #include "k3bcore.h" 0016 #include "k3bversion.h" 0017 #include "k3bglobalsettings.h" 0018 #include "k3b_i18n.h" 0019 0020 #include <QDebug> 0021 #include <QRegExp> 0022 0023 #include <errno.h> 0024 #include <string.h> 0025 0026 0027 class K3b::DvdBooktypeJob::Private 0028 { 0029 public: 0030 Private() 0031 : device(0), 0032 process(0), 0033 dvdBooktypeBin(0), 0034 running(false), 0035 forceNoEject(false) { 0036 } 0037 0038 K3b::Device::Device* device; 0039 K3b::Process* process; 0040 const K3b::ExternalBin* dvdBooktypeBin; 0041 0042 bool success; 0043 bool canceled; 0044 bool running; 0045 0046 bool forceNoEject; 0047 0048 int foundMediaType; 0049 }; 0050 0051 0052 K3b::DvdBooktypeJob::DvdBooktypeJob( K3b::JobHandler* jh, QObject* parent ) 0053 : K3b::Job( jh, parent ), 0054 m_action(0) 0055 { 0056 d = new Private; 0057 } 0058 0059 0060 K3b::DvdBooktypeJob::~DvdBooktypeJob() 0061 { 0062 delete d->process; 0063 delete d; 0064 } 0065 0066 0067 void K3b::DvdBooktypeJob::setForceNoEject( bool b ) 0068 { 0069 d->forceNoEject = b; 0070 } 0071 0072 0073 QString K3b::DvdBooktypeJob::jobDescription() const 0074 { 0075 return i18n("Changing DVD Booktype"); // Changing DVD±R(W) Booktype 0076 } 0077 0078 0079 QString K3b::DvdBooktypeJob::jobDetails() const 0080 { 0081 return QString(); 0082 } 0083 0084 0085 void K3b::DvdBooktypeJob::start() 0086 { 0087 d->canceled = false; 0088 d->running = true; 0089 0090 jobStarted(); 0091 0092 if( !d->device ) { 0093 emit infoMessage( i18n("No device set"), MessageError ); 0094 jobFinished(false); 0095 d->running = false; 0096 return; 0097 } 0098 0099 // 0100 // In case we want to change the writers default we do not need to wait for a media 0101 // 0102 if( m_action == SET_MEDIA_DVD_ROM || 0103 m_action == SET_MEDIA_DVD_R_W ) { 0104 emit newSubTask( i18n("Waiting for media") ); 0105 if( waitForMedium( d->device, 0106 K3b::Device::STATE_COMPLETE|K3b::Device::STATE_INCOMPLETE|K3b::Device::STATE_EMPTY, 0107 K3b::Device::MEDIA_DVD_PLUS_RW|K3b::Device::MEDIA_DVD_PLUS_R, 0108 0, 0109 i18n("Please insert an empty DVD+R or a DVD+RW medium into drive<p><b>%1 %2 (%3)</b>.", 0110 d->device->vendor(), 0111 d->device->description(), 0112 d->device->blockDeviceName()) ) == Device::MEDIA_UNKNOWN ) { 0113 emit canceled(); 0114 jobFinished(false); 0115 d->running = false; 0116 return; 0117 } 0118 0119 emit infoMessage( i18n("Checking medium"), MessageInfo ); 0120 emit newTask( i18n("Checking medium") ); 0121 0122 connect( K3b::Device::sendCommand( K3b::Device::DeviceHandler::CommandDiskInfo, d->device ), 0123 SIGNAL(finished(K3b::Device::DeviceHandler*)), 0124 this, 0125 SLOT(slotDeviceHandlerFinished(K3b::Device::DeviceHandler*)) ); 0126 } 0127 else { 0128 // change writer defaults 0129 startBooktypeChange(); 0130 } 0131 } 0132 0133 0134 void K3b::DvdBooktypeJob::start( K3b::Device::DeviceHandler* dh ) 0135 { 0136 d->canceled = false; 0137 d->running = true; 0138 0139 jobStarted(); 0140 0141 slotDeviceHandlerFinished( dh ); 0142 } 0143 0144 0145 void K3b::DvdBooktypeJob::cancel() 0146 { 0147 if( d->running ) { 0148 d->canceled = true; 0149 if( d->process ) 0150 d->process->terminate(); 0151 } 0152 else { 0153 qDebug() << "(K3b::DvdBooktypeJob) not running."; 0154 } 0155 } 0156 0157 0158 void K3b::DvdBooktypeJob::setDevice( K3b::Device::Device* dev ) 0159 { 0160 d->device = dev; 0161 } 0162 0163 0164 void K3b::DvdBooktypeJob::slotStderrLine( const QString& line ) 0165 { 0166 emit debuggingOutput( "dvd+rw-booktype", line ); 0167 // FIXME 0168 } 0169 0170 0171 void K3b::DvdBooktypeJob::slotProcessFinished( int exitCode, QProcess::ExitStatus exitStatus ) 0172 { 0173 if( d->canceled ) { 0174 emit canceled(); 0175 d->success = false; 0176 } 0177 else if( exitStatus == QProcess::NormalExit ) { 0178 if( exitCode == 0 ) { 0179 emit infoMessage( i18n("Booktype successfully changed"), K3b::Job::MessageSuccess ); 0180 d->success = true; 0181 } 0182 else { 0183 emit infoMessage( i18n("%1 returned an unknown error (code %2).",d->dvdBooktypeBin->name(), exitCode), 0184 K3b::Job::MessageError ); 0185 emit infoMessage( i18n("Please send me an email with the last output."), K3b::Job::MessageError ); 0186 0187 d->success = false; 0188 } 0189 } 0190 else { 0191 emit infoMessage( i18n("%1 did not exit cleanly.",d->dvdBooktypeBin->name()), 0192 MessageError ); 0193 d->success = false; 0194 } 0195 0196 // 0197 // No need to eject the media if we changed the writer's default 0198 // 0199 if( m_action == SET_MEDIA_DVD_ROM || 0200 m_action == SET_MEDIA_DVD_R_W ) { 0201 0202 if( d->forceNoEject || 0203 !k3bcore->globalSettings()->ejectMedia() ) { 0204 d->running = false; 0205 jobFinished(d->success); 0206 } 0207 else { 0208 emit infoMessage( i18n("Ejecting DVD..."), MessageInfo ); 0209 connect( K3b::Device::eject( d->device ), 0210 SIGNAL(finished(K3b::Device::DeviceHandler*)), 0211 this, 0212 SLOT(slotEjectingFinished(K3b::Device::DeviceHandler*)) ); 0213 } 0214 } 0215 else { 0216 d->running = false; 0217 jobFinished(d->success); 0218 } 0219 } 0220 0221 0222 void K3b::DvdBooktypeJob::slotEjectingFinished( K3b::Device::DeviceHandler* dh ) 0223 { 0224 if( !dh->success() ) 0225 emit infoMessage( i18n("Unable to eject media."), MessageError ); 0226 0227 d->running = false; 0228 jobFinished(d->success); 0229 } 0230 0231 0232 void K3b::DvdBooktypeJob::slotDeviceHandlerFinished( K3b::Device::DeviceHandler* dh ) 0233 { 0234 if( d->canceled ) { 0235 emit canceled(); 0236 d->running = false; 0237 jobFinished(false); 0238 } 0239 0240 if( dh->success() ) { 0241 0242 d->foundMediaType = dh->diskInfo().mediaType(); 0243 if( d->foundMediaType == K3b::Device::MEDIA_DVD_PLUS_R ) { 0244 // the media needs to be empty 0245 if( dh->diskInfo().empty() ) 0246 startBooktypeChange(); 0247 else { 0248 emit infoMessage( i18n("Cannot change booktype on non-empty DVD+R media."), MessageError ); 0249 jobFinished(false); 0250 } 0251 } 0252 else if( d->foundMediaType == K3b::Device::MEDIA_DVD_PLUS_RW ) { 0253 startBooktypeChange(); 0254 } 0255 else { 0256 emit infoMessage( i18n("No DVD+R(W) media found."), MessageError ); 0257 jobFinished(false); 0258 } 0259 } 0260 else { 0261 emit infoMessage( i18n("Unable to determine media state."), MessageError ); 0262 d->running = false; 0263 jobFinished(false); 0264 } 0265 } 0266 0267 0268 void K3b::DvdBooktypeJob::startBooktypeChange() 0269 { 0270 delete d->process; 0271 d->process = new K3b::Process(); 0272 d->process->setSuppressEmptyLines(true); 0273 connect( d->process, SIGNAL(stderrLine(QString)), this, SLOT(slotStderrLine(QString)) ); 0274 connect( d->process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotProcessFinished(int,QProcess::ExitStatus)) ); 0275 0276 d->dvdBooktypeBin = k3bcore->externalBinManager()->binObject( "dvd+rw-booktype" ); 0277 if( !d->dvdBooktypeBin ) { 0278 emit infoMessage( i18n("Could not find %1 executable.",QString("dvd+rw-booktype")), MessageError ); 0279 d->running = false; 0280 jobFinished(false); 0281 return; 0282 } 0283 0284 *d->process << d->dvdBooktypeBin; 0285 0286 switch( m_action ) { 0287 case SET_MEDIA_DVD_ROM: 0288 *d->process << "-dvd-rom-spec" 0289 << "-media"; 0290 break; 0291 case SET_MEDIA_DVD_R_W: 0292 if( d->foundMediaType == K3b::Device::MEDIA_DVD_PLUS_RW ) 0293 *d->process << "-dvd+rw-spec"; 0294 else 0295 *d->process << "-dvd+r-spec"; 0296 *d->process << "-media"; 0297 break; 0298 case SET_UNIT_DVD_ROM_ON_NEW_DVD_R: 0299 *d->process << "-dvd-rom-spec" 0300 << "-unit+r"; 0301 break; 0302 case SET_UNIT_DVD_ROM_ON_NEW_DVD_RW: 0303 *d->process << "-dvd-rom-spec" 0304 << "-unit+rw"; 0305 break; 0306 case SET_UNIT_DVD_R_ON_NEW_DVD_R: 0307 *d->process << "-dvd+r-spec" 0308 << "-unit+r"; 0309 break; 0310 case SET_UNIT_DVD_RW_ON_NEW_DVD_RW: 0311 *d->process << "-dvd+rw-spec" 0312 << "-unit+rw"; 0313 break; 0314 } 0315 0316 *d->process << d->device->blockDeviceName(); 0317 0318 qDebug() << "***** dvd+rw-booktype parameters:\n"; 0319 QString s = d->process->joinedArgs(); 0320 qDebug() << s << Qt::endl << Qt::flush; 0321 emit debuggingOutput( "dvd+rw-booktype command:", s ); 0322 0323 if( !d->process->start( KProcess::OnlyStderrChannel ) ) { 0324 // something went wrong when starting the program 0325 // it "should" be the executable 0326 emit infoMessage( i18n("Could not start %1.",d->dvdBooktypeBin->name()), K3b::Job::MessageError ); 0327 d->running = false; 0328 jobFinished(false); 0329 } 0330 else { 0331 emit newTask( i18n("Changing Booktype") ); 0332 } 0333 } 0334 0335 #include "moc_k3bdvdbooktypejob.cpp"