]> git.sesse.net Git - kdenlive/blobdiff - src/projectlist.cpp
* Fix aspect ratio of thumbnails to correctly use the project's arpect ratio
[kdenlive] / src / projectlist.cpp
index 1b71947680b70752851cf66d8df575894c2746a7..6e5ddb6c7fba1e2fec936ee2ef45a132c91a5423 100644 (file)
@@ -906,11 +906,14 @@ void ProjectList::slotDeleteClip(const QString &clipId)
         kDebug() << "/// Cannot find clip to delete";
         return;
     }
+    if (item->isProxyRunning()) m_abortProxy.append(item->referencedClip()->getProperty("proxy"));
     m_listView->blockSignals(true);
     QTreeWidgetItem *newSelectedItem = m_listView->itemAbove(item);
     if (!newSelectedItem)
         newSelectedItem = m_listView->itemBelow(item);
     delete item;
+    // Pause playing to prevent crash while deleting clip
+    slotPauseMonitor();
     m_doc->clipManager()->deleteClip(clipId);
     m_listView->blockSignals(false);
     if (newSelectedItem) {
@@ -1015,13 +1018,15 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
         item = new ProjectItem(m_listView, clip);
     }
     if (item->data(0, DurationRole).isNull()) item->setData(0, DurationRole, i18n("Loading"));
-    connect(clip, SIGNAL(createProxy(const QString)), this, SLOT(slotCreateProxy(const QString)));
-    connect(clip, SIGNAL(abortProxy(const QString, const QString)), this, SLOT(slotAbortProxy(const QString, const QString)));
+    connect(clip, SIGNAL(createProxy(const QString &)), this, SLOT(slotCreateProxy(const QString &)));
+    connect(clip, SIGNAL(abortProxy(const QString &, const QString &)), this, SLOT(slotAbortProxy(const QString, const QString)));
     if (getProperties) {
         m_listView->processLayout();
         QDomElement e = clip->toXML().cloneNode().toElement();
         e.removeAttribute("file_hash");
+        m_mutex.lock();
         m_infoQueue.insert(clip->getId(), e);
+        m_mutex.unlock();
     }
     else if (item->hasProxy() && !item->isProxyRunning()) {
         slotCreateProxy(clip->getId());
@@ -1068,13 +1073,15 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
         updateButtons();
     }
     
-    if (getProperties && m_processingClips.isEmpty())
-        m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    //if (getProperties && m_processingClips.isEmpty())
+        //m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    if (getProperties)
+        QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }
 
 void ProjectList::slotGotProxy(const QString &proxyPath)
 {
-    if (proxyPath.isEmpty()) return;
+    if (proxyPath.isEmpty() || !m_refreshed) return;
     QTreeWidgetItemIterator it(m_listView);
     ProjectItem *item;
 
@@ -1090,7 +1097,7 @@ void ProjectList::slotGotProxy(const QString &proxyPath)
 
 void ProjectList::slotGotProxy(ProjectItem *item)
 {
-    if (item == NULL) return;
+    if (item == NULL || !m_refreshed) return;
     DocClipBase *clip = item->referencedClip();
     // Proxy clip successfully created
     QDomElement e = clip->toXML().cloneNode().toElement();
@@ -1104,8 +1111,11 @@ void ProjectList::slotGotProxy(ProjectItem *item)
         }
     }
     e.setAttribute("replace", 1);
+    m_mutex.lock();
     m_infoQueue.insert(clip->getId(), e);
-    if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);   
+    m_mutex.unlock();
+    //if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }
 
 void ProjectList::slotResetProjectList()
@@ -1117,25 +1127,20 @@ void ProjectList::slotResetProjectList()
     m_refreshed = false;
 }
 
-void ProjectList::requestClipInfo(const QDomElement xml, const QString id)
-{
-    m_infoQueue.insert(id, xml);
-    //if (m_infoQueue.count() == 1 || ) QTimer::singleShot(300, this, SLOT(slotProcessNextClipInQueue()));
-}
-
 void ProjectList::slotProcessNextClipInQueue()
 {
     if (m_infoQueue.isEmpty()) {
         emit processNextThumbnail();
         return;
     }
-
+    QMutexLocker locker(&m_mutex);
     QMap<QString, QDomElement>::const_iterator j = m_infoQueue.constBegin();
     if (j != m_infoQueue.constEnd()) {
         QDomElement dom = j.value().cloneNode().toElement();
         const QString id = j.key();
         m_infoQueue.remove(id);
         m_processingClips.append(id);
+        locker.unlock();
         bool replace;
         if (dom.hasAttribute("replace")) {
             // Proxy action was enabled / disabled and we want to replace current producer
@@ -1173,7 +1178,7 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged)
     QPainter p(&missingPixmap);
     p.drawPixmap(3, 3, icon.pixmap(width - 6, height - 6));
     p.end();
-                        
+    kDebug()<<"//////////////7  UPDATE ALL CLPS";
     while (*it) {
         if ((*it)->type() == PROJECTSUBCLIPTYPE) {
             // subitem
@@ -1199,7 +1204,10 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged)
                         xml.removeAttribute("file_hash");
                         xml.removeAttribute("proxy_out");
                     }
-                    requestClipInfo(xml, clip->getId());
+                    m_mutex.lock();
+                    m_infoQueue.insert(clip->getId(), xml);
+                    m_mutex.unlock();
+                    QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
                 }
                 else {
                     item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
@@ -1237,7 +1245,12 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged)
         ++it;
     }
 
-    if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    //if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    //QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    /*while (!m_infoQueue.isEmpty()) {
+        QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    }*/
+    
     if (m_listView->isEnabled())
         monitorItemEditing(true);
     m_listView->setSortingEnabled(true);
@@ -1353,7 +1366,8 @@ void ProjectList::slotRemoveInvalidClip(const QString &id, bool replace)
     ProjectItem *item = getItemById(id);
     m_processingClips.removeAll(id);
     m_thumbnailQueue.removeAll(id);
-    if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    //if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);   
     if (item) {
         const QString path = item->referencedClip()->fileURL().path();
         if (item->referencedClip()->isPlaceHolder()) replace = false;
@@ -1387,7 +1401,8 @@ void ProjectList::slotRemoveInvalidProxy(const QString &id, bool durationError)
     }
     m_processingClips.removeAll(id);
     m_thumbnailQueue.removeAll(id);
-    if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    //if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }
 
 void ProjectList::slotAddColorClip()
@@ -1518,6 +1533,7 @@ void ProjectList::setDocument(KdenliveDoc *doc)
     }
 
     QList <DocClipBase*> list = doc->clipManager()->documentClipList();
+    if (list.isEmpty()) m_refreshed = true;
     for (int i = 0; i < list.count(); i++)
         slotAddClip(list.at(i), false);
 
@@ -1558,10 +1574,12 @@ QDomElement ProjectList::producersList()
 
 void ProjectList::slotCheckForEmptyQueue()
 {
-    if (!m_refreshed && m_processingClips.isEmpty() && m_thumbnailQueue.isEmpty() && m_infoQueue.isEmpty()) {
-        m_refreshed = true;
-        emit loadingIsOver();
-        emit displayMessage(QString(), -1);
+    if (m_processingClips.isEmpty() && m_thumbnailQueue.isEmpty() && m_infoQueue.isEmpty()) {
+        if (!m_refreshed) {
+            emit loadingIsOver();
+            emit displayMessage(QString(), -1);
+            m_refreshed = true;
+        }
         m_listView->blockSignals(false);
         m_listView->setEnabled(true);
         updateButtons();
@@ -1627,13 +1645,14 @@ void ProjectList::slotRefreshClipThumbnail(QTreeWidgetItem *it, bool update)
         }
         QPixmap pix;
         int height = m_listView->iconSize().height();
-        int width = (int)(height  * m_render->dar());
+        int swidth = (int)(height  * m_render->frameRenderWidth() / m_render->renderHeight()+ 0.5);
+        int dwidth = (int)(height  * m_render->dar() + 0.5);
         if (clip->clipType() == AUDIO)
-            pix = KIcon("audio-x-generic").pixmap(QSize(width, height));
+            pix = KIcon("audio-x-generic").pixmap(QSize(dwidth, height));
         else if (clip->clipType() == IMAGE)
-            pix = QPixmap::fromImage(KThumb::getFrame(item->referencedClip()->producer(), 0, width, height));
+            pix = QPixmap::fromImage(KThumb::getFrame(item->referencedClip()->producer(), 0, swidth, dwidth, height));
         else
-            pix = item->referencedClip()->extractImage(frame, width, height);
+            pix = item->referencedClip()->extractImage(frame, dwidth, height);
 
         if (!pix.isNull()) {
             monitorItemEditing(false);
@@ -1671,6 +1690,8 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
             item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled);
             toReload = clipId;
         }
+        clip->setProducer(producer, replace);
+        clip->askForAudioThumbs();
         // Proxy stuff
         QString size = properties.value("frame_size");
         if (!useProxy() && clip->getProperty("proxy").isEmpty()) setProxyStatus(item, NOPROXY);
@@ -1697,8 +1718,6 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
                 }
             }
         }
-        clip->setProducer(producer, replace);
-        clip->askForAudioThumbs();
 
         if (!replace && item->data(0, Qt::DecorationRole).isNull())
             requestClipThumbnail(clipId);
@@ -1735,7 +1754,8 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
     if (!toReload.isEmpty())
         emit clipNeedsReload(toReload, true);
 
-    if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    //if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }
 
 bool ProjectList::adjustProjectProfileToItem(ProjectItem *item)
@@ -2193,8 +2213,9 @@ void ProjectList::slotGenerateProxy(const QString destPath, const QString source
     emit projectModified();
     // Make sure proxy path is writable
     QFile file(destPath);
-    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+    if (!file.open(QIODevice::WriteOnly)) {
         setProxyStatus(destPath, PROXYCRASHED);
+        m_processingProxy.removeAll(destPath);
         return;
     }
     file.close();
@@ -2427,7 +2448,8 @@ void ProjectList::updateProxyConfig()
     }
     if (command->childCount() > 0) m_doc->commandStack()->push(command);
     else delete command;
-    if (!m_infoQueue.isEmpty() && !m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    //if (!m_infoQueue.isEmpty() && !m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }
 
 void ProjectList::slotProxyCurrentItem(bool doProxy)
@@ -2476,6 +2498,7 @@ void ProjectList::slotProxyCurrentItem(bool doProxy)
     }
     else delete command;
     //if (!m_infoQueue.isEmpty() && !m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+    if (!m_infoQueue.isEmpty()) QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }