File indexing completed on 2024-10-13 04:24:06
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 "definitions.h" 0009 #include "jobs/taskmanager.h" 0010 #include "kdenlivecore_export.h" 0011 #include "undohelper.hpp" 0012 #include "utils/timecode.h" 0013 #include <KSharedDataCache> 0014 #include <QColor> 0015 #include <QMutex> 0016 #include <QObject> 0017 #include <QPoint> 0018 #include <QTextEdit> 0019 #include <QThreadPool> 0020 #include <QUrl> 0021 #include <knewstuff_version.h> 0022 #include <memory> 0023 #include <unordered_set> 0024 0025 #include <mlt++/MltProfile.h> 0026 #include <mlt++/MltPlaylist.h> 0027 0028 class Bin; 0029 class DocUndoStack; 0030 class EffectStackModel; 0031 class KdenliveDoc; 0032 class LibraryWidget; 0033 class MainWindow; 0034 class MediaCapture; 0035 class MediaBrowser; 0036 class MixerManager; 0037 class Monitor; 0038 class MonitorManager; 0039 class ProfileModel; 0040 class ProjectItemModel; 0041 class ProjectManager; 0042 class SubtitleEdit; 0043 class SubtitleModel; 0044 class TextBasedEdit; 0045 class GuidesList; 0046 class TimeRemap; 0047 0048 namespace Mlt { 0049 class Repository; 0050 class Producer; 0051 } // namespace Mlt 0052 0053 #define EXIT_RESTART (42) 0054 #define EXIT_CLEAN_RESTART (43) 0055 #define pCore Core::self() 0056 0057 /** 0058 * @class Core 0059 * @brief Singleton that provides access to the different parts of Kdenlive 0060 * 0061 * Needs to be initialize before any widgets are created in MainWindow. 0062 * Plugins should be loaded after the widget setup. 0063 */ 0064 class /*KDENLIVECORE_EXPORT*/ Core : public QObject 0065 { 0066 Q_OBJECT 0067 0068 public: 0069 Core(const Core &) = delete; 0070 Core &operator=(const Core &) = delete; 0071 Core(Core &&) = delete; 0072 Core &operator=(Core &&) = delete; 0073 0074 ~Core() override; 0075 0076 /** 0077 * @brief Setup the basics of the application, in particular the connection 0078 * with Mlt 0079 * @param MltPath (optional) path to MLT environment 0080 */ 0081 static bool build(const QString &packageType, bool testMode = false); 0082 0083 void initHeadless(const QUrl &url); 0084 0085 /** 0086 * @brief Init the GUI part of the app and show the main window 0087 * @param inSandbox does the app run in a sanbox? If yes, we use App path to deduce 0088 * other binaries paths (melt, ffmpeg, etc) 0089 * @param MltPath 0090 * @param Url (optional) file to open 0091 * If Url is present, it will be opened, otherwise, if openlastproject is 0092 * set, latest project will be opened. If no file is open after trying this, 0093 * a default new file will be created. 0094 * @param clipsToLoad 0095 */ 0096 void initGUI(bool inSandbox, const QString &MltPath, const QUrl &Url, const QString &clipsToLoad = QString()); 0097 0098 /** @brief Returns a pointer to the singleton object. */ 0099 static std::unique_ptr<Core> &self(); 0100 0101 /** @brief Delete the global core instance */ 0102 static void clean(); 0103 0104 /** @brief Returns a pointer to the main window. */ 0105 MainWindow *window(); 0106 0107 /** @brief Open a file using an external app. */ 0108 QString openExternalApp(QString appPath, const QStringList args); 0109 0110 /** @brief Returns a pointer to the project manager. */ 0111 ProjectManager *projectManager(); 0112 /** @brief Returns a pointer to the current project. */ 0113 KdenliveDoc *currentDoc(); 0114 /** @brief Returns project's timecode. */ 0115 Timecode timecode() const; 0116 /** @brief Returns a pointer to the monitor manager. */ 0117 MonitorManager *monitorManager(); 0118 /** @brief Returns a pointer to the media browser widget. */ 0119 MediaBrowser *mediaBrowser(); 0120 /** @brief Returns a pointer to the view of the project bin. */ 0121 Bin *bin(); 0122 /** @brief Returns a pointer to the view of the active bin (or main bin on no focus). */ 0123 Bin *activeBin(); 0124 /** @brief Select a clip in the Bin from its id. */ 0125 void selectBinClip(const QString &id, bool activateMonitor = true, int frame = -1, const QPoint &zone = QPoint()); 0126 /** @brief Selects an item in the current timeline (clip, composition, subtitle). */ 0127 void selectTimelineItem(int id); 0128 /** @brief Returns a pointer to the model of the project bin. */ 0129 std::shared_ptr<ProjectItemModel> projectItemModel(); 0130 /** @brief Returns a pointer to the library. */ 0131 LibraryWidget *library(); 0132 /** @brief Returns a pointer to the subtitle edit. */ 0133 SubtitleEdit *subtitleWidget(); 0134 /** @brief Returns a pointer to the text based editing widget. */ 0135 TextBasedEdit *textEditWidget(); 0136 /** @brief Returns a pointer to the guides list widget. */ 0137 GuidesList *guidesList(); 0138 /** @brief Returns a pointer to the time remapping widget. */ 0139 TimeRemap *timeRemapWidget(); 0140 /** @brief Returns true if clip displayed in remap widget is the bin clip with id clipId. */ 0141 bool currentRemap(const QString &clipId); 0142 /** @brief Returns a pointer to the audio mixer. */ 0143 MixerManager *mixer(); 0144 ToolType::ProjectTool activeTool(); 0145 0146 /** @brief Returns a pointer to MLT's repository */ 0147 std::unique_ptr<Mlt::Repository> &getMltRepository(); 0148 0149 /** @brief Returns a pointer to the current profile */ 0150 std::unique_ptr<ProfileModel> &getCurrentProfile() const; 0151 const QString &getCurrentProfilePath() const; 0152 0153 /** @brief Define the active profile 0154 * @returns true if profile exists, false if not found 0155 */ 0156 bool setCurrentProfile(const QString profilePath); 0157 /** @brief Returns Sample Aspect Ratio of current profile */ 0158 double getCurrentSar() const; 0159 /** @brief Returns Display Aspect Ratio of current profile */ 0160 double getCurrentDar() const; 0161 0162 /** @brief Returns frame rate of current profile */ 0163 double getCurrentFps() const; 0164 0165 /** @brief Returns the frame size (width x height) of current profile */ 0166 QSize getCurrentFrameSize() const; 0167 /** @brief Returns the frame display size (width x height) of current profile */ 0168 QSize getCurrentFrameDisplaySize() const; 0169 /** @brief Request project monitor refresh, and restore previously active monitor */ 0170 void refreshProjectMonitorOnce(); 0171 /** @brief Request project monitor refresh if current position is inside range*/ 0172 void refreshProjectRange(QPair<int, int> range); 0173 /** @brief Request project monitor refresh if referenced item is under cursor */ 0174 void refreshProjectItem(const ObjectId &id); 0175 /** @brief Returns a reference to a monitor (clip or project monitor) */ 0176 Monitor *getMonitor(int id); 0177 /** @brief Seek a monitor to position */ 0178 void seekMonitor(int id, int position); 0179 /** @brief Returns timeline's active track info (position and tag) */ 0180 QPair <int,QString> currentTrackInfo() const; 0181 /** @brief This function must be called whenever the profile used changes */ 0182 void profileChanged(); 0183 0184 /** @brief Create and push and undo object based on the corresponding functions 0185 Note that if you class permits and requires it, you should use the macro PUSH_UNDO instead*/ 0186 void pushUndo(const Fun &undo, const Fun &redo, const QString &text); 0187 void pushUndo(QUndoCommand *command); 0188 /** @brief display a user info/warning message in statusbar */ 0189 void displayMessage(const QString &message, MessageType type, int timeout = -1); 0190 /** @brief display timeline selection info in statusbar */ 0191 void displaySelectionMessage(const QString &message); 0192 /** @brief Clear asset view if itemId is displayed. */ 0193 void clearAssetPanel(int itemId); 0194 /** @brief Returns the effectstack of a given bin clip. */ 0195 std::shared_ptr<EffectStackModel> getItemEffectStack(const QUuid &uuid, int itemType, int itemId); 0196 int getItemPosition(const ObjectId &id); 0197 /** @brief Get item in point. */ 0198 int getItemIn(const ObjectId &id); 0199 /** @brief Get item in point, possibly from another timeline. */ 0200 int getItemIn(const QUuid &uuid, const ObjectId &id); 0201 int getItemTrack(const ObjectId &id); 0202 int getItemDuration(const ObjectId &id); 0203 QSize getItemFrameSize(const ObjectId &id); 0204 /** @brief Returns the capabilities of a clip: AudioOnly, VideoOnly or Disabled if both are allowed */ 0205 PlaylistState::ClipState getItemState(const ObjectId &id); 0206 /** @brief Get a list of video track names with indexes */ 0207 QMap<int, QString> getTrackNames(bool videoOnly); 0208 /** @brief Returns the composition A track (MLT index / Track id) */ 0209 QPair<int, int> getCompositionATrack(int cid) const; 0210 void setCompositionATrack(int cid, int aTrack); 0211 /** @brief Return true if composition's a_track is automatic (no forced track) 0212 */ 0213 bool compositionAutoTrack(int cid) const; 0214 std::shared_ptr<DocUndoStack> undoStack(); 0215 double getClipSpeed(int id) const; 0216 /** @brief Mark an item as invalid for timeline preview */ 0217 void invalidateItem(ObjectId itemId); 0218 void invalidateRange(QPair<int, int>range); 0219 void prepareShutdown(); 0220 void finishShutdown(); 0221 /** the keyframe model changed (effect added, deleted, active effect changed), inform timeline */ 0222 void updateItemKeyframes(ObjectId id); 0223 /** A fade for clip id changed, update timeline */ 0224 void updateItemModel(ObjectId id, const QString &service); 0225 /** Show / hide keyframes for a timeline clip */ 0226 void showClipKeyframes(ObjectId id, bool enable); 0227 Mlt::Profile &thumbProfile(); 0228 /** @brief Returns the current project duration */ 0229 int projectDuration() const; 0230 /** @brief Returns true if current project has some rendered timeline preview */ 0231 bool hasTimelinePreview() const; 0232 /** @brief Returns monitor position */ 0233 int getMonitorPosition(Kdenlive::MonitorId id = Kdenlive::ProjectMonitor) const; 0234 /** @brief Handles audio and video capture **/ 0235 void startMediaCapture(int tid, bool, bool); 0236 void stopMediaCapture(int tid, bool, bool); 0237 QStringList getAudioCaptureDevices(); 0238 int getMediaCaptureState(); 0239 bool isMediaMonitoring() const; 0240 bool isMediaCapturing() const; 0241 MediaCapture *getAudioDevice(); 0242 /** @brief Returns Project Folder name for capture output location */ 0243 QString getProjectFolderName(bool folderForAudio = false); 0244 /** @brief Returns a timeline clip's bin id */ 0245 QString getTimelineClipBinId(int cid); 0246 /** @brief Returns all track ids in timeline */ 0247 std::unordered_set<QString> getAllTimelineTracksId(); 0248 /** @brief Returns a frame duration from a timecode */ 0249 int getDurationFromString(const QString &time); 0250 /** @brief An error occurred within a filter, inform user */ 0251 void processInvalidFilter(const QString &service, const QString &id, const QString &message); 0252 /** @brief Update current project's tags */ 0253 void updateProjectTags(int previousCount, const QMap <int, QStringList> &tags); 0254 /** @brief Returns the project profile */ 0255 Mlt::Profile &getProjectProfile(); 0256 /** @brief Returns the consumer profile, that will be scaled 0257 * according to preview settings. Should only be used on the consumer */ 0258 Mlt::Profile &getMonitorProfile(); 0259 /** @brief Returns a copy of current timeline's master playlist */ 0260 std::unique_ptr<Mlt::Producer> getMasterProducerInstance(); 0261 /** @brief Returns a copy of a track's playlist */ 0262 std::unique_ptr<Mlt::Producer> getTrackProducerInstance(int tid); 0263 /** @brief Returns the undo stack index (position). */ 0264 int undoIndex() const; 0265 /** @brief Enable / disable monitor multitrack view. Returns false if multitrack was not previously enabled */ 0266 bool enableMultiTrack(bool enable); 0267 /** @brief Returns number of audio channels for this project. */ 0268 int audioChannels(); 0269 /** @brief Add guides in the project. */ 0270 void addGuides(const QList <int> &guides); 0271 /** @brief Temporarily un/plug a list of clips in timeline. */ 0272 void temporaryUnplug(const QList<int> &clipIds, bool hide); 0273 /** @brief Transcode a video file. */ 0274 void transcodeFile(const QString &url); 0275 /** @brief Display key binding info in statusbar. */ 0276 void setWidgetKeyBinding(const QString &mess = QString()); 0277 KSharedDataCache audioThumbCache; 0278 /* @brief The thread job pool for clip jobs, allowing to set a max number of concurrent jobs */ 0279 TaskManager taskManager; 0280 /** @brief The number of clip load jobs changed */ 0281 void loadingClips(int, bool allowInterrupt = false); 0282 /** @brief Resize current mix item */ 0283 void resizeMix(int cid, int duration, MixAlignment align, int leftFrames = -1); 0284 /** @brief Get Mix cut pos (the duration of the mix on the right clip) */ 0285 int getMixCutPos(const ObjectId &) const; 0286 /** @brief Get alignment info for a mix item */ 0287 MixAlignment getMixAlign(const ObjectId &) const; 0288 /** @brief Closing current document, do some cleanup */ 0289 void cleanup(); 0290 /** @brief Clear clip reference in timeremap widget */ 0291 void clearTimeRemap(); 0292 /** @brief Create the dock widgets */ 0293 void buildDocks(); 0294 #if KNEWSTUFF_VERSION < QT_VERSION_CHECK(5, 98, 0) 0295 /** @brief Instantiates a "Get Hot New Stuff" dialog. 0296 * @param configFile configuration file for KNewStuff 0297 * @return number of installed items */ 0298 int getNewStuff(const QString &configFile); 0299 #endif 0300 /** @brief Get the frame size of the clip above a composition */ 0301 const QSize getCompositionSizeOnTrack(const ObjectId &id); 0302 void loadTimelinePreview(const QUuid uuid, const QString &chunks, const QString &dirty, bool enablePreview, Mlt::Playlist &playlist); 0303 /** @brief Returns true if the audio mixer widget is visible */ 0304 bool audioMixerVisible{false}; 0305 QString packageType() { return m_packageType; }; 0306 /** @brief Start / stop audio capture */ 0307 void switchCapture(); 0308 /** @brief Get the uuid of currently active timeline */ 0309 const QUuid currentTimelineId() const; 0310 /** @brief Update a sequence AV info (has audio/video) */ 0311 void updateSequenceAVType(const QUuid &uuid, int tracksCount); 0312 /** @brief A list of markers type categories {marker type, {color, category name}} */ 0313 struct MarkerCategory 0314 { 0315 QColor color; 0316 QString displayName; 0317 }; 0318 QMap<int, MarkerCategory> markerTypes; 0319 0320 private: 0321 explicit Core(const QString &packageType); 0322 static std::unique_ptr<Core> m_self; 0323 0324 /** @brief Makes sure Qt's locale and system locale settings match. */ 0325 void initLocale(); 0326 0327 MainWindow *m_mainWindow{nullptr}; 0328 ProjectManager *m_projectManager{nullptr}; 0329 MonitorManager *m_monitorManager{nullptr}; 0330 std::shared_ptr<ProjectItemModel> m_projectItemModel; 0331 LibraryWidget *m_library{nullptr}; 0332 SubtitleEdit *m_subtitleWidget{nullptr}; 0333 TextBasedEdit *m_textEditWidget{nullptr}; 0334 GuidesList *m_guidesList{nullptr}; 0335 TimeRemap *m_timeRemapWidget{nullptr}; 0336 MixerManager *m_mixerWidget{nullptr}; 0337 MediaBrowser *m_mediaBrowser{nullptr}; 0338 0339 /** @brief Current project's profile path */ 0340 QString m_currentProfile; 0341 0342 QString m_profile; 0343 QString m_packageType; 0344 Timecode m_timecode; 0345 Mlt::Profile m_thumbProfile; 0346 /** @brief Mlt profile used in the consumer 's monitors */ 0347 Mlt::Profile m_monitorProfile; 0348 /** @brief Mlt profile used to build the project's clips */ 0349 Mlt::Profile m_projectProfile; 0350 bool m_guiConstructed = false; 0351 /** @brief Check that the profile is valid (width is a multiple of 8 and height a multiple of 2 */ 0352 void checkProfileValidity(); 0353 std::unique_ptr<MediaCapture> m_capture; 0354 QUrl m_mediaCaptureFile; 0355 void resetThumbProfile(); 0356 0357 public Q_SLOTS: 0358 /** @brief Trigger (launch) an action by its actionCollection name */ 0359 void triggerAction(const QString &name); 0360 /** @brief Get an action's descriptive text by its actionCollection name */ 0361 const QString actionText(const QString &name); 0362 /** @brief Add an action to the app's actionCollection */ 0363 void addActionToCollection(const QString &name, QAction *action); 0364 /** @brief display a user info/warning message in the project bin */ 0365 void displayBinMessage(const QString &text, int type, const QList<QAction *> &actions = QList<QAction *>(), bool showClose = false, BinMessage::BinCategory messageCategory = BinMessage::BinCategory::NoMessage); 0366 void displayBinLogMessage(const QString &text, int type, const QString logInfo); 0367 /** @brief Create small thumbnails for luma used in compositions */ 0368 void buildLumaThumbs(const QStringList &values); 0369 /** @brief Try to find a display name for the given filename. 0370 * This is especially helpful for mlt's dynamically created luma files without thumb (luma01.pgm, luma02.pgm,...), 0371 * but also for others as it makes the visible name translatable. 0372 * @return The name that fits to the filename or if none is found the filename it self 0373 */ 0374 const QString nameForLumaFile(const QString &filename); 0375 /** @brief Set current project modified. */ 0376 void setDocumentModified(); 0377 /** @brief Show currently selected effect zone in timeline ruler. */ 0378 void showEffectZone(ObjectId id, QPair <int, int>inOut, bool checked); 0379 void updateMasterZones(); 0380 /** @brief Open the proxies test dialog. */ 0381 void testProxies(); 0382 /** @brief Refresh the monitor profile when project profile changes. */ 0383 void updateMonitorProfile(); 0384 /** @brief Add a new Bin Widget. */ 0385 void addBin(const QString &id = QString()); 0386 /** @brief Transcode a bin clip video. */ 0387 void transcodeFriendlyFile(const QString &binId, bool checkProfile); 0388 /** @brief Reset audio monitoring volume and channels. */ 0389 void resetAudioMonitoring(); 0390 /** @brief Start audio recording (after countdown). */ 0391 void startRecording(); 0392 /** @brief Show or hide track head audio rec controls. */ 0393 void monitorAudio(int tid, bool monitor); 0394 0395 Q_SIGNALS: 0396 void coreIsReady(); 0397 void updateLibraryPath(); 0398 //void updateMonitorProfile(); 0399 /** @brief Call config dialog on a selected page / tab */ 0400 void showConfigDialog(Kdenlive::ConfigPage, int); 0401 void finalizeRecording(const QString &captureFile); 0402 void autoScrollChanged(); 0403 /** @brief Update the message about the current loading progress */ 0404 void loadingMessageNewStage(const QString &message, int max = -1); 0405 /** @brief Increase the progress of the loading message by 1 */ 0406 void loadingMessageIncrease(); 0407 /** @brief Hide the message about the loading progress */ 0408 void loadingMessageHide(); 0409 /** @brief Opening finished, close splash screen */ 0410 void closeSplash(); 0411 /** @brief Trigger an update of the speech models list */ 0412 void voskModelUpdate(const QStringList models); 0413 /** @brief Update current effect zone */ 0414 void updateEffectZone(const QPoint p, bool withUndo); 0415 /** @brief The effect stask is about to be deleted, disconnect everything */ 0416 void disconnectEffectStack(); 0417 /** @brief Add a time remap effect to clip and show keyframes dialog */ 0418 void remapClip(int cid); 0419 /** @brief A monitor property changed, check if we need to reset */ 0420 void monitorProfileUpdated(); 0421 /** @brief Color theme changed, process refresh */ 0422 void updatePalette(); 0423 /** @brief Emitted when a clip is resized (to handle clip monitor inserted zones) */ 0424 void clipInstanceResized(const QString &binId); 0425 /** @brief Contains the project audio levels */ 0426 void audioLevelsAvailable(const QVector<double>& levels); 0427 /** @brief A frame was displayed in monitor, update audio mixer */ 0428 void updateMixerLevels(int pos); 0429 /** @brief Audio recording was started or stopped*/ 0430 void switchTimelineRecord(bool on); 0431 /** @brief Launch audio recording on track tid*/ 0432 void recordAudio(int tid, bool record); 0433 /** @brief Inform widgets that the project profile (and possibly fps) changed */ 0434 void updateProjectTimecode(); 0435 /** @brief Visible guide categories changed, reload snaps in timeline */ 0436 void refreshActiveGuides(); 0437 /** @brief The default marker category was changed, update guides list button */ 0438 void updateDefaultMarkerCategory(); 0439 /** @brief The default speech engine was changed */ 0440 void speechEngineChanged(); 0441 /** @brief Auto fit track height property changed, adjust size */ 0442 void autoTrackHeight(bool); 0443 /** @brief The number of missing clips in the project changed, inform user when rendering */ 0444 void gotMissingClipsCount(int total, int used); 0445 /** @brief Tell the current progress task to stop */ 0446 void stopProgressTask(); 0447 /** @brief A project clip was deleted */ 0448 void binClipDeleted(int cid); 0449 };