]> git.sesse.net Git - kdenlive/blobdiff - src/projectlist.cpp
Fix audio thumbs not displayed on project opening and abortion if audio thumbs creation
[kdenlive] / src / projectlist.cpp
index a0618d18cf7d13098c98ff7f2215ce014825030a..6fcbd91a9fe0887418245ede1526ca611f7a967d 100644 (file)
@@ -79,6 +79,7 @@ ProjectList::ProjectList(QWidget *parent) :
     m_listView = new ProjectListView(this);;
     QVBoxLayout *layout = new QVBoxLayout;
     layout->setContentsMargins(0, 0, 0, 0);
+    layout->setSpacing(0);
 
     // setup toolbar
     KTreeWidgetSearchLine *searchView = new KTreeWidgetSearchLine(this);
@@ -172,7 +173,7 @@ void ProjectList::setupMenu(QMenu *addMenu, QAction *defaultAction)
     m_menu->addActions(addMenu->actions());
 }
 
-void ProjectList::setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu)
+void ProjectList::setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu, QMenu *inTimelineMenu)
 {
     if (!addMenu) return;
     QMenu *menu = m_addButton->menu();
@@ -185,6 +186,8 @@ void ProjectList::setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu)
     if (transcodeMenu->isEmpty()) transcodeMenu->setEnabled(false);
     m_transcodeAction = transcodeMenu;
     m_menu->addAction(m_reloadAction);
+    m_menu->addMenu(inTimelineMenu);
+    inTimelineMenu->setEnabled(false);
     m_menu->addAction(m_editAction);
     m_menu->addAction(m_openAction);
     m_menu->addAction(m_deleteAction);
@@ -202,6 +205,11 @@ void ProjectList::setHeaderInfo(const QByteArray &state)
     m_listView->header()->restoreState(state);
 }
 
+void ProjectList::updateProjectFormat(Timecode t)
+{
+    m_timecode = t;
+}
+
 void ProjectList::slotEditClip()
 {
     QList<QTreeWidgetItem *> list = m_listView->selectedItems();
@@ -363,13 +371,22 @@ void ProjectList::slotReloadClip(const QString &id)
     else selected.append(getItemById(id));
     ProjectItem *item;
     for (int i = 0; i < selected.count(); i++) {
-        if (selected.at(i)->type() != PROJECTCLIPTYPE) continue;
+        if (selected.at(i)->type() != PROJECTCLIPTYPE) {
+            if (selected.at(i)->type() == PROJECTFOLDERTYPE) {
+                for (int j = 0; j < selected.at(i)->childCount(); j++)
+                    selected.append(selected.at(i)->child(j));
+            }
+            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
@@ -378,6 +395,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;
@@ -386,6 +452,7 @@ void ProjectList::setRenderer(Render *projectRender)
 
 void ProjectList::slotClipSelected()
 {
+    if (!m_listView->isEnabled()) return;
     if (m_listView->currentItem()) {
         if (m_listView->currentItem()->type() == PROJECTFOLDERTYPE) {
             emit clipSelected(NULL);
@@ -421,6 +488,8 @@ void ProjectList::slotClipSelected()
             } else m_openAction->setEnabled(false);
             // Display relevant transcoding actions only
             adjustTranscodeActions(clip);
+            // Display uses in timeline
+            emit findInTimeline(clip->clipId());
         }
     } else {
         emit clipSelected(NULL);
@@ -434,7 +503,7 @@ void ProjectList::slotClipSelected()
 
 void ProjectList::adjustTranscodeActions(ProjectItem *clip) const
 {
-    if (clip == NULL || clip->type() != PROJECTCLIPTYPE || clip->clipType() == COLOR || clip->clipType() == TEXT || clip->clipType() == PLAYLIST) {
+    if (clip == NULL || clip->type() != PROJECTCLIPTYPE || clip->clipType() == COLOR || clip->clipType() == TEXT || clip->clipType() == PLAYLIST || clip->clipType() == SLIDESHOW || clip->clipType() == IMAGE) {
         m_transcodeAction->setEnabled(false);
         return;
     }
@@ -578,6 +647,8 @@ void ProjectList::slotContextMenu(const QPoint &pos, QTreeWidgetItem *item)
             clip = static_cast <ProjectItem*>(item);
             // Display relevant transcoding actions only
             adjustTranscodeActions(clip);
+            // Display uses in timeline
+            emit findInTimeline(clip->clipId());
         } else m_transcodeAction->setEnabled(false);
         if (clip && clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) {
             m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp()));
@@ -675,8 +746,12 @@ void ProjectList::slotDeleteClip(const QString &clipId)
     delete item;
     m_doc->clipManager()->deleteClip(clipId);
     m_listView->blockSignals(false);
-    if (newSelectedItem) m_listView->setCurrentItem(newSelectedItem);
-    else updateButtons();
+    if (newSelectedItem) {
+        m_listView->setCurrentItem(newSelectedItem);
+    } else {
+        updateButtons();
+        emit clipSelected(NULL);
+    }
 }
 
 
@@ -720,12 +795,11 @@ void ProjectList::slotAddFolder(const QString foldername, const QString &clipId,
                 }
             }
         } else {
-            QStringList text;
-            text << foldername;
             m_listView->blockSignals(true);
-            m_listView->setCurrentItem(new FolderProjectItem(m_listView, text, clipId));
+            m_listView->setCurrentItem(new FolderProjectItem(m_listView, QStringList() << foldername, clipId));
             m_doc->clipManager()->addFolder(clipId, foldername);
             m_listView->blockSignals(false);
+            m_listView->editItem(m_listView->currentItem(), 0);
         }
         updateButtons();
     }
@@ -756,9 +830,9 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
         QDomElement e = clip->toXML().cloneNode().toElement();
         e.removeAttribute("file_hash");
         m_infoQueue.insert(clip->getId(), e);
-        clip->askForAudioThumbs();
         //m_render->getFileProperties(clip->toXML(), clip->getId(), true);
     }
+    clip->askForAudioThumbs();
     const QString parent = clip->getProperty("groupid");
     ProjectItem *item = NULL;
     if (!parent.isEmpty()) {
@@ -914,7 +988,7 @@ void ProjectList::slotAddClip(const QList <QUrl> givenList, const QString &group
     KUrl::List list;
     if (givenList.isEmpty()) {
         // Build list of mime types
-        QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "application/x-kdenlivetitle" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mlt-playlist" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
+        QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "application/x-kdenlivetitle" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mlt-playlist" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
 
         QString allExtensions;
         foreach(const QString& mimeType, mimeTypes) {
@@ -978,7 +1052,9 @@ void ProjectList::slotAddColorClip()
     dia_ui.setupUi(dia);
     dia->setWindowTitle(i18n("Color Clip"));
     dia_ui.clip_name->setText(i18n("Color Clip"));
-    dia_ui.clip_duration->setText(KdenliveSettings::color_duration());
+    dia_ui.clip_duration->setInputMask("");
+    dia_ui.clip_duration->setValidator(m_timecode.validator());
+    dia_ui.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::color_duration()));
     if (dia->exec() == QDialog::Accepted) {
         QString color = dia_ui.clip_color->color().name();
         color = color.replace(0, 1, "0x") + "ff";
@@ -1028,6 +1104,8 @@ void ProjectList::slotAddTitleTemplateClip()
     for (int i = 0; i < templateFiles.size(); ++i) {
         dia_ui.template_list->comboBox()->addItem(templateFiles.at(i), path + templateFiles.at(i));
     }
+    if (!templateFiles.isEmpty())
+        dia_ui.buttonBox->button(QDialogButtonBox::Ok)->setFocus();
     dia_ui.template_list->fileDialog()->setFilter("*.kdenlivetitle");
     //warning: setting base directory doesn't work??
     KUrl startDir(path);
@@ -1087,6 +1165,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()));
 }
 
@@ -1232,11 +1312,17 @@ 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
             emit clipSelected(NULL);
             emit clipSelected(item->referencedClip());
+            //TODO: Make sure the line below has no side effect
+            toReload = clipId;
         }
         /*else {
             // Check if duration changed.
@@ -1249,13 +1335,12 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
         }*/
     } else kDebug() << "////////  COULD NOT FIND CLIP TO UPDATE PRPS...";
     int max = m_doc->clipManager()->clipsCount();
-    emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max));
-    // small delay so that the app can display the progress info
     if (item && m_infoQueue.isEmpty() && m_thumbnailQueue.isEmpty()) {
         m_listView->setCurrentItem(item);
         emit clipSelected(item->referencedClip());
-    }
+    } else emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max));
     if (!toReload.isEmpty()) emit clipNeedsReload(toReload, true);
+    // small delay so that the app can display the progress info
     QTimer::singleShot(30, this, SLOT(slotProcessNextClipInQueue()));
 }
 
@@ -1446,6 +1531,7 @@ void ProjectList::addClipCut(const QString &id, int in, int out, const QString d
         SubProjectItem *sub = new SubProjectItem(clip, in, out, desc);
         if (newItem && desc.isEmpty() && !m_listView->isColumnHidden(1)) {
             if (!clip->isExpanded()) clip->setExpanded(true);
+            m_listView->scrollToItem(sub);
             m_listView->editItem(sub, 1);
         }
         QPixmap p = clip->referencedClip()->thumbProducer()->extractImage(in, (int)(sub->sizeHint(0).height()  * m_render->dar()), sub->sizeHint(0).height() - 2);