File indexing completed on 2024-05-05 04:34:53

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     QDateTime timestamp() const;
0060 
0061     /**
0062      * The title used to fill the window title template in formatted file names.
0063      */
0064     QString windowTitle() const;
0065 
0066     /**
0067      * Returns a formatted filename using a template string.
0068      */
0069     QString formattedFilename(const QString &nameTemplate = Settings::imageFilenameTemplate()) const;
0070 
0071     /**
0072      * The URL to record a video with before it is exported.
0073      */
0074     QUrl tempVideoUrl();
0075 
0076     const QTemporaryDir *temporaryDir();
0077 
0078     struct Placeholder {
0079         enum Flag {
0080             Other = 0,
0081             Date = 1,
0082             Time = 1 << 1,
0083             Extra = 1 << 28, //< Placeholders that are extras are hidden by default.
0084             Hidden = 1 << 29, //< Placeholders that won't be shown
0085             QDateTime = 1 << 30, //< Can be put directly into QDateTime::toString.
0086         };
0087         using Flags = QFlags<Flag>;
0088 
0089         const Flags flags;
0090         const QString baseKey;
0091         const QString plainKey;
0092         const QString htmlKey;
0093         // Placeholders with empty descriptions will not be visible in the config UI
0094         const KLocalizedString description;
0095 
0096         Placeholder(const Flags &flags, const QString &key, const KLocalizedString &description)
0097             : flags(flags)
0098             , baseKey(key)
0099             , plainKey(u"<" % key % u">")
0100             , htmlKey(u"&lt;" % key % u"&gt;") // key -> <key> in HTML
0101             , description(description)
0102         {
0103         }
0104 
0105         Placeholder(const Flags &flags, const QString &key)
0106             : flags(flags | Hidden)
0107             , baseKey(key)
0108             , plainKey(u"<" % key % u">")
0109         {
0110         }
0111     };
0112 
0113     static const QList<Placeholder> filenamePlaceholders;
0114 
0115 Q_SIGNALS:
0116     void imageChanged();
0117 
0118     void errorMessage(const QString &str);
0119     void imageExported(const ExportManager::Actions &actions, const QUrl &url = {});
0120     void videoExported(const ExportManager::Actions &actions, const QUrl &url = {});
0121     void qrCodeScanned(const QVariant &content);
0122 
0123 public Q_SLOTS:
0124 
0125     QUrl getAutosaveFilename() const;
0126     QUrl tempSave();
0127 
0128     void setWindowTitle(const QString &windowTitle);
0129     void exportImage(ExportManager::Actions actions, QUrl url = {});
0130     void exportVideo(ExportManager::Actions actions, const QUrl &inputUrl, QUrl outputUrl = {});
0131     void scanQRCode();
0132     void doPrint(QPrinter *printer);
0133 
0134 private:
0135     QString truncatedFilename(const QString &filename) const;
0136     using FileNameAlreadyUsedCheck = bool (ExportManager::*)(const QUrl &) const;
0137     QString autoIncrementFilename(const QString &baseName, const QString &extension, FileNameAlreadyUsedCheck isFileNameUsed) const;
0138     QString imageFileSuffix(const QUrl &url) const;
0139     bool writeImage(QIODevice *device, const QByteArray &suffix);
0140     bool save(const QUrl &url);
0141     bool localSave(const QUrl &url, const QString &suffix);
0142     bool remoteSave(const QUrl &url, const QString &suffix);
0143     bool isTempFileAlreadyUsed(const QUrl &url) const;
0144 
0145     bool m_imageSavedNotInTemp;
0146     QImage m_saveImage;
0147     QDateTime m_timestamp;
0148     QUrl m_tempFile;
0149     std::unique_ptr<QTemporaryDir> m_tempDir;
0150     QList<QUrl> m_usedTempFileNames;
0151     QString m_windowTitle;
0152 };
0153 
0154 Q_DECLARE_OPERATORS_FOR_FLAGS(ExportManager::Actions)
0155 Q_DECLARE_OPERATORS_FOR_FLAGS(ExportManager::Placeholder::Flags)