#include <KCursor>
#include <KMessageBox>
#include <KIO/NetAccess>
+#include <KFileDialog>
#include <QMouseEvent>
#include <QStylePainter>
// If mouse is at a border of the view, scroll
if (m_moveOpMode != SEEK) return;
if (mapFromScene(m_cursorPos, 0).x() < 3) {
+ if (horizontalScrollBar()->value() == 0) return;
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 2);
QTimer::singleShot(200, this, SLOT(slotCheckPositionScrolling()));
seekCursorPos(mapToScene(QPoint(-2, 0)).x());
else if (dragGroup && dragGroup->isSelected())
itemSelected = true;
- if (event->modifiers() == Qt::ControlModifier || itemSelected == false) {
+ if ((event->modifiers() == Qt::ControlModifier) || itemSelected == false) {
if (event->modifiers() != Qt::ControlModifier) {
resetSelectionGroup(false);
m_scene->clearSelection();
// A refresh seems necessary otherwise in zoomed mode, some clips disappear
viewport()->update();
- } else resetSelectionGroup();
+ } else {
+ resetSelectionGroup();
+ }
dragGroup = NULL;
if (m_dragItem->parentItem() && m_dragItem->parentItem()->type() == GROUPWIDGET) {
dragGroup = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
}
bool selected = !m_dragItem->isSelected();
- if (dragGroup)
+ /*if (dragGroup)
dragGroup->setSelected(selected);
- else
+ else*/
m_dragItem->setSelected(selected);
-
+ if (selected == false) {
+ m_dragItem = NULL;
+ }
groupSelectedItems();
- ClipItem *clip = static_cast <ClipItem *>(m_dragItem);
- updateClipTypeActions(dragGroup == NULL ? clip : NULL);
- m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
+ if (m_dragItem) {
+ ClipItem *clip = static_cast <ClipItem *>(m_dragItem);
+ updateClipTypeActions(dragGroup == NULL ? clip : NULL);
+ m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
+ }
+ else updateClipTypeActions(NULL);
}
if (collisionClip != NULL || m_dragItem == NULL) {
}
// If clicked item is selected, allow move
- if (event->modifiers() != Qt::ControlModifier && m_operationMode == NONE) QGraphicsView::mousePressEvent(event);
+ //if (!(event->modifiers() | Qt::ControlModifier) && m_operationMode == NONE)
+ QGraphicsView::mousePressEvent(event);
- m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps())), (int)(event->pos().y() - m_dragItem->pos().y()));
+ 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()));
if (m_selectionGroup && m_dragItem->parentItem() == m_selectionGroup) {
// all other modes break the selection, so the user probably wants to move it
m_operationMode = MOVE;
}
else m_operationMode = m_dragItem->operationMode(mapToScene(event->pos()));
}
+ } else m_operationMode = NONE;
m_controlModifier = (event->modifiers() == Qt::ControlModifier);
// Update snap points
pasteInfo.startPos = GenTime(m_cursorPos, m_document->fps());
pasteInfo.endPos = pasteInfo.startPos + info.endPos;
pasteInfo.track = selectedTrack();
- if (!canBePastedTo(pasteInfo, AVWIDGET)) {
+ bool ok = canBePastedTo(pasteInfo, AVWIDGET);
+ if (!ok) {
+ // Cannot be inserted at cursor pos, insert at end of track
+ int duration = m_document->renderer()->mltTrackDuration(m_document->tracksCount() - pasteInfo.track) + 1;
+ pasteInfo.startPos = GenTime(duration, m_document->fps());
+ pasteInfo.endPos = pasteInfo.startPos + info.endPos;
+ ok = canBePastedTo(pasteInfo, AVWIDGET);
+ }
+ if (!ok) {
emit displayMessage(i18n("Cannot insert clip in timeline"), ErrorMessage);
return;
}
// Check if clips can be inserted at that position
for (int i = 0; i < ids.size(); ++i) {
- DocClipBase *clip = m_document->getBaseClip(ids.at(i));
+ QString clipData = ids.at(i);
+ DocClipBase *clip = m_document->getBaseClip(clipData.section('/', 0, 0));
if (clip == NULL) {
kDebug() << " WARNING))))))))) CLIP NOT FOUND : " << ids.at(i);
return false;
}
ItemInfo info;
info.startPos = start;
- info.cropDuration = clip->duration();
- info.endPos = info.startPos + info.cropDuration;
+ if (clipData.contains('/')) {
+ // this is a clip zone, set in / out
+ int in = clipData.section('/', 1, 1).toInt();
+ int out = clipData.section('/', 2, 2).toInt();
+ info.cropStart = GenTime(in, m_document->fps());
+ info.cropDuration = GenTime(out - in, m_document->fps());
+ }
+ else {
+ info.cropDuration = clip->duration();
+ }
+ info.endPos = info.startPos + info.cropDuration;
info.track = track;
infoList.append(info);
- start += clip->duration();
+ start += info.cropDuration;
}
if (!canBePastedTo(infoList, AVWIDGET)) {
return true;
m_selectionGroup = new AbstractGroupItem(m_document->fps());
start = GenTime();
for (int i = 0; i < ids.size(); ++i) {
- DocClipBase *clip = m_document->getBaseClip(ids.at(i));
+ QString clipData = ids.at(i);
+ DocClipBase *clip = m_document->getBaseClip(clipData.section('/', 0, 0));
ItemInfo info;
info.startPos = start;
- info.cropDuration = clip->duration();
- info.endPos = info.startPos + info.cropDuration;
+ if (clipData.contains('/')) {
+ // this is a clip zone, set in / out
+ int in = clipData.section('/', 1, 1).toInt();
+ int out = clipData.section('/', 2, 2).toInt();
+ info.cropStart = GenTime(in, m_document->fps());
+ info.cropDuration = GenTime(out - in, m_document->fps());
+ }
+ else {
+ info.cropDuration = clip->duration();
+ }
+ info.endPos = info.startPos + info.cropDuration;
info.track = 0;
start += info.cropDuration;
offsetList.append(start);
clearSelection(false);
clip->setSelected(true);
m_dragItem = clip;
- emit clipItemSelected(clip);
}
+ emit clipItemSelected(clip);
break;
}
}
}
+ else {
+ for (int i = 0; i < itemList.count(); i++) {
+ if (itemList.at(i)->type() == AVWIDGET) {
+ ClipItem *clip = static_cast<ClipItem *>(itemList.at(i));
+ if (clip->isMainSelectedClip()) {
+ emit clipItemSelected(clip);
+ break;
+ }
+ }
+ }
+ }
} else delete effectCommand;
}
}
-void CustomTrackView::setCursorPos(int pos, bool seek)
+void CustomTrackView::setCursorPos(int pos)
{
if (pos != m_cursorPos) {
emit cursorMoved((int)(m_cursorPos), (int)(pos));
void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
{
if (m_moveOpMode == SEEK) m_moveOpMode = NONE;
- QGraphicsView::mouseReleaseEvent(event);
+ if (!m_controlModifier) QGraphicsView::mouseReleaseEvent(event);
setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
#if QT_VERSION >= 0x040600
if (m_dragItem) m_dragItem->setGraphicsEffect(NULL);
}
}
-void CustomTrackView::slotAddClipMarker(const QString &id, GenTime t, QString c)
+void CustomTrackView::slotAddClipMarker(const QString &id, GenTime t, QString c, QUndoCommand *groupCommand)
{
QString oldcomment = m_document->clipManager()->getClipById(id)->markerComment(t);
- AddMarkerCommand *command = new AddMarkerCommand(this, oldcomment, c, id, t);
- m_commandStack->push(command);
+ AddMarkerCommand *command = new AddMarkerCommand(this, oldcomment, c, id, t, groupCommand);
+ if (!groupCommand) m_commandStack->push(command);
}
void CustomTrackView::slotDeleteClipMarker(const QString &comment, const QString &id, const GenTime &position)
m_commandStack->push(deleteMarkers);
}
+void CustomTrackView::slotSaveClipMarkers(const QString &id)
+{
+ DocClipBase *base = m_document->clipManager()->getClipById(id);
+ QList < CommentedTime > markers = base->commentedSnapMarkers();
+ QString data;
+ for (int i = 0; i < markers.count(); i++) {
+ data.append(QString::number(markers.at(i).time().seconds()));
+ data.append("\t");
+ data.append(QString::number(markers.at(i).time().seconds()));
+ data.append("\t");
+ data.append(markers.at(i).comment());
+ data.append("\n");
+ }
+ if (!data.isEmpty()) {
+ QString url = KFileDialog::getSaveFileName(KUrl("kfiledialog:///projectfolder"), "text/plain", this, i18n("Save markers"));
+ if (url.isEmpty()) return;
+ QFile file(url);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ emit displayMessage(i18n("Cannot open file %1", url), ErrorMessage);
+ return;
+ }
+ file.write(data.toUtf8());
+ file.close();
+ }
+}
+
+void CustomTrackView::slotLoadClipMarkers(const QString &id)
+{
+ KUrl url = KFileDialog::getOpenUrl(KUrl("kfiledialog:///projectfolder"), "text/plain", this, i18n("Load marker file"));
+ if (url.isEmpty()) return;
+ QFile file(url.path());
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ emit displayMessage(i18n("Cannot open file %1", url.fileName()), ErrorMessage);
+ return;
+ }
+ QString data = QString::fromUtf8(file.readAll());
+ file.close();
+ QStringList lines = data.split("\n", QString::SkipEmptyParts);
+ QStringList values;
+ bool ok;
+ QUndoCommand *command = new QUndoCommand();
+ command->setText("Load markers");
+ QString markerText;
+ foreach(QString line, lines) {
+ markerText.clear();
+ values = line.split("\t", QString::SkipEmptyParts);
+ double time1 = values.at(0).toDouble(&ok);
+ double time2 = -1;
+ if (!ok) continue;
+ if (values.count() >1) {
+ time2 = values.at(1).toDouble(&ok);
+ if (values.count() == 2) {
+ // Check if second value is a number or text
+ if (!ok) {
+ time2 = -1;
+ markerText = values.at(1);
+ }
+ else markerText = i18n("Marker");
+ }
+ else {
+ // We assume 3 values per line: in out name
+ if (!ok) {
+ // 2nd value is not a number, drop
+ }
+ else {
+ markerText = values.at(2);
+ }
+ }
+ }
+ if (!markerText.isEmpty()) {
+ // Marker found, add it
+ slotAddClipMarker(id, GenTime(time1), markerText, command);
+ if (time2 > 0 && time2 != time1) slotAddClipMarker(id, GenTime(time2), markerText, command);
+ }
+ }
+ if (command->childCount() > 0) m_commandStack->push(command);
+ else delete command;
+}
+
void CustomTrackView::addMarker(const QString &id, const GenTime &pos, const QString &comment)
{
DocClipBase *base = m_document->clipManager()->getClipById(id);
{
painter->setClipRect(rect);
QPen pen1 = painter->pen();
- pen1.setColor(palette().dark().color());
+ QColor lineColor = palette().dark().color();
+ lineColor.setAlpha(100);
+ pen1.setColor(lineColor);
painter->setPen(pen1);
double min = rect.left();
double max = rect.right();
QList<QGraphicsItem *> collisions = scene()->items(rect, Qt::IntersectsItemBoundingRect);
for (int i = 0; i < collisions.count(); i++) {
if (collisions.at(i)->type() == AVWIDGET) {
- return static_cast < ClipItem *>(collisions.at(i));
+ ClipItem *clip = static_cast < ClipItem *>(collisions.at(i));
+ if (!clip->isItemLocked()) return clip;
}
}
return NULL;