}
void CustomTrackView::slotAddTransition(ClipItem* clip, ItemInfo transitionInfo, int endTrack, QDomElement transition) {
+ if (transitionInfo.startPos >= transitionInfo.endPos) {
+ emit displayMessage(i18n("Invalid transition"), ErrorMessage);
+ return;
+ }
AddTransitionCommand* command = new AddTransitionCommand(this, transitionInfo, endTrack, transition, false, true);
m_commandStack->push(command);
m_document->setModified(true);
void CustomTrackView::addTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) {
Transition *tr = new Transition(transitionInfo, endTrack, m_document->fps(), params, true);
- scene()->addItem(tr);
-
//kDebug() << "---- ADDING transition " << params.attribute("value");
- m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML());
- m_document->setModified(true);
+ if (m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML())) {
+ scene()->addItem(tr);
+ m_document->setModified(true);
+ } else {
+ emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
+ delete tr;
+ }
}
void CustomTrackView::deleteTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) {
// add transparency transition
int endTrack = getPreviousVideoTrack(info.track);
Transition *tr = new Transition(info, endTrack, m_document->fps(), MainWindow::transitions.getEffectByTag("composite", "alphatransparency"), true);
- scene()->addItem(tr);
- m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
+ if (m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML())) {
+ scene()->addItem(tr);
+ } else {
+ emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
+ delete tr;
+ }
}
info.track = m_document->tracksCount() - item->track();
m_document->renderer()->mltInsertClip(info, item->xml(), item->baseClip()->producer(item->track()));
}
}
if (m_dragItem->type() == TRANSITIONWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) {
- MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
- m_commandStack->push(command);
- Transition *transition = (Transition *) m_dragItem;
- transition->updateTransitionEndTrack(getPreviousVideoTrack(m_dragItem->track()));
- m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItem->track()), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
+ Transition *transition = static_cast <Transition *>(m_dragItem);
+ if (!m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItem->track()), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos)) {
+ MoveTransitionCommand *command = new MoveTransitionCommand(this, info, m_dragItemInfo, true);
+ m_commandStack->push(command);
+ } else {
+ MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
+ m_commandStack->push(command);
+ transition->updateTransitionEndTrack(getPreviousVideoTrack(m_dragItem->track()));
+ }
}
} else {
// Moving several clips. We need to delete them and readd them to new position,
ItemInfo trInfo = transition->info();
ItemInfo newTrInfo = trInfo;
newTrInfo.startPos = m_dragItem->startPos();
- new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+ if (newTrInfo.startPos < newTrInfo.endPos)
+ new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
}
// Check if there is an automatic transition on that clip (upper track)
transition = getTransitionItemAtStart(m_dragItemInfo.startPos, m_dragItemInfo.track - 1);
ItemInfo newTrInfo = trInfo;
newTrInfo.startPos = m_dragItem->startPos();
ClipItem * upperClip = getClipItemAt(m_dragItemInfo.startPos, m_dragItemInfo.track - 1);
- if (!upperClip || !upperClip->baseClip()->isTransparent()) {
+ if ((!upperClip || !upperClip->baseClip()->isTransparent()) && newTrInfo.startPos < newTrInfo.endPos) {
new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
}
}
emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
}
} else if (m_dragItem->type() == TRANSITIONWIDGET) {
- MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
- m_commandStack->push(command);
Transition *transition = static_cast <Transition *>(m_dragItem);
- m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItemInfo.track), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
+ if (!m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItemInfo.track), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos)) {
+ emit displayMessage(i18n("Cannot move transition"), ErrorMessage);
+ MoveTransitionCommand *command = new MoveTransitionCommand(this, info, m_dragItemInfo, true);
+ m_commandStack->push(command);
+ } else {
+ MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
+ m_commandStack->push(command);
+ }
+
}
//m_document->renderer()->doRefresh();
ItemInfo trInfo = tr->info();
ItemInfo newTrInfo = trInfo;
newTrInfo.endPos = m_dragItem->endPos();
- new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+ if (newTrInfo.endPos > newTrInfo.startPos) new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
}
// Check if there is an automatic transition on that clip (upper track)
ItemInfo newTrInfo = trInfo;
newTrInfo.endPos = m_dragItem->endPos();
ClipItem * upperClip = getClipItemAtEnd(m_dragItemInfo.endPos, m_dragItemInfo.track - 1);
- if (!upperClip || !upperClip->baseClip()->isTransparent()) {
+ if ((!upperClip || !upperClip->baseClip()->isTransparent()) && newTrInfo.endPos > newTrInfo.startPos) {
new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
}
}
emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
}
} else if (m_dragItem->type() == TRANSITIONWIDGET) {
- MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
- m_commandStack->push(command);
Transition *transition = static_cast <Transition *>(m_dragItem);
- m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
+ if (!m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos)) {
+ emit displayMessage(i18n("Cannot move transition"), ErrorMessage);
+ MoveTransitionCommand *command = new MoveTransitionCommand(this, info, m_dragItemInfo, true);
+ m_commandStack->push(command);
+ } else {
+ MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
+ m_commandStack->push(command);
+ }
}
//m_document->renderer()->doRefresh();
} else if (m_operationMode == FADEIN) {
// add transparency transition
int endTrack = getPreviousVideoTrack(info.track);
Transition *tr = new Transition(info, endTrack, m_document->fps(), MainWindow::transitions.getEffectByTag("composite", "alphatransparency"), true);
- scene()->addItem(tr);
- m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
+ if (m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML())) scene()->addItem(tr);
+ else {
+ emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
+ delete tr;
+ }
+
}
baseclip->addReference();
info.endPos = tr->endPos() + offset;
info.track = tr->track() + trackOffset;
if (canBePastedTo(info, TRANSITIONWIDGET)) {
- new AddTransitionCommand(this, info, tr->transitionEndTrack() + trackOffset, tr->toXML(), false, true, pasteClips);
+ if (info.startPos >= info.endPos) {
+ emit displayMessage(i18n("Invalid transition"), ErrorMessage);
+ } else new AddTransitionCommand(this, info, tr->transitionEndTrack() + trackOffset, tr->toXML(), false, true, pasteClips);
} else emit displayMessage(i18n("Cannot paste transition to selected place"), ErrorMessage);
}
}
return true;
}
-void Render::mltMoveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut) {
+bool Render::mltMoveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut) {
+ int new_in = (int)newIn.frames(m_fps);
+ int new_out = (int)newOut.frames(m_fps) - 1;
+ if (new_in >= new_out) return false;
+
Mlt::Service service(m_mltProducer->parent().get_service());
Mlt::Tractor tractor(service);
Mlt::Field *field = tractor.field();
QString resource = mlt_properties_get(properties, "mlt_service");
int old_pos = (int)(oldIn.frames(m_fps) + oldOut.frames(m_fps)) / 2;
- int new_in = (int)newIn.frames(m_fps);
- int new_out = (int)newOut.frames(m_fps) - 1;
-
while (mlt_type == "transition") {
mlt_transition tr = (mlt_transition) nextservice;
int currentTrack = mlt_transition_get_b_track(tr);
m_isBlocked = false;
mlt_service_unlock(service.get_service());
m_mltConsumer->set("refresh", 1);
+ return true;
}
void Render::mltUpdateTransition(QString oldTag, QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml) {
}
-void Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool do_refresh) {
-
+bool Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool do_refresh) {
+ if (in >= out) return false;
QMap<QString, QString> args = mltGetTransitionParamsFromXml(xml);
Mlt::Service service(m_mltProducer->parent().get_service());
field->plant_transition(*transition, a_track, b_track);
delete[] transId;
refresh();
+ return true;
}
void Render::mltSavePlaylist() {
transitionInfo.endPos = GenTime(e.attribute("out").toInt() + 1, m_doc->fps());
transitionInfo.track = m_projectTracks - 1 - b_track;
//kDebug() << "/////////////// +++++++++++ ADDING TRANSITION ON TRACK: " << b_track << ", TOTAL TRKA: " << m_projectTracks;
- if (transitionInfo.startPos >= transitionInfo.endPos) {
- // invalid transition, remove it.
- m_documentErrors.append(i18n("Removed invalid transition: %1\n", e.attribute("id")));
- kDebug()<<"///// REMOVED INVALID TRANSITION: "<<e.attribute("id");
+ if (transitionInfo.startPos >= transitionInfo.endPos) {
+ // invalid transition, remove it.
+ m_documentErrors.append(i18n("Removed invalid transition: %1\n", e.attribute("id")));
+ kDebug() << "///// REMOVED INVALID TRANSITION: " << e.attribute("id");
tractor.removeChild(transitions.item(i));
i--;
- }
- else {
- Transition *tr = new Transition(transitionInfo, a_track, m_doc->fps(), base, isAutomatic);
- if (forceTrack) tr->setForcedTrack(true, a_track);
- m_scene->addItem(tr);
- }
+ } else {
+ Transition *tr = new Transition(transitionInfo, a_track, m_doc->fps(), base, isAutomatic);
+ if (forceTrack) tr->setForcedTrack(true, a_track);
+ m_scene->addItem(tr);
+ }
}
}
}
}
}
- } else kWarning() << "CANNOT INSERT CLIP " << id;
+ } else {
+ // The clip in playlist was not listed in the kdenlive producers,
+ // something went wrong, repair required.
+ kWarning() << "CANNOT INSERT CLIP " << id;
+ int out = elem.attribute("out").toInt();
+
+ ItemInfo clipinfo;
+ clipinfo.startPos = GenTime(position, m_doc->fps());
+ clipinfo.endPos = clipinfo.startPos + GenTime(out - in + 1, m_doc->fps());
+ clipinfo.cropStart = GenTime(in, m_doc->fps());
+ clipinfo.track = ix;
+ //kDebug() << "// INSERTING CLIP: " << in << "x" << out << ", track: " << ix << ", ID: " << id << ", SCALE: " << m_scale << ", FPS: " << m_doc->fps();
+
+ DocClipBase *missingClip = getMissingProducer(id);
+ if (!missingClip) {
+ // We cannot find the producer, something is really wrong, add
+ // placeholder color clip
+ QDomElement producerXml;
+ producerXml.setTagName("producer");
+ producerXml.setAttribute("resource", "0xff0000ff");
+ producerXml.setAttribute("mlt_service", "colour");
+ producerXml.setAttribute("length", "15000");
+ producerXml.setAttribute("id", id);
+ missingClip = new DocClipBase(m_doc->clipManager(), producerXml, id);
+ m_documentErrors.append(i18n("Boken clip producer %1\n", id));
+ } else m_documentErrors.append(i18n("Replaced wrong clip producer %1 with %2\n", id, missingClip->getId()));
+ ClipItem *item = new ClipItem(missingClip, clipinfo, m_doc->fps(), false);
+ m_scene->addItem(item);
+ missingClip->addReference();
+ position += (out - in + 1);
+
+
+ }
//m_clipList.append(clip);
}
}
//track->show();
}
+DocClipBase *TrackView::getMissingProducer(const QString id) const {
+ QDomElement missingXml = QDomElement();
+ QDomDocument doc = m_doc->toXml();
+ QString docRoot = doc.documentElement().attribute("root");
+ if (!docRoot.endsWith('/')) docRoot.append('/');
+ QDomNodeList prods = doc.elementsByTagName("producer");
+ int maxprod = prods.count();
+ for (int i = 0; i < maxprod; i++) {
+ QDomNode m = prods.at(i);
+ QString prodId = m.toElement().attribute("id");
+ if (prodId == id) {
+ missingXml = m.toElement();
+ break;
+ }
+ }
+ if (missingXml == QDomElement()) return NULL;
+
+ QDomNodeList params = missingXml.childNodes();
+ QString resource;
+ QString mlt_service;
+ for (int j = 0; j < params.count(); j++) {
+ QDomElement e = params.item(j).toElement();
+ if (e.attribute("name") == "resource") {
+ resource = e.firstChild().nodeValue();
+ } else if (e.attribute("name") == "mlt_service") {
+ mlt_service = e.firstChild().nodeValue();
+ }
+ }
+ resource.prepend(docRoot);
+ DocClipBase *missingClip = NULL;
+ if (!resource.isEmpty())
+ missingClip = m_doc->clipManager()->getClipByResource(resource);
+ return missingClip;
+}
+
QGraphicsScene *TrackView::projectScene() {
return m_scene;
}