X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fcustomtrackview.cpp;h=cbc29dff8eb821718903eb126610d22281cd186b;hb=60eb4b82541e1560403e52c2d078c0b4b100de7d;hp=2c211f1c9d2abbe3d6996405348c820ebdcc480e;hpb=b6a63f517f9c93311bd5b119d6c30a85cca7edc4;p=kdenlive diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 2c211f1c..cbc29dff 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -405,6 +405,15 @@ void CustomTrackView::slotCheckPositionScrolling() } } +void CustomTrackView::slotAlignPlayheadToMousePos() +{ + /* get curser point ref in screen coord */ + QPoint ps = QCursor::pos(); + /* get xPos in scene coord */ + int mappedXPos = qMax((int)(mapToScene(mapFromGlobal(ps)).x() + 0.5), 0); + /* move playhead to new xPos*/ + seekCursorPos(mappedXPos); +} // virtual void CustomTrackView::mouseMoveEvent(QMouseEvent * event) @@ -809,8 +818,10 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) while (!m_dragGuide && ct < collisionList.count()) { if (collisionList.at(ct)->type() == AVWIDGET || collisionList.at(ct)->type() == TRANSITIONWIDGET) { collisionClip = static_cast (collisionList.at(ct)); - if (collisionClip->isItemLocked()) - break; + if (collisionClip->isItemLocked() || !collisionClip->isEnabled()) { + ct++; + continue; + } if (collisionClip == m_dragItem) { collisionClip = NULL; } @@ -818,6 +829,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) m_dragItem = collisionClip; } found = true; + m_dragItem->setProperty("y_absolute", mapToScene(m_clickEvent).y() - m_dragItem->scenePos().y()); m_dragItemInfo = m_dragItem->info(); if (m_selectionGroup) m_selectionGroup->setProperty("y_absolute", mapToScene(m_clickEvent).y() - m_dragItem->scenePos().y()); @@ -833,6 +845,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) if (m_dragItem) emit clipItemSelected(NULL); m_dragItem = NULL; } + #if QT_VERSION >= 0x040800 // Add shadow to dragged item, currently disabled because of painting artifacts /*if (m_dragItem) { @@ -842,22 +855,28 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) m_dragItem->setGraphicsEffect(eff); }*/ #endif - if (m_dragItem && m_dragItem->type() == TRANSITIONWIDGET) { + if (m_dragItem && m_dragItem->type() == TRANSITIONWIDGET && m_dragItem->isEnabled()) { // update transition menu action m_autoTransition->setChecked(static_cast(m_dragItem)->isAutomatic()); m_autoTransition->setEnabled(true); - } else m_autoTransition->setEnabled(false); - + // A transition is selected + QPoint p; + ClipItem *transitionClip = getClipItemAt(m_dragItemInfo.startPos, m_dragItemInfo.track); + if (transitionClip && transitionClip->baseClip()) { + QString size = transitionClip->baseClip()->getProperty("frame_size"); + double factor = transitionClip->baseClip()->getProperty("aspect_ratio").toDouble(); + if (factor == 0) factor = 1.0; + p.setX((int)(size.section('x', 0, 0).toInt() * factor + 0.5)); + p.setY(size.section('x', 1, 1).toInt()); + } + emit transitionItemSelected(static_cast (m_dragItem), getPreviousVideoTrack(m_dragItem->track()), p); + } else { + emit transitionItemSelected(NULL); + m_autoTransition->setEnabled(false); + } // context menu requested if (event->button() == Qt::RightButton) { - if (m_dragItem) { - if (dragGroup) dragGroup->setSelected(true); - else if (!m_dragItem->isSelected()) { - resetSelectionGroup(false); - m_scene->clearSelection(); - m_dragItem->setSelected(true); - } - } else if (!m_dragGuide) { + if (!m_dragItem && !m_dragGuide) { // check if there is a guide close to mouse click QList guidesCollisionList = items(event->pos().x() - 5, event->pos().y(), 10, 2); // a rect of height < 2 does not always collide with the guide for (int i = 0; i < guidesCollisionList.count(); i++) { @@ -877,9 +896,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) m_operationMode = NONE; displayContextMenu(event->globalPos(), m_dragItem, dragGroup); m_menuPosition = m_clickEvent; - m_dragItem = NULL; - event->accept(); - return; } // No item under click @@ -956,7 +972,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) updateSnapPoints(NULL, cleandOffsetList, true); } m_operationMode = SPACER; - } else { + } else if (event->button() != Qt::RightButton) { setCursor(Qt::ArrowCursor); seekCursorPos((int)(mapToScene(event->x(), 0).x())); } @@ -1024,7 +1040,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) if (selected == false) { m_dragItem = NULL; } - groupSelectedItems(QList (), false, false, true); + groupSelectedItems(QList (), false, true); if (m_dragItem) { ClipItem *clip = static_cast (m_dragItem); updateClipTypeActions(dragGroup == NULL ? clip : NULL); @@ -1181,7 +1197,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) resetSelectionGroup(false); m_dragItem->setSelected(true); } - m_blockRefresh = false; } @@ -1209,7 +1224,7 @@ void CustomTrackView::rebuildGroup(AbstractGroupItem *group) group->removeFromGroup(children.at(i)); }*/ scene()->destroyItemGroup(group); - groupSelectedItems(children, false, true, true); + groupSelectedItems(children, true, true); } } @@ -1238,7 +1253,7 @@ void CustomTrackView::resetSelectionGroup(bool selectItems) } } -void CustomTrackView::groupSelectedItems(QList selection, bool force, bool createNewGroup, bool selectNewGroup) +void CustomTrackView::groupSelectedItems(QList selection, bool createNewGroup, bool selectNewGroup) { if (m_selectionGroup) { kDebug() << "///// ERROR, TRYING TO OVERRIDE EXISTING GROUP"; @@ -1265,7 +1280,14 @@ void CustomTrackView::groupSelectedItems(QList selection, bool } } if (itemsList.isEmpty() && groupsList.isEmpty()) return; - + if (itemsList.count() == 1 && groupsList.isEmpty()) { + // only one item selected: + QSetIterator it(itemsList); + m_dragItem = static_cast(it.next()); + m_dragItem->setSelected(true); + return; + } + QRectF rectUnion; // Find top left position of selection foreach (const QGraphicsItemGroup *value, groupsList) { @@ -1274,56 +1296,54 @@ void CustomTrackView::groupSelectedItems(QList selection, bool foreach (const QGraphicsItem *value, itemsList) { rectUnion = rectUnion.united(value->sceneBoundingRect()); } - if (force || selection.count() > 1) { - bool snap = KdenliveSettings::snaptopoints(); - KdenliveSettings::setSnaptopoints(false); - if (createNewGroup) { - AbstractGroupItem *newGroup = m_document->clipManager()->createGroup(); - newGroup->setPos(rectUnion.left(), rectUnion.top() - 1); - QPointF diff = newGroup->pos(); - newGroup->translate(-diff.x(), -diff.y()); - //newGroup->translate((int) -rectUnion.left(), (int) -rectUnion.top() + 1); - - scene()->addItem(newGroup); - // Check if we are trying to include a group in a group - foreach (QGraphicsItemGroup *value, groupsList) { - QList children = value->childItems(); - for (int i = 0; i < children.count(); i++) { - if (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET) - itemsList.insert(children.at(i)); - } - AbstractGroupItem *grp = static_cast(value); - m_document->clipManager()->removeGroup(grp); - scene()->destroyItemGroup(grp); + bool snap = KdenliveSettings::snaptopoints(); + KdenliveSettings::setSnaptopoints(false); + if (createNewGroup) { + AbstractGroupItem *newGroup = m_document->clipManager()->createGroup(); + newGroup->setPos(rectUnion.left(), rectUnion.top() - 1); + QPointF diff = newGroup->pos(); + newGroup->translate(-diff.x(), -diff.y()); + //newGroup->translate((int) -rectUnion.left(), (int) -rectUnion.top() + 1); + + scene()->addItem(newGroup); + // Check if we are trying to include a group in a group + foreach (QGraphicsItemGroup *value, groupsList) { + QList children = value->childItems(); + for (int i = 0; i < children.count(); i++) { + if (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET) + itemsList.insert(children.at(i)); } + AbstractGroupItem *grp = static_cast(value); + m_document->clipManager()->removeGroup(grp); + scene()->destroyItemGroup(grp); + } - foreach (QGraphicsItem *value, itemsList) { - newGroup->addItem(value); - } - KdenliveSettings::setSnaptopoints(snap); - if (selectNewGroup) newGroup->setSelected(true); - } else { - m_selectionGroup = new AbstractGroupItem(m_document->fps()); - m_selectionGroup->setPos(rectUnion.left(), rectUnion.top() - 1); - QPointF diff = m_selectionGroup->pos(); - //m_selectionGroup->translate((int) - rectUnion.left(), (int) -rectUnion.top() + 1); - m_selectionGroup->translate(- diff.x(), -diff.y()); + foreach (QGraphicsItem *value, itemsList) { + newGroup->addItem(value); + } + KdenliveSettings::setSnaptopoints(snap); + if (selectNewGroup) newGroup->setSelected(true); + } else { + m_selectionGroup = new AbstractGroupItem(m_document->fps()); + m_selectionGroup->setPos(rectUnion.left(), rectUnion.top() - 1); + QPointF diff = m_selectionGroup->pos(); + //m_selectionGroup->translate((int) - rectUnion.left(), (int) -rectUnion.top() + 1); + m_selectionGroup->translate(- diff.x(), -diff.y()); - scene()->addItem(m_selectionGroup); - foreach (QGraphicsItemGroup *value, groupsList) { - m_selectionGroup->addItem(value); - } - foreach (QGraphicsItem *value, itemsList) { - m_selectionGroup->addItem(value); - } - KdenliveSettings::setSnaptopoints(snap); - if (m_selectionGroup) { - m_selectionGroupInfo.startPos = GenTime(m_selectionGroup->scenePos().x(), m_document->fps()); - m_selectionGroupInfo.track = m_selectionGroup->track(); - if (selectNewGroup) m_selectionGroup->setSelected(true); - } + scene()->addItem(m_selectionGroup); + foreach (QGraphicsItemGroup *value, groupsList) { + m_selectionGroup->addItem(value); + } + foreach (QGraphicsItem *value, itemsList) { + m_selectionGroup->addItem(value); } - } else resetSelectionGroup(); + KdenliveSettings::setSnaptopoints(snap); + if (m_selectionGroup) { + m_selectionGroupInfo.startPos = GenTime(m_selectionGroup->scenePos().x(), m_document->fps()); + m_selectionGroupInfo.track = m_selectionGroup->track(); + if (selectNewGroup) m_selectionGroup->setSelected(true); + } + } } void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) @@ -2713,7 +2733,7 @@ void CustomTrackView::dropEvent(QDropEvent * event) m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1); if (items.count() > 1) { - groupSelectedItems(items, true); + groupSelectedItems(items); } else if (items.count() == 1) { m_dragItem = static_cast (items.at(0)); emit clipItemSelected((ClipItem*) m_dragItem, false); @@ -3418,29 +3438,29 @@ void CustomTrackView::deleteClip(const QString &clipId) resetSelectionGroup(); QList itemList = items(); QUndoCommand *deleteCommand = new QUndoCommand(); + new RefreshMonitorCommand(this, false, true, deleteCommand); int count = 0; for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { ClipItem *item = (ClipItem *)itemList.at(i); if (item->clipProducer() == clipId) { - count++; + count++; if (item->parentItem()) { - // Clip is in a group, destroy the group - new GroupClipsCommand(this, QList() << item->info(), QList(), false, deleteCommand); + // Clip is in a group, destroy the group + new GroupClipsCommand(this, QList() << item->info(), QList(), false, deleteCommand); } new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), false, false, true, true, deleteCommand); } } } - deleteCommand->setText(i18np("Delete timeline clip", "Delete timeline clips", count)); if (count == 0) { delete deleteCommand; } else { + deleteCommand->setText(i18np("Delete timeline clip", "Delete timeline clips", count)); + new RefreshMonitorCommand(this, true, false, deleteCommand); updateTrackDuration(-1, deleteCommand); - new RefreshMonitorCommand(this, false, deleteCommand); m_commandStack->push(deleteCommand); } - m_document->renderer()->doRefresh(); } void CustomTrackView::seekCursorPos(int pos) @@ -3619,6 +3639,11 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) resetSelectionGroup(); groupSelectedItems(); m_operationMode = NONE; + if (m_selectionGroup == NULL && m_dragItem) { + // Only 1 item selected + if (m_dragItem->type() == AVWIDGET) + emit clipItemSelected(static_cast(m_dragItem)); + } } if (m_dragItem == NULL && m_selectionGroup == NULL) { @@ -3936,6 +3961,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) } } else { prepareResizeClipStart(m_dragItem, m_dragItemInfo, m_dragItem->startPos().frames(m_document->fps())); + if (m_dragItem->type() == AVWIDGET) static_cast (m_dragItem)->slotUpdateRange(); } } else if (m_operationMode == RESIZEEND && m_dragItem->endPos() != m_dragItemInfo.endPos) { // resize end @@ -3961,6 +3987,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) } } else { prepareResizeClipEnd(m_dragItem, m_dragItemInfo, m_dragItem->endPos().frames(m_document->fps())); + if (m_dragItem->type() == AVWIDGET) static_cast (m_dragItem)->slotUpdateRange(); } } else if (m_operationMode == FADEIN) { // resize fade in effect @@ -4083,19 +4110,6 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect()); emit clipItemSelected(item); } - if (m_dragItem && m_dragItem->type() == TRANSITIONWIDGET && m_dragItem->isSelected()) { - // A transition is selected - QPoint p; - ClipItem *transitionClip = getClipItemAt(m_dragItemInfo.startPos, m_dragItemInfo.track); - if (transitionClip && transitionClip->baseClip()) { - QString size = transitionClip->baseClip()->getProperty("frame_size"); - double factor = transitionClip->baseClip()->getProperty("aspect_ratio").toDouble(); - if (factor == 0) factor = 1.0; - p.setX((int)(size.section('x', 0, 0).toInt() * factor + 0.5)); - p.setY(size.section('x', 1, 1).toInt()); - } - emit transitionItemSelected(static_cast (m_dragItem), getPreviousVideoTrack(m_dragItem->track()), p); - } else emit transitionItemSelected(NULL); if (m_operationMode != NONE && m_operationMode != MOVE) setDocumentModified(); m_operationMode = NONE; } @@ -4160,6 +4174,7 @@ void CustomTrackView::deleteSelectedClips() } scene()->clearSelection(); QUndoCommand *deleteSelected = new QUndoCommand(); + new RefreshMonitorCommand(this, false, true, deleteSelected); int groupCount = 0; int clipCount = 0; @@ -4215,9 +4230,8 @@ void CustomTrackView::deleteSelectedClips() deleteSelected->setText(i18np("Delete selected transition", "Delete selected transitions", transitionCount)); else deleteSelected->setText(i18n("Delete selected items")); updateTrackDuration(-1, deleteSelected); - new RefreshMonitorCommand(this, false, deleteSelected); + new RefreshMonitorCommand(this, true, false, deleteSelected); m_commandStack->push(deleteSelected); - m_document->renderer()->doRefresh(); } @@ -4424,7 +4438,7 @@ void CustomTrackView::doGroupClips(QList clipInfos, QList //clip->setSelected(true); } } - groupSelectedItems(list, false, true, true); + groupSelectedItems(list, true, true); setDocumentModified(); } @@ -4476,8 +4490,9 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i m_document->renderer()->mltAddEffect(info.track, info.startPos, getEffectArgs(item->effect(i)), false); } setDocumentModified(); - if (refresh) + if (refresh) { m_document->renderer()->doRefresh(); + } if (!baseclip->isPlaceHolder()) m_waitingThumbs.append(item); m_thumbsTimer.start(); @@ -6013,6 +6028,7 @@ void CustomTrackView::pasteClip() } QUndoCommand *pasteClips = new QUndoCommand(); pasteClips->setText("Paste clips"); + new RefreshMonitorCommand(this, false, true, pasteClips); for (int i = 0; i < m_copiedItems.count(); i++) { // parse all clip names @@ -6042,7 +6058,7 @@ void CustomTrackView::pasteClip() } } updateTrackDuration(-1, pasteClips); - new RefreshMonitorCommand(this, false, pasteClips); + new RefreshMonitorCommand(this, false, false, pasteClips); m_commandStack->push(pasteClips); } @@ -6501,7 +6517,7 @@ void CustomTrackView::loadGroups(const QDomNodeList &groups) if (clip) list.append(clip);//clip->setSelected(true); } } - groupSelectedItems(list, false, true); + groupSelectedItems(list, true); } } @@ -6730,7 +6746,7 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, EffectsList ef videoIx++; } } - groupSelectedItems(QList ()<()<setSelected(true); } }*/ - groupSelectedItems(children, true, true); + groupSelectedItems(children, true); } else if (itemList.at(i)->type() == GUIDEITEM) { Guide *g = static_cast(itemList.at(i)); g->updatePos(); @@ -7093,14 +7109,14 @@ void CustomTrackView::slotSelectClipsInTrack() list.append(selection.at(i)); } } - groupSelectedItems(list, false, false, true); + groupSelectedItems(list, false, true); } void CustomTrackView::slotSelectAllClips() { m_scene->clearSelection(); resetSelectionGroup(); - groupSelectedItems(m_scene->items(), false, false, true); + groupSelectedItems(m_scene->items(), false, true); } void CustomTrackView::selectClip(bool add, bool group, int track, int pos) @@ -7589,19 +7605,27 @@ void CustomTrackView::slotGotFilterJobResults(const QString &/*id*/, int startPo void CustomTrackView::slotImportClipKeyframes(GRAPHICSRECTITEM type) { - if (!m_selectionGroup) { - emit displayMessage(i18n("You need to select one clip and one transition"), ErrorMessage); - return; - } - // Make sure there is no collision - QList children = m_selectionGroup->childItems(); ClipItem *item = NULL; - for (int i = 0; i < children.count(); i++) { - if (children.at(i)->type() == AVWIDGET) { - item = (ClipItem*) children.at(i); - break; - } + if (type == TRANSITIONWIDGET) { + // We want to import keyframes to a transition + if (!m_selectionGroup) { + emit displayMessage(i18n("You need to select one clip and one transition"), ErrorMessage); + return; + } + // Make sure there is no collision + QList children = m_selectionGroup->childItems(); + for (int i = 0; i < children.count(); i++) { + if (children.at(i)->type() == AVWIDGET) { + item = (ClipItem*) children.at(i); + break; + } + } } + else { + // Import keyframes from current clip to its effect + if (m_dragItem) item = static_cast (m_dragItem); + } + if (!item) { emit displayMessage(i18n("No clip found"), ErrorMessage); return; @@ -7630,7 +7654,23 @@ void CustomTrackView::slotImportClipKeyframes(GRAPHICSRECTITEM type) return; } QString keyframeData = ui.data_list->itemData(ui.data_list->currentIndex()).toString(); - QStringList keyframeList = keyframeData.split(';', QString::SkipEmptyParts); + + int offset = item->cropStart().frames(m_document->fps()); + Mlt::Geometry geometry(keyframeData.toUtf8().data(), item->baseClip()->maxDuration().frames(m_document->fps()), m_document->mltProfile().width, m_document->mltProfile().height); + Mlt::Geometry newGeometry(QString().toUtf8().data(), item->baseClip()->maxDuration().frames(m_document->fps()), m_document->mltProfile().width, m_document->mltProfile().height); + Mlt::GeometryItem gitem; + geometry.fetch(&gitem, offset); + gitem.frame(0); + newGeometry.insert(gitem); + int pos = offset + 1; + while (!geometry.next_key(&gitem, pos)) { + pos = gitem.frame(); + gitem.frame(pos - offset); + pos++; + newGeometry.insert(gitem); + } + QStringList keyframeList = QString(newGeometry.serialise()).split(';', QString::SkipEmptyParts); + QString result; if (ui.import_position->isChecked()) { if (ui.import_size->isChecked()) {