]> git.sesse.net Git - kdenlive/blobdiff - src/clipproperties.cpp
Fix display of aspect ratio in clip properties for mlt playlists
[kdenlive] / src / clipproperties.cpp
index c66c126e49f86d2b348c4412a97a112a6a888db6..b0b957093871f26f662cd2dc256dd880e823c82b 100644 (file)
 #include <KStandardDirs>
 #include <KDebug>
 #include <KFileItem>
+#include <kdeversion.h>
+#include <KUrlLabel>
+#include <KRun>
+
+#ifdef USE_NEPOMUK
+#if KDE_IS_VERSION(4,6,0)
+#include <Nepomuk/Variant>
+#include <Nepomuk/Resource>
+#include <Nepomuk/ResourceManager>
+#include <Nepomuk/Vocabulary/NIE>
+#endif
+#endif
+
 
 #include <QDir>
 
@@ -47,12 +60,16 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
     m_fps(fps),
     m_count(0),
     m_clipNeedsRefresh(false),
-    m_clipNeedsReLoad(false),
-    m_propsDelegate(NULL)
+    m_clipNeedsReLoad(false)
 {
     setAttribute(Qt::WA_DeleteOnClose, true);
     setFont(KGlobalSettings::toolBarFont());
     m_view.setupUi(this);
+    
+    // force transparency is only for group properties, so hide it
+    m_view.clip_force_transparency->setHidden(true);
+    m_view.clip_transparency->setHidden(true);
+    
     KUrl url = m_clip->fileURL();
     m_view.clip_path->setText(url.path());
     m_view.clip_description->setText(m_clip->description());
@@ -61,7 +78,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
     QMap <QString, QString> props = m_clip->properties();
     m_view.clip_force_out->setHidden(true);
     m_view.clip_out->setHidden(true);
-
+    
     // New display aspect ratio support
     if (props.contains("force_aspect_num") && props.value("force_aspect_num").toInt() > 0 &&
         props.contains("force_aspect_den") && props.value("force_aspect_den").toInt() > 0) {
@@ -113,6 +130,16 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
     connect(m_view.clip_force_progressive, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
     connect(m_view.clip_progressive, SIGNAL(valueChanged(int)), this, SLOT(slotModified()));
 
+    m_view.clip_fieldorder->addItem(i18n("Bottom first"), 0);
+    m_view.clip_fieldorder->addItem(i18n("Top first"), 1);
+    if (props.contains("force_tff")) {
+        m_view.clip_force_fieldorder->setChecked(true);
+        m_view.clip_fieldorder->setEnabled(true);
+        m_view.clip_fieldorder->setCurrentIndex(props.value("force_tff").toInt());
+    }
+    connect(m_view.clip_force_fieldorder, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+    connect(m_view.clip_fieldorder, SIGNAL(currentIndexChanged(int)), this, SLOT(slotModified()));
+    
     if (props.contains("threads") && props.value("threads").toInt() != 1) {
         m_view.clip_force_threads->setChecked(true);
         m_view.clip_threads->setEnabled(true);
@@ -177,21 +204,52 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
     connect(m_view.clip_force_ar, SIGNAL(toggled(bool)), m_view.clip_ar_den, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_framerate, SIGNAL(toggled(bool)), m_view.clip_framerate, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_progressive, SIGNAL(toggled(bool)), m_view.clip_progressive, SLOT(setEnabled(bool)));
+    connect(m_view.clip_force_fieldorder, SIGNAL(toggled(bool)), m_view.clip_fieldorder, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_threads, SIGNAL(toggled(bool)), m_view.clip_threads, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_vindex, SIGNAL(toggled(bool)), m_view.clip_vindex, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_aindex, SIGNAL(toggled(bool)), m_view.clip_aindex, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_colorspace, SIGNAL(toggled(bool)), m_view.clip_colorspace, SLOT(setEnabled(bool)));
 
     if (props.contains("audiocodec"))
-        QTreeWidgetItem *item = new QTreeWidgetItem(m_view.clip_aproperties, QStringList() << i18n("Audio codec") << props.value("audiocodec"));
+        new QTreeWidgetItem(m_view.clip_aproperties, QStringList() << i18n("Audio codec") << props.value("audiocodec"));
 
     if (props.contains("channels"))
-        QTreeWidgetItem *item = new QTreeWidgetItem(m_view.clip_aproperties, QStringList() << i18n("Channels") << props.value("channels"));
+        new QTreeWidgetItem(m_view.clip_aproperties, QStringList() << i18n("Channels") << props.value("channels"));
 
     if (props.contains("frequency"))
-        QTreeWidgetItem *item = new QTreeWidgetItem(m_view.clip_aproperties, QStringList() << i18n("Frequency") << props.value("frequency"));
+        new QTreeWidgetItem(m_view.clip_aproperties, QStringList() << i18n("Frequency") << props.value("frequency"));
+    
 
     CLIPTYPE t = m_clip->clipType();
+    
+    if (props.contains("proxy") && props.value("proxy") != "-") {
+        KFileItem f(KFileItem::Unknown, KFileItem::Unknown, KUrl(props.value("proxy")), true);
+        QFrame* line = new QFrame();
+        line->setFrameShape(QFrame::HLine);
+        line->setFrameShadow(QFrame::Sunken);
+        m_proxyContainer = new QFrame();
+        m_proxyContainer->setFrameShape(QFrame::NoFrame);
+        QHBoxLayout *l = new QHBoxLayout;
+        l->addWidget(new QLabel(i18n("Proxy clip: %1", KIO::convertSize(f.size()))));
+        l->addStretch(5);
+        QPushButton *pb = new QPushButton(i18n("Delete proxy"));
+        l->addWidget(pb);
+        connect(pb, SIGNAL(clicked()), this, SLOT(slotDeleteProxy()));
+        m_proxyContainer->setLayout(l);
+        if (t == IMAGE) {
+            m_view.tab_image->layout()->addWidget(line);
+            m_view.tab_image->layout()->addWidget(m_proxyContainer);
+        }
+        else if (t == AUDIO) {
+            m_view.tab_audio->layout()->addWidget(line);
+            m_view.tab_audio->layout()->addWidget(m_proxyContainer);
+        }
+        else {
+            m_view.tab_video->layout()->addWidget(line);
+            m_view.tab_video->layout()->addWidget(m_proxyContainer);
+        }
+    }
+    
     if (t != AUDIO && t != AV) {
         m_view.clip_force_aindex->setEnabled(false);
     }
@@ -200,6 +258,9 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         m_view.clip_force_vindex->setEnabled(false);
     }
 
+    if (t == PLAYLIST)
+       m_view.tabWidget->setTabText(VIDEOTAB, i18n("Playlist"));
+
     if (t == IMAGE) {
         m_view.tabWidget->removeTab(SLIDETAB);
         m_view.tabWidget->removeTab(COLORTAB);
@@ -224,7 +285,6 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         m_view.clip_color->setColor(QColor('#' + props.value("colour").right(8).left(6)));
         connect(m_view.clip_color, SIGNAL(changed(QColor)), this, SLOT(slotModified()));
     } else if (t == SLIDESHOW) {
-        bool isMime = true;
         if (url.fileName().startsWith(".all.")) {
             // the image sequence is defined by mimetype
             m_view.clip_path->setText(url.directory());
@@ -233,7 +293,6 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
             m_view.slide_type_label->setHidden(true);
             m_view.image_type->setHidden(true);
             m_view.clip_path->setText(url.path());
-            isMime = false;
         }
 
         m_view.tabWidget->removeTab(METATAB);
@@ -278,7 +337,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         }
         m_view.slide_duration->setText(tc.getTimecodeFromFrames(props.value("ttl").toInt()));
 
-        m_view.slide_duration_format->addItem(i18n("hh:mm:ss::ff"));
+        m_view.slide_duration_format->addItem(i18n("hh:mm:ss:ff"));
         m_view.slide_duration_format->addItem(i18n("Frames"));
         connect(m_view.slide_duration_format, SIGNAL(activated(int)), this, SLOT(slotUpdateDurationFormat(int)));
         m_view.slide_duration_frames->setHidden(true);
@@ -341,16 +400,15 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         m_view.tabWidget->removeTab(SLIDETAB);
         m_view.tabWidget->removeTab(COLORTAB);
 
-
-
-        m_propsDelegate = new PropertiesViewDelegate(this);
-        m_view.clip_vproperties->setItemDelegate(m_propsDelegate);
-        m_view.clip_aproperties->setItemDelegate(m_propsDelegate);
+        PropertiesViewDelegate *del1 = new PropertiesViewDelegate(this);
+        PropertiesViewDelegate *del2 = new PropertiesViewDelegate(this);
+        m_view.clip_vproperties->setItemDelegate(del1);
+        m_view.clip_aproperties->setItemDelegate(del2);
         m_view.clip_aproperties->setStyleSheet(QString("QTreeWidget { background-color: transparent;}"));
         m_view.clip_vproperties->setStyleSheet(QString("QTreeWidget { background-color: transparent;}"));
 
         if (props.contains("videocodec"))
-            QTreeWidgetItem *item = new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Video codec") << props.value("videocodec"));
+            new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Video codec") << props.value("videocodec"));
 
         if (props.contains("frame_size"))
             new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Frame size") << props.value("frame_size"));
@@ -359,6 +417,13 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
             new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Frame rate") << props.value("fps"));
             if (!m_view.clip_framerate->isEnabled()) m_view.clip_framerate->setValue(props.value("fps").toDouble());
         }
+
+        if (props.contains("progressive")) {
+            int scanning = props.value("progressive").toInt();
+            QString txt = scanning == 1 ? i18n("Progressive") : i18n("Interlaced");
+            new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Scanning") << txt);
+        }
+        
         if (props.contains("aspect_ratio"))
             new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Pixel aspect ratio") << props.value("aspect_ratio"));
 
@@ -367,12 +432,13 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
 
         if (props.contains("colorspace"))
             new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Colorspace") << ProfilesDialog::getColorspaceDescription(props.value("colorspace").toInt()));
+        
 
         int width = 180.0 * KdenliveSettings::project_display_ratio();
         if (width % 2 == 1) width++;
         QPixmap pix = m_clip->thumbProducer()->getImage(url, m_clip->getClipThumbFrame(), width, 180);
         m_view.clip_thumb->setPixmap(pix);
-        if (t == IMAGE || t == VIDEO) m_view.tabWidget->removeTab(AUDIOTAB);
+        if (t == IMAGE || t == VIDEO || t == PLAYLIST) m_view.tabWidget->removeTab(AUDIOTAB);
     } else {
         m_view.tabWidget->removeTab(IMAGETAB);
         m_view.tabWidget->removeTab(SLIDETAB);
@@ -388,11 +454,13 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         m_view.clip_filesize->setHidden(true);
         m_view.label_size->setHidden(true);
     }
-    m_view.clip_duration->setInputMask("");
-    m_view.clip_duration->setValidator(tc.validator());
+    m_view.clip_duration->setInputMask(tc.mask());
     m_view.clip_duration->setText(tc.getTimecode(m_clip->duration()));
     if (t != IMAGE && t != COLOR && t != TEXT) m_view.clip_duration->setReadOnly(true);
-    else connect(m_view.clip_duration, SIGNAL(editingFinished()), this, SLOT(slotCheckMaxLength()));
+    else {
+        connect(m_view.clip_duration, SIGNAL(editingFinished()), this, SLOT(slotCheckMaxLength()));
+        connect(m_view.clip_duration, SIGNAL(textChanged(QString)), this, SLOT(slotModified()));
+    }
 
     // markers
     m_view.marker_new->setIcon(KIcon("document-new"));
@@ -401,17 +469,48 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
     m_view.marker_edit->setToolTip(i18n("Edit marker"));
     m_view.marker_delete->setIcon(KIcon("trash-empty"));
     m_view.marker_delete->setToolTip(i18n("Delete marker"));
-
-    slotFillMarkersList();
+    m_view.marker_save->setIcon(KIcon("document-save-as"));
+    m_view.marker_save->setToolTip(i18n("Save markers"));
+    m_view.marker_load->setIcon(KIcon("document-open"));
+    m_view.marker_load->setToolTip(i18n("Load markers"));
+
+        // Check for Nepomuk metadata
+#ifdef USE_NEPOMUK
+#if KDE_IS_VERSION(4,6,0)
+    if (!url.isEmpty()) {
+        Nepomuk::ResourceManager::instance()->init();
+        Nepomuk::Resource res( url.path() );
+        // Check if file has a license
+        if (res.hasProperty(Nepomuk::Vocabulary::NIE::license())) {
+            QString ltype = res.property(Nepomuk::Vocabulary::NIE::licenseType()).toString();
+            m_view.clip_license->setText(i18n("License: %1", res.property(Nepomuk::Vocabulary::NIE::license()).toString()));
+            if (ltype.startsWith("http")) {
+                m_view.clip_license->setUrl(ltype);
+                connect(m_view.clip_license, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
+            }
+        }
+        else m_view.clip_license->setHidden(true);
+    }
+    else m_view.clip_license->setHidden(true);
+#else
+    m_view.clip_license->setHidden(true);
+#endif
+#else
+    m_view.clip_license->setHidden(true);
+#endif
+    
+    slotFillMarkersList(m_clip);
     connect(m_view.marker_new, SIGNAL(clicked()), this, SLOT(slotAddMarker()));
     connect(m_view.marker_edit, SIGNAL(clicked()), this, SLOT(slotEditMarker()));
     connect(m_view.marker_delete, SIGNAL(clicked()), this, SLOT(slotDeleteMarker()));
+    connect(m_view.marker_save, SIGNAL(clicked()), this, SLOT(slotSaveMarkers()));
+    connect(m_view.marker_load, SIGNAL(clicked()), this, SLOT(slotLoadMarkers()));
     connect(m_view.markers_list, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(slotEditMarker()));
 
     connect(this, SIGNAL(accepted()), this, SLOT(slotApplyProperties()));
     connect(m_view.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(slotApplyProperties()));
     m_view.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
-    //adjustSize();
+    adjustSize();
 }
 
 
@@ -427,6 +526,9 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
 {
     setFont(KGlobalSettings::toolBarFont());
     m_view.setupUi(this);
+    QString title = windowTitle();
+    title.append(' ' + i18np("(%1 clip)", "(%1 clips)", cliplist.count()));
+    setWindowTitle(title);
     QMap <QString, QString> props = cliplist.at(0)->properties();
     m_old_props = commonproperties;
 
@@ -450,6 +552,12 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
         m_view.clip_progressive->setValue(commonproperties.value("force_progressive").toInt());
     }
 
+    if (commonproperties.contains("force_tff") && !commonproperties.value("force_tff").isEmpty()) {
+        m_view.clip_force_fieldorder->setChecked(true);
+        m_view.clip_fieldorder->setEnabled(true);
+        m_view.clip_fieldorder->setCurrentIndex(commonproperties.value("force_tff").toInt());
+    }
+    
     if (commonproperties.contains("threads") && !commonproperties.value("threads").isEmpty() && commonproperties.value("threads").toInt() != 1) {
         m_view.clip_force_threads->setChecked(true);
         m_view.clip_threads->setEnabled(true);
@@ -476,6 +584,10 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
         m_view.clip_vindex->setMaximum(props.value("video_max").toInt());
     }
     
+    m_view.clip_colorspace->addItem(ProfilesDialog::getColorspaceDescription(601), 601);
+    m_view.clip_colorspace->addItem(ProfilesDialog::getColorspaceDescription(709), 709);
+    m_view.clip_colorspace->addItem(ProfilesDialog::getColorspaceDescription(240), 240);
+    
     if (commonproperties.contains("force_colorspace") && !commonproperties.value("force_colorspace").isEmpty() && commonproperties.value("force_colorspace").toInt() != 0) {
         m_view.clip_force_colorspace->setChecked(true);
         m_view.clip_colorspace->setEnabled(true);
@@ -485,7 +597,25 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
     if (commonproperties.contains("full_luma") && !commonproperties.value("full_luma").isEmpty()) {
         m_view.clip_full_luma->setChecked(true);
     }
+    
+    if (commonproperties.contains("transparency")) {
+        // image transparency checkbox
+        int transparency = commonproperties.value("transparency").toInt();
+        if (transparency == 0) {
+            m_view.clip_force_transparency->setChecked(true);
+        }
+        else if (transparency == 1) {
+            m_view.clip_force_transparency->setChecked(true);
+            m_view.clip_transparency->setCurrentIndex(1);
+        }
+    }
+    else {
+        m_view.clip_force_transparency->setHidden(true);
+        m_view.clip_transparency->setHidden(true);
+    }
+    
 
+    connect(m_view.clip_force_transparency, SIGNAL(toggled(bool)), m_view.clip_transparency, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_ar, SIGNAL(toggled(bool)), m_view.clip_ar_num, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_ar, SIGNAL(toggled(bool)), m_view.clip_ar_den, SLOT(setEnabled(bool)));
     connect(m_view.clip_force_progressive, SIGNAL(toggled(bool)), m_view.clip_progressive, SLOT(setEnabled(bool)));
@@ -528,13 +658,18 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
 
 ClipProperties::~ClipProperties()
 {
-    if (m_propsDelegate) delete m_propsDelegate;
+    QAbstractItemDelegate *del1 = m_view.clip_vproperties->itemDelegate();
+    if (del1) delete del1;
+    QAbstractItemDelegate *del2 = m_view.clip_aproperties->itemDelegate();
+    if (del2) delete del2;
 }
 
 void ClipProperties::slotApplyProperties()
 {
-    if (m_clip != NULL)
-        emit applyNewClipProperties(m_clip->getId(), m_clip->properties(), properties(), needsTimelineRefresh(), needsTimelineReload());
+    if (m_clip != NULL) {
+        QMap <QString, QString> props = properties();
+        emit applyNewClipProperties(m_clip->getId(), m_clip->currentProperties(props), props, needsTimelineRefresh(), needsTimelineReload());
+    }
     m_view.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
 }
 
@@ -577,8 +712,9 @@ void ClipProperties::slotEnableLumaFile(int state)
     m_view.label_softness->setEnabled(enable);
 }
 
-void ClipProperties::slotFillMarkersList()
+void ClipProperties::slotFillMarkersList(DocClipBase *clip)
 {
+    if (m_clip != clip) return;
     m_view.markers_list->clear();
     QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
     for (int count = 0; count < marks.count(); ++count) {
@@ -592,11 +728,22 @@ void ClipProperties::slotFillMarkersList()
 void ClipProperties::slotAddMarker()
 {
     CommentedTime marker(GenTime(), i18n("Marker"));
-    MarkerDialog d(m_clip, marker, m_tc, i18n("Add Marker"), this);
-    if (d.exec() == QDialog::Accepted) {
-        emit addMarker(m_clip->getId(), d.newMarker().time(), d.newMarker().comment());
+    QPointer<MarkerDialog> d = new MarkerDialog(m_clip, marker,
+                                          m_tc, i18n("Add Marker"), this);
+    if (d->exec() == QDialog::Accepted) {
+        emit addMarker(m_clip->getId(), d->newMarker().time(), d->newMarker().comment());
     }
-    QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
+    delete d;
+}
+
+void ClipProperties::slotSaveMarkers()
+{
+    emit saveMarkers(m_clip->getId());
+}
+
+void ClipProperties::slotLoadMarkers()
+{
+    emit loadMarkers(m_clip->getId());
 }
 
 void ClipProperties::slotEditMarker()
@@ -608,7 +755,6 @@ void ClipProperties::slotEditMarker()
     if (d.exec() == QDialog::Accepted) {
         emit addMarker(m_clip->getId(), d.newMarker().time(), d.newMarker().comment());
     }
-    QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
 }
 
 void ClipProperties::slotDeleteMarker()
@@ -617,8 +763,6 @@ void ClipProperties::slotDeleteMarker()
     int pos = m_view.markers_list->currentIndex().row();
     if (pos < 0 || pos > marks.count() - 1) return;
     emit addMarker(m_clip->getId(), marks.at(pos).time(), QString());
-
-    QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
 }
 
 const QString &ClipProperties::clipId() const
@@ -630,6 +774,7 @@ const QString &ClipProperties::clipId() const
 QMap <QString, QString> ClipProperties::properties()
 {
     QMap <QString, QString> props;
+    QLocale locale;
     CLIPTYPE t = UNKNOWN;
     if (m_clip != NULL) {
         t = m_clip->clipType();
@@ -647,11 +792,11 @@ QMap <QString, QString> ClipProperties::properties()
             m_clipNeedsRefresh = true;
         }
     } else {
-        if (m_old_props.contains("force_aspect_num")) {
+        if (m_old_props.contains("force_aspect_num") && !m_old_props.value("force_aspect_num").isEmpty()) {
             props["force_aspect_num"].clear();
             m_clipNeedsRefresh = true;
         }
-        if (m_old_props.contains("force_aspect_den")) {
+        if (m_old_props.contains("force_aspect_den") && !m_old_props.value("force_aspect_den").isEmpty()) {
             props["force_aspect_den"].clear();
             m_clipNeedsRefresh = true;
         }
@@ -660,10 +805,10 @@ QMap <QString, QString> ClipProperties::properties()
     double fps = m_view.clip_framerate->value();
     if (m_view.clip_force_framerate->isChecked()) {
         if (fps != m_old_props.value("force_fps").toDouble()) {
-            props["force_fps"] = QString::number(fps);
+            props["force_fps"] = locale.toString(fps);
             m_clipNeedsRefresh = true;
         }
-    } else if (m_old_props.contains("force_fps")) {
+    } else if (m_old_props.contains("force_fps") && !m_old_props.value("force_fps").isEmpty()) {
         props["force_fps"].clear();
         m_clipNeedsRefresh = true;
     }
@@ -673,16 +818,25 @@ QMap <QString, QString> ClipProperties::properties()
         if (progressive != m_old_props.value("force_progressive").toInt()) {
             props["force_progressive"] = QString::number(progressive);
         }
-    } else if (m_old_props.contains("force_progressive")) {
+    } else if (m_old_props.contains("force_progressive") && !m_old_props.value("force_progressive").isEmpty()) {
         props["force_progressive"].clear();
     }
 
+    int fieldOrder = m_view.clip_fieldorder->currentIndex();
+    if (m_view.clip_force_fieldorder->isChecked()) {
+        if (fieldOrder != m_old_props.value("force_tff").toInt()) {
+            props["force_tff"] = QString::number(fieldOrder);
+        }
+    } else if (m_old_props.contains("force_tff") && !m_old_props.value("force_tff").isEmpty()) {
+        props["force_tff"].clear();
+    }
+
     int threads = m_view.clip_threads->value();
     if (m_view.clip_force_threads->isChecked()) {
         if (threads != m_old_props.value("threads").toInt()) {
             props["threads"] = QString::number(threads);
         }
-    } else if (m_old_props.contains("threads")) {
+    } else if (m_old_props.contains("threads") && !m_old_props.value("threads").isEmpty()) {
         props["threads"].clear();
     }
 
@@ -691,7 +845,7 @@ QMap <QString, QString> ClipProperties::properties()
         if (vindex != m_old_props.value("video_index").toInt()) {
             props["video_index"] = QString::number(vindex);
         }
-    } else if (m_old_props.contains("video_index")) {
+    } else if (m_old_props.contains("video_index") && !m_old_props.value("video_index").isEmpty()) {
         props["video_index"].clear();
     }
 
@@ -700,7 +854,7 @@ QMap <QString, QString> ClipProperties::properties()
         if (aindex != m_old_props.value("audio_index").toInt()) {
             props["audio_index"] = QString::number(aindex);
         }
-    } else if (m_old_props.contains("audio_index")) {
+    } else if (m_old_props.contains("audio_index") && !m_old_props.value("audio_index").isEmpty()) {
         props["audio_index"].clear();
     }
     
@@ -710,7 +864,7 @@ QMap <QString, QString> ClipProperties::properties()
             props["force_colorspace"] = QString::number(colorspace);
             m_clipNeedsRefresh = true;
         }
-    } else if (m_old_props.contains("force_colorspace")) {
+    } else if (m_old_props.contains("force_colorspace") && !m_old_props.value("force_colorspace").isEmpty()) {
         props["force_colorspace"].clear();
         m_clipNeedsRefresh = true;
     }
@@ -718,10 +872,15 @@ QMap <QString, QString> ClipProperties::properties()
     if (m_view.clip_full_luma->isChecked()) {
         props["full_luma"] = QString::number(1);
         m_clipNeedsRefresh = true;
-    } else if (m_old_props.contains("full_luma")) {
+    } else if (m_old_props.contains("full_luma") && !m_old_props.value("full_luma").isEmpty()) {
         props["full_luma"].clear();
         m_clipNeedsRefresh = true;
     }
+    
+    if (m_view.clip_force_transparency->isChecked()) {
+        QString transp = QString::number(m_view.clip_transparency->currentIndex());
+        if (transp != m_old_props.value("transparency")) props["transparency"] = transp;
+    }
 
     // If we adjust several clips, return now
     if (m_clip == NULL) {
@@ -784,7 +943,7 @@ QMap <QString, QString> ClipProperties::properties()
         if (duration != m_old_props.value("ttl").toInt()) {
             m_clipNeedsRefresh = true;
             props["ttl"] = QString::number(duration);
-            props["out"] = QString::number(duration * m_count - 1);
+            props["length"] = QString::number(duration * m_count);
         }
 
         if (duration * m_count - 1 != m_old_props.value("out").toInt()) {
@@ -862,7 +1021,7 @@ void ClipProperties::parseFolder()
         QString filter = KUrl(m_view.clip_path->text()).fileName();
         QString ext = filter.section('.', -1);
         filter = filter.section('%', 0, -2);
-        QString regexp = "^" + filter + "\\d+\\." + ext + "$";
+        QString regexp = '^' + filter + "\\d+\\." + ext + '$';
         QRegExp rx(regexp);
         QStringList entries;
         foreach(const QString & path, result) {
@@ -924,6 +1083,20 @@ void ClipProperties::slotUpdateDurationFormat(int ix)
     }
 }
 
+void ClipProperties::slotDeleteProxy()
+{
+      QString proxy = m_clip->getProperty("proxy");
+      if (proxy.isEmpty()) return;
+      emit deleteProxy(proxy);
+      if (m_proxyContainer) delete m_proxyContainer;
+}
+
+void ClipProperties::slotOpenUrl(const QString &url)
+{
+    new KRun(KUrl(url), this);
+}
+
 #include "clipproperties.moc"
 
 
+