]> git.sesse.net Git - kdenlive/blob - src/docclipbase.cpp
folders in project view
[kdenlive] / src / docclipbase.cpp
1 /**************************1*************************************************
2                           DocClipBase.cpp  -  description
3                              -------------------
4     begin                : Fri Apr 12 2002
5     copyright            : (C) 2002 by Jason Wood
6     email                : jasonwood@blueyonder.co.uk
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17
18 #include <KDebug>
19
20 #include "kdenlivesettings.h"
21 #include "docclipbase.h"
22 #include "kthumb.h"
23 #include "clipmanager.h"
24
25 DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, uint id):
26         m_xml(xml), m_id(id), m_description(""), m_refcount(0), m_projectThumbFrame(0), m_audioThumbCreated(false), m_duration(GenTime()), m_thumbProd(NULL), m_audioTimer(NULL) {
27     int type = xml.attribute("type").toInt();
28     m_clipType = (CLIPTYPE) type;
29     m_name = xml.attribute("name");
30     m_xml.setAttribute("id", QString::number(id));
31     KUrl url = KUrl(xml.attribute("resource"));
32     int out = xml.attribute("out").toInt();
33     if (out != 0) setDuration(GenTime(out, 25));
34     if (m_name.isEmpty()) m_name = url.fileName();
35     if (!url.isEmpty()) {
36         m_thumbProd = new KThumb(clipManager, url);
37         connect(m_thumbProd, SIGNAL(audioThumbReady(QMap <int, QMap <int, QByteArray> >)), this , SLOT(updateAudioThumbnail(QMap <int, QMap <int, QByteArray> >)));
38         connect(this, SIGNAL(getAudioThumbs()), this , SLOT(slotGetAudioThumbs()));
39
40     }
41     kDebug() << "type is video" << (m_clipType == AV) << " " << m_clipType;
42
43     if (m_clipType == AV || m_clipType == AUDIO || m_clipType == UNKNOWN) {
44         m_audioTimer = new QTimer(this);
45         connect(m_audioTimer, SIGNAL(timeout()), this, SLOT(slotGetAudioThumbs()));
46     }
47 }
48
49
50
51 DocClipBase::DocClipBase(const DocClipBase& clip) {
52     m_xml = clip.toXML();
53     m_id = clip.getId();
54     m_clipType = clip.clipType();
55     m_name = clip.name();
56     m_duration = clip.duration();
57     m_audioThumbCreated = clip.audioThumbCreated();
58 }
59
60 DocClipBase & DocClipBase::operator=(const DocClipBase & clip) {
61     DocClipBase::operator=(clip);
62     m_xml = clip.toXML();
63     m_id = clip.getId();
64     m_clipType = clip.clipType();
65     m_name = clip.name();
66     m_duration = clip.duration();
67     m_audioThumbCreated = clip.audioThumbCreated();
68     return *this;
69 }
70
71 DocClipBase::~DocClipBase() {
72     if (m_thumbProd) delete m_thumbProd;
73 }
74
75 void DocClipBase::slotRequestAudioThumbs() {
76     emit getAudioThumbs();
77 }
78
79 void DocClipBase::slotClearAudioCache() {
80     audioFrameChache.clear();
81     m_audioThumbCreated = false;
82 }
83
84 void DocClipBase::setGroup(const QString name, const QString id) {
85     m_xml.setAttribute("groupname", name);
86     m_xml.setAttribute("groupid", id);
87 }
88
89 KThumb *DocClipBase::thumbProducer() {
90     return m_thumbProd;
91 }
92
93 bool DocClipBase::audioThumbCreated() const {
94     return m_audioThumbCreated;
95 }
96
97 void DocClipBase::setName(const QString name) {
98     m_name = name;
99 }
100
101 const QString & DocClipBase::name() const {
102
103     return m_name;
104 }
105
106 uint DocClipBase::getId() const {
107     return m_id;
108 }
109
110 void DocClipBase::setId(const uint &newId) {
111     m_id = newId;
112 }
113
114 const CLIPTYPE & DocClipBase::clipType() const {
115     return m_clipType;
116 }
117
118 void DocClipBase::setClipType(CLIPTYPE type) {
119     m_clipType = type;
120 }
121
122 KUrl DocClipBase::fileURL() const {
123     QString res = m_xml.attribute("resource");
124     if (m_clipType != COLOR && !res.isEmpty()) return KUrl(res);
125     return KUrl();
126 }
127
128 void DocClipBase::setProjectThumbFrame(const uint &ix) {
129     m_projectThumbFrame = ix;
130 }
131
132 uint DocClipBase::getProjectThumbFrame() const {
133     return m_projectThumbFrame;
134 }
135
136 void DocClipBase::setDescription(const QString & description) {
137     m_description = description;
138 }
139
140 const QString & DocClipBase::description() const {
141     return m_description;
142 }
143
144 void DocClipBase::setDuration(GenTime dur) {
145     m_duration = dur;
146 }
147
148 const GenTime &DocClipBase::duration() const {
149     return m_duration;
150 }
151
152 bool DocClipBase::hasFileSize() const {
153     return true;
154 }
155
156
157 // virtual
158 QDomElement DocClipBase::toXML() const {
159     /*
160         QDomDocument doc;
161
162         QDomElement clip = doc.createElement("kdenliveclip");
163         QDomText text = doc.createTextNode(description());
164         clip.appendChild(text);
165         doc.appendChild(clip);
166     */
167     return m_xml;
168 }
169
170 DocClipBase *DocClipBase::
171 createClip(KdenliveDoc *doc, const QDomElement & element) {
172     DocClipBase *clip = 0;
173     QString description;
174     QDomNode node = element;
175     node.normalize();
176     if (element.tagName() != "kdenliveclip") {
177         kWarning() <<
178         "DocClipBase::createClip() element has unknown tagName : " <<
179         element.tagName() << endl;
180         return 0;
181     }
182
183     QDomNode n = element.firstChild();
184
185     while (!n.isNull()) {
186         QDomElement e = n.toElement();
187         if (!e.isNull()) {
188             QString tagName = e.tagName();
189             if (e.tagName() == "avfile") {
190                 // clip = DocClipAVFile::createClip(e);
191             } else if (e.tagName() == "DocTrackBaseList") {
192                 // clip = DocClipProject::createClip(doc, e);
193             }
194         } else {
195             QDomText text = n.toText();
196             if (!text.isNull()) {
197                 description = text.nodeValue();
198             }
199         }
200
201         n = n.nextSibling();
202     }
203     if (clip == 0) {
204         kWarning() << "DocClipBase::createClip() unable to create clip" <<
205         endl;
206     } else {
207         // setup DocClipBase specifics of the clip.
208         clip->setDescription(description);
209         clip->setAudioThumbCreated(false);
210     }
211     return clip;
212 }
213
214 void DocClipBase::setAudioThumbCreated(bool isDone) {
215     m_audioThumbCreated = isDone;
216 }
217
218
219 QDomDocument DocClipBase::generateSceneList(bool, bool) const {
220 }
221
222 void DocClipBase::setThumbnail(const QPixmap & pixmap) {
223     m_thumbnail = pixmap;
224 }
225
226 const QPixmap & DocClipBase::thumbnail() const {
227     return m_thumbnail;
228 }
229
230 void DocClipBase::updateAudioThumbnail(QMap<int, QMap<int, QByteArray> > data) {
231     kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************";
232     audioFrameChache = data;
233     m_audioThumbCreated = true;
234     emit gotAudioData();
235 }
236
237 QList < GenTime > DocClipBase::snapMarkers() const {
238     QList < GenTime > markers;
239
240     for (uint count = 0; count < m_snapMarkers.count(); ++count) {
241         markers.append(m_snapMarkers[count].time());
242     }
243
244     return markers;
245 }
246
247 QList < CommentedTime > DocClipBase::commentedSnapMarkers() const {
248     return m_snapMarkers;
249 }
250
251 void DocClipBase::setSnapMarkers(QList < CommentedTime > markers) {
252     m_snapMarkers = markers;
253 }
254
255 void DocClipBase::addSnapMarker(const GenTime & time, QString comment) {
256     QList < CommentedTime >::Iterator it = m_snapMarkers.begin();
257     for (it = m_snapMarkers.begin(); it != m_snapMarkers.end(); ++it) {
258         if ((*it).time() >= time)
259             break;
260     }
261
262     if ((it != m_snapMarkers.end()) && ((*it).time() == time)) {
263         kError() <<
264         "trying to add Snap Marker that already exists, this will cause inconsistancies with undo/redo"
265         << endl;
266     } else {
267         CommentedTime t(time, comment);
268         m_snapMarkers.insert(it, t);
269     }
270
271 }
272
273 void DocClipBase::editSnapMarker(const GenTime & time, QString comment) {
274     QList < CommentedTime >::Iterator it;
275     for (it = m_snapMarkers.begin(); it != m_snapMarkers.end(); ++it) {
276         if ((*it).time() == time)
277             break;
278     }
279     if (it != m_snapMarkers.end()) {
280         (*it).setComment(comment);
281     } else {
282         kError() <<
283         "trying to edit Snap Marker that does not already exists"  << endl;
284     }
285 }
286
287 QString DocClipBase::deleteSnapMarker(const GenTime & time) {
288     QString result = i18n("Marker");
289     QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
290
291     while (itt != m_snapMarkers.end()) {
292         if ((*itt).time() == time)
293             break;
294         ++itt;
295     }
296
297     if ((itt != m_snapMarkers.end()) && ((*itt).time() == time)) {
298         result = (*itt).comment();
299         m_snapMarkers.erase(itt);
300     }
301     return result;
302 }
303
304
305 GenTime DocClipBase::hasSnapMarkers(const GenTime & time) {
306     QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
307
308     while (itt != m_snapMarkers.end()) {
309         if ((*itt).time() == time)
310             return time;
311         ++itt;
312     }
313
314     return GenTime(0.0);
315 }
316
317 GenTime DocClipBase::findPreviousSnapMarker(const GenTime & currTime) {
318     int it;
319     for (it = 0; it < m_snapMarkers.count(); it++) {
320         if (m_snapMarkers[it].time() >= currTime)
321             break;
322     }
323     if (it == 0) return GenTime();
324     else if (it == m_snapMarkers.count() - 1 && m_snapMarkers[it].time() < currTime)
325         return m_snapMarkers[it].time();
326     else return m_snapMarkers[it-1].time();
327 }
328
329 GenTime DocClipBase::findNextSnapMarker(const GenTime & currTime) {
330     int it;
331     for (it = 0; it < m_snapMarkers.count(); it++) {
332         if (m_snapMarkers[it].time() > currTime)
333             break;
334     }
335     if (it < m_snapMarkers.count() && m_snapMarkers[it].time() > currTime) return m_snapMarkers[it].time();
336     return duration();
337 }
338
339 QString DocClipBase::markerComment(GenTime t) {
340     QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
341
342     while (itt != m_snapMarkers.end()) {
343         if ((*itt).time() == t)
344             return (*itt).comment();
345         ++itt;
346     }
347     return QString::null;
348 }
349
350 //static
351 QString DocClipBase::getTypeName(CLIPTYPE type) {
352     QString result;
353     switch (type) {
354     case AV:
355         result = i18n("Video Clip");
356         break;
357     case COLOR:
358         result = i18n("Color Clip");
359         break;
360     case PLAYLIST:
361         result = i18n("Playlist Clip");
362         break;
363     case IMAGE:
364         result = i18n("Image Clip");
365         break;
366     case SLIDESHOW:
367         result = i18n("Slideshow Clip");
368         break;
369     case VIRTUAL:
370         result = i18n("Virtual Clip");
371         break;
372     case AUDIO:
373         result = i18n("Audio Clip");
374         break;
375     case VIDEO:
376         result = i18n("Mute Video Clip");
377         break;
378     case TEXT:
379         result = i18n("Text Clip");
380         break;
381     default:
382         result = i18n("None");
383         break;
384     }
385     return result;
386 }
387
388 void DocClipBase::slotGetAudioThumbs() {
389
390     if (m_audioThumbCreated) {
391         if (m_audioTimer != NULL)
392             m_audioTimer->stop();
393     } else {
394         if (m_audioTimer != NULL)
395             m_audioTimer->start(2000);
396         double lengthInFrames = duration().frames(/*framesPerSecond()*/25);
397         m_thumbProd->getAudioThumbs(2, 0, lengthInFrames /*must be number of frames*/, 20);
398     }
399 }
400
401
402