X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmonitor.cpp;h=cd2713d8dfb1ed447d5bbb24b6c32a8728cfde62;hb=fd8e8d7b0339661cf6c96f678e88fa0bcf8b1ced;hp=9ad543b5f2a1a67ff2dabfb96678d352e1cd00fa;hpb=70d0af35fb70afdc544faf6eb5d49a7945c438b5;p=kdenlive diff --git a/src/monitor.cpp b/src/monitor.cpp index 9ad543b5..cd2713d8 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -18,27 +18,30 @@ ***************************************************************************/ +#include "monitor.h" +#include "renderer.h" +#include "monitormanager.h" +#include "smallruler.h" +#include "docclipbase.h" +#include "kdenlivesettings.h" + +#include +#include +#include +#include +#include + #include #include #include #include #include #include +#include -#include -#include -#include -#include - -#include "gentime.h" -#include "monitor.h" -#include "renderer.h" -#include "monitormanager.h" -#include "smallruler.h" -#include "docclipbase.h" Monitor::Monitor(QString name, MonitorManager *manager, QWidget *parent) - : QWidget(parent), render(NULL), m_monitorManager(manager), m_name(name), m_isActive(false), m_currentClip(NULL), m_dragStarted(false) { + : QWidget(parent), render(NULL), m_monitorManager(manager), m_name(name), m_isActive(false), m_currentClip(NULL), m_dragStarted(false), m_overlay(NULL) { ui.setupUi(this); m_scale = 1; m_ruler = new SmallRuler(); @@ -55,8 +58,8 @@ Monitor::Monitor(QString name, MonitorManager *manager, QWidget *parent) m_playIcon = KIcon("media-playback-start"); m_pauseIcon = KIcon("media-playback-pause"); - QAction *zoneStart = toolbar->addAction(KIcon("kdenlive-zone-start"), i18n("Set zone start"), this, SLOT(slotSetZoneStart())); - QAction *zoneEnd = toolbar->addAction(KIcon("kdenlive-zone-end"), i18n("Set zone end"), this, SLOT(slotSetZoneEnd())); + toolbar->addAction(KIcon("kdenlive-zone-start"), i18n("Set zone start"), this, SLOT(slotSetZoneStart())); + toolbar->addAction(KIcon("kdenlive-zone-end"), i18n("Set zone end"), this, SLOT(slotSetZoneEnd())); toolbar->addAction(KIcon("media-seek-backward"), i18n("Rewind"), this, SLOT(slotRewind())); toolbar->addAction(KIcon("media-skip-backward"), i18n("Rewind 1 frame"), this, SLOT(slotRewindOneFrame())); @@ -66,8 +69,6 @@ Monitor::Monitor(QString name, MonitorManager *manager, QWidget *parent) m_playAction = m_playMenu->addAction(m_playIcon, i18n("Play")); m_playAction->setCheckable(true); connect(m_playAction, SIGNAL(triggered()), this, SLOT(slotPlay())); - m_playMenu->addAction(m_playIcon, i18n("Play Section"), this, SLOT(slotPlayZone())); - m_playMenu->addAction(m_playIcon, i18n("Loop Section"), this, SLOT(slotLoopZone())); playButton->setMenu(m_playMenu); playButton->setPopupMode(QToolButton::MenuButtonPopup); @@ -109,10 +110,7 @@ Monitor::Monitor(QString name, MonitorManager *manager, QWidget *parent) render = new Render(m_name, (int) m_monitorRefresh->winId(), -1, this); m_monitorRefresh->setRenderer(render); - - connect(m_ruler, SIGNAL(seekRenderer(int)), this, SLOT(slotSeek(int))); - connect(m_ruler, SIGNAL(zoneChanged(QPoint)), this, SIGNAL(zoneUpdated(QPoint))); connect(render, SIGNAL(durationChanged(int)), this, SLOT(adjustRulerSize(int))); connect(render, SIGNAL(rendererPosition(int)), this, SLOT(seekCursor(int))); connect(render, SIGNAL(rendererStopped(int)), this, SLOT(rendererStopped(int))); @@ -126,19 +124,33 @@ Monitor::Monitor(QString name, MonitorManager *manager, QWidget *parent) if (name != "clip") { connect(render, SIGNAL(rendererPosition(int)), this, SIGNAL(renderPosition(int))); connect(render, SIGNAL(durationChanged(int)), this, SIGNAL(durationChanged(int))); + connect(m_ruler, SIGNAL(zoneChanged(QPoint)), this, SIGNAL(zoneUpdated(QPoint))); + } else { + connect(m_ruler, SIGNAL(zoneChanged(QPoint)), this, SLOT(setClipZone(QPoint))); } m_monitorRefresh->show(); kDebug() << "/////// BUILDING MONITOR, ID: " << ui.video_frame->winId(); } +Monitor::~Monitor() { + delete m_ruler; + delete m_timePos; + if (m_overlay) delete m_overlay; + delete m_monitorRefresh; +} + QString Monitor::name() const { return m_name; } -void Monitor::setupMenu(QMenu *goMenu) { +void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMenu *markerMenu) { m_contextMenu = new QMenu(this); m_contextMenu->addMenu(m_playMenu); m_contextMenu->addMenu(goMenu); + if (markerMenu) m_contextMenu->addMenu(markerMenu); + + m_playMenu->addAction(playZone); + m_playMenu->addAction(loopZone); //TODO: add save zone to timeline monitor when fixed if (m_name == "clip") m_contextMenu->addAction(KIcon("document-save"), i18n("Save zone"), this, SLOT(slotSaveZone())); @@ -147,7 +159,7 @@ void Monitor::setupMenu(QMenu *goMenu) { m_contextMenu->addAction(extractFrame); if (m_name != "clip") { - QAction *splitView = m_contextMenu->addAction(KIcon("document-new"), i18n("Split view"), render, SLOT(slotSplitView(bool))); + QAction *splitView = m_contextMenu->addAction(KIcon("view-split-left-right"), i18n("Split view"), render, SLOT(slotSplitView(bool))); splitView->setCheckable(true); m_configMenu->addAction(splitView); } else { @@ -155,6 +167,11 @@ void Monitor::setupMenu(QMenu *goMenu) { m_configMenu->addAction(setThumbFrame); } + QAction *showTips = m_contextMenu->addAction(KIcon("help-hint"), i18n("Monitor overlay infos"), this, SLOT(slotSwitchMonitorInfo(bool))); + showTips->setCheckable(true); + slotSwitchMonitorInfo(KdenliveSettings::displayMonitorInfo()); + m_configMenu->addAction(showTips); + } void Monitor::slotSetSizeOneToOne() { @@ -199,18 +216,68 @@ void Monitor::resetSize() { ui.video_frame->setMinimumSize(0, 0); } +DocClipBase *Monitor::activeClip() { + return m_currentClip; +} + +void Monitor::slotSeekToPreviousSnap() { + if (m_currentClip) slotSeek(getSnapForPos(true).frames(m_monitorManager->timecode().fps())); +} + +void Monitor::slotSeekToNextSnap() { + if (m_currentClip) slotSeek(getSnapForPos(false).frames(m_monitorManager->timecode().fps())); +} + +GenTime Monitor::position() { + return GenTime(m_position, m_monitorManager->timecode().fps()); +} + +GenTime Monitor::getSnapForPos(bool previous) { + QList snaps; + QList < GenTime > markers = m_currentClip->snapMarkers(); + for (int i = 0; i < markers.size(); ++i) { + GenTime t = markers.at(i); + snaps.append(t); + } + QPoint zone = m_ruler->zone(); + snaps.append(GenTime(zone.x(), m_monitorManager->timecode().fps())); + snaps.append(GenTime(zone.y(), m_monitorManager->timecode().fps())); + snaps.append(GenTime()); + snaps.append(m_currentClip->duration()); + qSort(snaps); + + const GenTime pos(m_position, m_monitorManager->timecode().fps()); + for (int i = 0; i < snaps.size(); ++i) { + if (previous && snaps.at(i) >= pos) { + if (i == 0) i = 1; + return snaps.at(i - 1); + } else if (!previous && snaps.at(i) > pos) { + return snaps.at(i); + } + } + return GenTime(); +} + + + void Monitor::slotZoneMoved(int start, int end) { m_ruler->setZone(start, end); + checkOverlay(); + setClipZone(m_ruler->zone()); } void Monitor::slotSetZoneStart() { m_ruler->setZone(m_position, -1); emit zoneUpdated(m_ruler->zone()); + checkOverlay(); + setClipZone(m_ruler->zone()); } void Monitor::slotSetZoneEnd() { m_ruler->setZone(-1, m_position); emit zoneUpdated(m_ruler->zone()); + checkOverlay(); + setClipZone(m_ruler->zone()); } // virtual @@ -236,7 +303,7 @@ void Monitor::mouseReleaseEvent(QMouseEvent * event) { // virtual void Monitor::mouseMoveEvent(QMouseEvent *event) { - kDebug() << "// DRAG STARTED, MOUSE MOVED: "; + // kDebug() << "// DRAG STARTED, MOUSE MOVED: "; if (!m_dragStarted || m_currentClip == NULL) return; if ((event->pos() - m_DragStartPosition).manhattanLength() @@ -323,7 +390,10 @@ void Monitor::slotSetThumbFrame() { void Monitor::slotExtractCurrentFrame() { QPixmap frame = render->extractFrame(m_position); QString outputFile = KFileDialog::getSaveFileName(KUrl(), "image/png"); - if (!outputFile.isEmpty()) frame.save(outputFile); + if (!outputFile.isEmpty()) { + if (QFile::exists(outputFile) && KMessageBox::questionYesNo(this, i18n("File already exists.\nDo you want to overwrite it ?")) == KMessageBox::No) return; + frame.save(outputFile); + } } bool Monitor::isActive() const { @@ -331,7 +401,7 @@ bool Monitor::isActive() const { } void Monitor::activateMonitor() { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + if (!m_isActive) m_monitorManager->switchMonitors(); //m_monitorManager->activateMonitor(m_name); } void Monitor::slotSeek() { @@ -340,16 +410,31 @@ void Monitor::slotSeek() { } void Monitor::slotSeek(int pos) { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); if (render == NULL) return; - render->seekToFrame(pos); m_position = pos; + checkOverlay(); + render->seekToFrame(pos); emit renderPosition(m_position); m_timePos->setText(m_monitorManager->timecode().getTimecodeFromFrames(m_position)); } +void Monitor::checkOverlay() { + if (m_overlay == NULL) return; + QPoint zone = m_ruler->zone(); + if (m_position == zone.x()) m_overlay->setOverlayText(i18n("In Point")); + else if (m_position == zone.y()) m_overlay->setOverlayText(i18n("Out Point")); + else { + if (m_currentClip) { + QString markerComment = m_currentClip->markerComment(GenTime(m_position, m_monitorManager->timecode().fps())); + if (markerComment.isEmpty()) m_overlay->setHidden(true); + else m_overlay->setOverlayText(markerComment, false); + } else m_overlay->setHidden(true); + } +} + void Monitor::slotStart() { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); render->play(0); m_position = 0; render->seekToFrame(m_position); @@ -358,7 +443,7 @@ void Monitor::slotStart() { } void Monitor::slotEnd() { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); render->play(0); m_position = render->getLength(); render->seekToFrame(m_position); @@ -367,7 +452,7 @@ void Monitor::slotEnd() { } void Monitor::slotZoneStart() { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); render->play(0); m_position = m_ruler->zone().x(); render->seekToFrame(m_position); @@ -376,7 +461,7 @@ void Monitor::slotZoneStart() { } void Monitor::slotZoneEnd() { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); render->play(0); m_position = m_ruler->zone().y(); render->seekToFrame(m_position); @@ -385,7 +470,7 @@ void Monitor::slotZoneEnd() { } void Monitor::slotRewind(double speed) { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); if (speed == 0) { double currentspeed = render->playSpeed(); if (currentspeed >= 0) render->play(-2); @@ -396,7 +481,7 @@ void Monitor::slotRewind(double speed) { } void Monitor::slotForward(double speed) { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); if (speed == 0) { double currentspeed = render->playSpeed(); if (currentspeed <= 1) render->play(2); @@ -406,28 +491,33 @@ void Monitor::slotForward(double speed) { m_playAction->setIcon(m_pauseIcon); } -void Monitor::slotRewindOneFrame() { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); +void Monitor::slotRewindOneFrame(int diff) { + activateMonitor(); render->play(0); if (m_position < 1) return; - m_position--; + m_position -= diff; + m_position = qMax(m_position, 0); render->seekToFrame(m_position); emit renderPosition(m_position); m_timePos->setText(m_monitorManager->timecode().getTimecodeFromFrames(m_position)); + checkOverlay(); } -void Monitor::slotForwardOneFrame() { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); +void Monitor::slotForwardOneFrame(int diff) { + activateMonitor(); render->play(0); if (m_position >= m_length) return; - m_position++; + m_position += diff; + m_position = qMin(m_position, m_length); render->seekToFrame(m_position); emit renderPosition(m_position); m_timePos->setText(m_monitorManager->timecode().getTimecodeFromFrames(m_position)); + checkOverlay(); } void Monitor::seekCursor(int pos) { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); + checkOverlay(); m_position = pos; m_timePos->setText(m_monitorManager->timecode().getTimecodeFromFrames(pos)); m_ruler->slotNewValue(pos); @@ -437,6 +527,7 @@ void Monitor::rendererStopped(int pos) { //int rulerPos = (int)(pos * m_scale); m_ruler->slotNewValue(pos); m_position = pos; + //checkOverlay(); m_timePos->setText(m_monitorManager->timecode().getTimecodeFromFrames(pos)); m_playAction->setChecked(false); m_playAction->setIcon(m_playIcon); @@ -457,6 +548,10 @@ void Monitor::initMonitor() { void Monitor::adjustRulerSize(int length) { if (length > 0) m_length = length; m_ruler->adjustScale(m_length); + if (m_currentClip != NULL) { + QPoint zone = m_currentClip->zone(); + m_ruler->setZone(zone.x(), zone.y()); + } } void Monitor::stop() { @@ -473,14 +568,14 @@ void Monitor::start() { void Monitor::refreshMonitor(bool visible) { if (visible && render) { - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); render->doRefresh(); //askForRefresh(); } } void Monitor::pause() { if (render == NULL) return; - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); render->pause(); //m_playAction->setChecked(true); //m_playAction->setIcon(m_pauseIcon); @@ -488,15 +583,20 @@ void Monitor::pause() { void Monitor::slotPlay() { if (render == NULL) return; - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); + if (render->playSpeed() == 0) { + m_playAction->setChecked(true); + m_playAction->setIcon(m_pauseIcon); + } else { + m_playAction->setChecked(false); + m_playAction->setIcon(m_playIcon); + } render->switchPlay(); - m_playAction->setChecked(true); - m_playAction->setIcon(m_pauseIcon); } void Monitor::slotPlayZone() { if (render == NULL) return; - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); QPoint p = m_ruler->zone(); render->playZone(GenTime(p.x(), render->fps()), GenTime(p.y(), render->fps())); m_playAction->setChecked(true); @@ -505,7 +605,7 @@ void Monitor::slotPlayZone() { void Monitor::slotLoopZone() { if (render == NULL) return; - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); QPoint p = m_ruler->zone(); render->loopZone(GenTime(p.x(), render->fps()), GenTime(p.y(), render->fps())); m_playAction->setChecked(true); @@ -514,21 +614,22 @@ void Monitor::slotLoopZone() { void Monitor::slotSetXml(DocClipBase *clip, const int position) { if (render == NULL) return; - if (!m_isActive) m_monitorManager->activateMonitor(m_name); - if (!clip) return; - if (clip != m_currentClip && clip->producer() != NULL) { + activateMonitor(); + if (!clip && m_currentClip != NULL) { + m_currentClip = NULL; + render->setProducer(NULL, -1); + return; + } + if (clip != m_currentClip) { m_currentClip = clip; render->setProducer(clip->producer(), position); - //m_ruler->slotNewValue(0); - //adjustRulerSize(clip->producer()->get_playtime()); - //m_timePos->setText("00:00:00:00"); m_position = position; } else if (position != -1) render->seek(GenTime(position, render->fps())); } void Monitor::slotOpenFile(const QString &file) { if (render == NULL) return; - if (!m_isActive) m_monitorManager->activateMonitor(m_name); + activateMonitor(); QDomDocument doc; QDomElement westley = doc.createElement("westley"); doc.appendChild(westley); @@ -557,6 +658,30 @@ void Monitor::saveSceneList(QString path, QDomElement info) { render->saveSceneList(path, info); } +const QString Monitor::sceneList() { + if (render == NULL) return QString(); + return render->sceneList(); +} + + +void Monitor::setClipZone(QPoint pos) { + if (m_currentClip == NULL) return; + m_currentClip->setZone(pos); +} + +void Monitor::slotSwitchMonitorInfo(bool show) { + KdenliveSettings::setDisplayMonitorInfo(show); + if (show) { + if (m_overlay) return; + m_overlay = new Overlay(m_monitorRefresh); + m_overlay->raise(); + m_overlay->setHidden(true); + } else { + delete m_overlay; + m_overlay = NULL; + } +} + MonitorRefresh::MonitorRefresh(QWidget* parent): QWidget(parent), m_renderer(NULL) { setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_OpaquePaintEvent); //setAttribute(Qt::WA_NoSystemBackground); @@ -570,4 +695,32 @@ void MonitorRefresh::paintEvent(QPaintEvent * event) { if (m_renderer) m_renderer->doRefresh(); } + +Overlay::Overlay(QWidget* parent): QLabel(parent) { + setAttribute(Qt::WA_TransparentForMouseEvents); + setAttribute(Qt::WA_OpaquePaintEvent); + //setAttribute(Qt::WA_NoSystemBackground); + setAutoFillBackground(false); +} + +void Overlay::paintEvent(QPaintEvent * event) { + QPainter painter(this); + QColor col; + painter.setPen(Qt::white); + if (m_isZone) col = QColor(200, 0, 0); + else col = QColor(0, 0, 200); + painter.fillRect(rect(), col); + painter.drawText(rect(), Qt::AlignCenter, text()); +} + + + +void Overlay::setOverlayText(const QString &text, bool isZone) { + setHidden(true); + m_isZone = isZone; + setText(' ' + text + ' '); + setHidden(false); + update(); +} + #include "monitor.moc"