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