]> git.sesse.net Git - kdenlive/blobdiff - src/projectlist.cpp
* Allow to edit transparent background for images in group properties
[kdenlive] / src / projectlist.cpp
index cd1c8d83b6c8e851e4266d529d293a19bf122145..e6d9149893388ae8df9d464f57ef32d8cdbcab9c 100644 (file)
@@ -262,9 +262,11 @@ void ProjectList::editClipSelection(QList<QTreeWidgetItem *> list)
     commonproperties.insert("audio_index", "-");
     commonproperties.insert("force_colorspace", "-");
     commonproperties.insert("full_luma", "-");
+    QString transparency = "-";
 
     bool allowDurationChange = true;
     int commonDuration = -1;
+    bool hasImages = false;;
     ProjectItem *item;
     for (int i = 0; i < list.count(); i++) {
         item = NULL;
@@ -286,6 +288,29 @@ void ProjectList::editClipSelection(QList<QTreeWidgetItem *> list)
             // check properties
             DocClipBase *clip = item->referencedClip();
             if (clipList.contains(clip)) continue;
+            if (clip->clipType() == IMAGE) {
+                hasImages = true;
+                if (clip->getProperty("transparency").isEmpty() || clip->getProperty("transparency").toInt() == 0) {
+                    if (transparency == "-") {
+                        // first non transparent image
+                        transparency = "0";
+                    }
+                    else if (transparency == "1") {
+                        // we have transparent and non transparent clips
+                        transparency = "-1";
+                    }
+                }
+                else {
+                    if (transparency == "-") {
+                        // first transparent image
+                        transparency = "1";
+                    }
+                    else if (transparency == "0") {
+                        // we have transparent and non transparent clips
+                        transparency = "-1";
+                    }
+                }
+            }
             if (clip->clipType() != COLOR && clip->clipType() != IMAGE && clip->clipType() != TEXT)
                 allowDurationChange = false;
             if (allowDurationChange && commonDuration != 0) {
@@ -313,6 +338,8 @@ void ProjectList::editClipSelection(QList<QTreeWidgetItem *> list)
     }
     if (allowDurationChange)
         commonproperties.insert("out", QString::number(commonDuration));
+    if (hasImages)
+        commonproperties.insert("transparency", transparency);
     /*QMapIterator<QString, QString> p(commonproperties);
     while (p.hasNext()) {
         p.next();
@@ -442,10 +469,8 @@ void ProjectList::slotReloadClip(const QString &id)
                 int length = QString(item->referencedClip()->producerProperty("length")).toInt();
                 if (length > 0 && !e.hasAttribute("length")) {
                     e.setAttribute("length", length);
-                    e.setAttribute("out", length - 1);
                 }
-            }
-            
+            }            
             emit getFileProperties(e, item->clipId(), m_listView->iconSize().height(), true, false);
         }
     }
@@ -585,7 +610,7 @@ void ProjectList::adjustProxyActions(ProjectItem *clip) const
         m_proxyAction->setEnabled(false);
         return;
     }
-    m_proxyAction->setEnabled(true);
+    m_proxyAction->setEnabled(useProxy());
     m_proxyAction->blockSignals(true);
     m_proxyAction->setChecked(clip->hasProxy());
     m_proxyAction->blockSignals(false);
@@ -827,7 +852,7 @@ void ProjectList::updateButtons() const
             m_openAction->setEnabled(true);
             m_reloadAction->setEnabled(true);
             m_transcodeAction->setEnabled(true);
-            m_proxyAction->setEnabled(true);
+            m_proxyAction->setEnabled(useProxy());
             return;
         }
         else if (item && item->type() == PROJECTFOLDERTYPE && item->childCount() > 0) {
@@ -960,18 +985,21 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
         if (parentitem)
             item = new ProjectItem(parentitem, clip);
     }
-    if (item == NULL)
+    if (item == NULL) {
         item = new ProjectItem(m_listView, clip);
+    }
     if (item->data(0, DurationRole).isNull()) item->setData(0, DurationRole, i18n("Loading"));
     if (getProperties) {
+        m_listView->processLayout();
         m_refreshed = false;
         // Proxy clips
         CLIPTYPE t = clip->clipType();
-        if ((t == VIDEO || t == AV || t == UNKNOWN) && KdenliveSettings::enableproxy()) {
+        if ((t == VIDEO || t == AV || t == UNKNOWN) && useProxy()) {
             if (clip->getProperty("proxy").isEmpty()) {
-                connect(clip, SIGNAL(proxyReady(const QString, bool)), this, SLOT(slotGotProxy(const QString, bool)));
-                setProxyStatus(item, 1);
-                clip->generateProxy(m_doc->projectFolder());
+                
+                //connect(clip, SIGNAL(proxyReady(const QString&, bool)), this, SLOT(slotGotProxy(const QString&, bool)));
+                //setProxyStatus(item, 1);
+                //clip->generateProxy(m_doc->projectFolder(), proxyParams());
             }
             else {
                 // Proxy clip already created
@@ -981,19 +1009,19 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
                 m_infoQueue.insert(clip->getId(), e);
             }
         }
-        else {
+        //else {
             // We don't use proxies
             // remove file_hash so that we load all properties for the clip
             QDomElement e = clip->toXML().cloneNode().toElement();
             e.removeAttribute("file_hash");
             m_infoQueue.insert(clip->getId(), e);
-        }
+        //}
         //m_render->getFileProperties(clip->toXML(), clip->getId(), true);
     }
     else if (!clip->getProperty("proxy").isEmpty()) {
-        connect(clip, SIGNAL(proxyReady(const QString, bool)), this, SLOT(slotGotProxy(const QString, bool)));
+        connect(clip, SIGNAL(proxyReady(const QString&, bool)), this, SLOT(slotGotProxy(const QString&, bool)));
         setProxyStatus(item, 1);
-        clip->generateProxy(m_doc->projectFolder());
+        clip->generateProxy(m_doc->projectFolder(), proxyParams());
     }
     clip->askForAudioThumbs();
     
@@ -1041,7 +1069,7 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
         m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }
 
-void ProjectList::slotGotProxy(const QString id, bool success)
+void ProjectList::slotGotProxy(const QString &id, bool success)
 {
     ProjectItem *item = getItemById(id);
     if (item) {
@@ -1151,8 +1179,7 @@ void ProjectList::updateAllClips()
         //qApp->processEvents();
         ++it;
     }
-    /*if (!m_queueTimer.isActive())
-        m_queueTimer.start();*/
+
     if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
     if (m_listView->isEnabled())
         monitorItemEditing(true);
@@ -1167,7 +1194,7 @@ 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" << "video/webm"
-                            << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "application/mxf" << "application/x-shockwave-flash"
+                            << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "audio/x-aiff" << "audio/aiff" << "application/ogg" << "application/mxf" << "application/x-shockwave-flash"
                             << "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;
@@ -1192,10 +1219,21 @@ void ProjectList::slotAddClip(const QList <QUrl> givenList, const QString &group
         const QString dialogFilter = allExtensions + ' ' + QLatin1Char('|') + i18n("All Supported Files") + "\n* " + QLatin1Char('|') + i18n("All Files");
         QCheckBox *b = new QCheckBox(i18n("Import image sequence"));
         b->setChecked(KdenliveSettings::autoimagesequence());
-        KFileDialog *d = new KFileDialog(KUrl("kfiledialog:///clipfolder"), dialogFilter, kapp->activeWindow(), b);
+        QCheckBox *c = new QCheckBox(i18n("Transparent background for images"));
+        c->setChecked(KdenliveSettings::autoimagetransparency());
+        QFrame *f = new QFrame;
+        f->setFrameShape(QFrame::NoFrame);
+        QHBoxLayout *l = new QHBoxLayout;
+        l->addWidget(b);
+        l->addWidget(c);
+        l->addStretch(5);
+        f->setLayout(l);
+        KFileDialog *d = new KFileDialog(KUrl("kfiledialog:///clipfolder"), dialogFilter, kapp->activeWindow(), f);
         d->setOperationMode(KFileDialog::Opening);
         d->setMode(KFile::Files);
-        d->exec();
+        if (d->exec() == QDialog::Accepted) {
+            KdenliveSettings::setAutoimagetransparency(c->isChecked());
+        }
         list = d->selectedUrls();
         if (b->isChecked() && list.count() == 1) {
             // Check for image sequence
@@ -1560,9 +1598,18 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
             item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled);
             toReload = clipId;
         }
-        if (item->referencedClip()->getProperty("proxy").isEmpty()) setProxyStatus(item, 0);
-        item->referencedClip()->setProducer(producer, replace);
-        item->referencedClip()->askForAudioThumbs();
+        if (!useProxy() && item->referencedClip()->getProperty("proxy").isEmpty()) setProxyStatus(item, 0);
+        QString size = properties.value("frame_size");
+        DocClipBase *clip = item->referencedClip();
+        if (useProxy() && (item->clipType() == AV || item->clipType() == VIDEO) && generateProxy() && size.section('x', 0, 0).toInt() > proxyMinSize()) {
+            if (clip->getProperty("proxy").isEmpty()) {
+                connect(clip, SIGNAL(proxyReady(const QString&, bool)), this, SLOT(slotGotProxy(const QString&, bool)));
+                setProxyStatus(item, 1);
+                clip->generateProxy(m_doc->projectFolder(), proxyParams());
+            }
+        }
+        clip->setProducer(producer, replace);
+        clip->askForAudioThumbs();
         if (!replace && item->data(0, Qt::DecorationRole).isNull())
             requestClipThumbnail(clipId);
         if (!toReload.isEmpty())
@@ -1571,7 +1618,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
         if (m_listView->isEnabled() && replace) {
             // update clip in clip monitor
             emit clipSelected(NULL);
-            emit clipSelected(item->referencedClip());
+            emit clipSelected(clip);
             //TODO: Make sure the line below has no side effect
             toReload = clipId;
         }
@@ -1668,6 +1715,26 @@ bool ProjectList::adjustProjectProfileToItem(ProjectItem *item)
     return profileUpdated;
 }
 
+bool ProjectList::useProxy() const
+{
+    return m_doc->getDocumentProperty("enableproxy").toInt();
+}
+
+bool ProjectList::generateProxy() const
+{
+    return m_doc->getDocumentProperty("generateproxy").toInt();
+}
+
+int ProjectList::proxyMinSize() const
+{
+    return m_doc->getDocumentProperty("proxyminsize").toInt();
+}
+
+QString ProjectList::proxyParams() const
+{
+    return m_doc->getDocumentProperty("proxyparams").simplified();
+}
+
 void ProjectList::slotReplyGetImage(const QString &clipId, const QPixmap &pix)
 {
     ProjectItem *item = getItemById(clipId);
@@ -1722,7 +1789,7 @@ ProjectItem *ProjectList::getItemById(const QString &id)
     QTreeWidgetItemIterator it(m_listView);
     while (*it) {
         if ((*it)->type() != PROJECTCLIPTYPE) {
-            // subitem
+            // subitem or folder
             ++it;
             continue;
         }
@@ -1759,7 +1826,7 @@ void ProjectList::slotSelectClip(const QString &ix)
         m_deleteButton->defaultAction()->setEnabled(true);
         m_reloadAction->setEnabled(true);
         m_transcodeAction->setEnabled(true);
-        m_proxyAction->setEnabled(true);
+        m_proxyAction->setEnabled(useProxy());
         if (clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) {
             m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp()));
             m_openAction->setEnabled(true);
@@ -2010,12 +2077,19 @@ void ProjectList::updateProxyConfig()
             continue;
         }
         item = static_cast<ProjectItem *>(*it);
-        if (item && item->referencedClip() != NULL) {
-            if  (KdenliveSettings::enableproxy()) {
+        if (item == NULL) {
+            ++it;
+            continue;
+        }
+        CLIPTYPE t = item->clipType();
+        if ((t == VIDEO || t == AV || t == UNKNOWN) && item->referencedClip() != NULL) {
+            if  (generateProxy() && useProxy()) {
                 DocClipBase *clip = item->referencedClip();
-                connect(clip, SIGNAL(proxyReady(const QString, bool)), this, SLOT(slotGotProxy(const QString, bool)));
-                setProxyStatus(item, 1);
-                clip->generateProxy(m_doc->projectFolder());
+                if (clip->getProperty("frame_size").section('x', 0, 0).toInt() > proxyMinSize()) {
+                    connect(clip, SIGNAL(proxyReady(const QString &, bool)), this, SLOT(slotGotProxy(const QString &, bool)));
+                    setProxyStatus(item, 1);
+                    clip->generateProxy(m_doc->projectFolder(), proxyParams());
+                }
             }
             else if (!item->referencedClip()->getProperty("proxy").isEmpty()) {
                 // remove proxy
@@ -2045,20 +2119,24 @@ void ProjectList::slotProxyCurrentItem(bool doProxy)
         }
         if (listItem->type() == PROJECTCLIPTYPE) {
             ProjectItem *item = static_cast <ProjectItem*>(listItem);
-            if (item->referencedClip()) {
+            CLIPTYPE t = item->clipType();
+            if ((t == VIDEO || t == AV || t == UNKNOWN) && item->referencedClip()) {
                 if (doProxy) {
                     DocClipBase *clip = item->referencedClip();
-                    connect(clip, SIGNAL(proxyReady(const QString, bool)), this, SLOT(slotGotProxy(const QString, bool)));
+                    connect(clip, SIGNAL(proxyReady(const QString&, bool)), this, SLOT(slotGotProxy(const QString&, bool)));
                     setProxyStatus(item, 1);
-                    clip->generateProxy(m_doc->projectFolder());
+                    clip->generateProxy(m_doc->projectFolder(), proxyParams());
                 }
                 else if (!item->referencedClip()->getProperty("proxy").isEmpty()) {
                     // remove proxy
-                    item->referencedClip()->clearProperty("proxy");
-                    QDomElement e = item->toXml().cloneNode().toElement();
-                    e.removeAttribute("file_hash");
-                    e.setAttribute("replace", 1);
-                    m_infoQueue.insert(item->clipId(), e);
+                    if (!item->isProxyRunning()) {
+                        setProxyStatus(item, 0);
+                        QDomElement e = item->toXml().cloneNode().toElement();
+                        e.removeAttribute("file_hash");
+                        e.setAttribute("replace", 1);
+                        m_infoQueue.insert(item->clipId(), e);
+                    }
+                    else setProxyStatus(item, 0);
                 }
             }
         }