monitormanager.cpp 21.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/***************************************************************************
 *   Copyright (C) 2007 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          *
 ***************************************************************************/

Vincent Pinon's avatar
Vincent Pinon committed
20
#include "monitormanager.h"
21
#include "core.h"
Nicolas Carion's avatar
Nicolas Carion committed
22
#include "doc/kdenlivedoc.h"
23
#include "kdenlivesettings.h"
24
#include "mainwindow.h"
25
#include "mltcontroller/bincontroller.h"
Nicolas Carion's avatar
Nicolas Carion committed
26 27
#include "renderer.h"
#include "utils/KoIconUtils.h"
28

29
#include <mlt++/Mlt.h>
30

31
#include "klocalizedstring.h"
32 33
#include <KDualAction>

Laurent Montel's avatar
Laurent Montel committed
34
#include "kdenlive_debug.h"
Nicolas Carion's avatar
Nicolas Carion committed
35
#include <QObject>
36

Nicolas Carion's avatar
Nicolas Carion committed
37
MonitorManager::MonitorManager(QObject *parent)
38 39 40 41 42
    : QObject(parent)
    , m_document(nullptr)
    , m_clipMonitor(nullptr)
    , m_projectMonitor(nullptr)
    , m_activeMonitor(nullptr)
43
{
44
    setupActions();
45 46
}

Laurent Montel's avatar
Laurent Montel committed
47
Timecode MonitorManager::timecode() const
48
{
49
    return m_timecode;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
50 51
}

52 53 54 55 56
void MonitorManager::setDocument(KdenliveDoc *doc)
{
    m_document = doc;
}

Laurent Montel's avatar
Laurent Montel committed
57
QAction *MonitorManager::getAction(const QString &name)
58
{
59
    return pCore->window()->action(name.toUtf8().constData());
60 61
}

62
void MonitorManager::initMonitors(Monitor *clipMonitor, Monitor *projectMonitor)
63
{
64 65
    m_clipMonitor = clipMonitor;
    m_projectMonitor = projectMonitor;
66 67 68 69 70 71
    m_monitorsList.append(clipMonitor);
    m_monitorsList.append(projectMonitor);
}

void MonitorManager::appendMonitor(AbstractMonitor *monitor)
{
Laurent Montel's avatar
Laurent Montel committed
72 73 74
    if (!m_monitorsList.contains(monitor)) {
        m_monitorsList.append(monitor);
    }
75 76 77 78 79
}

void MonitorManager::removeMonitor(AbstractMonitor *monitor)
{
    m_monitorsList.removeAll(monitor);
80 81
}

Laurent Montel's avatar
Laurent Montel committed
82
AbstractMonitor *MonitorManager::monitor(Kdenlive::MonitorId monitorName)
83
{
Laurent Montel's avatar
Laurent Montel committed
84
    AbstractMonitor *monitor = nullptr;
Laurent Montel's avatar
Laurent Montel committed
85
    for (int i = 0; i < m_monitorsList.size(); ++i) {
86
        if (m_monitorsList[i]->id() == monitorName) {
Laurent Montel's avatar
Laurent Montel committed
87 88
            monitor = m_monitorsList.at(i);
        }
89 90 91 92
    }
    return monitor;
}

93 94
void MonitorManager::setConsumerProperty(const QString &name, const QString &value)
{
Laurent Montel's avatar
Laurent Montel committed
95
    if (m_clipMonitor) {
96
        m_clipMonitor->setConsumerProperty(name, value);
Laurent Montel's avatar
Laurent Montel committed
97 98
    }
    if (m_projectMonitor) {
99
        m_projectMonitor->setConsumerProperty(name, value);
Laurent Montel's avatar
Laurent Montel committed
100
    }
101 102
}

103 104
void MonitorManager::lockMonitor(Kdenlive::MonitorId name, bool lock)
{
Vincent Pinon's avatar
Vincent Pinon committed
105
    Q_UNUSED(name)
Laurent Montel's avatar
Laurent Montel committed
106 107 108 109 110
    if (lock) {
        m_refreshMutex.lock();
    } else {
        m_refreshMutex.unlock();
    }
111 112
}

113 114 115 116 117
void MonitorManager::focusProjectMonitor()
{
    activateMonitor(Kdenlive::ProjectMonitor);
}

118 119 120 121 122 123 124
void MonitorManager::refreshProjectRange(QSize range)
{
    if (m_projectMonitor->position() >= range.width() && m_projectMonitor->position() <= range.height()) {
        m_projectMonitor->refreshMonitorIfActive();
    }
}

125 126 127 128 129
void MonitorManager::refreshProjectMonitor()
{
    m_projectMonitor->refreshMonitorIfActive();
}

130 131 132 133 134
void MonitorManager::refreshClipMonitor()
{
    m_clipMonitor->refreshMonitorIfActive();
}

135
bool MonitorManager::activateMonitor(Kdenlive::MonitorId name)
136
{
Laurent Montel's avatar
Laurent Montel committed
137
    if (m_clipMonitor == nullptr || m_projectMonitor == nullptr) {
138
        return false;
Laurent Montel's avatar
Laurent Montel committed
139
    }
Nicolas Carion's avatar
Nicolas Carion committed
140
    if ((m_activeMonitor != nullptr) && m_activeMonitor->id() == name) {
141
        return false;
142
    }
143
    QMutexLocker locker(&m_switchMutex);
144
    bool stopCurrent = m_activeMonitor != nullptr;
145
    for (int i = 0; i < m_monitorsList.count(); ++i) {
146
        if (m_monitorsList.at(i)->id() == name) {
147
            m_activeMonitor = m_monitorsList.at(i);
148
        } else if (stopCurrent) {
149 150
            m_monitorsList.at(i)->stop();
        }
151
    }
152 153
    if (m_activeMonitor) {
        m_activeMonitor->parentWidget()->raise();
154 155
        if (name == Kdenlive::ClipMonitor) {
            emit updateOverlayInfos(name, KdenliveSettings::displayClipMonitorInfo());
156 157
            m_projectMonitor->displayAudioMonitor(false);
            m_clipMonitor->displayAudioMonitor(true);
Laurent Montel's avatar
Laurent Montel committed
158
        } else if (name == Kdenlive::ProjectMonitor) {
159 160 161
            emit updateOverlayInfos(name, KdenliveSettings::displayProjectMonitorInfo());
            m_clipMonitor->displayAudioMonitor(false);
            m_projectMonitor->displayAudioMonitor(true);
162
        }
163
    }
164
    emit checkColorScopes();
Laurent Montel's avatar
Laurent Montel committed
165
    return (m_activeMonitor != nullptr);
166 167
}

168 169 170 171 172 173
void MonitorManager::resetDisplay()
{
    m_projectMonitor->clearDisplay();
    m_clipMonitor->clearDisplay();
}

174
bool MonitorManager::isActive(Kdenlive::MonitorId id) const
175
{
Laurent Montel's avatar
Laurent Montel committed
176
    return m_activeMonitor ? m_activeMonitor->id() == id : false;
177 178
}

179
void MonitorManager::slotSwitchMonitors(bool activateClip)
180
{
Laurent Montel's avatar
Laurent Montel committed
181
    if (activateClip) {
182
        activateMonitor(Kdenlive::ClipMonitor);
Laurent Montel's avatar
Laurent Montel committed
183
    } else {
184
        activateMonitor(Kdenlive::ProjectMonitor);
Laurent Montel's avatar
Laurent Montel committed
185
    }
186 187
}

188
void MonitorManager::stopActiveMonitor()
189
{
Laurent Montel's avatar
Laurent Montel committed
190 191 192
    if (m_activeMonitor) {
        m_activeMonitor->stop();
    }
193 194 195
}

void MonitorManager::pauseActiveMonitor()
196
{
Laurent Montel's avatar
Laurent Montel committed
197 198 199 200 201
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->pause();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->pause();
    }
202 203
}

204 205
void MonitorManager::slotPlay()
{
Laurent Montel's avatar
Laurent Montel committed
206 207 208
    if (m_activeMonitor) {
        m_activeMonitor->slotPlay();
    }
209 210
}

211 212
void MonitorManager::slotPause()
{
213
    pauseActiveMonitor();
214 215
}

216 217
void MonitorManager::slotPlayZone()
{
Laurent Montel's avatar
Laurent Montel committed
218 219 220 221 222
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotPlayZone();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotPlayZone();
    }
223 224
}

225 226
void MonitorManager::slotLoopZone()
{
Laurent Montel's avatar
Laurent Montel committed
227 228 229 230 231
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotLoopZone();
    } else {
        m_projectMonitor->slotLoopZone();
    }
232 233
}

234 235
void MonitorManager::slotRewind(double speed)
{
Laurent Montel's avatar
Laurent Montel committed
236 237 238 239 240
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotRewind(speed);
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotRewind(speed);
    }
241 242
}

243 244
void MonitorManager::slotForward(double speed)
{
Laurent Montel's avatar
Laurent Montel committed
245 246 247 248 249
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotForward(speed);
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotForward(speed);
    }
250 251
}

252 253
void MonitorManager::slotRewindOneFrame()
{
Laurent Montel's avatar
Laurent Montel committed
254 255 256 257 258
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotRewindOneFrame();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotRewindOneFrame();
    }
259 260
}

261 262
void MonitorManager::slotForwardOneFrame()
{
Laurent Montel's avatar
Laurent Montel committed
263 264 265 266 267
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotForwardOneFrame();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotForwardOneFrame();
    }
268 269
}

270 271
void MonitorManager::slotRewindOneSecond()
{
Laurent Montel's avatar
Laurent Montel committed
272 273 274 275 276
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotRewindOneFrame(m_timecode.fps());
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotRewindOneFrame(m_timecode.fps());
    }
277 278
}

279 280
void MonitorManager::slotForwardOneSecond()
{
Laurent Montel's avatar
Laurent Montel committed
281 282 283 284 285
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotForwardOneFrame(m_timecode.fps());
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotForwardOneFrame(m_timecode.fps());
    }
286 287
}

288 289
void MonitorManager::slotStart()
{
Laurent Montel's avatar
Laurent Montel committed
290 291 292 293 294
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotStart();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotStart();
    }
295 296
}

297 298
void MonitorManager::slotEnd()
{
Laurent Montel's avatar
Laurent Montel committed
299 300 301 302 303
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotEnd();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotEnd();
    }
304 305
}

306
void MonitorManager::resetProfiles(const Timecode &tc)
307
{
308
    m_timecode = tc;
309 310
    m_clipMonitor->resetProfile();
    m_projectMonitor->resetProfile();
311 312
}

313 314
void MonitorManager::slotUpdateAudioMonitoring()
{
315 316
    if (m_clipMonitor) {
        m_clipMonitor->updateAudioForAnalysis();
317 318
    }
    if (m_projectMonitor) {
319
        m_projectMonitor->updateAudioForAnalysis();
320
    }
321 322
}

323 324 325 326 327
void MonitorManager::clearScopeSource()
{
    emit clearScopes();
}

328 329 330 331 332
void MonitorManager::updateScopeSource()
{
    emit checkColorScopes();
}

333
AbstractMonitor *MonitorManager::activeMonitor()
334
{
335
    if (m_activeMonitor) {
336
        return m_activeMonitor;
337
    }
Laurent Montel's avatar
Laurent Montel committed
338
    return nullptr;
339 340
}

341 342
void MonitorManager::slotSwitchFullscreen()
{
Laurent Montel's avatar
Laurent Montel committed
343 344 345
    if (m_activeMonitor) {
        m_activeMonitor->slotSwitchFullScreen();
    }
346 347
}

348 349
QString MonitorManager::getProjectFolder() const
{
Laurent Montel's avatar
Laurent Montel committed
350
    if (m_document == nullptr) {
Nicolas Carion's avatar
Nicolas Carion committed
351
        // qCDebug(KDENLIVE_LOG)<<" + + +nullptr DOC!!";
Laurent Montel's avatar
Laurent Montel committed
352
        return QString();
353
    }
354
    return m_document->projectDataFolder() + QDir::separator();
355 356
}

357 358
BinController *MonitorManager::binController()
{
Nicolas Carion's avatar
Nicolas Carion committed
359
    // REFACTORING TODO delete this function
360
    return pCore->binController().get();
361 362
}

363 364
void MonitorManager::setupActions()
{
365
    KDualAction *playAction = new KDualAction(i18n("Play"), i18n("Pause"), this);
366 367
    playAction->setInactiveIcon(KoIconUtils::themedIcon(QStringLiteral("media-playback-start")));
    playAction->setActiveIcon(KoIconUtils::themedIcon(QStringLiteral("media-playback-pause")));
368
    playAction->setShortcut(Qt::Key_Space);
369
    pCore->window()->addAction(QStringLiteral("monitor_play"), playAction);
370
    connect(playAction, &QAction::triggered, this, &MonitorManager::slotPlay);
371

Laurent Montel's avatar
Laurent Montel committed
372
    QAction *monitorPause = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-playback-stop")), i18n("Pause"), this);
373
    monitorPause->setShortcut(Qt::Key_K);
374
    pCore->window()->addAction(QStringLiteral("monitor_pause"), monitorPause);
Laurent Montel's avatar
Laurent Montel committed
375
    connect(monitorPause, &QAction::triggered, this, &MonitorManager::slotPause);
Laurent Montel's avatar
Laurent Montel committed
376

377
    QAction *fullMonitor = new QAction(i18n("Switch monitor fullscreen"), this);
378 379
    fullMonitor->setIcon(KoIconUtils::themedIcon(QStringLiteral("view-fullscreen")));
    pCore->window()->addAction(QStringLiteral("monitor_fullscreen"), fullMonitor);
Laurent Montel's avatar
Laurent Montel committed
380
    connect(fullMonitor, &QAction::triggered, this, &MonitorManager::slotSwitchFullscreen);
381

382 383 384 385 386 387 388 389 390 391
    QAction *monitorZoomIn = new QAction(i18n("Zoom in monitor"), this);
    monitorZoomIn->setIcon(KoIconUtils::themedIcon(QStringLiteral("zoom-in")));
    pCore->window()->addAction(QStringLiteral("monitor_zoomin"), monitorZoomIn);
    connect(monitorZoomIn, &QAction::triggered, this, &MonitorManager::slotZoomIn);

    QAction *monitorZoomOut = new QAction(i18n("Zoom out monitor"), this);
    monitorZoomOut->setIcon(KoIconUtils::themedIcon(QStringLiteral("zoom-out")));
    pCore->window()->addAction(QStringLiteral("monitor_zoomout"), monitorZoomOut);
    connect(monitorZoomOut, &QAction::triggered, this, &MonitorManager::slotZoomOut);

Laurent Montel's avatar
Laurent Montel committed
392
    QAction *monitorSeekBackward = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-seek-backward")), i18n("Rewind"), this);
393
    monitorSeekBackward->setShortcut(Qt::Key_J);
394
    pCore->window()->addAction(QStringLiteral("monitor_seek_backward"), monitorSeekBackward);
395 396
    connect(monitorSeekBackward, SIGNAL(triggered(bool)), SLOT(slotRewind()));

Laurent Montel's avatar
Laurent Montel committed
397
    QAction *monitorSeekBackwardOneFrame = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-skip-backward")), i18n("Rewind 1 Frame"), this);
398
    monitorSeekBackwardOneFrame->setShortcut(Qt::Key_Left);
399
    pCore->window()->addAction(QStringLiteral("monitor_seek_backward-one-frame"), monitorSeekBackwardOneFrame);
Laurent Montel's avatar
Laurent Montel committed
400
    connect(monitorSeekBackwardOneFrame, &QAction::triggered, this, &MonitorManager::slotRewindOneFrame);
401

Laurent Montel's avatar
Laurent Montel committed
402
    QAction *monitorSeekBackwardOneSecond = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-skip-backward")), i18n("Rewind 1 Second"), this);
403
    monitorSeekBackwardOneSecond->setShortcut(Qt::SHIFT + Qt::Key_Left);
404
    pCore->window()->addAction(QStringLiteral("monitor_seek_backward-one-second"), monitorSeekBackwardOneSecond);
Laurent Montel's avatar
Laurent Montel committed
405
    connect(monitorSeekBackwardOneSecond, &QAction::triggered, this, &MonitorManager::slotRewindOneSecond);
406

Laurent Montel's avatar
Laurent Montel committed
407
    QAction *monitorSeekForward = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-seek-forward")), i18n("Forward"), this);
408
    monitorSeekForward->setShortcut(Qt::Key_L);
409
    pCore->window()->addAction(QStringLiteral("monitor_seek_forward"), monitorSeekForward);
410 411
    connect(monitorSeekForward, SIGNAL(triggered(bool)), SLOT(slotForward()));

Laurent Montel's avatar
Laurent Montel committed
412
    QAction *projectStart = new QAction(KoIconUtils::themedIcon(QStringLiteral("go-first")), i18n("Go to Project Start"), this);
413
    projectStart->setShortcut(Qt::CTRL + Qt::Key_Home);
414
    pCore->window()->addAction(QStringLiteral("seek_start"), projectStart);
Laurent Montel's avatar
Laurent Montel committed
415
    connect(projectStart, &QAction::triggered, this, &MonitorManager::slotStart);
416

Laurent Montel's avatar
Laurent Montel committed
417
    QAction *projectEnd = new QAction(KoIconUtils::themedIcon(QStringLiteral("go-last")), i18n("Go to Project End"), this);
418
    projectEnd->setShortcut(Qt::CTRL + Qt::Key_End);
419
    pCore->window()->addAction(QStringLiteral("seek_end"), projectEnd);
Laurent Montel's avatar
Laurent Montel committed
420
    connect(projectEnd, &QAction::triggered, this, &MonitorManager::slotEnd);
421

Laurent Montel's avatar
Laurent Montel committed
422
    QAction *monitorSeekForwardOneFrame = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-skip-forward")), i18n("Forward 1 Frame"), this);
423
    monitorSeekForwardOneFrame->setShortcut(Qt::Key_Right);
424
    pCore->window()->addAction(QStringLiteral("monitor_seek_forward-one-frame"), monitorSeekForwardOneFrame);
Laurent Montel's avatar
Laurent Montel committed
425
    connect(monitorSeekForwardOneFrame, &QAction::triggered, this, &MonitorManager::slotForwardOneFrame);
426

Laurent Montel's avatar
Laurent Montel committed
427
    QAction *monitorSeekForwardOneSecond = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-skip-forward")), i18n("Forward 1 Second"), this);
428
    monitorSeekForwardOneSecond->setShortcut(Qt::SHIFT + Qt::Key_Right);
429
    pCore->window()->addAction(QStringLiteral("monitor_seek_forward-one-second"), monitorSeekForwardOneSecond);
Laurent Montel's avatar
Laurent Montel committed
430
    connect(monitorSeekForwardOneSecond, &QAction::triggered, this, &MonitorManager::slotForwardOneSecond);
431 432 433 434 435 436

    KSelectAction *interlace = new KSelectAction(i18n("Deinterlacer"), this);
    interlace->addAction(i18n("One Field (fast)"));
    interlace->addAction(i18n("Linear Blend (fast)"));
    interlace->addAction(i18n("YADIF - temporal only (good)"));
    interlace->addAction(i18n("YADIF - temporal + spacial (best)"));
Laurent Montel's avatar
Laurent Montel committed
437 438 439 440 441 442 443 444 445
    if (KdenliveSettings::mltdeinterlacer() == QLatin1String("linearblend")) {
        interlace->setCurrentItem(1);
    } else if (KdenliveSettings::mltdeinterlacer() == QLatin1String("yadif-temporal")) {
        interlace->setCurrentItem(2);
    } else if (KdenliveSettings::mltdeinterlacer() == QLatin1String("yadif")) {
        interlace->setCurrentItem(3);
    } else {
        interlace->setCurrentItem(0);
    }
446
    pCore->window()->addAction(QStringLiteral("mlt_interlace"), interlace);
Laurent Montel's avatar
Laurent Montel committed
447
    connect(interlace, static_cast<void (KSelectAction::*)(int)>(&KSelectAction::triggered), this, &MonitorManager::slotSetDeinterlacer);
Laurent Montel's avatar
Laurent Montel committed
448

449 450 451 452 453
    KSelectAction *interpol = new KSelectAction(i18n("Interpolation"), this);
    interpol->addAction(i18n("Nearest Neighbor (fast)"));
    interpol->addAction(i18n("Bilinear (good)"));
    interpol->addAction(i18n("Bicubic (better)"));
    interpol->addAction(i18n("Hyper/Lanczos (best)"));
Laurent Montel's avatar
Laurent Montel committed
454 455 456 457 458 459 460 461 462
    if (KdenliveSettings::mltinterpolation() == QLatin1String("bilinear")) {
        interpol->setCurrentItem(1);
    } else if (KdenliveSettings::mltinterpolation() == QLatin1String("bicubic")) {
        interpol->setCurrentItem(2);
    } else if (KdenliveSettings::mltinterpolation() == QLatin1String("hyper")) {
        interpol->setCurrentItem(3);
    } else {
        interpol->setCurrentItem(0);
    }
463
    pCore->window()->addAction(QStringLiteral("mlt_interpolation"), interpol);
Laurent Montel's avatar
Laurent Montel committed
464
    connect(interpol, static_cast<void (KSelectAction::*)(int)>(&KSelectAction::triggered), this, &MonitorManager::slotSetInterpolation);
465

Laurent Montel's avatar
Laurent Montel committed
466
    QAction *zoneStart = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-seek-backward")), i18n("Go to Zone Start"), this);
467
    zoneStart->setShortcut(Qt::SHIFT + Qt::Key_I);
468
    pCore->window()->addAction(QStringLiteral("seek_zone_start"), zoneStart);
Laurent Montel's avatar
Laurent Montel committed
469
    connect(zoneStart, &QAction::triggered, this, &MonitorManager::slotZoneStart);
470

471
    m_muteAction = new KDualAction(i18n("Mute monitor"), i18n("Unmute monitor"), this);
472 473 474
    m_muteAction->setActiveIcon(KoIconUtils::themedIcon(QStringLiteral("audio-volume-medium")));
    m_muteAction->setInactiveIcon(KoIconUtils::themedIcon(QStringLiteral("audio-volume-muted")));
    pCore->window()->addAction(QStringLiteral("mlt_mute"), m_muteAction);
Laurent Montel's avatar
Laurent Montel committed
475
    connect(m_muteAction, &KDualAction::activeChanged, this, &MonitorManager::slotMuteCurrentMonitor);
476

Laurent Montel's avatar
Laurent Montel committed
477
    QAction *zoneEnd = new QAction(KoIconUtils::themedIcon(QStringLiteral("media-seek-forward")), i18n("Go to Zone End"), this);
478
    zoneEnd->setShortcut(Qt::SHIFT + Qt::Key_O);
479
    pCore->window()->addAction(QStringLiteral("seek_zone_end"), zoneEnd);
Laurent Montel's avatar
Laurent Montel committed
480
    connect(zoneEnd, &QAction::triggered, this, &MonitorManager::slotZoneEnd);
481

482
    QAction *markIn = new QAction(KoIconUtils::themedIcon(QStringLiteral("zone-in")), i18n("Set Zone In"), this);
483
    markIn->setShortcut(Qt::Key_I);
484
    pCore->window()->addAction(QStringLiteral("mark_in"), markIn);
Laurent Montel's avatar
Laurent Montel committed
485
    connect(markIn, &QAction::triggered, this, &MonitorManager::slotSetInPoint);
486

487
    QAction *markOut = new QAction(KoIconUtils::themedIcon(QStringLiteral("zone-out")), i18n("Set Zone Out"), this);
488
    markOut->setShortcut(Qt::Key_O);
Nicolas Carion's avatar
Nicolas Carion committed
489
    pCore->window()->addAction(QStringLiteral("mark_out"), markOut);
Laurent Montel's avatar
Laurent Montel committed
490
    connect(markOut, &QAction::triggered, this, &MonitorManager::slotSetOutPoint);
491
}
492

493 494 495 496 497 498
void MonitorManager::refreshIcons()
{
    QList<QAction *> allMenus = this->findChildren<QAction *>();
    for (int i = 0; i < allMenus.count(); i++) {
        QAction *m = allMenus.at(i);
        QIcon ic = m->icon();
Laurent Montel's avatar
Laurent Montel committed
499 500 501
        if (ic.isNull() || ic.name().isEmpty()) {
            continue;
        }
502 503 504
        QIcon newIcon = KoIconUtils::themedIcon(ic.name());
        m->setIcon(newIcon);
    }
505 506 507 508 509 510 511 512
}

void MonitorManager::slotSetDeinterlacer(int ix)
{
    QString value;
    switch (ix) {

    case 1:
513
        value = QStringLiteral("linearblend");
514 515
        break;
    case 2:
516
        value = QStringLiteral("yadif-nospatial");
517 518
        break;
    case 3:
519
        value = QStringLiteral("yadif");
520 521
        break;
    default:
522
        value = QStringLiteral("onefield");
523 524
    }
    KdenliveSettings::setMltdeinterlacer(value);
525
    setConsumerProperty(QStringLiteral("deinterlace_method"), value);
526 527 528 529 530 531 532
}

void MonitorManager::slotSetInterpolation(int ix)
{
    QString value;
    switch (ix) {
    case 1:
533
        value = QStringLiteral("bilinear");
534 535
        break;
    case 2:
536
        value = QStringLiteral("bicubic");
537 538
        break;
    case 3:
539
        value = QStringLiteral("hyper");
540 541
        break;
    default:
542
        value = QStringLiteral("nearest");
543 544
    }
    KdenliveSettings::setMltinterpolation(value);
545
    setConsumerProperty(QStringLiteral("rescale"), value);
546
}
547

548 549 550 551 552
void MonitorManager::slotMuteCurrentMonitor(bool active)
{
    m_activeMonitor->mute(active);
}

Laurent Montel's avatar
Laurent Montel committed
553
Monitor *MonitorManager::clipMonitor()
Till Theato's avatar
Till Theato committed
554 555 556 557
{
    return m_clipMonitor;
}

Laurent Montel's avatar
Laurent Montel committed
558
Monitor *MonitorManager::projectMonitor()
Till Theato's avatar
Till Theato committed
559 560 561 562
{
    return m_projectMonitor;
}

563 564
void MonitorManager::slotZoneStart()
{
Laurent Montel's avatar
Laurent Montel committed
565
    if (m_activeMonitor == m_clipMonitor) {
566
        m_clipMonitor->slotZoneStart();
Laurent Montel's avatar
Laurent Montel committed
567
    } else if (m_activeMonitor == m_projectMonitor) {
568
        m_projectMonitor->slotZoneStart();
Laurent Montel's avatar
Laurent Montel committed
569
    }
570 571 572 573
}

void MonitorManager::slotZoneEnd()
{
Laurent Montel's avatar
Laurent Montel committed
574
    if (m_activeMonitor == m_projectMonitor) {
575
        m_projectMonitor->slotZoneEnd();
Laurent Montel's avatar
Laurent Montel committed
576
    } else if (m_activeMonitor == m_clipMonitor) {
577
        m_clipMonitor->slotZoneEnd();
Laurent Montel's avatar
Laurent Montel committed
578
    }
579 580
}

581 582 583 584 585 586 587 588 589 590 591 592 593 594
void MonitorManager::slotSetInPoint()
{
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotSetZoneStart();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotSetZoneStart();
    }
}

void MonitorManager::slotSetOutPoint()
{
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotSetZoneEnd();
    } else if (m_activeMonitor == m_projectMonitor) {
595 596 597 598
        // Zone end behaves slightly differently in clip monitor and timeline monitor.
        // in timeline, set zone end selects the frame before current cursor, but in clip monitor
        // it selects frame at current cursor position.
        m_projectMonitor->slotSetZoneEnd(true);
599 600
    }
}
601

602 603 604
QDir MonitorManager::getCacheFolder(CacheType type)
{
    bool ok = false;
Laurent Montel's avatar
Laurent Montel committed
605
    if (m_document) {
606
        return m_document->getCacheDir(type, &ok);
Laurent Montel's avatar
Laurent Montel committed
607
    }
608 609
    return QDir();
}
610 611 612 613 614 615 616 617 618 619 620 621 622 623

void MonitorManager::slotExtractCurrentFrame()
{
    if (m_activeMonitor) {
        static_cast<Monitor *>(m_activeMonitor)->slotExtractCurrentFrame();
    }
}

void MonitorManager::slotExtractCurrentFrameToProject()
{
    if (m_activeMonitor) {
        static_cast<Monitor *>(m_activeMonitor)->slotExtractCurrentFrame(QString(), true);
    }
}
624 625 626 627 628 629 630 631 632 633 634 635 636 637

void MonitorManager::slotZoomIn()
{
    if (m_activeMonitor) {
        static_cast<Monitor *>(m_activeMonitor)->slotZoomIn();
    }
}

void MonitorManager::slotZoomOut()
{
    if (m_activeMonitor) {
        static_cast<Monitor *>(m_activeMonitor)->slotZoomOut();
    }
}