+
+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;
+ 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();
+ //kDebug() << "/ / / /SENDING EFFECT PARAM: " << e.attribute("type") << ", NAME_ " << e.attribute("tag");
+ 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 + "=" + QString::number(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").startsWith('%')) {
+ fact = ProfilesDialog::getStringEval(m_document->mltProfile(), e.attribute("factor"));
+ } else fact = e.attribute("factor", "1").toDouble();
+ parameters.addParam(e.attribute("name"), QString::number(e.attribute("value").toDouble() / fact));
+ } else {
+ parameters.addParam(e.attribute("name"), e.attribute("value"));
+ }
+ }
+ }
+ return parameters;
+}
+
+void CustomTrackView::updatePanZoom(ClipItem* item, GenTime cutPos)
+{
+ QList <int> effects = item->updatePanZoom(m_document->width(), m_document->height(), cutPos.frames(m_document->fps()));
+ for (int i = 0; i < effects.count(); ++i) {
+ if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), getEffectArgs(item->effectAt(effects.at(i)))))
+ emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+
+ // if effect is displayed, update the effect edit widget with new clip duration
+ /*if (item->isSelected() && effects.at(i) == item->selectedEffectIndex())
+ emit clipItemSelected(item, effects.at(i));*/
+ }
+ // update always, otherwise there might problems when resizing groups
+ if (effects.count() > 0)
+ emit clipItemSelected(item, item->selectedEffectIndex());
+}
+
+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
+ */
+ }
+ }
+ }
+}
+
+