+
+ selectClip(true, false, m_selectedTrack, in);
+ // Automatic audio split
+ if (KdenliveSettings::splitaudio())
+ splitAudio();
+}
+
+void CustomTrackView::clearSelection()
+{
+ resetSelectionGroup();
+ scene()->clearSelection();
+ m_dragItem = NULL;
+ emit clipItemSelected(NULL);
+}
+
+void CustomTrackView::updatePalette()
+{
+ m_activeTrackBrush = KStatefulBrush(KColorScheme::View, KColorScheme::ActiveBackground, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
+ if (m_cursorLine) {
+ QPen pen1 = QPen();
+ pen1.setWidth(1);
+ pen1.setColor(palette().text().color());
+ m_cursorLine->setPen(pen1);
+ }
+ emit tracksChanged();
+}
+
+void CustomTrackView::removeTipAnimation()
+{
+ if (m_visualTip) {
+ scene()->removeItem(m_visualTip);
+ m_animationTimer->stop();
+ delete m_animation;
+ m_animation = NULL;
+ delete m_visualTip;
+ m_visualTip = NULL;
+ }
+}
+
+void CustomTrackView::setTipAnimation(AbstractClipItem *clip, OPERATIONTYPE mode, const double size)
+{
+ if (m_visualTip == NULL) {
+ QRectF rect = clip->sceneBoundingRect();
+ m_animation = new QGraphicsItemAnimation;
+ m_animation->setTimeLine(m_animationTimer);
+ m_animation->setScaleAt(1, 1, 1);
+ QPolygon polygon;
+ switch (mode) {
+ case FADEIN:
+ case FADEOUT:
+ m_visualTip = new QGraphicsEllipseItem(-size, -size, size * 2, size * 2);
+ ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
+ ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
+ if (mode == FADEIN)
+ m_visualTip->setPos(rect.x() + ((ClipItem *) clip)->fadeIn(), rect.y());
+ else
+ m_visualTip->setPos(rect.right() - ((ClipItem *) clip)->fadeOut(), rect.y());
+
+ m_animation->setScaleAt(.5, 2, 2);
+ break;
+ case RESIZESTART:
+ case RESIZEEND:
+ polygon << QPoint(0, - size * 2);
+ if (mode == RESIZESTART)
+ polygon << QPoint(size * 2, 0);
+ else
+ polygon << QPoint(- size * 2, 0);
+ polygon << QPoint(0, size * 2);
+ polygon << QPoint(0, - size * 2);
+
+ m_visualTip = new QGraphicsPolygonItem(polygon);
+ ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor);
+ ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen);
+ if (mode == RESIZESTART)
+ m_visualTip->setPos(rect.x(), rect.y() + rect.height() / 2);
+ else
+ m_visualTip->setPos(rect.right(), rect.y() + rect.height() / 2);
+
+ m_animation->setScaleAt(.5, 2, 1);
+ break;
+ case TRANSITIONSTART:
+ case TRANSITIONEND:
+ polygon << QPoint(0, - size * 2);
+ if (mode == TRANSITIONSTART)
+ polygon << QPoint(size * 2, 0);
+ else
+ polygon << QPoint(- size * 2, 0);
+ polygon << QPoint(0, 0);
+ polygon << QPoint(0, - size * 2);
+
+ m_visualTip = new QGraphicsPolygonItem(polygon);
+ ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor);
+ ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen);
+ if (mode == TRANSITIONSTART)
+ m_visualTip->setPos(rect.x(), rect.bottom());
+ else
+ m_visualTip->setPos(rect.right(), rect.bottom());
+
+ m_animation->setScaleAt(.5, 2, 2);
+ break;
+ default:
+ delete m_animation;
+ return;
+ }
+
+ m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations);
+ m_visualTip->setZValue(100);
+ scene()->addItem(m_visualTip);
+ m_animation->setItem(m_visualTip);
+ m_animationTimer->start();
+ }
+}
+
+bool CustomTrackView::hasAudio(int track) const
+{
+ QRectF rect(0, (double)(track * m_tracksHeight + 1), (double) sceneRect().width(), (double)(m_tracksHeight - 1));
+ QList<QGraphicsItem *> collisions = scene()->items(rect, Qt::IntersectsItemBoundingRect);
+ QGraphicsItem *item;
+ for (int i = 0; i < collisions.count(); i++) {
+ item = collisions.at(i);
+ if (!item->isEnabled()) continue;
+ if (item->type() == AVWIDGET) {
+ ClipItem *clip = static_cast <ClipItem *>(item);
+ if (!clip->isVideoOnly() && (clip->clipType() == AUDIO || clip->clipType() == AV || clip->clipType() == PLAYLIST)) return true;
+ }
+ }
+ return false;
+}
+
+void CustomTrackView::slotAddTrackEffect(const QDomElement effect, int ix)
+{
+ AddEffectCommand *command = new AddEffectCommand(this, m_document->tracksCount() - ix, GenTime(-1), effect, true);
+ m_commandStack->push(command);
+ setDocumentModified();
+}
+
+
+EffectsParameterList CustomTrackView::getEffectArgs(const QDomElement effect)
+{
+ EffectsParameterList parameters;
+ QLocale locale;
+ parameters.addParam("tag", effect.attribute("tag"));
+ if (effect.hasAttribute("region")) parameters.addParam("region", effect.attribute("region"));
+ parameters.addParam("kdenlive_ix", effect.attribute("kdenlive_ix"));
+ parameters.addParam("id", effect.attribute("id"));
+ if (effect.hasAttribute("src")) parameters.addParam("src", effect.attribute("src"));
+ if (effect.hasAttribute("disable")) parameters.addParam("disable", effect.attribute("disable"));
+ if (effect.hasAttribute("in")) parameters.addParam("in", effect.attribute("in"));
+ if (effect.hasAttribute("out")) parameters.addParam("out", effect.attribute("out"));
+
+ QDomNodeList params = effect.elementsByTagName("parameter");
+ for (int i = 0; i < params.count(); i++) {
+ QDomElement e = params.item(i).toElement();
+ if (e.attribute("type") == "geometry" && !e.hasAttribute("fixed")) {
+ // effects with geometry param need in / out synced with the clip, request it...
+ parameters.addParam("_sync_in_out", "1");
+ }
+ if (e.attribute("type") == "simplekeyframe") {
+
+ QStringList values = e.attribute("keyframes").split(";", QString::SkipEmptyParts);
+ double factor = e.attribute("factor", "1").toDouble();
+ for (int j = 0; j < values.count(); j++) {
+ QString pos = values.at(j).section(':', 0, 0);
+ double val = values.at(j).section(':', 1, 1).toDouble() / factor;
+ values[j] = pos + "=" + locale.toString(val);
+ }
+ // kDebug() << "/ / / /SENDING KEYFR:" << values;
+ parameters.addParam(e.attribute("name"), values.join(";"));
+ /*parameters.addParam(e.attribute("name"), e.attribute("keyframes").replace(":", "="));
+ parameters.addParam("max", e.attribute("max"));
+ parameters.addParam("min", e.attribute("min"));
+ parameters.addParam("factor", e.attribute("factor", "1"));*/
+ } else if (e.attribute("type") == "keyframe") {
+ kDebug() << "/ / / /SENDING KEYFR EFFECT TYPE";
+ parameters.addParam("keyframes", e.attribute("keyframes"));
+ parameters.addParam("max", e.attribute("max"));
+ parameters.addParam("min", e.attribute("min"));
+ parameters.addParam("factor", e.attribute("factor", "1"));
+ parameters.addParam("starttag", e.attribute("starttag", "start"));
+ parameters.addParam("endtag", e.attribute("endtag", "end"));
+ } else if (e.attribute("namedesc").contains(';')) {
+ QString format = e.attribute("format");
+ QStringList separators = format.split("%d", QString::SkipEmptyParts);
+ QStringList values = e.attribute("value").split(QRegExp("[,:;x]"));
+ QString neu;
+ QTextStream txtNeu(&neu);
+ if (values.size() > 0)
+ txtNeu << (int)values[0].toDouble();
+ for (int i = 0; i < separators.size() && i + 1 < values.size(); i++) {
+ txtNeu << separators[i];
+ txtNeu << (int)(values[i+1].toDouble());
+ }
+ parameters.addParam("start", neu);
+ } else {
+ if (e.attribute("factor", "1") != "1") {
+ double fact;
+ if (e.attribute("factor").contains('%')) {
+ fact = ProfilesDialog::getStringEval(m_document->mltProfile(), e.attribute("factor"));
+ } else fact = e.attribute("factor", "1").toDouble();
+ parameters.addParam(e.attribute("name"), locale.toString(e.attribute("value").toDouble() / fact));
+ } else {
+ parameters.addParam(e.attribute("name"), e.attribute("value"));
+ }
+ }
+ }
+ return parameters;
+}
+
+void CustomTrackView::updateTrackNames(int track, bool added)
+{
+ QList <TrackInfo> tracks = m_document->tracksList();
+ int max = tracks.count();
+ int docTrack = max - track - 1;
+
+ // count number of tracks of each type
+ int videoTracks = 0;
+ int audioTracks = 0;
+ for (int i = max - 1; i >= 0; --i) {
+ TrackInfo info = tracks.at(i);
+ if (info.type == VIDEOTRACK)
+ videoTracks++;
+ else
+ audioTracks++;
+
+ if (i <= docTrack) {
+ QString type = (info.type == VIDEOTRACK ? "Video " : "Audio ");
+ int typeNumber = (info.type == VIDEOTRACK ? videoTracks : audioTracks);
+
+ if (added) {
+ if (i == docTrack || info.trackName == type + QString::number(typeNumber - 1)) {
+ info.trackName = type + QString::number(typeNumber);
+ m_document->setTrackType(i, info);
+ }
+ } else {
+ if (info.trackName == type + QString::number(typeNumber + 1)) {
+ info.trackName = type + QString::number(typeNumber);
+ m_document->setTrackType(i, info);
+ }
+ }
+ }
+ }
+ emit tracksChanged();
+}
+
+void CustomTrackView::updateTrackDuration(int track, QUndoCommand *command)
+{
+ Q_UNUSED(command)
+
+ QList<int> tracks;
+ if (track >= 0) {
+ tracks << m_document->tracksCount() - track - 1;
+ } else {
+ // negative track number -> update all tracks
+ for (int i = 0; i < m_document->tracksCount(); ++i)
+ tracks << i;
+ }
+ int t, duration;
+ for (int i = 0; i < tracks.count(); ++i) {
+ t = tracks.at(i);
+ // t + 1 because of black background track
+ duration = m_document->renderer()->mltTrackDuration(t + 1);
+ if (duration != m_document->trackDuration(t)) {
+ m_document->setTrackDuration(t, duration);
+
+ // update effects
+ EffectsList effects = m_document->getTrackEffects(t);
+ for (int j = 0; j < effects.count(); ++j) {
+ /* TODO
+ * - lookout for keyframable parameters and update them so all keyframes are in the new range (0 - duration)
+ * - update the effectstack if necessary
+ */
+ }
+ }
+ }
+}
+
+void CustomTrackView::slotRefreshThumbs(const QString &id, bool resetThumbs)
+{
+ QList<QGraphicsItem *> list = scene()->items();
+ ClipItem *clip = NULL;
+ for (int i = 0; i < list.size(); ++i) {
+ if (list.at(i)->type() == AVWIDGET) {
+ clip = static_cast <ClipItem *>(list.at(i));
+ if (clip->clipProducer() == id) {
+ clip->refreshClip(true, resetThumbs);
+ }
+ }
+ }