]> git.sesse.net Git - kdenlive/commitdiff
Starting KDE4 porting
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 29 Dec 2007 20:13:27 +0000 (20:13 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 29 Dec 2007 20:13:27 +0000 (20:13 +0000)
svn path=/branches/KDE4/; revision=1777

29 files changed:
CMakeLists.txt [new file with mode: 0644]
src/CMakeLists.txt [new file with mode: 0644]
src/customruler.cpp [new file with mode: 0644]
src/customruler.h [new file with mode: 0644]
src/docclipbase.cpp [new file with mode: 0644]
src/docclipbase.h [new file with mode: 0644]
src/gentime.cpp [new file with mode: 0644]
src/gentime.h [new file with mode: 0644]
src/kdenlivedoc.cpp [new file with mode: 0644]
src/kdenlivedoc.h [new file with mode: 0644]
src/kdenliveui.rc [new file with mode: 0644]
src/main.cpp [new file with mode: 0644]
src/mainwindow.cpp [new file with mode: 0644]
src/mainwindow.h [new file with mode: 0644]
src/monitor.cpp [new file with mode: 0644]
src/monitor.h [new file with mode: 0644]
src/projectitem.cpp [new file with mode: 0644]
src/projectitem.h [new file with mode: 0644]
src/projectlist.cpp [new file with mode: 0644]
src/projectlist.h [new file with mode: 0644]
src/renderer.cpp [new file with mode: 0644]
src/renderer.h [new file with mode: 0644]
src/timecode.cpp [new file with mode: 0644]
src/timecode.h [new file with mode: 0644]
src/trackview.cpp [new file with mode: 0644]
src/trackview.h [new file with mode: 0644]
src/widgets/monitor_ui.ui [new file with mode: 0644]
src/widgets/projectlist_ui.ui [new file with mode: 0644]
src/widgets/timeline_ui.ui [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..49e288e
--- /dev/null
@@ -0,0 +1,20 @@
+project(kdenlive)
+
+
+set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
+
+# search packages used by KDE
+find_package(KDE4 REQUIRED)
+include (KDE4Defaults)
+include (MacroLibrary)
+include(MacroOptionalAddSubdirectory)
+
+add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
+include_directories (${QDBUS_INCLUDE_DIRS}  ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} ${CMAKE_SOURCE_DIR}/widgets)
+
+FIND_PACKAGE(LIBMLT REQUIRED)
+FIND_PACKAGE(LIBMLTPLUS REQUIRED)
+FIND_PACKAGE(LIBFFMPEG REQUIRED)
+
+add_subdirectory(src)
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d415349
--- /dev/null
@@ -0,0 +1,51 @@
+
+add_subdirectory( widgets )
+
+
+include_directories(
+    ${CMAKE_SOURCE_DIR}/src/widgets
+    ${LIBMLT_INCLUDE_DIR}
+    ${LIBMLTPLUS_INCLUDE_DIR}
+    ${LIBFFMPEG_INCLUDE_DIR}
+)
+
+LINK_DIRECTORIES(
+${LIBMLT_LIBRARY}
+${LIBMLTPLUS_LIBRARY}
+${LIBFFMPEG_LIBRARY}
+)
+
+
+kde4_add_ui_files(kdenlive_UI
+  widgets/timeline_ui.ui
+  widgets/projectlist_ui.ui
+  widgets/monitor_ui.ui
+)
+set(kdenlive_SRCS 
+  main.cpp
+  mainwindow.cpp
+  customruler.cpp
+  projectlist.cpp
+  projectitem.cpp
+  monitor.cpp
+  gentime.cpp
+  renderer.cpp
+  kdenlivedoc.cpp
+  trackview.cpp
+  docclipbase.cpp
+  timecode.cpp
+)
+
+kde4_add_executable(kdenlive ${kdenlive_SRCS} ${kdenlive_UI})
+target_link_libraries(kdenlive 
+  ${KDE4_KDEUI_LIBS}
+  ${KDE4_KIO_LIBS} 
+  ${LIBMLTPLUS_LIBRARY}
+  ${LIBMLT_LIBRARY}
+)
+install(TARGETS kdenlive DESTINATION ${BIN_INSTALL_DIR})
+install( FILES kdenliveui.rc 
+         DESTINATION  ${DATA_INSTALL_DIR}/kdenlive )
\ No newline at end of file
diff --git a/src/customruler.cpp b/src/customruler.cpp
new file mode 100644 (file)
index 0000000..e7f95c8
--- /dev/null
@@ -0,0 +1,189 @@
+
+#include <QMouseEvent>
+#include <QStylePainter>
+
+#include <KDebug>
+
+
+#include "customruler.h"
+
+
+#define INIT_VALUE 0
+#define INIT_MIN_VALUE 0
+#define INIT_MAX_VALUE 100
+#define INIT_TINY_MARK_DISTANCE 1
+#define INIT_LITTLE_MARK_DISTANCE 5
+#define INIT_MIDDLE_MARK_DISTANCE (INIT_LITTLE_MARK_DISTANCE * 2)
+#define INIT_BIG_MARK_DISTANCE (INIT_LITTLE_MARK_DISTANCE * 10)
+#define INIT_SHOW_TINY_MARK false
+#define INIT_SHOW_LITTLE_MARK true
+#define INIT_SHOW_MEDIUM_MARK true
+#define INIT_SHOW_BIG_MARK true
+#define INIT_SHOW_END_MARK true
+#define INIT_SHOW_POINTER true
+#define INIT_SHOW_END_LABEL true
+
+#define INIT_PIXEL_PER_MARK (double)10.0 /* distance between 2 base marks in pixel */
+#define INIT_OFFSET (-20)
+#define INIT_LENGTH_FIX true
+#define INIT_END_OFFSET 0
+
+#define FIX_WIDTH 20 /* widget width in pixel */
+#define LINE_END (FIX_WIDTH - 3)
+#define END_MARK_LENGTH (FIX_WIDTH - 6)
+#define END_MARK_X2 LINE_END
+#define END_MARK_X1 (END_MARK_X2 - END_MARK_LENGTH)
+#define BIG_MARK_LENGTH (END_MARK_LENGTH*3/4)
+#define BIG_MARK_X2 LINE_END
+#define BIG_MARK_X1 (BIG_MARK_X2 - BIG_MARK_LENGTH)
+#define MIDDLE_MARK_LENGTH (END_MARK_LENGTH/2)
+#define MIDDLE_MARK_X2 LINE_END
+#define MIDDLE_MARK_X1 (MIDDLE_MARK_X2 - MIDDLE_MARK_LENGTH)
+#define LITTLE_MARK_LENGTH (MIDDLE_MARK_LENGTH/2)
+#define LITTLE_MARK_X2 LINE_END
+#define LITTLE_MARK_X1 (LITTLE_MARK_X2 - LITTLE_MARK_LENGTH)
+#define BASE_MARK_LENGTH (LITTLE_MARK_LENGTH/2)
+#define BASE_MARK_X2 LINE_END
+#define BASE_MARK_X1 (BASE_MARK_X2 - 3) //BASE_MARK_LENGTH
+
+#define LABEL_SIZE 8
+#define END_LABEL_X 4
+#define END_LABEL_Y (END_LABEL_X + LABEL_SIZE - 2)
+
+#define FRAME_SIZE 90
+
+
+const int CustomRuler::comboScale[] =
+       { 1, 2, 5, 10, 25, 50, 125, 250, 500, 725, 1500, 3000, 6000,
+           12000 };
+
+CustomRuler::CustomRuler(QWidget *parent)
+    : KRuler(parent)
+{
+  slotNewOffset(0);
+  setRulerMetricStyle(KRuler::Pixel);
+  setLength(1024);
+  setMaximum(1024);
+  setPixelPerMark(3);
+  setLittleMarkDistance (FRAME_SIZE);
+  setMediumMarkDistance (FRAME_SIZE * 25);
+  setBigMarkDistance (FRAME_SIZE * 25 * 60);
+}
+
+// virtual 
+void CustomRuler::mousePressEvent ( QMouseEvent * event )
+{
+  int pos = event->x();
+  slotNewValue( pos );
+  kDebug()<<pos;
+}
+
+void CustomRuler::slotNewValue ( int _value )
+{
+  m_cursorPosition = _value / pixelPerMark();
+  KRuler::slotNewValue(_value);
+}
+
+void CustomRuler::setPixelPerMark (double rate)
+{
+    int scale = comboScale[(int) rate];
+    int newPos = m_cursorPosition * (1.0 / scale); 
+    KRuler::setPixelPerMark(1.0 / scale);
+    KRuler::slotNewValue( newPos );
+}
+
+// virtual 
+void CustomRuler::paintEvent(QPaintEvent * /*e*/)
+ {
+   //  debug ("KRuler::drawContents, %s",(horizontal==dir)?"horizontal":"vertical");
+   QStylePainter p(this);
+
+   int value  = this->value(),
+     minval = minimum(),
+     maxval;
+     maxval = maximum()
+     + offset() - endOffset();
+
+     //ioffsetval = value-offset;
+     //    pixelpm = (int)ppm;
+   //    left  = clip.left(),
+   //    right = clip.right();
+   double f, fend,
+     offsetmin=(double)(minval-offset()),
+     offsetmax=(double)(maxval-offset()),
+     fontOffset = (((double)minval)>offsetmin)?(double)minval:offsetmin;
+   // draw labels
+   QFont font = p.font();
+   font.setPointSize(LABEL_SIZE);
+   p.setFont( font );
+   // draw littlemarklabel
+   // draw mediummarklabel
+   // draw bigmarklabel
+   // draw endlabel
+   /*if (d->showEndL) {
+     if (d->dir == Qt::Horizontal) {
+       p.translate( fontOffset, 0 );
+       p.drawText( END_LABEL_X, END_LABEL_Y, d->endlabel );
+     }*/
+   // draw the tiny marks
+   //if (showTinyMarks()) 
+   /*{
+     fend =   pixelPerMark()*tinyMarkDistance();
+     if (fend > 5) for ( f=offsetmin; f<offsetmax; f+=fend ) {
+         p.drawLine((int)f, BASE_MARK_X1, (int)f, BASE_MARK_X2);
+     }
+   }*/
+   if (showLittleMarks()) {
+     // draw the little marks
+     fend = pixelPerMark()*littleMarkDistance();
+     if (fend > 5) for ( f=offsetmin; f<offsetmax; f+=fend ) {
+         p.drawLine((int)f, LITTLE_MARK_X1, (int)f, LITTLE_MARK_X2);
+        if (fend > 30) p.drawText( (int)f + 2, LABEL_SIZE, QString::number((f - offsetmin) / pixelPerMark() / FRAME_SIZE) );
+     }
+   }
+   if (showMediumMarks()) {
+     // draw medium marks
+     fend = pixelPerMark()*mediumMarkDistance();
+     if (fend > 5) for ( f=offsetmin; f<offsetmax; f+=fend ) {
+         p.drawLine((int)f, MIDDLE_MARK_X1, (int)f, MIDDLE_MARK_X2);
+        if (fend > 30) p.drawText( (int)f + 2, LABEL_SIZE, QString::number((f - offsetmin) / pixelPerMark() / FRAME_SIZE) );
+     }
+   }
+   if (showBigMarks()) {
+     // draw big marks
+     fend = pixelPerMark()*bigMarkDistance();
+     if (fend > 5) for ( f=offsetmin; f<offsetmax; f+=fend ) {
+         p.drawLine((int)f, BIG_MARK_X1, (int)f, BIG_MARK_X2);
+        if (fend > 30) p.drawText( (int)f + 2, LABEL_SIZE, QString::number((f - offsetmin) / pixelPerMark() / FRAME_SIZE) );
+     }
+   }
+/*   if (d->showem) {
+     // draw end marks
+     if (d->dir == Qt::Horizontal) {
+       p.drawLine(minval-d->offset, END_MARK_X1, minval-d->offset, END_MARK_X2);
+       p.drawLine(maxval-d->offset, END_MARK_X1, maxval-d->offset, END_MARK_X2);
+     }
+     else {
+       p.drawLine(END_MARK_X1, minval-d->offset, END_MARK_X2, minval-d->offset);
+       p.drawLine(END_MARK_X1, maxval-d->offset, END_MARK_X2, maxval-d->offset);
+     }
+   }*/
+   // draw pointer
+   if (showPointer()) {
+     QPolygon pa(4);
+       pa.setPoints(3, value-6, 9, value+6, 9, value/*+0*/, 16);
+     p.setBrush( QBrush(Qt::yellow) );
+     p.drawPolygon( pa );
+   }
+ }
+
+#include "customruler.moc"
diff --git a/src/customruler.h b/src/customruler.h
new file mode 100644 (file)
index 0000000..767c580
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef CUSTOMRULER_H
+#define CUSTOMRULER_H
+
+#include <KRuler>
+
+class CustomRuler : public KRuler
+{
+  Q_OBJECT
+  
+  public:
+    CustomRuler(QWidget *parent=0);
+    virtual void mousePressEvent ( QMouseEvent * event );
+    void setPixelPerMark (double rate);
+    static const int comboScale[];
+  protected:
+    virtual void paintEvent(QPaintEvent * /*e*/);
+
+  private:
+    int m_cursorPosition;
+
+  public slots:
+    void slotNewValue ( int _value );
+};
+
+#endif
diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp
new file mode 100644 (file)
index 0000000..baf9221
--- /dev/null
@@ -0,0 +1,323 @@
+/**************************1*************************************************
+                          DocClipBase.cpp  -  description
+                             -------------------
+    begin                : Fri Apr 12 2002
+    copyright            : (C) 2002 by Jason Wood
+    email                : jasonwood@blueyonder.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include <KDebug>
+
+#include "docclipbase.h"
+/*#include "docclipavfile.h"
+#include "doccliptextfile.h"
+#include "docclipproject.h"
+#include "doctrackbase.h"*/
+
+DocClipBase::DocClipBase():
+m_description(""), m_refcount(0), m_projectThumbFrame(0), audioThumbCreated(false)
+{
+    //thumbCreator = 0;
+}
+
+DocClipBase::~DocClipBase()
+{
+    //delete thumbCreator;
+}
+
+void DocClipBase::setName(const QString name)
+{
+    m_name = name;
+}
+
+const QString & DocClipBase::name() const
+{
+    return m_name;
+}
+
+uint DocClipBase::getId() const
+{
+    return m_id;
+}
+
+void DocClipBase::setId( const uint &newId)
+{
+    m_id = newId;
+}
+
+void DocClipBase::setProjectThumbFrame( const uint &ix)
+{
+    m_projectThumbFrame = ix;
+}
+
+uint DocClipBase::getProjectThumbFrame() const
+{
+    return m_projectThumbFrame;
+}
+
+void DocClipBase::setDescription(const QString & description)
+{
+    m_description = description;
+}
+
+const QString & DocClipBase::description() const
+{
+    return m_description;
+}
+
+// virtual
+QDomDocument DocClipBase::toXML() const
+{
+    QDomDocument doc;
+
+    QDomElement clip = doc.createElement("kdenliveclip");
+    QDomText text = doc.createTextNode(description());
+    clip.appendChild(text);
+    doc.appendChild(clip);
+
+    return doc;
+}
+
+DocClipBase *DocClipBase::
+createClip(KdenliveDoc *doc, const QDomElement & element)
+{
+    DocClipBase *clip = 0;
+    QString description;
+    QDomNode node = element;
+    node.normalize();
+    if (element.tagName() != "kdenliveclip") {
+       kWarning() <<
+           "DocClipBase::createClip() element has unknown tagName : " <<
+           element.tagName() << endl;
+       return 0;
+    }
+
+    QDomNode n = element.firstChild();
+
+    while (!n.isNull()) {
+       QDomElement e = n.toElement();
+       if (!e.isNull()) {
+           QString tagName = e.tagName();
+           if (e.tagName() == "avfile") {
+               // clip = DocClipAVFile::createClip(e);
+           } else if (e.tagName() == "DocTrackBaseList") {
+               // clip = DocClipProject::createClip(doc, e);
+           }
+       } else {
+           QDomText text = n.toText();
+           if (!text.isNull()) {
+               description = text.nodeValue();
+           }
+       }
+
+       n = n.nextSibling();
+    }
+    if (clip == 0) {
+       kWarning() << "DocClipBase::createClip() unable to create clip" <<
+           endl;
+    } else {
+       // setup DocClipBase specifics of the clip.
+       clip->setDescription(description);
+       clip->setAudioThumbCreated(false);
+    }
+    return clip;
+}
+
+void DocClipBase::setAudioThumbCreated(bool isDone)
+{
+    audioThumbCreated = isDone;
+}
+
+
+QDomDocument DocClipBase::generateSceneList(bool, bool) const
+{
+}
+
+void DocClipBase::setThumbnail(const QPixmap & pixmap)
+{
+    m_thumbnail = pixmap;
+}
+
+const QPixmap & DocClipBase::thumbnail() const
+{
+    return m_thumbnail;
+}
+
+void DocClipBase::updateAudioThumbnail(QMap<int,QMap<int,QByteArray> > data)
+{
+    audioFrameChache = data;
+    audioThumbCreated = true;
+}
+
+QList < GenTime > DocClipBase::snapMarkers() const
+{
+    QList < GenTime > markers;
+
+    for (uint count = 0; count < m_snapMarkers.count(); ++count) {
+       markers.append(m_snapMarkers[count].time());
+    }
+
+    return markers;
+}
+
+QList < CommentedTime > DocClipBase::commentedSnapMarkers() const
+{
+    return m_snapMarkers;
+}
+
+void DocClipBase::setSnapMarkers(QList < CommentedTime > markers)
+{
+    m_snapMarkers = markers;
+}
+
+void DocClipBase::addSnapMarker(const GenTime & time, QString comment)
+{
+    QList < CommentedTime >::Iterator it = m_snapMarkers.begin();
+    for ( it = m_snapMarkers.begin(); it != m_snapMarkers.end(); ++it ) {
+       if ((*it).time() >= time)
+           break;
+    }
+
+    if ((it != m_snapMarkers.end()) && ((*it).time() == time)) {
+       kError() <<
+           "trying to add Snap Marker that already exists, this will cause inconsistancies with undo/redo"
+           << endl;
+    } else {
+       CommentedTime t(time, comment);
+       m_snapMarkers.insert(it, t);
+    }
+
+}
+
+void DocClipBase::editSnapMarker(const GenTime & time, QString comment)
+{
+    QList < CommentedTime >::Iterator it;
+    for ( it = m_snapMarkers.begin(); it != m_snapMarkers.end(); ++it ) {
+       if ((*it).time() == time)
+           break;
+    }
+    if (it != m_snapMarkers.end()) {
+       (*it).setComment(comment);
+    } else {
+       kError() <<
+           "trying to edit Snap Marker that does not already exists"  << endl;
+    }
+}
+
+QString DocClipBase::deleteSnapMarker(const GenTime & time)
+{
+    QString result = i18n("Marker");
+    QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
+
+    while (itt != m_snapMarkers.end()) {
+       if ((*itt).time() == time)
+           break;
+       ++itt;
+    }
+
+    if ((itt != m_snapMarkers.end()) && ((*itt).time() == time)) {
+       result = (*itt).comment();
+       m_snapMarkers.erase(itt);
+    }
+    return result;
+}
+
+
+GenTime DocClipBase::hasSnapMarkers(const GenTime & time)
+{
+    QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
+
+    while (itt != m_snapMarkers.end()) {
+       if ((*itt).time() == time)
+           return time;
+       ++itt;
+    }
+
+    return GenTime(0.0);
+}
+
+GenTime DocClipBase::findPreviousSnapMarker(const GenTime & currTime)
+{
+    int it;
+    for ( it = 0; it < m_snapMarkers.count(); it++ ) {
+       if (m_snapMarkers[it].time() >= currTime)
+           break;
+    }
+    if (it == 0) return GenTime();
+    else if (it == m_snapMarkers.count() - 1 && m_snapMarkers[it].time() < currTime)
+       return m_snapMarkers[it].time();
+    else return m_snapMarkers[it-1].time();
+}
+
+GenTime DocClipBase::findNextSnapMarker(const GenTime & currTime)
+{
+    int it;
+    for ( it = 0; it < m_snapMarkers.count(); it++ ) {
+       if (m_snapMarkers[it].time() > currTime)
+           break;
+    }
+    if (it < m_snapMarkers.count() && m_snapMarkers[it].time() > currTime) return m_snapMarkers[it].time();
+    return duration();
+}
+
+QString DocClipBase::markerComment(GenTime t)
+{
+    QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
+
+    while (itt != m_snapMarkers.end()) {
+       if ((*itt).time() == t)
+           return (*itt).comment();
+       ++itt;
+    }
+    return QString::null;
+}
+
+//static
+QString DocClipBase::getTypeName(CLIPTYPE type)
+{
+    QString result;
+    switch (type) {
+       case AV:
+           result = i18n("Video Clip");
+           break;
+       case COLOR:
+           result = i18n("Color Clip");
+           break;
+       case PLAYLIST:
+           result = i18n("Playlist Clip");
+           break;
+       case IMAGE:
+           result = i18n("Image Clip");
+           break;
+       case SLIDESHOW:
+           result = i18n("Slideshow Clip");
+           break;
+       case VIRTUAL:
+           result = i18n("Virtual Clip");
+           break;
+       case AUDIO:
+           result = i18n("Audio Clip");
+           break;
+       case VIDEO:
+           result = i18n("Mute Video Clip");
+           break;
+       case TEXT:
+           result = i18n("Text Clip");
+           break;
+       default:
+           result = i18n("None");
+           break;
+    }
+    return result;
+}
+
+
diff --git a/src/docclipbase.h b/src/docclipbase.h
new file mode 100644 (file)
index 0000000..fadb38c
--- /dev/null
@@ -0,0 +1,224 @@
+/***************************************************************************
+                          docclipbase.h  -  description
+                             -------------------
+    begin                : Fri Apr 12 2002
+    copyright            : (C) 2002 by Jason Wood
+    email                : jasonwood@blueyonder.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef DOCCLIPBASE_H
+#define DOCCLIPBASE_H
+
+/**DocClip is a class for the various types of clip
+  *@author Jason Wood
+  */
+
+#include <qdom.h>
+#include <qobject.h>
+#include <qpixmap.h>
+
+#include <kurl.h>
+#include <klocale.h>
+
+#include "gentime.h"
+// #include "kthumb.h"
+
+/*
+class DocTrackBase;
+class DocClipAVFile;
+class DocClipTextFile;
+class DocClipVirtual;
+class EffectDescriptionList;*/
+class KdenliveDoc;
+
+class CommentedTime
+    {
+    public:
+        CommentedTime(): t(GenTime(0)) {}
+        CommentedTime( const GenTime time, QString comment)
+            : t( time ), c( comment )
+        { }
+
+        QString comment()   const          { return (c.isEmpty() ? i18n("Marker") : c);}
+        GenTime time() const          { return t; }
+        void    setComment( QString comm) { c = comm; }
+    private:
+        GenTime t;
+        QString c;
+    };
+
+
+class DocClipBase:public QObject {
+  Q_OBJECT public:
+       /** this enum determines the types of "feed" available within this clip. types must be non-exclusive
+        * - e.g. if you can have audio and video seperately, it should be possible to combin the two, as is
+        *   done here. If a new clip type is added then it should be possible to combine it with both audio
+        *   and video. */
+    enum CLIPTYPE { NONE = 0, AUDIO = 1, VIDEO = 2, AV = 3, COLOR =
+           4, IMAGE = 5, TEXT = 6, SLIDESHOW = 7, VIRTUAL = 8, PLAYLIST = 9};
+
+     DocClipBase();
+     virtual ~ DocClipBase();
+
+       /** sets the name of this clip. */
+    void setName(const QString name);
+
+       /** returns the name of this clip. */
+    const QString & name() const;
+
+       /** Sets the description for this clip. */
+    void setDescription(const QString & descripton);
+
+       /** Returns the description of this clip. */
+    const QString & description() const;
+
+    /** Returns the internal unique id of the clip. */
+    uint getId() const;
+    void setId( const uint &newId);
+
+    //KThumb *thumbCreator;
+    bool audioThumbCreated;
+    
+       /** returns the duration of this clip */
+    virtual const GenTime & duration() const = 0;
+
+       /** returns clip type (audio, text, image,...) */
+    virtual const DocClipBase::CLIPTYPE & clipType() const = 0;
+
+       /** remove tmp file if the clip has one (for example text clips) */
+    virtual void removeTmpFile() const = 0;
+
+       /** Returns a url to a file describing this clip. Exactly what this url is,
+       whether it is temporary or not, and whether it provokes a render will
+       depend entirely on what the clip consists of. */
+    virtual const KUrl & fileURL() const = 0;
+
+       /** Returns true if the clip duration is known, false otherwise. */
+    virtual bool durationKnown() const = 0;
+    // Returns the number of frames per second that this clip should play at.
+    virtual double framesPerSecond() const = 0;
+
+    virtual bool isDocClipAVFile() const {
+       return false;
+    } 
+    
+    /*virtual DocClipAVFile *toDocClipAVFile() {
+       return 0;
+    }
+
+    virtual DocClipTextFile *toDocClipTextFile() {
+        return 0;
+    }
+    
+    virtual bool isDocClipTextFile() const {
+        return false;
+    }
+
+    virtual bool isDocClipVirtual() const {
+        return false;
+    } 
+    
+    virtual DocClipVirtual *toDocClipVirtual() {
+        return 0;
+    }*/
+    
+       /** Returns true if this clip is a project clip, false otherwise. Overridden in DocClipProject,
+        * where it returns true. */ 
+    virtual bool isProjectClip() const {
+       return false;
+    }
+    // Appends scene times for this clip to the passed vector.
+/*     virtual void populateSceneTimes(QList < GenTime >
+       &toPopulate) const = 0;*/
+
+       /** Reads in the element structure and creates a clip out of it.*/
+    // Returns an XML document that describes part of the current scene.
+    virtual QDomDocument sceneToXML(const GenTime & startTime,
+       const GenTime & endTime) const = 0;
+       /** returns a QString containing all of the XML data required to recreate this clip. */
+    virtual QDomDocument toXML() const;
+    virtual QDomDocument generateSceneList(bool addProducers = true, bool rendering = false) const;
+
+       /** Returns true if the xml passed matches the values in this clip */
+    virtual bool matchesXML(const QDomElement & element) const = 0;
+
+    void addReference() {
+       ++m_refcount;
+    }
+    void removeReference() {
+       --m_refcount;
+    }
+    uint numReferences() const {
+       return m_refcount;
+    }
+       /** Returns true if this clip has a meaningful filesize. */
+       virtual bool hasFileSize() const = 0;
+
+       /** Returns the filesize, or 0 if there is no appropriate filesize. */
+    virtual uint fileSize() const = 0;
+
+       /** Returns true if this clip refers to the clip passed in. A clip refers to another clip if
+        * it uses it as part of it's own composition. */
+    virtual bool referencesClip(DocClipBase * clip) const = 0;
+
+       /** Sets the thumbnail to be used by this clip */
+    void setThumbnail(const QPixmap & pixmap);
+
+       /** Returns the thumbnail used by this clip */
+    const QPixmap & thumbnail() const;
+
+    static DocClipBase *createClip(KdenliveDoc *doc, const QDomElement & element);
+    /** Cache for every audio Frame with 10 Bytes */
+    /** format is frame -> channel ->bytes */
+    QMap<int,QMap<int,QByteArray> > audioFrameChache;
+
+       /** return english name for clip type */
+    static QString getTypeName(CLIPTYPE type);
+
+  private:                     // Private attributes
+       /** The name of this clip */
+    QString m_name;
+       /** A description of this clip */
+    QString m_description;
+       /** The number of times this clip is used in the project - the number of references to this clip
+        * that exist. */
+    uint m_refcount;
+
+       /** A list of snap markers; these markers are added to a clips snap-to points, and are displayed as necessary. */
+    QList < CommentedTime > m_snapMarkers;
+
+
+       /** A thumbnail for this clip */
+    QPixmap m_thumbnail;
+    
+    /** a unique numeric id */
+    uint m_id;
+    uint m_projectThumbFrame;
+    void setAudioThumbCreated(bool isDone);
+
+  public slots:
+       void updateAudioThumbnail(QMap<int,QMap<int,QByteArray> > data);
+       QList < CommentedTime > commentedSnapMarkers() const;
+       void setSnapMarkers(QList < CommentedTime > markers);
+       GenTime findNextSnapMarker(const GenTime & currTime);
+       GenTime findPreviousSnapMarker(const GenTime & currTime);
+       GenTime hasSnapMarkers(const GenTime & time);
+       QString deleteSnapMarker(const GenTime & time);
+       void editSnapMarker(const GenTime & time, QString comment);
+       void addSnapMarker(const GenTime & time, QString comment);
+       QList < GenTime > snapMarkers() const;
+       QString markerComment(GenTime t);
+       void setProjectThumbFrame( const uint &ix);
+       uint getProjectThumbFrame() const;
+};
+
+#endif
diff --git a/src/gentime.cpp b/src/gentime.cpp
new file mode 100644 (file)
index 0000000..a962e20
--- /dev/null
@@ -0,0 +1,54 @@
+/***************************************************************************
+                          time.cpp  -  description
+                             -------------------
+    begin                : Sat Sep 14 2002
+    copyright            : (C) 2002 by Jason Wood
+    email                : jasonwood@blueyonder.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "gentime.h"
+
+double GenTime::s_delta = 0.00001;
+
+/** Creates a time object, with a time of 0 seconds. */
+GenTime::GenTime()
+{
+    m_time = 0.0;
+}
+
+/** Creates a time object, with time given in seconds. */
+GenTime::GenTime(double seconds)
+{
+    m_time = seconds;
+}
+
+/** Creates a time object, by passing number of frames and how many frames per second */
+GenTime::GenTime(int frames, double framesPerSecond)
+{
+    m_time = (double) frames / framesPerSecond;
+}
+
+/** Returns the time, in milliseconds */
+double GenTime::ms() const
+{
+    return m_time * 1000;
+}
+
+/** Returns the time in frames, after being given the number of frames per second */
+double GenTime::frames(double framesPerSecond) const
+{
+    return (int) floor(m_time * framesPerSecond + 0.5);
+}
+
+GenTime::~GenTime()
+{
+}
diff --git a/src/gentime.h b/src/gentime.h
new file mode 100644 (file)
index 0000000..65e06d3
--- /dev/null
@@ -0,0 +1,104 @@
+/***************************************************************************
+                          time.h  -  description
+                             -------------------
+    begin                : Sat Sep 14 2002
+    copyright            : (C) 2002 by Jason Wood
+    email                : jasonwood@blueyonder.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef GENTIME_H
+#define GENTIME_H
+
+#include <cmath>
+
+/**Encapsulates a time, which can be set in various forms and outputted in various forms.
+  *@author Jason Wood
+  */
+
+class GenTime {
+  public:
+       /** Creates a time object, with a time of 0 seconds. */
+    GenTime();
+
+       /** Creates a time object, with time given in seconds. */
+    explicit GenTime(double seconds);
+
+       /** Creates a time object, by passing number of frames and how many frames per second */
+     GenTime(int frames, double framesPerSecond);
+
+       /** returns the time, in seconds */
+    double seconds() const {
+       return m_time;
+    }
+       /** Returns the time, in milliseconds */ double ms() const;
+
+       /** Returns the time in frames, after being given the number of frames per second */
+    double frames(double framesPerSecond) const;
+
+     GenTime & operator+=(GenTime op) {
+       m_time += op.m_time;
+       return *this;
+    }
+       /** Adds two GenTimes */ GenTime operator+(GenTime op) const {
+       return GenTime(m_time + op.m_time);
+    }
+       /** Subtracts one genTime from another */ GenTime operator-(GenTime op) const {
+       return GenTime(m_time - op.m_time);
+    }
+       /** Multiplies one GenTime by a double value, returning a GenTime */
+       GenTime operator*(double op) const {
+       return GenTime(m_time * op);
+    }
+       /** Divides one GenTime by a double value, returning a GenTime */
+       GenTime operator/(double op) const {
+       return GenTime(m_time / op);
+    }
+    /* Implementation of < operator; Works identically as with basic types. */
+       bool operator<(GenTime op) const {
+       return m_time + s_delta < op.m_time;
+    }
+    /* Implementation of > operator; Works identically as with basic types. */
+       bool operator>(GenTime op) const {
+       return m_time > op.m_time + s_delta;
+    }
+    /* Implementation of >= operator; Works identically as with basic types. */
+       bool operator>=(GenTime op) const {
+       return m_time + s_delta >= op.m_time;
+    }
+    /* Implementation of <= operator; Works identically as with basic types. */
+       bool operator<=(GenTime op) const {
+       return m_time <= op.m_time + s_delta;
+    }
+    /* Implementation of == operator; Works identically as with basic types. */
+       bool operator==(GenTime op) const {
+       return fabs(m_time - op.m_time) < s_delta;
+    }
+    /* Implementation of != operator; Works identically as with basic types. */
+       bool operator!=(GenTime op) const {
+       return fabs(m_time - op.m_time) >= s_delta;
+    }
+    /* Rounds the GenTIme's value to the nearest frame */
+       GenTime & roundNearestFrame(double framesPerSecond) {
+       m_time = floor((m_time * framesPerSecond) + 0.5) / framesPerSecond;
+       return *this;
+    }
+
+    ~GenTime();
+  private:                     // Private attributes
+  /** Holds the time for this object. */
+    double m_time;
+
+  /** A delta value that is used to get around floating point rounding issues. */
+    static double s_delta;
+};
+
+#endif
diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp
new file mode 100644 (file)
index 0000000..2792e45
--- /dev/null
@@ -0,0 +1,72 @@
+/***************************************************************************
+                        kdenlivedoc.cpp  -  description
+                           -------------------
+  begin                : Fri Nov 22 2002
+  copyright            : (C) 2002 by Jason Wood
+  email                : jasonwood@blueyonder.co.uk
+  copyright            : (C) 2005 Lucio Flavio Correa
+  email                : lucio.correa@gmail.com
+  copyright            : (C) Marco Gittler
+  email                : g.marco@freenet.de
+  copyright            : (C) 2006 Jean-Baptiste Mardelle
+  email                : jb@ader.ch
+
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+
+#include <KDebug>
+#include <KStandardDirs>
+#include <KMessageBox>
+#include <KLocale>
+#include <KFileDialog>
+#include <KIO/NetAccess>
+
+
+#include "kdenlivedoc.h"
+
+KdenliveDoc::KdenliveDoc(KUrl url, double fps, int width, int height, QWidget *parent):QObject(parent), m_url(url), m_projectName(NULL)
+{
+  if (!url.isEmpty()) {
+    QString tmpFile;
+    if(KIO::NetAccess::download(url.path(), tmpFile, parent))
+  {
+    QFile file(tmpFile);
+    m_document.setContent(&file, false);
+    file.close();
+    m_projectName = url.fileName();
+    KIO::NetAccess::removeTempFile(tmpFile);
+  }
+  else
+  {
+    KMessageBox::error(parent, 
+        KIO::NetAccess::lastErrorString());
+  }
+  }
+}
+
+KdenliveDoc::~KdenliveDoc()
+{
+}
+
+QString KdenliveDoc::documentName()
+{
+  return m_projectName;
+}
+
+QDomNodeList KdenliveDoc::producersList()
+{
+  return m_document.elementsByTagName("producer");
+}
+
+#include "kdenlivedoc.moc"
+
diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h
new file mode 100644 (file)
index 0000000..a8040a5
--- /dev/null
@@ -0,0 +1,49 @@
+/***************************************************************************
+                         krender.h  -  description
+                            -------------------
+   begin                : Fri Nov 22 2002
+   copyright            : (C) 2002 by Jason Wood
+   email                : jasonwood@blueyonder.co.uk
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef KDENLIVEDOC_H
+#define KDENLIVEDOC_H
+
+#include <qdom.h>
+#include <qstring.h>
+#include <qmap.h>
+#include <QList>
+#include <QObject>
+
+#include <kurl.h>
+
+#include "gentime.h"
+
+
+class KdenliveDoc:public QObject {
+  Q_OBJECT public:
+
+    KdenliveDoc(KUrl url, double fps, int width, int height, QWidget *parent = 0);
+    ~KdenliveDoc();
+    QString documentName();
+    QDomNodeList producersList();
+
+  private:
+    KUrl m_url;
+    QDomDocument m_document;
+    QString m_projectName;
+
+  public slots:
+    
+};
+
+#endif
diff --git a/src/kdenliveui.rc b/src/kdenliveui.rc
new file mode 100644 (file)
index 0000000..f8d6be5
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<gui name="kdenlive" version="1">
+  <ToolBar name="mainToolBar" >
+    <text>Main Toolbar</text>
+    <Action name="clear" />
+  </ToolBar>
+  <MenuBar>
+    <Menu name="file" >
+      <Action name="clear" />
+    </Menu>
+  </MenuBar>
+</gui>
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644 (file)
index 0000000..cbfa0c2
--- /dev/null
@@ -0,0 +1,33 @@
+#include <KApplication>
+#include <KAboutData>
+#include <KCmdLineArgs>
+#include <KUrl> //new
+#include "mainwindow.h"
+int main (int argc, char *argv[])
+{
+  KAboutData aboutData( "Kdenlive", "kdenlive",
+      ki18n("Kdenlive"), "1.0",
+      ki18n("A simple text area which can load and save."),
+      KAboutData::License_GPL,
+      ki18n("Copyright (c) 2007 Developer") );
+  KCmdLineArgs::init( argc, argv, &aboutData );
+  KCmdLineOptions options; //new
+  options.add("+[file]", ki18n("Document to open")); //new
+  KCmdLineArgs::addCmdLineOptions(options); //new
+  KApplication app;
+  MainWindow* window = new MainWindow();
+  window->show();
+  KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); //new
+  if(args->count()) //new
+  {
+    window->openFile(args->url(0).url()); //new
+  }
+  return app.exec();
+}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
new file mode 100644 (file)
index 0000000..3d5c8e3
--- /dev/null
@@ -0,0 +1,173 @@
+
+#include <KApplication>
+#include <KAction>
+#include <KLocale>
+#include <KActionCollection>
+#include <KStandardAction>
+#include <KFileDialog>
+#include <KMessageBox>
+#include <KDebug>
+#include <KIO/NetAccess>
+#include <KSaveFile>
+#include <KRuler>
+#include <QTextStream>
+
+#include <mlt++/Mlt.h>
+
+#include "mainwindow.h"
+#include "trackview.h"
+MainWindow::MainWindow(QWidget *parent)
+    : KXmlGuiWindow(parent),
+      fileName(QString())
+{
+  m_timelineArea = new KTabWidget(this);
+  m_timelineArea->setHoverCloseButton(true);
+  m_timelineArea->setTabReorderingEnabled(true);
+  connect(m_timelineArea, SIGNAL(currentChanged (int)), this, SLOT(activateDocument()));
+  setCentralWidget(m_timelineArea);
+
+  projectListDock = new QDockWidget(i18n("Project Tree"), this);
+  m_projectList = new ProjectList(NULL, this);
+  projectListDock->setWidget(m_projectList);
+  addDockWidget(Qt::TopDockWidgetArea, projectListDock);
+
+  effectListDock = new QDockWidget(i18n("Effect List"), this);
+  effectList = new KListWidget(this);
+  effectListDock->setWidget(effectList);
+  addDockWidget(Qt::TopDockWidgetArea, effectListDock);
+  
+  effectStackDock = new QDockWidget(i18n("Effect Stack"), this);
+  effectStack = new KListWidget(this);
+  effectStackDock->setWidget(effectStack);
+  addDockWidget(Qt::TopDockWidgetArea, effectStackDock);
+  
+  transitionConfigDock = new QDockWidget(i18n("Transition"), this);
+  transitionConfig = new KListWidget(this);
+  transitionConfigDock->setWidget(transitionConfig);
+  addDockWidget(Qt::TopDockWidgetArea, transitionConfigDock);
+
+  Mlt::Factory::init(NULL);
+
+  clipMonitorDock = new QDockWidget(i18n("Clip Monitor"), this);
+  m_clipMonitor = new Monitor("clip", this);
+  clipMonitorDock->setWidget(m_clipMonitor);
+  addDockWidget(Qt::TopDockWidgetArea, clipMonitorDock);
+
+  projectMonitorDock = new QDockWidget(i18n("Project Monitor"), this);
+  m_projectMonitor = new Monitor("project", this);
+  projectMonitorDock->setWidget(m_projectMonitor);
+  addDockWidget(Qt::TopDockWidgetArea, projectMonitorDock);
+
+  setupActions();
+  tabifyDockWidget (effectListDock, projectListDock);
+  tabifyDockWidget (effectListDock, effectStackDock);
+  tabifyDockWidget (effectListDock, transitionConfigDock);
+
+  tabifyDockWidget (clipMonitorDock, projectMonitorDock);
+
+  connect(m_projectList, SIGNAL(clipSelected(const QDomElement &)), m_projectMonitor, SLOT(slotSetXml(const QDomElement &)));
+
+  connect(m_projectList, SIGNAL(getFileProperties(const KUrl &, uint)), m_projectMonitor->render, SLOT(getFileProperties(const KUrl &, uint)));
+
+  connect(m_projectMonitor->render, SIGNAL(replyGetImage(const KUrl &, int, const QPixmap &, int, int)), m_projectList, SLOT(slotReplyGetImage(const KUrl &, int, const QPixmap &, int, int)));
+
+  connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QMap < QString, QString > &, const QMap < QString, QString > &)), m_projectList, SLOT(slotReplyGetFileProperties(const QMap < QString, QString > &, const QMap < QString, QString > &)));
+
+}
+void MainWindow::setupActions()
+{
+  KAction* clearAction = new KAction(this);
+  clearAction->setText(i18n("Clear"));
+  clearAction->setIcon(KIcon("document-new"));
+  clearAction->setShortcut(Qt::CTRL + Qt::Key_W);
+  actionCollection()->addAction("clear", clearAction);
+  /*connect(clearAction, SIGNAL(triggered(bool)),
+          textArea, SLOT(clear()));*/
+  KStandardAction::quit(kapp, SLOT(quit()),
+                        actionCollection());
+  KStandardAction::open(this, SLOT(openFile()),
+                        actionCollection());
+  KStandardAction::save(this, SLOT(saveFile()),
+                        actionCollection());
+  KStandardAction::saveAs(this, SLOT(saveFileAs()),
+                        actionCollection());
+  KStandardAction::openNew(this, SLOT(newFile()),
+                        actionCollection());
+  setupGUI();
+}
+void MainWindow::newFile()
+{
+  KdenliveDoc *doc = new KdenliveDoc(KUrl(), 25, 720, 576);
+  TrackView *trackView = new TrackView(doc);
+  m_timelineArea->addTab(trackView, "New Project");
+}
+
+void MainWindow::activateDocument()
+{
+  TrackView *currentTab = (TrackView *) m_timelineArea->currentWidget();
+  KdenliveDoc *currentDoc = currentTab->document();
+  connectDocument(currentDoc);
+}
+void MainWindow::saveFileAs(const QString &outputFileName)
+{
+  KSaveFile file(outputFileName);
+  file.open();
+  
+  QByteArray outputByteArray;
+  //outputByteArray.append(textArea->toPlainText());
+  file.write(outputByteArray);
+  file.finalize();
+  file.close();
+  
+  fileName = outputFileName;
+}
+void MainWindow::saveFileAs()
+{
+  saveFileAs(KFileDialog::getSaveFileName());
+}
+void MainWindow::saveFile()
+{
+  if(!fileName.isEmpty())
+  {
+    saveFileAs(fileName);
+  }
+  else
+  {
+    saveFileAs();
+  }
+}
+void MainWindow::openFile() //changed
+{
+  openFile(KFileDialog::getOpenFileName(KUrl(), "application/vnd.kde.kdenlive"));
+}
+void MainWindow::openFile(const QString &inputFileName) //new
+{
+  KdenliveDoc *doc = new KdenliveDoc(KUrl(inputFileName), 25, 720, 576);
+  TrackView *trackView = new TrackView(doc);
+  m_timelineArea->setCurrentIndex(m_timelineArea->addTab(trackView, QIcon(), doc->documentName()));
+  connectDocument(doc);
+  
+}
+
+void MainWindow::connectDocument(KdenliveDoc *doc) //changed
+{
+  m_projectList->populate(doc->producersList());
+  //connect(doc, SIGNAL(addClip(QDomElement &)), m_projectList, SLOT(slotAddClip(QDomElement &)));
+}
+
+#include "mainwindow.moc"
diff --git a/src/mainwindow.h b/src/mainwindow.h
new file mode 100644 (file)
index 0000000..18e1cf2
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+#include <QDockWidget>
+
+#include <KXmlGuiWindow>
+#include <KTextEdit>
+#include <KListWidget>
+#include <KTabWidget>
+
+#include "projectlist.h"
+#include "monitor.h"
+#include "kdenlivedoc.h"
+
+class MainWindow : public KXmlGuiWindow
+{
+  Q_OBJECT
+  
+  public:
+    MainWindow(QWidget *parent=0);
+    void openFile(const QString &inputFileName);
+  
+  private:
+    KTabWidget* m_timelineArea;
+    void setupActions();
+    QString fileName;
+
+    QDockWidget *projectListDock;
+    ProjectList *m_projectList;
+
+    QDockWidget *effectListDock;
+    KListWidget *effectList;
+
+    QDockWidget *effectStackDock;
+    KListWidget *effectStack;
+
+    QDockWidget *transitionConfigDock;
+    KListWidget *transitionConfig;
+
+    QDockWidget *clipMonitorDock;
+    Monitor *m_clipMonitor;
+
+    QDockWidget *projectMonitorDock;
+    Monitor *m_projectMonitor;
+  private slots:
+    void newFile();
+    void activateDocument();
+    void connectDocument(KdenliveDoc*);
+    void openFile();
+    void saveFile();
+    void saveFileAs();
+    void saveFileAs(const QString &outputFileName);
+};
+#endif
diff --git a/src/monitor.cpp b/src/monitor.cpp
new file mode 100644 (file)
index 0000000..bd56f1a
--- /dev/null
@@ -0,0 +1,66 @@
+
+#include <QMouseEvent>
+#include <QStylePainter>
+
+#include <KDebug>
+#include <KLocale>
+
+#include "gentime.h"
+#include "monitor.h"
+
+Monitor::Monitor(QString name, QWidget *parent)
+    : QWidget(parent)
+{
+  ui.setupUi(this);
+  if (name == "project") {
+  render = new Render(name, this);
+  render->createVideoXWindow(ui.video_frame->winId(), -1);
+  connect(ui.button_play, SIGNAL(clicked()), this, SLOT(slotOpen()));
+  connect(ui.button_rew, SIGNAL(clicked()), this, SLOT(slotRewind()));
+  connect(ui.button_play_2, SIGNAL(clicked()), this, SLOT(slotPlay()));
+  }
+}
+
+void Monitor::slotOpen()
+{
+
+render->mltInsertClip(2, GenTime(1, 25), QString("<westley><producer mlt_service=\"colour\" colour=\"red\" in=\"1\" out=\"30\" /></westley>"));
+render->mltInsertClip(2, GenTime(0, 25), QString("<westley><producer mlt_service=\"avformat\" resource=\"/home/one/.vids/clip3e.mpg\" in=\"1\" out=\"300\" /></westley>"));
+}
+
+void Monitor::slotRewind()
+{
+  render->seek(GenTime(0));
+
+}
+
+void Monitor::slotPlay()
+{
+  render->switchPlay();
+}
+
+void Monitor::slotSetXml(const QDomElement &e)
+{
+    QDomDocument doc;
+    QDomElement westley = doc.createElement("westley");
+    doc.appendChild(westley);
+    westley.appendChild(e);
+    render->setSceneList(doc, 0);
+}
+
+
+void Monitor::slotOpenFile(const QString &file)
+{
+    QDomDocument doc;
+    QDomElement westley = doc.createElement("westley");
+    doc.appendChild(westley);
+    QDomElement prod = doc.createElement("producer");
+    westley.appendChild(prod);
+    prod.setAttribute("mlt_service", "avformat");
+    prod.setAttribute("resource", file);
+    render->setSceneList(doc, 0);
+}
+
+
+
+#include "monitor.moc"
diff --git a/src/monitor.h b/src/monitor.h
new file mode 100644 (file)
index 0000000..9ca51b9
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef MONITOR_H
+#define MONITOR_H
+
+#include <KListWidget>
+#include "ui_monitor_ui.h"
+#include "renderer.h"
+
+class Monitor : public QWidget
+{
+  Q_OBJECT
+  
+  public:
+    Monitor(QString name, QWidget *parent=0);
+    Render *render;
+
+  private:
+    Ui::Monitor_UI ui;
+
+  private slots:
+    void slotPlay();
+    void slotOpen();
+    void slotRewind();
+
+  public slots:
+    void slotOpenFile(const QString &);
+    void slotSetXml(const QDomElement &e);
+};
+
+#endif
diff --git a/src/projectitem.cpp b/src/projectitem.cpp
new file mode 100644 (file)
index 0000000..97595eb
--- /dev/null
@@ -0,0 +1,178 @@
+
+#include <QMouseEvent>
+#include <QStylePainter>
+#include <QLabel>
+#include <QLayout>
+
+#include <KDebug>
+#include <KLocale>
+
+
+#include "projectitem.h"
+#include "timecode.h"
+
+  const int NameRole = Qt::UserRole;
+  const int DurationRole = NameRole + 1;
+  const int FullPathRole = NameRole + 2;
+  const int ClipTypeRole = NameRole + 3;
+
+ProjectItem::ProjectItem(QTreeWidget * parent, const QStringList & strings, QDomElement xml, int type)
+    : QTreeWidgetItem(parent, strings, type), m_element(xml), m_clipType(DocClipBase::NONE)
+{
+  setSizeHint(0, QSize(65, 45));
+  setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled);
+  QString cType = m_element.attribute("type", 0);
+  if (!cType.isEmpty()) {
+    m_clipType = (DocClipBase::CLIPTYPE) cType.toInt();
+    slotSetToolTip();
+  }
+  
+}
+
+ProjectItem::~ProjectItem()
+{
+}
+
+QDomElement ProjectItem::toXml()
+{
+    return m_element;
+}
+
+void ProjectItem::slotSetToolTip()
+{
+  QString tip = "<qt><b>";
+  switch (m_clipType) {
+    case 1:
+      tip.append(i18n("Audio clip"));
+      break;
+    case 2:
+      tip.append(i18n("Mute video clip"));
+      break;
+    case 3:
+      tip.append(i18n("Video clip"));
+      break;
+    case 4:
+      tip.append(i18n("Color clip"));
+      break;
+    case 5:
+      tip.append(i18n("Image clip"));
+      break;
+    case 6:
+      tip.append(i18n("Text clip"));
+      break;
+    case 7:
+      tip.append(i18n("Slideshow clip"));
+      break;
+    case 8:
+      tip.append(i18n("Virtual clip"));
+      break;
+    case 9:
+      tip.append(i18n("Playlist clip"));
+      break;
+    default:
+      tip.append(i18n("Unknown clip"));
+    break;
+  }
+
+  setToolTip(1, tip);
+}
+
+void ProjectItem::setProperties(const QMap < QString, QString > &attributes, const QMap < QString, QString > &metadata)
+{
+       if (attributes.contains("duration")) {
+           m_duration = GenTime(attributes["duration"].toInt(), 25);
+           setData(1, DurationRole, Timecode::getEasyTimecode(m_duration, 25));
+           m_durationKnown = true;
+       } else {
+           // No duration known, use an arbitrary one until it is.
+           m_duration = GenTime(0.0);
+           m_durationKnown = false;
+       }
+
+
+       //extend attributes -reh
+       if (attributes.contains("type")) {
+           if (attributes["type"] == "audio")
+               m_clipType = DocClipBase::AUDIO;
+           else if (attributes["type"] == "video")
+               m_clipType = DocClipBase::VIDEO;
+           else if (attributes["type"] == "av")
+               m_clipType = DocClipBase::AV;
+           else if (attributes["type"] == "playlist")
+               m_clipType = DocClipBase::PLAYLIST;
+       } else {
+           m_clipType = DocClipBase::AV;
+       }
+       slotSetToolTip();
+
+       if (m_element.isNull()) {
+         QDomDocument doc;
+         m_element = doc.createElement("producer");
+         m_element.setAttribute("resource", attributes["filename"]);
+         m_element.setAttribute("type", (int) m_clipType);
+        }
+/*
+       if (attributes.contains("height")) {
+           m_height = attributes["height"].toInt();
+       } else {
+           m_height = 0;
+       }
+       if (attributes.contains("width")) {
+           m_width = attributes["width"].toInt();
+       } else {
+           m_width = 0;
+       }
+       //decoder name
+       if (attributes.contains("name")) {
+           m_decompressor = attributes["name"];
+       } else {
+           m_decompressor = "n/a";
+       }
+       //video type ntsc/pal
+       if (attributes.contains("system")) {
+           m_system = attributes["system"];
+       } else {
+           m_system = "n/a";
+       }
+       if (attributes.contains("fps")) {
+           m_framesPerSecond = attributes["fps"].toInt();
+       } else {
+           // No frame rate known.
+           m_framesPerSecond = 0;
+       }
+       //audio attributes -reh
+       if (attributes.contains("channels")) {
+           m_channels = attributes["channels"].toInt();
+       } else {
+           m_channels = 0;
+       }
+       if (attributes.contains("format")) {
+           m_format = attributes["format"];
+       } else {
+           m_format = "n/a";
+       }
+       if (attributes.contains("frequency")) {
+           m_frequency = attributes["frequency"].toInt();
+       } else {
+           m_frequency = 0;
+       }
+       if (attributes.contains("videocodec")) {
+           m_videoCodec = attributes["videocodec"];
+       }
+       if (attributes.contains("audiocodec")) {
+           m_audioCodec = attributes["audiocodec"];
+       }
+
+       m_metadata = metadata;
+
+       if (m_metadata.contains("description")) {
+           setDescription (m_metadata["description"]);
+       }
+       else if (m_metadata.contains("comment")) {
+           setDescription (m_metadata["comment"]);
+       }
+*/
+
+}
+
+#include "projectitem.moc"
diff --git a/src/projectitem.h b/src/projectitem.h
new file mode 100644 (file)
index 0000000..e38d30b
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef PROJECTITEM_H
+#define PROJECTITEM_H
+
+#include <QTreeWidgetItem>
+#include <QTreeWidget>
+#include <QDomElement>
+
+#include "gentime.h"
+#include "docclipbase.h"
+
+
+class ProjectItem : public QTreeWidgetItem
+{
+  public:
+    ProjectItem(QTreeWidget * parent, const QStringList & strings, QDomElement xml = QDomElement(), int type = QTreeWidgetItem::UserType);
+    ~ProjectItem();
+    QDomElement toXml();
+
+    void setProperties(const QMap < QString, QString > &attributes, const QMap < QString, QString > &metadata);
+
+  private:
+    QDomElement m_element;
+    GenTime m_duration;
+    bool m_durationKnown;
+    DocClipBase::CLIPTYPE m_clipType;
+    void slotSetToolTip();
+};
+
+#endif
diff --git a/src/projectlist.cpp b/src/projectlist.cpp
new file mode 100644 (file)
index 0000000..a68ec1c
--- /dev/null
@@ -0,0 +1,199 @@
+
+#include <QMouseEvent>
+#include <QStylePainter>
+#include <QPixmap>
+#include <QIcon>
+
+#include <KDebug>
+#include <KLocale>
+#include <KFileDialog>
+#include <klistwidgetsearchline.h>
+
+#include "projectlist.h"
+#include "projectitem.h"
+
+#include <QtGui>
+
+  const int NameRole = Qt::UserRole;
+  const int DurationRole = NameRole + 1;
+  const int FullPathRole = NameRole + 2;
+  const int ClipTypeRole = NameRole + 3;
+
+class ItemDelegate: public QItemDelegate
+{
+  public:
+    ItemDelegate(QObject* parent = 0): QItemDelegate(parent)
+    {
+    }
+
+void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+  if (index.column() == 1)
+  {
+    QFont font = painter->font();
+    font.setPointSize(font.pointSize() - 2 );
+    QRect r1 = option.rect;
+    r1.setBottom(r1.y() + (r1.height() *2 / 3 ));
+    QRect r2 = option.rect;
+    r2.setTop(r2.y() + (r2.height() *2 / 3 ));
+    painter->drawText(r1, Qt::AlignLeft | Qt::AlignVCenter , index.data().toString());
+    painter->setPen(Qt::green);
+    painter->drawText(r2, Qt::AlignLeft | Qt::AlignTop , index.data(DurationRole).toString());
+    painter->setPen(Qt::black);
+  }
+  else
+  {
+    QItemDelegate::paint(painter, option, index);
+  }
+}
+};
+
+
+ProjectList::ProjectList(Render *projectRender, QWidget *parent)
+    : QWidget(parent), m_render(projectRender)
+{
+
+  ui.setupUi(this);
+  ui.project_search->setTreeWidget(ui.project_list);
+      QStringList itemEntry;
+      itemEntry.append(QString::null);
+      itemEntry.append("coucou");
+  new ProjectItem(ui.project_list, itemEntry);
+  connect(ui.button_add, SIGNAL(clicked ( bool )), this, SLOT(slotAddClip()));
+  connect(ui.project_list, SIGNAL(itemSelectionChanged()), this, SLOT(slotClipSelected()));
+  connect(ui.project_list, SIGNAL(itemDoubleClicked ( QTreeWidgetItem *, int )), this, SLOT(slotEditClip(QTreeWidgetItem *, int)));
+
+
+  ui.project_list->setItemDelegate(new ItemDelegate(ui.project_list));
+  ui.project_list->setIconSize(QSize(60, 40));
+  ui.project_list->setSortingEnabled (true);
+
+}
+
+void ProjectList::setRenderer(Render *projectRender)
+{
+  m_render = projectRender;
+}
+
+void ProjectList::slotDoubleClicked(QListWidgetItem *item, const QPoint &pos)
+{
+  kDebug()<<" / / / DBL CLICK";
+  if (item) {
+    KUrl url = KFileDialog::getOpenUrl( KUrl(), "video/mpeg");
+  }
+}
+
+void ProjectList::slotClipSelected()
+{
+  ProjectItem *item = (ProjectItem*) ui.project_list->currentItem();
+  if (item) emit clipSelected(item->toXml());
+}
+
+void ProjectList::slotEditClip(QTreeWidgetItem *item, int column)
+{
+  if (column != 2){
+    return;
+  }
+}
+
+void ProjectList::slotAddClip()
+{
+   
+  KUrl::List list = KFileDialog::getOpenUrls( KUrl(), "application/vnd.kde.kdenlive application/vnd.westley.scenelist application/flv application/vnd.rn-realmedia video/x-dv video/x-msvideo video/mpeg video/x-ms-wmv audio/x-mp3 audio/x-wav application/ogg *.m2t *.dv video/mp4 video/quicktime image/gif image/jpeg image/png image/x-bmp image/svg+xml image/tiff image/x-xcf-gimp image/x-vnd.adobe.photoshop image/x-pcx image/x-exr");
+
+  KUrl::List::Iterator it;
+  KUrl url;
+       
+  for (it = list.begin(); it != list.end(); it++) {
+      QStringList itemEntry;
+      itemEntry.append(QString::null);
+      itemEntry.append((*it).fileName());
+      ProjectItem *item = new ProjectItem(ui.project_list, itemEntry, QDomElement());
+      item->setData(1, FullPathRole, (*it).path());
+      emit getFileProperties((*it), 0);
+  }
+
+}
+
+void ProjectList::populate(QDomNodeList prods)
+{
+  ui.project_list->clear();
+  for (int i = 0; i <  prods.count () ; i++)
+  {
+    addProducer(prods.item(i).toElement());
+  }
+}
+
+void ProjectList::slotReplyGetFileProperties(const QMap < QString, QString > &properties, const QMap < QString, QString > &metadata)
+{
+  QTreeWidgetItem *parent = 0;
+  int count =
+    parent ? parent->childCount() : ui.project_list->topLevelItemCount();
+
+  for (int i = 0; i < count; i++)
+  {
+    QTreeWidgetItem *item =
+      parent ? parent->child(i) : ui.project_list->topLevelItem(i);
+
+    if (item->data(1, FullPathRole).toString() == properties["filename"]) {
+      ((ProjectItem *) item)->setProperties(properties, metadata);
+      break;
+    }
+  }
+}
+
+
+void ProjectList::slotReplyGetImage(const KUrl &url, int pos, const QPixmap &pix, int w, int h)
+{
+   QTreeWidgetItem *parent = 0;
+  int count =
+    parent ? parent->childCount() : ui.project_list->topLevelItemCount();
+
+  for (int i = 0; i < count; i++)
+  {
+    QTreeWidgetItem *item =
+      parent ? parent->child(i) : ui.project_list->topLevelItem(i);
+
+    if (item->data(1, FullPathRole).toString() == url.path()) {
+      item->setIcon(0,pix);
+      break;
+    }
+  }
+
+}
+
+
+void ProjectList::addProducer(QDomElement producer)
+{
+  DocClipBase::CLIPTYPE type = (DocClipBase::CLIPTYPE) producer.attribute("type").toInt();
+  
+  if (type == DocClipBase::AUDIO || type == DocClipBase::VIDEO || type == DocClipBase::AV)
+  {
+    KUrl resource = KUrl(producer.attribute("resource"));
+    if (!resource.isEmpty()) {
+      QStringList itemEntry;
+      itemEntry.append(QString::null);
+      itemEntry.append(resource.fileName());
+      ProjectItem *item = new ProjectItem(ui.project_list, itemEntry, producer);
+      //item->setIcon(0, Render::getVideoThumbnail(resource, 0, 60, 40));
+      item->setData(1, FullPathRole, resource.path());
+      item->setData(1, ClipTypeRole, (int) type);
+      emit getFileProperties(resource, producer.attribute("frame_thumbnail", 0).toInt());
+    }
+  }
+  else if (type == DocClipBase::COLOR) {
+    QString colour = producer.attribute("colour");
+    QPixmap pix(60, 40);
+    colour = colour.replace(0, 2, "#");
+    pix.fill(QColor(colour.left(7)));
+    QStringList itemEntry;
+    itemEntry.append(QString::null);
+    itemEntry.append(i18n("Color Clip"));
+    ProjectItem *item = new ProjectItem(ui.project_list, itemEntry, producer);
+    item->setIcon(0, QIcon(pix));
+    item->setData(1, ClipTypeRole, (int) type);
+  }
+      
+}
+
+#include "projectlist.moc"
diff --git a/src/projectlist.h b/src/projectlist.h
new file mode 100644 (file)
index 0000000..34ac7f9
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef PRJECTLIST_H
+#define PRJECTLIST_H
+
+#include <QDomNodeList>
+#include <QTreeWidget>
+
+#include "ui_projectlist_ui.h"
+#include "docclipbase.h"
+#include "renderer.h"
+
+class ProjectList : public QWidget
+{
+  Q_OBJECT
+  
+  public:
+    ProjectList(Render *projectRender, QWidget *parent=0);
+
+  public slots:
+    void populate(QDomNodeList prods);
+    void addProducer(QDomElement producer);
+    void setRenderer(Render *projectRender);
+    void slotReplyGetImage(const KUrl &url, int pos, const QPixmap &pix, int w, int h);
+    void slotReplyGetFileProperties(const QMap < QString, QString > &properties, const QMap < QString, QString > &metadata);
+
+  private:
+    Ui::ProjectList_UI ui;
+    Render *m_render;
+
+  private slots:
+    void slotDoubleClicked(QListWidgetItem *, const QPoint &);
+    void slotAddClip();
+    void slotEditClip(QTreeWidgetItem *item, int column);
+    void slotClipSelected();
+
+  signals:
+    void clipSelected(const QDomElement &);
+    void getFileProperties(const KUrl &, uint);
+};
+
+#endif
diff --git a/src/renderer.cpp b/src/renderer.cpp
new file mode 100644 (file)
index 0000000..32b328e
--- /dev/null
@@ -0,0 +1,1389 @@
+/***************************************************************************
+                        krender.cpp  -  description
+                           -------------------
+  begin                : Fri Nov 22 2002
+  copyright            : (C) 2002 by Jason Wood
+  email                : jasonwood@blueyonder.co.uk
+  copyright            : (C) 2005 Lucio Flavio Correa
+  email                : lucio.correa@gmail.com
+  copyright            : (C) Marco Gittler
+  email                : g.marco@freenet.de
+  copyright            : (C) 2006 Jean-Baptiste Mardelle
+  email                : jb@ader.ch
+
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+// ffmpeg Header files
+
+extern "C" {
+#include <ffmpeg/avformat.h>
+}
+#include <QTimer>
+#include <QDir>
+#include <QApplication>
+#include <QPainter>
+
+#include <KDebug>
+#include <KStandardDirs>
+#include <KMessageBox>
+#include <KLocale>
+
+
+#include <mlt++/Mlt.h>
+
+
+#include "renderer.h"
+
+Render::Render(const QString & rendererName, QWidget *parent):QObject(parent), m_name(rendererName), m_mltConsumer(NULL), m_mltProducer(NULL), m_mltTextProducer(NULL), m_sceneList(QDomDocument()), m_winid(-1), m_framePosition(0), m_generateScenelist(false), isBlocked(true)
+{
+    refreshTimer = new QTimer( this );
+    connect( refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()) );
+
+    m_connectTimer = new QTimer( this );
+    connect( m_connectTimer, SIGNAL(timeout()), this, SLOT(connectPlaylist()) );
+
+    if (rendererName == "project") m_monitorId = 10000;
+    else m_monitorId = 10001;
+    osdTimer = new QTimer( this );
+    connect( osdTimer, SIGNAL(timeout()), this, SLOT(slotOsdTimeout()) );
+
+    m_osdProfile =   KStandardDirs::locate("data", "kdenlive/profiles/metadata.properties");
+    /*m_osdInfo = new Mlt::Filter("data_show");
+    char *tmp = decodedString(m_osdProfile);
+    m_osdInfo->set("resource", tmp);
+    delete[] tmp;*/
+    //      Does it do anything usefull? I mean, RenderThread doesn't do anything useful at the moment
+    //      (except being cpu hungry :)
+
+    /*      if(!s_renderThread) {
+    s_renderThread = new RenderThread;
+    s_renderThread->start();
+    } */
+}
+
+Render::~Render()
+{
+    closeMlt();
+}
+
+
+void Render::closeMlt()
+{
+    delete m_connectTimer;
+    delete osdTimer;
+    delete refreshTimer;
+    if (m_mltConsumer)
+        delete m_mltConsumer;
+    if (m_mltProducer)
+       delete m_mltProducer;
+    //delete m_osdInfo;
+}
+
+
+static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr)
+{
+    // detect if the producer has finished playing. Is there a better way to do it ?
+    //if (self->isBlocked) return;
+    if (mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame_ptr ), "_speed" ) == 0.0) {
+        self->emitConsumerStopped();
+    }
+    else {
+       self->emitFrameNumber(mlt_frame_get_position(frame_ptr));
+    }
+}
+
+/** Wraps the VEML command of the same name; requests that the renderer
+should create a video window. If show is true, then the window should be
+displayed, otherwise it should be hidden. Render will emit the signal
+replyCreateVideoXWindow() once the renderer has replied. */
+
+void Render::createVideoXWindow(WId winid, WId externalMonitor)
+{
+    if (m_mltConsumer) {
+       delete m_mltConsumer;
+    }
+
+    m_mltConsumer = new Mlt::Consumer("sdl_preview");
+    if (!m_mltConsumer || !m_mltConsumer->is_valid()) {
+       KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install.\n Exiting now..."));
+       kError()<<"Sorry, cannot create MLT consumer, check your MLT install you miss SDL libraries support in MLT";
+       exit(1);
+    }
+
+    //only as is saw, if we want to lock something with the sdl lock
+    /*if (!KdenliveSettings::videoprofile().isEmpty()) 
+       m_mltConsumer->set("profile", KdenliveSettings::videoprofile().ascii());*/
+
+    m_mltConsumer->set("profile", "hdv_1080_50i"); //KdenliveSettings::videoprofile().ascii());
+    /*m_mltConsumer->set("app_locked", 1);
+    m_mltConsumer->set("app_lock", (void *) &my_lock, 0);
+    m_mltConsumer->set("app_unlock", (void *) &my_unlock, 0);*/
+    m_externalwinid = (int) externalMonitor;
+    m_winid = (int) winid;
+    
+    m_mltConsumer->set("window_id", m_winid);
+    m_mltConsumer->set("resize", 1);
+    
+    m_mltConsumer->set("terminate_on_pause", 1);
+    /*QString aDevice = KdenliveSettings::audiodevice();
+    if (!KdenliveSettings::videodriver().isEmpty()) m_mltConsumer->set("video_driver", KdenliveSettings::videodriver().ascii());
+    if (!KdenliveSettings::audiodriver().isEmpty()) m_mltConsumer->set("audio_driver", KdenliveSettings::audiodriver().ascii());
+    m_mltConsumer->set("audio_device", aDevice.section(";", 1).ascii());*/
+    m_mltConsumer->set("progressive", 1);
+    m_mltConsumer->set("audio_buffer", 1024);
+    m_mltConsumer->set("frequency", 48000);
+
+    m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+
+    QTimer::singleShot(500, this, SLOT(initSceneList()));
+    //initSceneList();
+//  m_mltConsumer->listen("consumer-stopped", this, (mlt_listener) consumer_stopped);
+//  m_mltConsumer->set("buffer", 25);
+}
+
+
+int Render::resetRendererProfile(char * profile)
+{
+    if (!m_mltConsumer) return 0;
+    if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop();
+    m_mltConsumer->set("refresh", 0);
+    m_mltConsumer->set("profile", profile);
+    kDebug()<<" + + RESET CONSUMER WITH PROFILE: "<<profile;
+    m_fps = 25;
+    m_mltConsumer->set("fps", m_fps);
+    mlt_properties properties = MLT_CONSUMER_PROPERTIES( m_mltConsumer->get_consumer() );
+    int result = mlt_consumer_profile( properties, profile );
+    refresh();
+    return result;
+}
+
+void Render::restartConsumer()
+{
+    if (m_winid != -1) createVideoXWindow( m_winid, m_externalwinid);
+}
+
+/** Wraps the VEML command of the same name; Seeks the renderer clip to the given time. */
+void Render::seek(GenTime time)
+{
+    sendSeekCommand(time);
+    //emit positionChanged(time);
+}
+
+//static
+char *Render::decodedString(QString str)
+{
+    /*QCString fn = QFile::encodeName(str);
+    char *t = new char[fn.length() + 1];
+    strcpy(t, (const char *)fn);*/
+
+  return qstrdup( str.toLatin1().data() );
+}
+
+//static
+QPixmap Render::frameThumbnail(Mlt::Frame *frame, int width, int height, bool border)
+{
+    QPixmap pix(width, height);
+
+    mlt_image_format format = mlt_image_rgb24a;
+    /*if (border) {
+       width = width -2;
+       height = height -2;
+    }*/
+    uint8_t *thumb = frame->get_image(format, width, height);
+    QImage image(thumb, width, height, QImage::Format_ARGB32);
+  
+    if (!image.isNull()) {
+      pix = pix.fromImage(image);
+      if (border) {
+       QPainter painter(&pix);
+       painter.drawRect(0, 0, width - 1, height - 1);
+      }
+       /*if (!border) pix = pix.fromImage(image);
+       //bitBlt(&pix, 0, 0, &image, 0, 0, width, height);
+       else {
+               pix.fill(black);
+               bitBlt(&pix, 1, 1, &image, 0, 0, width, height);
+       }*/
+    }
+    else pix.fill(Qt::black);
+    return pix;
+}
+
+
+QPixmap Render::extractFrame(int frame_position, int width, int height)
+{
+    QPixmap pix(width, height);
+    if (!m_mltProducer) {
+       pix.fill(Qt::black);
+       return pix;
+    }
+    Mlt::Producer *mlt_producer = m_mltProducer->cut(frame_position, frame_position + 1);
+    Mlt::Filter m_convert("avcolour_space");
+    m_convert.set("forced", mlt_image_rgb24a);
+    mlt_producer->attach(m_convert);
+    Mlt::Frame *frame = mlt_producer->get_frame();
+
+    if (frame) {
+       pix = frameThumbnail(frame, width, height);
+       delete frame;
+    }
+    else pix.fill(Qt::black);
+    delete mlt_producer;
+    return pix;
+}
+
+QPixmap Render::getImageThumbnail(KUrl url, int width, int height)
+{
+    QImage im;
+    QPixmap pixmap;
+    if (url.fileName().startsWith(".all.")) {  //  check for slideshow
+           QString fileType = url.fileName().right(3);
+           QStringList more;
+           QStringList::Iterator it;
+
+            QDir dir( url.directory() );
+            more = dir.entryList( QDir::Files );
+            for ( it = more.begin() ; it != more.end() ; ++it ) {
+                if ((*it).endsWith("."+fileType, Qt::CaseInsensitive)) {
+                       im.load(url.directory() + "/" + *it);
+                       break;
+               }
+           }
+    }
+    else im.load(url.path());
+    //pixmap = im.scaled(width, height);
+    return pixmap;
+}
+
+//static
+QPixmap Render::getVideoThumbnail(QString file, int frame_position, int width, int height)
+{
+    QPixmap pix(width, height);
+    char *tmp = decodedString(file);
+    Mlt::Producer m_producer(tmp);
+    delete[] tmp;
+    if (m_producer.is_blank()) {
+       pix.fill(Qt::black);
+       return pix;
+    }
+
+    Mlt::Filter m_convert("avcolour_space");
+    m_convert.set("forced", mlt_image_rgb24a);
+    m_producer.attach(m_convert);
+    m_producer.seek(frame_position);
+    Mlt::Frame * frame = m_producer.get_frame();
+    if (frame) {
+       pix = frameThumbnail(frame, width, height, true);
+       delete frame;
+    }
+    return pix;
+}
+
+
+void Render::getImage(KUrl url, int frame_position, QPoint size)
+{
+    char *tmp = decodedString(url.path());
+    Mlt::Producer m_producer(tmp);
+    delete[] tmp;
+    if (m_producer.is_blank()) {
+       return;
+    }
+    Mlt::Filter m_convert("avcolour_space");
+    m_convert.set("forced", mlt_image_rgb24a);
+    m_producer.attach(m_convert);
+    m_producer.seek(frame_position);
+
+    Mlt::Frame * frame = m_producer.get_frame();
+
+    if (frame) {
+       QPixmap pix = frameThumbnail(frame, size.x(), size.y(), true);
+       delete frame;
+       emit replyGetImage(url, frame_position, pix, size.x(), size.y());
+    }
+}
+
+/* Create thumbnail for color */
+void Render::getImage(int id, QString color, QPoint size)
+{
+    QPixmap pixmap(size.x() - 2, size.y() - 2);
+    color = color.replace(0, 2, "#");
+    color = color.left(7);
+    pixmap.fill(QColor(color));
+    QPixmap result(size.x(), size.y());
+    result.fill(Qt::black);
+    //copyBlt(&result, 1, 1, &pixmap, 0, 0, size.x() - 2, size.y() - 2);
+    emit replyGetImage(id, result, size.x(), size.y());
+
+}
+
+/* Create thumbnail for image */
+void Render::getImage(KUrl url, QPoint size)
+{
+    QImage im;
+    QPixmap pixmap;
+    if (url.fileName().startsWith(".all.")) {  //  check for slideshow
+           QString fileType = url.fileName().right(3);
+           QStringList more;
+           QStringList::Iterator it;
+
+            QDir dir( url.directory() );
+            more = dir.entryList( QDir::Files );
+            for ( it = more.begin() ; it != more.end() ; ++it ) {
+                if ((*it).endsWith("."+fileType, Qt::CaseInsensitive)) {
+                       if (!im.load(url.directory() + "/" + *it))
+                           kDebug()<<"++ ERROR LOADIN IMAGE: "<<url.directory() + "/" + *it;
+                       break;
+               }
+           }
+    }
+    else im.load(url.path());
+
+    //pixmap = im.smoothScale(size.x() - 2, size.y() - 2);
+    QPixmap result(size.x(), size.y());
+    result.fill(Qt::black);
+    //copyBlt(&result, 1, 1, &pixmap, 0, 0, size.x() - 2, size.y() - 2);
+    emit replyGetImage(url, 1, result, size.x(), size.y());
+}
+
+
+double Render::consumerRatio() const
+{
+    if (!m_mltConsumer) return 1.0;
+    return (m_mltConsumer->get_double("aspect_ratio_num")/m_mltConsumer->get_double("aspect_ratio_den"));
+}
+
+
+int Render::getLength()
+{
+
+    if (m_mltProducer) 
+    {
+       kDebug()<<"//////  LENGTH: "<<mlt_producer_get_playtime(m_mltProducer->get_producer());
+       return mlt_producer_get_playtime(m_mltProducer->get_producer());
+    }
+    return 0;
+}
+
+bool Render::isValid(KUrl url)
+{
+    char *tmp = decodedString(url.path());
+    Mlt::Producer producer(tmp);
+    delete[] tmp;
+    if (producer.is_blank())
+       return false;
+
+    return true;
+}
+
+
+void Render::getFileProperties(const KUrl &url, uint framenb)
+{
+        int height = 40;
+        int width = height * 16/9.0; //KdenliveSettings::displayratio();
+       char *tmp = decodedString(url.path());
+       Mlt::Producer producer(tmp);
+       delete[] tmp;
+       if (producer.is_blank()) {
+           return;
+       }
+       producer.seek( framenb );
+       mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer.get_producer() );
+
+       QMap < QString, QString > filePropertyMap;
+        QMap < QString, QString > metadataPropertyMap;
+
+       filePropertyMap["filename"] = url.path();
+       filePropertyMap["duration"] = QString::number(producer.get_playtime());
+        
+        Mlt::Filter m_convert("avcolour_space");
+        m_convert.set("forced", mlt_image_rgb24a);
+        producer.attach(m_convert);
+
+       Mlt::Frame * frame = producer.get_frame();
+
+       if (frame->is_valid()) {
+           filePropertyMap["fps"] =
+               QString::number(mlt_producer_get_fps( producer.get_producer() ));
+           filePropertyMap["width"] =
+               QString::number(frame->get_int("width"));
+           filePropertyMap["height"] =
+               QString::number(frame->get_int("height"));
+           filePropertyMap["frequency"] =
+               QString::number(frame->get_int("frequency"));
+           filePropertyMap["channels"] =
+               QString::number(frame->get_int("channels"));
+
+       // Retrieve audio / video codec name
+
+       // Fetch the video_context
+       AVFormatContext *context = (AVFormatContext *) mlt_properties_get_data( properties, "video_context", NULL );
+       if (context != NULL) {
+               // Get the video_index
+               int index = mlt_properties_get_int( properties, "video_index" );
+               filePropertyMap["videocodec"] = context->streams[ index ]->codec->codec->name;
+       }
+       context = (AVFormatContext *) mlt_properties_get_data( properties, "audio_context", NULL );
+       if (context != NULL) {
+               // Get the video_index
+               int index = mlt_properties_get_int( properties, "audio_index" );
+               filePropertyMap["audiocodec"] = context->streams[ index ]->codec->codec->name;
+       }
+
+
+
+           // metadata
+
+           mlt_properties metadata = mlt_properties_new( );
+           mlt_properties_pass( metadata, properties, "meta.attr." );
+           int count = mlt_properties_count( metadata );
+           for ( int i = 0; i < count; i ++ )
+           {
+               QString name = mlt_properties_get_name( metadata, i );
+               QString value = QString::fromUtf8(mlt_properties_get_value( metadata, i ));
+               if (name.endsWith("markup") && !value.isEmpty())
+                       metadataPropertyMap[ name.section(".", 0, -2) ] = value;
+           }
+
+           if (frame->get_int("test_image") == 0) {
+               if (url.path().endsWith(".westley") || url.path().endsWith(".kdenlive")) {
+                   filePropertyMap["type"] = "playlist";
+                   metadataPropertyMap["comment"] = QString::fromUtf8(mlt_properties_get( MLT_SERVICE_PROPERTIES( producer.get_service() ), "title"));
+               }
+               else if (frame->get_int("test_audio") == 0)
+                   filePropertyMap["type"] = "av";
+               else
+                   filePropertyMap["type"] = "video";
+
+                // Generate thumbnail for this frame
+               QPixmap pixmap = frameThumbnail(frame, width, height, true);
+
+                emit replyGetImage(url, 0, pixmap, width, height);
+
+           } else if (frame->get_int("test_audio") == 0) {
+                QPixmap pixmap(KStandardDirs::locate("appdata", "graphics/music.png"));
+                emit replyGetImage(url, 0, pixmap, width, height);
+               filePropertyMap["type"] = "audio";
+            }
+       }
+       emit replyGetFileProperties(filePropertyMap, metadataPropertyMap);
+       delete frame;
+}
+
+QDomDocument Render::sceneList() const
+{
+    return m_sceneList;
+}
+
+/** Create the producer from the Westley QDomDocument */
+void Render::initSceneList()
+{
+    kDebug()<<"--------  INIT SCENE LIST ------_";
+    QDomDocument doc;
+    QDomElement westley = doc.createElement("westley");
+    doc.appendChild(westley);
+    QDomElement prod = doc.createElement("producer");
+    prod.setAttribute("resource", "colour");
+    prod.setAttribute("colour", "red");
+    prod.setAttribute("id", "black");
+    prod.setAttribute("in", "0");
+    prod.setAttribute("out", "0");
+
+    QDomElement tractor = doc.createElement("tractor");
+    QDomElement multitrack = doc.createElement("multitrack"); 
+
+    QDomElement playlist1 = doc.createElement("playlist");
+    playlist1.appendChild(prod);
+    multitrack.appendChild(playlist1);
+    QDomElement playlist2 = doc.createElement("playlist");
+    multitrack.appendChild(playlist2);
+    QDomElement playlist3 = doc.createElement("playlist");
+    multitrack.appendChild(playlist3);
+    QDomElement playlist4 = doc.createElement("playlist");
+    multitrack.appendChild(playlist4);
+    QDomElement playlist5 = doc.createElement("playlist");
+    multitrack.appendChild(playlist5);
+    tractor.appendChild(multitrack);
+    westley.appendChild(tractor);
+    kDebug()<<doc.toString();
+/*
+   QString tmp = QString("<westley><producer resource=\"colour\" colour=\"red\" id=\"red\" /><tractor><multitrack><playlist></playlist><playlist></playlist><playlist /><playlist /><playlist></playlist></multitrack></tractor></westley>");*/
+    setSceneList(doc, 0);
+}
+
+
+/** Create the producer from the Westley QDomDocument */
+void Render::setSceneList(QDomDocument list, int position)
+{
+    if (!m_winid == -1) return;
+    m_generateScenelist = true;
+
+    kWarning()<<"//////  RENDER, SET SCENE LIST";
+
+    Mlt::Playlist track;
+    char *tmp = decodedString(list.toString());
+   kDebug()<<" / / /STRING rESULT-----------: "<<tmp;
+    Mlt::Producer clip("westley-xml", tmp);
+    delete[] tmp;
+
+    if (!clip.is_valid()) {
+       kWarning()<<" ++++ WARNING, UNABLE TO CREATE MLT PRODUCER";
+       m_generateScenelist = false;
+       return;
+    }
+
+    track.append(clip);
+
+    if (m_mltConsumer) {
+       m_mltConsumer->set("refresh", 0);
+       if (!m_mltConsumer->is_stopped()) {
+       //emitConsumerStopped();
+       m_mltConsumer->stop();
+       }
+    }
+
+    if (m_mltProducer) {
+       m_mltProducer->set_speed(0.0);
+
+       //if (KdenliveSettings::osdtimecode() && m_osdInfo) m_mltProducer->detach(*m_osdInfo);
+
+       delete m_mltProducer;
+       m_mltProducer = NULL;
+       emit stopped();
+    }
+
+    m_mltProducer = new Mlt::Producer(clip); //track.current();
+    m_mltProducer->optimise();
+    if (position != 0) m_mltProducer->seek(position);
+
+    /*if (KdenliveSettings::osdtimecode()) {
+               // Attach filter for on screen display of timecode
+               delete m_osdInfo;
+               QString attr = "attr_check";
+               mlt_filter filter = mlt_factory_filter( "data_feed", (char*) attr.ascii() );
+               mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "_fezzik", 1 );
+               mlt_producer_attach( m_mltProducer->get_producer(), filter );
+               mlt_filter_close( filter );
+
+               m_osdInfo = new Mlt::Filter("data_show");
+               tmp = decodedString(m_osdProfile);
+               m_osdInfo->set("resource", tmp);
+               delete[] tmp;
+               mlt_properties properties = MLT_PRODUCER_PROPERTIES(m_mltProducer->get_producer());
+               mlt_properties_set_int( properties, "meta.attr.timecode", 1);
+               mlt_properties_set( properties, "meta.attr.timecode.markup", "#timecode#");
+               m_osdInfo->set("dynamic", "1");
+
+               if (m_mltProducer->attach(*m_osdInfo) == 1) kDebug()<<"////// error attaching filter";
+       } else {
+               m_osdInfo->set("dynamic", "0");
+       }*/
+
+       m_fps = m_mltProducer->get_fps();
+        if (!m_mltConsumer) {
+           restartConsumer();
+        }
+
+       m_connectTimer->start( 500 );
+       m_generateScenelist = false;
+  
+}
+
+
+void Render::connectPlaylist() {
+        kDebug()<<"**************  CONNECTING PLAYLIST";
+        m_connectTimer->stop();
+       if (m_mltConsumer->start() == -1) {
+               KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
+               m_mltConsumer = NULL;
+       }
+       else {
+           m_mltConsumer->connect(*m_mltProducer);
+           m_mltProducer->set_speed(0.0);
+           refresh();
+       }
+}
+
+void Render::refreshDisplay() {
+
+       if (!m_mltProducer) return;
+       m_mltConsumer->set("refresh", 0);
+
+       mlt_properties properties = MLT_PRODUCER_PROPERTIES(m_mltProducer->get_producer());
+       /*if (KdenliveSettings::osdtimecode()) {
+           mlt_properties_set_int( properties, "meta.attr.timecode", 1);
+           mlt_properties_set( properties, "meta.attr.timecode.markup", "#timecode#");
+           m_osdInfo->set("dynamic", "1");
+           m_mltProducer->attach(*m_osdInfo);
+       }
+       else {
+           m_mltProducer->detach(*m_osdInfo);
+           m_osdInfo->set("dynamic", "0");
+       }*/
+       refresh();
+}
+
+void Render::setVolume(double volume)
+{
+    if (!m_mltConsumer || !m_mltProducer) return;
+    /*osdTimer->stop();
+       m_mltConsumer->set("refresh", 0);
+    // Attach filter for on screen display of timecode
+    mlt_properties properties = MLT_PRODUCER_PROPERTIES(m_mltProducer->get_producer());
+    mlt_properties_set_double( properties, "meta.volume", volume );
+    mlt_properties_set_int( properties, "meta.attr.osdvolume", 1);
+    mlt_properties_set( properties, "meta.attr.osdvolume.markup", i18n("Volume: ") + QString::number(volume * 100));
+
+    if (!KdenliveSettings::osdtimecode()) {
+       m_mltProducer->detach(*m_osdInfo);
+       mlt_properties_set_int( properties, "meta.attr.timecode", 0);
+       if (m_mltProducer->attach(*m_osdInfo) == 1) kDebug()<<"////// error attaching filter";
+    }*/
+    refresh();
+    osdTimer->setSingleShot(2500 );
+}
+
+void Render::slotOsdTimeout()
+{
+    mlt_properties properties = MLT_PRODUCER_PROPERTIES(m_mltProducer->get_producer());
+    mlt_properties_set_int(properties, "meta.attr.osdvolume", 0);
+    mlt_properties_set(properties, "meta.attr.osdvolume.markup", NULL);
+    //if (!KdenliveSettings::osdtimecode()) m_mltProducer->detach(*m_osdInfo);
+    refresh();
+}
+
+void Render::start()
+{
+    if (!m_mltConsumer || m_winid == -1) {
+       restartConsumer();
+       return;
+    }
+
+    if (m_mltConsumer->is_stopped()) {
+       if (m_mltConsumer->start() == -1) {
+           KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
+           m_mltConsumer = NULL;
+           return;
+       }
+       else {
+               refresh();
+       }
+    }
+    isBlocked = false;
+}
+
+void Render::clear()
+{
+    if (m_mltConsumer) {
+       m_mltConsumer->set("refresh", 0);
+       if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop();
+    }
+
+    if (m_mltProducer) {
+       //if (KdenliveSettings::osdtimecode() && m_osdInfo) m_mltProducer->detach(*m_osdInfo);
+       m_mltProducer->set_speed(0.0);
+       delete m_mltProducer;
+       m_mltProducer = NULL;
+       emit stopped();
+    }
+}
+
+void Render::stop()
+{
+    kDebug()<<"/////////////   RENDER STOP-------";
+    if (m_mltConsumer && !m_mltConsumer->is_stopped()) {
+       m_mltConsumer->set("refresh", 0);
+       m_mltConsumer->stop();
+    }
+
+    isBlocked = true;
+
+    if (m_mltProducer) {
+       m_mltProducer->set_speed(0.0);
+       m_mltProducer->set("out", m_mltProducer->get_length() - 1);
+    }
+}
+
+void Render::stop(const GenTime & startTime)
+{
+    kDebug()<<"/////////////   RENDER STOP-------2";
+    if (m_mltProducer) {
+       m_mltProducer->set_speed(0.0);
+       m_mltProducer->seek((int) startTime.frames(m_fps));
+    }
+    m_mltConsumer->purge();
+}
+
+void Render::switchPlay()
+{
+    if (!m_mltProducer)
+       return;
+    if (m_mltProducer->get_speed() == 0.0) m_mltProducer->set_speed(1.0);
+    else {
+      m_mltProducer->set_speed(0.0);
+      kDebug()<<"// POSITON: "<<m_framePosition;
+      m_mltProducer->seek((int) m_framePosition);
+    }
+
+    /*if (speed == 0.0) {
+       m_mltProducer->seek((int) m_framePosition + 1);
+        m_mltConsumer->purge();
+    }*/
+    refresh();
+}
+
+void Render::play(double speed)
+{
+    if (!m_mltProducer)
+       return;
+    if (speed == 0.0) m_mltProducer->set("out", m_mltProducer->get_length() - 1);
+    m_mltProducer->set_speed(speed);
+    /*if (speed == 0.0) {
+       m_mltProducer->seek((int) m_framePosition + 1);
+        m_mltConsumer->purge();
+    }*/
+    refresh();
+}
+
+void Render::play(double speed, const GenTime & startTime)
+{
+    kDebug()<<"/////////////   RENDER PLAY2-------"<<speed;
+    if (!m_mltProducer)
+       return;
+    //m_mltProducer->set("out", m_mltProducer->get_length() - 1);
+    //if (speed == 0.0) m_mltConsumer->set("refresh", 0);
+    m_mltProducer->set_speed(speed);
+    m_mltProducer->seek((int) (startTime.frames(m_fps)));
+    //m_mltConsumer->purge();
+    //refresh();
+}
+
+void Render::play(double speed, const GenTime & startTime,
+    const GenTime & stopTime)
+{
+    kDebug()<<"/////////////   RENDER PLAY3-------"<<speed;
+    if (!m_mltProducer)
+       return;
+    m_mltProducer->set("out", stopTime.frames(m_fps));
+    m_mltProducer->seek((int) (startTime.frames(m_fps)));
+    m_mltConsumer->purge();
+    m_mltProducer->set_speed(speed);
+    refresh();
+}
+
+void Render::render(const KUrl & url)
+{
+    QDomDocument doc;
+    QDomElement elem = doc.createElement("render");
+    elem.setAttribute("filename", url.path());
+    doc.appendChild(elem);
+}
+
+void Render::sendSeekCommand(GenTime time)
+{
+    if (!m_mltProducer)
+       return;
+    //kDebug()<<"//////////  KDENLIVE SEEK: "<<(int) (time.frames(m_fps));
+    m_mltProducer->seek((int) (time.frames(m_fps)));
+    refresh();
+}
+
+void Render::askForRefresh()
+{
+    // Use a Timer so that we don't refresh too much
+    refreshTimer->start(200 );
+}
+
+void Render::refresh()
+{
+    if (!m_mltProducer)
+       return;
+    refreshTimer->stop();
+    if (m_mltConsumer) {
+       m_mltConsumer->set("refresh", 1);
+    }
+}
+
+/** Sets the description of this renderer to desc. */
+void Render::setDescription(const QString & description)
+{
+    m_description = description;
+}
+
+/** Returns the description of this renderer */
+QString Render::description()
+{
+    return m_description;
+}
+
+
+double Render::playSpeed()
+{
+    if (m_mltProducer) return m_mltProducer->get_speed();
+    return 0.0;
+}
+
+const GenTime & Render::seekPosition() const
+{
+    if (m_mltProducer) return GenTime((int) m_mltProducer->position(), m_fps);
+    else return GenTime();
+}
+
+
+const QString & Render::rendererName() const
+{
+    return m_name;
+}
+
+
+void Render::emitFrameNumber(double position)
+{
+      kDebug()<<"// POSITON: "<<m_framePosition;
+       if (m_generateScenelist) return;
+       m_framePosition = position;
+        //if (qApp->activeWindow()) QApplication::postEvent(qApp->activeWindow(), new PositionChangeEvent( GenTime((int) position, m_fps), m_monitorId));
+}
+
+void Render::emitConsumerStopped()
+{
+    // This is used to know when the playing stopped
+    if (m_mltProducer && !m_generateScenelist) {
+       double pos = m_mltProducer->position();
+        //if (qApp->activeWindow()) QApplication::postEvent(qApp->activeWindow(), new PositionChangeEvent(GenTime((int) pos, m_fps), m_monitorId + 100));
+       //new QCustomEvent(10002));
+    }
+}
+
+
+
+void Render::exportFileToFirewire(QString srcFileName, int port, GenTime startTime, GenTime endTime)
+{
+KMessageBox::sorry(0, i18n("Firewire is not enabled on your system.\n Please install Libiec61883 and recompile Kdenlive"));
+}
+
+
+void Render::exportCurrentFrame(KUrl url, bool notify) {
+    if (!m_mltProducer) {
+       KMessageBox::sorry(qApp->activeWindow(), i18n("There is no clip, cannot extract frame."));
+       return;
+    }
+
+    int height = 1080;//KdenliveSettings::defaultheight();
+    int width = 1940; //KdenliveSettings::displaywidth();
+
+    QPixmap pix(width, height);
+
+    Mlt::Filter m_convert("avcolour_space");
+    m_convert.set("forced", mlt_image_rgb24a);
+    m_mltProducer->attach(m_convert);
+    Mlt::Frame * frame = m_mltProducer->get_frame();
+    m_mltProducer->detach(m_convert);
+    if (frame) {
+       pix = frameThumbnail(frame, width, height);
+       delete frame;
+    }
+    pix.save(url.path(), "PNG");
+    //if (notify) QApplication::postEvent(qApp->activeWindow(), new UrlEvent(url, 10003));
+}
+
+/**    MLT PLAYLIST DIRECT MANIPULATON         **/
+
+
+void Render::mltCheckLength()
+{
+    //kDebug()<<"checking track length: "<<track<<"..........";
+    Mlt::Service service(m_mltProducer->get_service());
+    Mlt::Tractor tractor(service);
+
+    int trackNb = tractor.count( );
+    double duration = 0;
+    double trackDuration;
+    if (trackNb == 1) {
+        Mlt::Producer trackProducer(tractor.track(0));
+        Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+        duration = Mlt::Producer(trackPlaylist.get_producer()).get_playtime() - 1;
+       m_mltProducer->set("out", duration);
+       emit durationChanged();
+       return;
+    }
+    while (trackNb > 1) {
+        Mlt::Producer trackProducer(tractor.track(trackNb - 1));
+        Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+        trackDuration = Mlt::Producer(trackPlaylist.get_producer()).get_playtime() - 1;
+
+       kDebug()<<" / / /DURATON FOR TRACK "<<trackNb - 1<<" = "<<trackDuration;
+       if (trackDuration > duration) duration = trackDuration;
+       trackNb--;
+    }
+
+    Mlt::Producer blackTrackProducer(tractor.track(0));
+    Mlt::Playlist blackTrackPlaylist(( mlt_playlist ) blackTrackProducer.get_service());
+    double blackDuration = Mlt::Producer(blackTrackPlaylist.get_producer()).get_playtime() - 1;
+       kDebug()<<" / / /DURATON FOR TRACK 0 = "<<blackDuration;
+    if (blackDuration != duration) {
+       blackTrackPlaylist.remove_region( 0, blackDuration );
+       int i = 0;
+       int dur = duration;
+       
+        while (dur > 14000) { // <producer mlt_service=\"colour\" colour=\"black\" in=\"0\" out=\"13999\" />
+           mltInsertClip(0, GenTime(i * 14000, m_fps), QString("<westley><producer mlt_service=\"colour\" colour=\"black\" in=\"0\" out=\"13999\" /></westley>"));
+           dur = dur - 14000;
+           i++;
+        }
+
+       mltInsertClip(0, GenTime(), QString("<westley><producer mlt_service=\"colour\" colour=\"black\" in=\"0\" out=\"" + QString::number(dur) + "\" /></westley>"));
+
+       m_mltProducer->set("out", duration);
+       emit durationChanged();
+    }
+}
+
+
+void Render::mltInsertClip(int track, GenTime position, QString resource)
+{
+    if (!m_mltProducer) {
+       kDebug()<<"PLAYLIST NOT INITIALISED //////";
+       return;
+    }
+    Mlt::Producer parentProd(m_mltProducer->parent());
+    if (parentProd.get_producer() == NULL) {
+       kDebug()<<"PLAYLIST BROKEN, CANNOT INSERT CLIP //////";
+       return;
+    }
+    Mlt::Service service(parentProd.get_service());
+    Mlt::Tractor tractor(service);
+
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    char *tmp = decodedString(resource);
+    Mlt::Producer clip("westley-xml", tmp);
+    //clip.set_in_and_out(in.frames(m_fps), out.frames(m_fps));
+    delete[] tmp;
+
+    trackPlaylist.insert_at(position.frames(m_fps), clip, 1);
+    tractor.multitrack()->refresh();
+    tractor.refresh();
+    if (track != 0) mltCheckLength();
+    double duration = Mlt::Producer(trackPlaylist.get_producer()).get_playtime();
+    kDebug()<<"// +  +INSERTING CLIP: "<<resource<<" AT: "<<position.frames(m_fps)<<" on track: "<<track<<", DURATION: "<<duration;
+
+
+}
+
+void Render::mltCutClip(int track, GenTime position)
+{
+    Mlt::Service service(m_mltProducer->parent().get_service());
+    if (service.type() == playlist_type) kDebug()<<"// PLAYLIST TYPE";
+    if (service.type() == tractor_type) kDebug()<<"// TRACOT TYPE";
+    if (service.type() == multitrack_type) kDebug()<<"// MULTITRACK TYPE";
+    if (service.type() == producer_type) kDebug()<<"// PROD TYPE";
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    trackPlaylist.split_at(position.frames(m_fps));
+    trackPlaylist.consolidate_blanks(0);
+    kDebug()<<"/ / / /CUTTING CLIP AT: "<<position.frames(m_fps);
+}
+
+
+void Render::mltRemoveClip(int track, GenTime position)
+{
+    Mlt::Service service(m_mltProducer->parent().get_service());
+    if (service.type() == playlist_type) kDebug()<<"// PLAYLIST TYPE";
+    if (service.type() == tractor_type) kDebug()<<"// TRACOT TYPE";
+    if (service.type() == multitrack_type) kDebug()<<"// MULTITRACK TYPE";
+    if (service.type() == producer_type) kDebug()<<"// PROD TYPE";
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    int clipIndex = trackPlaylist.get_clip_index_at(position.frames(m_fps));
+    //trackPlaylist.remove(clipIndex);
+    trackPlaylist.replace_with_blank(clipIndex);
+    trackPlaylist.consolidate_blanks(0);
+    if (track != 0) mltCheckLength();
+    //emit durationChanged();
+}
+
+void Render::mltRemoveEffect(int track, GenTime position, QString id, QString tag, int index)
+{
+    Mlt::Service service(m_mltProducer->parent().get_service());
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    //int clipIndex = trackPlaylist.get_clip_index_at(position.frames(m_fps));
+    Mlt::Producer *clip = trackPlaylist.get_clip_at(position.frames(m_fps));
+    if (!clip) {
+       kDebug()<<" / / / CANNOT FIND CLIP TO REMOVE EFFECT";
+       return;
+    }
+    Mlt::Service clipService(clip->get_service());
+
+    if (tag.startsWith("ladspa")) tag = "ladspa";
+
+    if (index == -1) {
+       int ct = 0;
+       Mlt::Filter *filter = clipService.filter( ct );
+       while (filter) {
+           if (filter->get("mlt_service") == tag && filter->get("kdenlive_id") == id) {
+               clipService.detach(*filter);
+               kDebug()<<" / / / DLEETED EFFECT: "<<ct;
+           }
+           else ct++;
+           filter = clipService.filter( ct );
+       }
+    }
+    else {
+        Mlt::Filter *filter = clipService.filter( index );
+        if (filter && filter->get("mlt_service") == tag && filter->get("kdenlive_id") == id) clipService.detach(*filter);
+        else {
+           kDebug()<<"WARINIG, FILTER "<<id<<" NOT FOUND!!!!!";
+        }
+    }
+    refresh();
+}
+
+
+void Render::mltAddEffect(int track, GenTime position, QString id, QString tag, QMap <QString, QString> args)
+{
+    Mlt::Service service(m_mltProducer->parent().get_service());
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+
+    Mlt::Producer *clip = trackPlaylist.get_clip_at(position.frames(m_fps));
+
+    if (!clip) {
+       kDebug()<<"**********  CANNOT FIND CLIP TO APPLY EFFECT-----------";
+       return;
+    }
+    Mlt::Service clipService(clip->get_service());
+
+    // create filter
+    kDebug()<<" / / INSERTING EFFECT: "<<id;
+    if (tag.startsWith("ladspa")) tag = "ladspa";
+    char *filterId = decodedString(tag);
+    Mlt::Filter *filter = new Mlt::Filter(filterId);
+    filter->set("kdenlive_id", filterId);
+
+    QMap<QString, QString>::Iterator it;
+    QString keyFrameNumber = "#0";
+
+    for ( it = args.begin(); it != args.end(); ++it ) {
+    //kDebug()<<" / / INSERTING EFFECT ARGS: "<<it.key()<<": "<<it.data();
+       QString key;
+       QString currentKeyFrameNumber;
+       if (it.key().startsWith("#")) {
+           currentKeyFrameNumber = it.key().section(":", 0, 0);
+           if (currentKeyFrameNumber != keyFrameNumber) {
+               // attach filter to the clip
+               clipService.attach(*filter);
+               filter = new Mlt::Filter(filterId);
+               filter->set("kdenlive_id", filterId);
+               keyFrameNumber = currentKeyFrameNumber;
+           }
+           key = it.key().section(":", 1);
+       }
+       else key = it.key();
+        char *name = decodedString(key);
+        char *value = decodedString(it.value());
+        filter->set(name, value);
+       delete[] name;
+       delete[] value;
+    }
+    // attach filter to the clip
+    clipService.attach(*filter);
+    delete[] filterId;
+    refresh();
+
+}
+
+void Render::mltEditEffect(int track, GenTime position, int index, QString id, QString tag, QMap <QString, QString> args)
+{
+    QMap<QString, QString>::Iterator it = args.begin();
+    if (it.key().startsWith("#") || tag.startsWith("ladspa") || tag == "sox" || tag == "autotrack_rectangle") {
+       // This is a keyframe effect, to edit it, we remove it and re-add it.
+       mltRemoveEffect(track, position, id, tag, -1);
+       mltAddEffect(track, position, id, tag, args);
+       return;
+    }
+
+    // create filter
+    Mlt::Service service(m_mltProducer->parent().get_service());
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    //int clipIndex = trackPlaylist.get_clip_index_at(position.frames(m_fps));
+    Mlt::Producer *clip = trackPlaylist.get_clip_at(position.frames(m_fps));
+    Mlt::Service clipService(clip->get_service());
+    Mlt::Filter *filter = clipService.filter( index );
+
+
+    if (!filter || filter->get("mlt_service") != tag) {
+       kDebug()<<"WARINIG, FILTER NOT FOUND!!!!!";
+       int index = 0;
+       filter = clipService.filter( index );
+       while (filter) {
+           if (filter->get("mlt_service") == tag && filter->get("kdenlive_id") == id) break;
+           index++;
+           filter = clipService.filter( index );
+       }
+    }
+    if (!filter) {
+       kDebug()<<"WARINIG, FILTER "<<id<<" NOT FOUND!!!!!";
+       return;
+    }
+
+    for ( it = args.begin(); it != args.end(); ++it ) {
+    kDebug()<<" / / INSERTING EFFECT ARGS: "<<it.key()<<": "<<it.value();
+        char *name = decodedString(it.key());
+        char *value = decodedString(it.value());
+        filter->set(name, value);
+       delete[] name;
+       delete[] value;
+    }
+    refresh();
+}
+
+void Render::mltResizeClipEnd(int track, GenTime pos, GenTime in, GenTime out)
+{
+    Mlt::Service service(m_mltProducer->parent().get_service());
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    if (trackPlaylist.is_blank_at(pos.frames(m_fps) + 1)) 
+       kDebug()<<"////////  ERROR RSIZING BLANK CLIP!!!!!!!!!!!";
+    int clipIndex = trackPlaylist.get_clip_index_at(pos.frames(m_fps) + 1);
+
+    int previousDuration = trackPlaylist.clip_length(clipIndex) - 1;
+    int newDuration = out.frames(m_fps) - 1;
+
+    kDebug()<<" ** RESIZING CLIP END:" << clipIndex << " on track:"<< track <<", mid pos: "<<pos.frames(25)<<", in: "<<in.frames(25)<<", out: "<<out.frames(25)<<", PREVIOUS duration: "<<previousDuration;
+    trackPlaylist.resize_clip(clipIndex, in.frames(m_fps), newDuration);
+    trackPlaylist.consolidate_blanks(0);
+    if (previousDuration < newDuration) {
+       // clip was made longer, trim next blank if there is one.
+       if (trackPlaylist.is_blank(clipIndex + 1)) {
+           trackPlaylist.split(clipIndex + 1, newDuration - previousDuration);
+           trackPlaylist.remove(clipIndex + 1);
+       }
+    }
+    else trackPlaylist.insert_blank(clipIndex + 1, previousDuration - newDuration - 1);
+
+    trackPlaylist.consolidate_blanks(0);
+    tractor.multitrack()->refresh();
+    tractor.refresh();
+    if (track != 0) mltCheckLength();
+
+}
+
+void Render::mltChangeTrackState(int track, bool mute, bool blind)
+{
+    Mlt::Service service(m_mltProducer->parent().get_service());
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    if (mute) {
+       if (blind) trackProducer.set("hide", 3);
+       else trackProducer.set("hide", 2);
+    }
+    else if (blind) {
+       trackProducer.set("hide", 1);
+    }
+    else {
+       trackProducer.set("hide", 0);
+    }
+    tractor.multitrack()->refresh();
+    tractor.refresh();
+    refresh();
+}
+
+void Render::mltResizeClipStart(int track, GenTime pos, GenTime moveEnd, GenTime moveStart, GenTime in, GenTime out)
+{
+    Mlt::Service service(m_mltProducer->parent().get_service());
+    if (service.type() == playlist_type) kDebug()<<"// PLAYLIST TYPE";
+    if (service.type() == tractor_type) kDebug()<<"// TRACOT TYPE";
+    if (service.type() == multitrack_type) kDebug()<<"// MULTITRACK TYPE";
+    if (service.type() == producer_type) kDebug()<<"// PROD TYPE";
+
+    int moveFrame = (moveEnd - moveStart).frames(m_fps);
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    if (trackPlaylist.is_blank_at(pos.frames(m_fps) - 1)) 
+       kDebug()<<"////////  ERROR RSIZING BLANK CLIP!!!!!!!!!!!";
+    int clipIndex = trackPlaylist.get_clip_index_at(pos.frames(m_fps) - 1);
+    kDebug()<<" ** RESIZING CLIP START:" << clipIndex << " on track:"<< track <<", mid pos: "<<pos.frames(25)<<", moving: "<<moveFrame<<", in: "<<in.frames(25)<<", out: "<<out.frames(25);
+
+    trackPlaylist.resize_clip(clipIndex, in.frames(m_fps), out.frames(m_fps));
+    if (moveFrame > 0) trackPlaylist.insert_blank(clipIndex, moveFrame - 1);
+    else {
+       int midpos = moveStart.frames(m_fps) - 1; //+ (moveFrame / 2)
+       int blankIndex = trackPlaylist.get_clip_index_at(midpos);
+       int blankLength = trackPlaylist.clip_length(blankIndex);
+
+       kDebug()<<" + resizing blank: "<<blankIndex<<", Mid: "<<midpos<<", Length: "<<blankLength<< ", SIZE DIFF: "<<moveFrame;
+
+       
+       if (blankLength + moveFrame == 0) trackPlaylist.remove(blankIndex);
+       else trackPlaylist.resize_clip(blankIndex, 0, blankLength + moveFrame -1);
+    }
+    trackPlaylist.consolidate_blanks(0);
+
+    kDebug()<<"-----------------\n"<<"CLIP 0: "<<trackPlaylist.clip_start(0)<<", LENGT: "<<trackPlaylist.clip_length(0);
+    kDebug()<<"CLIP 1: "<<trackPlaylist.clip_start(1)<<", LENGT: "<<trackPlaylist.clip_length(1);
+    kDebug()<<"CLIP 2: "<<trackPlaylist.clip_start(2)<<", LENGT: "<<trackPlaylist.clip_length(2);
+    kDebug()<<"CLIP 3: "<<trackPlaylist.clip_start(3)<<", LENGT: "<<trackPlaylist.clip_length(3);
+   kDebug()<<"CLIP 4: "<<trackPlaylist.clip_start(4)<<", LENGT: "<<trackPlaylist.clip_length(4);
+}
+
+void Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd)
+{
+    mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps));
+}
+
+
+void Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd)
+{
+    m_mltConsumer->set("refresh", 0);
+    Mlt::Service service(m_mltProducer->parent().get_service());
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(startTrack));
+    Mlt::Playlist trackPlaylist(( mlt_playlist ) trackProducer.get_service());
+    int clipIndex = trackPlaylist.get_clip_index_at(moveStart + 1);
+
+
+    mlt_field field = mlt_tractor_field(tractor.get_tractor());
+
+    mlt_multitrack multitrack = mlt_field_multitrack(field); //mlt_tractor_multitrack(tractor.get_tractor());
+    kDebug()<<" --  CURRENT MULTIOTRACK HAS: "<<mlt_multitrack_count(multitrack)<<" tracks";;
+    mlt_service multiprod = mlt_multitrack_service( multitrack );
+
+    Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
+    trackPlaylist.consolidate_blanks(0);
+    mlt_events_block( MLT_PRODUCER_PROPERTIES(clipProducer.get_producer()), NULL );
+
+    if (endTrack == startTrack) {
+       if (!trackPlaylist.is_blank_at(moveEnd)) {
+           kWarning()<<"// ERROR, CLIP COLLISION----------";
+           int ix = trackPlaylist.get_clip_index_at(moveEnd);
+               kDebug()<<"BAD CLIP STARTS AT: "<<trackPlaylist.clip_start(ix)<<", LENGT: "<<trackPlaylist.clip_length(ix);
+       }
+       trackPlaylist.insert_at(moveEnd, clipProducer, 1);
+       trackPlaylist.consolidate_blanks(0);
+    }
+    else {
+       trackPlaylist.consolidate_blanks(0);
+       Mlt::Producer destTrackProducer(tractor.track(endTrack));
+       Mlt::Playlist destTrackPlaylist(( mlt_playlist ) destTrackProducer.get_service());
+       destTrackPlaylist.consolidate_blanks(1);
+       destTrackPlaylist.insert_at(moveEnd, clipProducer, 1);
+       destTrackPlaylist.consolidate_blanks(0);
+    }
+
+    mltCheckLength();
+    mlt_events_unblock( MLT_PRODUCER_PROPERTIES(clipProducer.get_producer()), NULL );
+}
+
+void Render::mltMoveTransition(QString type, int startTrack, int trackOffset, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut)
+{
+    m_mltConsumer->set("refresh", 0);
+    mlt_service serv = m_mltProducer->parent().get_service();
+
+    mlt_service nextservice = mlt_service_get_producer(serv);
+    mlt_properties properties = MLT_SERVICE_PROPERTIES( nextservice );
+    QString mlt_type = mlt_properties_get( properties, "mlt_type" );
+    QString resource = mlt_properties_get( properties, "mlt_service");
+    int old_pos = (oldIn.frames(m_fps) + oldOut.frames(m_fps)) / 2;
+
+    int new_in = newIn.frames(m_fps);
+    int new_out = newOut.frames(m_fps) - 1;
+    while (mlt_type == "transition") {
+       mlt_transition tr = (mlt_transition) nextservice;
+       int currentTrack = mlt_transition_get_b_track(tr);
+       int currentIn = (int) mlt_transition_get_in(tr);
+        int currentOut = (int) mlt_transition_get_out(tr);
+       kDebug()<<"// FOUND EXISTING TRANS, IN: "<<currentIn<<", OUT: "<<currentOut<<", TRACK: "<<currentTrack;
+       //kDebug()<<"// LOOKING FOR IN: "<<old_in<<", OUT: "<<old_out;
+       kDebug()<<"// OLD IN: "<<oldIn.frames(m_fps)<<" // OLD OUT: "<<oldOut.frames(m_fps)<<", TRACK: "<<startTrack<<", MID POS: "<<old_pos;
+       if (resource == type && startTrack == currentTrack && currentIn <= old_pos && currentOut >= old_pos) {
+            mlt_transition_set_in_and_out(tr, new_in, new_out);
+            if (trackOffset != 0) {
+               mlt_properties properties = MLT_TRANSITION_PROPERTIES( tr );
+               mlt_properties_set_int( properties, "a_track", mlt_transition_get_a_track(tr) + trackOffset );
+               mlt_properties_set_int( properties, "b_track", mlt_transition_get_b_track(tr) + trackOffset );
+            }
+            break;
+        }
+       nextservice = mlt_service_producer(nextservice);
+       properties = MLT_SERVICE_PROPERTIES( nextservice );
+       mlt_type = mlt_properties_get( properties, "mlt_type" );
+       resource = mlt_properties_get( properties, "mlt_service" );
+    }
+}
+
+void Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QMap <QString, QString> args)
+{
+    Mlt::Service service(m_mltProducer->parent().get_service());
+
+    Mlt::Tractor tractor(service);
+    Mlt::Field *field = tractor.field();
+
+    char *transId = decodedString(tag);
+    Mlt::Transition *transition = new Mlt::Transition(transId);
+    transition->set_in_and_out((int) in.frames(m_fps), (int) out.frames(m_fps));
+    QMap<QString, QString>::Iterator it;
+    QString key;
+
+    kDebug()<<" ------  ADDING TRANSITION PARAMs: "<<args.count();
+
+    for ( it = args.begin(); it != args.end(); ++it ) {
+       key = it.key();
+        char *name = decodedString(key);
+        char *value = decodedString(it.value());
+        transition->set(name, value);
+       kDebug()<<" ------  ADDING TRANS PARAM: "<<name<<": "<<value;
+       //filter->set("kdenlive_id", id);
+       delete[] name;
+       delete[] value;
+    }
+    // attach filter to the clip
+    field->plant_transition(*transition, a_track, b_track);
+    delete[] transId;
+    refresh();
+
+}
+
+void Render::mltSavePlaylist()
+{
+    kWarning()<<"// UPDATING PLAYLIST TO DISK++++++++++++++++";
+    Mlt::Consumer *fileConsumer = new Mlt::Consumer("westley");
+    fileConsumer->set("resource", "/home/one/playlist.xml");
+
+    Mlt::Service service(m_mltProducer->get_service());
+    Mlt::Tractor tractor(service);
+
+    fileConsumer->connect(service);
+    fileConsumer->start();
+
+}
+
+#include "renderer.moc"
diff --git a/src/renderer.h b/src/renderer.h
new file mode 100644 (file)
index 0000000..5d7826f
--- /dev/null
@@ -0,0 +1,257 @@
+/***************************************************************************
+                         krender.h  -  description
+                            -------------------
+   begin                : Fri Nov 22 2002
+   copyright            : (C) 2002 by Jason Wood
+   email                : jasonwood@blueyonder.co.uk
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef KRENDER_H
+#define KRENDER_H
+
+#include <qdom.h>
+#include <qstring.h>
+#include <qmap.h>
+#include <QList>
+#include <QWidget>
+
+#include <kurl.h>
+
+#include "gentime.h"
+/*#include "docclipref.h"
+#include "effectdesc.h"
+#include "effectparamdescfactory.h"*/
+
+/**Render encapsulates the client side of the interface to a renderer.
+From Kdenlive's point of view, you treat the Render object as the
+renderer, and simply use it as if it was local. Calls are asyncrhonous -
+you send a call out, and then recieve the return value through the
+relevant signal that get's emitted once the call completes.
+  *@author Jason Wood
+  */
+
+class Render;
+//class EffectParamDesc;
+class QPixmap;
+
+namespace Mlt {
+    class Consumer;
+    class Playlist;
+    class Tractor;
+    class Frame;
+    class Producer;
+    class Filter;
+
+    class Multitrack;
+};
+
+
+
+class Render:public QObject {
+  Q_OBJECT public:
+
+    enum FailStates { OK = 0,
+       APP_NOEXIST
+    };
+
+     Render(const QString & rendererName, QWidget *parent = 0);
+    ~Render();
+
+       /** Wraps the VEML command of the same name; requests that the renderer
+       should create a video window. If show is true, then the window should be
+       displayed, otherwise it should be hidden. Render will emit the signal
+       replyCreateVideoXWindow() once the renderer has replied. */
+    void createVideoXWindow(WId winid, WId externalMonitor);
+       /** Seeks the renderer clip to the given time. */
+    void seek(GenTime time);
+    
+    static QPixmap getVideoThumbnail(QString file, int frame, int width, int height);
+    QPixmap getImageThumbnail(KUrl url, int width, int height);
+
+       /** Return thumbnail for color clip */
+    void getImage(int id, QString color, QPoint size);
+
+    static QPixmap frameThumbnail(Mlt::Frame *frame, int width, int height, bool border = false);
+    
+    /** Return thumbnail for image clip */
+    void getImage(KUrl url, QPoint size);
+
+       /** Requests a particular frame from the given file. 
+        * 
+        * The pixmap will be returned by emitting the replyGetImage() signal.
+        * */
+    void getImage(KUrl url, int frame, QPoint size);
+
+       /** Wraps the VEML command of the same name. Sets the current scene list to
+       be list. */
+    void setSceneList(QDomDocument list, int position = 0);
+
+       /** Wraps the VEML command of the same name. Tells the renderer to
+       play the current scene at the speed specified, relative to normal
+       playback. e.g. 1.0 is normal speed, 0.0 is paused, -1.0 means play
+       backwards. Does not specify start/stop times for playback.*/
+    void play(double speed);
+    void switchPlay();
+       /** stop playing */
+    void stop(const GenTime & startTime);
+    void setVolume(double volume);
+
+    QPixmap extractFrame(int frame_position, int width, int height);
+       /** Wraps the VEML command of the same name. Tells the renderer to
+       play the current scene at the speed specified, relative to normal
+       playback. e.g. 1.0 is normal speed, 0.0 is paused, -1.0 means play
+       backwards. Specifes the start/stop times for playback.*/
+    void play(double speed, const GenTime & startTime);
+    void play(double speed, const GenTime & startTime,
+       const GenTime & stopTime);
+       /** Wraps the VEML command of the same name - render the currently
+       specified sceneList - set with setSceneList() - to the document
+       name specified. */
+    void render(const KUrl & url);
+
+       /** Returns the description of this renderer */
+    QString description();
+
+       /** Returns the name of the renderer. */
+    const QString & rendererName() const;
+
+       /** Returns the speed at which the renderer is currently playing, 0.0 if the renderer is
+       not playing anything. */
+    double playSpeed();
+       /** Returns the current seek position of the renderer. */
+    const GenTime & seekPosition() const;
+
+    void emitFrameNumber(double position);
+    void emitConsumerStopped();
+
+    /** Gives the aspect ratio of the consumer */
+    double consumerRatio() const;
+
+    /** Gives the aspect ratio of the consumer */
+    void askForRefresh();
+    
+    /** Save current producer frame as image */
+    void exportCurrentFrame(KUrl url, bool notify);
+
+    /** Turn on or off on screen display */
+    void refreshDisplay();
+    /** returns the current scenelist */
+    QDomDocument sceneList() const;
+    int resetRendererProfile(char * profile);
+    bool isBlocked;
+
+    /** Playlist manipulation */
+    void mltInsertClip(int track, GenTime position, QString resource);
+    void mltCutClip(int track, GenTime position);
+    void mltResizeClipEnd(int track, GenTime pos, GenTime in, GenTime out);
+    void mltResizeClipStart(int track, GenTime pos, GenTime moveEnd, GenTime moveStart, GenTime in, GenTime out);
+    void mltMoveClip(int startTrack, int endTrack, GenTime pos, GenTime moveStart);
+    void mltMoveClip(int startTrack, int endTrack, int pos, int moveStart);
+    void mltRemoveClip(int track, GenTime position);
+    void mltRemoveEffect(int track, GenTime position, QString id, QString tag, int index);
+    void mltAddEffect(int track, GenTime position, QString id, QString tag, QMap <QString, QString> args);
+    void mltEditEffect(int track, GenTime position, int index, QString id, QString tag, QMap <QString, QString> args);
+    void mltChangeTrackState(int track, bool mute, bool blind);
+    void mltMoveTransition(QString type, int startTrack, int trackOffset, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut);
+    void mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QMap <QString, QString> args);
+
+  private:                     // Private attributes & methods
+       /** The name of this renderer - useful to identify the renderes by what they do - e.g. background rendering, workspace monitor, etc... */
+     QString m_name;
+     Mlt::Consumer * m_mltConsumer;
+     Mlt::Producer * m_mltProducer;
+     Mlt::Producer *m_mltTextProducer;
+     Mlt::Filter *m_osdInfo;
+     double m_framePosition;
+     double m_fps;
+     uint m_monitorId;
+     bool m_generateScenelist;
+
+       /** Holds the path to on screen display profile */
+     QString m_osdProfile;
+     
+     QTimer *refreshTimer;
+     QTimer *osdTimer;
+     QTimer *m_connectTimer;
+     KUrl m_exportedFile;
+     int exportDuration, firstExportFrame, lastExportFrame;
+
+       /** Holds the scenelist to be sent, if pending. */
+    QDomDocument m_sceneList;
+
+       /** A human-readable description of this renderer. */
+    QString m_description;
+    int m_winid;
+    int m_externalwinid;
+       /** The actually seek command, private so people can't avoid the buffering of multiple seek commands. */
+    void sendSeekCommand(GenTime time);
+
+       /** Sets the description of this renderer to desc. */
+    void setDescription(const QString & description);
+    void closeMlt();
+    void mltCheckLength();
+
+    private slots:             // Private slots
+       /** refresh monitor display */
+        void refresh();
+       void slotOsdTimeout();
+       void restartConsumer();
+       void connectPlaylist();
+       void initSceneList();
+
+     signals:                  // Signals
+       /** This signal is emitted once a reply to createVideoXWidow() has been recieved. */
+    void replyCreateVideoXWindow(WId);
+       /** emitted when the renderer recieves a reply to a getFileProperties request. */
+    void replyGetFileProperties(const QMap < QString, QString > &, const QMap < QString, QString > &);
+
+       /** emitted when the renderer recieves a reply to a getImage request. */
+    void replyGetImage(const KUrl &, int, const QPixmap &, int, int);
+    void replyGetImage(int, const QPixmap &, int, int);
+
+       /** Emitted when the renderer stops, either playing or rendering. */
+    void stopped();
+       /** Emitted when the renderer starts playing. */
+    void playing(double);
+       /** Emitted when the renderer is rendering. */
+    void rendering(const GenTime &);
+       /** Emitted when rendering has finished */
+    void renderFinished();
+       /** Emitted when the current seek position has been changed by the renderer. */
+//    void positionChanged(const GenTime &);
+       /** Emitted when an error occurs within this renderer. */
+    void error(const QString &, const QString &);
+    void durationChanged();
+
+    
+    public slots:              // Public slots
+       /** Start Consumer */
+    void start();
+       /** Stop Consumer */
+    void stop();
+    void clear();
+    int getLength();
+       /** If the file is readable by mlt, return true, otherwise false */
+    bool isValid(KUrl url);
+
+       /** Wraps the VEML command of the same name. Requests the file properties
+    for the specified url from the renderer. Upon return, the result will be emitted
+    via replyGetFileProperties(). */
+    void getFileProperties(const KUrl &url, uint framenb = 0);
+    
+    void exportFileToFirewire(QString srcFileName, int port, GenTime startTime, GenTime endTime);
+    static char *decodedString(QString str);
+    void mltSavePlaylist();
+};
+
+#endif
diff --git a/src/timecode.cpp b/src/timecode.cpp
new file mode 100644 (file)
index 0000000..5d9a308
--- /dev/null
@@ -0,0 +1,262 @@
+/***************************************************************************
+                          timecode  -  description
+                             -------------------
+    begin                : Wed Dec 17 2003
+    copyright            : (C) 2003 by Jason Wood
+    email                : jasonwood@blueyonder.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#include "timecode.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+
+Timecode::Timecode(Formats format, int framesPerSecond,
+    bool dropFrame):m_format(format), m_dropFrame(dropFrame),
+m_displayedFramesPerSecond(framesPerSecond)
+{
+}
+
+Timecode::~Timecode()
+{
+}
+
+int Timecode::getFrameNumber(const QString duration, double fps) const
+{
+    if (m_dropFrame) {
+       // calculate how many frames need to be dropped every minute.
+       int frames;
+       int toDrop = (int) floor (600.0 * (m_displayedFramesPerSecond - fps)  + 0.5);
+
+       int perMinute = toDrop / 9;
+       int tenthMinute = toDrop % 9;
+
+       // calculate how many frames are in a normal minute, and how many are in a tenth minute.
+       int normalMinuteFrames = (m_displayedFramesPerSecond * 60) - perMinute;
+       int tenthMinuteFrames = (m_displayedFramesPerSecond * 60) - tenthMinute;;
+
+       // Number of actual frames in a 10 minute interval :
+       int tenMinutes = (normalMinuteFrames * 9) + tenthMinuteFrames;
+       frames = 6 * duration.section(":",0,0).toInt() * tenMinutes;
+       int minutes = duration.section(":",1,1).toInt();
+       frames += ((int) minutes / 10) * tenMinutes;
+       int mins = minutes % 10;
+       if (mins > 0) {
+           frames += tenthMinuteFrames;
+           mins--;
+           if (mins > 0) frames += mins * normalMinuteFrames;
+       }
+       if (minutes % 10 > 0) frames -= perMinute;
+       frames += duration.section(":",2,2).toInt() * m_displayedFramesPerSecond + duration.section(":",3,3).toInt();
+       return frames;  
+    }
+    return (int) ((duration.section(":",0,0).toInt()*3600.0 + duration.section(":",1,1).toInt()*60.0 + duration.section(":",2,2).toInt()) * fps + duration.section(":",3,3).toInt());
+}
+
+QString Timecode::getTimecode(const GenTime & time, double fps) const
+{
+    switch (m_format) {
+    case HH_MM_SS_FF:
+       return getTimecodeHH_MM_SS_FF(time, fps);
+       break;
+    case HH_MM_SS_HH:
+       return getTimecodeHH_MM_SS_HH(time);
+       break;
+    case Frames:
+       return getTimecodeFrames(time, fps);
+       break;
+    case Seconds:
+       return getTimecodeSeconds(time);
+       break;
+    default:
+       kWarning() <<
+           "Unknown timecode format specified, defaulting to HH_MM_SS_FF"
+           << endl;
+       return getTimecodeHH_MM_SS_FF(time, fps);
+    }
+}
+
+QString Timecode::getTimecodeFromFrames(int frames)
+{
+    return getTimecodeHH_MM_SS_FF(frames);
+}
+
+//static 
+QString Timecode::getEasyTimecode(const GenTime & time, const double &fps)
+{
+    // Returns the timecode in an easily read display, like 3 min. 5 sec.
+    int frames = (int)time.frames(fps);
+    int seconds = frames / (int) floor(fps + 0.5);
+    frames = frames % ((int) fps);
+
+    int minutes = seconds / 60;
+    seconds = seconds % 60;
+    int hours = minutes / 60;
+    minutes = minutes % 60;
+
+    QString text;
+    bool trim = false;
+
+    if (hours!= 0) {
+        text.append(QString::number(hours).rightJustified(2, '0', FALSE));
+        text.append(" " + i18n("hour") + " ");
+        trim = true;
+    }
+    if (minutes!= 0 || trim) {
+        if (!trim) {
+            text.append(QString::number(minutes));
+        }
+        else
+            text.append(QString::number(minutes).rightJustified(2, '0', FALSE));
+        text.append(" " + i18n("min.") + " ");
+        trim = true;
+    }
+    if (seconds!= 0 || trim) {
+        if (!trim) {
+            text.append(QString::number(seconds));
+        }
+        else 
+            text.append(QString::number(seconds).rightJustified(2, '0', FALSE));
+        text.append(" " + i18n("sec."));
+        trim = true;
+    }
+    if (!trim) {
+            text.append(QString::number(frames));
+            text.append(" " + i18n("frames"));
+    }
+
+    return text;
+}
+
+
+QString Timecode::getTimecodeHH_MM_SS_FF(const GenTime & time, double fps) const
+{
+    if (m_dropFrame)
+       return getTimecodeDropFrame(time, fps);
+
+    return getTimecodeHH_MM_SS_FF((int)time.frames(fps));
+}
+
+QString Timecode::getTimecodeHH_MM_SS_FF(int frames) const
+{
+    int seconds = frames / m_displayedFramesPerSecond;
+    frames = frames % m_displayedFramesPerSecond;
+
+    int minutes = seconds / 60;
+    seconds = seconds % 60;
+    int hours = minutes / 60;
+    minutes = minutes % 60;
+
+    QString text;
+
+    text.append(QString::number(hours).rightJustified(2, '0', FALSE));
+    text.append(":");
+    text.append(QString::number(minutes).rightJustified(2, '0', FALSE));
+    text.append(":");
+    text.append(QString::number(seconds).rightJustified(2, '0', FALSE));
+    text.append(":");
+    text.append(QString::number(frames).rightJustified(2, '0', FALSE));
+
+    return text;
+}
+
+QString Timecode::getTimecodeHH_MM_SS_HH(const GenTime & time) const
+{
+    int hundredths = (int)(time.seconds() * 100);
+    int seconds = hundredths / 100;
+    hundredths = hundredths % 100;
+    int minutes = seconds / 60;
+    seconds = seconds % 60;
+    int hours = minutes / 60;
+    minutes = minutes % 60;
+
+    QString text;
+
+    text.append(QString::number(hours).rightJustified(2, '0', FALSE));
+    text.append(":");
+    text.append(QString::number(minutes).rightJustified(2, '0', FALSE));
+    text.append(":");
+    text.append(QString::number(seconds).rightJustified(2, '0', FALSE));
+    text.append(":");
+    text.append(QString::number(hundredths).rightJustified(2, '0', FALSE));
+
+    return text;
+}
+
+QString Timecode::getTimecodeFrames(const GenTime & time, double fps) const
+{
+    return QString::number(time.frames(fps));
+}
+
+QString Timecode::getTimecodeSeconds(const GenTime & time) const
+{
+    return QString::number(time.seconds());
+}
+
+QString Timecode::getTimecodeDropFrame(const GenTime & time, double fps) const
+{
+    // Calculate the timecode using dropframes to remove the difference in fps. Note that this algorithm should work
+    // for NTSC times, but is untested for any others - it is in no way an "official" algorithm, unless it's by fluke.
+    int frames = (int)time.frames(fps);
+
+    // calculate how many frames need to be dropped every minute.
+    int toDrop = (int) floor (600.0 * (m_displayedFramesPerSecond - fps)  + 0.5);
+
+    int perMinute = toDrop / 9;
+    int tenthMinute = toDrop % 9;
+
+    // calculate how many frames are in a normal minute, and how many are in a tenth minute.
+    int normalMinuteFrames = (m_displayedFramesPerSecond * 60) - perMinute;
+    int tenthMinuteFrames = (m_displayedFramesPerSecond * 60) - tenthMinute;;
+
+    // Number of actual frames in a 10 minute interval :
+    int tenMinutes = (normalMinuteFrames * 9) + tenthMinuteFrames;
+
+    int tenMinuteIntervals = frames / tenMinutes;
+    frames = frames % tenMinutes;
+
+    int hours = tenMinuteIntervals / 6;
+    tenMinuteIntervals = tenMinuteIntervals % 6;
+
+    // At the point, we have figured out HH:M?:??:??
+
+    int numMinutes;
+
+    if (frames < tenthMinuteFrames) {
+       // tenth minute logic applies.
+       numMinutes = 0;
+    } else {
+       // normal minute logic applies.
+       numMinutes = 1 + (frames - tenthMinuteFrames) / normalMinuteFrames;
+       frames = (frames - tenthMinuteFrames) % normalMinuteFrames;
+       frames +=  tenthMinute + perMinute;
+    }
+    // We now have HH:MM:??:??
+
+    int seconds = frames / m_displayedFramesPerSecond;
+    frames = frames % m_displayedFramesPerSecond;
+
+    // We now have HH:MM:SS:FF
+
+    // THANK FUCK FOR THAT.
+
+    QString text;
+    text.append(QString::number(hours).rightJustified(2, '0', FALSE));
+    text.append(":");
+    text.append(QString::number(tenMinuteIntervals));
+    text.append(QString::number(numMinutes));
+    text.append(":");
+    text.append(QString::number(seconds).rightJustified(2, '0', FALSE));
+    text.append(":");
+    text.append(QString::number(frames).rightJustified(2, '0', FALSE));
+
+    return text;
+}
diff --git a/src/timecode.h b/src/timecode.h
new file mode 100644 (file)
index 0000000..b71393b
--- /dev/null
@@ -0,0 +1,67 @@
+/***************************************************************************
+                        timecode  -  description
+                           -------------------
+  begin                : Wed Dec 17 2003
+  copyright            : (C) 2003 by Jason Wood
+  email                : jasonwood@blueyonder.co.uk
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#ifndef TIMECODE_H
+#define TIMECODE_H
+
+#include <qstring.h>
+
+#include "gentime.h"
+
+/**
+Handles the conversion of a GenTime into a nicely formatted string, taking into account things such as drop frame if necessary. Handles multiple formats, such as HH:MM:SS:FF, HH:MM:SS:F, All Frames, All Seconds, etc.
+
+@author Jason Wood
+*/
+class Timecode {
+  public:
+    enum Formats { HH_MM_SS_FF, HH_MM_SS_HH, Frames, Seconds };
+
+     Timecode(Formats format = HH_MM_SS_FF, int framesPerSecond =
+       25, bool dropFrame = false);
+
+       /** Set the current timecode format; this is the output format for this timecode. */
+    void setFormat(int framesPerSecond, bool dropFrame = false, Formats format = HH_MM_SS_FF) {
+       m_displayedFramesPerSecond = framesPerSecond;
+       m_dropFrame = dropFrame;
+       m_format = format;
+    } 
+
+    Formats format() const {
+       return m_format;
+    } 
+
+    ~Timecode();
+
+       /** Returns the timecode for a given time */
+    QString getTimecode(const GenTime & time, double fps) const;
+    int getFrameNumber(const QString duration, double fps) const;
+    static QString getEasyTimecode(const GenTime & time, const double &fps);
+    QString getTimecodeFromFrames(int frames);
+  private:
+    Formats m_format;
+    bool m_dropFrame;
+    int m_displayedFramesPerSecond;
+
+    QString getTimecodeHH_MM_SS_FF(const GenTime & time, double fps) const;
+    QString getTimecodeHH_MM_SS_FF(int frames) const;
+    QString getTimecodeHH_MM_SS_HH(const GenTime & time) const;
+    QString getTimecodeFrames(const GenTime & time, double fps) const;
+    QString getTimecodeSeconds(const GenTime & time) const;
+    QString getTimecodeDropFrame(const GenTime & time, double fps) const;
+};
+
+#endif
diff --git a/src/trackview.cpp b/src/trackview.cpp
new file mode 100644 (file)
index 0000000..5463237
--- /dev/null
@@ -0,0 +1,33 @@
+
+#include <QMouseEvent>
+#include <QStylePainter>
+
+#include <KDebug>
+
+
+#include "trackview.h"
+
+TrackView::TrackView(KdenliveDoc *doc, QWidget *parent)
+    : QWidget(parent), m_doc(doc)
+{
+  view = new Ui::TimeLine_UI();
+  view->setupUi(this);
+  m_ruler = new CustomRuler();
+  QVBoxLayout *layout = new QVBoxLayout;
+  layout->addWidget(m_ruler);
+  view->ruler_frame->setLayout(layout);
+
+  connect(view->horizontalSlider, SIGNAL(valueChanged ( int )), this, SLOT(slotChangeZoom( int )));
+}
+
+void TrackView::slotChangeZoom(int factor)
+{
+  m_ruler->setPixelPerMark(factor);
+}
+
+KdenliveDoc *TrackView::document()
+{
+  return m_doc;
+}
+
+#include "trackview.moc"
diff --git a/src/trackview.h b/src/trackview.h
new file mode 100644 (file)
index 0000000..63340c3
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef TRACKVIEW_H
+#define TRACKVIEW_H
+
+#include <KRuler>
+#include "ui_timeline_ui.h"
+#include "customruler.h"
+#include "kdenlivedoc.h"
+
+class TrackView : public QWidget
+{
+  Q_OBJECT
+  
+  public:
+    TrackView(KdenliveDoc *doc, QWidget *parent=0);
+
+  public slots:
+    KdenliveDoc *document();
+
+  private:
+    Ui::TimeLine_UI *view;
+    CustomRuler *m_ruler;
+    KdenliveDoc *m_doc;
+
+  private slots:
+    void slotChangeZoom(int factor);
+};
+
+#endif
diff --git a/src/widgets/monitor_ui.ui b/src/widgets/monitor_ui.ui
new file mode 100644 (file)
index 0000000..e32fb9d
--- /dev/null
@@ -0,0 +1,302 @@
+<ui version="4.0" >
+ <class>Monitor_UI</class>
+ <widget class="QWidget" name="Monitor_UI" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>365</width>
+    <height>249</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" >
+   <item row="0" column="0" colspan="2" >
+    <widget class="QFrame" name="video_frame" >
+     <property name="frameShape" >
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow" >
+      <enum>QFrame::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0" colspan="2" >
+    <widget class="KRuler" name="monitor_ruler" />
+   </item>
+   <item row="2" column="0" >
+    <layout class="QHBoxLayout" >
+     <property name="spacing" >
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="KPushButton" name="button_play" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="button_rew" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="button_play_2" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_18" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_19" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_20" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="3" column="0" >
+    <layout class="QHBoxLayout" >
+     <property name="spacing" >
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_9" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_10" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_11" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_12" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_13" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="kpushbutton_14" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize" >
+        <size>
+         <width>40</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="flat" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="3" column="1" >
+    <widget class="KRestrictedLine" name="krestrictedline" >
+     <property name="inputMask" >
+      <string>99:99:99:99; </string>
+     </property>
+     <property name="validChars" >
+      <string/>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KPushButton</class>
+   <extends>QPushButton</extends>
+   <header>kpushbutton.h</header>
+  </customwidget>
+  <customwidget>
+   <class>KRestrictedLine</class>
+   <extends>KLineEdit</extends>
+   <header>krestrictedline.h</header>
+  </customwidget>
+  <customwidget>
+   <class>KRuler</class>
+   <extends>QWidget</extends>
+   <header>kruler.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/widgets/projectlist_ui.ui b/src/widgets/projectlist_ui.ui
new file mode 100644 (file)
index 0000000..17edccb
--- /dev/null
@@ -0,0 +1,69 @@
+<ui version="4.0" >
+ <class>ProjectList_UI</class>
+ <widget class="QWidget" name="ProjectList_UI" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>347</width>
+    <height>205</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" >
+   <item row="0" column="0" >
+    <widget class="KTreeWidgetSearchLine" name="project_search" />
+   </item>
+   <item row="0" column="1" >
+    <widget class="KPushButton" name="button_add" />
+   </item>
+   <item row="0" column="2" >
+    <widget class="KPushButton" name="button_edit" />
+   </item>
+   <item row="0" column="3" >
+    <widget class="KPushButton" name="button_delete" />
+   </item>
+   <item row="1" column="0" colspan="4" >
+    <widget class="QTreeWidget" name="project_list" >
+     <property name="alternatingRowColors" >
+      <bool>true</bool>
+     </property>
+     <property name="allColumnsShowFocus" >
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text" >
+       <string>Thumb</string>
+      </property>
+     </column>
+     <column>
+      <property name="text" >
+       <string>Filename</string>
+      </property>
+     </column>
+     <column>
+      <property name="text" >
+       <string>Description</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KPushButton</class>
+   <extends>QPushButton</extends>
+   <header>kpushbutton.h</header>
+  </customwidget>
+  <customwidget>
+   <class>KTreeWidgetSearchLine</class>
+   <extends>KLineEdit</extends>
+   <header>ktreewidgetsearchline.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/widgets/timeline_ui.ui b/src/widgets/timeline_ui.ui
new file mode 100644 (file)
index 0000000..1d4d06e
--- /dev/null
@@ -0,0 +1,77 @@
+<ui version="4.0" >
+ <class>TimeLine_UI</class>
+ <widget class="QWidget" name="TimeLine_UI" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>390</width>
+    <height>288</height>
+   </rect>
+  </property>
+  <layout class="QGridLayout" >
+   <property name="topMargin" >
+    <number>0</number>
+   </property>
+   <item row="0" column="0" >
+    <widget class="QSlider" name="horizontalSlider" >
+     <property name="maximumSize" >
+      <size>
+       <width>100</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="minimum" >
+      <number>0</number>
+     </property>
+     <property name="maximum" >
+      <number>13</number>
+     </property>
+     <property name="singleStep" >
+      <number>1</number>
+     </property>
+     <property name="pageStep" >
+      <number>3</number>
+     </property>
+     <property name="value" >
+      <number>5</number>
+     </property>
+     <property name="sliderPosition" >
+      <number>5</number>
+     </property>
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1" >
+    <widget class="QFrame" name="ruler_frame" >
+     <property name="sizePolicy" >
+      <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="frameShape" >
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow" >
+      <enum>QFrame::Raised</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0" colspan="2" >
+    <widget class="QFrame" name="frame" >
+     <property name="frameShape" >
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow" >
+      <enum>QFrame::Raised</enum>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>