File indexing completed on 2024-04-21 04:52:00
0001 /* 0002 SPDX-FileCopyrightText: 2014 Till Theato <root@ttill.de> 0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 #pragma once 0007 0008 #include "kdenlivecore_export.h" 0009 #include <KRecentFilesAction> 0010 #include <QDir> 0011 #include <QObject> 0012 #include <QTime> 0013 #include <QTimer> 0014 #include <QUrl> 0015 #include <QElapsedTimer> 0016 0017 #include "timeline2/model/timelineitemmodel.hpp" 0018 0019 #include <memory> 0020 #include <unordered_map> 0021 #include <unordered_set> 0022 0023 class KAutoSaveFile; 0024 class KJob; 0025 class KdenliveDoc; 0026 class MarkerListModel; 0027 class NotesPlugin; 0028 class Project; 0029 class QAction; 0030 class QProgressDialog; 0031 class QUrl; 0032 class DocUndoStack; 0033 class TimelineWidget; 0034 0035 /** @class ProjectManager 0036 @brief Takes care of interaction with projects. 0037 */ 0038 class /*KDENLIVECORE_EXPORT*/ ProjectManager : public QObject 0039 { 0040 Q_OBJECT 0041 0042 public: 0043 friend class RenderRequest; 0044 /** @brief Sets up actions to interact for project interaction (undo, redo, open, save, ...) and creates an empty project. */ 0045 explicit ProjectManager(QObject *parent = nullptr); 0046 ~ProjectManager() override; 0047 0048 /** @brief Returns a pointer to the currently opened project. A project should always be open. 0049 The method is virtual to allow mocking 0050 */ 0051 virtual KdenliveDoc *current(); 0052 0053 /** @brief Store command line args for later opening. */ 0054 void init(const QUrl &projectUrl, const QString &clipList); 0055 0056 void doOpenFile(const QUrl &url, KAutoSaveFile *stale, bool isBackup = false); 0057 void doOpenFileHeadless(const QUrl &url); 0058 KRecentFilesAction *recentFilesAction(); 0059 void prepareSave(); 0060 /** @brief Disable all bin effects in current project 0061 * @param disable if true, all project bin effects will be disabled 0062 * @param refreshMonitor if false, monitors will not be refreshed 0063 */ 0064 void disableBinEffects(bool disable, bool refreshMonitor = true); 0065 /** @brief Returns current project's xml scene */ 0066 QString projectSceneList(const QString &outputFolder, const QString &overlayData = QString()); 0067 /** @brief returns a default hd profile depending on timezone*/ 0068 static QString getDefaultProjectFormat(); 0069 void saveZone(const QStringList &info, const QDir &dir); 0070 /** @brief Move project data files to new url */ 0071 void moveProjectData(const QString &src, const QString &dest); 0072 /** @brief Retrieve current project's notes */ 0073 QString documentNotes() const; 0074 0075 /** @brief Retrieve the current Guide Model 0076 The method is virtual to allow mocking 0077 */ 0078 virtual std::shared_ptr<MarkerListModel> getGuideModel(); 0079 0080 /** @brief Return the current undo stack 0081 The method is virtual to allow mocking 0082 */ 0083 virtual std::shared_ptr<DocUndoStack> undoStack(); 0084 0085 virtual const QDir cacheDir(bool audio, bool *ok) const; 0086 0087 /** @brief This will create a backup file with fps appended to project name, 0088 * and save the project with an updated profile info, then reopen it. 0089 */ 0090 void saveWithUpdatedProfile(const QString &updatedProfile); 0091 0092 /** @brief Get the number of tracks in this project (video, audio). 0093 */ 0094 QPair<int, int> avTracksCount(); 0095 0096 /** @brief Add requested audio tracks number to project. 0097 */ 0098 void addAudioTracks(int tracksCount); 0099 /** @brief This method is only there for tests, do not use in real app. 0100 */ 0101 void testSetActiveDocument(KdenliveDoc *doc, std::shared_ptr<TimelineItemModel> timeline = nullptr); 0102 /** @brief This method is only there for tests, do not use in real app. 0103 */ 0104 bool testSaveFileAs(const QString &outputFileName); 0105 /** @brief Retrieve the current timeline (mostly used for testing. 0106 */ 0107 std::shared_ptr<TimelineItemModel> getTimeline(); 0108 /** @brief Initialize a new timeline's default properties. 0109 */ 0110 void initSequenceProperties(const QUuid &uuid, std::pair<int, int> tracks); 0111 /** @brief Open a timeline clip in a tab. 0112 * @returns true if the timeline was not previously opened 0113 */ 0114 bool openTimeline(const QString &id, const QUuid &uuid, int position = -1, bool duplicate = false, 0115 std::shared_ptr<TimelineItemModel> existingModel = nullptr); 0116 /** @brief Set a property on timeline uuid 0117 */ 0118 void setTimelinePropery(QUuid uuid, const QString &prop, const QString &val); 0119 /** @brief Get the count of timelines in this project 0120 */ 0121 int getTimelinesCount() const; 0122 0123 void activateDocument(const QUuid &uuid); 0124 /** @brief Close a timeline tab through its uuid 0125 */ 0126 bool closeTimeline(const QUuid &uuid, bool onDeletion = false, bool clearUndo = true); 0127 /** @brief Update a timeline sequence before saving or extracting xml 0128 */ 0129 void syncTimeline(const QUuid &uuid, bool refresh = false); 0130 void doSyncTimeline(std::shared_ptr<TimelineItemModel> model, bool refresh); 0131 void setActiveTimeline(const QUuid &uuid); 0132 /** @brief Replace all instance of a @param sourceId clip with another @param replacementId in the active timline sequence 0133 * @param replaceAudio if true, only the audio clips will be replaced. if false, only the video parts. 0134 */ 0135 void replaceTimelineInstances(const QString &sourceId, const QString &replacementId, bool replaceAudio, bool replaceVideo); 0136 0137 public Q_SLOTS: 0138 void newFile(QString profileName, bool showProjectSettings = true); 0139 void newFile(bool showProjectSettings = true); 0140 /** @brief Shows file open dialog. */ 0141 void openFile(); 0142 void openLastFile(); 0143 /** @brief Load files / clips passed on the command line. */ 0144 void slotLoadOnOpen(); 0145 0146 void slotLoadHeadless(const QUrl &projectUrl); 0147 0148 /** @brief Checks whether a URL is available to save to. 0149 * @return Whether the file was saved. */ 0150 bool saveFile(); 0151 0152 /** @brief Shows a save file dialog for saving the project. 0153 * @param saveACopy Default is false. If true, the file title of the dialog is set to "Save Copy…" 0154 * @return Whether the file was saved. */ 0155 bool saveFileAs(bool saveACopy = false); 0156 0157 /** @brief Set properties to match outputFileName and save the document. 0158 * Creates an autosave version of the output file too (only if not in copymode), at 0159 * ~/.kde/data/stalefiles/kdenlive/ \n 0160 * that will be actually written in KdenliveDoc::slotAutoSave() 0161 * @param outputFileName The URL to save to / The document's URL. 0162 * @param saveACopy Default is false. If true, the file will be saved but isn’t opened afterwards. Besides no autosave version will be created 0163 * @return Whether we had success. */ 0164 bool saveFileAs(const QString &outputFileName, bool saveOverExistingFile = true, bool saveACopy = false); 0165 0166 /** @brief Close currently opened document. Returns false if something went wrong (cannot save modifications, ...). */ 0167 bool closeCurrentDocument(bool saveChanges = true, bool quit = false); 0168 0169 /** @brief Prepares opening @param url. 0170 * 0171 * Checks if already open and whether backup exists */ 0172 void openFile(const QUrl &url); 0173 0174 /** @brief Start autosave timer */ 0175 void slotStartAutoSave(); 0176 0177 /** @brief Update project and monitors profiles */ 0178 void slotResetProfiles(bool reloadThumbs); 0179 0180 /** @brief Rebuild consumers after a property change */ 0181 void slotResetConsumers(bool fullReset); 0182 0183 /** @brief Dis/enable all timeline effects */ 0184 void slotDisableTimelineEffects(bool disable); 0185 0186 /** @brief Mute/Unmute or Hide/Show current timeline track */ 0187 void slotSwitchTrackDisabled(); 0188 /** @brief Un/Lock current timeline track */ 0189 void slotSwitchTrackLock(); 0190 void slotSwitchAllTrackLock(); 0191 0192 /** @brief Make current timeline track active/inactive*/ 0193 void slotSwitchTrackActive(); 0194 /** @brief Toggle the active/inactive state of all tracks*/ 0195 void slotSwitchAllTrackActive(); 0196 /** @brief Make all tracks active or inactive */ 0197 void slotMakeAllTrackActive(); 0198 /** @brief Restore current clip target tracks */ 0199 void slotRestoreTargetTracks(); 0200 0201 /** @brief Un/Set current track as target */ 0202 void slotSwitchTrackTarget(); 0203 0204 /** @brief Set the text for current project's notes */ 0205 void setDocumentNotes(const QString ¬es); 0206 0207 /** @brief Project's duration changed, adjust monitor, etc. */ 0208 void adjustProjectDuration(int duration); 0209 /** @brief Add an asset in timeline (effect, transition). */ 0210 void activateAsset(const QVariantMap &effectData); 0211 /** @brief insert current timeline timecode in notes widget and focus widget to allow entering quick note */ 0212 void slotAddProjectNote(); 0213 /** @brief insert license text in notes widget and focus widget to allow entering quick note. Virtual to allow Mocking */ 0214 virtual void slotAddTextNote(const QString &text); 0215 /** @brief Open a timeline with a reference to a track / position. */ 0216 void seekTimeline(const QString &frameAndTrack); 0217 /** @brief Create a sequence clip from timeline selection. */ 0218 void slotCreateSequenceFromSelection(); 0219 0220 private Q_SLOTS: 0221 void slotRevert(); 0222 /** @brief A timeline sequence duration changed, update our properties. */ 0223 void updateSequenceDuration(const QUuid &uuid); 0224 /** @brief Open the project's backupdialog. */ 0225 bool slotOpenBackup(const QUrl &url = QUrl()); 0226 /** @brief Start autosaving the document. */ 0227 void slotAutoSave(); 0228 /** @brief Report progress of folder move operation. */ 0229 void slotMoveProgress(KJob *, unsigned long progress); 0230 void slotMoveFinished(KJob *job); 0231 0232 Q_SIGNALS: 0233 void docOpened(KdenliveDoc *document); 0234 0235 protected: 0236 /** @brief Update the timeline according to the MLT XML */ 0237 bool updateTimeline(bool createNewTab, const QString &chunks, const QString &dirty, const QDateTime &documentDate, bool enablePreview); 0238 KdenliveDoc *m_project{nullptr}; 0239 0240 private: 0241 /** @brief checks if autoback files exists, recovers from it if user says yes, returns true if files were recovered. */ 0242 bool checkForBackupFile(const QUrl &url, bool newFile = false); 0243 /** @brief Update the sequence producer stored in the project model. */ 0244 void updateSequenceProducer(const QUuid &uuid, std::shared_ptr<Mlt::Producer> prod); 0245 0246 std::shared_ptr<TimelineItemModel> m_activeTimelineModel; 0247 QElapsedTimer m_lastSave; 0248 QTimer m_autoSaveTimer; 0249 QUrl m_startUrl; 0250 QString m_loadClipsOnOpen; 0251 QMap<QString, QString> m_replacementPattern; 0252 0253 QAction *m_fileRevert; 0254 KRecentFilesAction *m_recentFilesAction; 0255 NotesPlugin *m_notesPlugin; 0256 void saveRecentFiles(); 0257 /** @brief Something went wrong, stop loading file */ 0258 void abortLoading(); 0259 /** @brief Project loading failed, ask user if he wants to open a backup */ 0260 void requestBackup(const QString &errorMessage); 0261 /** @brief WHen building a sequence producer, ensure we pass along all properties */ 0262 void passSequenceProperties(const QUuid &uuid, std::shared_ptr<Mlt::Producer> prod, Mlt::Tractor tractor, std::shared_ptr<TimelineItemModel> timelineModel, 0263 TimelineWidget *timelineWidget); 0264 /** @brief Ensure sequences are correctly stored in our project model */ 0265 void checkProjectIntegrity(); 0266 };