Logo Search packages:      
Sourcecode: kdenlive version File versions

capturemonitor.cpp

/***************************************************************************
                          capturemonitor  -  description
                             -------------------
    begin                : Sun Jun 12 2005
    copyright            : (C) 2005 by Jason Wood
    email                : jasonwood@blueyonder.co.uk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
#include "capturemonitor.h"

#include <qtoolbutton.h>

#include <kled.h>
#include <klocale.h>
#include <kio/netaccess.h>
#include <kstandarddirs.h>
#include <klineeditdlg.h>
#include <kurlrequester.h>
#include <klistview.h>
#include <kiconloader.h>
#include <kmessagebox.h>

#include "kdenlivedoc.h"
#include "kmmrecpanel.h"


00035 namespace Gui {

    CaptureMonitor::CaptureMonitor(KdenliveApp * app, QWidget * parent,
      const char *name):KMonitor(parent, name),
      m_app(app), m_screenHolder(new QVBox(this,name)), m_screen(new QWidget(m_screenHolder, name)),
      m_recPanel(new KMMRecPanel(app->getDocument(), this, name)), captureProcess(0), hasCapturedFiles(false), m_tmpFolder(QString::null)
    {
      m_fileNumber = 0;
      m_screen->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
      m_screen->setBackgroundMode(Qt::PaletteDark);
      slotCheckCaptureStatus();
      m_recPanel->capture_format->setCurrentItem(KdenliveSettings::captureformat());

      connect(m_recPanel, SIGNAL(activateMonitor()), this,  SLOT(activateMonitor()));
      connect(m_recPanel, SIGNAL(stopDevice()), this, SLOT(slotStop()));
      connect(m_recPanel, SIGNAL(playDevice()), this, SLOT(slotPlay()));
      connect(m_recPanel, SIGNAL(pauseDevice()), this, SLOT(slotPause()));
      connect(m_recPanel, SIGNAL(recDevice()), this, SLOT(slotRec()));
      connect(m_recPanel, SIGNAL(forwardDevice()), this, SLOT(slotFastForward()));
      connect(m_recPanel, SIGNAL(stepForwardDevice()), this, SLOT(slotForward()));
      connect(m_recPanel, SIGNAL(rewindDevice()), this, SLOT(slotRewind()));
      connect(m_recPanel, SIGNAL(stepRewindDevice()), this, SLOT(slotReverse()));
    } 

    CaptureMonitor::~CaptureMonitor() {
      if (captureProcess) delete captureProcess;
    }

    void CaptureMonitor::slotCheckCaptureStatus() {
      QObject *label = m_screenHolder->child("warn_message");
      if (label) delete label;
      label = m_screenHolder->child("warn_button");
      if (label) delete label;
      QString warnMessage;
      if (KStandardDirs::findExe("dvgrab") == QString::null ||KStandardDirs::findExe("ffplay") == QString::null) {
            warnMessage = i18n("<b>The programs dvgrab or ffplay are missing</b>.<br>Firewire capture will be disabled until you install them.");
            m_readyForCapture = false;
      }
      else if (!KIO::NetAccess::exists(KURL("/dev/raw1394"), false, this)) {
            if (!warnMessage.isEmpty()) warnMessage += "<br>";
            warnMessage += i18n("<b>Device not detected. Make sure that the camcorder is turned on. Please check that the kernel module raw1394 is loaded and that you have write permission to /dev/raw1394 or equivalent.");
            m_readyForCapture = false;
      }
      else m_readyForCapture = true;
      m_recPanel->setEnabled(m_readyForCapture);
      if (!m_readyForCapture) {
            QLabel *warningLabel = new QLabel(warnMessage, m_screenHolder, "warn_message");
            QPushButton *pb = new QPushButton(i18n("Check again"), m_screenHolder, "warn_button");
            connect(pb, SIGNAL(clicked()), this, SLOT(slotCheckCaptureStatus()));
            warningLabel->setPaletteBackgroundColor(Qt::red);
            warningLabel->setMargin(5);
            warningLabel->show();
            pb->show();
      }
    }
    
    void CaptureMonitor::exportCurrentFrame(KURL url, bool notify) const {
      // TODO FIXME
    } 

    KMMEditPanel *CaptureMonitor::editPanel() const {
      // TODO FIXME
      return 0;
    } 
    
    KMMScreen *CaptureMonitor::screen() const {
      // TODO FIXME
      return 0;
    } 

    void CaptureMonitor::activateMonitor() {
      m_app->activateMonitor(this);
    }

    void CaptureMonitor::slotSetActive() {
        m_recPanel->rendererConnected();
    }
    
    DocClipRef *CaptureMonitor::clip() const {
      return 0;
    } 
    
    void CaptureMonitor::slotSetupScreen() {
      //m_screen->setCapture();
    }

    void CaptureMonitor::slotRewind() {
      if (!captureProcess) slotInit();
      captureProcess->writeStdin("a", 1);
    }

    void CaptureMonitor::slotReverse() {
      if (!captureProcess) slotInit();
      captureProcess->writeStdin("j", 1);
    }


void CaptureMonitor::displayCapturedFiles()
{
      if (m_tmpFolder.isEmpty()) return;
      KDialogBase *dia = new KDialogBase(  KDialogBase::Swallow, i18n("Captured Clips"), KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, this, "captured_clips", true);
      dia->setButtonOKText (i18n("Process captured files"));
      dia->setButtonCancelText (i18n("Continue capture..."));
      QVBox *page = new QVBox(dia);
      KListView *lv = new KListView(page);
      lv->addColumn(i18n("Add"));
      lv->addColumn("original_name",0);
      lv->addColumn(i18n("Clip Name"));
      lv->setItemsRenameable(true);
      lv->setResizeMode(QListView::LastColumn);
      lv->setRenameable(2, true);
      lv->setRenameable(0, false);
      lv->setAllColumnsShowFocus(true);

      QHBox *box1 = new QHBox(page);
      QLabel *lab = new QLabel(i18n("Move selected files to:"), box1);
      KURLRequester *urlreq = new KURLRequester(box1);
      urlreq->setMode(KFile::Directory);
      urlreq->setURL(KdenliveSettings::currentdefaultfolder());

      QStringList more;
      QStringList::Iterator it;

        QDir dir( KURL(m_tmpFolder).path() );
        more = dir.entryList( QDir::Files );
        for ( it = more.begin() ; it != more.end() ; ++it ){
            KURL url;
            url.setPath(m_tmpFolder);
            url.addPath(*it);
            QPixmap p = m_app->getDocument()->renderer()->getVideoThumbnail(url.path(), 1, 60, 40);
            if (!p.isNull()) {
                QCheckListItem *item = new QCheckListItem(lv, QString::null, QCheckListItem::CheckBox);
                item->setPixmap(0, p);
                item->setText(1, (*it));
                item->setText(2, (*it));
                ((QCheckListItem*)item)->setOn(true);
            }
          }
      lv->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
      dia->setMainWidget(page);
      dia->setMinimumSize(400, 240);
      dia->adjustSize();
      if (dia->exec() == QDialog::Accepted) {
          QListViewItemIterator it( lv );
          for ( ; it.current(); ++it )
                if ( ( (QCheckListItem*)it.current() )->isOn() ) {
                bool ok = true;
                // move selected files to our project folder
                    QString source = m_tmpFolder + it.current()->text( 1 );
                QString dest = urlreq->url() + "/" + it.current()->text( 2 );
                while (KIO::NetAccess::exists(KURL(dest), true, this) && ok) {
                  dest = KLineEditDlg::getText(i18n("File exists"), i18n("File already exists, enter a new name"), dest, &ok);
                }
                if (ok) {
                  KIO::NetAccess::move(KURL(source), KURL(dest), this);
                    m_app->insertClipFromUrl(dest);
                }
              }
          KIO::NetAccess::del(m_tmpFolder, this);
          m_tmpFolder = QString::null;
          hasCapturedFiles = false;
      }
      delete lab;
      delete urlreq;
      delete box1;
      delete lv;
      delete page;
      delete dia;
}

    void CaptureMonitor::slotProcessStopped(KProcess *) {
      KMessageBox::detailedSorry(this, i18n("The capture stopped, see details for more info."), m_errorLog);
      slotStop();
    }

    void CaptureMonitor::receivedStderr(KProcess *, char *buffer, int len)
    {
      QCString res(buffer, len);
      m_errorLog.append(res + "\n");
    }

    void CaptureMonitor::slotStop() {
      if (captureProcess) {
       //if (!captureProcess->normalExit()) 
        if (m_screen) {
          delete m_screen;
          m_screen = new QWidget(m_screenHolder, name());
          m_screen->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
          m_screen->setBackgroundMode(Qt::PaletteDark);
          m_screen->show();
      }
          captureProcess->writeStdin("q", 1);
          if (captureProcess) delete captureProcess;
          captureProcess = 0;
      }
      m_recPanel->rendererDisconnected();
      m_recPanel->capture_format->setEnabled(true);
      if (hasCapturedFiles) displayCapturedFiles();
      m_recPanel->unsetRecording();
    }

    void CaptureMonitor::slotInit() {
      if (captureProcess) slotStop();
      m_errorLog = QString::null;
      captureProcess = new KProcess();
      //if (!m_tmpFolder.isEmpty()) KIO::NetAccess::del(m_tmpFolder, this);
      m_tmpFolder = KdenliveSettings::currenttmpfolder() + "/dvcapture/";
      KIO::NetAccess::mkdir(KURL(m_tmpFolder), this);
      if (!KIO::NetAccess::exists(m_tmpFolder, false, this)) {
            // creation of custom tmp folder failed, default to system tmp resource
            m_tmpFolder = locateLocal("tmp", "dvcapture/", true);
      }
      captureProcess->setWorkingDirectory(m_tmpFolder);
        captureProcess->setUseShell(true);
        captureProcess->setEnvironment("SDL_WINDOWID", QString::number(m_screen->winId()));
      *captureProcess<<"dvgrab";

      bool isHdv = false;

      switch (m_recPanel->capture_format->currentItem()){
          case 0:
            *captureProcess<<"--format"<<"dv1";
            break;
          case 1:
            *captureProcess<<"--format"<<"dv2";
            break;
          case 3:
            *captureProcess<<"--format"<<"hdv";
            isHdv = true;
            break;
          default:
            *captureProcess<<"--format"<<"raw";
            break;
      }

      if (KdenliveSettings::autosplit()) *captureProcess<<"--autosplit";
      if (KdenliveSettings::timestamp()) *captureProcess<<"--timestamp";
      *captureProcess<<"-i"<<"capture"<<"-";
        if (isHdv)
          *captureProcess<<"|"<<"ffplay"<<"-f"<<"mpegts"<<"-x"<<QString::number(m_screen->width())<<"-y"<<QString::number(m_screen->height())<<"-";
      else 
          *captureProcess<<"|"<<"ffplay"<<"-f"<<"dv"<<"-x"<<QString::number(m_screen->width())<<"-y"<<QString::number(m_screen->height())<<"-";
        connect(captureProcess, SIGNAL(processExited(KProcess *)), this, SLOT(slotProcessStopped(KProcess *)));
      connect(captureProcess, SIGNAL(receivedStderr (KProcess *, char *, int )), this, SLOT(receivedStderr(KProcess *, char *, int)));
      captureProcess->start(KProcess::NotifyOnExit, KProcess::Communication(KProcess::Stdin | KProcess::Stderr));
      m_recPanel->capture_format->setEnabled(false);
      m_recPanel->rendererConnected();
    }

    void CaptureMonitor::slotPause() {
      if (!captureProcess) slotInit();
      captureProcess->writeStdin("\e", 2);
      m_recPanel->unsetRecording();
    }

    void CaptureMonitor::slotPlay() {
      if (!captureProcess) slotInit();
      captureProcess->writeStdin(" ", 1);
    }

    void CaptureMonitor::slotRec() {
        QDir dir( KURL(m_tmpFolder).path() );
        m_fileNumber = dir.entryList( QDir::Files ).count();
      if (!captureProcess) slotInit();
      captureProcess->writeStdin("c\n", 3);
      hasCapturedFiles = true;
      QTimer::singleShot( 1500, this, SLOT(checkCapture()) );
    }

    void CaptureMonitor::checkCapture() {
      QDir dir( KURL(m_tmpFolder).path() );
        int fileNumber = dir.entryList( QDir::Files ).count();
      if (fileNumber > m_fileNumber) m_recPanel->setRecording();
    }

    void CaptureMonitor::slotForward() {
      if (!captureProcess) slotInit();
      captureProcess->writeStdin("l", 1);
    }

    void CaptureMonitor::slotFastForward() {
      if (!captureProcess) slotInit();
      captureProcess->writeStdin("z", 1);
    }

}


Generated by  Doxygen 1.6.0   Back to index