]> git.sesse.net Git - kdenlive/blobdiff - src/projectlist.cpp
Improve profile autodetection
[kdenlive] / src / projectlist.cpp
index dc5d239892099218a45185f11b9c282eca46a695..18562312f62821e09ddc82d3d787e8be209bf200 100644 (file)
@@ -32,6 +32,7 @@
 #include "kthumb.h"
 #include "projectlistview.h"
 #include "timecodedisplay.h"
+#include "profilesdialog.h"
 #include "editclipcommand.h"
 #include "editclipcutcommand.h"
 #include "editfoldercommand.h"
 #include <QInputDialog>
 
 ProjectList::ProjectList(QWidget *parent) :
-        QWidget(parent),
-        m_render(NULL),
-        m_fps(-1),
-        m_commandStack(NULL),
-        m_editAction(NULL),
-        m_deleteAction(NULL),
-        m_openAction(NULL),
-        m_reloadAction(NULL),
-        m_transcodeAction(NULL),
-        m_doc(NULL),
-        m_refreshed(false),
-        m_infoQueue(),
-        m_thumbnailQueue()
+    QWidget(parent),
+    m_render(NULL),
+    m_fps(-1),
+    m_commandStack(NULL),
+    m_editAction(NULL),
+    m_deleteAction(NULL),
+    m_openAction(NULL),
+    m_reloadAction(NULL),
+    m_transcodeAction(NULL),
+    m_doc(NULL),
+    m_refreshed(false),
+    m_infoQueue(),
+    m_thumbnailQueue()
 {
 
     m_listView = new ProjectListView(this);;
@@ -559,9 +560,9 @@ void ProjectList::adjustTranscodeActions(ProjectItem *clip) const
         if (data.count() > 2) {
             condition = data.at(2);
             if (condition.startsWith("vcodec"))
-                transcodeActions.at(i)->setEnabled(clip->referencedClip()->hasVideoCodec(condition.section("=", 1, 1)));
+                transcodeActions.at(i)->setEnabled(clip->referencedClip()->hasVideoCodec(condition.section('=', 1, 1)));
             else if (condition.startsWith("acodec"))
-                transcodeActions.at(i)->setEnabled(clip->referencedClip()->hasVideoCodec(condition.section("=", 1, 1)));
+                transcodeActions.at(i)->setEnabled(clip->referencedClip()->hasVideoCodec(condition.section('=', 1, 1)));
         }
     }
 
@@ -1054,11 +1055,11 @@ QString ProjectList::getExtensions()
     // Build list of mime types
     QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "application/x-kdenlivetitle" << "video/mlt-playlist" << "text/plain"
                             << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "video/mp4" << "video/quicktime"
-                            << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg"
+                            << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "application/mxf"
                             << "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) {
+    foreach(const QString & mimeType, mimeTypes) {
         KMimeType::Ptr mime(KMimeType::mimeType(mimeType));
         if (mime) {
             allExtensions.append(mime->patterns().join(" "));
@@ -1077,14 +1078,48 @@ void ProjectList::slotAddClip(const QList <QUrl> givenList, const QString &group
     if (givenList.isEmpty()) {
         QString allExtensions = getExtensions();
         const QString dialogFilter = allExtensions + ' ' + QLatin1Char('|') + i18n("All Supported Files") + "\n* " + QLatin1Char('|') + i18n("All Files");
-        list = KFileDialog::getOpenUrls(KUrl("kfiledialog:///clipfolder"), dialogFilter, this);
-
+        QCheckBox *b = new QCheckBox(i18n("Import image sequence"));
+        b->setChecked(KdenliveSettings::autoimagesequence());
+        KFileDialog *d = new KFileDialog(KUrl("kfiledialog:///clipfolder"), dialogFilter, this, b);
+        d->setOperationMode(KFileDialog::Opening);
+        d->setMode(KFile::Files);
+        d->exec();
+        list = d->selectedUrls();
+        if (b->isChecked() && list.count() == 1) {
+            // Check for image sequence
+            KUrl url = list.at(0);
+            QString fileName = url.fileName().section('.', 0, -2);
+            if (fileName.at(fileName.size() - 1).isDigit()) {
+                KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url);
+                if (item.mimetype().startsWith("image")) {
+                    int count = 0;
+                    // import as sequence if we found more than one image in the sequence
+                    QString pattern = SlideshowClip::selectedPath(url.path(), false, QString(), &count);
+                    if (count > 1) {
+                        delete d;
+                        QStringList groupInfo = getGroup();
+
+                        // get image sequence base name
+                        while (fileName.at(fileName.size() - 1).isDigit()) {
+                            fileName.chop(1);
+                        }
+
+                        m_doc->slotCreateSlideshowClipFile(fileName, pattern, count, m_timecode.reformatSeparators(KdenliveSettings::sequence_duration()),
+                                                           false, false, false,
+                                                           m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps()))), QString(), 0,
+                                                           QString(), groupInfo.at(0), groupInfo.at(1));
+                        return;
+                    }
+                }
+            }
+        }
+        delete d;
     } else {
         for (int i = 0; i < givenList.count(); i++)
             list << givenList.at(i);
     }
 
-    foreach(const KUrl &file, list) {
+    foreach(const KUrl & file, list) {
         // Check there is no folder here
         KMimeType::Ptr type = KMimeType::findByUrl(file);
         if (type->is("inode/directory")) {
@@ -1160,8 +1195,10 @@ void ProjectList::slotAddSlideshowClip()
 
     if (dia->exec() == QDialog::Accepted) {
         QStringList groupInfo = getGroup();
-        m_doc->slotCreateSlideshowClipFile(dia->clipName(), dia->selectedPath(), dia->imageCount(), dia->clipDuration(), dia->loop(), dia->fade(),
-                                           dia->lumaDuration(), dia->lumaFile(), dia->softness(), groupInfo.at(0), groupInfo.at(1));
+        m_doc->slotCreateSlideshowClipFile(dia->clipName(), dia->selectedPath(), dia->imageCount(), dia->clipDuration(),
+                                           dia->loop(), dia->crop(), dia->fade(),
+                                           dia->lumaDuration(), dia->lumaFile(), dia->softness(),
+                                           dia->animation(), groupInfo.at(0), groupInfo.at(1));
     }
     delete dia;
 }
@@ -1270,7 +1307,7 @@ QDomElement ProjectList::producersList()
     QDomDocument doc;
     QDomElement prods = doc.createElement("producerlist");
     doc.appendChild(prods);
-    kDebug() << "////////////  PRO LIST BUILD PRDSLIST ";
+    kDebug() << "////////////  PRO LIST BUILD PRDSLIST ";
     QTreeWidgetItemIterator it(m_listView);
     while (*it) {
         if ((*it)->type() != PROJECTCLIPTYPE) {
@@ -1436,11 +1473,56 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
     int max = m_doc->clipManager()->clipsCount();
     if (item && m_infoQueue.isEmpty() && m_thumbnailQueue.isEmpty()) {
         m_listView->setCurrentItem(item);
+        bool displayClipInMonitor = true;
         if (item->parent()) {
             if (item->parent()->type() == PROJECTFOLDERTYPE)
                 static_cast <FolderProjectItem *>(item->parent())->switchIcon();
+        } else if (KdenliveSettings::checkfirstprojectclip() &&  m_listView->topLevelItemCount() == 1) {
+            // this is the first clip loaded in project, check if we want to adjust project settings to the clip
+            int width = properties.value("frame_size").section('x', 0, 0).toInt();
+            int height = properties.value("frame_size").section('x', -1).toInt();
+            double fps = properties.value("fps").toDouble();
+            double par = properties.value("aspect_ratio").toDouble();
+            if (item->clipType() == IMAGE || item->clipType() == AV || item->clipType() == VIDEO) {
+                if (ProfilesDialog::matchProfile(width, height, fps, par, item->clipType() == IMAGE, m_doc->mltProfile()) == false) {
+                    // get a list of compatible profiles
+                    QMap <QString, QString> suggestedProfiles = ProfilesDialog::getProfilesFromProperties(width, height, fps, par, item->clipType() == IMAGE);
+                    if (!suggestedProfiles.isEmpty()) {
+                        KDialog *dialog = new KDialog(this);
+                        dialog->setCaption(i18n("Change project profile"));
+                        dialog->setButtons(KDialog::Ok | KDialog::Cancel);
+
+                        QWidget container;
+                        QVBoxLayout *l = new QVBoxLayout;
+                        QLabel *label = new QLabel(i18n("Your clip does not match current project's profile.\nDo you want to change the project profile?\n\nThe following profiles match the clip (size: %1, fps: %2)", properties.value("frame_size"), fps));
+                        l->addWidget(label);
+                        QListWidget *list = new QListWidget;
+                        list->setAlternatingRowColors(true);
+                        QMapIterator<QString, QString> i(suggestedProfiles);
+                        while (i.hasNext()) {
+                            i.next();
+                            QListWidgetItem *item = new QListWidgetItem(i.value(), list);
+                            item->setData(Qt::UserRole, i.key());
+                            item->setToolTip(i.key());
+                        }
+                        list->setCurrentRow(0);
+                        l->addWidget(list);
+                        container.setLayout(l);
+                        dialog->setButtonText(KDialog::Ok, i18n("Update profile"));
+                        dialog->setMainWidget(&container);
+                        if (dialog->exec() == QDialog::Accepted) {
+                            //Change project profile
+                            displayClipInMonitor = false;
+                            if (list->currentItem())
+                                emit updateProfile(list->currentItem()->data(Qt::UserRole).toString());
+                        }
+                        delete list;
+                        delete label;
+                    } else KMessageBox::information(this, i18n("Your clip does not match current project's profile.\nNo existing profile found to match the clip's properties.\nClip size: %1\nFps: %2\n", properties.value("frame_size"), fps));
+                }
+            }
         }
-        emit clipSelected(item->referencedClip());
+        if (displayClipInMonitor) emit clipSelected(item->referencedClip());
     } else {
         emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max));
     }
@@ -1585,9 +1667,9 @@ KUrl::List ProjectList::getConditionalUrls(const QString &condition) const
             continue;
         DocClipBase *clip = item->referencedClip();
         if (!condition.isEmpty()) {
-            if (condition.startsWith("vcodec") && !clip->hasVideoCodec(condition.section("=", 1, 1)))
+            if (condition.startsWith("vcodec") && !clip->hasVideoCodec(condition.section('=', 1, 1)))
                 continue;
-            else if (condition.startsWith("acodec") && !clip->hasAudioCodec(condition.section("=", 1, 1)))
+            else if (condition.startsWith("acodec") && !clip->hasAudioCodec(condition.section('=', 1, 1)))
                 continue;
         }
         result.append(item->clipUrl());