timelinecontroller.h 34.6 KB
Newer Older
1
/***************************************************************************
2
 *   Copyright (C) 2017 by Jean-Baptiste Mardelle                          *
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *   This file is part of Kdenlive. See www.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) version 3 or any later version accepted by the       *
 *   membership of KDE e.V. (or its successor approved  by the membership  *
 *   of KDE e.V.), which shall act as a proxy defined in Section 14 of     *
 *   version 3 of the license.                                             *
 *                                                                         *
 *   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, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#ifndef TIMELINECONTROLLER_H
#define TIMELINECONTROLLER_H

Nicolas Carion's avatar
Nicolas Carion committed
25
#include "definitions.h"
26
#include "lib/audio/audioCorrelation.h"
27
#include "timeline2/model/timelineitemmodel.hpp"
28

29
30
31
#include <KActionCollection>
#include <QDir>

32
33
class PreviewManager;
class QAction;
34
class QQuickItem;
35

Nicolas Carion's avatar
linting    
Nicolas Carion committed
36
// see https://bugreports.qt.io/browse/QTBUG-57714, don't expose a QWidget as a context property
37
38
39
class TimelineController : public QObject
{
    Q_OBJECT
40
    /** @brief holds a list of currently selected clips (list of clipId's)
41
     */
42
    Q_PROPERTY(QList<int> selection READ selection NOTIFY selectionChanged)
43
    Q_PROPERTY(int selectedMix READ selectedMix NOTIFY selectedMixChanged)
44
    /** @brief holds the timeline zoom factor
45
46
     */
    Q_PROPERTY(double scaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged)
47
    /** @brief holds the current project duration
48
49
     */
    Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
50
    Q_PROPERTY(int fullDuration READ fullDuration NOTIFY durationChanged)
51
    Q_PROPERTY(bool audioThumbFormat READ audioThumbFormat NOTIFY audioThumbFormatChanged)
52
    Q_PROPERTY(bool audioThumbNormalize READ audioThumbNormalize NOTIFY audioThumbNormalizeChanged)
53
54
    Q_PROPERTY(int zoneIn READ zoneIn WRITE setZoneIn NOTIFY zoneChanged)
    Q_PROPERTY(int zoneOut READ zoneOut WRITE setZoneOut NOTIFY zoneChanged)
55
56
    Q_PROPERTY(bool ripple READ ripple NOTIFY rippleChanged)
    Q_PROPERTY(bool scrub READ scrub NOTIFY scrubChanged)
57
    Q_PROPERTY(bool snap READ snap NOTIFY snapChanged)
58
59
60
    Q_PROPERTY(bool showThumbnails READ showThumbnails NOTIFY showThumbnailsChanged)
    Q_PROPERTY(bool showMarkers READ showMarkers NOTIFY showMarkersChanged)
    Q_PROPERTY(bool showAudioThumbnails READ showAudioThumbnails NOTIFY showAudioThumbnailsChanged)
61
62
    Q_PROPERTY(QVariantList dirtyChunks READ dirtyChunks NOTIFY dirtyChunksChanged)
    Q_PROPERTY(QVariantList renderedChunks READ renderedChunks NOTIFY renderedChunksChanged)
63
    Q_PROPERTY(QVariantList masterEffectZones MEMBER m_masterEffectZones NOTIFY masterZonesChanged)
64
    Q_PROPERTY(int workingPreview READ workingPreview NOTIFY workingPreviewChanged)
65
    Q_PROPERTY(bool useRuler READ useRuler NOTIFY useRulerChanged)
Pistos Pi's avatar
Pistos Pi committed
66
    Q_PROPERTY(bool scrollVertically READ scrollVertically NOTIFY scrollVerticallyChanged)
67
    Q_PROPERTY(int activeTrack READ activeTrack WRITE setActiveTrack NOTIFY activeTrackChanged)
68
    Q_PROPERTY(QVariantList audioTarget READ audioTarget NOTIFY audioTargetChanged)
69
    Q_PROPERTY(int videoTarget READ videoTarget WRITE setVideoTarget NOTIFY videoTargetChanged)
70

71
    Q_PROPERTY(QVariantList lastAudioTarget READ lastAudioTarget  NOTIFY lastAudioTargetChanged)
72
    Q_PROPERTY(int lastVideoTarget MEMBER m_lastVideoTarget NOTIFY lastVideoTargetChanged)
73

74
    Q_PROPERTY(int hasAudioTarget READ hasAudioTarget NOTIFY hasAudioTargetChanged)
75
    Q_PROPERTY(bool hasVideoTarget READ hasVideoTarget NOTIFY hasVideoTargetChanged)
76
    Q_PROPERTY(int clipTargets READ clipTargets NOTIFY hasAudioTargetChanged)
77
    Q_PROPERTY(bool autoScroll READ autoScroll NOTIFY autoScrollChanged)
78
79
    Q_PROPERTY(QColor videoColor READ videoColor NOTIFY colorsChanged)
    Q_PROPERTY(QColor audioColor READ audioColor NOTIFY colorsChanged)
80
    Q_PROPERTY(QColor titleColor READ titleColor NOTIFY colorsChanged)
Sashmita Raghav's avatar
Sashmita Raghav committed
81
    Q_PROPERTY(QColor imageColor READ imageColor NOTIFY colorsChanged)
82
83
    Q_PROPERTY(QColor thumbColor1 READ thumbColor1 NOTIFY colorsChanged)
    Q_PROPERTY(QColor thumbColor2 READ thumbColor2 NOTIFY colorsChanged)
84
    Q_PROPERTY(QColor slideshowColor READ slideshowColor NOTIFY colorsChanged)
85
86
    Q_PROPERTY(QColor targetColor READ targetColor NOTIFY colorsChanged)
    Q_PROPERTY(QColor targetTextColor READ targetTextColor NOTIFY colorsChanged)
87
    Q_PROPERTY(QColor lockedColor READ lockedColor NOTIFY colorsChanged)
Vincent Pinon's avatar
Vincent Pinon committed
88
    Q_PROPERTY(QColor selectionColor READ selectionColor NOTIFY colorsChanged)
89
    Q_PROPERTY(QColor groupColor READ groupColor NOTIFY colorsChanged)
90
91
    Q_PROPERTY(bool subtitlesDisabled READ subtitlesDisabled NOTIFY subtitlesDisabledChanged)
    Q_PROPERTY(bool subtitlesLocked READ subtitlesLocked NOTIFY subtitlesLockedChanged)
92
    Q_PROPERTY(bool guidesLocked READ guidesLocked NOTIFY guidesLockedChanged)
93
    Q_PROPERTY(QPoint effectZone MEMBER m_effectZone NOTIFY effectZoneChanged)
94
95

public:
96
    TimelineController(QObject *parent);
Nicolas Carion's avatar
Nicolas Carion committed
97
    ~TimelineController() override;
98
    /** @brief Sets the model that this widgets displays */
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
99
    void setModel(std::shared_ptr<TimelineItemModel> model);
100
    std::shared_ptr<TimelineItemModel> getModel() const;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
101
    void setRoot(QQuickItem *root);
102
103
    /** @brief Edit an item's in/out points with a dialog
     */
104
    Q_INVOKABLE void editItemDuration(int itemId = -1);
105
106
107
    /** @brief Edit a title clip with a title widget
     */
    Q_INVOKABLE void editTitleClip(int itemId = -1);
108
109
110
111
112
113
114
115
116
117
118

    /** @brief Returns the topmost track containing a selected item (-1 if selection is embty) */
    Q_INVOKABLE int selectedTrack() const;

    /** @brief Select the clip in active track under cursor
        @param type is the type of the object (clip or composition)
        @param select: true if the object should be selected and false if it should be deselected
        @param addToCurrent: if true, the object will be added to the new selection
    */
    void selectCurrentItem(ObjectType type, bool select, bool addToCurrent = false);

119
    /** @brief Select all timeline items
120
121
     */
    void selectAll();
122
    /** @brief Select all items in one track
123
124
     */
    void selectCurrentTrack();
125
126
127
128
129
    /** @brief Select multiple objects on the timeline
        @param tracks List of ids of tracks from which to select
        @param start/endFrame Interval from which to select the items
        @param addToSelect if true, the old selection is retained
    */
130
    Q_INVOKABLE void selectItems(const QVariantList &tracks, int startFrame, int endFrame, bool addToSelect, bool selectBottomCompositions, bool selectSubTitles);
131
132
133
134

    /** @brief request a selection with a list of ids*/
    Q_INVOKABLE void selectItems(const QList<int> &ids);

135
    /** @brief Returns true is item is selected as well as other items */
136
137
    Q_INVOKABLE bool isInSelection(int itemId);

138
    /** @brief Show/hide audio record controls on a track
139
     */
140
    Q_INVOKABLE void switchRecording(int trackId);
141
    /** @brief Add recorded file to timeline
142
143
     */
    void finishRecording(const QString &recordedFile);
144
    /** @brief Open Kdenlive's config diablog on a defined page and tab
145
146
     */
    Q_INVOKABLE void showConfig(int page, int tab);
147

148
    /** @brief Returns true if we have at least one active track
149
150
151
     */
    Q_INVOKABLE bool hasActiveTracks() const;

152
    /** @brief returns current timeline's zoom factor
153
154
     */
    Q_INVOKABLE double scaleFactor() const;
155
    /** @brief set current timeline's zoom factor
156
     */
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
157
    void setScaleFactorOnMouse(double scale, bool zoomOnMouse);
158
    void setScaleFactor(double scale);
159
    /** @brief Returns the project's duration (tractor)
160
161
     */
    Q_INVOKABLE int duration() const;
162
    Q_INVOKABLE int fullDuration() const;
163
    /** @brief Returns the current cursor position (frame currently displayed by MLT)
164
     */
165
    /** @brief Returns the seek request position (-1 = no seek pending)
166
     */
167
168
169
    Q_INVOKABLE QVariantList audioTarget() const;
    Q_INVOKABLE QVariantList lastAudioTarget() const;
    Q_INVOKABLE const QString audioTargetName(int tid) const;
170
    Q_INVOKABLE int videoTarget() const;
171
    Q_INVOKABLE int hasAudioTarget() const;
172
    Q_INVOKABLE int clipTargets() const;
173
    Q_INVOKABLE bool hasVideoTarget() const;
174
    bool autoScroll() const;
175
    Q_INVOKABLE int activeTrack() const { return m_activeTrack; }
176
177
    Q_INVOKABLE QColor videoColor() const;
    Q_INVOKABLE QColor audioColor() const;
178
    Q_INVOKABLE QColor titleColor() const;
Sashmita Raghav's avatar
Sashmita Raghav committed
179
    Q_INVOKABLE QColor imageColor() const;
180
181
    Q_INVOKABLE QColor thumbColor1() const;
    Q_INVOKABLE QColor thumbColor2() const;
182
    Q_INVOKABLE QColor slideshowColor() const;
183
184
    Q_INVOKABLE QColor targetColor() const;
    Q_INVOKABLE QColor targetTextColor() const;
185
    Q_INVOKABLE QColor lockedColor() const;
Vincent Pinon's avatar
Vincent Pinon committed
186
    Q_INVOKABLE QColor selectionColor() const;
187
    Q_INVOKABLE QColor groupColor() const;
188
    Q_INVOKABLE void showToolTip(const QString &info = QString()) const;
189
190
    Q_INVOKABLE void showKeyBinding(const QString &info = QString()) const;
    Q_INVOKABLE void showTimelineToolInfo(bool show) const;
191
192
193
194
    void switchSubtitleDisable();
    bool subtitlesDisabled() const;
    void switchSubtitleLock();
    bool subtitlesLocked() const;
195
    bool guidesLocked() const;
196
    /** @brief Request a seek operation
197
198
       @param position is the desired new timeline position
     */
199
200
201
202
203
    int zoneIn() const { return m_zone.x(); }
    int zoneOut() const { return m_zone.y(); }
    void setZoneIn(int inPoint);
    void setZoneOut(int outPoint);
    void setZone(const QPoint &zone, bool withUndo = true);
204
    /** @brief Request a seek operation
205
206
207
208
209
210
       @param position is the desired new timeline position
     */
    Q_INVOKABLE void setPosition(int position);
    Q_INVOKABLE bool snap();
    Q_INVOKABLE bool ripple();
    Q_INVOKABLE bool scrub();
211
212
213
    Q_INVOKABLE QString timecode(int frames) const;
    QString framesToClock(int frames) const;
    Q_INVOKABLE QString simplifiedTC(int frames) const;
214
    /** @brief Request inserting a new clip in timeline (dragged from bin or monitor)
215
216
217
218
219
220
       @param tid is the destination track
       @param position is the timeline position
       @param xml is the data describing the dropped clip
       @param logUndo if set to false, no undo object is stored
       @return the id of the inserted clip
     */
221
    Q_INVOKABLE int insertClip(int tid, int position, const QString &xml, bool logUndo, bool refreshView, bool useTargets);
222
    /** @brief Request inserting multiple clips into the timeline (dragged from bin or monitor)
223
224
225
226
227
228
229
     * @param tid is the destination track
     * @param position is the timeline position
     * @param binIds the IDs of the bins being dropped
     * @param logUndo if set to false, no undo object is stored
     * @return the ids of the inserted clips
     */
    Q_INVOKABLE QList<int> insertClips(int tid, int position, const QStringList &binIds, bool logUndo, bool refreshView);
230
    Q_INVOKABLE void copyItem();
231
    Q_INVOKABLE bool pasteItem(int position = -1, int tid = -1);
232
    /** @brief Request inserting a new composition in timeline (dragged from compositions list)
233
234
235
236
237
238
239
       @param tid is the destination track
       @param position is the timeline position
       @param transitionId is the data describing the dropped composition
       @param logUndo if set to false, no undo object is stored
       @return the id of the inserted composition
    */
    Q_INVOKABLE int insertComposition(int tid, int position, const QString &transitionId, bool logUndo);
240
    /** @brief Request inserting a new composition in timeline (dragged from compositions list)
241
242
243
244
245
246
247
248
249
       this function will check if there is a clip at insert point and
       adjust the composition length accordingly
       @param tid is the destination track
       @param position is the timeline position
       @param transitionId is the data describing the dropped composition
       @param logUndo if set to false, no undo object is stored
       @return the id of the inserted composition
    */
    Q_INVOKABLE int insertNewComposition(int tid, int position, const QString &transitionId, bool logUndo);
250
    Q_INVOKABLE int insertNewComposition(int tid, int clipId, int offset, const QString &transitionId, bool logUndo);
251

252
    /** @brief Request deletion of the currently selected clips
253
254
255
256
     */
    Q_INVOKABLE void deleteSelectedClips();

    Q_INVOKABLE void triggerAction(const QString &name);
257
    Q_INVOKABLE const QString actionText(const QString &name);
258

259
    /** @brief Returns id of the timeline selected clip if there is only 1 clip selected
Pistos Pi's avatar
Pistos Pi committed
260
     * or an AVSplit group. If allowComposition is true, returns composition id if
261
262
     * only 1 is selected, otherwise returns -1. If restrictToCurrentPos is true, it will
     * only return the id if timeline cursor is inside item
263
     */
264
    int getMainSelectedItem(bool restrictToCurrentPos = true, bool allowComposition = false);
265
    int getMainSelectedClip() const;
266

267
    /** @brief Do we want to display video thumbnails
268
269
270
271
272
     */
    bool showThumbnails() const;
    bool showAudioThumbnails() const;
    bool showMarkers() const;
    bool audioThumbFormat() const;
273
    bool audioThumbNormalize() const;
274
    /** @brief Do we want to display audio thumbnails
275
276
     */
    Q_INVOKABLE bool showWaveforms() const;
277
    /** @brief Insert a timeline track
278
279
     */
    Q_INVOKABLE void addTrack(int tid);
280
    /** @brief Remove multiple(or single) timeline tracks
281
     */
282
    Q_INVOKABLE void deleteMultipleTracks(int tid);
283
    /** @brief Show / hide audio rec controls in active track
284
285
     */
    void switchTrackRecord(int tid = -1);
286
    /** @brief Group selected items in timeline
287
288
     */
    Q_INVOKABLE void groupSelection();
289
    /** @brief Ungroup selected items in timeline
290
     */
291
    Q_INVOKABLE void unGroupSelection(int cid = -1);
292
    /** @brief Ask for edit marker dialog
293
     */
294
    Q_INVOKABLE void editMarker(int cid = -1, int position = -1);
295
    /** @brief Ask for marker add dialog
296
     */
297
    Q_INVOKABLE void addMarker(int cid = -1, int position = -1);
298
    /** @brief Ask for quick marker add (without dialog)
299
     */
300
    Q_INVOKABLE void addQuickMarker(int cid = -1, int position = -1);
301
    /** @brief Ask for marker delete
302
     */
303
    Q_INVOKABLE void deleteMarker(int cid = -1, int position = -1);
304
    /** @brief Ask for all markers delete
305
     */
306
    Q_INVOKABLE void deleteAllMarkers(int cid = -1);
307
    /** @brief Ask for edit timeline guide dialog
308
     */
309
    Q_INVOKABLE void editGuide(int frame = -1);
310
    Q_INVOKABLE void moveGuide(int frame, int newFrame);
311
    Q_INVOKABLE void moveGuideWithoutUndo(int frame, int newFrame);
312
    /** @brief Move all guides in the given range
313
314
315
316
317
     * @param start the start point of the range in frames
     * @param end the end point of the range in frames
     * @param offset how many frames the guides are moved
     */
    Q_INVOKABLE bool moveGuidesInRange(int start, int end, int offset);
318
    /** @brief Move all guides in the given range (same as above but with undo/redo)
319
320
321
322
323
324
325
326
     * @param start the start point of the range in frames
     * @param end the end point of the range in frames
     * @param offset how many frames the guides are moved
     * @param undo
     * @param redo
     */
    Q_INVOKABLE bool moveGuidesInRange(int start, int end, int offset, Fun &undo, Fun &redo);

327
    /** @brief Add a timeline guide
328
     */
329
    Q_INVOKABLE void switchGuide(int frame = -1, bool deleteOnly = false, bool showGui = false);
330
    /** @brief Request monitor refresh
331
332
333
     */
    Q_INVOKABLE void requestRefresh();

334
    /** @brief Show the asset of the given item in the AssetPanel
335
336
337
338
       If the id corresponds to a clip, we show the corresponding effect stack
       If the id corresponds to a composition, we show its properties
    */
    Q_INVOKABLE void showAsset(int id);
339
    Q_INVOKABLE void showTrackAsset(int trackId);
340
    /** @brief Adjust height of all similar (audio or video) tracks
341
342
    */
    Q_INVOKABLE void adjustAllTrackHeight(int trackId, int height);
343
    Q_INVOKABLE void collapseAllTrackHeight(int trackId, bool collapse, int collapsedHeight);
344

Eugen Mohr's avatar
Eugen Mohr committed
345
    /** @brief Reset track \@trackId height to default track height. Adjusts all tracks if \@trackId == -1
346
347
348
    */
    Q_INVOKABLE void defaultTrackHeight(int trackId);

349
    Q_INVOKABLE bool exists(int itemId);
350

351
352
353
    Q_INVOKABLE int headerWidth() const;
    Q_INVOKABLE void setHeaderWidth(int width);

354
    /** @brief Seek to next snap point
355
356
     */
    void gotoNextSnap();
357
    /** @brief Seek to previous snap point
358
359
     */
    void gotoPreviousSnap();
360
    /** @brief Seek to previous guide
361
362
     */
    void gotoPreviousGuide();
363
    /** @brief Seek to next guide
364
365
366
     */
    void gotoNextGuide();

367
    /** @brief Set current item's start point to cursor position
368
369
     */
    void setInPoint();
370
    /** @brief Set current item's end point to cursor position
371
372
     */
    void setOutPoint();
373
    /** @brief Return the project's tractor
374
375
     */
    Mlt::Tractor *tractor();
376
    /** @brief Return a track's producer
377
378
     */
    Mlt::Producer trackProducer(int tid);
379
    /** @brief Get the list of currently selected clip id's
380
381
     */
    QList<int> selection() const;
382
    /** @brief Returns the id of the currently selected mix's clip, -1 if no mix selected
383
384
     */
    int selectedMix() const;
385

386
    /** @brief Add an asset (effect, composition)
387
     */
Nicolas Carion's avatar
Nicolas Carion committed
388
    void addAsset(const QVariantMap &data);
389

390
    /** @brief Cuts the clip on current track at timeline position
391
     */
392
    Q_INVOKABLE void cutClipUnderCursor(int position = -1, int track = -1);
393
    /** @brief Cuts all clips at timeline position
394
395
     */
    Q_INVOKABLE void cutAllClipsUnderCursor(int position = -1);
396
    /** @brief Request a spacer operation
397
     */
398
    Q_INVOKABLE int requestSpacerStartOperation(int trackId, int position);
399
400
401
    /** @brief Returns the minimum available position for a spacer operation
     */
    Q_INVOKABLE int spacerMinPos() const;
402
403
404
405
406
407
408
409
410
    /** @brief Get a list of guides Id after a given frame
     */
    Q_INVOKABLE QVector<int> spacerSelection(int startFrame);
    /** @brief Move a list of guides from a given offset
     */
    Q_INVOKABLE void spacerMoveGuides(QVector<int> ids, int offset);
    /** @brief Get the position of the first marker in the list
     */
    Q_INVOKABLE int getGuidePosition(int ids);
411
    /** @brief Request a spacer operation
412
     */
413
    Q_INVOKABLE bool requestSpacerEndOperation(int clipId, int startPosition, int endPosition, int affectedTrack, QVector<int> selectedGuides = QVector<int>(), int guideStart = -1);
414
    /** @brief Request a Fade in effect for clip
415
     */
416
    Q_INVOKABLE void adjustFade(int cid, const QString &effectId, int duration, int initialDuration);
417

418
    Q_INVOKABLE const QString getTrackNameFromMltIndex(int trackPos);
419
    /** @brief Request inserting space in a track
420
     */
421
422
    Q_INVOKABLE void insertSpace(int trackId = -1, int frame = -1);
    Q_INVOKABLE void removeSpace(int trackId = -1, int frame = -1, bool affectAllTracks = false);
423
    /** @brief If clip is enabled, disable, otherwise enable
424
     */
425
    Q_INVOKABLE void switchEnableState(std::unordered_set<int> selection = {});
426
427
    Q_INVOKABLE void addCompositionToClip(const QString &assetId, int clipId = -1, int offset = -1);
    Q_INVOKABLE void addEffectToClip(const QString &assetId, int clipId = -1);
428
429
430

    Q_INVOKABLE void requestClipCut(int clipId, int position);

431
432
433
434
435
436
    /** @brief Extract (delete + remove space) current clip
     */
    void extract(int clipId = -1);
    /** @brief Save current clip cut as bin subclip
     */
    void saveZone(int clipId = -1);
437

438
    Q_INVOKABLE void splitAudio(int clipId);
439
    Q_INVOKABLE void splitVideo(int clipId);
440
441
    Q_INVOKABLE void setAudioRef(int clipId = -1);
    Q_INVOKABLE void alignAudio(int clipId = -1);
442
    Q_INVOKABLE void urlDropped(QStringList droppedFile, int frame, int tid);
443
444

    Q_INVOKABLE bool endFakeMove(int clipId, int position, bool updateView, bool logUndo, bool invalidateTimeline);
445
    Q_INVOKABLE int getItemMovingTrack(int itemId) const;
446
447
    bool endFakeGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, bool logUndo);
    bool endFakeGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, bool finalMove, Fun &undo, Fun &redo);
448

449
    bool splitAV();
450

451
    /** @brief Seeks to selected clip start / end
452
     */
453
    Q_INVOKABLE void pasteEffects(int targetId = -1);
454
    Q_INVOKABLE void deleteEffects(int targetId = -1);
455
    Q_INVOKABLE double fps() const;
456
457
    Q_INVOKABLE void addEffectKeyframe(int cid, int frame, double val);
    Q_INVOKABLE void removeEffectKeyframe(int cid, int frame);
Nicolas Carion's avatar
Nicolas Carion committed
458
    Q_INVOKABLE void updateEffectKeyframe(int cid, int oldFrame, int newFrame, const QVariant &normalizedValue = QVariant());
459
    Q_INVOKABLE bool hasKeyframeAt(int cid, int frame);
460

461
    /** @brief Make current timeline track active/inactive*/
462
    Q_INVOKABLE void switchTrackActive(int trackId = -1);
463
    /** @brief Toggle the active/inactive state of all tracks*/
464
    void switchAllTrackActive();
465
466
    /** @brief Make all tracks active or inactive */
    void makeAllTrackActive();
467
468
    void switchTrackLock(bool applyToAll = false);
    void switchTargetTrack();
469

470
    const QString getTrackNameFromIndex(int trackIndex);
471
    /** @brief Seeks to selected clip start / end
472
473
     */
    void seekCurrentClip(bool seekToEnd = false);
474
    /** @brief Seeks to a clip start (or end) based on it's clip id
475
476
     */
    void seekToClip(int cid, bool seekToEnd);
477
    /** @brief Returns true if timeline cursor is inside the item
478
479
     */
    bool positionIsInItem(int id);
480
    /** @brief Returns the number of tracks (audioTrakcs, videoTracks)
481
     */
482
    QPair<int, int>getTracksCount() const;
483
    /** @brief Request monitor refresh if item (clip or composition) is under timeline cursor
484
485
     */
    void refreshItem(int id);
486
    /** @brief Seek timeline to mouse position
487
488
     */
    void seekToMouse();
489

490
    /** @brief Set a property on the active track
491
     */
492
    void setActiveTrackProperty(const QString &name, const QString &value);
493
    /** @brief Get a property on the active track
494
495
     */
    const QVariant getActiveTrackProperty(const QString &name) const;
496
    /** @brief Is the active track audio
497
498
     */
    bool isActiveTrackAudio() const;
499

500
    /** @brief Returns a list of all luma files used in the project
501
502
     */
    QStringList extractCompositionLumas() const;
Julius Künzel's avatar
Julius Künzel committed
503
504
505
    /** @brief Returns a list of all external files used by effects in the timeline
     */
    QStringList extractExternalEffectFiles() const;
506
    /** @brief Get the frame where mouse is positioned
507
508
     */
    int getMousePos();
509
    /** @brief Get the frame where mouse is positioned
510
511
     */
    int getMouseTrack();
512
    /** @brief Returns a map of track ids/track names
513
514
     */
    QMap<int, QString> getTrackNames(bool videoOnly);
515
    /** @brief Returns the transition a track index for a composition (MLT index / Track id)
516
     */
Nicolas Carion's avatar
Nicolas Carion committed
517
    QPair<int, int> getCompositionATrack(int cid) const;
518
    void setCompositionATrack(int cid, int aTrack);
519
    /** @brief Return true if composition's a_track is automatic (no forced track)
520
521
     */
    bool compositionAutoTrack(int cid) const;
522
    const QString getClipBinId(int clipId) const;
523
    void focusItem(int itemId);
524
    /** @brief Create and display a split clip view to compare effect
525
     */
526
    bool createSplitOverlay(int clipId, std::shared_ptr<Mlt::Filter> filter);
527
    /** @brief Delete the split clip view to compare effect
528
529
     */
    void removeSplitOverlay();
530
    /** @brief Add current timeline zone to preview rendering
531
532
     */
    void addPreviewRange(bool add);
533
    /** @brief Clear current timeline zone from preview rendering
534
     */
535
    void clearPreviewRange(bool resetZones);
536
537
538
539
    void startPreviewRender();
    void stopPreviewRender();
    QVariantList dirtyChunks() const;
    QVariantList renderedChunks() const;
540
    /** @brief returns the frame currently processed by timeline preview, -1 if none
541
     */
542
    int workingPreview() const;
543
544

    /** @brief Return true if we want to use timeline ruler zone for editing */
545
    bool useRuler() const;
Pistos Pi's avatar
Pistos Pi committed
546
547
548
549

    /** @brief Return true if the scroll wheel should scroll vertically (Shift key for horizontal); false if it should scroll horizontally (Shift for vertical) */
    bool scrollVertically() const;

550
    /** @brief Load timeline preview from saved doc
551
     */
Nicolas Carion's avatar
Nicolas Carion committed
552
    void loadPreview(const QString &chunks, const QString &dirty, const QDateTime &documentDate, int enable);
553
    /** @brief Return document properties with added settings from timeline
554
555
     */
    QMap<QString, QString> documentProperties();
556
557
558
559
560

    /** @brief Change track compsiting mode */
    void switchCompositing(int mode);

    /** @brief Change a clip item's speed in timeline */
561
    Q_INVOKABLE void changeItemSpeed(int clipId, double speed);
562
563
    /** @brief Activate time remap on the clip */
    void remapItemTime(int clipId, double speed);
564
565
566
567
    /** @brief Delete selected zone and fill gap by moving following clips
     *  @param lift if true, the zone will simply be deleted but clips won't be moved
     */
    void extractZone(QPoint zone, bool liftOnly = false);
568
569
570
    /** @brief Insert clip monitor into timeline
     *  @returns the zone end position or -1 on fail
     */
571
    Q_INVOKABLE bool insertClipZone(const QString &binId, int tid, int pos);
572
    int insertZone(const QString &binId, QPoint zone, bool overwrite);
Nicolas Carion's avatar
Nicolas Carion committed
573
    void updateClip(int clipId, const QVector<int> &roles);
574
    void showClipKeyframes(int clipId, bool value);
575
    void showCompositionKeyframes(int clipId, bool value);
576
577
    /** @brief Adjust all timeline tracks height */
    void resetTrackHeight();
578
579
    /** @brief timeline preview params changed, reset */
    void resetPreview();
580
    /** @brief Set target tracks (video, audio) */
581
    void setTargetTracks(bool hasVideo, QMap <int, QString> audioTargets);
582
583
    /** @brief Restore Bin Clip original target tracks (video, audio) */
    void restoreTargetTracks();
584
    /** @brief Return asset's display name from it's id (effect or composition) */
585
    Q_INVOKABLE const QString getAssetName(const QString &assetId, bool isTransition);
586
    /** @brief Set keyboard grabbing on current selection */
587
    Q_INVOKABLE void grabCurrent();
588
589
    /** @brief Returns keys for all used thumbnails */
    QStringList getThumbKeys();
590
591
    /** @brief Returns true if a drag operation is currently running in timeline */
    bool dragOperationRunning();
592
593
    /** @brief Disconnect some stuff before closing project */
    void prepareClose();
594
595
    /** @brief Check that we don't keep a deleted track id */
    void checkTrackDeletion(int selectedTrackIx);
596
597
598
    /** @brief Return true if an overlay track is used */
    bool hasPreviewTrack() const;
    void updatePreviewConnection(bool enable);
599
600
    /** @brief Display project master effects */
    Q_INVOKABLE void showMasterEffects();
601
    /** @brief Return true if an instance of this bin clip is currently under timeline cursor */
602
    bool refreshIfVisible(int cid);
603
604
    /** @brief Collapse / expand active track */
    void collapseActiveTrack();
605
606
    /** @brief Expand MLT playlist to its contained clips/compositions */
    void expandActiveClip();
607
608
609
610
    /** @brief Retrieve a list of possible audio stream targets */
    QMap <int, QString> getCurrentTargets(int trackId, int &activeTargetStream);
    /** @brief Define audio stream target for a track index */
    void assignAudioTarget(int trackId, int stream);
611
612
    /** @brief Define a stream target for current track from the stream index */
    void assignCurrentTarget(int index);
Vincent Pinon's avatar
Vincent Pinon committed
613
614
    /** @brief Get the first unassigned target audio stream. */
    int getFirstUnassignedStream() const;
615

616
617
    /** @brief Add tracks to project */
    void addTracks(int videoTracks, int audioTracks);
618
619
    /** @brief Get in/out of currently selected items */
    QPoint selectionInOut() const;
620
621
    /** @brief Create a mix transition with currently selected clip. If delta = -1, mix with previous clip, +1 with next clip and 0 will check cursor position*/
    Q_INVOKABLE void mixClip(int cid = -1, int delta = 0);
622
623
    /** @brief Temporarily un/plug a list of clips in timeline. */
    void temporaryUnplug(QList<int> clipIds, bool hide);
624
625
626
    /** @brief Edit the subtitle text*/
    Q_INVOKABLE void editSubtitle(int startFrame, int endFrame, QString newText, QString oldText);
    /** @brief Edit the subtitle end */
627
    Q_INVOKABLE void resizeSubtitle(int startFrame, int endFrame, int oldEndFrame, bool refreshModel);
628
    /** @brief Add subtitle clip at cursor's position in timeline */
629
    Q_INVOKABLE void addSubtitle(int startframe = -1, QString text = QString());
Eugen Mohr's avatar
Eugen Mohr committed
630
    /** @brief Cut a subtitle and split the text at \@param pos */
631
    void cutSubtitle(int id, int cursorPos);
632
    /** @brief Delete subtitle clip with frame as start position*/
633
    Q_INVOKABLE void deleteSubtitle(int frameframe, int endframe, QString Ctext);
634
    /** @brief Import a subtitle file*/
635
    void importSubtitle(const QString path = QString());
636
637
    /** @brief Export a subtitle file*/
    void exportSubtitle();
638
639
    /** @brief Launch speech recognition on timeline zone*/
    void subtitleSpeechRecognition();
640
641
    /** @brief Show active effect zone for current effect*/
    void showRulerEffectZone(QPair <int, int>inOut, bool checked);
642
643
    /** @brief Set the list of master effect zones */
    void updateMasterZones(QVariantList zones);
644
645
    /** @brief get Maximum duration of a clip */
    int clipMaxDuration(int cid);
646

647
public slots:
648
    void resetView();
649
650
    void setAudioTarget(QMap<int, int> tracks);
    Q_INVOKABLE void switchAudioTarget(int trackId);
651
    Q_INVOKABLE void setVideoTarget(int track);
652
    Q_INVOKABLE void setActiveTrack(int track);
653
    void addEffectToCurrentClip(const QStringList &effectData);
654
655
    /** @brief Dis / enable timeline preview. */
    void disablePreview(bool disable);
656
    void invalidateItem(int cid);
657
    void invalidateTrack(int tid);
658
    void invalidateZone(int in, int out);
659
    void checkDuration();
660
    /** @brief Dis / enable multi track view. */
661
    void slotMultitrackView(bool enable = true, bool refresh = true);
662
663
    /** @brief Activate a video track by its position (0 = topmost). */
    void activateTrackAndSelect(int trackPosition);
664
    /** @brief Save timeline selected clips to target folder. */
Nicolas Carion's avatar
Nicolas Carion committed
665
    void saveTimelineSelection(const QDir &targetDir);
666
667
    /** @brief Restore timeline scroll pos on open. */
    void setScrollPos(int pos);
668
    /** @brief Request resizing currently selected mix. */
669
670
671
    void resizeMix(int cid, int duration, MixAlignment align);
    /** @brief Get align info for a mix. */
    MixAlignment getMixAlign(int cid) const;
672
673
    /** @brief change zone info with undo. */
    Q_INVOKABLE void updateZone(const QPoint oldZone, const QPoint newZone, bool withUndo = true);
674
    Q_INVOKABLE void updateEffectZone(const QPoint oldZone, const QPoint newZone, bool withUndo = true);
675

676
private slots:
677
    void updateClipActions();
678
679
    void updateVideoTarget();
    void updateAudioTarget();
680
681
    /** @brief Dis / enable multi track view. */
    void updateMultiTrack();
682
683
684

public:
    /** @brief a list of actions that have to be enabled/disabled depending on the timeline selection */
685
    QList<QAction *> clipActions;
686

687
private:
688
    QQuickItem *m_root;
689
690
    KActionCollection *m_actionCollection;
    std::shared_ptr<TimelineItemModel> m_model;
691
    bool m_usePreview;
692
693
    int m_audioTarget;
    int m_videoTarget;
694
    int m_audioRef;
695
    int m_hasAudioTarget {0};
696
    bool m_hasVideoTarget {false};
697
    int m_lastVideoTarget {-1};
698
699
    /** @brief The last combination of audio targets in the form: {timeline track id, bin stream index} */
    QMap <int, int> m_lastAudioTarget;
700
701
    bool m_videoTargetActive {true};
    bool m_audioTargetActive {true};
702
    QPair<int, int> m_recordStart;
703
    int m_recordTrack;
704
    QPoint m_zone;
705
    int m_activeTrack;
706
707
    double m_scale;
    static int m_duration;
708
709
    PreviewManager *m_timelinePreview;
    QAction *m_disablePreview;
710
    std::shared_ptr<AudioCorrelation> m_audioCorrelator;
711
    QMutex m_metaMutex;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
712
    bool m_ready;
713
    std::vector<int> m_activeSnaps;
714
    int m_snapStackIndex;
715
    QMetaObject::Connection m_connection;
716
    QMetaObject::Connection m_deleteConnection;
717
    QPoint m_effectZone;
718
    QVariantList m_masterEffectZones;
719

720
    void initializePreview();
721
    bool darkBackground() const;
722
    int getMenuOrTimelinePos() const;
723
724
725
726

signals:
    void selected(Mlt::Producer *producer);
    void selectionChanged();
727
    void selectedMixChanged();
728
729
730
731
    void frameFormatChanged();
    void trackHeightChanged();
    void scaleFactorChanged();
    void audioThumbFormatChanged();
732
    void audioThumbNormalizeChanged();
733
    void durationChanged();
734
735
    void audioTargetChanged();
    void videoTargetChanged();
736
737
738
    void hasAudioTargetChanged();
    void hasVideoTargetChanged();
    void lastAudioTargetChanged();
739
    void autoScrollChanged();
740
    void lastVideoTargetChanged();
741
    void activeTrackChanged();
742
    void colorsChanged();
743
744
745
746
747
748
    void showThumbnailsChanged();
    void showAudioThumbnailsChanged();
    void showMarkersChanged();
    void rippleChanged();
    void scrubChanged();
    void seeked(int position);
749
750
    void zoneChanged();
    void zoneMoved(const QPoint &zone);
751
    /** @brief Requests that a given parameter model is displayed in the asset panel */
752
    void showTransitionModel(int tid, std::shared_ptr<AssetParameterModel>);
753
    /** @brief Requests that a given mix is displayed in the asset panel */
754
    void showMixModel(int cid, const std::shared_ptr<AssetParameterModel> &asset);
755
    void showItemEffectStack(const QString &clipName, std::shared_ptr<EffectStackModel>, QSize frameSize, bool showKeyframes);
756
    void showSubtitle(int id);
757
    /** @brief notify of chunks change
758
759
760
761
     */
    void dirtyChunksChanged();
    void renderedChunksChanged();
    void workingPreviewChanged();
762
763
    void subtitlesDisable