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