editkeyframecommand.cpp
clipdurationdialog.cpp
managecapturesdialog.cpp
+ changespeedcommand.cpp
)
kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc )
return m_maxDuration;
}
+void AbstractClipItem::setMaxDuration(const GenTime &max) {
+ m_maxDuration = max;
+}
+
QPainterPath AbstractClipItem::upperRectPart(QRectF br) {
QPainterPath roundRectPathUpper;
double roundingY = 20;
virtual double fps() const;
virtual GenTime maxDuration() const;
virtual void setCropStart(GenTime pos);
+ virtual void setMaxDuration(const GenTime &max);
protected:
int m_track;
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2007 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 <KLocale>
+
+#include "changespeedcommand.h"
+#include "customtrackview.h"
+
+ChangeSpeedCommand::ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, int clipId, bool doIt, QUndoCommand * parent) : QUndoCommand(parent), m_view(view), m_clipInfo(info), m_old_speed(old_speed), m_new_speed(new_speed), m_clipId(clipId), m_doIt(doIt) {
+ setText(i18n("Adjust clip length"));
+}
+
+
+// virtual
+void ChangeSpeedCommand::undo() {
+ m_view->doChangeClipSpeed(m_clipInfo, m_old_speed, m_clipId);
+}
+// virtual
+void ChangeSpeedCommand::redo() {
+ if (m_doIt) {
+ m_view->doChangeClipSpeed(m_clipInfo, m_new_speed, m_clipId);
+ }
+ m_doIt = true;
+}
+
+#include "changespeedcommand.moc"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2007 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 CHANGESPEEDCOMMAND_H
+#define CHANGESPEEDCOMMAND_H
+
+#include <QUndoCommand>
+#include <QGraphicsView>
+#include <KDebug>
+
+#include "gentime.h"
+#include "definitions.h"
+
+class CustomTrackView;
+
+class ChangeSpeedCommand : public QUndoCommand {
+public:
+ ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, int clipId, bool doIt, QUndoCommand * parent = 0);
+ virtual void undo();
+ virtual void redo();
+
+private:
+ CustomTrackView *m_view;
+ ItemInfo m_clipInfo;
+ int m_clipId;
+ bool m_doIt;
+ double m_old_speed;
+ double m_new_speed;
+};
+
+#endif
+
#include "kthumb.h"
ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps)
- : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_thumbsRequested(0), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1) {
+ : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_thumbsRequested(0), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0) {
QRectF rect((double) info.startPos.frames(fps) * scale, (double)(info.track * KdenliveSettings::trackheight() + 1), (double)(info.endPos - info.startPos).frames(fps) * scale, (double)(KdenliveSettings::trackheight() - 1));
setRect(rect);
flashClip();
}
+double ClipItem::speed() const {
+ return m_speed;
+}
+
+void ClipItem::setSpeed(const double speed) {
+ m_speed = speed;
+ if (m_speed == 1.0) m_clipName = baseClip()->name();
+ else m_clipName = baseClip()->name() + " - " + QString::number(speed * 100, 'f', 0) + "%";
+ update();
+}
+
//virtual
void ClipItem::dropEvent(QGraphicsSceneDragDropEvent * event) {
QString effects = QString(event->mimeData()->data("kdenlive/effectslist"));
QString keyframes(const int index);
void setKeyframes(const int ix, const QString keyframes);
void setEffectList(const EffectsList effectList);
+ void setSpeed(const double speed);
+ double speed() const;
protected:
//virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
QTimeLine *m_timeLine;
uint m_thumbsRequested;
bool m_hover;
+ double m_speed;
EffectsList m_effectList;
QList <Transition*> m_transitionsList;
profilePath += "/lumas/PAL/";
QDir dir(profilePath);
- QStringList filter;
- filter << "*.pgm";
+ QStringList filter;
+ filter << "*.pgm";
const QStringList result = dir.entryList(filter, QDir::Files);
QStringList imagefiles;
QStringList imagenamelist;
int current;
foreach(const QString file, result) {
- m_view.luma_file->addItem(KIcon(profilePath + file), file, profilePath + file);
- if (!lumaFile.isEmpty() && lumaFile == QString(profilePath + file))
- current = m_view.luma_file->count() - 1;
+ m_view.luma_file->addItem(KIcon(profilePath + file), file, profilePath + file);
+ if (!lumaFile.isEmpty() && lumaFile == QString(profilePath + file))
+ current = m_view.luma_file->count() - 1;
}
if (!lumaFile.isEmpty()) {
#include "addtransitioncommand.h"
#include "edittransitioncommand.h"
#include "editkeyframecommand.h"
+#include "changespeedcommand.h"
#include "addmarkercommand.h"
#include "razorclipcommand.h"
#include "kdenlivesettings.h"
m_commandStack->push(deleteSelected);
}
+void CustomTrackView::changeClipSpeed() {
+ QList<QGraphicsItem *> itemList = scene()->selectedItems();
+ if (itemList.count() == 0) {
+ emit displayMessage(i18n("Select clip to change speed"), ErrorMessage);
+ return;
+ }
+ QUndoCommand *changeSelected = new QUndoCommand();
+ changeSelected->setText("Edit clip speed");
+ for (int i = 0; i < itemList.count(); i++) {
+ if (itemList.at(i)->type() == AVWIDGET) {
+ ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
+ ItemInfo info = item->info();
+ int percent = QInputDialog::getInteger(this, i18n("Edit Clip Speed"), i18n("New speed (percents)"), 100, 1, 300);
+ double speed = (double) percent / 100.0;
+ new ChangeSpeedCommand(this, info, item->speed(), speed, item->clipProducer(), true, changeSelected);
+ }
+ }
+ m_commandStack->push(changeSelected);
+}
+
+void CustomTrackView::doChangeClipSpeed(ItemInfo info, double speed, int id) {
+ DocClipBase *baseclip = m_document->clipManager()->getClipById(id);
+ ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()) + 1, info.track);
+ info.track = m_tracksList.count() - item->track();
+ int newLength = m_document->renderer()->mltChangeClipSpeed(info, speed, baseclip->producer());
+ GenTime maxDuration(newLength, m_document->fps());
+ item->setMaxDuration(maxDuration);
+ item->setSpeed(speed);
+ if (maxDuration < item->duration()) {
+ info = item->info();
+ ItemInfo endInfo = info;
+ endInfo.endPos = info.startPos + maxDuration;
+ ResizeClipCommand *command = new ResizeClipCommand(this, info, endInfo, true);
+ m_commandStack->push(command);
+ }
+}
+
void CustomTrackView::cutSelectedClips() {
QList<QGraphicsItem *> itemList = scene()->selectedItems();
GenTime currentPos = GenTime(m_cursorPos, m_document->fps());
void clearSearchStrings();
void clipStart();
void clipEnd();
+ void changeClipSpeed();
+ void doChangeClipSpeed(ItemInfo info, double speed, int id);
public slots:
void setCursorPos(int pos, bool seek = true);
QDir directory;
for (more = direc.begin() ; more != direc.end() ; ++more) {
directory = QDir(*more);
- QStringList filter;
- filter << "*.xml";
+ QStringList filter;
+ filter << "*.xml";
fileList = directory.entryList(filter, QDir::Files);
for (it = fileList.begin() ; it != fileList.end() ; ++it) {
itemName = KUrl(*more + *it).path();
QDomElement infoXml = infoXmlNode.toElement();
QString profilePath = infoXml.attribute("profile");
m_startPos = infoXml.attribute("position").toInt();
- m_zoom = infoXml.attribute("zoom").toInt();
+ m_zoom = infoXml.attribute("zoom", "4").toInt();
if (!profilePath.isEmpty()) setProfilePath(profilePath);
double version = infoXml.attribute("version").toDouble();
if (version < 0.7) convertDocument(version);
QDomNode multitrack = m_document.elementsByTagName("multitrack").at(0);
QDomNodeList playlists = m_document.elementsByTagName("playlist");
+ m_startPos = kdenlivedoc.toElement().attribute("timeline_position").toInt();
+
QDomNode props = m_document.elementsByTagName("properties").at(0).toElement();
QString profile = props.toElement().attribute("videoprofile");
if (profile == "dv_wide") profile = "dv_pal_wide";
<Menu name="timeline" ><text>Timeline</text>
<Action name="cut_timeline_clip" />
<Action name="delete_timeline_clip" />
+ <Action name="change_clip_speed" />
<Menu name="marker_menu" ><text>Markers</text>
<Action name="add_clip_marker" />
<Action name="edit_clip_marker" />
m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));
m_timelineContextClipMenu->addAction(actionCollection()->action("delete_timeline_clip"));
+ m_timelineContextClipMenu->addAction(actionCollection()->action("change_clip_speed"));
m_timelineContextClipMenu->addAction(actionCollection()->action("cut_timeline_clip"));
m_timelineContextClipMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
m_timelineContextClipMenu->addAction(actionCollection()->action("paste_effects"));
actionCollection()->addAction("delete_timeline_clip", deleteTimelineClip);
connect(deleteTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotDeleteTimelineClip()));
+ KAction* editTimelineClipSpeed = new KAction(KIcon("edit-delete"), i18n("Change Clip Speed"), this);
+ actionCollection()->addAction("change_clip_speed", editTimelineClipSpeed);
+ connect(editTimelineClipSpeed, SIGNAL(triggered(bool)), this, SLOT(slotChangeClipSpeed()));
+
KAction* cutTimelineClip = new KAction(KIcon("edit-cut"), i18n("Cut Clip"), this);
cutTimelineClip->setShortcut(Qt::SHIFT + Qt::Key_R);
actionCollection()->addAction("cut_timeline_clip", cutTimelineClip);
}
}
+void MainWindow::slotChangeClipSpeed() {
+ if (m_activeTimeline) {
+ m_activeTimeline->projectView()->changeClipSpeed();
+ }
+}
+
void MainWindow::slotAddClipMarker() {
if (m_activeTimeline) {
m_activeTimeline->projectView()->slotAddClipMarker();
void slotPaste();
void slotPasteEffects();
void slotReloadEffects();
+ void slotChangeClipSpeed();
};
int ct = 0;
int count = m_view.treeWidget->topLevelItemCount();
while (ct < count) {
- QTreeWidgetItem *item = m_view.treeWidget->topLevelItem(ct);
- //QTreeWidgetItem *item = m_view.treeWidget->currentItem();
- if (item->icon(0).isNull()) {
- QPixmap p = KThumb::getImage(KUrl(item->data(0, Qt::UserRole).toString()), 0, 70, 50);
- item->setIcon(0, QIcon(p));
- m_view.treeWidget->resizeColumnToContents(0);
- repaint();
- //QTimer::singleShot(400, this, SLOT(slotCheckItemIcon()));
- }
- ct++;
+ QTreeWidgetItem *item = m_view.treeWidget->topLevelItem(ct);
+ //QTreeWidgetItem *item = m_view.treeWidget->currentItem();
+ if (item->icon(0).isNull()) {
+ QPixmap p = KThumb::getImage(KUrl(item->data(0, Qt::UserRole).toString()), 0, 70, 50);
+ item->setIcon(0, QIcon(p));
+ m_view.treeWidget->resizeColumnToContents(0);
+ repaint();
+ //QTimer::singleShot(400, this, SLOT(slotCheckItemIcon()));
+ }
+ ct++;
}
m_view.treeWidget->setEnabled(true);
}
}
}
foreach(const KUrl file, list) {
- if (KIO::NetAccess::exists(file, KIO::NetAccess::SourceSide, NULL))
- m_doc->slotAddClipFile(file, group, groupId);
+ if (KIO::NetAccess::exists(file, KIO::NetAccess::SourceSide, NULL))
+ m_doc->slotAddClipFile(file, group, groupId);
}
}
ProjectItem *item = getItemById(id);
if (item) {
QString path = item->referencedClip()->fileURL().path();
- if (!path.isEmpty()) KMessageBox::sorry(this, i18n("<qt>Clip <b>%1</b><br>is invalid, will be removed from project.", path));
-
+ if (!path.isEmpty()) KMessageBox::sorry(this, i18n("<qt>Clip <b>%1</b><br>is invalid, will be removed from project.", path));
+
}
QList <int> ids;
ids << id;
m_mltProducer = producer;
if (m_blackClip) delete m_blackClip;
m_blackClip = new Mlt::Producer(*m_mltProfile , "colour", "black");
- m_blackClip->set("id", "black");
+ m_blackClip->set("id", "black");
m_mltConsumer->connect(*m_mltProducer);
m_mltProducer->set_speed(0.0);
QStringList::Iterator it;
QDir dir(url.directory());
- QStringList filter;
- filter << "*." + fileType;
- filter << "*." + fileType.toUpper();
+ QStringList filter;
+ filter << "*." + fileType;
+ filter << "*." + fileType.toUpper();
more = dir.entryList(filter, QDir::Files);
- im.load(url.directory() + "/" + more.at(0));
+ im.load(url.directory() + "/" + more.at(0));
} else im.load(url.path());
//pixmap = im.scaled(width, height);
return pixmap;
if (producer->is_blank()) {
kDebug() << " / / / / / / / /ERRROR / / / / // CANNOT LOAD PRODUCER: ";
- emit removeInvalidClip(clipId);
+ emit removeInvalidClip(clipId);
return;
}
producer->set("id", clipId);
m_isBlocked = false;
}
+int Render::mltChangeClipSpeed(ItemInfo info, double speed, Mlt::Producer *prod) {
+ m_isBlocked = true;
+ int newLength = 0;
+ Mlt::Service service(m_mltProducer->parent().get_service());
+ if (service.type() != tractor_type) kWarning() << "// TRACTOR PROBLEM";
+
+ Mlt::Tractor tractor(service);
+ Mlt::Producer trackProducer(tractor.track(info.track));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+ int clipIndex = trackPlaylist.get_clip_index_at((int) info.startPos.frames(m_fps));
+ Mlt::Producer clip(trackPlaylist.get_clip(clipIndex));
+ QString serv = clip.parent().get("mlt_service");
+ QString id = clip.parent().get("id");
+ kDebug() << "CLIP SERVICE: " << clip.parent().get("mlt_service");
+ if (serv == "avformat" && speed != 1.0) {
+ mlt_service_lock(service.get_service());
+ QString url = clip.parent().get("resource");
+ url.append(":" + QString::number(speed));
+ char *tmp = decodedString(url);
+ Mlt::Producer *slow = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp);
+ delete[] tmp;
+ tmp = decodedString(id);
+ slow->set("id", tmp);
+ delete[] tmp;
+ slow->set_in_and_out(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps));
+ newLength = slow->get_length();
+ trackPlaylist.replace_with_blank(clipIndex);
+ trackPlaylist.consolidate_blanks(0);
+ trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *slow, 1);
+ mlt_service_unlock(service.get_service());
+ kDebug() << "AVFORMAT CLIP!!!:";
+ } else if (speed == 1.0) {
+ mlt_service_lock(service.get_service());
+ Mlt::Producer *cut = prod->cut(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps) - 1);
+ trackPlaylist.replace_with_blank(clipIndex);
+ newLength = cut->get_length();
+ trackPlaylist.consolidate_blanks(0);
+ trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *cut, 1);
+ mlt_service_unlock(service.get_service());
+ } else if (serv == "framebuffer") {
+ mlt_service_lock(service.get_service());
+ QString url = clip.parent().get("resource");
+ url = url.section(":", 0, -1);
+ url.append(":" + QString::number(speed));
+ char *tmp = decodedString(url);
+ Mlt::Producer *slow = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp);
+ delete[] tmp;
+ tmp = decodedString(id);
+ slow->set("id", tmp);
+ delete[] tmp;
+ slow->set_in_and_out(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps));
+ newLength = slow->get_length();
+ trackPlaylist.replace_with_blank(clipIndex);
+ trackPlaylist.consolidate_blanks(0);
+ trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *slow, 1);
+ mlt_service_unlock(service.get_service());
+ kDebug() << "AVFORMAT CLIP!!!:";
+ }
+
+ m_isBlocked = false;
+ return newLength;
+}
+
bool Render::mltRemoveEffect(int track, GenTime position, QString index, bool doRefresh) {
Mlt::Service service(m_mltProducer->parent().get_service());
void mltMoveTransparency(int startTime, int endTime, int startTrack, int endTrack, int id);
void mltDeleteTransparency(int pos, int track, int id);
void mltResizeTransparency(int oldStart, int newStart, int newEnd, int track, int id);
+ int mltChangeClipSpeed(ItemInfo info, double speed, Mlt::Producer *prod);
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... */
#include "resizeclipcommand.h"
#include "customtrackview.h"
-ResizeClipCommand::ResizeClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool doIt)
- : m_view(view), m_startPos(start), m_endPos(end), m_doIt(doIt) {
+ResizeClipCommand::ResizeClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool doIt, QUndoCommand * parent) : QUndoCommand(parent), m_view(view), m_startPos(start), m_endPos(end), m_doIt(doIt) {
setText(i18n("Resize clip"));
}
class ResizeClipCommand : public QUndoCommand {
public:
- ResizeClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool doIt);
+ ResizeClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool doIt, QUndoCommand * parent = 0);
virtual void undo();
virtual void redo();