File indexing completed on 2025-01-05 04:01:21

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #pragma once
0008 
0009 #include <QFileInfo>
0010 #include <QObject>
0011 #include <QBuffer>
0012 
0013 #include "app/settings/settings_group.hpp"
0014 #include "app/log/log_line.hpp"
0015 
0016 #include "model/document.hpp"
0017 #include "model/assets/composition.hpp"
0018 
0019 namespace glaxnimate::io {
0020 
0021 class ImportExport : public QObject
0022 {
0023     Q_OBJECT
0024 
0025     Q_PROPERTY(QString name READ name)
0026     Q_PROPERTY(QString slug READ slug)
0027     Q_PROPERTY(QStringList extensions READ extensions)
0028     Q_PROPERTY(bool can_open READ can_open)
0029     Q_PROPERTY(bool can_save READ can_save)
0030 
0031 public:
0032     enum Direction
0033     {
0034         Import,
0035         Export,
0036     };
0037     Q_ENUM(Direction)
0038 
0039     virtual ~ImportExport() = default;
0040 
0041     Q_INVOKABLE bool can_handle(glaxnimate::io::ImportExport::Direction direction) const
0042     {
0043         if ( direction == Import )
0044             return can_open();
0045         else if ( direction == Export )
0046             return can_save();
0047         return false;
0048     }
0049 
0050     Q_INVOKABLE bool can_handle_extension(const QString& extension, glaxnimate::io::ImportExport::Direction direction) const
0051     {
0052         return can_handle(direction) && extensions().contains(extension);
0053     }
0054 
0055     Q_INVOKABLE bool can_handle_filename(const QString& filename, glaxnimate::io::ImportExport::Direction direction) const
0056     {
0057         return can_handle_extension(QFileInfo(filename).completeSuffix(), direction);
0058     }
0059 
0060     /**
0061      * @pre @p setting_values contains all the settings correctly && can_open()
0062      */
0063     bool open(QIODevice& file, const QString& filename,
0064         model::Document* document, const QVariantMap& setting_values);
0065 
0066     /**
0067      * @pre @p setting_values contains all the settings correctly && can_open()
0068      * @param file File to write to
0069      * @param filename Filename for error reporting
0070      * @param comp Composition, for formats supporting multiple comps, use comp->document()
0071      * @param setting_values Values based on save_settings()
0072      */
0073     bool save(QIODevice& file, const QString& filename,
0074         model::Composition* comp, const QVariantMap& setting_values);
0075 
0076     /**
0077      * \brief Will save the first comp in the document
0078      */
0079     bool save(QIODevice& file, const QString& filename, model::Document* document, const QVariantMap& setting_values);
0080 
0081     Q_INVOKABLE QByteArray save(glaxnimate::model::Composition* comp, const QVariantMap& setting_values={}, const QString& filename = "data");
0082     Q_INVOKABLE bool load(glaxnimate::model::Document* document, const QByteArray& data, const QVariantMap& setting_values={}, const QString& filename = "data");
0083 
0084 
0085     virtual QString name() const = 0;
0086     virtual QString slug() const = 0;
0087     virtual QStringList extensions() const = 0;
0088     virtual std::unique_ptr<app::settings::SettingsGroup> open_settings() const { return {}; }
0089     virtual std::unique_ptr<app::settings::SettingsGroup> save_settings(model::Composition* ) const { return {}; }
0090     virtual bool can_open() const = 0;
0091     virtual bool can_save() const = 0;
0092     /**
0093      * \brief Priority when multiple classes support the same file types
0094      */
0095     virtual int priority() const { return 0; }
0096 
0097     /**
0098      * \brief File dialog name filter
0099      */
0100     Q_INVOKABLE QString name_filter() const;
0101 
0102     Q_INVOKABLE void warning(const QString& message)
0103     {
0104         Q_EMIT this->message(message, app::log::Warning);
0105     }
0106 
0107     Q_INVOKABLE void information(const QString& message)
0108     {
0109         Q_EMIT this->message(message, app::log::Info);
0110     }
0111 
0112     Q_INVOKABLE void error(const QString& message)
0113     {
0114         Q_EMIT this->message(message, app::log::Error);
0115     }
0116 
0117 protected:
0118     virtual bool auto_open() const { return true; }
0119 
0120     virtual bool on_open(QIODevice& file, const QString& filename,
0121                       model::Document* document, const QVariantMap& setting_values)
0122     {
0123         Q_UNUSED(file);
0124         Q_UNUSED(filename);
0125         Q_UNUSED(document);
0126         Q_UNUSED(setting_values);
0127         return false;
0128     }
0129 
0130     virtual bool on_save(
0131         QIODevice& file,
0132         const QString& filename,
0133         model::Composition* comp,
0134         const QVariantMap& setting_values)
0135     {
0136         Q_UNUSED(file);
0137         Q_UNUSED(filename);
0138         Q_UNUSED(comp);
0139         Q_UNUSED(setting_values);
0140         return false;
0141     }
0142 
0143 Q_SIGNALS:
0144     void message(const QString& message, app::log::Severity severity);
0145     void progress_max_changed(int max);
0146     void progress(int value);
0147     void completed(bool success);
0148 };
0149 
0150 } // namespace glaxnimate::io
0151