void K3bVideoDVDRippingPreview::generatePreview( const K3bVideoDVD::VideoDVD& dvd, int title, int chapter ) { // cleanup first delete m_process; delete m_tempDir; m_process = 0; m_tempDir = 0; m_canceled = false; const K3bExternalBin* bin = k3bcore->externalBinManager()->binObject("transcode"); if( !bin ) { emit previewDone( false ); return; } // auto-select a chapter // choose the center chapter, but not the first or last if possible if( chapter == 0 ) chapter = QMIN( QMAX( dvd[title-1].numChapters()/2, 2 ), QMAX( dvd[title-1].numChapters() - 1, 1 ) ); // select a frame number unsigned int frame = 30; if( dvd[title-1][chapter-1].playbackTime().totalFrames() < frame ) frame = dvd[title-1][chapter-1].playbackTime().totalFrames() / 2; m_dvd = dvd; m_title = title; m_chapter = chapter; m_tempDir = new KTempDir(); m_tempDir->setAutoDelete( true ); m_process = new KProcess(); *m_process << bin->path; *m_process << "-i" << dvd.device()->blockDeviceName(); *m_process << "-T" << QString("%1,%2").arg(title).arg(chapter); *m_process << "-x" << "dvd,null"; *m_process << "--dvd_access_delay" << "0"; *m_process << "-y" << "ppm,null"; *m_process << "-c" << QString("%1-%2").arg( frame ).arg( frame+1 ); *m_process << "-Z" << "x200"; *m_process << "-o" << m_tempDir->name(); connect( m_process, SIGNAL(processExited(KProcess*)), this, SLOT(slotTranscodeFinished(KProcess*)) ); if( !m_process->start( KProcess::NotifyOnExit, KProcess::AllOutput ) ) { // we use AllOutput to not pollute stdout // something went wrong when starting the program // it "should" be the executable kdDebug() << "(K3bVideoDVDRippingPreview) Could not start transcode." << endl; delete m_process; delete m_tempDir; m_process = 0; m_tempDir = 0; emit previewDone( false ); } }
void K3bVideoDVDRippingPreview::slotTranscodeFinished( KProcess* ) { // read the image QString filename = m_tempDir->name() + "000000.ppm";// + tempQDir->entryList( QDir::Files ).first(); kdDebug() << "(K3bVideoDVDRippingPreview) reading from file " << filename << endl; m_preview = QImage( filename ); bool success = !m_preview.isNull() && !m_canceled; // remove temp files delete m_tempDir; m_tempDir = 0; // clean up delete m_process; m_process = 0; // retry the first chapter in case another failed if( !success && m_chapter > 1 ) generatePreview( m_dvd, m_title, 1 ); else emit previewDone( success ); }
void PreviewWidget::showActivePreview(const QString &text,const QString &textfilename,int startrow,int previewtype) { KILE_DEBUG() << "==PreviewWidget::showActivePreview()=========================="; m_info->logWidget()->clear(); if(m_running || m_info->quickPreview()->isRunning()) { showError( i18n("There is already a preview running that has to be finished to run this one.") ); return; } // determine the type of conversion int conversiontype; switch(previewtype) { case KileTool::qpSelection: conversiontype = KileConfig::selPreviewTool(); break; case KileTool::qpEnvironment: conversiontype = KileConfig::envPreviewTool(); break; case KileTool::qpMathgroup: conversiontype = KileConfig::mathgroupPreviewTool(); break; default: // should not happen conversiontype = pwDvipng; break; } // set parameter for these tools QString tasklist, tool, toolcfg, extension; if(conversiontype == pwConvert) { m_conversionTool = "convert"; tasklist = "PreviewPDFLaTeX,,,,,png"; tool = "Convert"; toolcfg = "pdf2png"; extension = "pdf"; } else if(conversiontype == pwDvipsConvert) { m_conversionTool = "dvips/convert"; tasklist = "PreviewLaTeX,DVItoPS,dvi2eps,,,png"; tool = "Convert"; toolcfg = "eps2png"; extension = "eps"; } else { m_conversionTool = "dvipng"; tasklist = "PreviewLaTeX,,,,,png"; tool = "DVItoPNG"; toolcfg.clear(); extension = "dvi"; } if(!m_info->quickPreview()->run(text, textfilename, startrow, tasklist)) { return; } KileTool::Base *pngConverter = m_info->toolFactory()->create(tool); if(!pngConverter) { showError(i18n("Could not run '%1' for QuickPreview.", tool)); return; } pngConverter->setSource(m_info->quickPreview()->getPreviewFile(extension)); // First, we have to disconnect the old done() signal, because this is // passed immediately to the toolmanager, whichs destroys the tool. This // means, that all connections, which are done later, will never been called. disconnect(pngConverter, SIGNAL(done(Base*,int)), m_info->toolManager(), SLOT(done(Base*,int))); // Now we make some new connections, which are called in this sequence: // 1) when the tool is finished, the preview will be shown // 2) then the done() signal can be passed to the toolmanager, // which destroys the tool connect(pngConverter, SIGNAL(done (Base*,int)), this, SLOT(drawImage())); connect(pngConverter, SIGNAL(done(Base*,int)), m_info->toolManager(), SLOT(done(Base*,int))); // Finally we will send a signal, which will pass the focus from the log window // to the formula preview (dvipng --> toolmanager --> kile) // // Remark: // It's also possible to use only (!) the destroyed() signal. This must be sent // to the toolmanager, which passes it over to the kile object. This object can // call drawImage() and after it, we have to set the focus to the preview widget. // This can only be done from the kile object, which explains this indirect way. // // But i (dani) prefer the chosen way above, because // - we can distinguish between drawImage() and focusPreview(), which may be // important some time // - it is more complicated connect(pngConverter, SIGNAL(destroyed()), m_info->toolManager(), SIGNAL(previewDone())); connect(pngConverter, SIGNAL(destroyed()), this, SLOT(toolDestroyed())); // Now we are ready to start the process... if(m_info->toolManager()->run(pngConverter,toolcfg) == KileTool::Running) { m_running = true; } }