]> git.sesse.net Git - kdenlive/blobdiff - src/clipproperties.cpp
Allow to display several clip properties, force clip properties can be applied withou...
[kdenlive] / src / clipproperties.cpp
index 0388a3b91dca93c367a16c8bd565800231aa4cfb..f2e07813d53b84bf7a6615b2d6d004ef81fb8db0 100644 (file)
@@ -22,6 +22,7 @@
 #include "kdenlivesettings.h"
 #include "kthumb.h"
 #include "markerdialog.h"
+#include "profilesdialog.h"
 
 #include <KStandardDirs>
 #include <KDebug>
@@ -38,22 +39,26 @@ static const int MARKERTAB = 5;
 static const int METATAB = 6;
 static const int ADVANCEDTAB = 7;
 
+
 ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidget * parent) :
-        QDialog(parent),
-        m_clip(clip),
-        m_tc(tc),
-        m_fps(fps),
-        m_count(0),
-        m_clipNeedsRefresh(false),
-        m_clipNeedsReLoad(false)
+    QDialog(parent),
+    m_clip(clip),
+    m_tc(tc),
+    m_fps(fps),
+    m_count(0),
+    m_clipNeedsRefresh(false),
+    m_clipNeedsReLoad(false),
+    m_propsDelegate(NULL)
 {
+    setAttribute(Qt::WA_DeleteOnClose, true);
     setFont(KGlobalSettings::toolBarFont());
     m_view.setupUi(this);
     KUrl url = m_clip->fileURL();
     m_view.clip_path->setText(url.path());
     m_view.clip_description->setText(m_clip->description());
-    QMap <QString, QString> props = m_clip->properties();
+    connect(m_view.clip_description, SIGNAL(textChanged(QString)), this, SLOT(slotModified()));
 
+    QMap <QString, QString> props = m_clip->properties();
     m_view.clip_force_out->setHidden(true);
     m_view.clip_out->setHidden(true);
 
@@ -61,37 +66,49 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         m_view.clip_force_ar->setChecked(true);
         m_view.clip_ar->setEnabled(true);
         m_view.clip_ar->setValue(props.value("force_aspect_ratio").toDouble());
-    }
+    } else if (props.contains("aspect_ratio")) m_view.clip_ar->setValue(props.value("aspect_ratio").toDouble());
+    connect(m_view.clip_force_ar, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+    connect(m_view.clip_ar, SIGNAL(valueChanged(double)), this, SLOT(slotModified()));
 
     if (props.contains("force_fps") && props.value("force_fps").toDouble() > 0) {
         m_view.clip_force_framerate->setChecked(true);
         m_view.clip_framerate->setEnabled(true);
         m_view.clip_framerate->setValue(props.value("force_fps").toDouble());
     }
+    connect(m_view.clip_force_framerate, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+    connect(m_view.clip_framerate, SIGNAL(valueChanged(double)), this, SLOT(slotModified()));
 
     if (props.contains("force_progressive")) {
         m_view.clip_force_progressive->setChecked(true);
         m_view.clip_progressive->setEnabled(true);
         m_view.clip_progressive->setValue(props.value("force_progressive").toInt());
     }
+    connect(m_view.clip_force_progressive, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+    connect(m_view.clip_progressive, SIGNAL(valueChanged(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);
         m_view.clip_threads->setValue(props.value("threads").toInt());
     }
+    connect(m_view.clip_force_threads, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+    connect(m_view.clip_threads, SIGNAL(valueChanged(int)), this, SLOT(slotModified()));
 
     if (props.contains("video_index") && props.value("video_index").toInt() != 0) {
         m_view.clip_force_vindex->setChecked(true);
         m_view.clip_vindex->setEnabled(true);
         m_view.clip_vindex->setValue(props.value("video_index").toInt());
     }
+    connect(m_view.clip_force_vindex, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+    connect(m_view.clip_vindex, SIGNAL(valueChanged(int)), this, SLOT(slotModified()));
 
     if (props.contains("audio_index") && props.value("audio_index").toInt() != 0) {
         m_view.clip_force_aindex->setChecked(true);
         m_view.clip_aindex->setEnabled(true);
         m_view.clip_aindex->setValue(props.value("audio_index").toInt());
     }
+    connect(m_view.clip_force_aindex, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+    connect(m_view.clip_aindex, SIGNAL(valueChanged(int)), this, SLOT(slotModified()));
 
     if (props.contains("audio_max")) {
         m_view.clip_aindex->setMaximum(props.value("audio_max").toInt());
@@ -119,11 +136,13 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
     connect(m_view.clip_force_aindex, SIGNAL(toggled(bool)), m_view.clip_aindex, SLOT(setEnabled(bool)));
 
     if (props.contains("audiocodec"))
-        m_view.clip_acodec->setText(props.value("audiocodec"));
-    if (props.contains("frequency"))
-        m_view.clip_frequency->setText(props.value("frequency"));
+        QTreeWidgetItem *item = new QTreeWidgetItem(m_view.clip_aproperties, QStringList() << i18n("Audio codec") << props.value("audiocodec"));
+
     if (props.contains("channels"))
-        m_view.clip_channels->setText(props.value("channels"));
+        QTreeWidgetItem *item = 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"));
 
     CLIPTYPE t = m_clip->clipType();
     if (t != AUDIO && t != AV) {
@@ -143,6 +162,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
             m_view.image_size->setText(props.value("frame_size"));
         if (props.contains("transparency"))
             m_view.image_transparency->setChecked(props.value("transparency").toInt());
+        connect(m_view.image_transparency, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
         int width = 180.0 * KdenliveSettings::project_display_ratio();
         if (width % 2 == 1) width++;
         m_view.clip_thumb->setPixmap(QPixmap(url.path()).scaled(QSize(width, 180), Qt::KeepAspectRatio));
@@ -155,6 +175,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         m_view.tabWidget->removeTab(VIDEOTAB);
         m_view.clip_thumb->setHidden(true);
         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.")) {
@@ -225,9 +246,9 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         filters << "*.pgm" << "*.png";
 
         QStringList customLumas = KGlobal::dirs()->findDirs("appdata", "lumas");
-        foreach(const QString &folder, customLumas) {
+        foreach(const QString & folder, customLumas) {
             QStringList filesnames = QDir(folder).entryList(filters, QDir::Files);
-            foreach(const QString &fname, filesnames) {
+            foreach(const QString & fname, filesnames) {
                 QString filePath = KUrl(folder).path(KUrl::AddTrailingSlash) + fname;
                 m_view.luma_file->addItem(KIcon(filePath), fname, filePath);
             }
@@ -239,7 +260,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         folder.append("/lumas/PAL"); // TODO: cleanup the PAL / NTSC mess in luma files
         QDir lumafolder(folder);
         QStringList filesnames = lumafolder.entryList(filters, QDir::Files);
-        foreach(const QString &fname, filesnames) {
+        foreach(const QString & fname, filesnames) {
             QString filePath = KUrl(folder).path(KUrl::AddTrailingSlash) + fname;
             m_view.luma_file->addItem(KIcon(filePath), fname, filePath);
         }
@@ -250,24 +271,55 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         } else m_view.luma_file->setEnabled(false);
         slotEnableLuma(m_view.slide_fade->checkState());
         slotEnableLumaFile(m_view.slide_luma->checkState());
+
+        connect(m_view.slide_fade, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+        connect(m_view.slide_luma, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+        connect(m_view.slide_loop, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+        connect(m_view.slide_crop, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
+        connect(m_view.slide_duration, SIGNAL(textChanged(QString)), this, SLOT(slotModified()));
+        connect(m_view.slide_duration_frames, SIGNAL(valueChanged(int)), this, SLOT(slotModified()));
+        connect(m_view.luma_duration, SIGNAL(textChanged(QString)), this, SLOT(slotModified()));
+        connect(m_view.luma_softness, SIGNAL(valueChanged(int)), this, SLOT(slotModified()));
+        connect(m_view.luma_file, SIGNAL(currentIndexChanged(int)), this, SLOT(slotModified()));
+        connect(m_view.animation, SIGNAL(currentIndexChanged(int)), this, SLOT(slotModified()));
+
+
         connect(m_view.slide_fade, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLuma(int)));
         connect(m_view.slide_luma, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLumaFile(int)));
-
         connect(m_view.image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(parseFolder()));
+
     } else if (t != AUDIO) {
         m_view.tabWidget->removeTab(IMAGETAB);
         m_view.tabWidget->removeTab(SLIDETAB);
         m_view.tabWidget->removeTab(COLORTAB);
-        if (props.contains("frame_size"))
-            m_view.clip_size->setText(props.value("frame_size"));
+
+
+
+        m_propsDelegate = new PropertiesViewDelegate(this);
+        m_view.clip_vproperties->setItemDelegate(m_propsDelegate);
+        m_view.clip_aproperties->setItemDelegate(m_propsDelegate);
+        m_view.clip_aproperties->setStyleSheet(QString("QTreeWidget { background-color: transparent;}"));
+        m_view.clip_vproperties->setStyleSheet(QString("QTreeWidget { background-color: transparent;}"));
+
         if (props.contains("videocodec"))
-            m_view.clip_vcodec->setText(props.value("videocodec"));
+            QTreeWidgetItem *item = 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"));
+
         if (props.contains("fps")) {
-            m_view.clip_fps->setText(props.value("fps"));
+            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("aspect_ratio"))
-            m_view.clip_ratio->setText(props.value("aspect_ratio"));
+            new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Pixel aspect ratio") << props.value("aspect_ratio"));
+
+        if (props.contains("pix_fmt"))
+            new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Pixel format") << props.value("pix_fmt"));
+
+        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);
@@ -308,19 +360,22 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
     connect(m_view.marker_delete, SIGNAL(clicked()), this, SLOT(slotDeleteMarker()));
     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();
 }
 
 
 // Used for multiple clips editing
 ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap <QString, QString> commonproperties, QWidget * parent) :
-        QDialog(parent),
-        m_clip(NULL),
-        m_tc(tc),
-        m_fps(0),
-        m_count(0),
-        m_clipNeedsRefresh(false),
-        m_clipNeedsReLoad(false)
+    QDialog(parent),
+    m_clip(NULL),
+    m_tc(tc),
+    m_fps(0),
+    m_count(0),
+    m_clipNeedsRefresh(false),
+    m_clipNeedsReLoad(false)
 {
     setFont(KGlobalSettings::toolBarFont());
     m_view.setupUi(this);
@@ -409,6 +464,32 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
     }
 }
 
+ClipProperties::~ClipProperties()
+{
+    if (m_propsDelegate) delete m_propsDelegate;
+}
+
+void ClipProperties::slotApplyProperties()
+{
+    if (m_clip != NULL)
+        emit applyNewClipProperties(m_clip->getId(), m_clip->properties(), properties(), needsTimelineRefresh(), needsTimelineReload());
+    m_view.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
+}
+
+void ClipProperties::disableClipId(const QString &id)
+{
+    if (m_clip && m_view.buttonBox->button(QDialogButtonBox::Ok)->isEnabled()) {
+        if (m_clip->getId() == id) {
+            // clip was removed from project, close this properties dialog
+            close();
+        }
+    }
+}
+
+void ClipProperties::slotModified()
+{
+    m_view.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
+}
 
 
 void ClipProperties::slotEnableLuma(int state)
@@ -593,17 +674,17 @@ QMap <QString, QString> ClipProperties::properties()
         if (m_old_props.value("fade") != value) props["fade"] = value;
         value = QString::number((int) m_view.luma_softness->value());
         if (m_old_props.value("softness") != value) props["softness"] = value;
-       
-       bool isMime = !(m_view.clip_path->text().contains('%'));
-       if (isMime) {
-           QString extension = "/.all." + m_view.image_type->itemData(m_view.image_type->currentIndex()).toString();
-           QString new_path = m_view.clip_path->text() + extension;
-           if (new_path != m_old_props.value("resource")) {
-               m_clipNeedsReLoad = true;
-               props["resource"] = new_path;
-               kDebug() << "////  SLIDE EDIT, NEW:" << new_path << ", OLD; " << m_old_props.value("resource");
-           }
-       }
+
+        bool isMime = !(m_view.clip_path->text().contains('%'));
+        if (isMime) {
+            QString extension = "/.all." + m_view.image_type->itemData(m_view.image_type->currentIndex()).toString();
+            QString new_path = m_view.clip_path->text() + extension;
+            if (new_path != m_old_props.value("resource")) {
+                m_clipNeedsReLoad = true;
+                props["resource"] = new_path;
+                kDebug() << "////  SLIDE EDIT, NEW:" << new_path << ", OLD; " << m_old_props.value("resource");
+            }
+        }
         int duration;
         if (m_view.slide_duration_format->currentIndex() == 1) {
             // we are in frames mode
@@ -693,13 +774,14 @@ void ClipProperties::parseFolder()
         QString regexp = "^" + filter + "\\d+\\." + ext + "$";
         QRegExp rx(regexp);
         QStringList entries;
-        foreach(const QString &path, result) {
+        foreach(const QString & path, result) {
             if (rx.exactMatch(path)) entries << path;
         }
         result = entries;
     }
 
     m_count = result.count();
+    m_view.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(m_count > 0);
     if (m_count == 0) {
         // no images, do not accept that
         m_view.slide_info->setText(i18n("No image found"));