monitormanager.cpp 21.9 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

26
#include <mlt++/Mlt.h>
27

28
#include "klocalizedstring.h"
29 30
#include <KDualAction>

Laurent Montel's avatar
Laurent Montel committed
31
#include "kdenlive_debug.h"
Nicolas Carion's avatar
Nicolas Carion committed
32
#include <QObject>
33

34 35
const double MonitorManager::speedArray[5] = {1.1, 1.5, 3., 5.5, 10.};

Nicolas Carion's avatar
Nicolas Carion committed
36
MonitorManager::MonitorManager(QObject *parent)
37
    : QObject(parent)
Nicolas Carion's avatar
Nicolas Carion committed
38

39
{
40
    setupActions();
41 42 43
    refreshTimer.setSingleShot(true);
    refreshTimer.setInterval(200);
    connect(&refreshTimer, &QTimer::timeout, this, &MonitorManager::forceProjectMonitorRefresh);
44 45
}

Laurent Montel's avatar
Laurent Montel committed
46
QAction *MonitorManager::getAction(const QString &name)
47
{
48
    return pCore->window()->action(name.toUtf8().constData());
49 50
}

51
void MonitorManager::initMonitors(Monitor *clipMonitor, Monitor *projectMonitor)
52
{
53 54
    m_clipMonitor = clipMonitor;
    m_projectMonitor = projectMonitor;
55 56 57 58 59 60
    m_monitorsList.append(clipMonitor);
    m_monitorsList.append(projectMonitor);
}

void MonitorManager::appendMonitor(AbstractMonitor *monitor)
{
Laurent Montel's avatar
Laurent Montel committed
61 62 63
    if (!m_monitorsList.contains(monitor)) {
        m_monitorsList.append(monitor);
    }
64 65 66 67 68
}

void MonitorManager::removeMonitor(AbstractMonitor *monitor)
{
    m_monitorsList.removeAll(monitor);
69 70
}

Laurent Montel's avatar
Laurent Montel committed
71
AbstractMonitor *MonitorManager::monitor(Kdenlive::MonitorId monitorName)
72
{
Laurent Montel's avatar
Laurent Montel committed
73
    AbstractMonitor *monitor = nullptr;
Nicolas Carion's avatar
Nicolas Carion committed
74 75 76
    for (auto &i : m_monitorsList) {
        if (i->id() == monitorName) {
            monitor = i;
Laurent Montel's avatar
Laurent Montel committed
77
        }
78 79 80 81
    }
    return monitor;
}

82 83
void MonitorManager::setConsumerProperty(const QString &name, const QString &value)
{
Laurent Montel's avatar
Laurent Montel committed
84
    if (m_clipMonitor) {
85
        m_clipMonitor->setConsumerProperty(name, value);
Laurent Montel's avatar
Laurent Montel committed
86 87
    }
    if (m_projectMonitor) {
88
        m_projectMonitor->setConsumerProperty(name, value);
Laurent Montel's avatar
Laurent Montel committed
89
    }
90 91
}

92 93
void MonitorManager::lockMonitor(Kdenlive::MonitorId name, bool lock)
{
Vincent Pinon's avatar
Vincent Pinon committed
94
    Q_UNUSED(name)
Laurent Montel's avatar
Laurent Montel committed
95 96 97 98 99
    if (lock) {
        m_refreshMutex.lock();
    } else {
        m_refreshMutex.unlock();
    }
100 101
}

102 103 104 105 106
void MonitorManager::focusProjectMonitor()
{
    activateMonitor(Kdenlive::ProjectMonitor);
}

107 108 109 110 111 112 113
void MonitorManager::refreshProjectRange(QSize range)
{
    if (m_projectMonitor->position() >= range.width() && m_projectMonitor->position() <= range.height()) {
        m_projectMonitor->refreshMonitorIfActive();
    }
}

114 115 116 117 118
void MonitorManager::refreshProjectMonitor()
{
    m_projectMonitor->refreshMonitorIfActive();
}

119 120 121 122 123
void MonitorManager::refreshClipMonitor()
{
    m_clipMonitor->refreshMonitorIfActive();
}

124 125 126 127 128 129 130
void MonitorManager::forceProjectMonitorRefresh()
{
    m_projectMonitor->forceMonitorRefresh();
}

bool MonitorManager::projectMonitorVisible() const
{
131
    return (m_projectMonitor->monitorIsFullScreen() || (m_projectMonitor->isVisible() && !m_projectMonitor->visibleRegion().isEmpty()));
132 133
}

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

172 173 174 175 176 177
void MonitorManager::resetDisplay()
{
    m_projectMonitor->clearDisplay();
    m_clipMonitor->clearDisplay();
}

178
bool MonitorManager::isActive(Kdenlive::MonitorId id) const
179
{
Laurent Montel's avatar
Laurent Montel committed
180
    return m_activeMonitor ? m_activeMonitor->id() == id : false;
181 182
}

183
void MonitorManager::slotSwitchMonitors(bool activateClip)
184
{
Laurent Montel's avatar
Laurent Montel committed
185
    if (activateClip) {
186
        activateMonitor(Kdenlive::ClipMonitor);
Laurent Montel's avatar
Laurent Montel committed
187
    } else {
188
        activateMonitor(Kdenlive::ProjectMonitor);
Laurent Montel's avatar
Laurent Montel committed
189
    }
190 191
}

192
void MonitorManager::stopActiveMonitor()
193
{
Laurent Montel's avatar
Laurent Montel committed
194 195 196
    if (m_activeMonitor) {
        m_activeMonitor->stop();
    }
197 198 199
}

void MonitorManager::pauseActiveMonitor()
200
{
Laurent Montel's avatar
Laurent Montel committed
201 202 203 204 205
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->pause();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->pause();
    }
206 207
}

208 209
void MonitorManager::slotPlay()
{
Laurent Montel's avatar
Laurent Montel committed
210 211 212
    if (m_activeMonitor) {
        m_activeMonitor->slotPlay();
    }
213 214
}

215 216
void MonitorManager::slotPause()
{
217
    pauseActiveMonitor();
218 219
}

220 221
void MonitorManager::slotPlayZone()
{
Laurent Montel's avatar
Laurent Montel committed
222 223 224 225 226
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotPlayZone();
    } else if (m_activeMonitor == m_projectMonitor) {
        m_projectMonitor->slotPlayZone();
    }
227 228
}

229 230
void MonitorManager::slotLoopZone()
{
Laurent Montel's avatar
Laurent Montel committed
231 232 233 234 235
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotLoopZone();
    } else {
        m_projectMonitor->slotLoopZone();
    }
236 237
}

238 239
void MonitorManager::slotRewind(double speed)
{
240 241
    if (m_activeMonitor) {
        m_activeMonitor->slotRewind(speed);
Laurent Montel's avatar
Laurent Montel committed
242
    }
243 244
}

245 246
void MonitorManager::slotForward(double speed)
{
247
    if (m_activeMonitor) {
248
        m_activeMonitor->slotForward(speed, true);
Laurent Montel's avatar
Laurent Montel committed
249
    }
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
    if (m_activeMonitor == m_clipMonitor) {
273
        m_clipMonitor->slotRewindOneFrame(qRound(pCore->getCurrentFps()));
Laurent Montel's avatar
Laurent Montel committed
274
    } else if (m_activeMonitor == m_projectMonitor) {
275
        m_projectMonitor->slotRewindOneFrame(qRound(pCore->getCurrentFps()));
Laurent Montel's avatar
Laurent Montel committed
276
    }
277 278
}

279 280
void MonitorManager::slotForwardOneSecond()
{
Laurent Montel's avatar
Laurent Montel committed
281
    if (m_activeMonitor == m_clipMonitor) {
282
        m_clipMonitor->slotForwardOneFrame(qRound(pCore->getCurrentFps()));
Laurent Montel's avatar
Laurent Montel committed
283
    } else if (m_activeMonitor == m_projectMonitor) {
284
        m_projectMonitor->slotForwardOneFrame(qRound(pCore->getCurrentFps()));
Laurent Montel's avatar
Laurent Montel committed
285
    }
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()
307
{
308 309
    m_clipMonitor->resetProfile();
    m_projectMonitor->resetProfile();
310 311
}

312 313 314 315 316 317 318 319 320 321 322 323
void MonitorManager::resetConsumers(bool fullReset)
{
    bool clipMonitorActive = m_clipMonitor->isActive();
    m_clipMonitor->resetConsumer(fullReset);
    m_projectMonitor->resetConsumer(fullReset);
    if (clipMonitorActive) {
        refreshClipMonitor();
    } else {
        refreshProjectMonitor();
    }
}

324 325
void MonitorManager::slotUpdateAudioMonitoring()
{
326 327
    if (m_clipMonitor) {
        m_clipMonitor->updateAudioForAnalysis();
328 329
    }
    if (m_projectMonitor) {
330
        m_projectMonitor->updateAudioForAnalysis();
331
    }
332 333
}

334 335 336 337 338
void MonitorManager::clearScopeSource()
{
    emit clearScopes();
}

339 340 341 342 343
void MonitorManager::updateScopeSource()
{
    emit checkColorScopes();
}

344
AbstractMonitor *MonitorManager::activeMonitor()
345
{
346
    if (m_activeMonitor) {
347
        return m_activeMonitor;
348
    }
Laurent Montel's avatar
Laurent Montel committed
349
    return nullptr;
350 351
}

352 353
void MonitorManager::slotSwitchFullscreen()
{
Laurent Montel's avatar
Laurent Montel committed
354 355 356
    if (m_activeMonitor) {
        m_activeMonitor->slotSwitchFullScreen();
    }
357 358
}

359 360
void MonitorManager::setupActions()
{
361
    KDualAction *playAction = new KDualAction(i18n("Play"), i18n("Pause"), this);
362 363
    playAction->setInactiveIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
    playAction->setActiveIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause")));
364 365
    connect(playAction, &KDualAction::activeChangedByUser, this, &MonitorManager::slotPlay);
    pCore->window()->addAction(QStringLiteral("monitor_play"), playAction, Qt::Key_Space);
366

367
    QAction *monitorPause = new QAction(QIcon::fromTheme(QStringLiteral("media-playback-stop")), i18n("Pause"), this);
Laurent Montel's avatar
Laurent Montel committed
368
    connect(monitorPause, &QAction::triggered, this, &MonitorManager::slotPause);
369
    pCore->window()->addAction(QStringLiteral("monitor_pause"), monitorPause, Qt::Key_K);
Laurent Montel's avatar
Laurent Montel committed
370

371
    QAction *fullMonitor = new QAction(i18n("Switch monitor fullscreen"), this);
372
    fullMonitor->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen")));
Laurent Montel's avatar
Laurent Montel committed
373
    connect(fullMonitor, &QAction::triggered, this, &MonitorManager::slotSwitchFullscreen);
374
    pCore->window()->addAction(QStringLiteral("monitor_fullscreen"), fullMonitor);
375

376
    QAction *monitorZoomIn = new QAction(i18n("Zoom in monitor"), this);
377
    monitorZoomIn->setIcon(QIcon::fromTheme(QStringLiteral("zoom-in")));
378
    connect(monitorZoomIn, &QAction::triggered, this, &MonitorManager::slotZoomIn);
379
    pCore->window()->addAction(QStringLiteral("monitor_zoomin"), monitorZoomIn);
380 381

    QAction *monitorZoomOut = new QAction(i18n("Zoom out monitor"), this);
382
    monitorZoomOut->setIcon(QIcon::fromTheme(QStringLiteral("zoom-out")));
383
    connect(monitorZoomOut, &QAction::triggered, this, &MonitorManager::slotZoomOut);
384
    pCore->window()->addAction(QStringLiteral("monitor_zoomout"), monitorZoomOut);
385

386
    QAction *monitorSeekBackward = new QAction(QIcon::fromTheme(QStringLiteral("media-seek-backward")), i18n("Rewind"), this);
387
    connect(monitorSeekBackward, &QAction::triggered, this, &MonitorManager::slotRewind);
388
    pCore->window()->addAction(QStringLiteral("monitor_seek_backward"), monitorSeekBackward, Qt::Key_J);
389

390
    QAction *monitorSeekBackwardOneFrame = new QAction(QIcon::fromTheme(QStringLiteral("media-skip-backward")), i18n("Rewind 1 Frame"), this);
Laurent Montel's avatar
Laurent Montel committed
391
    connect(monitorSeekBackwardOneFrame, &QAction::triggered, this, &MonitorManager::slotRewindOneFrame);
392
    pCore->window()->addAction(QStringLiteral("monitor_seek_backward-one-frame"), monitorSeekBackwardOneFrame, Qt::Key_Left);
393

394
    QAction *monitorSeekBackwardOneSecond = new QAction(QIcon::fromTheme(QStringLiteral("media-skip-backward")), i18n("Rewind 1 Second"), this);
Laurent Montel's avatar
Laurent Montel committed
395
    connect(monitorSeekBackwardOneSecond, &QAction::triggered, this, &MonitorManager::slotRewindOneSecond);
396
    pCore->window()->addAction(QStringLiteral("monitor_seek_backward-one-second"), monitorSeekBackwardOneSecond, Qt::SHIFT + Qt::Key_Left);
397

398
    QAction *monitorSeekForward = new QAction(QIcon::fromTheme(QStringLiteral("media-seek-forward")), i18n("Forward"), this);
399
    connect(monitorSeekForward,  &QAction::triggered, this, &MonitorManager::slotForward);
400
    pCore->window()->addAction(QStringLiteral("monitor_seek_forward"), monitorSeekForward, Qt::Key_L);
401

402
    QAction *projectStart = new QAction(QIcon::fromTheme(QStringLiteral("go-first")), i18n("Go to Project Start"), this);
Laurent Montel's avatar
Laurent Montel committed
403
    connect(projectStart, &QAction::triggered, this, &MonitorManager::slotStart);
404
    pCore->window()->addAction(QStringLiteral("seek_start"), projectStart, Qt::CTRL + Qt::Key_Home);
405

406 407 408
    m_multiTrack = new QAction(QIcon::fromTheme(QStringLiteral("view-split-left-right")), i18n("Multitrack view"), this);
    m_multiTrack->setCheckable(true);
    connect(m_multiTrack, &QAction::triggered, [&](bool checked) {
409
        if (m_projectMonitor) {
410
            m_projectMonitor->multitrackView(checked, true);
411 412
        }
    });
413
    pCore->window()->addAction(QStringLiteral("monitor_multitrack"), m_multiTrack);
414

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

419
    QAction *monitorSeekForwardOneFrame = new QAction(QIcon::fromTheme(QStringLiteral("media-skip-forward")), i18n("Forward 1 Frame"), this);
Laurent Montel's avatar
Laurent Montel committed
420
    connect(monitorSeekForwardOneFrame, &QAction::triggered, this, &MonitorManager::slotForwardOneFrame);
421
    pCore->window()->addAction(QStringLiteral("monitor_seek_forward-one-frame"), monitorSeekForwardOneFrame, Qt::Key_Right);
422

423
    QAction *monitorSeekForwardOneSecond = new QAction(QIcon::fromTheme(QStringLiteral("media-skip-forward")), i18n("Forward 1 Second"), this);
Laurent Montel's avatar
Laurent Montel committed
424
    connect(monitorSeekForwardOneSecond, &QAction::triggered, this, &MonitorManager::slotForwardOneSecond);
425
    pCore->window()->addAction(QStringLiteral("monitor_seek_forward-one-second"), monitorSeekForwardOneSecond, Qt::SHIFT + Qt::Key_Right);
426 427 428 429 430 431

    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
432 433 434 435 436 437 438 439 440
    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);
    }
Laurent Montel's avatar
Laurent Montel committed
441
    connect(interlace, static_cast<void (KSelectAction::*)(int)>(&KSelectAction::triggered), this, &MonitorManager::slotSetDeinterlacer);
442
    pCore->window()->addAction(QStringLiteral("mlt_interlace"), interlace);
Laurent Montel's avatar
Laurent Montel committed
443

444 445 446 447 448
    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
449 450 451 452 453 454 455 456 457
    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);
    }
Laurent Montel's avatar
Laurent Montel committed
458
    connect(interpol, static_cast<void (KSelectAction::*)(int)>(&KSelectAction::triggered), this, &MonitorManager::slotSetInterpolation);
459
    pCore->window()->addAction(QStringLiteral("mlt_interpolation"), interpol);
460

461
    QAction *zoneStart = new QAction(QIcon::fromTheme(QStringLiteral("media-seek-backward")), i18n("Go to Zone Start"), this);
Laurent Montel's avatar
Laurent Montel committed
462
    connect(zoneStart, &QAction::triggered, this, &MonitorManager::slotZoneStart);
463
    pCore->window()->addAction(QStringLiteral("seek_zone_start"), zoneStart, Qt::SHIFT + Qt::Key_I);
464

465
    m_muteAction = new KDualAction(i18n("Mute monitor"), i18n("Unmute monitor"), this);
466 467
    m_muteAction->setActiveIcon(QIcon::fromTheme(QStringLiteral("audio-volume-medium")));
    m_muteAction->setInactiveIcon(QIcon::fromTheme(QStringLiteral("audio-volume-muted")));
468
    connect(m_muteAction, &KDualAction::activeChangedByUser, this, &MonitorManager::slotMuteCurrentMonitor);
469
    pCore->window()->addAction(QStringLiteral("mlt_mute"), m_muteAction);
470

471
    QAction *zoneEnd = new QAction(QIcon::fromTheme(QStringLiteral("media-seek-forward")), i18n("Go to Zone End"), this);
Laurent Montel's avatar
Laurent Montel committed
472
    connect(zoneEnd, &QAction::triggered, this, &MonitorManager::slotZoneEnd);
473
    pCore->window()->addAction(QStringLiteral("seek_zone_end"), zoneEnd, Qt::SHIFT + Qt::Key_O);
474

475
    QAction *markIn = new QAction(QIcon::fromTheme(QStringLiteral("zone-in")), i18n("Set Zone In"), this);
Laurent Montel's avatar
Laurent Montel committed
476
    connect(markIn, &QAction::triggered, this, &MonitorManager::slotSetInPoint);
477
    pCore->window()->addAction(QStringLiteral("mark_in"), markIn, Qt::Key_I);
478

479
    QAction *markOut = new QAction(QIcon::fromTheme(QStringLiteral("zone-out")), i18n("Set Zone Out"), this);
Laurent Montel's avatar
Laurent Montel committed
480
    connect(markOut, &QAction::triggered, this, &MonitorManager::slotSetOutPoint);
481
    pCore->window()->addAction(QStringLiteral("mark_out"), markOut, Qt::Key_O);
482
}
483

484 485 486 487 488 489
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
490 491 492
        if (ic.isNull() || ic.name().isEmpty()) {
            continue;
        }
493
        QIcon newIcon = QIcon::fromTheme(ic.name());
494 495
        m->setIcon(newIcon);
    }
496 497 498 499 500 501 502 503
}

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

    case 1:
504
        value = QStringLiteral("linearblend");
505 506
        break;
    case 2:
507
        value = QStringLiteral("yadif-nospatial");
508 509
        break;
    case 3:
510
        value = QStringLiteral("yadif");
511 512
        break;
    default:
513
        value = QStringLiteral("onefield");
514 515
    }
    KdenliveSettings::setMltdeinterlacer(value);
516
    setConsumerProperty(QStringLiteral("deinterlace_method"), value);
517 518 519 520 521 522 523
}

void MonitorManager::slotSetInterpolation(int ix)
{
    QString value;
    switch (ix) {
    case 1:
524
        value = QStringLiteral("bilinear");
525 526
        break;
    case 2:
527
        value = QStringLiteral("bicubic");
528 529
        break;
    case 3:
530
        value = QStringLiteral("hyper");
531 532
        break;
    default:
533
        value = QStringLiteral("nearest");
534 535
    }
    KdenliveSettings::setMltinterpolation(value);
536
    setConsumerProperty(QStringLiteral("rescale"), value);
537
}
538

539 540 541 542 543
void MonitorManager::slotMuteCurrentMonitor(bool active)
{
    m_activeMonitor->mute(active);
}

Laurent Montel's avatar
Laurent Montel committed
544
Monitor *MonitorManager::clipMonitor()
Till Theato's avatar
Till Theato committed
545 546 547 548
{
    return m_clipMonitor;
}

Laurent Montel's avatar
Laurent Montel committed
549
Monitor *MonitorManager::projectMonitor()
Till Theato's avatar
Till Theato committed
550 551 552 553
{
    return m_projectMonitor;
}

554 555
void MonitorManager::slotZoneStart()
{
Laurent Montel's avatar
Laurent Montel committed
556
    if (m_activeMonitor == m_clipMonitor) {
557
        m_clipMonitor->slotZoneStart();
Laurent Montel's avatar
Laurent Montel committed
558
    } else if (m_activeMonitor == m_projectMonitor) {
559
        m_projectMonitor->slotZoneStart();
Laurent Montel's avatar
Laurent Montel committed
560
    }
561 562 563 564
}

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

572 573 574 575 576
void MonitorManager::slotSetInPoint()
{
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotSetZoneStart();
    } else if (m_activeMonitor == m_projectMonitor) {
577 578 579
        QPoint sourceZone = m_projectMonitor->getZoneInfo();
        QPoint destZone = sourceZone;
        destZone.setX(m_projectMonitor->position());
580 581 582
        if (destZone.x() > destZone.y()) {
            destZone.setY(qMin(pCore->projectDuration(), destZone.x() + (sourceZone.y() - sourceZone.x())));
        }
583
        m_projectMonitor->zoneUpdatedWithUndo(sourceZone, destZone);
584 585 586 587 588 589 590 591
    }
}

void MonitorManager::slotSetOutPoint()
{
    if (m_activeMonitor == m_clipMonitor) {
        m_clipMonitor->slotSetZoneEnd();
    } else if (m_activeMonitor == m_projectMonitor) {
592 593 594
        QPoint sourceZone = m_projectMonitor->getZoneInfo();
        QPoint destZone = sourceZone;
        destZone.setY(m_projectMonitor->position());
595 596 597
        if (destZone.y() < destZone.x()) {
            destZone.setX(qMax(0, destZone.y() - (sourceZone.y() - sourceZone.x())));
        }
598
        m_projectMonitor->zoneUpdatedWithUndo(sourceZone, destZone);
599 600
    }
}
601

602 603 604 605 606 607 608 609 610 611 612 613 614
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);
    }
}
615 616 617 618 619 620 621 622 623 624 625 626 627 628

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

void MonitorManager::slotZoomOut()
{
    if (m_activeMonitor) {
        static_cast<Monitor *>(m_activeMonitor)->slotZoomOut();
    }
}
629 630 631 632 633 634 635 636

bool MonitorManager::isMultiTrack() const
{
    if (m_multiTrack) {
        return m_multiTrack->isChecked();
    }
    return false;
}
637 638 639 640 641 642 643 644 645 646

void MonitorManager::updateBgColor()
{
    if (m_projectMonitor) {
        m_projectMonitor->updateBgColor();
    }
    if (m_clipMonitor) {
        m_clipMonitor->updateBgColor();
    }
}
647