}
QRectF rect = sceneBoundingRect();
const double scale = projectScene()->scale();
- double maximumOffset;
- if (scale > 3) maximumOffset = 25 / scale;
- else maximumOffset = 6 / scale;
-
- //kDebug()<<"// Item rect: "<<rect.x()<<". pos. "<<pos.x()<<", scale: "<<scale<<", ratio: "<<qAbs((int)(pos.x() - rect.x())) / scale;
+ double maximumOffset = 6 / scale;
if (qAbs((int)(pos.x() - (rect.x() + m_startFade))) < maximumOffset && qAbs((int)(pos.y() - rect.y())) < 6) {
if (m_startFade == 0) setToolTip(i18n("Add audio fade"));
m_view.clip_channels->setText(props.value("channels"));
CLIPTYPE t = m_clip->clipType();
+ if (t != AUDIO && t != AV) {
+ m_view.clip_force_aindex->setEnabled(false);
+ }
+
+ if (t != VIDEO && t != AV) {
+ m_view.clip_force_vindex->setEnabled(false);
+ }
+
if (t == IMAGE) {
m_view.tabWidget->removeTab(SLIDETAB);
m_view.tabWidget->removeTab(COLORTAB);
m_document->updateClip(item->baseClip()->getId());
ItemInfo info;
info = item->info();
+ if (item->baseClip()->isTransparent()) {
+ // 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_scene->m_tracksList.count() - info.track, info.startPos, info.endPos, tr->toXML());
+ }
info.track = m_scene->m_tracksList.count() - item->track();
m_document->renderer()->mltInsertClip(info, item->xml(), item->baseClip()->producer());
item->setSelected(true);
if (success) {
MoveClipCommand *command = new MoveClipCommand(this, m_dragItemInfo, info, false);
m_commandStack->push(command);
+ ClipItem *item = static_cast <ClipItem *>(m_dragItem);
+ if (item->baseClip()->isTransparent()) {
+ // Also move automatic transition
+ Transition *tr = getTransitionItemAt((int) m_dragItemInfo.startPos.frames(m_document->fps()) + 1, m_dragItemInfo.track);
+ if (tr && tr->isAutomatic()) {
+ tr->updateTransitionEndTrack(getPreviousVideoTrack(info.track));
+ m_document->renderer()->mltMoveTransition(tr->transitionTag(), m_scene->m_tracksList.count() - m_dragItemInfo.track, m_scene->m_tracksList.count() - info.track, tr->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
+ tr->setPos((int) info.startPos.frames(m_document->fps()), (int)(info.track * m_tracksHeight + 1));
+ }
+ }
} else {
// undo last move and emit error message
MoveClipCommand *command = new MoveClipCommand(this, info, m_dragItemInfo, true);
if (item->isSelected()) emit clipItemSelected(NULL);
item->baseClip()->removeReference();
m_document->updateClip(item->baseClip()->getId());
+
+ if (item->baseClip()->isTransparent()) {
+ // also remove automatic transition
+ Transition *tr = getTransitionItemAt((int) info.startPos.frames(m_document->fps()) + 1, info.track);
+ if (tr && tr->isAutomatic()) {
+ m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_scene->m_tracksList.count() - info.track, info.startPos, info.endPos, tr->toXML());
+ scene()->removeItem(tr);
+ delete tr;
+ }
+ }
scene()->removeItem(item);
delete item;
m_document->renderer()->mltRemoveClip(m_scene->m_tracksList.count() - info.track, info.startPos);
ClipItem *item = new ClipItem(baseclip, info, m_document->fps());
item->setEffectList(effects);
scene()->addItem(item);
+ if (item->baseClip()->isTransparent()) {
+ // 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_scene->m_tracksList.count() - info.track, info.startPos, info.endPos, tr->toXML());
+ }
+
baseclip->addReference();
m_document->updateClip(baseclip->getId());
info.track = m_scene->m_tracksList.count() - info.track;
bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - start.track), (int)(m_scene->m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()));
if (success) {
item->setPos((int) end.startPos.frames(m_document->fps()), (int)(end.track * m_tracksHeight + 1));
+ if (item->baseClip()->isTransparent()) {
+ // Also move automatic transition
+ Transition *tr = getTransitionItemAt((int) start.startPos.frames(m_document->fps()) + 1, start.track);
+ if (tr && tr->isAutomatic()) {
+ tr->updateTransitionEndTrack(getPreviousVideoTrack(end.track));
+ m_document->renderer()->mltMoveTransition(tr->transitionTag(), m_scene->m_tracksList.count() - start.track, m_scene->m_tracksList.count() - end.track, tr->transitionEndTrack(), start.startPos, start.endPos, end.startPos, end.endPos);
+ tr->setPos((int) end.startPos.frames(m_document->fps()), (int)(end.track * m_tracksHeight + 1));
+ }
+ }
} else {
// undo last move and emit error message
emit displayMessage(i18n("Cannot move clip to position %1seconds", QString::number(end.startPos.seconds(), 'g', 2)), ErrorMessage);
*/
}
- QString wipetrans = "<ktransition tag=\"composite\" ><name>Wipe</name><description>Slide image from one side to another</description><parameter tag=\"geometry\" type=\"wipe\" default=\"-100%,0%:100%x100%;-1=0%,0%:100%x100%\" name=\"geometry\"><name>Direction</name> </parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>Align</name></parameter></ktransition>";
+ QString wipetrans = "<ktransition tag=\"composite\" id=\"wipe\"><name>Wipe</name><description>Slide image from one side to another</description><parameter tag=\"geometry\" type=\"wipe\" default=\"-100%,0%:100%x100%;-1=0%,0%:100%x100%\" name=\"geometry\"><name>Direction</name> </parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>Align</name></parameter></ktransition>";
QDomDocument ret;
ret.setContent(wipetrans);
transitions->append(ret.documentElement());
+
+ QString alphatrans = "<ktransition tag=\"composite\" id=\"alphatransparency\" ><name>Alpha transparency</name><description>Make alpha channel transparent</description><parameter tag=\"geometry\" type=\"fixed\" default=\"0%,0%:100%x100%\" name=\"geometry\"><name>Direction</name></parameter><parameter tag=\"fill\" default=\"0\" type=\"bool\" name=\"fill\" ><name>Rescale</name></parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>Align</name></parameter></ktransition>";
+ QDomDocument ret2;
+ ret2.setContent(alphatrans);
+ transitions->append(ret2.documentElement());
}
QDomElement initEffects::quickParameterFill(QDomDocument & doc, QString name, QString tag, QString type, QString def, QString min, QString max, QString list, QString listdisplaynames, QString factor, QString namedesc, QString format) {
QMenu *transitionsMenu = new QMenu(i18n("Add Transition"), this);
QStringList effects = transitions.effectNames();
- foreach(const QString &name, effects) {
- action = new QAction(name, this);
- action->setData(name);
+
+ effectsList.clear();
+ for (int ix = 0; ix < transitions.count(); ix++) {
+ effectInfo = transitions.effectIdInfo(ix);
+ effectsList.insert(effectInfo.at(0).toLower(), effectInfo);
+ }
+ foreach(QStringList value, effectsList) {
+ action = new QAction(value.at(0), this);
+ action->setData(value);
transitionsMenu->addAction(action);
}
connect(transitionsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddTransition(QAction *)));
void MainWindow::slotAddTransition(QAction *result) {
if (!result) return;
- QDomElement effect = transitions.getEffectByName(result->data().toString());
+ QStringList info = result->data().toStringList();
+ if (info.isEmpty()) return;
+ QDomElement transition = transitions.getEffectByTag(info.at(1), info.at(2));
+ //QDomElement effect = transitions.getEffectByName(result->data().toString());
if (m_activeTimeline) {
- m_activeTimeline->projectView()->slotAddTransitionToSelectedClips(effect);
+ m_activeTimeline->projectView()->slotAddTransitionToSelectedClips(transition);
}
}
Mlt::Producer *clip = prod->cut((int) info.cropStart.frames(m_fps), (int)(info.endPos - info.startPos + info.cropStart).frames(m_fps) - 1);
int newIndex = trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *clip, 1);
- if (QString(prod->get("transparency")).toInt() == 1)
- mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt());
+ /*if (QString(prod->get("transparency")).toInt() == 1)
+ mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt());*/
mlt_service_unlock(service.get_service());
Mlt::Producer clip(trackPlaylist.get_clip(clipIndex));
trackPlaylist.replace_with_blank(clipIndex);
trackPlaylist.consolidate_blanks(0);
- if (QString(clip.parent().get("transparency")).toInt() == 1)
- mltDeleteTransparency((int) position.frames(m_fps), track, QString(clip.parent().get("id")).toInt());
+ /*if (QString(clip.parent().get("transparency")).toInt() == 1)
+ mltDeleteTransparency((int) position.frames(m_fps), track, QString(clip.parent().get("id")).toInt());*/
/* // Display playlist info
kDebug()<<"//// AFTER";
trackPlaylist.consolidate_blanks(0);
- /* // Display playlist info
- kDebug()<<"//////////// AFTER RESIZE";
- for (int i = 0; i < trackPlaylist.count(); i++) {
- int blankStart = trackPlaylist.clip_start(i);
- int blankDuration = trackPlaylist.clip_length(i) - 1;
- QString blk;
- if (trackPlaylist.is_blank(i)) blk = "(blank)";
- kDebug()<<"CLIP "<<i<<": ("<<blankStart<<"x"<<blankStart + blankDuration<<")"<<blk;
- }*/
- //tractor.multitrack()->refresh();
- //tractor.refresh();
if (info.track != 0 && clipIndex == trackPlaylist.count()) mltCheckLength();
- if (QString(clip->parent().get("transparency")).toInt() == 1) {
+ /*if (QString(clip->parent().get("transparency")).toInt() == 1) {
//mltResizeTransparency(previousStart, previousStart, previousStart + newDuration, track, QString(clip->parent().get("id")).toInt());
mltDeleteTransparency(info.startPos.frames(m_fps), info.track, QString(clip->parent().get("id")).toInt());
ItemInfo transpinfo;
transpinfo.endPos = info.startPos + clipDuration;
transpinfo.track = info.track;
mltAddClipTransparency(transpinfo, info.track - 1, QString(clip->parent().get("id")).toInt());
- }
+ }*/
m_isBlocked = false;
return true;
}
else trackPlaylist.resize_clip(blankIndex, 0, blankLength + moveFrame - 1);
}
trackPlaylist.consolidate_blanks(0);
- if (QString(clip->parent().get("transparency")).toInt() == 1) {
+ /*if (QString(clip->parent().get("transparency")).toInt() == 1) {
//mltResizeTransparency(previousStart, (int) moveEnd.frames(m_fps), (int) (moveEnd + out - in).frames(m_fps), track, QString(clip->parent().get("id")).toInt());
mltDeleteTransparency(info.startPos.frames(m_fps), info.track, QString(clip->parent().get("id")).toInt());
ItemInfo transpinfo;
transpinfo.endPos = info.startPos + diff + (info.endPos - info.startPos);
transpinfo.track = info.track;
mltAddClipTransparency(transpinfo, info.track - 1, QString(clip->parent().get("id")).toInt());
- }
+ }*/
m_isBlocked = false;
//m_mltConsumer->set("refresh", 1);
mlt_service_unlock(service.get_service());
} else {
trackPlaylist.consolidate_blanks(0);
int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1);
- if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
+ /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
- }
+ }*/
if (newIndex + 1 == trackPlaylist.count()) checkLength = true;
}
//mlt_service_unlock(service.get_service());
destTrackPlaylist.consolidate_blanks(1);
int newIndex = destTrackPlaylist.insert_at(moveEnd, clipProducer, 1);
destTrackPlaylist.consolidate_blanks(0);
- if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
+ /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
kDebug() << "//////// moving clip transparency";
mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
- }
+ }*/
if (clipIndex > trackPlaylist.count()) checkLength = true;
else if (newIndex + 1 == destTrackPlaylist.count()) checkLength = true;
}
mlt_type = mlt_properties_get(properties, "mlt_type");
resource = mlt_properties_get(properties, "mlt_service");
}
- if (do_refresh) m_mltConsumer->set("refresh", 1);
+ //if (do_refresh) m_mltConsumer->set("refresh", 1);
}
QMap<QString, QString> Render::mltGetTransitionParamsFromXml(QDomElement xml) {
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();
+ if (xml.attribute("automatic") == "1") transition->set("automatic", 1);
+ //kDebug() << " ------ ADDING TRANSITION PARAMs: " << args.count();
for (it = args.begin(); it != args.end(); ++it) {
key = it.key();
bool transitionAdd = true;
int a_track = 0;
int b_track = 0;
+ bool isAutomatic = false;
+ QString mlt_geometry;
QString mlt_service;
for (int k = 0; k < transitionparams.count(); k++) {
p = transitionparams.item(k).toElement();
if (paramName == "internal_added" && p.text() == "237") {
transitionAdd = false;
//kDebug() << "// TRANSITRION " << i << " IS NOT VALID (INTERN ADDED)";
- break;
+ //break;
} else if (paramName == "a_track") a_track = p.text().toInt();
else if (paramName == "b_track") b_track = m_projectTracks - 1 - p.text().toInt();
else if (paramName == "mlt_service") mlt_service = p.text();
+ else if (paramName == "geometry") mlt_geometry = p.text();
+ else if (paramName == "automatic" && p.text() == "1") isAutomatic = true;;
}
}
- if (transitionAdd) {
+ if (transitionAdd || mlt_service != "mix") {
// Transition should be added to the scene
ItemInfo transitionInfo;
- QDomElement base = MainWindow::transitions.getEffectByTag(mlt_service, QString()).cloneNode().toElement();
+ QString transitionId;
+ if (mlt_service == "composite") {
+ kDebug() << "//////////\n\nADDING COMPO TRANS\n\n " << mlt_geometry << "\n\n//////////";
+ if (mlt_geometry == "0%,0%:100%x100%") transitionId = "alphatransparency";
+ else if (mlt_geometry.count(';') == 1) {
+ mlt_geometry.remove(QChar('%'), Qt::CaseInsensitive);
+ mlt_geometry.replace(QChar('x'), QChar(','), Qt::CaseInsensitive);
+ QString start = mlt_geometry.section(';', 0, 0);
+ start = start.section(':', 0, 1);
+ start.replace(QChar(':'), QChar(','), Qt::CaseInsensitive);
+ QString end = mlt_geometry.section('=', 1, 1);
+ end = end.section(':', 0, 1);
+ end.replace(QChar(':'), QChar(','), Qt::CaseInsensitive);
+ start.append(',' + end);
+ QStringList numbers = start.split(',', QString::SkipEmptyParts);
+ bool isWipeTransition = true;
+ int checkNumber;
+ for (int i = 0; i < numbers.size(); ++i) {
+ checkNumber = qAbs(numbers.at(i).toInt());
+ if (checkNumber != 0 && checkNumber != 100) {
+ isWipeTransition = false;
+ break;
+ }
+ }
+ if (isWipeTransition) transitionId = "wipe";
+ }
+ }
+ QDomElement base = MainWindow::transitions.getEffectByTag(mlt_service, transitionId).cloneNode().toElement();
for (int k = 0; k < transitionparams.count(); k++) {
p = transitionparams.item(k).toElement();
transitionInfo.endPos = GenTime(e.attribute("out").toInt(), m_doc->fps());
transitionInfo.track = b_track;
//kDebug() << "/////////////// +++++++++++ ADDING TRANSITION ON TRACK: " << b_track << ", TOTAL TRKA: " << m_projectTracks;
- Transition *tr = new Transition(transitionInfo, a_track, m_doc->fps(), base);
+ Transition *tr = new Transition(transitionInfo, a_track, m_doc->fps(), base, isAutomatic);
m_scene->addItem(tr);
}
}
#include "customtrackscene.h"
#include "mainwindow.h"
-Transition::Transition(const ItemInfo info, int transitiontrack, double fps, QDomElement params) : AbstractClipItem(info, QRectF(), fps), m_gradient(QLinearGradient(0, 0, 0, 0)) {
+Transition::Transition(const ItemInfo info, int transitiontrack, double fps, QDomElement params, bool automaticTransition) : AbstractClipItem(info, QRectF(), fps), m_gradient(QLinearGradient(0, 0, 0, 0)), m_automaticTransition(automaticTransition) {
setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() / 3 * 2 - 1));
setPos((qreal) info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2));
} else {
m_parameters = params;
}
-
+ if (m_automaticTransition) m_parameters.setAttribute("automatic", 1);
+ else if (m_parameters.attribute("automatic") == "1") m_automaticTransition = true;
m_name = m_parameters.elementsByTagName("name").item(0).toElement().text();
m_secondClip = 0;
setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
return m_parameters.attribute("tag");
}
+bool Transition::isAutomatic() const {
+ return m_automaticTransition;
+}
+
void Transition::setTransitionParameters(const QDomElement params) {
m_parameters = params;
m_name = m_parameters.elementsByTagName("name").item(0).toElement().text();
OPERATIONTYPE Transition::operationMode(QPointF pos) {
+ const double scale = projectScene()->scale();
+ double maximumOffset = 6 / scale;
+
QRectF rect = sceneBoundingRect();
- if (qAbs((int)(pos.x() - rect.x())) < 6) return RESIZESTART;
- else if (qAbs((int)(pos.x() - (rect.right()))) < 6) return RESIZEEND;
+ if (qAbs((int)(pos.x() - rect.x())) < maximumOffset) return RESIZESTART;
+ else if (qAbs((int)(pos.x() - (rect.right()))) < maximumOffset) return RESIZEEND;
return MOVE;
}
Q_OBJECT
public:
- Transition(const ItemInfo info, int transitiontrack, double fps, QDomElement params = QDomElement());
+ Transition(const ItemInfo info, int transitiontrack, double fps, QDomElement params = QDomElement(), bool automaticTransition = false);
virtual ~Transition();
virtual void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
void updateTransitionEndTrack(int newtrack);
const ClipItem *referencedClip() const;
Transition *clone();
+ bool isAutomatic() const;
protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
bool m_singleClip;
QLinearGradient m_gradient;
QString m_name;
+
+ /** true if the transition was added automatically and should be moved with its clip */
+ bool m_automaticTransition;
/** contains the transition parameters */
QDomElement m_parameters;
/** The clip to which the transition is attached */