]> git.sesse.net Git - kdenlive/blobdiff - src/mainwindow.cpp
Finally fixed the proxy crash,
[kdenlive] / src / mainwindow.cpp
index 2606751c63e15e9f9325f26cf0506159b0ee750a..ea51b42ccf3602f85d163707e02120ff8aaf011a 100644 (file)
@@ -62,6 +62,7 @@
 #include "audiospectrum.h"
 #include "spectrogram.h"
 #include "archivewidget.h"
+#include "databackup/backupwidget.h"
 
 #include <KApplication>
 #include <KAction>
@@ -200,7 +201,8 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
     m_clipMonitorDock->setObjectName("clip_monitor");
     m_clipMonitor = new Monitor("clip", m_monitorManager, QString(), m_timelineArea);
     m_clipMonitorDock->setWidget(m_clipMonitor);
-
+    connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, QPoint)));
+    
     m_projectMonitorDock = new QDockWidget(i18n("Project Monitor"), this);
     m_projectMonitorDock->setObjectName("project_monitor");
     m_projectMonitor = new Monitor("project", m_monitorManager, QString());
@@ -850,6 +852,8 @@ void MainWindow::slotConnectMonitors()
     connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &, bool, bool)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &, bool, bool)));
 
     connect(m_projectMonitor->render, SIGNAL(removeInvalidClip(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidClip(const QString &, bool)));
+    
+    connect(m_projectMonitor->render, SIGNAL(blockClipMonitor(const QString)), this, SLOT(slotBlockClipMonitor(const QString)));
     connect(m_projectMonitor->render, SIGNAL(removeInvalidProxy(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidProxy(const QString &, bool)));
 
     connect(m_clipMonitor, SIGNAL(refreshClipThumbnail(const QString &, bool)), m_projectList, SLOT(slotRefreshClipThumbnail(const QString &, bool)));
@@ -859,8 +863,8 @@ void MainWindow::slotConnectMonitors()
 
     connect(m_projectMonitor, SIGNAL(requestFrameForAnalysis(bool)), this, SLOT(slotMonitorRequestRenderFrame(bool)));
 
-    connect(m_clipMonitor, SIGNAL(saveZone(Render *, QPoint)), this, SLOT(slotSaveZone(Render *, QPoint)));
-    connect(m_projectMonitor, SIGNAL(saveZone(Render *, QPoint)), this, SLOT(slotSaveZone(Render *, QPoint)));
+    connect(m_clipMonitor, SIGNAL(saveZone(Render *, QPoint, DocClipBase *)), this, SLOT(slotSaveZone(Render *, QPoint, DocClipBase *)));
+    connect(m_projectMonitor, SIGNAL(saveZone(Render *, QPoint, DocClipBase *)), this, SLOT(slotSaveZone(Render *, QPoint, DocClipBase *)));
 }
 
 void MainWindow::slotAdjustClipMonitor()
@@ -1161,6 +1165,10 @@ void MainWindow::setupActions()
     collection.addAction("project_settings", projectAction);
     connect(projectAction, SIGNAL(triggered(bool)), this, SLOT(slotEditProjectSettings()));
 
+    KAction* backupAction = new KAction(KIcon("edit-undo"), i18n("Open Backup File"), this);
+    collection.addAction("open_backup", backupAction);
+    connect(backupAction, SIGNAL(triggered(bool)), this, SLOT(slotOpenBackupDialog()));
+
     KAction* projectRender = new KAction(KIcon("media-record"), i18n("Render"), this);
     collection.addAction("project_render", projectRender);
     projectRender->setShortcut(Qt::CTRL + Qt::Key_Return);
@@ -1506,15 +1514,6 @@ void MainWindow::setupActions()
     showTitleBar->setChecked(KdenliveSettings::showtitlebars());
     slotShowTitleBars(KdenliveSettings::showtitlebars());
 
-
-    //const QByteArray state = layoutGroup.readEntry("layout1", QByteArray());
-
-    /*QAction *maxCurrent = new KAction(i18n("Maximize Current Widget"), this);
-    collection.addAction("maximize_current", maxCurrent);
-    maxCurrent->setCheckable(true);
-    maxCurrent->setChecked(false);
-    connect(maxCurrent, SIGNAL(triggered(bool)), this, SLOT(slotMaximizeCurrent(bool)));*/
-
     m_closeAction = KStandardAction::close(this,  SLOT(closeCurrentDocument()),   collection);
     KStandardAction::quit(this,                   SLOT(close()),                  collection);
     KStandardAction::open(this,                   SLOT(openFile()),               collection);
@@ -1591,6 +1590,13 @@ void MainWindow::setupActions()
     connect(reloadClip , SIGNAL(triggered()), m_projectList, SLOT(slotReloadClip()));
     reloadClip->setEnabled(false);
 
+    QAction *proxyClip = new KAction(i18n("Proxy Clip"), this);
+    collection.addAction("proxy_clip", proxyClip);
+    proxyClip->setData("proxy_clip");
+    proxyClip->setCheckable(true);
+    proxyClip->setChecked(false);
+    connect(proxyClip, SIGNAL(toggled(bool)), m_projectList, SLOT(slotProxyCurrentItem(bool)));
+    
     QAction *stopMotion = new KAction(KIcon("image-x-generic"), i18n("Stop Motion Capture"), this);
     collection.addAction("stopmotion", stopMotion);
     connect(stopMotion , SIGNAL(triggered()), this, SLOT(slotOpenStopmotion()));
@@ -1604,6 +1610,7 @@ void MainWindow::setupActions()
     addClips->addAction(addFolderButton);
 
     addClips->addAction(reloadClip);
+    addClips->addAction(proxyClip);
     addClips->addAction(clipProperties);
     addClips->addAction(openClip);
     addClips->addAction(deleteClip);
@@ -1625,8 +1632,6 @@ void MainWindow::setupActions()
     }
     //m_effectsActionCollection->readSettings();
 
-    //connect(collection, SIGNAL( clearStatusText() ),
-    //statusBar(), SLOT( clear() ) );
 }
 
 void MainWindow::slotDisplayActionMessage(QAction *a)
@@ -1675,9 +1680,7 @@ void MainWindow::slotLoadLayout(QAction *action)
     if (layoutId.isEmpty()) return;
     KSharedConfigPtr config = KGlobal::config();
     KConfigGroup layouts(config, "Layouts");
-    //QByteArray geom = QByteArray::fromBase64(layouts.readEntry(layoutId).toAscii());
     QByteArray state = QByteArray::fromBase64(layouts.readEntry(layoutId).toAscii());
-    //restoreGeometry(geom);
     restoreState(state);
 }
 
@@ -1803,8 +1806,8 @@ void MainWindow::newFile(bool showProjectSettings, bool force)
     }
     m_timelineArea->setEnabled(true);
     m_projectList->setEnabled(true);
-    
-    KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, m_commandStack, profileName, documentProperties, projectTracks, m_projectMonitor->render, m_notesWidget, this);
+    bool openBackup;
+    KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, m_commandStack, profileName, documentProperties, projectTracks, m_projectMonitor->render, m_notesWidget, &openBackup, this);
     doc->m_autosave = new KAutoSaveFile(KUrl(), doc);
     bool ok;
     TrackView *trackView = new TrackView(doc, &ok, this);
@@ -1968,6 +1971,11 @@ void MainWindow::openFile(const KUrl &url)
         delete ar;
         return;
     }
+    if (!url.fileName().endsWith(".kdenlive")) {
+        // This is not a Kdenlive project file, abort loading
+        KMessageBox::sorry(this, i18n("File %1 is not a Kdenlive project file", url.path()));
+        return;
+    }
     
     // Check if the document is already opened
     const int ct = m_timelineArea->count();
@@ -2028,7 +2036,8 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale)
     progressDialog.progressBar()->setValue(0);
     qApp->processEvents();
 
-    KdenliveDoc *doc = new KdenliveDoc(url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QMap <QString, QString> (), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, m_notesWidget, this, &progressDialog);
+    bool openBackup;
+    KdenliveDoc *doc = new KdenliveDoc(url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QMap <QString, QString> (), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, m_notesWidget, &openBackup, this, &progressDialog);
 
     progressDialog.progressBar()->setValue(1);
     progressDialog.progressBar()->setMaximum(4);
@@ -2075,6 +2084,7 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale)
     m_clipMonitor->refreshMonitor(true);
 
     progressDialog.progressBar()->setValue(4);
+    if (openBackup) slotOpenBackupDialog(url);
 }
 
 void MainWindow::recoverFiles(QList<KAutoSaveFile *> staleFiles)
@@ -2198,6 +2208,7 @@ void MainWindow::slotEditProjectSettings()
 {
     QPoint p = m_activeDocument->getTracksCount();
     ProjectSettings *w = new ProjectSettings(m_projectList, m_activeTimeline->projectView()->extractTransitionsLumas(), p.x(), p.y(), m_activeDocument->projectFolder().path(), true, !m_activeDocument->isModified(), this);
+    connect(w, SIGNAL(disableProxies()), this, SLOT(slotDisableProxies()));
 
     if (w->exec() == QDialog::Accepted) {
         QString profile = w->selectedProfile();
@@ -2246,6 +2257,13 @@ void MainWindow::slotEditProjectSettings()
     delete w;
 }
 
+void MainWindow::slotDisableProxies()
+{
+    m_activeDocument->setDocumentProperty("enableproxy", QString::number((int) false));
+    m_activeDocument->setModified();
+    slotUpdateProxySettings();
+}
+
 void MainWindow::slotUpdateProjectProfile(const QString &profile)
 {
     // Recreate the stopmotion widget if profile changes
@@ -2384,7 +2402,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
             disconnect(m_projectList, SIGNAL(projectModified()), m_activeDocument, SLOT(setModified()));
             disconnect(m_projectList, SIGNAL(updateProfile(const QString &)), this, SLOT(slotUpdateProjectProfile(const QString &)));
 
-            disconnect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers(bool)), m_activeDocument, SLOT(checkProjectClips(bool)));
+            disconnect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers(bool, bool)), m_activeDocument, SLOT(checkProjectClips(bool, bool)));
 
             disconnect(m_activeDocument, SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated()));
             disconnect(m_activeDocument, SIGNAL(addProjectClip(DocClipBase *, bool)), m_projectList, SLOT(slotAddClip(DocClipBase *, bool)));
@@ -2425,7 +2443,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
             m_effectStack->clear();
         }
         //m_activeDocument->setRenderer(NULL);
-        disconnect(m_projectList, SIGNAL(clipSelected(DocClipBase *)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *)));
         disconnect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), m_monitorManager, SLOT(slotRefreshCurrentMonitor()));
         m_clipMonitor->stop();
     }
@@ -2435,7 +2452,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     m_projectList->setDocument(doc);
     m_transitionConfig->updateProjectFormat(doc->mltProfile(), doc->timecode(), doc->tracksList());
     m_effectStack->updateProjectFormat(doc->mltProfile(), doc->timecode());
-    connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, QPoint)));
     connect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), m_monitorManager, SLOT(slotRefreshCurrentMonitor()));
     connect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), trackView->projectView(), SLOT(slotRefreshThumbs(const QString &, bool)));
     connect(m_projectList, SIGNAL(clipNeedsReload(const QString&, bool)), trackView->projectView(), SLOT(slotUpdateClip(const QString &, bool)));
@@ -2460,7 +2476,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), doc, SLOT(setModified()));
     connect(m_clipMonitor, SIGNAL(zoneUpdated(QPoint)), doc, SLOT(setModified()));
     connect(m_projectMonitor, SIGNAL(durationChanged(int)), trackView, SLOT(setDuration(int)));
-    connect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers(bool)), doc, SLOT(checkProjectClips(bool)));
+    connect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers(bool, bool)), doc, SLOT(checkProjectClips(bool, bool)));
 
     connect(doc, SIGNAL(addProjectClip(DocClipBase *, bool)), m_projectList, SLOT(slotAddClip(DocClipBase *, bool)));
     connect(doc, SIGNAL(resetProjectList()), m_projectList, SLOT(slotResetProjectList()));
@@ -2470,6 +2486,8 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
 
     connect(doc, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
     connect(doc, SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated()));
+    connect(doc, SIGNAL(saveTimelinePreview(const QString)), trackView, SLOT(slotSaveTimelinePreview(const QString)));
+    
     connect(m_notesWidget, SIGNAL(textChanged()), doc, SLOT(setModified()));
 
     connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int)));
@@ -3170,6 +3188,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip)
     // any type of clip but a title
     ClipProperties *dia = new ClipProperties(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this);
     connect(dia, SIGNAL(addMarker(const QString &, GenTime, QString)), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, GenTime, QString)));
+    connect(dia, SIGNAL(deleteProxy(const QString)), m_projectList, SLOT(slotDeleteProxy(const QString)));
     connect(dia, SIGNAL(applyNewClipProperties(const QString, QMap <QString, QString> , QMap <QString, QString> , bool, bool)), this, SLOT(slotApplyNewClipProperties(const QString, QMap <QString, QString> , QMap <QString, QString> , bool, bool)));
     dia->show();
 }
@@ -3515,7 +3534,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event)
 }
 
 
-void MainWindow::slotSaveZone(Render *render, QPoint zone)
+void MainWindow::slotSaveZone(Render *render, QPoint zone, DocClipBase *baseClip, KUrl path)
 {
     KDialog *dialog = new KDialog(this);
     dialog->setCaption("Save clip zone");
@@ -3526,9 +3545,15 @@ void MainWindow::slotSaveZone(Render *render, QPoint zone)
 
     QVBoxLayout *vbox = new QVBoxLayout(widget);
     QLabel *label1 = new QLabel(i18n("Save clip zone as:"), this);
-    QString path = m_activeDocument->projectFolder().path(KUrl::AddTrailingSlash);
-    path.append("untitled.mlt");
-    KUrlRequester *url = new KUrlRequester(KUrl(path), this);
+    if (path.isEmpty()) {
+        QString tmppath = m_activeDocument->projectFolder().path(KUrl::AddTrailingSlash);
+        if (baseClip == NULL) tmppath.append("untitled.mlt");
+        else {
+            tmppath.append((baseClip->name().isEmpty() ? baseClip->fileURL().fileName() : baseClip->name()) + "-" + QString::number(zone.x()).rightJustified(4, '0') + ".mlt");
+        }
+        path = KUrl(tmppath);
+    }
+    KUrlRequester *url = new KUrlRequester(path, this);
     url->setFilter("video/mlt-playlist");
     QLabel *label2 = new QLabel(i18n("Description:"), this);
     KLineEdit *edit = new KLineEdit(this);
@@ -3536,27 +3561,54 @@ void MainWindow::slotSaveZone(Render *render, QPoint zone)
     vbox->addWidget(url);
     vbox->addWidget(label2);
     vbox->addWidget(edit);
-    if (dialog->exec() == QDialog::Accepted)
-        render->saveZone(url->url(), edit->text(), zone);
+    if (dialog->exec() == QDialog::Accepted) {
+        if (QFile::exists(url->url().path())) {
+            if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", url->url().path())) == KMessageBox::No) {
+                slotSaveZone(render, zone, baseClip, url->url());
+                return;
+            }
+        }
+        if (baseClip && !baseClip->fileURL().isEmpty()) {
+            // create zone from clip url, so that we don't have problems with proxy clips
+            QProcess p;
+#if QT_VERSION >= 0x040600
+            QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+            env.remove("MLT_PROFILE");
+            p.setProcessEnvironment(env);
+#else
+            QStringList env = QProcess::systemEnvironment();
+            env << "MLT_PROFILE='\0'";
+            p.setEnvironment(env);
+#endif
+            p.start(KdenliveSettings::rendererpath(), QStringList() << baseClip->fileURL().path() << "in=" + QString::number(zone.x()) << "out=" + QString::number(zone.y()) << "-consumer" << "xml:" + url->url().path());
+            if (!p.waitForStarted(3000)) {
+                KMessageBox::sorry(this, i18n("Cannot start MLT's renderer:\n%1", KdenliveSettings::rendererpath()));
+            }
+            else if (!p.waitForFinished(5000)) {
+                KMessageBox::sorry(this, i18n("Timeout while creating xml output"));
+            }
+        }
+        else render->saveZone(url->url(), edit->text(), zone);
+    }
 
 }
 
 void MainWindow::slotSetInPoint()
 {
-    if (m_clipMonitor->isActive())
+    if (m_clipMonitor->isActive()) {
         m_clipMonitor->slotSetZoneStart();
-    else
+    } else {
         m_projectMonitor->slotSetZoneStart();
-    //else m_activeTimeline->projectView()->setInPoint();
+    }
 }
 
 void MainWindow::slotSetOutPoint()
 {
-    if (m_clipMonitor->isActive())
+    if (m_clipMonitor->isActive()) {
         m_clipMonitor->slotSetZoneEnd();
-    else
+    } else {
         m_projectMonitor->slotSetZoneEnd();
-    // else m_activeTimeline->projectView()->setOutPoint();
+    }
 }
 
 void MainWindow::slotResizeItemStart()
@@ -3667,21 +3719,15 @@ void MainWindow::slotShowTimeline(bool show)
     }
 }
 
-void MainWindow::slotMaximizeCurrent(bool /*show*/)
+void MainWindow::slotMaximizeCurrent(bool)
 {
     //TODO: is there a way to maximize current widget?
-    //if (show == true)
-    {
-        m_timelineState = saveState();
-        QWidget *par = focusWidget()->parentWidget();
-        while (par->parentWidget() && par->parentWidget() != this)
-            par = par->parentWidget();
-        kDebug() << "CURRENT WIDGET: " << par->objectName();
-    }
-    /*else {
-    //centralWidget()->setHidden(false);
-    //restoreState(m_timelineState);
-    }*/
+
+    m_timelineState = saveState();
+    QWidget *par = focusWidget()->parentWidget();
+    while (par->parentWidget() && par->parentWidget() != this)
+        par = par->parentWidget();
+    kDebug() << "CURRENT WIDGET: " << par->objectName();
 }
 
 void MainWindow::loadTranscoders()
@@ -4218,7 +4264,7 @@ void MainWindow::slotUpdateColorScopes()
         if (!m_gfxScopesList.at(i)->widget()->visibleRegion().isEmpty() && !(static_cast<AbstractGfxScopeWidget *>(m_gfxScopesList.at(i)->widget())->autoRefreshEnabled())) request = true;
         static_cast<AbstractGfxScopeWidget *>(m_gfxScopesList.at(i)->widget())->slotActiveMonitorChanged();
     }
-    if (request) {
+    if (request && m_monitorManager->activeRenderer()) {
         m_monitorManager->activeRenderer()->sendFrameUpdate();
     }
 }
@@ -4278,6 +4324,43 @@ void MainWindow::slotArchiveProject()
 }
 
 
+void MainWindow::slotOpenBackupDialog(const KUrl url)
+{
+    KUrl projectFile;
+    KUrl projectFolder;
+    QString projectId;
+    kDebug()<<"// BACKUP URL: "<<url.path();
+    if (!url.isEmpty()) {
+        // we could not open the project file, guess where the backups are
+        projectFolder = KUrl(KdenliveSettings::defaultprojectfolder());
+        projectFile = url;
+    }
+    else {
+        projectFolder = m_activeDocument->projectFolder();
+        projectFile = m_activeDocument->url();
+        projectId = m_activeDocument->getDocumentProperty("documentid");
+    }
+
+    BackupWidget *dia = new BackupWidget(projectFile, projectFolder, projectId, this);
+    if (dia->exec() == QDialog::Accepted) {
+        QString requestedBackup = dia->selectedFile();
+        m_activeDocument->backupLastSavedVersion(projectFile.path());
+        closeCurrentDocument(false);
+        doOpenFile(KUrl(requestedBackup), NULL);
+        m_activeDocument->setUrl(projectFile);
+        m_activeDocument->setModified(true);
+        setCaption(m_activeDocument->description());
+    }
+    delete dia;
+}
+
+void MainWindow::slotBlockClipMonitor(const QString id)
+{
+    if (m_clipMonitor->activeClip() && m_clipMonitor->activeClip()->getId() == id) m_clipMonitor->slotSetXml(NULL);
+}
+
+
+
 #include "mainwindow.moc"
 
 #ifdef DEBUG_MAINW