]> git.sesse.net Git - kdenlive/blob - src/clipproperties.cpp
423a2814828349da2a40954ca0fb907d62f3963a
[kdenlive] / src / clipproperties.cpp
1 /***************************************************************************
2  *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20
21 #include "clipproperties.h"
22 #include "kdenlivesettings.h"
23 #include "kthumb.h"
24 #include "markerdialog.h"
25
26 #include <KStandardDirs>
27 #include <KDebug>
28 #include <KFileItem>
29
30 #include <QDir>
31
32 static const int VIDEOTAB = 0;
33 static const int AUDIOTAB = 1;
34 static const int COLORTAB = 2;
35 static const int SLIDETAB = 3;
36 static const int IMAGETAB = 4;
37 static const int MARKERTAB = 5;
38 static const int METATAB = 6;
39 static const int ADVANCEDTAB = 7;
40
41 ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidget * parent) :
42         QDialog(parent),
43         m_clip(clip),
44         m_tc(tc),
45         m_fps(fps),
46         m_count(0),
47         m_clipNeedsRefresh(false),
48         m_clipNeedsReLoad(false)
49 {
50     setFont(KGlobalSettings::toolBarFont());
51     m_view.setupUi(this);
52     KUrl url = m_clip->fileURL();
53     m_view.clip_path->setText(url.path());
54     m_view.clip_description->setText(m_clip->description());
55     QMap <QString, QString> props = m_clip->properties();
56
57     if (props.contains("force_aspect_ratio") && props.value("force_aspect_ratio").toDouble() > 0) {
58         m_view.clip_force_ar->setChecked(true);
59         m_view.clip_ar->setEnabled(true);
60         m_view.clip_ar->setValue(props.value("force_aspect_ratio").toDouble());
61     }
62
63     if (props.contains("force_fps") && props.value("force_fps").toDouble() > 0) {
64         m_view.clip_force_framerate->setChecked(true);
65         m_view.clip_framerate->setEnabled(true);
66         m_view.clip_framerate->setValue(props.value("force_fps").toDouble());
67     }
68
69     if (props.contains("force_progressive")) {
70         m_view.clip_force_progressive->setChecked(true);
71         m_view.clip_progressive->setEnabled(true);
72         m_view.clip_progressive->setValue(props.value("force_progressive").toInt());
73     }
74
75     if (props.contains("threads") && props.value("threads").toInt() != 1) {
76         m_view.clip_force_threads->setChecked(true);
77         m_view.clip_threads->setEnabled(true);
78         m_view.clip_threads->setValue(props.value("threads").toInt());
79     }
80
81     if (props.contains("video_index") && props.value("video_index").toInt() != 0) {
82         m_view.clip_force_vindex->setChecked(true);
83         m_view.clip_vindex->setEnabled(true);
84         m_view.clip_vindex->setValue(props.value("video_index").toInt());
85     }
86
87     if (props.contains("audio_index") && props.value("audio_index").toInt() != 0) {
88         m_view.clip_force_aindex->setChecked(true);
89         m_view.clip_aindex->setEnabled(true);
90         m_view.clip_aindex->setValue(props.value("audio_index").toInt());
91     }
92
93     if (props.contains("audio_max")) {
94         m_view.clip_aindex->setMaximum(props.value("audio_max").toInt());
95     }
96
97     if (props.contains("video_max")) {
98         m_view.clip_vindex->setMaximum(props.value("video_max").toInt());
99     }
100
101     // Check for Metadata
102     QMap<QString, QString> meta = m_clip->metadata();
103     QMap<QString, QString>::const_iterator i = meta.constBegin();
104     while (i != meta.constEnd()) {
105         QTreeWidgetItem *metaitem = new QTreeWidgetItem(m_view.metadata_list);
106         metaitem->setText(0, i.key()); //i18n(i.key().section('.', 2, 3).toUtf8().data()));
107         metaitem->setText(1, i.value());
108         ++i;
109     }
110
111     connect(m_view.clip_force_ar, SIGNAL(toggled(bool)), m_view.clip_ar, SLOT(setEnabled(bool)));
112     connect(m_view.clip_force_framerate, SIGNAL(toggled(bool)), m_view.clip_framerate, SLOT(setEnabled(bool)));
113     connect(m_view.clip_force_progressive, SIGNAL(toggled(bool)), m_view.clip_progressive, SLOT(setEnabled(bool)));
114     connect(m_view.clip_force_threads, SIGNAL(toggled(bool)), m_view.clip_threads, SLOT(setEnabled(bool)));
115     connect(m_view.clip_force_vindex, SIGNAL(toggled(bool)), m_view.clip_vindex, SLOT(setEnabled(bool)));
116     connect(m_view.clip_force_aindex, SIGNAL(toggled(bool)), m_view.clip_aindex, SLOT(setEnabled(bool)));
117
118     if (props.contains("audiocodec"))
119         m_view.clip_acodec->setText(props.value("audiocodec"));
120     if (props.contains("frequency"))
121         m_view.clip_frequency->setText(props.value("frequency"));
122     if (props.contains("channels"))
123         m_view.clip_channels->setText(props.value("channels"));
124
125     CLIPTYPE t = m_clip->clipType();
126     if (t != AUDIO && t != AV) {
127         m_view.clip_force_aindex->setEnabled(false);
128     }
129
130     if (t != VIDEO && t != AV) {
131         m_view.clip_force_vindex->setEnabled(false);
132     }
133
134     if (t == IMAGE) {
135         m_view.tabWidget->removeTab(SLIDETAB);
136         m_view.tabWidget->removeTab(COLORTAB);
137         m_view.tabWidget->removeTab(AUDIOTAB);
138         m_view.tabWidget->removeTab(VIDEOTAB);
139         if (props.contains("frame_size"))
140             m_view.image_size->setText(props.value("frame_size"));
141         if (props.contains("transparency"))
142             m_view.image_transparency->setChecked(props.value("transparency").toInt());
143         int width = 180.0 * KdenliveSettings::project_display_ratio();
144         if (width % 2 == 1) width++;
145         m_view.clip_thumb->setPixmap(QPixmap(url.path()).scaled(QSize(width, 180), Qt::KeepAspectRatio));
146     } else if (t == COLOR) {
147         m_view.clip_path->setEnabled(false);
148         m_view.tabWidget->removeTab(METATAB);
149         m_view.tabWidget->removeTab(IMAGETAB);
150         m_view.tabWidget->removeTab(SLIDETAB);
151         m_view.tabWidget->removeTab(AUDIOTAB);
152         m_view.tabWidget->removeTab(VIDEOTAB);
153         m_view.clip_thumb->setHidden(true);
154         m_view.clip_color->setColor(QColor('#' + props.value("colour").right(8).left(6)));
155     } else if (t == SLIDESHOW) {
156         m_view.clip_path->setText(url.directory());
157         m_view.tabWidget->removeTab(METATAB);
158         m_view.tabWidget->removeTab(IMAGETAB);
159         m_view.tabWidget->removeTab(COLORTAB);
160         m_view.tabWidget->removeTab(AUDIOTAB);
161         m_view.tabWidget->removeTab(VIDEOTAB);
162
163         //WARNING: Keep in sync with slideshowclip.cpp
164         m_view.image_type->addItem("JPG (*.jpg)", "jpg");
165         m_view.image_type->addItem("JPEG (*.jpeg)", "jpeg");
166         m_view.image_type->addItem("PNG (*.png)", "png");
167         m_view.image_type->addItem("BMP (*.bmp)", "bmp");
168         m_view.image_type->addItem("GIF (*.gif)", "gif");
169         m_view.image_type->addItem("TGA (*.tga)", "tga");
170         m_view.image_type->addItem("TIFF (*.tiff)", "tiff");
171         m_view.image_type->addItem("Open EXR (*.exr)", "exr");
172
173         m_view.slide_loop->setChecked(props.value("loop").toInt());
174         m_view.slide_fade->setChecked(props.value("fade").toInt());
175         m_view.luma_softness->setValue(props.value("softness").toInt());
176         QString path = props.value("resource");
177         QString ext = path.section('.', -1);
178         for (int i = 0; i < m_view.image_type->count(); i++) {
179             if (m_view.image_type->itemData(i).toString() == ext) {
180                 m_view.image_type->setCurrentIndex(i);
181                 break;
182             }
183         }
184         m_view.slide_duration->setText(tc.getTimecodeFromFrames(props.value("ttl").toInt()));
185
186         m_view.slide_duration_format->addItem(i18n("hh:mm:ss::ff"));
187         m_view.slide_duration_format->addItem(i18n("Frames"));
188         connect(m_view.slide_duration_format, SIGNAL(activated(int)), this, SLOT(slotUpdateDurationFormat(int)));
189         m_view.slide_duration_frames->setHidden(true);
190         m_view.luma_duration_frames->setHidden(true);
191
192         parseFolder();
193
194         m_view.luma_duration->setText(tc.getTimecodeFromFrames(props.value("luma_duration").toInt()));
195         QString lumaFile = props.value("luma_file");
196
197         // Check for Kdenlive installed luma files
198         QStringList filters;
199         filters << "*.pgm" << "*.png";
200
201         QStringList customLumas = KGlobal::dirs()->findDirs("appdata", "lumas");
202         foreach(const QString &folder, customLumas) {
203             QStringList filesnames = QDir(folder).entryList(filters, QDir::Files);
204             foreach(const QString &fname, filesnames) {
205                 QString filePath = KUrl(folder).path(KUrl::AddTrailingSlash) + fname;
206                 m_view.luma_file->addItem(KIcon(filePath), fname, filePath);
207             }
208         }
209
210         // Check for MLT lumas
211         QString profilePath = KdenliveSettings::mltpath();
212         QString folder = profilePath.section('/', 0, -3);
213         folder.append("/lumas/PAL"); // TODO: cleanup the PAL / NTSC mess in luma files
214         QDir lumafolder(folder);
215         QStringList filesnames = lumafolder.entryList(filters, QDir::Files);
216         foreach(const QString &fname, filesnames) {
217             QString filePath = KUrl(folder).path(KUrl::AddTrailingSlash) + fname;
218             m_view.luma_file->addItem(KIcon(filePath), fname, filePath);
219         }
220
221         if (!lumaFile.isEmpty()) {
222             m_view.slide_luma->setChecked(true);
223             m_view.luma_file->setCurrentIndex(m_view.luma_file->findData(lumaFile));
224         } else m_view.luma_file->setEnabled(false);
225         slotEnableLuma(m_view.slide_fade->checkState());
226         slotEnableLumaFile(m_view.slide_luma->checkState());
227         connect(m_view.slide_fade, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLuma(int)));
228         connect(m_view.slide_luma, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLumaFile(int)));
229
230         connect(m_view.image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(parseFolder()));
231     } else if (t != AUDIO) {
232         m_view.tabWidget->removeTab(IMAGETAB);
233         m_view.tabWidget->removeTab(SLIDETAB);
234         m_view.tabWidget->removeTab(COLORTAB);
235         if (props.contains("frame_size"))
236             m_view.clip_size->setText(props.value("frame_size"));
237         if (props.contains("videocodec"))
238             m_view.clip_vcodec->setText(props.value("videocodec"));
239         if (props.contains("fps")) {
240             m_view.clip_fps->setText(props.value("fps"));
241             if (!m_view.clip_framerate->isEnabled()) m_view.clip_framerate->setValue(props.value("fps").toDouble());
242         }
243         if (props.contains("aspect_ratio"))
244             m_view.clip_ratio->setText(props.value("aspect_ratio"));
245         int width = 180.0 * KdenliveSettings::project_display_ratio();
246         if (width % 2 == 1) width++;
247         QPixmap pix = m_clip->thumbProducer()->getImage(url, m_clip->getClipThumbFrame(), width, 180);
248         m_view.clip_thumb->setPixmap(pix);
249         if (t == IMAGE || t == VIDEO) m_view.tabWidget->removeTab(AUDIOTAB);
250     } else {
251         m_view.tabWidget->removeTab(IMAGETAB);
252         m_view.tabWidget->removeTab(SLIDETAB);
253         m_view.tabWidget->removeTab(COLORTAB);
254         m_view.tabWidget->removeTab(VIDEOTAB);
255         m_view.clip_thumb->setHidden(true);
256     }
257
258     KFileItem f(KFileItem::Unknown, KFileItem::Unknown, url, true);
259     m_view.clip_filesize->setText(KIO::convertSize(f.size()));
260     m_view.clip_duration->setText(tc.getTimecode(m_clip->duration()));
261     if (t != IMAGE && t != COLOR && t != TEXT) m_view.clip_duration->setReadOnly(true);
262     else connect(m_view.clip_duration, SIGNAL(editingFinished()), this, SLOT(slotCheckMaxLength()));
263
264     // markers
265     m_view.marker_new->setIcon(KIcon("document-new"));
266     m_view.marker_new->setToolTip(i18n("Add marker"));
267     m_view.marker_edit->setIcon(KIcon("document-properties"));
268     m_view.marker_edit->setToolTip(i18n("Edit marker"));
269     m_view.marker_delete->setIcon(KIcon("trash-empty"));
270     m_view.marker_delete->setToolTip(i18n("Delete marker"));
271
272     slotFillMarkersList();
273     connect(m_view.marker_new, SIGNAL(clicked()), this, SLOT(slotAddMarker()));
274     connect(m_view.marker_edit, SIGNAL(clicked()), this, SLOT(slotEditMarker()));
275     connect(m_view.marker_delete, SIGNAL(clicked()), this, SLOT(slotDeleteMarker()));
276     connect(m_view.markers_list, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(slotEditMarker()));
277
278     //adjustSize();
279 }
280
281
282 // Used for multiple clips editing
283 ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, QMap <QString, QString> commonproperties, QWidget * parent) :
284         QDialog(parent),
285         m_clip(NULL),
286         m_fps(0),
287         m_count(0),
288         m_clipNeedsRefresh(false),
289         m_clipNeedsReLoad(false)
290 {
291     setFont(KGlobalSettings::toolBarFont());
292     m_view.setupUi(this);
293     QMap <QString, QString> props = cliplist.at(0)->properties();
294     m_old_props = commonproperties;
295
296     if (commonproperties.contains("force_aspect_ratio") && !commonproperties.value("force_aspect_ratio").isEmpty() && commonproperties.value("force_aspect_ratio").toDouble() > 0) {
297         m_view.clip_force_ar->setChecked(true);
298         m_view.clip_ar->setEnabled(true);
299         m_view.clip_ar->setValue(commonproperties.value("force_aspect_ratio").toDouble());
300     }
301
302     if (commonproperties.contains("force_fps") && !commonproperties.value("force_fps").isEmpty() && commonproperties.value("force_fps").toDouble() > 0) {
303         m_view.clip_force_framerate->setChecked(true);
304         m_view.clip_framerate->setEnabled(true);
305         m_view.clip_framerate->setValue(commonproperties.value("force_fps").toDouble());
306     }
307
308     if (commonproperties.contains("force_progressive") && !commonproperties.value("force_progressive").isEmpty()) {
309         m_view.clip_force_progressive->setChecked(true);
310         m_view.clip_progressive->setEnabled(true);
311         m_view.clip_progressive->setValue(commonproperties.value("force_progressive").toInt());
312     }
313
314     if (commonproperties.contains("threads") && !commonproperties.value("threads").isEmpty() && commonproperties.value("threads").toInt() != 1) {
315         m_view.clip_force_threads->setChecked(true);
316         m_view.clip_threads->setEnabled(true);
317         m_view.clip_threads->setValue(commonproperties.value("threads").toInt());
318     }
319
320     if (commonproperties.contains("video_index") && !commonproperties.value("video_index").isEmpty() && commonproperties.value("video_index").toInt() != 0) {
321         m_view.clip_force_vindex->setChecked(true);
322         m_view.clip_vindex->setEnabled(true);
323         m_view.clip_vindex->setValue(commonproperties.value("video_index").toInt());
324     }
325
326     if (commonproperties.contains("audio_index") && !commonproperties.value("audio_index").isEmpty() && commonproperties.value("audio_index").toInt() != 0) {
327         m_view.clip_force_aindex->setChecked(true);
328         m_view.clip_aindex->setEnabled(true);
329         m_view.clip_aindex->setValue(commonproperties.value("audio_index").toInt());
330     }
331
332     if (props.contains("audio_max")) {
333         m_view.clip_aindex->setMaximum(props.value("audio_max").toInt());
334     }
335
336     if (props.contains("video_max")) {
337         m_view.clip_vindex->setMaximum(props.value("video_max").toInt());
338     }
339
340     connect(m_view.clip_force_ar, SIGNAL(toggled(bool)), m_view.clip_ar, SLOT(setEnabled(bool)));
341     connect(m_view.clip_force_progressive, SIGNAL(toggled(bool)), m_view.clip_progressive, SLOT(setEnabled(bool)));
342     connect(m_view.clip_force_threads, SIGNAL(toggled(bool)), m_view.clip_threads, SLOT(setEnabled(bool)));
343     connect(m_view.clip_force_vindex, SIGNAL(toggled(bool)), m_view.clip_vindex, SLOT(setEnabled(bool)));
344     connect(m_view.clip_force_aindex, SIGNAL(toggled(bool)), m_view.clip_aindex, SLOT(setEnabled(bool)));
345
346     m_view.tabWidget->removeTab(METATAB);
347     m_view.tabWidget->removeTab(MARKERTAB);
348     m_view.tabWidget->removeTab(IMAGETAB);
349     m_view.tabWidget->removeTab(SLIDETAB);
350     m_view.tabWidget->removeTab(COLORTAB);
351     m_view.tabWidget->removeTab(AUDIOTAB);
352     m_view.tabWidget->removeTab(VIDEOTAB);
353
354     m_view.clip_path->setHidden(true);
355     m_view.label_path->setHidden(true);
356     m_view.label_description->setHidden(true);
357     m_view.label_duration->setHidden(true);
358     m_view.label_size->setHidden(true);
359     m_view.clip_filesize->setHidden(true);
360     m_view.clip_filesize->setHidden(true);
361     m_view.clip_duration->setHidden(true);
362     m_view.clip_path->setHidden(true);
363     m_view.clip_description->setHidden(true);
364 }
365
366
367
368 void ClipProperties::slotEnableLuma(int state)
369 {
370     bool enable = false;
371     if (state == Qt::Checked) enable = true;
372     m_view.luma_duration->setEnabled(enable);
373     m_view.luma_duration_frames->setEnabled(enable);
374     m_view.slide_luma->setEnabled(enable);
375     if (enable) {
376         m_view.luma_file->setEnabled(m_view.slide_luma->isChecked());
377     } else m_view.luma_file->setEnabled(false);
378     m_view.label_softness->setEnabled(m_view.slide_luma->isChecked() && enable);
379     m_view.luma_softness->setEnabled(m_view.label_softness->isEnabled());
380 }
381
382 void ClipProperties::slotEnableLumaFile(int state)
383 {
384     bool enable = false;
385     if (state == Qt::Checked) enable = true;
386     m_view.luma_file->setEnabled(enable);
387     m_view.luma_softness->setEnabled(enable);
388     m_view.label_softness->setEnabled(enable);
389 }
390
391 void ClipProperties::slotFillMarkersList()
392 {
393     m_view.markers_list->clear();
394     QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
395     for (int count = 0; count < marks.count(); ++count) {
396         QString time = m_tc.getTimecode(marks[count].time());
397         QStringList itemtext;
398         itemtext << time << marks[count].comment();
399         (void) new QTreeWidgetItem(m_view.markers_list, itemtext);
400     }
401 }
402
403 void ClipProperties::slotAddMarker()
404 {
405     CommentedTime marker(GenTime(), i18n("Marker"));
406     MarkerDialog d(m_clip, marker, m_tc, i18n("Add Marker"), this);
407     if (d.exec() == QDialog::Accepted) {
408         emit addMarker(m_clip->getId(), d.newMarker().time(), d.newMarker().comment());
409     }
410     QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
411 }
412
413 void ClipProperties::slotEditMarker()
414 {
415     QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
416     int pos = m_view.markers_list->currentIndex().row();
417     if (pos < 0 || pos > marks.count() - 1) return;
418     MarkerDialog d(m_clip, marks.at(pos), m_tc, i18n("Edit Marker"), this);
419     if (d.exec() == QDialog::Accepted) {
420         emit addMarker(m_clip->getId(), d.newMarker().time(), d.newMarker().comment());
421     }
422     QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
423 }
424
425 void ClipProperties::slotDeleteMarker()
426 {
427     QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
428     int pos = m_view.markers_list->currentIndex().row();
429     if (pos < 0 || pos > marks.count() - 1) return;
430     emit addMarker(m_clip->getId(), marks.at(pos).time(), QString());
431
432     QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
433 }
434
435 const QString &ClipProperties::clipId() const
436 {
437     return m_clip->getId();
438 }
439
440
441 QMap <QString, QString> ClipProperties::properties()
442 {
443     QMap <QString, QString> props;
444     CLIPTYPE t;
445     if (m_clip != NULL) {
446         t = m_clip->clipType();
447         m_old_props = m_clip->properties();
448     }
449
450     double aspect = m_view.clip_ar->value();
451     if (m_view.clip_force_ar->isChecked()) {
452         if (aspect != m_old_props.value("force_aspect_ratio").toDouble()) {
453             props["force_aspect_ratio"] = QString::number(aspect);
454             m_clipNeedsRefresh = true;
455         }
456     } else if (m_old_props.contains("force_aspect_ratio")) {
457         props["force_aspect_ratio"].clear();
458         m_clipNeedsRefresh = true;
459     }
460
461     double fps = m_view.clip_framerate->value();
462     if (m_view.clip_force_framerate->isChecked()) {
463         if (fps != m_old_props.value("force_fps").toDouble()) {
464             props["force_fps"] = QString::number(fps);
465             m_clipNeedsRefresh = true;
466         }
467     } else if (m_old_props.contains("force_fps")) {
468         props["force_fps"].clear();
469         m_clipNeedsRefresh = true;
470     }
471
472     int progressive = m_view.clip_progressive->value();
473     if (m_view.clip_force_progressive->isChecked()) {
474         if (progressive != m_old_props.value("force_progressive").toInt()) {
475             props["force_progressive"] = QString::number(progressive);
476         }
477     } else if (m_old_props.contains("force_progressive")) {
478         props["force_progressive"].clear();
479     }
480
481     int threads = m_view.clip_threads->value();
482     if (m_view.clip_force_threads->isChecked()) {
483         if (threads != m_old_props.value("threads").toInt()) {
484             props["threads"] = QString::number(threads);
485         }
486     } else if (m_old_props.contains("threads")) {
487         props["threads"].clear();
488     }
489
490     int vindex = m_view.clip_vindex->value();
491     if (m_view.clip_force_vindex->isChecked()) {
492         if (vindex != m_old_props.value("video_index").toInt()) {
493             props["video_index"] = QString::number(vindex);
494         }
495     } else if (m_old_props.contains("video_index")) {
496         props["video_index"].clear();
497     }
498
499     int aindex = m_view.clip_aindex->value();
500     if (m_view.clip_force_aindex->isChecked()) {
501         if (aindex != m_old_props.value("audio_index").toInt()) {
502             props["audio_index"] = QString::number(aindex);
503         }
504     } else if (m_old_props.contains("audio_index")) {
505         props["audio_index"].clear();
506     }
507
508     // If we adjust several clips, return now
509     if (m_clip == NULL) return props;
510
511     if (m_old_props.value("description") != m_view.clip_description->text())
512         props["description"] = m_view.clip_description->text();
513
514     if (t == COLOR) {
515         QString new_color = m_view.clip_color->color().name();
516         if (new_color != QString('#' + m_old_props.value("colour").right(8).left(6))) {
517             m_clipNeedsRefresh = true;
518             props["colour"] = "0x" + new_color.right(6) + "ff";
519         }
520         int duration = m_tc.getFrameCount(m_view.clip_duration->text());
521         if (duration != m_clip->duration().frames(m_fps)) {
522             props["out"] = QString::number(duration);
523         }
524     } else if (t == IMAGE) {
525         if ((int) m_view.image_transparency->isChecked() != m_old_props.value("transparency").toInt()) {
526             props["transparency"] = QString::number((int)m_view.image_transparency->isChecked());
527             //m_clipNeedsRefresh = true;
528         }
529         int duration = m_tc.getFrameCount(m_view.clip_duration->text());
530         if (duration != m_clip->duration().frames(m_fps)) {
531             props["out"] = QString::number(duration);
532         }
533     } else if (t == SLIDESHOW) {
534         QString value = QString::number((int) m_view.slide_loop->isChecked());
535         if (m_old_props.value("loop") != value) props["loop"] = value;
536         value = QString::number((int) m_view.slide_fade->isChecked());
537         if (m_old_props.value("fade") != value) props["fade"] = value;
538         value = QString::number((int) m_view.luma_softness->value());
539         if (m_old_props.value("softness") != value) props["softness"] = value;
540
541         QString extension = "/.all." + m_view.image_type->itemData(m_view.image_type->currentIndex()).toString();
542         QString new_path = m_view.clip_path->text() + extension;
543         if (new_path != m_old_props.value("resource")) {
544             m_clipNeedsReLoad = true;
545             props["resource"] = new_path;
546             kDebug() << "////  SLIDE EDIT, NEW:" << new_path << ", OLD; " << m_old_props.value("resource");
547         }
548         int duration;
549         if (m_view.slide_duration_format->currentIndex() == 1) {
550             // we are in frames mode
551             duration = m_view.slide_duration_frames->value();
552         } else duration = m_tc.getFrameCount(m_view.slide_duration->text());
553         if (duration != m_old_props.value("ttl").toInt()) {
554             m_clipNeedsRefresh = true;
555             props["ttl"] = QString::number(duration);
556             props["out"] = QString::number(duration * m_count);
557         }
558         if (duration * m_count != m_old_props.value("out").toInt()) {
559             m_clipNeedsRefresh = true;
560             props["out"] = QString::number(duration * m_count);
561         }
562         if (m_view.slide_fade->isChecked()) {
563             int luma_duration;
564             if (m_view.slide_duration_format->currentIndex() == 1) {
565                 // we are in frames mode
566                 luma_duration = m_view.luma_duration_frames->value();
567             } else luma_duration = m_tc.getFrameCount(m_view.luma_duration->text());
568             if (luma_duration != m_old_props.value("luma_duration").toInt()) {
569                 m_clipNeedsRefresh = true;
570                 props["luma_duration"] = QString::number(luma_duration);
571             }
572             QString lumaFile;
573             if (m_view.slide_luma->isChecked())
574                 lumaFile = m_view.luma_file->itemData(m_view.luma_file->currentIndex()).toString();
575             if (lumaFile != m_old_props.value("luma_file")) {
576                 m_clipNeedsRefresh = true;
577                 props["luma_file"] = lumaFile;
578             }
579         } else {
580             if (!m_old_props.value("luma_file").isEmpty()) {
581                 props["luma_file"].clear();
582             }
583         }
584
585     }
586     return props;
587 }
588
589 bool ClipProperties::needsTimelineRefresh() const
590 {
591     return m_clipNeedsRefresh;
592 }
593
594 bool ClipProperties::needsTimelineReload() const
595 {
596     return m_clipNeedsReLoad;
597 }
598
599 void ClipProperties::parseFolder()
600 {
601
602     QDir dir(m_view.clip_path->text());
603     QStringList filters;
604     filters << "*." + m_view.image_type->itemData(m_view.image_type->currentIndex()).toString();
605     QString extension = "/.all." + m_view.image_type->itemData(m_view.image_type->currentIndex()).toString();
606
607     dir.setNameFilters(filters);
608     QStringList result = dir.entryList(QDir::Files);
609     m_count = result.count();
610     if (m_count == 0) {
611         // no images, do not accept that
612         m_view.slide_info->setText(i18n("No image found"));
613         m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
614         return;
615     }
616     m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
617     m_view.slide_info->setText(i18np("1 image found", "%1 images found", m_count));
618     QDomElement xml = m_clip->toXML();
619     xml.setAttribute("resource", m_view.clip_path->text() + extension);
620     int width = 180.0 * KdenliveSettings::project_display_ratio();
621     if (width % 2 == 1) width++;
622     QPixmap pix = m_clip->thumbProducer()->getImage(KUrl(m_view.clip_path->text() + extension), 1, width, 180);
623     QMap <QString, QString> props = m_clip->properties();
624     m_view.clip_duration->setText(m_tc.getTimecodeFromFrames(props.value("ttl").toInt() * m_count));
625     m_view.clip_thumb->setPixmap(pix);
626 }
627
628 void ClipProperties::slotCheckMaxLength()
629 {
630     if (m_clip->maxDuration() == GenTime()) return;
631     int duration = m_tc.getFrameCount(m_view.clip_duration->text());
632     if (duration > m_clip->maxDuration().frames(m_fps)) {
633         m_view.clip_duration->setText(m_tc.getTimecode(m_clip->maxDuration()));
634     }
635 }
636
637 void ClipProperties::slotUpdateDurationFormat(int ix)
638 {
639     bool framesFormat = ix == 1;
640     if (framesFormat) {
641         // switching to frames count, update widget
642         m_view.slide_duration_frames->setValue(m_tc.getFrameCount(m_view.slide_duration->text()));
643         m_view.luma_duration_frames->setValue(m_tc.getFrameCount(m_view.luma_duration->text()));
644         m_view.slide_duration->setHidden(true);
645         m_view.luma_duration->setHidden(true);
646         m_view.slide_duration_frames->setHidden(false);
647         m_view.luma_duration_frames->setHidden(false);
648     } else {
649         // switching to timecode format
650         m_view.slide_duration->setText(m_tc.getTimecodeFromFrames(m_view.slide_duration_frames->value()));
651         m_view.luma_duration->setText(m_tc.getTimecodeFromFrames(m_view.luma_duration_frames->value()));
652         m_view.slide_duration_frames->setHidden(true);
653         m_view.luma_duration_frames->setHidden(true);
654         m_view.slide_duration->setHidden(false);
655         m_view.luma_duration->setHidden(false);
656     }
657 }
658
659 #include "clipproperties.moc"
660
661