From: Ed Rogalsky Date: Tue, 30 Oct 2012 07:05:15 +0000 (+0100) Subject: Merge branch 'master' into feature/pkey X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=09194484c415d7a7645bcf7c2245cc753059ea4c;hp=71e41ad0c197e2e2eb033dff7800427f64d3428f;p=kdenlive Merge branch 'master' into feature/pkey --- diff --git a/src/abstractclipitem.h b/src/abstractclipitem.h index 8703c919..1cdcf0cb 100644 --- a/src/abstractclipitem.h +++ b/src/abstractclipitem.h @@ -94,7 +94,6 @@ public: protected: ItemInfo m_info; -// int m_track; /** The position of the current keyframe when it has moved */ int m_editedKeyframe; /** The position of the current keyframe before it was moved */ diff --git a/src/abstractgroupitem.cpp b/src/abstractgroupitem.cpp index 2db8874e..9442aa2b 100644 --- a/src/abstractgroupitem.cpp +++ b/src/abstractgroupitem.cpp @@ -32,6 +32,7 @@ #include #include + AbstractGroupItem::AbstractGroupItem(double /* fps */) : QObject(), QGraphicsItemGroup() @@ -114,7 +115,7 @@ QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, QPointF offset void AbstractGroupItem::addItem(QGraphicsItem * item) { addToGroup(item); - //fixItemRect(); + item->setFlag(QGraphicsItem::ItemIsMovable, false); } void AbstractGroupItem::fixItemRect() @@ -168,22 +169,18 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant //kDebug()<<"GRP XPOS:"<tracksCount() - (int)(boundingRect().height() + 5) / trackHeight); - correctedTrack = qMax(correctedTrack, 0); - - proposedTrack += (correctedTrack - realTrack); + int yOffset = property("y_absolute").toInt() + newPos.y(); + int proposedTrack = yOffset / trackHeight; // Check if top item is a clip or a transition int offset = 0; int topTrack = -1; QList children = childItems(); for (int i = 0; i < children.count(); i++) { - int currentTrack = (int)(children.at(i)->scenePos().y() / trackHeight); + int currentTrack = 0; + if (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET) currentTrack = static_cast (children.at(i))->track(); + else if (children.at(i)->type() == GROUPWIDGET) currentTrack = static_cast (children.at(i))->track(); + else continue; if (children.at(i)->type() == AVWIDGET) { if (topTrack == -1 || currentTrack <= topTrack) { offset = 0; diff --git a/src/abstractmonitor.cpp b/src/abstractmonitor.cpp index fa6f43c9..e66a4bd1 100644 --- a/src/abstractmonitor.cpp +++ b/src/abstractmonitor.cpp @@ -59,9 +59,9 @@ bool AbstractMonitor::isActive() const return m_monitorManager->isActive(m_id); } -bool AbstractMonitor::slotActivateMonitor() +bool AbstractMonitor::slotActivateMonitor(bool forceRefresh) { - return m_monitorManager->activateMonitor(m_id); + return m_monitorManager->activateMonitor(m_id, forceRefresh); } VideoContainer::VideoContainer(AbstractMonitor* monitor, QWidget *parent) : diff --git a/src/abstractmonitor.h b/src/abstractmonitor.h index 0a821288..eec0cfef 100644 --- a/src/abstractmonitor.h +++ b/src/abstractmonitor.h @@ -105,7 +105,7 @@ public slots: virtual void start() = 0; virtual void slotPlay() = 0; virtual void slotMouseSeek(int eventDelta, bool fast) = 0; - bool slotActivateMonitor(); + bool slotActivateMonitor(bool forceRefresh = false); virtual void slotSwitchFullScreen() = 0; protected: diff --git a/src/commands/CMakeLists.txt b/src/commands/CMakeLists.txt index 5da8b75b..cface28b 100644 --- a/src/commands/CMakeLists.txt +++ b/src/commands/CMakeLists.txt @@ -30,6 +30,7 @@ set(kdenlive_SRCS commands/razorclipcommand.cpp commands/razorgroupcommand.cpp commands/rebuildgroupcommand.cpp + commands/refreshmonitorcommand.cpp commands/resizeclipcommand.cpp commands/splitaudiocommand.cpp PARENT_SCOPE diff --git a/src/commands/refreshmonitorcommand.cpp b/src/commands/refreshmonitorcommand.cpp new file mode 100644 index 00000000..8130bbb3 --- /dev/null +++ b/src/commands/refreshmonitorcommand.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2012 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#include "refreshmonitorcommand.h" +#include "customtrackview.h" + + +RefreshMonitorCommand::RefreshMonitorCommand(CustomTrackView *view, bool execute, QUndoCommand * parent) : + QUndoCommand(parent), + m_view(view), + m_exec(execute) +{ +} + + +// virtual +void RefreshMonitorCommand::undo() +{ + m_view->monitorRefresh(); +} +// virtual +void RefreshMonitorCommand::redo() +{ + if (m_exec) + m_view->monitorRefresh(); + m_exec = true; +} + + diff --git a/src/commands/refreshmonitorcommand.h b/src/commands/refreshmonitorcommand.h new file mode 100644 index 00000000..5a11a4ce --- /dev/null +++ b/src/commands/refreshmonitorcommand.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2012 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#ifndef REFRESHMONITORCOMMAND_H +#define REFRESHMONITORCOMMAND_H + +#include + +class CustomTrackView; + +class RefreshMonitorCommand : public QUndoCommand +{ +public: + RefreshMonitorCommand(CustomTrackView *view, bool execute, QUndoCommand * parent = 0); + virtual void undo(); + virtual void redo(); + +private: + CustomTrackView *m_view; + bool m_exec; +}; + +#endif + diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index d03e745d..c9c4df4a 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -63,6 +63,7 @@ #include "commands/configtrackscommand.h" #include "commands/rebuildgroupcommand.h" #include "commands/razorgroupcommand.h" +#include "commands/refreshmonitorcommand.h" #include "profilesdialog.h" #include "lib/audio/audioEnvelope.h" @@ -433,9 +434,9 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) if (event->buttons() != Qt::NoButton) { bool move = (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance(); + if (m_dragItem && move) m_clipDrag = true; if (m_dragItem && m_tool == SELECTTOOL) { - if (m_operationMode == MOVE && move) { - //m_dragItem->setProperty("y_absolute", event->pos().y()); + if (m_operationMode == MOVE && m_clipDrag) { QGraphicsView::mouseMoveEvent(event); // If mouse is at a border of the view, scroll if (pos < 5) { @@ -735,6 +736,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { setFocus(Qt::MouseFocusReason); m_menuPosition = QPoint(); + m_clipDrag = false; // special cases (middle click button or ctrl / shift click if (event->button() == Qt::MidButton) { @@ -812,16 +814,19 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) collisionClip = static_cast (collisionList.at(ct)); if (collisionClip->isItemLocked()) break; - if (collisionClip == m_dragItem) + if (collisionClip == m_dragItem) { collisionClip = NULL; - else + } + else { 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()); if (m_dragItem->parentItem() && m_dragItem->parentItem()->type() == GROUPWIDGET && m_dragItem->parentItem() != m_selectionGroup) { - // kDebug()<<"// KLIK FOUND GRP: "<sceneBoundingRect(); dragGroup = static_cast (m_dragItem->parentItem()); + dragGroup->setProperty("y_absolute", mapToScene(m_clickEvent).y() - m_dragItem->scenePos().y()); } break; } @@ -831,13 +836,14 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) if (m_dragItem) emit clipItemSelected(NULL); m_dragItem = NULL; } -#if QT_VERSION >= 0x040600 +#if QT_VERSION >= 0x040800 // Add shadow to dragged item, currently disabled because of painting artifacts - //TODO: re-enable when fixed - /*QGraphicsDropShadowEffect *eff = new QGraphicsDropShadowEffect(); - eff->setBlurRadius(5); - eff->setOffset(3, 3); - m_dragItem->setGraphicsEffect(eff);*/ + /*if (m_dragItem) { + QGraphicsDropShadowEffect *eff = new QGraphicsDropShadowEffect(); + eff->setBlurRadius(5); + eff->setOffset(3, 3); + m_dragItem->setGraphicsEffect(eff); + }*/ #endif if (m_dragItem && m_dragItem->type() == TRANSITIONWIDGET) { // update transition menu action @@ -925,8 +931,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) if (item->isItemLocked()) continue; offsetList.append(item->startPos()); offsetList.append(item->endPos()); - m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(selection.at(i)); } else if (/*selection.at(i)->parentItem() == 0 && */selection.at(i)->type() == GROUPWIDGET) { if (static_cast(selection.at(i))->isItemLocked()) continue; QList children = selection.at(i)->childItems(); @@ -935,13 +940,10 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) offsetList.append(item->startPos()); offsetList.append(item->endPos()); } - m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(selection.at(i)); } else if (selection.at(i)->parentItem() && !selection.contains(selection.at(i)->parentItem())) { if (static_cast(selection.at(i)->parentItem())->isItemLocked()) continue; - //AbstractGroupItem *grp = static_cast(selection.at(i)->parentItem()); - m_selectionGroup->addToGroup(selection.at(i)->parentItem()); - selection.at(i)->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(selection.at(i)->parentItem()); } } m_spacerOffset = m_selectionGroup->sceneBoundingRect().left() - (int)(mapToScene(m_clickEvent).x()); @@ -961,7 +963,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) } else { seekCursorPos((int)(mapToScene(event->x(), 0).x())); } - //QGraphicsView::mousePressEvent(event); + QGraphicsView::mousePressEvent(event); event->ignore(); return; } @@ -988,12 +990,15 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) } bool itemSelected = false; - if (m_dragItem->isSelected()) + if (m_dragItem->isSelected()) { itemSelected = true; - else if (m_dragItem->parentItem() && m_dragItem->parentItem()->isSelected()) + } + else if (m_dragItem->parentItem() && m_dragItem->parentItem()->isSelected()) { itemSelected = true; - else if (dragGroup && dragGroup->isSelected()) + } + else if (dragGroup && dragGroup->isSelected()) { itemSelected = true; + } if ((event->modifiers() == Qt::ControlModifier) || itemSelected == false) { if (event->modifiers() != Qt::ControlModifier) { @@ -1008,10 +1013,16 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) if (m_dragItem->parentItem() && m_dragItem->parentItem()->type() == GROUPWIDGET) { dragGroup = static_cast (m_dragItem->parentItem()); } + bool selected = !m_dragItem->isSelected(); - /*if (dragGroup) + QGraphicsView::mousePressEvent(event); + + if (dragGroup) { dragGroup->setSelected(selected); - else*/ + if (dragGroup->parentItem()) + dragGroup->parentItem()->setSelected(selected); + } + else m_dragItem->setSelected(selected); if (selected == false) { m_dragItem = NULL; @@ -1024,6 +1035,20 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) } else updateClipTypeActions(NULL); } + else { + QGraphicsView::mousePressEvent(event); + if (m_selectionGroup) { + QList children = m_selectionGroup->childItems(); + for (int i = 0; i < children.count(); i++) { + children.at(i)->setSelected(itemSelected); + } + m_selectionGroup->setSelected(itemSelected); + + } + if (dragGroup) + dragGroup->setSelected(itemSelected); + m_dragItem->setSelected(itemSelected); + } if (collisionClip != NULL || m_dragItem == NULL) { if (m_dragItem && m_dragItem->type() == AVWIDGET && !m_dragItem->isItemLocked()) { @@ -1036,7 +1061,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) // If clicked item is selected, allow move //if (!(event->modifiers() | Qt::ControlModifier) && m_operationMode == NONE) - QGraphicsView::mousePressEvent(event); + //QGraphicsView::mousePressEvent(event); if (m_dragItem) { m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps())), (int)(event->pos().y() - m_dragItem->pos().y())); @@ -1161,8 +1186,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) } m_blockRefresh = false; - //kDebug()<clearSelection(); - QList children = group->childItems(); m_document->clipManager()->removeGroup(group); - scene()->destroyItemGroup(group); - for (int i = 0; i < children.count(); i++) - children.at(i)->setSelected(true); - groupSelectedItems(false, true); + /*for (int i = 0; i < children.count(); i++) { + group->removeFromGroup(children.at(i)); + }*/ + scene()->destroyItemGroup(group); + groupSelectedItems(children, false, true, true); } } @@ -1204,6 +1225,7 @@ void CustomTrackView::resetSelectionGroup(bool selectItems) QList children = m_selectionGroup->childItems(); scene()->destroyItemGroup(m_selectionGroup); + m_selectionGroup = NULL; for (int i = 0; i < children.count(); i++) { if (children.at(i)->parentItem() == 0 && (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET)) { if (!static_cast (children.at(i))->isItemLocked()) { @@ -1215,33 +1237,46 @@ void CustomTrackView::resetSelectionGroup(bool selectItems) children.at(i)->setSelected(selectItems); } } - - m_selectionGroup = NULL; KdenliveSettings::setSnaptopoints(snap); } } -void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup) +void CustomTrackView::groupSelectedItems(QList selection, bool force, bool createNewGroup, bool selectNewGroup) { if (m_selectionGroup) { kDebug() << "///// ERROR, TRYING TO OVERRIDE EXISTING GROUP"; return; } - QList selection = m_scene->selectedItems(); - if (m_dragItem && !selection.contains(m_dragItem)) { - selection << m_dragItem; + if (selection.isEmpty()) selection = m_scene->selectedItems(); + // Split groups and items + QSet groupsList; + QSet itemsList; + + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == GROUPWIDGET) { + groupsList.insert(static_cast (selection.at(i))); + } + } + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET) { + if (selection.at(i)->parentItem() && selection.at(i)->parentItem()->type() == GROUPWIDGET) { + groupsList.insert(static_cast (selection.at(i)->parentItem())); + } + else { + itemsList.insert(selection.at(i)); + } + } } - if (selection.isEmpty()) return; + if (itemsList.isEmpty() && groupsList.isEmpty()) return; + QRectF rectUnion; // Find top left position of selection - for (int i = 0; i < selection.count(); i++) { - if (selection.at(i)->parentItem() == 0 && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) { - rectUnion = rectUnion.united(selection.at(i)->sceneBoundingRect()); - } else if (selection.at(i)->parentItem()) { - rectUnion = rectUnion.united(selection.at(i)->parentItem()->sceneBoundingRect()); - } + foreach (const QGraphicsItemGroup *value, groupsList) { + rectUnion = rectUnion.united(value->sceneBoundingRect()); + } + foreach (const QGraphicsItem *value, itemsList) { + rectUnion = rectUnion.united(value->sceneBoundingRect()); } - if (force || selection.count() > 1) { bool snap = KdenliveSettings::snaptopoints(); KdenliveSettings::setSnaptopoints(false); @@ -1253,32 +1288,23 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup) //newGroup->translate((int) -rectUnion.left(), (int) -rectUnion.top() + 1); scene()->addItem(newGroup); - // Check if we are trying to include a group in a group - QList groups; - for (int i = 0; i < selection.count(); i++) { - if (selection.at(i)->type() == GROUPWIDGET && !groups.contains(static_cast(selection.at(i)))) - groups.append(static_cast(selection.at(i))); - else if (selection.at(i)->parentItem() && !groups.contains(static_cast(selection.at(i)->parentItem()))) - groups.append(static_cast(selection.at(i)->parentItem())); - } - if (!groups.isEmpty()) { - // ungroup previous groups - while (!groups.isEmpty()) { - AbstractGroupItem *grp = groups.takeFirst(); - m_document->clipManager()->removeGroup(grp); - scene()->destroyItemGroup(grp); - } - selection = m_scene->selectedItems(); - } + 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); + } - for (int i = 0; i < selection.count(); i++) { - if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET) { - newGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); - } + 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); @@ -1287,16 +1313,17 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup) m_selectionGroup->translate(- diff.x(), -diff.y()); scene()->addItem(m_selectionGroup); - for (int i = 0; i < selection.count(); i++) { - if (selection.at(i)->parentItem() == 0 && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) { - m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); - } + 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); } } } else resetSelectionGroup(); @@ -1576,8 +1603,7 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint &pos) } m_selectionGroup = new AbstractGroupItem(m_document->fps()); ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1, getFrameWidth()); - m_selectionGroup->addToGroup(item); - item->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(item); QList offsetList; offsetList.append(info.endPos); @@ -1654,8 +1680,7 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint &pos) start += info.cropDuration; offsetList.append(start); ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1, getFrameWidth(), false); - item->setFlag(QGraphicsItem::ItemIsMovable, false); - m_selectionGroup->addToGroup(item); + m_selectionGroup->addItem(item); if (!clip->isPlaceHolder()) m_waitingThumbs.append(item); } @@ -2615,6 +2640,7 @@ void CustomTrackView::dropEvent(QDropEvent * event) if (m_selectionGroup && m_clipDrag) { QList items = m_selectionGroup->childItems(); resetSelectionGroup(); + m_dragItem = NULL; m_scene->clearSelection(); bool hasVideoClip = false; QUndoCommand *addCommand = new QUndoCommand(); @@ -2690,11 +2716,12 @@ void CustomTrackView::dropEvent(QDropEvent * event) m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1); if (items.count() > 1) { - groupSelectedItems(true); + groupSelectedItems(items, true); } else if (items.count() == 1) { m_dragItem = static_cast (items.at(0)); emit clipItemSelected((ClipItem*) m_dragItem, false); } + m_document->renderer()->refreshIfActive(); event->setDropAction(Qt::MoveAction); event->accept(); @@ -2882,8 +2909,7 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) scene()->addItem(m_selectionGroup); for (int i = 0; i < selection.count(); i++) { if ((!selection.at(i)->parentItem()) && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) { - m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(selection.at(i)); } } // Move graphic items @@ -2967,8 +2993,7 @@ void CustomTrackView::removeTrack(int ix) scene()->addItem(m_selectionGroup); for (int i = 0; i < selection.count(); i++) { if ((!selection.at(i)->parentItem()) && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) { - m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(selection.at(i)); } } // Move graphic items @@ -3345,11 +3370,9 @@ void CustomTrackView::insertSpace(QList clipsToMove, QList t clip = getClipItemAtStart(clipsToMove.at(i).startPos + offset, clipsToMove.at(i).track); if (clip) { if (clip->parentItem()) { - m_selectionGroup->addToGroup(clip->parentItem()); - clip->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(clip->parentItem()); } else { - m_selectionGroup->addToGroup(clip); - clip->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(clip); } if (trackClipStartList.value(m_document->tracksCount() - clipsToMove.at(i).track) == -1 || clipsToMove.at(i).startPos.frames(m_document->fps()) < trackClipStartList.value(m_document->tracksCount() - clipsToMove.at(i).track)) trackClipStartList[m_document->tracksCount() - clipsToMove.at(i).track] = clipsToMove.at(i).startPos.frames(m_document->fps()); @@ -3361,11 +3384,9 @@ void CustomTrackView::insertSpace(QList clipsToMove, QList t transition = getTransitionItemAtStart(transToMove.at(i).startPos + offset, transToMove.at(i).track); if (transition) { if (transition->parentItem()) { - m_selectionGroup->addToGroup(transition->parentItem()); - transition->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(transition->parentItem()); } else { - m_selectionGroup->addToGroup(transition); - transition->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(transition); } if (trackTransitionStartList.value(m_document->tracksCount() - transToMove.at(i).track) == -1 || transToMove.at(i).startPos.frames(m_document->fps()) < trackTransitionStartList.value(m_document->tracksCount() - transToMove.at(i).track)) trackTransitionStartList[m_document->tracksCount() - transToMove.at(i).track] = transToMove.at(i).startPos.frames(m_document->fps()); @@ -3417,8 +3438,10 @@ void CustomTrackView::deleteClip(const QString &clipId) delete deleteCommand; } else { updateTrackDuration(-1, deleteCommand); + new RefreshMonitorCommand(this, false, deleteCommand); m_commandStack->push(deleteCommand); } + m_document->renderer()->doRefresh(); } void CustomTrackView::seekCursorPos(int pos) @@ -3483,16 +3506,22 @@ void CustomTrackView::checkScrolling() void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { if (m_moveOpMode == SEEK) m_moveOpMode = NONE; - if (!m_controlModifier) QGraphicsView::mouseReleaseEvent(event); - setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate); -#if QT_VERSION >= 0x040600 - if (m_dragItem) m_dragItem->setGraphicsEffect(NULL); + if (!m_controlModifier && m_operationMode != RUBBERSELECTION) { + //event->accept(); + if (m_clipDrag) QGraphicsView::mouseReleaseEvent(event); + } + m_clipDrag = false; + //setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate); +#if QT_VERSION >= 0x040800 + if (m_dragItem) { + m_dragItem->setGraphicsEffect(NULL); + } #endif if (m_scrollTimer.isActive()) m_scrollTimer.stop(); if (event->button() == Qt::MidButton) { return; } - setDragMode(QGraphicsView::NoDrag); + if (m_operationMode == MOVEGUIDE) { setCursor(Qt::ArrowCursor); m_operationMode = NONE; @@ -3562,20 +3591,25 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) updateTrackDuration(track, command); m_commandStack->push(command); if (track != -1) track = m_document->tracksCount() - track; - kDebug() << "SPACER TRACK:" << track; m_document->renderer()->mltInsertSpace(trackClipStartList, trackTransitionStartList, track, timeOffset, GenTime()); setDocumentModified(); } } - for (int i = 0; i < groups.count(); i++) + resetSelectionGroup(); + for (int i = 0; i < groups.count(); i++) { rebuildGroup(groups.at(i)); + } - resetSelectionGroup(); clearSelection(); m_operationMode = NONE; } else if (m_operationMode == RUBBERSELECTION) { + //event->accept(); + QGraphicsView::mouseReleaseEvent(event); + setDragMode(QGraphicsView::NoDrag); + setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate); + if (event->modifiers() != Qt::ControlModifier) m_dragItem = NULL; resetSelectionGroup(); groupSelectedItems(); m_operationMode = NONE; @@ -3742,10 +3776,12 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) // Moving several clips. We need to delete them and readd them to new position, // or they might overlap each other during the move QGraphicsItemGroup *group; - if (m_selectionGroup) + if (m_selectionGroup) { group = static_cast (m_selectionGroup); - else + } + else { group = static_cast (m_dragItem->parentItem()); + } QList items = group->childItems(); QList clipsToMove; QList transitionsToMove; @@ -3829,31 +3865,43 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) if (m_selectionGroup) { m_selectionGroupInfo.startPos = GenTime(m_selectionGroup->scenePos().x(), m_document->fps()); m_selectionGroupInfo.track = m_selectionGroup->track(); - - QList groupList; - for (int i = 0; i < items.count(); ++i) { - if (items.at(i)->type() == GROUPWIDGET) { - AbstractGroupItem* group = (AbstractGroupItem*)items.at(i); - if (!groupList.contains(group)) groupList.append(group); - items.removeAt(i); - --i; + items = m_selectionGroup->childItems(); + resetSelectionGroup(false); + + QSet groupList; + QSet itemList; + while (!items.isEmpty()) { + QGraphicsItem *first = items.takeFirst(); + if (first->type() == GROUPWIDGET) { + if (first != m_selectionGroup) { + groupList.insert(first); + } } - } - for (int i = 0; i < groupList.count(); ++i) { - rebuildGroup(groupList.at(i)); + else if (first->type() == AVWIDGET || first->type() == TRANSITIONWIDGET) { + if (first->parentItem() && first->parentItem()->type() == GROUPWIDGET) { + if (first->parentItem() != m_selectionGroup) { + groupList.insert(first->parentItem()); + } + else itemList.insert(first); + } + else itemList.insert(first); + } } - - for (int i = 0; i < items.count(); ++i) { - if (items.at(i)) { - items.at(i)->setSelected(true); - if (items.at(i)->parentItem()) - items.at(i)->parentItem()->setSelected(true); - } + foreach(QGraphicsItem *item, groupList) { + itemList.unite(item->childItems().toSet()); + rebuildGroup(static_cast (item)); + } + + foreach(QGraphicsItem *item, itemList) { + item->setSelected(true); + if (item->parentItem()) + item->parentItem()->setSelected(true); } resetSelectionGroup(); - groupSelectedItems(); + groupSelectedItems(itemList.toList()); } else { - rebuildGroup((AbstractGroupItem *)group); + AbstractGroupItem *grp = static_cast (group); + rebuildGroup(grp); } setDocumentModified(); } @@ -4161,7 +4209,9 @@ 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); m_commandStack->push(deleteSelected); + m_document->renderer()->doRefresh(); } @@ -4353,21 +4403,22 @@ void CustomTrackView::doGroupClips(QList clipInfos, QList setDocumentModified(); return; } - - QList groups; + QList list; for (int i = 0; i < clipInfos.count(); i++) { ClipItem *clip = getClipItemAt(clipInfos.at(i).startPos, clipInfos.at(i).track); if (clip) { - clip->setSelected(true); + list.append(clip); + //clip->setSelected(true); } } for (int i = 0; i < transitionInfos.count(); i++) { Transition *clip = getTransitionItemAt(transitionInfos.at(i).startPos, transitionInfos.at(i).track); if (clip) { - clip->setSelected(true); + list.append(clip); + //clip->setSelected(true); } } - groupSelectedItems(false, true); + groupSelectedItems(list, false, true); setDocumentModified(); } @@ -4650,11 +4701,9 @@ void CustomTrackView::moveGroup(QList startClip, QList sta if (clip) { clip->setItemLocked(false); if (clip->parentItem()) { - m_selectionGroup->addToGroup(clip->parentItem()); - clip->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(clip->parentItem()); } else { - m_selectionGroup->addToGroup(clip); - clip->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(clip); } m_document->renderer()->mltRemoveClip(m_document->tracksCount() - startClip.at(i).track, startClip.at(i).startPos); } else kDebug() << "//MISSING CLIP AT: " << startClip.at(i).startPos.frames(25); @@ -4668,11 +4717,9 @@ void CustomTrackView::moveGroup(QList startClip, QList sta if (tr) { tr->setItemLocked(false); if (tr->parentItem()) { - m_selectionGroup->addToGroup(tr->parentItem()); - tr->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(tr->parentItem()); } else { - m_selectionGroup->addToGroup(tr); - tr->setFlag(QGraphicsItem::ItemIsMovable, false); + m_selectionGroup->addItem(tr); } m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_document->tracksCount() - startTransition.at(i).track, startTransition.at(i).startPos, startTransition.at(i).endPos, tr->toXML()); } else kDebug() << "//MISSING TRANSITION AT: " << startTransition.at(i).startPos.frames(25); @@ -4740,8 +4787,9 @@ void CustomTrackView::moveGroup(QList startClip, QList sta } resetSelectionGroup(false); - for (int i = 0; i < groupList.count(); i++) + for (int i = 0; i < groupList.count(); i++) { rebuildGroup(groupList.at(i)); + } clearSelection(); @@ -5977,6 +6025,7 @@ void CustomTrackView::pasteClip() } } updateTrackDuration(-1, pasteClips); + new RefreshMonitorCommand(this, false, pasteClips); m_commandStack->push(pasteClips); } @@ -6422,19 +6471,20 @@ void CustomTrackView::loadGroups(const QDomNodeList &groups) for (int i = 0; i < groups.count(); i++) { QDomNodeList children = groups.at(i).childNodes(); scene()->clearSelection(); + QList list; for (int nodeindex = 0; nodeindex < children.count(); nodeindex++) { QDomElement elem = children.item(nodeindex).toElement(); int pos = elem.attribute("position").toInt(); int track = elem.attribute("track").toInt(); if (elem.tagName() == "clipitem") { ClipItem *clip = getClipItemAt(pos, track); //m_document->tracksCount() - transitiontrack); - if (clip) clip->setSelected(true); + if (clip) list.append(clip);//clip->setSelected(true); } else { Transition *clip = getTransitionItemAt(pos, track); //m_document->tracksCount() - transitiontrack); - if (clip) clip->setSelected(true); + if (clip) list.append(clip);//clip->setSelected(true); } } - groupSelectedItems(false, true); + groupSelectedItems(list, false, true); } } @@ -6631,28 +6681,25 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, EffectsList ef } } } - kDebug() << "GOT TRK: " << track; if (freetrack == 0) { emit displayMessage(i18n("No empty space to put clip audio"), ErrorMessage); } else { ItemInfo info = clip->info(); info.track = m_document->tracksCount() - freetrack; - addClip(clip->xml(), clip->clipProducer(), info, clip->effectList()); - scene()->clearSelection(); + QDomElement xml = clip->xml(); + xml.setAttribute("audio_only", 1); + scene()->clearSelection(); + addClip(xml, clip->clipProducer(), info, clip->effectList(), false, false, false); clip->setSelected(true); ClipItem *audioClip = getClipItemAt(start, info.track); if (audioClip) { + clip->setVideoOnly(true); Mlt::Tractor *tractor = m_document->renderer()->lockService(); - clip->setVideoOnly(true); if (m_document->renderer()->mltUpdateClipProducer(tractor, m_document->tracksCount() - track, start, clip->baseClip()->videoProducer(info.track)) == false) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", start, track), ErrorMessage); } - if (m_document->renderer()->mltUpdateClipProducer(tractor, m_document->tracksCount() - info.track, start, clip->baseClip()->audioProducer(info.track)) == false) { - emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", start, info.track), ErrorMessage); - } m_document->renderer()->unlockService(tractor); audioClip->setSelected(true); - audioClip->setAudioOnly(true); // keep video effects, move audio effects to audio clip int videoIx = 0; @@ -6666,8 +6713,7 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, EffectsList ef videoIx++; } } - - groupSelectedItems(false, true); + groupSelectedItems(QList ()<push(videoCommand); } +void CustomTrackView::monitorRefresh() +{ + m_document->renderer()->doRefresh(); +} + void CustomTrackView::doChangeClipType(const GenTime &pos, int track, bool videoOnly, bool audioOnly) { ClipItem *clip = getClipItemAt(pos, track); @@ -6937,13 +6988,13 @@ void CustomTrackView::updateProjectFps() m_scene->addItem(grp); scene()->destroyItemGroup(grp); scene()->clearSelection(); - for (int j = 0; j < children.count(); j++) { + /*for (int j = 0; j < children.count(); j++) { if (children.at(j)->type() == AVWIDGET || children.at(j)->type() == TRANSITIONWIDGET) { //children.at(j)->setParentItem(0); children.at(j)->setSelected(true); } - } - groupSelectedItems(true, true); + }*/ + groupSelectedItems(children, true, true); } else if (itemList.at(i)->type() == GUIDEITEM) { Guide *g = static_cast(itemList.at(i)); g->updatePos(); @@ -7018,26 +7069,22 @@ void CustomTrackView::slotSelectClipsInTrack() QRectF rect(0, m_selectedTrack * m_tracksHeight + m_tracksHeight / 2, sceneRect().width(), m_tracksHeight / 2 - 1); QList selection = m_scene->items(rect); m_scene->clearSelection(); + QList list; for (int i = 0; i < selection.count(); i++) { if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET) { - selection.at(i)->setSelected(true); + list.append(selection.at(i)); } } resetSelectionGroup(); - groupSelectedItems(); + groupSelectedItems(list); } void CustomTrackView::slotSelectAllClips() { QList selection = m_scene->items(); m_scene->clearSelection(); - for (int i = 0; i < selection.count(); i++) { - if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET) { - selection.at(i)->setSelected(true); - } - } resetSelectionGroup(); - groupSelectedItems(); + groupSelectedItems(selection); } void CustomTrackView::selectClip(bool add, bool group, int track, int pos) diff --git a/src/customtrackview.h b/src/customtrackview.h index bdaa7461..42341874 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -205,6 +205,9 @@ public: int getFrameWidth(); /** @brief Returns last requested seeking pos (or SEEK_INACTIVE if no seek). */ int seekPosition() const; + + /** @brief Trigger a monitor refresh. */ + void monitorRefresh(); public slots: /** @brief Send seek request to MLT. */ @@ -408,7 +411,7 @@ private: ClipItem *getClipUnderCursor() const; AbstractClipItem *getMainActiveClip() const; void resetSelectionGroup(bool selectItems = true); - void groupSelectedItems(bool force = false, bool createNewGroup = false); + void groupSelectedItems(QList selection = QList (), bool force = false, bool createNewGroup = false, bool selectNewGroup = false); /** Get available space for clip move (min and max free positions) */ void getClipAvailableSpace(AbstractClipItem *item, GenTime &minimum, GenTime &maximum); /** Get available space for transition move (min and max free positions) */ diff --git a/src/effectstackedit.cpp b/src/effectstackedit.cpp index cc4212fd..10899110 100644 --- a/src/effectstackedit.cpp +++ b/src/effectstackedit.cpp @@ -152,7 +152,7 @@ void EffectStackEdit::transferParamDesc(const QDomElement &d, ItemInfo info, boo m_paramWidget = new ParameterContainer(d, info, &m_metaInfo, m_baseWidget); connect (m_paramWidget, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int))); - connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList)), this, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList))); + connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,const QMap)), this, SIGNAL(startFilterJob(QString,QString,QString,QString,const QMap))); connect (this, SIGNAL(syncEffectsPos(int)), m_paramWidget, SIGNAL(syncEffectsPos(int))); connect (m_paramWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int))); diff --git a/src/effectstackedit.h b/src/effectstackedit.h index 3ef8aaa9..f7602222 100644 --- a/src/effectstackedit.h +++ b/src/effectstackedit.h @@ -81,7 +81,7 @@ signals: void showComments(bool show); void effectStateChanged(bool enabled); /** @brief Start an MLT filter job on this clip. */ - void startFilterJob(const QString &filterName, const QString &filterParams, const QString &finalFilterName, const QString &consumer, const QString &consumerParams, const QStringList&extraParams); + void startFilterJob(const QString &filterName, const QString &filterParams, const QString &consumer, const QString &consumerParams, const QMap ); void importClipKeyframes(GRAPHICSRECTITEM = AVWIDGET); }; diff --git a/src/geometrywidget.cpp b/src/geometrywidget.cpp index 55a23404..fcbb90a6 100644 --- a/src/geometrywidget.cpp +++ b/src/geometrywidget.cpp @@ -26,6 +26,7 @@ #include "monitorscene.h" #include "monitoreditwidget.h" #include "onmonitoritems/onmonitorrectitem.h" +#include "onmonitoritems/onmonitorpathitem.h" #include "kdenlivesettings.h" #include "dragvalue.h" @@ -46,6 +47,7 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos, m_outPoint(1), m_isEffect(isEffect), m_rect(NULL), + m_geomPath(NULL), m_previous(NULL), m_geometry(NULL), m_showScene(true), @@ -245,7 +247,9 @@ GeometryWidget::~GeometryWidget() delete m_spinHeight; delete m_opacity; m_scene->removeItem(m_rect); + m_scene->removeItem(m_geomPath); if (m_rect) delete m_rect; + if (m_geomPath) delete m_geomPath; if (m_previous) delete m_previous; delete m_geometry; m_extraGeometryNames.clear(); @@ -315,14 +319,25 @@ void GeometryWidget::setupParam(const QDomElement elem, int minframe, int maxfra } Mlt::GeometryItem item; - m_geometry->fetch(&item, 0); - delete m_rect; + if (m_rect) { + m_scene->removeItem(m_rect); + delete m_rect; + } + if (m_geomPath) { + m_scene->removeItem(m_geomPath); + delete m_geomPath; + } m_rect = new OnMonitorRectItem(QRectF(0, 0, item.w(), item.h()), m_monitor->render->dar()); m_rect->setPos(item.x(), item.y()); m_rect->setZValue(0); m_scene->addItem(m_rect); connect(m_rect, SIGNAL(changed()), this, SLOT(slotUpdateGeometry())); + m_geomPath = new OnMonitorPathItem(m_monitor->render->dar()); + connect(m_geomPath, SIGNAL(changed()), this, SLOT(slotUpdatePath())); + m_geomPath->setPen(QPen(Qt::red)); + m_scene->addItem(m_geomPath); + m_geomPath->setPoints(m_geometry); m_scene->centerView(); slotPositionChanged(0, false); } @@ -527,6 +542,25 @@ void GeometryWidget::slotAddDeleteKeyframe() slotDeleteKeyframe(); } +void GeometryWidget::slotUpdatePath() +{ + if (!m_geomPath) return; + QList points = m_geomPath->points(); + Mlt::GeometryItem item; + int pos = 0; + int ix = 0; + while (ix < points.count() && !m_geometry->next_key(&item, pos)) { + QPointF center = points.at(ix); + QSizeF size(item.w(), item.h()); + item.x(center.x() - size.width()/2); + item.y(center.y() - size.height()/2); + m_geometry->insert(item); + pos = item.frame() + 1; + ix++; + } + slotPositionChanged(-1, false); + emit parameterChanged(); +} void GeometryWidget::slotUpdateGeometry() @@ -556,6 +590,7 @@ void GeometryWidget::slotUpdateGeometry() geom->insert(item2); } } + if (m_geomPath) m_geomPath->setPoints(m_geometry); emit parameterChanged(); } diff --git a/src/geometrywidget.h b/src/geometrywidget.h index df26b9c4..0ae57f73 100644 --- a/src/geometrywidget.h +++ b/src/geometrywidget.h @@ -33,6 +33,7 @@ class MonitorScene; class KeyframeHelper; class TimecodeDisplay; class OnMonitorRectItem; +class OnMonitorPathItem; class QGraphicsRectItem; class DragValue; @@ -81,6 +82,7 @@ private: bool m_isEffect; MonitorScene *m_scene; OnMonitorRectItem *m_rect; + OnMonitorPathItem *m_geomPath; QGraphicsRectItem *m_previous; KeyframeHelper *m_timeline; /** Stores the different settings in the MLT geometry format. */ @@ -128,6 +130,8 @@ private slots: /** @brief Adds or deletes a keyframe depending on whether there is already a keyframe at the current position. */ void slotAddDeleteKeyframe(); + /** @brief Updates the Mlt::Geometry path object. */ + void slotUpdatePath(); /** @brief Updates the Mlt::Geometry object. */ void slotUpdateGeometry(); /** @brief Updates the spinBoxes according to the rect. */ diff --git a/src/kdenlive.desktop b/src/kdenlive.desktop index 6e41c668..b632a4b9 100644 --- a/src/kdenlive.desktop +++ b/src/kdenlive.desktop @@ -15,6 +15,7 @@ Name[hu]=Kdenlive Name[it]=Kdenlive Name[ja]=Kdenlive Name[km]=Kdenlive +Name[lt]=Kdenlive Name[nb]=Kdenlive Name[nds]=Kdenlive Name[nl]=Kdenlive @@ -43,6 +44,7 @@ GenericName[hu]=Videoszerkesztő GenericName[it]=Editor video GenericName[ja]=ビデオエディタ GenericName[km]=កម្មវិធី​កែសម្រួល​វីដេអូ +GenericName[lt]=Video redaktorius GenericName[nb]=Videoredigeringsprogram GenericName[nl]=Video-bewerker GenericName[pl]=Edytor wideo @@ -69,6 +71,7 @@ Comment[hu]=Nemlineáris videoszerkesztő a KDE-hez Comment[it]=Editor di video non lineare per KDE Comment[ja]=KDE 向けノンリニアビデオエディタ Comment[km]=កម្មវិធី​កែសម្រួល​វីដេអូ​មិន​លីនេអ៊ែរ​សម្រាប់ KDE +Comment[lt]=Nelinijinis veido redaktorius skirtas KDE Comment[nb]=Videoredigeringsprogram for KDE med dataklipping Comment[nl]=Niet-lineaire video-bewerker voor KDE Comment[pl]=Nieliniowy edytor wideo dla KDE diff --git a/src/kdenlive.notifyrc b/src/kdenlive.notifyrc index 5c4702ce..cec4a2fa 100644 --- a/src/kdenlive.notifyrc +++ b/src/kdenlive.notifyrc @@ -15,6 +15,7 @@ Comment[hu]=Kdenlive Comment[it]=Kdenlive Comment[ja]=Kdenlive Comment[km]=Kdenlive +Comment[lt]=Kdenlive Comment[nb]=Kdenlive Comment[nds]=Kdenlive Comment[nl]=Kdenlive @@ -44,6 +45,7 @@ Name[hu]=A renderelés befejeződött Name[it]=Esportazione terminata Name[ja]=レンダリングが完了しました Name[km]=បាន​បញ្ចប់​ការ​បង្ហាញ +Name[lt]=Atvaizdavimas baigtas Name[nb]=Opptegning avsluttet Name[nl]=Weergave uitwerken beëindigd Name[pl]=Ukończono renderowanie @@ -70,6 +72,7 @@ Comment[hu]=A renderelésnek vége Comment[it]=L'esportazione è terminata Comment[ja]=レンダリングが終了しました Comment[km]=ការ​បង្ហាញ​បាន​ចប់ +Comment[lt]=Atvaizdavimas baigtas Comment[nb]=Ferdig med opptegning Comment[nl]=Weergave uitwerken is gereed Comment[pl]=Ukończono zostało zakończone @@ -99,6 +102,7 @@ Name[hu]=A renderelés elkezdődött Name[it]=Esportazione avviata Name[ja]=レンダリングを開始しました Name[km]=ការ​បង្ហាញ​បាន​ចាប់ផ្ដើម +Name[lt]=Atvaizdavimas pradėtas Name[nb]=Opptegning påbegynt Name[nl]=Weergave uitwerken begonnen Name[pl]=Rozpoczęto renderowanie @@ -125,6 +129,7 @@ Comment[hu]=A renderelés elkezdődött Comment[it]=L'esportazione è stata avviata Comment[ja]=レンダリングを開始しました Comment[km]=ការ​បង្ហាញ​ត្រូវ​បាន​ចាប់ផ្ដើម +Comment[lt]=Atvaizdavimas buvo pradėtas Comment[nb]=Startet opptegning Comment[nl]=Weergave uitwerken is begonnen Comment[pl]=Renderowanie zostało rozpoczęte @@ -154,6 +159,7 @@ Name[hu]=Képkocka rögzítve Name[it]=Fotogramma acquisito Name[ja]=フレームをキャプチャしました Name[km]=បាន​ចាប់​យក​ស៊ុម +Name[lt]=Kadras išsaugotas Name[nb]=Stillbilde tatt Name[nl]=Frame opgenomen Name[pl]=Przechwycono klatkę @@ -180,6 +186,7 @@ Comment[hu]=Egy képkocka rögzítésre került a lemezre Comment[it]=È stato acquisito un fotogramma sul disco Comment[ja]=フレームをディスクにキャプチャしました Comment[km]=ស៊ុម​ត្រូវ​បាន​ចាប់​យក​ទៅកាន់​ថាស +Comment[lt]=Kadras buvo išsaugotas į diską Comment[nb]=Et stillbilde ble lagret Comment[nl]=Een frame is op schijf opgenomen Comment[pl]=Klatka została przechwycona na dysk @@ -210,6 +217,7 @@ Name[hu]=Kezdődhet a rögzítés Name[it]=Pronto per la registrazione Name[ja]=キャプチャ準備完了 Name[km]=រួចរាល់​ដើម្បី​ចាប់​យក +Name[lt]=Pasiruošęs išsaugoti Name[nb]=Klar til å ta stillbilde Name[nl]=Gereed om op te nemen Name[pl]=Gotowy do przechwycenia @@ -241,6 +249,7 @@ Name[hu]=Hiba Name[it]=Errore Name[ja]=エラー Name[km]=កំហុស +Name[lt]=Klaida Name[nb]=Feil Name[nds]=Fehler Name[nl]=Fout @@ -269,6 +278,7 @@ Comment[hu]=Hiba történt a Kdenlive-ban Comment[it]=Si è verificato un errore in Kdenlive Comment[ja]=Kdenlive 内でエラーが発生 Comment[km]=មាន​កំហុស​បាន​កើតឡើង​នៅ​ក្នុង Kdenlive +Comment[lt]=Įvyko Kdenlive klaida Comment[nb]=En feil oppsto i Kdenlive Comment[nl]=Er is een fout opgetreden in Kdenlive Comment[pl]=Wystąpił błąd w Kdenlive diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9eadf01b..7355b8d3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -234,7 +234,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & // Connect the project list connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint, bool)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool))); - connect(m_projectList, SIGNAL(raiseClipMonitor()), m_clipMonitor, SLOT(slotActivateMonitor())); + connect(m_projectList, SIGNAL(raiseClipMonitor(bool)), m_clipMonitor, SLOT(slotActivateMonitor(bool))); connect(m_projectList, SIGNAL(loadingIsOver()), this, SLOT(slotElapsedTime())); connect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus())); diff --git a/src/monitor.cpp b/src/monitor.cpp index 67b35e92..02a9d921 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -743,7 +743,7 @@ void Monitor::stop() void Monitor::start() { if (!isVisible() || !isActive()) return; - if (render) render->doRefresh();// start(); + if (render) render->startConsumer(); } void Monitor::refreshMonitor(bool visible) @@ -842,7 +842,6 @@ void Monitor::slotSetClipProducer(DocClipBase *clip, QPoint zone, bool forceUpda if (m_currentClip) m_currentClip->lastSeekPosition = render->seekFramePosition(); m_currentClip = clip; if (position == -1) position = clip->lastSeekPosition; - if (m_currentClip) slotActivateMonitor(); updateMarkers(clip); Mlt::Producer *prod = NULL; if (clip) prod = clip->getCloneProducer(); diff --git a/src/monitoreditwidget.cpp b/src/monitoreditwidget.cpp index d09a13c4..c756cf94 100644 --- a/src/monitoreditwidget.cpp +++ b/src/monitoreditwidget.cpp @@ -22,13 +22,18 @@ #include "monitorscene.h" #include "kdenlivesettings.h" +#include "onmonitoritems/onmonitorrectitem.h" +#include "onmonitoritems/onmonitorpathitem.h" + #include #include #include #include +#include #include + MonitorEditWidget::MonitorEditWidget(Render* renderer, QWidget* parent) : QWidget(parent) { @@ -41,7 +46,7 @@ MonitorEditWidget::MonitorEditWidget(Render* renderer, QWidget* parent) : m_scene = new MonitorScene(renderer); m_view = new QGraphicsView(m_scene, m_ui.frameVideo); m_view->setFrameShape(QFrame::NoFrame); - m_view->setRenderHints(QFlags()); + //m_view->setRenderHints(QFlags()); m_view->scale(((double) renderer->renderWidth()) / renderer->frameRenderWidth(), 1.0); m_view->setMouseTracking(true); m_scene->setUp(); diff --git a/src/monitoreditwidget.h b/src/monitoreditwidget.h index 4df207ab..34f3b07c 100644 --- a/src/monitoreditwidget.h +++ b/src/monitoreditwidget.h @@ -22,6 +22,7 @@ #include "ui_monitoreditwidget_ui.h" #include +#include class QIcon; class MonitorScene; @@ -31,7 +32,6 @@ class QToolButton; class QVBoxLayout; - class MonitorEditWidget : public QWidget { Q_OBJECT diff --git a/src/monitormanager.cpp b/src/monitormanager.cpp index 09c6c1e1..178ffc1d 100644 --- a/src/monitormanager.cpp +++ b/src/monitormanager.cpp @@ -74,12 +74,14 @@ AbstractMonitor* MonitorManager::monitor(Kdenlive::MONITORID monitorName) return monitor; } -bool MonitorManager::activateMonitor(Kdenlive::MONITORID name) +bool MonitorManager::activateMonitor(Kdenlive::MONITORID name, bool forceRefresh) { if (m_clipMonitor == NULL || m_projectMonitor == NULL) return false; - if (m_activeMonitor && m_activeMonitor->id() == name) + if (m_activeMonitor && m_activeMonitor->id() == name) { + if (forceRefresh) m_activeMonitor->start(); return false; + } m_activeMonitor = NULL; for (int i = 0; i < m_monitorsList.count(); i++) { if (m_monitorsList.at(i)->id() == name) { diff --git a/src/monitormanager.h b/src/monitormanager.h index 880b6d12..8ce0e3f3 100644 --- a/src/monitormanager.h +++ b/src/monitormanager.h @@ -50,7 +50,7 @@ public slots: /** @brief Activates a monitor. * @param name name of the monitor to activate */ - bool activateMonitor(Kdenlive::MONITORID); + bool activateMonitor(Kdenlive::MONITORID, bool forceRefresh = false); bool isActive(Kdenlive::MONITORID id) const; void slotPlay(); void slotPause(); diff --git a/src/onmonitoritems/CMakeLists.txt b/src/onmonitoritems/CMakeLists.txt index 58ece7c0..041a4d76 100644 --- a/src/onmonitoritems/CMakeLists.txt +++ b/src/onmonitoritems/CMakeLists.txt @@ -2,5 +2,6 @@ set(kdenlive_SRCS ${kdenlive_SRCS} onmonitoritems/onmonitorcornersitem.cpp onmonitoritems/onmonitorrectitem.cpp + onmonitoritems/onmonitorpathitem.cpp PARENT_SCOPE ) diff --git a/src/onmonitoritems/onmonitorpathitem.cpp b/src/onmonitoritems/onmonitorpathitem.cpp new file mode 100644 index 00000000..97e7ac99 --- /dev/null +++ b/src/onmonitoritems/onmonitorpathitem.cpp @@ -0,0 +1,203 @@ +/*************************************************************************** + * Copyright (C) 2010 by Till Theato (root@ttill.de) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "onmonitorpathitem.h" +#include "kdenlivesettings.h" + +#include +#include +#include +#include +#include +#include + +#include + +OnMonitorPathItem::OnMonitorPathItem(double dar, QGraphicsItem* parent) : + QGraphicsPathItem(parent), + m_dar(dar), + m_modified(false), + m_view(NULL), + m_activePoint(-1) +{ + setFlags(QGraphicsItem::ItemIsMovable); + + QPen framepen(Qt::SolidLine); + framepen.setColor(Qt::red); + setPen(framepen); + setBrush(Qt::transparent); + setAcceptHoverEvents(true); +} + +void OnMonitorPathItem::setPoints(Mlt::Geometry *geometry) +{ + m_points.clear(); + QRectF r; + int pos = 0; + Mlt::GeometryItem item; + while (!geometry->next_key(&item, pos)) { + r = QRectF(item.x(), item.y(), item.w(), item.h()); + m_points << r.center(); + pos = item.frame() + 1; + } + rebuildShape(); +} + +void OnMonitorPathItem::rebuildShape() { + if (m_activePoint > m_points.count()) m_activePoint = -1; + QPainterPath p; + QPainterPath shape; + + if (!m_points.isEmpty()) { + QRectF r(0, 0, 20, 20); + r.moveCenter(m_points.at(0)); + shape.addRect(r); + + p.moveTo(m_points.at(0)); + for (int i = 1; i < m_points.count(); i++) { + p.lineTo(m_points.at(i)); + r.moveCenter(m_points.at(i)); + shape.addRect(r); + } + } + m_shape = shape; + setPath(p); +} + +void OnMonitorPathItem::getMode(QPointF pos) +{ + double dist = 8; + if (getView()) { + dist /= m_view->matrix().m11(); + } + // Item mapped coordinates + for (int i = 0; i < m_points.count(); i++) { + if ((pos - m_points.at(i)).manhattanLength() <= dist) { + m_activePoint = i; + return; + } + } + m_activePoint = -1; +} + +void OnMonitorPathItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event) +{ + /*if (event->buttons() != Qt::NoButton && (event->screenPos() - m_screenClickPoint).manhattanLength() < QApplication::startDragDistance()) { + * event->accept(); + * return; + }*/ + + if (m_activePoint >= 0 && event->buttons() & Qt::LeftButton) { + QPointF mousePos = event->pos(); + m_points[m_activePoint] = mousePos; + rebuildShape(); + m_modified = true; + update(); + } + + if (m_modified) { + event->accept(); + if (KdenliveSettings::monitorscene_directupdate()) { + emit changed(); + m_modified = false; + } + } else { + event->ignore(); + } +} + +QList OnMonitorPathItem::points() const +{ + return m_points; +} + +void OnMonitorPathItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) +{ + if (m_modified) { + m_modified = false; + emit changed(); + } + event->accept(); +} + +QRectF OnMonitorPathItem::boundingRect () const +{ + return shape().boundingRect(); +} + +QPainterPath OnMonitorPathItem::shape () const +{ + return m_shape; +} + +void OnMonitorPathItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) +{ + if (m_activePoint != -1) { + m_activePoint = -1; + update(); + } + unsetCursor(); +} + +void OnMonitorPathItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) +{ + setCursor(QCursor(Qt::PointingHandCursor)); +} + +void OnMonitorPathItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event) +{ + int currentPoint = m_activePoint; + getMode(event->pos()); + if (currentPoint != m_activePoint) update(); + setCursor(QCursor(Qt::PointingHandCursor)); +} + +void OnMonitorPathItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + //Q_UNUSED(widget) + QGraphicsPathItem::paint(painter, option, widget); + + double w = 6; + double h = 6; + if (getView()) { + w /= m_view->matrix().m11(); + h /= m_view->matrix().m22(); + } + + QRectF handle(0, 0, w, h); + for (int i = 0; i < m_points.count(); i++) { + handle.moveCenter(m_points.at(i)); + painter->fillRect(handle, m_activePoint == i ? Qt::blue : pen().color()); + } +} + +bool OnMonitorPathItem::getView() +{ + if (m_view) + return true; + + if (scene() && scene()->views().count()) { + m_view = scene()->views()[0]; + return true; + } else { + return false; + } +} + +#include "onmonitorpathitem.moc" diff --git a/src/onmonitoritems/onmonitorpathitem.h b/src/onmonitoritems/onmonitorpathitem.h new file mode 100644 index 00000000..7665852a --- /dev/null +++ b/src/onmonitoritems/onmonitorpathitem.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2010 by Till Theato (root@ttill.de) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#ifndef ONMONITORPATHITEM_H +#define ONMONITORPATHITEM_H + + +#include +#include + +class QGraphicsView; + +namespace Mlt { +class Geometry; +} + + +class OnMonitorPathItem : public QObject, public QGraphicsPathItem +{ + Q_OBJECT +public: + OnMonitorPathItem(double dar, QGraphicsItem *parent = 0); + void setPoints(Mlt::Geometry *geometry); + void getMode(QPointF pos); + void rebuildShape(); + QList points() const; + virtual QPainterPath shape () const; + + /** @brief Reimplemented to draw the handles. */ + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0 ); + virtual QRectF boundingRect () const; + +protected: + //virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + +private: + double m_dar; + QList m_points; + QPointF m_lastPoint; + bool m_modified; + QGraphicsView *m_view; + int m_activePoint; + QPainterPath m_shape; + + /** @brief Tries to get the view of the scene. */ + bool getView(); + +signals: + void changed(); +}; + +#endif diff --git a/src/onmonitoritems/onmonitorrectitem.cpp b/src/onmonitoritems/onmonitorrectitem.cpp index acf5c1fa..37f918f3 100644 --- a/src/onmonitoritems/onmonitorrectitem.cpp +++ b/src/onmonitoritems/onmonitorrectitem.cpp @@ -56,10 +56,13 @@ rectActions OnMonitorRectItem::getMode(QPointF pos) right.lineTo(pol.at(2)); QPainterPath mouseArea; - qreal size = 8; - if (getView()) - size /= m_view->matrix().m11(); - mouseArea.addRect(pos.x() - size / 2, pos.y() - size / 2, size, size); + qreal xsize = 10; + qreal ysize = 10; + if (getView()) { + xsize /= m_view->matrix().m11(); + ysize /= m_view->matrix().m22(); + } + mouseArea.addRect(pos.x() - xsize / 2, pos.y() - ysize / 2, xsize, ysize); // Check for collisions between the mouse and the borders if (mouseArea.contains(pol.at(0))) @@ -262,15 +265,24 @@ void OnMonitorRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* painter->setPen(pen()); painter->drawRect(option->rect); - + const QRectF r = painter->worldTransform().mapRect(option->rect); + painter->setWorldMatrixEnabled(false); if (isEnabled()) { - double handleSize = 6 / painter->worldTransform().m11(); - double halfHandleSize = handleSize / 2; - painter->fillRect(-halfHandleSize, -halfHandleSize, handleSize, handleSize, QColor(Qt::yellow)); - painter->fillRect(option->rect.width() - halfHandleSize, -halfHandleSize, handleSize, handleSize, QColor(Qt::yellow)); - painter->fillRect(option->rect.width() - halfHandleSize, option->rect.height() - halfHandleSize, handleSize, handleSize, QColor(Qt::yellow)); - painter->fillRect(-halfHandleSize, option->rect.height() - halfHandleSize, handleSize, handleSize, QColor(Qt::yellow)); + QRectF handle(0, 0, 6, 6); + handle.moveTopLeft(r.topLeft()); + painter->fillRect(handle, QColor(Qt::yellow)); + handle.moveTopRight(r.topRight()); + painter->fillRect(handle, QColor(Qt::yellow)); + handle.moveBottomLeft(r.bottomLeft()); + painter->fillRect(handle, QColor(Qt::yellow)); + handle.moveBottomRight(r.bottomRight()); + painter->fillRect(handle, QColor(Qt::yellow)); } + + // Draw cross at center + QPointF center = r.center(); + painter->drawLine(center + QPointF(-6, 0), center + QPointF(6, 0)); + painter->drawLine(center + QPointF(0, 6), center + QPointF(0, -6)); } bool OnMonitorRectItem::getView() diff --git a/src/onmonitoritems/onmonitorrectitem.h b/src/onmonitoritems/onmonitorrectitem.h index ea7c2fe7..15e93941 100644 --- a/src/onmonitoritems/onmonitorrectitem.h +++ b/src/onmonitoritems/onmonitorrectitem.h @@ -29,6 +29,7 @@ class QGraphicsView; enum rectActions { Move, ResizeTopLeft, ResizeBottomLeft, ResizeTopRight, ResizeBottomRight, ResizeLeft, ResizeRight, ResizeTop, ResizeBottom, NoAction }; + class OnMonitorRectItem : public QObject, public QGraphicsRectItem { Q_OBJECT diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 022b1971..3cb9cad7 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -310,7 +310,7 @@ ProjectList::ProjectList(QWidget *parent) : connect(this, SIGNAL(processNextThumbnail()), this, SLOT(slotProcessNextThumbnail())); connect(m_listView, SIGNAL(projectModified()), this, SIGNAL(projectModified())); connect(m_listView, SIGNAL(itemSelectionChanged()), this, SLOT(slotClipSelected())); - connect(m_listView, SIGNAL(focusMonitor()), this, SIGNAL(raiseClipMonitor())); + connect(m_listView, SIGNAL(focusMonitor(bool)), this, SIGNAL(raiseClipMonitor(bool))); connect(m_listView, SIGNAL(pauseMonitor()), this, SIGNAL(pauseMonitor())); connect(m_listView, SIGNAL(requestMenu(const QPoint &, QTreeWidgetItem *)), this, SLOT(slotContextMenu(const QPoint &, QTreeWidgetItem *))); connect(m_listView, SIGNAL(addClip()), this, SIGNAL(pauseMonitor())); diff --git a/src/projectlist.h b/src/projectlist.h index ef290dad..49bccdf0 100644 --- a/src/projectlist.h +++ b/src/projectlist.h @@ -515,7 +515,7 @@ signals: void updateProfile(const QString &); void processNextThumbnail(); /** @brief Activate the clip monitor. */ - void raiseClipMonitor(); + void raiseClipMonitor(bool forceRefresh); /** @brief Set number of running jobs. */ void jobCount(int); void cancelRunningJob(const QString, stringMap); diff --git a/src/projectlistview.cpp b/src/projectlistview.cpp index 21e212c2..74f306bf 100644 --- a/src/projectlistview.cpp +++ b/src/projectlistview.cpp @@ -333,7 +333,7 @@ void ProjectListView::mouseReleaseEvent(QMouseEvent *event) { QTreeWidget::mouseReleaseEvent(event); QTreeWidgetItem *underMouse = itemAt(event->pos()); - if (underMouse) emit focusMonitor(); + if (underMouse) emit focusMonitor(true); } // virtual diff --git a/src/projectlistview.h b/src/projectlistview.h index 26e2c581..55a0e212 100644 --- a/src/projectlistview.h +++ b/src/projectlistview.h @@ -70,7 +70,7 @@ signals: void addClip(); void addClip(const QList , const QString &, const QString &); void showProperties(DocClipBase *); - void focusMonitor(); + void focusMonitor(bool forceRefresh); void pauseMonitor(); void addClipCut(const QString&, int, int); void projectModified(); diff --git a/src/renderer.cpp b/src/renderer.cpp index 20763707..d54c90e6 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1095,8 +1095,10 @@ int Render::setProducer(Mlt::Producer *producer, int position) if (producer) delete producer; return -1; } + bool monitorIsActive = false; m_mltConsumer->set("refresh", 0); if (!m_mltConsumer->is_stopped()) { + monitorIsActive = true; m_mltConsumer->stop(); } m_mltConsumer->purge(); @@ -1107,6 +1109,7 @@ int Render::setProducer(Mlt::Producer *producer, int position) if (!producer || !producer->is_valid()) { if (producer) delete producer; producer = m_blackClip->cut(0, 1); + producer->set("id", "black"); } if (!producer || !producer->is_valid()) { @@ -1159,8 +1162,15 @@ int Render::setProducer(Mlt::Producer *producer, int position) } m_mltProducer = producer; m_mltProducer->set_speed(0); + if (monitorIsActive) startConsumer(); emit durationChanged(m_mltProducer->get_playtime()); - if (m_mltConsumer->start() == -1) { + position = m_mltProducer->position(); + emit rendererPosition(position); + return 0; +} + +void Render::startConsumer() { + if (m_mltConsumer->is_stopped() && m_mltConsumer->start() == -1) { // ARGH CONSUMER BROKEN!!!! KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it.")); if (m_showFrameEvent) delete m_showFrameEvent; @@ -1169,18 +1179,14 @@ int Render::setProducer(Mlt::Producer *producer, int position) m_pauseEvent = NULL; delete m_mltConsumer; m_mltConsumer = NULL; - return -1; + return; } - - position = m_mltProducer->position(); m_mltConsumer->set("refresh", 1); // Make sure the first frame is displayed, otherwise if we change producer too fast // We can crash the avformat producer Mlt::Event *ev = m_mltConsumer->setup_wait_for("consumer-frame-show"); m_mltConsumer->wait_for(ev); delete ev; - emit rendererPosition(position); - return 0; } int Render::setSceneList(QDomDocument list, int position) @@ -1640,6 +1646,11 @@ void Render::seekToFrameDiff(int diff) else seek(requestedSeekPosition + diff); } +void Render::refreshIfActive() +{ + if (!m_mltConsumer->is_stopped() && m_mltProducer && m_mltProducer->get_speed() == 0) m_refreshTimer.start(); +} + void Render::doRefresh() { if (m_mltProducer && m_mltProducer->get_speed() == 0) m_refreshTimer.start(); @@ -2064,15 +2075,13 @@ bool Render::mltCutClip(int track, GenTime position) Mlt::Tractor *Render::lockService() { // we are going to replace some clips, purge consumer - QMutexLocker locker(&m_mutex); if (!m_mltProducer) return NULL; + QMutexLocker locker(&m_mutex); if (m_mltConsumer) { - if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop(); m_mltConsumer->purge(); } Mlt::Service service(m_mltProducer->parent().get_service()); if (service.type() != tractor_type) { - kWarning() << "// TRACTOR PROBLEM"; return NULL; } service.lock(); diff --git a/src/renderer.h b/src/renderer.h index f1ca980c..9813d627 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -199,6 +199,10 @@ Q_OBJECT public: double dar() const; /** @brief Returns sample aspect ratio. */ double sar() const; + /** @brief If monitor is active, refresh it. */ + void refreshIfActive(); + /** @brief Start the MLT monitor consumer. */ + void startConsumer(); /* * Playlist manipulation. diff --git a/src/slideshowclip.cpp b/src/slideshowclip.cpp index 457af2e0..8a0b5c97 100644 --- a/src/slideshowclip.cpp +++ b/src/slideshowclip.cpp @@ -200,7 +200,12 @@ void SlideshowClip::parseFolder() bool isMime = m_view.method_mime->isChecked(); QString path = isMime ? m_view.folder_url->url().path() : m_view.pattern_url->url().directory(); QDir dir(path); - if (path.isEmpty() || !dir.exists()) return; + if (path.isEmpty() || !dir.exists()) { + m_count = 0; + m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + m_view.label_info->setText(QString()); + return; + } KIcon unknownicon("unknown"); QStringList result; @@ -241,9 +246,8 @@ void SlideshowClip::parseFolder() item->setData(Qt::UserRole, dir.filePath(path)); m_view.icon_list->addItem(item); } - m_count = result.count(); - if (m_count == 0) m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); - else m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + m_count = m_view.icon_list->count(); + m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_count > 0); m_view.label_info->setText(i18np("1 image found", "%1 images found", m_count)); if (m_view.show_thumbs->isChecked()) slotGenerateThumbs(); m_view.icon_list->setCurrentRow(0); @@ -344,6 +348,9 @@ QString SlideshowClip::selectedPath(KUrl url, bool isMime, QString extension, QS int precision = fullSize - filter.size(); int firstFrame = firstFrameData.right(precision).toInt(); + // Workaround bug in MLT image sequence detection + if (firstFrame < 3) firstFrame = 0; + // Check how many files we have QDir dir(folder); QString path; @@ -358,7 +365,7 @@ QString SlideshowClip::selectedPath(KUrl url, bool isMime, QString extension, QS } } if (firstFrame > 0) extension = filter + '%' + QString::number(firstFrame).rightJustified(precision, '0', false) + 'd' + ext; - else extension = filter + '%' + QString::number(precision) + 'd' + ext; + else extension = filter + "%0" + QString::number(precision) + 'd' + ext; } kDebug() << "// FOUND " << (*list).count() << " items for " << url.path(); return folder + extension; diff --git a/thumbnailer/westleypreview.desktop b/thumbnailer/westleypreview.desktop index 39a904c4..043712ae 100644 --- a/thumbnailer/westleypreview.desktop +++ b/thumbnailer/westleypreview.desktop @@ -15,6 +15,7 @@ Name[hu]=MLT lejátszólista Name[it]=Scaletta MLT Name[ja]=MLT プレイリスト Name[km]=បញ្ជី​ចាក់ MLT +Name[lt]=MTL grojaraštis Name[nb]=MLT-spilleliste Name[nl]=MLT-afspeellijst Name[pl]=Lista odtwarzania MLT