File indexing completed on 2024-05-12 08:34:14

0001 /* This file is part of Spectacle, the KDE screenshot utility
0002  * SPDX-FileCopyrightText: 2015 Boudhayan Gupta <bgupta@kde.org>
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  */
0005 
0006 #pragma once
0007 
0008 #include "settings.h"
0009 #include <KLocalizedString>
0010 #include <QDateTime>
0011 class QIODevice;
0012 #include <QMap>
0013 #include <QObject>
0014 class QPrinter;
0015 #include <QUrl>
0016 
0017 class QTemporaryDir;
0018 
0019 class ExportManager : public QObject
0020 {
0021     Q_OBJECT
0022 
0023     // singleton-ize the class
0024 
0025 public:
0026     static ExportManager *instance();
0027 
0028 private:
0029     explicit ExportManager(QObject *parent = nullptr);
0030     ~ExportManager() override;
0031 
0032     ExportManager(ExportManager const &) = delete;
0033     void operator=(ExportManager const &) = delete;
0034 
0035     // now the usual stuff
0036 
0037 public:
0038     enum Action {
0039         NoActions   = 0b00000,
0040         Save        = 0b00001,
0041         SaveAs      = 0b00010,
0042         CopyImage   = 0b00100,
0043         CopyPath    = 0b01000,
0044         UserAction  = 0b10000,
0045         AnySave     = Save | SaveAs,
0046         AnyAction   = AnySave | CopyImage | CopyPath,
0047     };
0048     Q_DECLARE_FLAGS(Actions, Action)
0049     Q_FLAG(Action)
0050 
0051     QString defaultSaveLocation() const;
0052     QString defaultVideoSaveLocation() const;
0053     bool isFileExists(const QUrl &url) const;
0054     bool isImageSavedNotInTemp() const;
0055     void setImage(const QImage &image);
0056     QImage image() const;
0057     void updateTimestamp();
0058     void setTimestamp(const QDateTime &timestamp);
0059 
0060     /**
0061      * The title used to fill the window title template in formatted file names.
0062      */
0063     QString windowTitle() const;
0064 
0065     /**
0066      * Returns a formatted filename using a template string.
0067      */
0068     QString formattedFilename(const QString &nameTemplate = Settings::imageFilenameTemplate()) const;
0069 
0070     /**
0071      * The URL to record a video with before it is exported.
0072      */
0073     QUrl tempVideoUrl();
0074 
0075     const QTemporaryDir *temporaryDir();
0076 
0077     struct Placeholder {
0078         enum Flag {
0079             Other = 0,
0080             Date = 1,
0081             Time = 1 << 1,
0082             Extra = 1 << 28, //< Placeholders that are extras are hidden by default.
0083             Hidden = 1 << 29, //< Placeholders that won't be shown
0084             QDateTime = 1 << 30, //< Can be put directly into QDateTime::toString.
0085         };
0086         using Flags = QFlags<Flag>;
0087 
0088         const Flags flags;
0089         const QString baseKey;
0090         const QString plainKey;
0091         const QString htmlKey;
0092         // Placeholders with empty descriptions will not be visible in the config UI
0093         const KLocalizedString description;
0094 
0095         Placeholder(const Flags &flags, const QString &key, const KLocalizedString &description)
0096             : flags(flags)
0097             , baseKey(key)
0098             , plainKey(u"<" % key % u">")
0099             , htmlKey(u"&lt;" % key % u"&gt;") // key -> <key> in HTML
0100             , description(description)
0101         {
0102         }
0103 
0104         Placeholder(const Flags &flags, const QString &key)
0105             : flags(flags | Hidden)
0106             , baseKey(key)
0107             , plainKey(u"<" % key % u">")
0108         {
0109         }
0110     };
0111 
0112     static const QList<Placeholder> filenamePlaceholders;
0113 
0114 Q_SIGNALS:
0115     void imageChanged();
0116 
0117     void errorMessage(const QString &str);
0118     void imageExported(const ExportManager::Actions &actions, const QUrl &url = {});
0119     void videoExported(const ExportManager::Actions &actions, const QUrl &url = {});
0120 
0121 public Q_SLOTS:
0122 
0123     QUrl getAutosaveFilename() const;
0124     QUrl tempSave();
0125 
0126     void setWindowTitle(const QString &windowTitle);
0127     void exportImage(ExportManager::Actions actions, QUrl url = {});
0128     void exportVideo(ExportManager::Actions actions, const QUrl &inputUrl, QUrl outputUrl = {});
0129     void doPrint(QPrinter *printer);
0130 
0131 private:
0132     QString truncatedFilename(const QString &filename) const;
0133     using FileNameAlreadyUsedCheck = bool (ExportManager::*)(const QUrl &) const;
0134     QString autoIncrementFilename(const QString &baseName, const QString &extension, FileNameAlreadyUsedCheck isFileNameUsed) const;
0135     QString imageFileSuffix(const QUrl &url) const;
0136     bool writeImage(QIODevice *device, const QByteArray &suffix);
0137     bool save(const QUrl &url);
0138     bool localSave(const QUrl &url, const QString &suffix);
0139     bool remoteSave(const QUrl &url, const QString &suffix);
0140     bool isTempFileAlreadyUsed(const QUrl &url) const;
0141 
0142     bool m_imageSavedNotInTemp;
0143     QImage m_saveImage;
0144     QDateTime m_timestamp;
0145     QUrl m_tempFile;
0146     std::unique_ptr<QTemporaryDir> m_tempDir;
0147     QList<QUrl> m_usedTempFileNames;
0148     QString m_windowTitle;
0149 };
0150 
0151 Q_DECLARE_OPERATORS_FOR_FLAGS(ExportManager::Actions)
0152 Q_DECLARE_OPERATORS_FOR_FLAGS(ExportManager::Placeholder::Flags)