From: Jean-Baptiste Mardelle Date: Fri, 2 May 2008 13:31:01 +0000 (+0000) Subject: *Re-introduce slideshow clips X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=3d8380d9471c13f2fda9ca9270a0bc1e416fabe1;p=kdenlive *Re-introduce slideshow clips *color of color clips can now be edited *cleanup svn path=/branches/KDE4/; revision=2169 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d75bebed..c08a1d86 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,7 @@ kde4_add_ui_files(kdenlive_UI widgets/monitor_ui.ui widgets/recmonitor_ui.ui widgets/colorclip_ui.ui + widgets/slideshowclip_ui.ui widgets/configmisc_ui.ui widgets/configenv_ui.ui widgets/configdisplay_ui.ui @@ -104,6 +105,7 @@ set(kdenlive_SRCS editfoldercommand.cpp clipproperties.cpp movetransitioncommand.cpp + slideshowclip.cpp ) kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc ) diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 21d24e3d..d3ce230d 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -45,13 +45,12 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) setRect(rect); kDebug() << "///// NEW CLIP RECT: " << rect; m_fps = fps; - m_xml = clip->toXML(); m_clipName = clip->name(); m_producer = clip->getId(); m_clipType = clip->clipType(); m_cropStart = GenTime(); - m_maxDuration = m_cropDuration; + m_maxDuration = clip->maxDuration(); setAcceptDrops(true); audioThumbReady = clip->audioThumbCreated(); /* @@ -68,7 +67,7 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) connect(this , SIGNAL(prepareAudioThumb(double, QPainterPath, int, int)) , this, SLOT(slotPrepareAudioThumb(double, QPainterPath, int, int))); setBrush(QColor(141, 166, 215)); - if (m_clipType == VIDEO || m_clipType == AV) { + if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW) { m_hasThumbs = true; connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int))); connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); @@ -81,15 +80,12 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) endThumbTimer = new QTimer(this); endThumbTimer->setSingleShot(true); connect(endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb())); - } else if (m_clipType == COLOR) { - m_maxDuration = GenTime(10000, m_fps); - QString colour = m_xml.attribute("colour"); + QString colour = clip->getProperty("colour"); colour = colour.replace(0, 2, "#"); setBrush(QColor(colour.left(7))); } else if (m_clipType == IMAGE || m_clipType == TEXT) { - m_maxDuration = GenTime(10000, m_fps); - m_startPix = KThumb::getImage(KUrl(m_xml.attribute("resource")), (int)(50 * KdenliveSettings::project_display_ratio()), 50); + m_startPix = KThumb::getImage(KUrl(clip->getProperty("resource")), (int)(50 * KdenliveSettings::project_display_ratio()), 50); m_endPix = m_startPix; } else if (m_clipType == AUDIO) { connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); @@ -107,6 +103,20 @@ void ClipItem::resetThumbs() { audioThumbCachePic.clear(); } + +void ClipItem::refreshClip() { + m_maxDuration = m_clip->maxDuration(); + if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW) slotFetchThumbs(); + else if (m_clipType == COLOR) { + QString colour = m_clip->getProperty("colour"); + colour = colour.replace(0, 2, "#"); + setBrush(QColor(colour.left(7))); + } else if (m_clipType == IMAGE || m_clipType == TEXT) { + m_startPix = KThumb::getImage(KUrl(m_clip->getProperty("resource")), (int)(50 * KdenliveSettings::project_display_ratio()), 50); + m_endPix = m_startPix; + } +} + void ClipItem::slotFetchThumbs() { m_thumbsRequested += 2; emit getThumb((int)m_cropStart.frames(m_fps), (int)(m_cropStart + m_cropDuration).frames(m_fps)); @@ -144,7 +154,7 @@ DocClipBase *ClipItem::baseClip() { } QDomElement ClipItem::xml() const { - return m_xml; + return m_clip->toXML(); } int ClipItem::clipType() { diff --git a/src/clipitem.h b/src/clipitem.h index f9de3c1a..992a8f81 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -75,6 +75,8 @@ public: void addTransition(Transition*); /** regenerate audio and video thumbnails */ void resetThumbs(); + /** update clip properties from base clip */ + void refreshClip(); protected: virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); @@ -87,7 +89,6 @@ protected: virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *); private: - QDomElement m_xml; DocClipBase *m_clip; OPERATIONTYPE m_resizeMode; int m_grabPoint; diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index 9b43fed2..6feccc28 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -128,6 +128,26 @@ void ClipManager::slotAddColorClipFile(const QString name, const QString color, m_doc->commandStack()->push(command); } +void ClipManager::slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, QString group, const int groupId) { + QDomDocument doc; + QDomElement prod = doc.createElement("producer"); + prod.setAttribute("resource", path); + prod.setAttribute("type", (int) SLIDESHOW); + uint id = m_clipIdCounter++; + prod.setAttribute("id", QString::number(id)); + prod.setAttribute("in", "0"); + prod.setAttribute("out", m_doc->getFramePos(duration) * count); + prod.setAttribute("ttl", m_doc->getFramePos(duration)); + prod.setAttribute("name", name); + prod.setAttribute("loop", loop); + if (!group.isEmpty()) { + prod.setAttribute("groupname", group); + prod.setAttribute("groupid", groupId); + } + AddClipCommand *command = new AddClipCommand(m_doc, prod, id, true); + m_doc->commandStack()->push(command); +} + void ClipManager::slotAddTextClipFile(const QString path, const QString group, const int groupId) { diff --git a/src/clipmanager.h b/src/clipmanager.h index d4062aef..2fac528a 100644 --- a/src/clipmanager.h +++ b/src/clipmanager.h @@ -51,6 +51,7 @@ Q_OBJECT public: void slotAddClipFile(const KUrl url, const QString group, const int groupId); void slotAddTextClipFile(const QString path, const QString group, const int groupId); void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const int groupId); + void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, bool loop, const QString group, const int groupId); DocClipBase *getClipById(int clipId); void slotDeleteClip(uint clipId); void setThumbsProgress(KUrl url, int progress); diff --git a/src/clipproperties.cpp b/src/clipproperties.cpp index 81e4c88a..6268a478 100644 --- a/src/clipproperties.cpp +++ b/src/clipproperties.cpp @@ -27,6 +27,17 @@ #include "clipproperties.h" #include "kthumb.h" +#define VIDEOTAB 0 +#define AUDIOTAB 1 +#define COLORTAB 2 +#define SLIDETAB 3 +#define ADVANCEDTAB 4 + +#define TYPE_JPEG 0 +#define TYPE_PNG 1 +#define TYPE_BMP 2 +#define TYPE_GIF 3 + ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidget * parent): QDialog(parent), m_tc(tc), m_clip(clip), m_fps(fps) { setFont(KGlobalSettings::toolBarFont()); m_view.setupUi(this); @@ -36,28 +47,54 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg QMap props = m_clip->properties(); if (props.contains("audiocodec")) - m_view.clip_acodec->setText(props["audiocodec"]); + m_view.clip_acodec->setText(props.value("audiocodec")); if (props.contains("frequency")) - m_view.clip_frequency->setText(props["frequency"]); + m_view.clip_frequency->setText(props.value("frequency")); if (props.contains("channels")) - m_view.clip_channels->setText(props["channels"]); + m_view.clip_channels->setText(props.value("channels")); CLIPTYPE t = m_clip->clipType(); - if (t != AUDIO) { + if (t == COLOR) { + m_view.clip_path->setEnabled(false); + m_view.tabWidget->removeTab(SLIDETAB); + m_view.tabWidget->removeTab(AUDIOTAB); + m_view.tabWidget->removeTab(VIDEOTAB); + m_view.clip_thumb->setHidden(true); + m_view.clip_color->setColor(QColor("#" + props.value("colour").right(8).left(6))); + } + else if (t == SLIDESHOW) { + m_view.tabWidget->removeTab(COLORTAB); + m_view.tabWidget->removeTab(AUDIOTAB); + m_view.tabWidget->removeTab(VIDEOTAB); + QStringList types; + types << "JPG" << "PNG" << "BMP" << "GIF"; + m_view.image_type->addItems(types); + m_view.slide_loop->setChecked(props.value("loop").toInt()); + QString path = props.value("resource"); + if (path.endsWith("png")) m_view.image_type->setCurrentIndex(TYPE_PNG); + else if (path.endsWith("bmp")) m_view.image_type->setCurrentIndex(TYPE_BMP); + else if (path.endsWith("gif")) m_view.image_type->setCurrentIndex(TYPE_GIF); + m_view.slide_duration->setText(tc.getTimecodeFromFrames(props.value("ttl").toInt())); + } + else if (t != AUDIO) { + m_view.tabWidget->removeTab(SLIDETAB); + m_view.tabWidget->removeTab(COLORTAB); if (props.contains("frame_size")) - m_view.clip_size->setText(props["frame_size"]); + m_view.clip_size->setText(props.value("frame_size")); if (props.contains("videocodec")) - m_view.clip_vcodec->setText(props["videocodec"]); + m_view.clip_vcodec->setText(props.value("videocodec")); if (props.contains("fps")) - m_view.clip_fps->setText(props["fps"]); + m_view.clip_fps->setText(props.value("fps")); if (props.contains("aspect_ratio")) - m_view.clip_ratio->setText(props["aspect_ratio"]); + m_view.clip_ratio->setText(props.value("aspect_ratio")); QPixmap pix = m_clip->thumbProducer()->getImage(url, 240, 180); m_view.clip_thumb->setPixmap(pix); - if (t == IMAGE || t == VIDEO || t == COLOR) m_view.tabWidget->removeTab(1); + if (t == IMAGE || t == VIDEO) m_view.tabWidget->removeTab(AUDIOTAB); } else { - m_view.tabWidget->removeTab(0); + m_view.tabWidget->removeTab(SLIDETAB); + m_view.tabWidget->removeTab(COLORTAB); + m_view.tabWidget->removeTab(VIDEOTAB); m_view.clip_thumb->setHidden(true); } if (t != IMAGE && t != COLOR && t != TEXT) m_view.clip_duration->setReadOnly(true); @@ -72,9 +109,20 @@ int ClipProperties::clipId() { return m_clip->getId(); } + QMap ClipProperties::properties() { QMap props; props["description"] = m_view.clip_description->text(); + CLIPTYPE t = m_clip->clipType(); + if (t == SLIDESHOW) { + props["loop"] = QString::number((int) m_view.slide_loop->isChecked()); + } + else if (t == COLOR) { + QMap old_props = m_clip->properties(); + QString new_color = m_view.clip_color->color().name(); + if (new_color != QString("#" + old_props.value("colour").right(8).left(6))) + props["colour"] = "0x" + new_color.right(6) + "ff"; + } return props; } diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index b25d863d..e6018196 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -903,6 +903,20 @@ void CustomTrackView::addClip(QDomElement xml, int clipId, ItemInfo info) { m_document->renderer()->doRefresh(); } +void CustomTrackView::slotUpdateClip(int clipId) { + QList list = scene()->items(); + ClipItem *clip = NULL; + for (int i = 0; i < list.size(); ++i) { + if (list.at(i)->type() == AVWIDGET) { + clip = static_cast (list.at(i)); + if (clip->clipProducer() == clipId) { + clip->refreshClip(); + m_document->renderer()->mltUpdateClip(m_tracksList.count() - clip->track(), clip->startPos(), clip->xml()); + } + } + } +} + ClipItem *CustomTrackView::getClipItemAt(int pos, int track) { QList list = scene()->items(QPointF(pos * m_scale, track * m_tracksHeight + m_tracksHeight / 2)); ClipItem *clip = NULL; diff --git a/src/customtrackview.h b/src/customtrackview.h index 09c52724..6d21ade0 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -87,6 +87,7 @@ public slots: void slotTransitionUpdated(Transition *, QDomElement); void slotSwitchTrackAudio(int ix); void slotSwitchTrackVideo(int ix); + void slotUpdateClip(int clipId); protected: virtual void drawBackground(QPainter * painter, const QRectF & rect); diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index 5b85e6cc..1142ba1a 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -156,6 +156,14 @@ const GenTime &DocClipBase::duration() const { return m_duration; } +const GenTime &DocClipBase::maxDuration() const { + if (m_clipType == COLOR || m_clipType == IMAGE || m_clipType == TEXT || (m_clipType == SLIDESHOW && m_properties.value("loop") == "1")) { + GenTime dur(10000, KdenliveSettings::project_fps()); + return dur; + } + return m_duration; +} + bool DocClipBase::hasFileSize() const { return true; } @@ -367,11 +375,14 @@ void DocClipBase::setProperties(QMap properties) { } } +void DocClipBase::setProperty(QString key, QString value) { + m_properties.insert(key, value); +} + QMap DocClipBase::properties() const { return m_properties; } - void DocClipBase::slotGetAudioThumbs() { if (m_audioThumbCreated) { diff --git a/src/docclipbase.h b/src/docclipbase.h index e7ec0ae3..753ec2bb 100644 --- a/src/docclipbase.h +++ b/src/docclipbase.h @@ -87,6 +87,7 @@ Q_OBJECT public: /** Returns any property of this clip. */ const QString getProperty(const QString prop) const; + void setProperty(QString key, QString value); /** Returns the internal unique id of the clip. */ uint getId() const; @@ -97,6 +98,7 @@ Q_OBJECT public: /** returns the duration of this clip */ const GenTime & duration() const; + const GenTime &maxDuration() const; /** returns the duration of this clip */ void setDuration(GenTime dur); diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index df368746..1fe1bb32 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -379,6 +379,11 @@ void KdenliveDoc::slotAddColorClipFile(const QString name, const QString color, setModified(true); } +void KdenliveDoc::slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, bool loop, const QString group, const int groupId) { + m_clipManager->slotAddSlideshowClipFile(name, path, count, duration, loop, group, groupId); + setModified(true); +} + void KdenliveDoc::slotCreateTextClip(QString group, int groupId) { QString titlesFolder = projectFolder().path() + "/titles/"; KStandardDirs::makeDir(titlesFolder); diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index cfb922f9..a3de7ba1 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -69,6 +69,7 @@ Q_OBJECT public: void slotDeleteFolder(const QString folderName, const int id); void slotEditFolder(const QString folderName, const QString oldfolderName, int clipId); void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const int groupId = -1); + void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, bool loop, const QString group, const int groupId = -1); void deleteClip(const uint clipId); int getFramePos(QString duration); DocClipBase *getBaseClip(int clipId); diff --git a/src/kdenlivesettings.kcfg b/src/kdenlivesettings.kcfg index 4e94371e..eb59244d 100644 --- a/src/kdenlivesettings.kcfg +++ b/src/kdenlivesettings.kcfg @@ -169,6 +169,10 @@ 1.7777778 + + + 25 + hdv_1080_50i diff --git a/src/kthumb.cpp b/src/kthumb.cpp index 8f1b9d47..9d47cf48 100644 --- a/src/kthumb.cpp +++ b/src/kthumb.cpp @@ -220,7 +220,25 @@ QPixmap KThumb::getImage(KUrl url, int frame, int width, int height) { return pix; } return getFrame(&producer, frame, width, height); +} + +QPixmap KThumb::getImage(QDomElement xml, int frame, int width, int height) { + Mlt::Profile profile((char*) KdenliveSettings::current_profile().data()); + QPixmap pix(width, height); + QDomDocument doc; + QDomElement westley = doc.createElement("westley"); + doc.appendChild(westley); + westley.appendChild(doc.importNode(xml, true)); + char *tmp = Render::decodedString(doc.toString()); + kDebug()<<" - - - UPDATING THMB, XML: "<timecode(), m_activeDocument->fps(), this); if (dia.exec() == QDialog::Accepted) { m_projectList->slotUpdateClipProperties(dia.clipId(), dia.properties()); + // update clip in timeline + TrackView *currentTab = (TrackView *) m_timelineArea->currentWidget(); + currentTab->projectView()->slotUpdateClip(dia.clipId()); + } } diff --git a/src/projectitem.cpp b/src/projectitem.cpp index 3d7a98fe..e32b3e6b 100644 --- a/src/projectitem.cpp +++ b/src/projectitem.cpp @@ -40,32 +40,32 @@ const int UsageRole = NameRole + 2; ProjectItem::ProjectItem(QTreeWidget * parent, const QStringList & strings, QDomElement xml, int clipId) : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_clipType(UNKNOWN), m_clipId(clipId) { - m_element = xml.cloneNode().toElement(); + QDomElement element = xml.cloneNode().toElement(); setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); - if (!m_element.isNull()) { - m_element.setAttribute("id", clipId); - QString cType = m_element.attribute("type", QString::null); + if (!element.isNull()) { + element.setAttribute("id", clipId); + QString cType = element.attribute("type", QString::null); if (!cType.isEmpty()) { m_clipType = (CLIPTYPE) cType.toInt(); slotSetToolTip(); } - if (m_clipType == COLOR || m_clipType == IMAGE) m_element.setAttribute("duration", MAXCLIPDURATION); - else if (m_element.attribute("duration").isEmpty() && !m_element.attribute("out").isEmpty()) { - m_element.setAttribute("duration", m_element.attribute("out").toInt() - m_element.attribute("in").toInt()); + if (m_clipType == COLOR || m_clipType == IMAGE) element.setAttribute("duration", MAXCLIPDURATION); + else if (element.attribute("duration").isEmpty() && !element.attribute("out").isEmpty()) { + element.setAttribute("duration", element.attribute("out").toInt() - element.attribute("in").toInt()); } } } ProjectItem::ProjectItem(QTreeWidgetItem * parent, const QStringList & strings, QDomElement xml, int clipId) : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_clipType(UNKNOWN), m_clipId(clipId) { - m_element = xml.cloneNode().toElement(); + QDomElement element = xml.cloneNode().toElement(); setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); - if (!m_element.isNull()) { - m_element.setAttribute("id", clipId); - QString cType = m_element.attribute("type", QString::null); + if (!element.isNull()) { + element.setAttribute("id", clipId); + QString cType = element.attribute("type", QString::null); if (!cType.isEmpty()) { m_clipType = (CLIPTYPE) cType.toInt(); slotSetToolTip(); @@ -75,7 +75,7 @@ ProjectItem::ProjectItem(QTreeWidgetItem * parent, const QStringList & strings, // folder ProjectItem::ProjectItem(QTreeWidget * parent, const QStringList & strings, int clipId) - : QTreeWidgetItem(parent, strings), m_element(QDomElement()), m_clipType(FOLDER), m_groupName(strings.at(1)), m_clipId(clipId), m_clip(NULL) { + : QTreeWidgetItem(parent, strings), m_clipType(FOLDER), m_groupName(strings.at(1)), m_clipId(clipId), m_clip(NULL) { setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); setIcon(0, KIcon("folder")); @@ -87,11 +87,10 @@ ProjectItem::ProjectItem(QTreeWidget * parent, DocClipBase *clip) setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); m_clip = clip; - m_element = clip->toXML(); m_clipId = clip->getId(); - QString name = m_element.attribute("name"); - if (name.isEmpty()) name = KUrl(m_element.attribute("resource")).fileName(); - m_clipType = (CLIPTYPE) m_element.attribute("type").toInt(); + QString name = m_clip->getProperty("name"); + if (name.isEmpty()) name = KUrl(m_clip->getProperty("resource")).fileName(); + m_clipType = (CLIPTYPE) m_clip->getProperty("type").toInt(); setText(1, name); kDebug() << "PROJECT ITE;. ADDING LCIP: " << m_clipId; } @@ -101,11 +100,10 @@ ProjectItem::ProjectItem(QTreeWidgetItem * parent, DocClipBase *clip) setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); m_clip = clip; - m_element = clip->toXML(); m_clipId = clip->getId(); - QString name = m_element.attribute("name"); - if (name.isEmpty()) name = KUrl(m_element.attribute("resource")).fileName(); - m_clipType = (CLIPTYPE) m_element.attribute("type").toInt(); + QString name = m_clip->getProperty("name"); + if (name.isEmpty()) name = KUrl(m_clip->getProperty("resource")).fileName(); + m_clipType = (CLIPTYPE) m_clip->getProperty("type").toInt(); setText(1, name); kDebug() << "PROJECT ITE;. ADDING LCIP: " << m_clipId; } @@ -128,7 +126,7 @@ CLIPTYPE ProjectItem::clipType() const { } int ProjectItem::clipMaxDuration() const { - return m_element.attribute("duration").toInt(); + return m_clip->getProperty("duration").toInt(); } bool ProjectItem::isGroup() const { @@ -152,17 +150,17 @@ QStringList ProjectItem::names() const { } QDomElement ProjectItem::toXml() const { - return m_element; + return m_clip->toXML(); } const KUrl ProjectItem::clipUrl() const { - if (m_clipType != COLOR && m_clipType != VIRTUAL && m_clipType != UNKNOWN) - return KUrl(m_element.attribute("resource")); + if (m_clipType != COLOR && m_clipType != VIRTUAL && m_clipType != UNKNOWN && m_clipType != FOLDER) + return KUrl(m_clip->getProperty("resource")); else return KUrl(); } void ProjectItem::changeDuration(int frames) { - m_element.setAttribute("duration", frames); + m_clip->setProperty("duration", QString::number(frames)); m_duration = GenTime(frames, 25); setData(1, DurationRole, Timecode::getEasyTimecode(m_duration, 25)); m_durationKnown = true; @@ -191,7 +189,7 @@ void ProjectItem::slotSetToolTip() { break; case 4: tip.append(i18n("Color clip")); - setData(1, DurationRole, Timecode::getEasyTimecode(GenTime(m_element.attribute("out", "250").toInt(), 25), 25)); + setData(1, DurationRole, Timecode::getEasyTimecode(GenTime(m_clip->getProperty("out").toInt(), 25), 25)); break; case 5: tip.append(i18n("Image clip") + "
" + clipUrl().path()); @@ -218,7 +216,7 @@ void ProjectItem::slotSetToolTip() { void ProjectItem::setProperties(const QMap < QString, QString > &attributes, const QMap < QString, QString > &metadata) { if (attributes.contains("duration")) { - if (m_clipType == AUDIO || m_clipType == VIDEO || m_clipType == AV) m_element.setAttribute("duration", attributes["duration"].toInt()); + if (m_clipType == AUDIO || m_clipType == VIDEO || m_clipType == AV) m_clip->setProperty("duration", attributes["duration"]); m_duration = GenTime(attributes["duration"].toInt(), 25); setData(1, DurationRole, Timecode::getEasyTimecode(m_duration, 25)); m_durationKnown = true; @@ -249,14 +247,6 @@ void ProjectItem::setProperties(const QMap < QString, QString > &attributes, con m_clip->setClipType(m_clipType); } slotSetToolTip(); - if (m_element.isNull()) { - QDomDocument doc; - m_element = doc.createElement("producer"); - } - if (m_element.attribute("duration") == QString::null) m_element.setAttribute("duration", attributes["duration"].toInt()); - m_element.setAttribute("resource", attributes["filename"]); - m_element.setAttribute("type", (int) m_clipType); - if (KdenliveSettings::audiothumbnails()) m_clip->slotRequestAudioThumbs(); m_clip->setProperties(attributes); diff --git a/src/projectitem.h b/src/projectitem.h index cffb513c..2b52c89d 100644 --- a/src/projectitem.h +++ b/src/projectitem.h @@ -57,7 +57,6 @@ public: void setProperties(QMap props); private: - QDomElement m_element; GenTime m_duration; QString m_groupName; bool m_durationKnown; diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 33678dc9..2da1928d 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -40,8 +40,10 @@ #include "projectlist.h" #include "projectitem.h" #include "kdenlivesettings.h" +#include "slideshowclip.h" #include "ui_colorclip_ui.h" + #include "definitions.h" #include "clipmanager.h" #include "docclipbase.h" @@ -75,6 +77,9 @@ ProjectList::ProjectList(QWidget *parent) QAction *addColorClip = addMenu->addAction(KIcon("document-new"), i18n("Add Color Clip")); connect(addColorClip, SIGNAL(triggered()), this, SLOT(slotAddColorClip())); + QAction *addSlideClip = addMenu->addAction(KIcon("document-new"), i18n("Add Slideshow Clip")); + connect(addSlideClip, SIGNAL(triggered()), this, SLOT(slotAddSlideshowClip())); + QAction *addTitleClip = addMenu->addAction(KIcon("document-new"), i18n("Add Title Clip")); connect(addTitleClip, SIGNAL(triggered()), this, SLOT(slotAddTitleClip())); @@ -134,7 +139,10 @@ void ProjectList::slotClipSelected() { void ProjectList::slotUpdateClipProperties(int id, QMap properties) { ProjectItem *item = getItemById(id); - if (item) slotUpdateClipProperties(item, properties); + if (item) { + slotUpdateClipProperties(item, properties); + if (properties.contains("colour")) slotRefreshClipThumbnail(item); + } } void ProjectList::slotUpdateClipProperties(ProjectItem *clip, QMap properties) { @@ -410,6 +418,31 @@ void ProjectList::slotAddColorClip() { delete dia; } + +void ProjectList::slotAddSlideshowClip() { + if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!!  NO CMD STK"; + SlideshowClip *dia = new SlideshowClip(); + + if (dia->exec() == QDialog::Accepted) { + + QString group = QString(); + int groupId = -1; + ProjectItem *item = static_cast (listView->currentItem()); + if (item && item->clipType() != FOLDER) { + while (item->parent()) { + item = static_cast (item->parent()); + if (item->clipType() == FOLDER) break; + } + } + if (item && item->clipType() == FOLDER) { + group = item->groupName(); + groupId = item->clipId(); + } + + m_doc->slotAddSlideshowClipFile(dia->clipName(), dia->selectedPath(), dia->imageCount(), dia->clipDuration(), dia->loop(), group, groupId); + } + delete dia; +} void ProjectList::slotAddTitleClip() { QString group = QString(); int groupId = -1; @@ -427,6 +460,7 @@ void ProjectList::slotAddTitleClip() { m_doc->slotCreateTextClip(group, groupId); } + void ProjectList::setDocument(KdenliveDoc *doc) { listView->clear(); QList list = doc->clipManager()->documentClipList(); @@ -468,10 +502,15 @@ QDomElement ProjectList::producersList() { void ProjectList::slotRefreshClipThumbnail(int clipId) { ProjectItem *item = getItemById(clipId); + if (item) slotRefreshClipThumbnail(item); +} + +void ProjectList::slotRefreshClipThumbnail(ProjectItem *item) { if (item) { int height = 40; int width = (int)(height * (double) m_render->renderWidth() / m_render->renderHeight()); - QPixmap pix = KThumb::getImage(item->clipUrl(), item->referencedClip()->getProjectThumbFrame(), width, height); + QPixmap pix = KThumb::getImage(item->toXml(), item->referencedClip()->getProjectThumbFrame(), width, height); + //QPixmap pix = KThumb::getFrame(item->toXml()), 0, width, height); item->setIcon(0, pix); } } diff --git a/src/projectlist.h b/src/projectlist.h index 4bc08c82..1c03bc62 100644 --- a/src/projectlist.h +++ b/src/projectlist.h @@ -117,6 +117,7 @@ public slots: void slotDeleteClip(int clipId); void slotUpdateClip(int id); void slotRefreshClipThumbnail(int clipId); + void slotRefreshClipThumbnail(ProjectItem *item); private: @@ -141,6 +142,7 @@ private slots: void slotRemoveClip(); void slotClipSelected(); void slotAddColorClip(); + void slotAddSlideshowClip(); void slotAddTitleClip(); void slotContextMenu(const QPoint &pos, QTreeWidgetItem *); void slotAddFolder(); diff --git a/src/renderer.cpp b/src/renderer.cpp index 823b3b2f..5f161c2a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -378,7 +378,7 @@ void Render::getFileProperties(const QDomElement &xml, int clipId) { QDomElement westley = doc.createElement("westley"); doc.appendChild(westley); westley.appendChild(doc.importNode(xml, true)); - kDebug() << "////////////\n" << doc.toString() << "////////////////\n"; + //kDebug() << "////////////\n" << doc.toString() << "////////////////\n"; char *tmp = decodedString(doc.toString()); Mlt::Producer producer(*m_mltProfile, "westley-xml", tmp); @@ -1065,6 +1065,12 @@ void Render::mltCutClip(int track, GenTime position) { m_isBlocked = false; } +void Render::mltUpdateClip(int track, GenTime position, QDomElement element) { + // TODO: optimize + mltCutClip(track, position); + mltInsertClip(track, position, element); +} + void Render::mltRemoveClip(int track, GenTime position) { m_isBlocked = true; diff --git a/src/renderer.h b/src/renderer.h index 82fde528..173ed216 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -147,6 +147,7 @@ Q_OBJECT public: /** Playlist manipulation */ void mltInsertClip(int track, GenTime position, QDomElement element); + void mltUpdateClip(int track, GenTime position, QDomElement element); 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); diff --git a/src/slideshowclip.cpp b/src/slideshowclip.cpp new file mode 100644 index 00000000..80ecf220 --- /dev/null +++ b/src/slideshowclip.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include + +#include +#include +#include + +#include "kdenlivesettings.h" +#include "slideshowclip.h" + +#define TYPE_JPEG 0 +#define TYPE_PNG 1 +#define TYPE_BMP 2 +#define TYPE_GIF 3 + +SlideshowClip::SlideshowClip(QWidget * parent): QDialog(parent), m_count(0) { + setFont(KGlobalSettings::toolBarFont()); + //wsetCaption(i18n("Add Slideshow Clip")); + m_view.setupUi(this); + m_view.clip_name->setText(i18n("Slideshow Clip")); + m_view.folder_url->setMode(KFile::Directory); + m_view.icon_list->setIconSize(QSize(50, 50)); + connect(m_view.folder_url, SIGNAL(textChanged(const QString &)), this, SLOT(parseFolder())); + connect(m_view.image_type, SIGNAL(currentIndexChanged ( int )), this, SLOT(parseFolder())); + m_view.image_type->addItem("JPG"); + m_view.image_type->addItem("PNG"); + m_view.image_type->addItem("BMP"); + m_view.image_type->addItem("GIF"); + m_view.clip_duration->setText("00:00:03:00"); + adjustSize(); +} + +void SlideshowClip::parseFolder() { + m_view.icon_list->clear(); + QDir dir(m_view.folder_url->url().path()); + QStringList filters; + switch (m_view.image_type->currentIndex()) { + case TYPE_PNG: + filters << "*.png"; + break; + case TYPE_BMP: + filters << "*.bmp"; + break; + case TYPE_GIF: + filters << "*.gif"; + break; + default: + filters << "*.jpg" << "*.jpeg"; + break; + } + + dir.setNameFilters(filters); + QStringList result = dir.entryList(QDir::Files); + m_count = result.count(); + m_view.label_info->setText(i18n("%1 images found", m_count)); + foreach (QString path, result) { + QIcon icon(dir.filePath(path)); + QListWidgetItem *item = new QListWidgetItem(icon, KUrl(path).fileName()); + m_view.icon_list->addItem(item); + } +} + +QString SlideshowClip::selectedPath() const { + QString extension; + switch (m_view.image_type->currentIndex()) { + case TYPE_PNG: + extension = "/.all.png"; + break; + case TYPE_BMP: + extension = "/.all.bmp"; + break; + case TYPE_GIF: + extension = "/.all.gif"; + break; + default: + extension = "/.all.jpg"; + break; + } + return m_view.folder_url->url().path() + extension; +} + + +QString SlideshowClip::clipName() const { + return m_view.clip_name->text(); +} + +QString SlideshowClip::clipDuration() const { + return m_view.clip_duration->text(); +} + +int SlideshowClip::imageCount() const { + return m_count; +} + +bool SlideshowClip::loop() const { + return m_view.slide_loop->isChecked(); +} +#include "slideshowclip.moc" + + diff --git a/src/slideshowclip.h b/src/slideshowclip.h new file mode 100644 index 00000000..eae190bb --- /dev/null +++ b/src/slideshowclip.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#ifndef SLIDESHOWDIALOG_H +#define SLIDESHOWDIALOG_H + +#include + +#include "definitions.h" +#include "docclipbase.h" +#include "timecode.h" +#include "ui_slideshowclip_ui.h" + +class SlideshowClip : public QDialog { + Q_OBJECT + +public: + SlideshowClip(QWidget * parent = 0); + /** return selected path for slideshow in MLT format */ + QString selectedPath() const; + QString clipName() const; + QString clipDuration() const; + int imageCount() const; + bool loop() const; + +private slots: + void parseFolder(); + +private: + Ui::SlideshowClip_UI m_view; + int m_count; +}; + + +#endif + diff --git a/src/widgets/clipproperties_ui.ui b/src/widgets/clipproperties_ui.ui index b57d2dcb..e69b4e06 100644 --- a/src/widgets/clipproperties_ui.ui +++ b/src/widgets/clipproperties_ui.ui @@ -5,8 +5,8 @@ 0 0 - 310 - 459 + 283 + 435 @@ -78,15 +78,15 @@ - 0 + 3 0 0 - 290 - 171 + 263 + 159 @@ -165,6 +165,14 @@ + + + 0 + 0 + 263 + 159 + + Audio @@ -176,13 +184,6 @@ - - - - true - - - @@ -203,6 +204,13 @@ + + + + true + + + @@ -225,7 +233,6 @@ - ClipProperties_2 clip_acodec clip_frequency verticalSpacer_3 @@ -234,13 +241,127 @@ label_11 label_10 + + + + 0 + 0 + 263 + 159 + + + + Color + + + + + + Color + + + + + + + + + + Qt::Vertical + + + + 122 + 118 + + + + + + + + + + 0 + 0 + 263 + 159 + + + + Slideshow + + + + + + Image type + + + + + + + + + + Frame duration + + + + + + + 99:99:99:99; + + + + + + + Crossfade + + + + + + + Luma file + + + + + + + + + + Qt::Vertical + + + + 20 + 15 + + + + + + + + Loop + + + + + 0 0 263 - 171 + 159 @@ -345,6 +466,16 @@ + + KColorButton + QPushButton +
kcolorbutton.h
+
+ + KComboBox + QComboBox +
kcombobox.h
+
KDoubleNumInput QWidget diff --git a/src/widgets/slideshowclip_ui.ui b/src/widgets/slideshowclip_ui.ui new file mode 100644 index 00000000..0d946786 --- /dev/null +++ b/src/widgets/slideshowclip_ui.ui @@ -0,0 +1,168 @@ + + SlideshowClip_UI + + + + 0 + 0 + 319 + 332 + + + + Dialog + + + + + + Name + + + + + + + + + + Frame Duration + + + + + + + 99:99:99:99; + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + Folder + + + + + + + + + + Image Type + + + + + + + + + + No image found + + + + + + + Crossfade + + + + + + + Luma File + + + + + + + + + + Loop + + + + + + + + KComboBox + QComboBox +
kcombobox.h
+
+ + KLineEdit + QLineEdit +
klineedit.h
+
+ + KListWidget + QListWidget +
klistwidget.h
+
+ + KRestrictedLine + KLineEdit +
krestrictedline.h
+
+ + KUrlRequester + QFrame +
kurlrequester.h
+
+
+ + + + buttonBox + accepted() + SlideshowClip_UI + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SlideshowClip_UI + reject() + + + 316 + 260 + + + 286 + 274 + + + + +