]> git.sesse.net Git - kdenlive/commitdiff
Monitor all clips for deletion, and replace with red clip if a video file is removed...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 11 Apr 2010 21:17:54 +0000 (21:17 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 11 Apr 2010 21:17:54 +0000 (21:17 +0000)
http://www.kdenlive.org/mantis/view.php?id=685

svn path=/trunk/kdenlive/; revision=4382

14 files changed:
src/customtrackview.cpp
src/docclipbase.cpp
src/docclipbase.h
src/kdenlivedoc.cpp
src/mainwindow.cpp
src/mainwindow.h
src/projectitem.h
src/projectlist.cpp
src/projectlist.h
src/renderer.cpp
src/renderer.h
src/renderwidget.cpp
src/renderwidget.h
src/widgets/renderwidget_ui.ui

index 5481cd81e1d399690eeea9f210bb85ff2d390647..3054da721e50f29d27ecccb99e994c64c222b984 100644 (file)
@@ -1299,9 +1299,8 @@ void CustomTrackView::editClipDuration()
 {
     AbstractClipItem *item;
     if (m_dragItem) {
-       item = m_dragItem;
-    }
-    else {
+        item = m_dragItem;
+    } else {
         GenTime pos = GenTime((int)(mapToScene(m_menuPosition).x()), m_document->fps());
         int track = (int)(mapToScene(m_menuPosition).y() / m_tracksHeight);
         item = getClipItemAt(pos, track);
@@ -5240,7 +5239,7 @@ void CustomTrackView::slotChangeTrack(int ix)
     d.track_nb->setValue(ix);
     d.slotUpdateName(ix);
     d.setWindowTitle(i18n("Change Track Type"));
-    
+
     TrackInfo oldInfo = m_document->trackInfoAt(m_document->tracksCount() - ix - 1);
     if (oldInfo.type == VIDEOTRACK)
         d.video_track->setChecked(true);
index 90bc8d146f0be54cc795d5821bb514fa7d01076e..599f32f5236ac5822bfb7e7293641d81330bb399 100644 (file)
@@ -461,7 +461,7 @@ void DocClipBase::setValid()
 
 void DocClipBase::setProducer(Mlt::Producer *producer, bool reset)
 {
-    if (producer == NULL || m_placeHolder) return;
+    if (producer == NULL || (m_placeHolder && !reset)) return;
     if (m_thumbProd && (reset || !m_thumbProd->hasProducer())) m_thumbProd->setProducer(producer);
     if (reset) {
         // Clear all previous producers
@@ -760,6 +760,13 @@ void DocClipBase::getFileHash(const QString url)
     }
 }
 
+bool DocClipBase::checkHash() const
+{
+    KUrl url = fileURL();
+    if (!url.isEmpty() && getClipHash() != getHash(url.path())) return false;
+    return true;
+}
+
 QString DocClipBase::getClipHash() const
 {
     QString hash;
@@ -770,6 +777,11 @@ QString DocClipBase::getClipHash() const
     return hash;
 }
 
+void DocClipBase::setPlaceHolder(bool place)
+{
+    m_placeHolder = place;
+}
+
 // static
 QString DocClipBase::getHash(const QString &path)
 {
index 620fc70611b9c94b4862590620f60ffacf04427d..6ad3894c7a3c8c0bf77f51d15a2335aee543357a 100644 (file)
@@ -200,6 +200,8 @@ Q_OBJECT public:
 
     bool hasVideoCodec(const QString &codec) const;
     bool hasAudioCodec(const QString &codec) const;
+    bool checkHash() const;
+    void setPlaceHolder(bool place);
 
 private:   // Private attributes
 
index dd88c3b575b95f522e9d0859fe6e5440596b289a..9a9f3cd017a41f4e447c8119d311a8f4fc1e7fda 100644 (file)
@@ -739,7 +739,6 @@ void KdenliveDoc::setRenderer(Render *render) {
 
 void KdenliveDoc::checkProjectClips()
 {
-    kDebug() << "+++++++++++++ + + + + CHK PCLIPS";
     if (m_render == NULL) return;
     m_clipManager->resetProducersList(m_render->producersList());
 }
index b3ad1d899d4f2af7eec61e93d67e26ad8f30c517..8a61c88f3b8595778ec91e2ad0b3c8ca212c50fc 100644 (file)
@@ -1897,6 +1897,7 @@ void MainWindow::slotRenderProject()
             m_renderWidget->setRenderProfile(m_activeDocument->getDocumentProperty("renderdestination"), m_activeDocument->getDocumentProperty("rendercategory"), m_activeDocument->getDocumentProperty("renderprofile"), m_activeDocument->getDocumentProperty("renderurl"));
         }
     }
+    slotCheckRenderStatus();
     /*TrackView *currentTab = (TrackView *) m_timelineArea->currentWidget();
     if (currentTab) m_renderWidget->setTimeline(currentTab);
     m_renderWidget->setDocument(m_activeDocument);*/
@@ -1904,6 +1905,12 @@ void MainWindow::slotRenderProject()
     m_renderWidget->showNormal();
 }
 
+void MainWindow::slotCheckRenderStatus()
+{
+    // Make sure there are no missing clips
+    if (m_renderWidget) m_renderWidget->missingClips(m_projectList->hasMissingClips());
+}
+
 void MainWindow::setRenderingProgress(const QString &url, int progress)
 {
     if (m_renderWidget) m_renderWidget->setRenderJob(url, progress);
@@ -2001,6 +2008,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
             disconnect(m_activeTimeline, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int)));
             disconnect(m_projectList, SIGNAL(loadingIsOver()), m_activeTimeline->projectView(), SLOT(slotUpdateAllThumbs()));
             disconnect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
+            disconnect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus()));
             disconnect(m_projectList, SIGNAL(clipNeedsReload(const QString&, bool)), m_activeTimeline->projectView(), SLOT(slotUpdateClip(const QString &, bool)));
             m_effectStack->clear();
         }
@@ -2077,11 +2085,13 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     connect(trackView, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int)));
     connect(m_projectList, SIGNAL(loadingIsOver()), trackView->projectView(), SLOT(slotUpdateAllThumbs()));
     connect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
+    connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus()));
 
 
     trackView->projectView()->setContextMenu(m_timelineContextMenu, m_timelineContextClipMenu, m_timelineContextTransitionMenu, m_clipTypeGroup, (QMenu*)(factory()->container("marker_menu", this)));
     m_activeTimeline = trackView;
     if (m_renderWidget) {
+        slotCheckRenderStatus();
         m_renderWidget->setProfile(doc->mltProfile());
         m_renderWidget->setGuides(doc->guidesXml(), doc->projectDuration());
         m_renderWidget->setDocumentPath(doc->projectFolder().path(KUrl::AddTrailingSlash));
@@ -2549,6 +2559,9 @@ void MainWindow::slotGotProgressInfo(const QString &message, int progress)
     if (progress >= 0) {
         if (!message.isEmpty()) m_messageLabel->setMessage(message, InformationMessage);//statusLabel->setText(message);
         m_statusProgressBar->setVisible(true);
+    } else if (progress == -2) {
+        if (!message.isEmpty()) m_messageLabel->setMessage(message, ErrorMessage);
+        m_statusProgressBar->setVisible(false);
     } else {
         m_messageLabel->setMessage(QString(), DefaultMessage);
         m_statusProgressBar->setVisible(false);
index a940cb85962dd520c6c8083a236e00a163187d69..62b562e3164d553d95876177c305cbdadc9a295a 100644 (file)
@@ -341,6 +341,7 @@ private slots:
     /** \brief Change color scheme */
     void slotChangePalette(QAction *action, const QString &themename = QString());
     void slotSwitchMonitors();
+    void slotCheckRenderStatus();
     void slotInsertZoneToTree();
     void slotInsertZoneToTimeline();
     void slotDeleteProjectClips(QStringList ids, QMap<QString, QString> folderids);
index 30321386b1dc15563fe092dccff3eb3909b21b4c..0ed280211ba20de6764e89678d373fef38337346 100644 (file)
@@ -61,6 +61,7 @@ public:
     void clearProperty(const QString &key);
     QString getClipHash() const;
     static int itemDefaultHeight();
+    void slotSetToolTip();
 
     virtual bool operator<(const QTreeWidgetItem &other)const {
         int column = treeWidget()->sortColumn();
@@ -72,7 +73,6 @@ public:
 private:
     CLIPTYPE m_clipType;
     QString m_clipId;
-    void slotSetToolTip();
     DocClipBase *m_clip;
 };
 
index 8f42095eb9b5c3805320b325cdf397aa0c9cf255..ebce6b7c56d16b3493055db8160dcbedae5e563d 100644 (file)
@@ -80,6 +80,8 @@ ProjectList::ProjectList(QWidget *parent) :
     QVBoxLayout *layout = new QVBoxLayout;
     layout->setContentsMargins(0, 0, 0, 0);
 
+
+
     // setup toolbar
     KTreeWidgetSearchLine *searchView = new KTreeWidgetSearchLine(this);
     m_toolbar = new QToolBar("projectToolBar", this);
@@ -371,10 +373,13 @@ void ProjectList::slotReloadClip(const QString &id)
         if (selected.at(i)->type() != PROJECTCLIPTYPE) continue;
         item = static_cast <ProjectItem *>(selected.at(i));
         if (item) {
-            if (item->clipType() == IMAGE) {
-                item->referencedClip()->producer()->set("force_reload", 1);
-            } else if (item->clipType() == TEXT) {
+            if (item->clipType() == TEXT) {
                 if (!item->referencedClip()->getProperty("xmltemplate").isEmpty()) regenerateTemplate(item);
+            } else if (item->clipType() != COLOR && item->clipType() != SLIDESHOW && item->referencedClip() &&  item->referencedClip()->checkHash() == false) {
+                item->referencedClip()->setPlaceHolder(true);
+                item->setProperty("file_hash", QString());
+            } else if (item->clipType() == IMAGE) {
+                item->referencedClip()->producer()->set("force_reload", 1);
             }
             //requestClipInfo(item->toXml(), item->clipId(), true);
             // Clear the file_hash value, which will cause a complete reload of the clip
@@ -383,6 +388,55 @@ void ProjectList::slotReloadClip(const QString &id)
     }
 }
 
+void ProjectList::slotMissingClip(const QString &id)
+{
+    ProjectItem *item = getItemById(id);
+    if (item) {
+        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+        if (item->referencedClip()) {
+            item->referencedClip()->setPlaceHolder(true);
+            if (m_render == NULL) kDebug() << "*********  ERROR, NULL RENDR";
+            item->referencedClip()->setProducer(m_render->invalidProducer(id), true);
+            item->slotSetToolTip();
+            emit clipNeedsReload(id, true);
+        }
+    }
+    update();
+    emit displayMessage(i18n("Check missing clips"), -2);
+    emit updateRenderStatus();
+}
+
+void ProjectList::slotAvailableClip(const QString &id)
+{
+    ProjectItem *item = getItemById(id);
+    if (item == NULL) return;
+    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+    if (item->referencedClip()) { // && item->referencedClip()->checkHash() == false) {
+        item->setProperty("file_hash", QString());
+        slotReloadClip(id);
+    }
+    /*else {
+    item->referencedClip()->setValid();
+    item->slotSetToolTip();
+    }
+    update();*/
+    emit updateRenderStatus();
+}
+
+bool ProjectList::hasMissingClips()
+{
+    bool missing = false;
+    QTreeWidgetItemIterator it(m_listView);
+    while (*it) {
+        if ((*it)->type() == PROJECTCLIPTYPE && !((*it)->flags() & Qt::ItemIsDragEnabled)) {
+            missing = true;
+            break;
+        }
+        it++;
+    }
+    return missing;
+}
+
 void ProjectList::setRenderer(Render *projectRender)
 {
     m_render = projectRender;
@@ -1094,6 +1148,8 @@ void ProjectList::setDocument(KdenliveDoc *doc)
     m_listView->blockSignals(false);
     m_toolbar->setEnabled(true);
     connect(m_doc->clipManager(), SIGNAL(reloadClip(const QString &)), this, SLOT(slotReloadClip(const QString &)));
+    connect(m_doc->clipManager(), SIGNAL(missingClip(const QString &)), this, SLOT(slotMissingClip(const QString &)));
+    connect(m_doc->clipManager(), SIGNAL(availableClip(const QString &)), this, SLOT(slotAvailableClip(const QString &)));
     connect(m_doc->clipManager(), SIGNAL(checkAllClips()), this, SLOT(updateAllClips()));
 }
 
@@ -1239,6 +1295,10 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
         if (!replace && item->data(0, Qt::DecorationRole).isNull()) {
             requestClipThumbnail(clipId);
         }
+        if (!toReload.isEmpty()) {
+            item->slotSetToolTip();
+
+        }
         //emit receivedClipDuration(clipId);
         if (m_listView->isEnabled() && replace) {
             // update clip in clip monitor
index e9951fd8909da48cd4af9059043c23992fbc09c5..a0172cefe44ae7c4bc39e64378d998e90f312204 100644 (file)
@@ -155,6 +155,7 @@ public:
     void focusTree() const;
     SubProjectItem *getSubItem(ProjectItem *clip, QPoint zone);
     void doUpdateClipCut(const QString &id, const QPoint oldzone, const QPoint zone, const QString &comment);
+    bool hasMissingClips();
     void deleteProjectFolder(QMap <QString, QString> map);
 
 public slots:
@@ -229,6 +230,8 @@ private slots:
     void slotProcessNextThumbnail();
     void slotCheckForEmptyQueue();
     void slotPauseMonitor();
+    void slotMissingClip(const QString &id);
+    void slotAvailableClip(const QString &id);
     //void slotShowMenu(const QPoint &pos);
 
 signals:
@@ -243,6 +246,7 @@ signals:
     void clipNameChanged(const QString, const QString);
     void clipNeedsReload(const QString&, bool);
     void refreshClip();
+    void updateRenderStatus();
     void deleteProjectClips(QStringList ids, QMap <QString, QString> folderids);
 };
 
index f90ecd364a0154c0c42a35da463556399832bb71..9ea419bea59beb4f2b70025116ab31bc2e6fc088 100644 (file)
@@ -243,6 +243,16 @@ void Render::buildConsumer(const QString profileName)
 
 }
 
+Mlt::Producer *Render::invalidProducer(const QString &id)
+{
+    Mlt::Producer *clip = new Mlt::Producer(*m_mltProfile , "colour", "red");
+    char *tmp = decodedString(id);
+    clip->set("id", tmp);
+    delete[] tmp;
+    clip->set("mlt_type", "producer");
+    return clip;
+}
+
 int Render::resetProfile(const QString profileName)
 {
     if (m_mltConsumer) {
index 66b7022f7f1165bff3d43a2d51a0a3071099f919..d0c8c9296bf5b78aaab6c5cd274c2501998b9d27 100644 (file)
@@ -206,6 +206,7 @@ Q_OBJECT public:
     void mltInsertTrack(int ix, bool videoTrack);
     void mltDeleteTrack(int ix);
     bool mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod);
+    Mlt::Producer *invalidProducer(const QString &id);
 
     /** Change speed of a clip in playlist. To do this, we create a new "framebuffer" producer.
     This new producer must have its "resource" param set to: video.mpg?0.6 where video.mpg is the path
index 77937ccd899ae02730eec79fcea8f2abce0042a4..434a53194da38b45e3947e4c13482e349f1179e8 100644 (file)
@@ -102,6 +102,13 @@ RenderWidget::RenderWidget(const QString &projectfolder, QWidget * parent) :
     m_view.format_list->setAlternatingRowColors(true);
     m_view.size_list->setAlternatingRowColors(true);
 
+    KColorScheme scheme(palette().currentColorGroup(), KColorScheme::Window);
+    QPalette p = m_view.errorLabel->palette();
+    p.setColor(QPalette::Background, scheme.background(KColorScheme::NegativeBackground).color());
+    m_view.errorLabel->setAutoFillBackground(true);
+    m_view.errorLabel->setPalette(p);
+    m_view.errorLabel->setHidden(true);
+
     parseProfiles();
     parseScriptFiles();
 
@@ -1760,5 +1767,11 @@ void RenderWidget::slotPlayRendering(QTreeWidgetItem *item, int)
     KRun::runCommand(command, KdenliveSettings::defaultplayerapp(), KdenliveSettings::defaultplayerapp(), this, startId);
 }
 
-
+void RenderWidget::missingClips(bool hasMissing)
+{
+    if (hasMissing) {
+        m_view.errorLabel->setText(i18n("Check missing clips"));
+        m_view.errorLabel->setHidden(false);
+    } else m_view.errorLabel->setHidden(true);
+}
 
index 57b4c65a3b508e33cefee9c28eed83bf1a3336ae..7559ac38e4c54d8ab20534fd42a9cfe18c33b3fd 100644 (file)
@@ -112,6 +112,7 @@ public:
     int waitingJobsCount() const;
     QString getFreeScriptName(const QString &prefix = QString());
     bool startWaitingRenderJobs();
+    void missingClips(bool hasMissing);
 
 public slots:
     void slotExport(bool scriptExport, int zoneIn, int zoneOut, const QString &playlistPath, const QString &scriptPath);
index a82a0744bddcb68c49f774055c9245ecc9ba423a..f8d61166555e5c4d528233c5f1c992f58e5a815b 100644 (file)
          </layout>
         </widget>
        </item>
-       <item row="13" column="0" colspan="2">
+       <item row="14" column="0" colspan="2">
         <widget class="QPushButton" name="buttonRender">
          <property name="text">
           <string>Render to File</string>
          </property>
         </widget>
        </item>
-       <item row="13" column="2" colspan="1">
+       <item row="14" column="2">
         <widget class="QPushButton" name="buttonGenerateScript">
          <property name="text">
           <string>Generate Script</string>
          </property>
         </widget>
        </item>
-       <item row="13" column="3" colspan="6">
+       <item row="14" column="3" colspan="6">
         <spacer name="horizontalSpacer">
          <property name="orientation">
           <enum>Qt::Horizontal</enum>
          </property>
         </spacer>
        </item>
-       <item row="13" column="9" colspan="2">
+       <item row="14" column="9" colspan="2">
         <widget class="KPushButton" name="buttonClose">
          <property name="text">
           <string>Close</string>
          </property>
         </spacer>
        </item>
+       <item row="13" column="0" colspan="11">
+        <widget class="QLabel" name="errorLabel">
+         <property name="text">
+          <string/>
+         </property>
+        </widget>
+       </item>
       </layout>
      </widget>
      <widget class="QWidget" name="tab_2">