]> git.sesse.net Git - kdenlive/blob - src/clipproperties.cpp
slideshow update
[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 #include <QDir>
21
22 #include <KStandardDirs>
23 #include <KDebug>
24 #include <KFileItem>
25
26 #include "kdenlivesettings.h"
27 #include "clipproperties.h"
28 #include "kthumb.h"
29 #include "markerdialog.h"
30
31 #define VIDEOTAB 0
32 #define AUDIOTAB 1
33 #define COLORTAB 2
34 #define SLIDETAB 3
35 #define ADVANCEDTAB 4
36
37 #define TYPE_JPEG 0
38 #define TYPE_PNG 1
39 #define TYPE_BMP 2
40 #define TYPE_GIF 3
41
42 ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidget * parent): QDialog(parent), m_tc(tc), m_clip(clip), m_fps(fps), m_clipNeedsRefresh(false), m_count(0) {
43     setFont(KGlobalSettings::toolBarFont());
44     m_view.setupUi(this);
45     KUrl url = m_clip->fileURL();
46     m_view.clip_path->setText(url.path());
47     m_view.clip_description->setText(m_clip->description());
48     QMap <QString, QString> props = m_clip->properties();
49
50     if (props.contains("audiocodec"))
51         m_view.clip_acodec->setText(props.value("audiocodec"));
52     if (props.contains("frequency"))
53         m_view.clip_frequency->setText(props.value("frequency"));
54     if (props.contains("channels"))
55         m_view.clip_channels->setText(props.value("channels"));
56
57     CLIPTYPE t = m_clip->clipType();
58     if (t == COLOR) {
59         m_view.clip_path->setEnabled(false);
60         m_view.tabWidget->removeTab(SLIDETAB);
61         m_view.tabWidget->removeTab(AUDIOTAB);
62         m_view.tabWidget->removeTab(VIDEOTAB);
63         m_view.clip_thumb->setHidden(true);
64         m_view.clip_color->setColor(QColor("#" + props.value("colour").right(8).left(6)));
65     } else if (t == SLIDESHOW) {
66         m_view.clip_path->setText(url.directory());
67         m_view.tabWidget->removeTab(COLORTAB);
68         m_view.tabWidget->removeTab(AUDIOTAB);
69         m_view.tabWidget->removeTab(VIDEOTAB);
70         QStringList types;
71         types << "JPG" << "PNG" << "BMP" << "GIF";
72         m_view.image_type->addItems(types);
73         m_view.slide_loop->setChecked(props.value("loop").toInt());
74         m_view.slide_fade->setChecked(props.value("fade").toInt());
75         m_view.luma_softness->setValue(props.value("softness").toInt());
76         QString path = props.value("resource");
77         if (path.endsWith("png")) m_view.image_type->setCurrentIndex(TYPE_PNG);
78         else if (path.endsWith("bmp")) m_view.image_type->setCurrentIndex(TYPE_BMP);
79         else if (path.endsWith("gif")) m_view.image_type->setCurrentIndex(TYPE_GIF);
80         m_view.slide_duration->setText(tc.getTimecodeFromFrames(props.value("ttl").toInt()));
81         parseFolder();
82
83         m_view.luma_duration->setText(tc.getTimecodeFromFrames(props.value("luma_duration").toInt()));
84         QString lumaFile = props.value("luma_file");
85         QString profilePath = KdenliveSettings::mltpath();
86         profilePath = profilePath.section('/', 0, -3);
87         profilePath += "/lumas/PAL/";
88
89         QDir dir(profilePath);
90         QStringList result = dir.entryList(QDir::Files);
91         QStringList imagefiles;
92         QStringList imagenamelist;
93         int current;
94         foreach(QString file, result) {
95             if (file.endsWith(".pgm")) {
96                 m_view.luma_file->addItem(KIcon(profilePath + file), file, profilePath + file);
97                 if (!lumaFile.isEmpty() && lumaFile == QString(profilePath + file))
98                     current = m_view.luma_file->count() - 1;
99             }
100         }
101
102         if (!lumaFile.isEmpty()) {
103             m_view.slide_luma->setChecked(true);
104             m_view.luma_file->setCurrentIndex(current);
105         }
106
107         connect(m_view.image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(parseFolder()));
108     } else if (t != AUDIO) {
109         m_view.tabWidget->removeTab(SLIDETAB);
110         m_view.tabWidget->removeTab(COLORTAB);
111         if (props.contains("frame_size"))
112             m_view.clip_size->setText(props.value("frame_size"));
113         if (props.contains("videocodec"))
114             m_view.clip_vcodec->setText(props.value("videocodec"));
115         if (props.contains("fps"))
116             m_view.clip_fps->setText(props.value("fps"));
117         if (props.contains("aspect_ratio"))
118             m_view.clip_ratio->setText(props.value("aspect_ratio"));
119
120         QPixmap pix = m_clip->thumbProducer()->getImage(url, m_clip->getClipThumbFrame(), 240, 180);
121         m_view.clip_thumb->setPixmap(pix);
122         if (t == IMAGE || t == VIDEO) m_view.tabWidget->removeTab(AUDIOTAB);
123     } else {
124         m_view.tabWidget->removeTab(SLIDETAB);
125         m_view.tabWidget->removeTab(COLORTAB);
126         m_view.tabWidget->removeTab(VIDEOTAB);
127         m_view.clip_thumb->setHidden(true);
128     }
129     if (t != IMAGE && t != COLOR && t != TEXT) m_view.clip_duration->setReadOnly(true);
130
131     KFileItem f(KFileItem::Unknown, KFileItem::Unknown, url, true);
132     m_view.clip_filesize->setText(KIO::convertSize(f.size()));
133     m_view.clip_duration->setText(tc.getTimecode(m_clip->duration(), m_fps));
134
135     // markers
136     m_view.marker_new->setIcon(KIcon("document-new"));
137     m_view.marker_new->setToolTip(i18n("Add marker"));
138     m_view.marker_edit->setIcon(KIcon("document-properties"));
139     m_view.marker_edit->setToolTip(i18n("Edit marker"));
140     m_view.marker_delete->setIcon(KIcon("trash-empty"));
141     m_view.marker_delete->setToolTip(i18n("Delete marker"));
142
143     slotFillMarkersList();
144     connect(m_view.marker_new, SIGNAL(clicked()), this, SLOT(slotAddMarker()));
145     connect(m_view.marker_edit, SIGNAL(clicked()), this, SLOT(slotEditMarker()));
146     connect(m_view.marker_delete, SIGNAL(clicked()), this, SLOT(slotDeleteMarker()));
147     connect(m_view.markers_list, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(slotEditMarker()));
148
149     adjustSize();
150 }
151
152 void ClipProperties::slotFillMarkersList() {
153     m_view.markers_list->clear();
154     QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
155     for (uint count = 0; count < marks.count(); ++count) {
156         QString time = m_tc.getTimecode(marks[count].time(), m_tc.fps());
157         QStringList itemtext;
158         itemtext << time << marks[count].comment();
159         (void) new QTreeWidgetItem(m_view.markers_list, itemtext);
160     }
161 }
162
163 void ClipProperties::slotAddMarker() {
164     CommentedTime marker(GenTime(), i18n("Marker"));
165     MarkerDialog d(m_clip, marker, m_tc, this);
166     if (d.exec() == QDialog::Accepted) {
167         int id = m_clip->getId();
168         emit addMarker(id, d.newMarker().time(), d.newMarker().comment());
169     }
170     QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
171 }
172
173 void ClipProperties::slotEditMarker() {
174     QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
175     int pos = m_view.markers_list->currentIndex().row();
176     if (pos < 0 || pos > marks.count() - 1) return;
177     MarkerDialog d(m_clip, marks.at(pos), m_tc, this);
178     if (d.exec() == QDialog::Accepted) {
179         int id = m_clip->getId();
180         emit addMarker(id, d.newMarker().time(), d.newMarker().comment());
181     }
182     QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
183 }
184
185 void ClipProperties::slotDeleteMarker() {
186     QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
187     int pos = m_view.markers_list->currentIndex().row();
188     if (pos < 0 || pos > marks.count() - 1) return;
189     int id = m_clip->getId();
190     emit addMarker(id, marks.at(pos).time(), QString());
191
192     QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
193 }
194
195 int ClipProperties::clipId() const {
196     return m_clip->getId();
197 }
198
199
200 QMap <QString, QString> ClipProperties::properties() {
201     QMap <QString, QString> props;
202     props["description"] = m_view.clip_description->text();
203     CLIPTYPE t = m_clip->clipType();
204     if (t == COLOR) {
205         QMap <QString, QString> old_props = m_clip->properties();
206         QString new_color = m_view.clip_color->color().name();
207         if (new_color != QString("#" + old_props.value("colour").right(8).left(6))) {
208             m_clipNeedsRefresh = true;
209             props["colour"] = "0x" + new_color.right(6) + "ff";
210         }
211     } else if (t == SLIDESHOW) {
212         QMap <QString, QString> old_props = m_clip->properties();
213         QString value = QString::number((int) m_view.slide_loop->isChecked());
214         if (old_props.value("loop") != value) props["loop"] = value;
215         value = QString::number((int) m_view.slide_fade->isChecked());
216         if (old_props.value("fade") != value) props["fade"] = value;
217
218         QString extension;
219         switch (m_view.image_type->currentIndex()) {
220         case TYPE_PNG:
221             extension = "/.all.png";
222             break;
223         case TYPE_BMP:
224             extension = "/.all.bmp";
225             break;
226         case TYPE_GIF:
227             extension = "/.all.gif";
228             break;
229         default:
230             extension = "/.all.jpg";
231             break;
232         }
233         QString new_path = m_view.clip_path->text() + extension;
234         if (new_path != old_props.value("resource")) {
235             m_clipNeedsRefresh = true;
236             props["resource"] = new_path;
237             kDebug() << "////  SLIDE EDIT, NEW:" << new_path << ", OLD; " << old_props.value("resource");
238         }
239         int duration = m_tc.getFrameCount(m_view.slide_duration->text(), m_fps);
240         if (duration != old_props.value("ttl").toInt()) {
241             m_clipNeedsRefresh = true;
242             props["ttl"] = QString::number(duration);
243             props["out"] = QString::number(duration * m_count);
244         }
245         if (duration * m_count != old_props.value("out").toInt()) {
246             m_clipNeedsRefresh = true;
247             props["out"] = QString::number(duration * m_count);
248         }
249         if (m_view.slide_fade->isChecked()) {
250             int luma_duration = m_tc.getFrameCount(m_view.luma_duration->text(), m_fps);
251             if (luma_duration != old_props.value("luma_duration").toInt()) {
252                 m_clipNeedsRefresh = true;
253                 props["luma_duration"] = QString::number(luma_duration);
254             }
255             QString lumaFile;
256             if (m_view.slide_luma->isChecked())
257                 lumaFile = m_view.luma_file->itemData(m_view.luma_file->currentIndex()).toString();
258             if (lumaFile != old_props.value("luma_file")) {
259                 m_clipNeedsRefresh = true;
260                 props["luma_file"] = lumaFile;
261             }
262         } else {
263             if (old_props.value("luma_file") != QString()) {
264                 props["luma_file"] = QString();
265             }
266         }
267
268     }
269     return props;
270 }
271
272 bool ClipProperties::needsTimelineRefresh() const {
273     return m_clipNeedsRefresh;
274 }
275
276 void ClipProperties::parseFolder() {
277
278     QDir dir(m_view.clip_path->text());
279     QStringList filters;
280     QString extension;
281     switch (m_view.image_type->currentIndex()) {
282     case TYPE_PNG:
283         filters << "*.png";
284         extension = "/.all.png";
285         break;
286     case TYPE_BMP:
287         filters << "*.bmp";
288         extension = "/.all.bmp";
289         break;
290     case TYPE_GIF:
291         filters << "*.gif";
292         extension = "/.all.gif";
293         break;
294     default:
295         filters << "*.jpg" << "*.jpeg";
296         extension = "/.all.jpg";
297         break;
298     }
299
300     dir.setNameFilters(filters);
301     QStringList result = dir.entryList(QDir::Files);
302     m_count = result.count();
303     m_view.slide_info->setText(i18n("%1 images found", m_count));
304     QDomElement xml = m_clip->toXML();
305     xml.setAttribute("resource", m_view.clip_path->text() + extension);
306     QPixmap pix = m_clip->thumbProducer()->getImage(xml, 1, 240, 180);
307     QMap <QString, QString> props = m_clip->properties();
308     m_view.clip_duration->setText(m_tc.getTimecodeFromFrames(props.value("ttl").toInt() * m_count));
309     m_view.clip_thumb->setPixmap(pix);
310 }
311
312 #include "clipproperties.moc"
313
314