File indexing completed on 2024-04-14 04:47:07

0001 
0002 /*
0003 SPDX-FileCopyrightText: 2017 Jean-Baptiste Mardelle <jb@kdenlive.org>
0004 This file is part of Kdenlive. See www.kdenlive.org.
0005 
0006 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0007 */
0008 
0009 #pragma once
0010 
0011 #include "definitions.h"
0012 #include "undohelper.hpp"
0013 #include <memory>
0014 #include <unordered_set>
0015 #include <unordered_map>
0016 
0017 #include <QDir>
0018 
0019 class TimelineItemModel;
0020 
0021 /** @namespace TimelineFunction
0022     @brief This namespace contains a list of static methods for advanced timeline editing features
0023     based on timelinemodel methods
0024  */
0025 struct TimelineFunctions
0026 {
0027     /** @brief Cuts a clip at given position
0028        If the clip is part of the group, all clips of the groups are cut at the same position. The group structure is then preserved for clips on both sides
0029        Returns true on success
0030        @param timeline : ptr to the timeline model
0031        @param clipId: Id of the clip to split
0032        @param position: position (in frames from the beginning of the timeline) where to cut
0033     */
0034 
0035     struct TimelineTracksInfo {
0036         QList<int> audioIds;
0037         QList<int> videoIds;
0038     };
0039 
0040     static bool requestClipCut(std::shared_ptr<TimelineItemModel> timeline, int clipId, int position);
0041     /** @brief This is the same function, except that it accumulates undo/redo */
0042     static bool requestClipCut(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, int position, Fun &undo, Fun &redo);
0043     /** @brief This is the same function, except that it accumulates undo/redo and do not deal with groups. Do not call directly */
0044     static bool processClipCut(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, int position, int &newId, Fun &undo, Fun &redo);
0045 
0046     /** @brief Cuts all clips at given position */
0047     static bool requestClipCutAll(std::shared_ptr<TimelineItemModel> timeline, int position);
0048 
0049     /** @brief Makes a perfect clone of a given clip, but do not insert it */
0050     static bool cloneClip(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, int &newId, PlaylistState::ClipState state, Fun &undo, Fun &redo);
0051 
0052     /** @brief Creates a string representation of the given clips, that can then be pasted using pasteClips(). Return an empty string on failure */
0053     static QString copyClips(const std::shared_ptr<TimelineItemModel> &timeline, const std::unordered_set<int> &itemIds);
0054 
0055     /** @brief Paste the clips as described by the string. Returns true on success*/
0056     static bool pasteClips(const std::shared_ptr<TimelineItemModel> &timeline, const QString &pasteString, int trackId, int position);
0057     static bool pasteClips(const std::shared_ptr<TimelineItemModel> &timeline, const QString &pasteString, int trackId, int position, Fun &undo, Fun &redo,
0058                            int inPos = 0, int duration = -1);
0059     static bool pasteClipsWithUndo(const std::shared_ptr<TimelineItemModel> &timeline, const QString &pasteString, int trackId, int position, Fun &undo,
0060                                    Fun &redo);
0061     static bool pasteTimelineClips(const std::shared_ptr<TimelineItemModel> &timeline, const QDomDocument &copiedItems, int position, int inPos = 0,
0062                                    int duration = -1);
0063     static bool pasteTimelineClips(const std::shared_ptr<TimelineItemModel> &timeline, QDomDocument copiedItems, int position, Fun &timeline_undo,
0064                                    Fun &timeline_redo, bool pushToStack, int inPos = 0, int duration = -1);
0065 
0066     /** @brief Request the addition of multiple clips to the timeline
0067      * If the addition of any of the clips fails, the entire operation is undone.
0068      * @returns true on success, false otherwise.
0069      * @param binIds the list of bin ids to be inserted
0070      * @param trackId the track where the insertion should happen
0071      * @param position the position at which the clips should be inserted
0072      * @param clipIds a return parameter with the ids assigned to the clips if success, empty otherwise
0073      */
0074     static bool requestMultipleClipsInsertion(const std::shared_ptr<TimelineItemModel> &timeline, const QStringList &binIds, int trackId, int position,
0075                                               QList<int> &clipIds, bool logUndo, bool refreshView);
0076 
0077     /** @brief This function will find the blank located in the given track at the given position and remove it
0078         @returns true on success, false otherwise
0079         @param trackId id of the track to search in
0080         @param position of the blank
0081         @param affectAllTracks if true, the same blank will be removed from all tracks. Note that all the tracks must have a blank at least that big in that
0082        position
0083     */
0084     static bool requestDeleteBlankAt(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, int position, bool affectAllTracks);
0085 
0086     /** @brief This function will delete all blanks on the given track after the given position
0087         @returns true on success, false otherwise
0088         @param trackId id of the track to search in
0089         @param position of the blank
0090     */
0091     static bool requestDeleteAllBlanksFrom(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, int position);
0092 
0093     /** @brief This function will delete all clips on the given track after the given position
0094         @returns true on success, false otherwise
0095         @param trackId id of the track to search in
0096         @param position start position for the operation
0097     */
0098     static bool requestDeleteAllClipsFrom(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, int position);
0099 
0100     /** @brief Starts a spacer operation. Should be used together with requestSpacerEndOperation
0101         @returns {clipId, max blank duration} of the position-wise first clip in the temporary group
0102         @param timeline TimelineItemModel where the operation should be performed on
0103         @param trackId
0104         @param position
0105         @param ignoreMultiTrackGroups
0106         @param allowGroupBreaking Whether independant move of grouped items is allowed
0107         @see requestSpacerEndOperation
0108     */
0109     static std::pair<int, int> requestSpacerStartOperation(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, int position,
0110                                                            bool ignoreMultiTrackGroups = false, bool allowGroupBreaking = false);
0111     /**
0112         @see requestSpacerStartOperation
0113         @param moveGuidesPosition if > -1, all guides after this position will be moved as well in the operation
0114      */
0115     static bool requestSpacerEndOperation(const std::shared_ptr<TimelineItemModel> &timeline, int itemId, int startPosition, int endPosition, int affectedTrack,
0116                                           int moveGuidesPosition, Fun &undo, Fun &redo, bool pushUndo = true);
0117     static bool extractZone(const std::shared_ptr<TimelineItemModel> &timeline, const QVector<int> &tracks, QPoint zone, bool liftOnly, int clipToUnGroup = -1,
0118                             std::unordered_set<int> clipsToRegroup = {});
0119     static bool extractZoneWithUndo(const std::shared_ptr<TimelineItemModel> &timeline, const QVector<int> &tracks, QPoint zone, bool liftOnly,
0120                                     int clipToUnGroup, std::unordered_set<int> clipsToRegroup, Fun &undo, Fun &redo);
0121     static bool liftZone(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, QPoint zone, Fun &undo, Fun &redo);
0122     static bool removeSpace(const std::shared_ptr<TimelineItemModel> &timeline, QPoint zone, Fun &undo, Fun &redo,
0123                             const QVector<int> &allowedTracks = QVector<int>(), bool useTargets = true);
0124 
0125     /** @brief This function will insert a blank space starting at zone.x, and ending at zone.y. This will affect all the tracks
0126         @returns true on success, false otherwise
0127     */
0128     static bool requestInsertSpace(const std::shared_ptr<TimelineItemModel> &timeline, QPoint zone, Fun &undo, Fun &redo,
0129                                    const QVector<int> &allowedTracks = QVector<int>());
0130     static bool insertZone(const std::shared_ptr<TimelineItemModel> &timeline, const QList<int> &trackIds, const QString &binId, int insertFrame, QPoint zone,
0131                            bool overwrite, bool useTargets = true);
0132     static bool insertZone(const std::shared_ptr<TimelineItemModel> &timeline, QList<int> trackIds, const QString &binId, int insertFrame, QPoint zone,
0133                            bool overwrite, bool useTargets, Fun &undo, Fun &redo);
0134 
0135     static bool requestItemCopy(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, int trackId, int position);
0136     static void showClipKeyframes(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, bool value);
0137     static void showCompositionKeyframes(const std::shared_ptr<TimelineItemModel> &timeline, int compoId, bool value);
0138 
0139     /** @brief If the clip is activated, disable, otherwise enable
0140      * @param timeline: pointer to the timeline that we modify
0141      * @param clipId: Id of the clip to modify
0142      * @param status: target status of the clip
0143      This function creates an undo object and returns true on success
0144      */
0145     static bool switchEnableState(const std::shared_ptr<TimelineItemModel> &timeline, std::unordered_set<int> selection);
0146     /** @brief change the clip state and accumulates for undo/redo
0147      */
0148     static bool changeClipState(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, PlaylistState::ClipState status, Fun &undo, Fun &redo);
0149 
0150     static bool requestSplitAudio(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, int audioTarget);
0151     static bool requestSplitVideo(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, int videoTarget);
0152     static void setCompositionATrack(const std::shared_ptr<TimelineItemModel> &timeline, int cid, int aTrack);
0153     static QStringList enableMultitrackView(const std::shared_ptr<TimelineItemModel> &timeline, bool enable, bool refresh);
0154     static void saveTimelineSelection(const std::shared_ptr<TimelineItemModel> &timeline, const std::unordered_set<int> &selection, const QDir &targetDir,
0155                                       int duration);
0156     /** @brief returns the number of same type tracks between 2 tracks
0157      */
0158     static int getTrackOffset(const std::shared_ptr<TimelineItemModel> &timeline, int startTrack, int destTrack);
0159     /** @brief returns an offset track id
0160      */
0161     static int getOffsetTrackId(const std::shared_ptr<TimelineItemModel> &timeline, int startTrack, int offset, bool audioOffset);
0162     /** @brief returns a list of ids for all audio tracks and all video tracks
0163      */
0164     static TimelineTracksInfo getAVTracksIds(const std::shared_ptr<TimelineItemModel> &timeline);
0165 
0166     /** @brief This function breaks group is an item in the zone is grouped with an item outside of selected tracks
0167      */
0168     static bool breakAffectedGroups(const std::shared_ptr<TimelineItemModel> &timeline, const QVector<int> &tracks, QPoint zone, Fun &undo, Fun &redo);
0169 
0170     /** @brief This function extracts the content of an xml playlist file and converts it to json paste format
0171      */
0172     static QDomDocument extractClip(const std::shared_ptr<TimelineItemModel> &timeline, int cid, const QString &binId);
0173 
0174     static int spacerMinPos();
0175 
0176 private:
0177     static bool getUsedTracks(const QDomNodeList &clips, const QDomNodeList &compositions, int masterSourceTrack, int &topAudioMirror, TimelineTracksInfo &allTracks, QList<int> &singleAudioTracks, std::unordered_map<int, int> &audioMirrors);
0178 };