File indexing completed on 2025-02-02 04:11:25

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 <QFileDialog>
0010 #include <QDialogButtonBox>
0011 #include <QMessageBox>
0012 #include <QApplication>
0013 
0014 #include "io/io_registry.hpp"
0015 #include "model/document.hpp"
0016 #include "app/settings/widget_builder.hpp"
0017 
0018 namespace glaxnimate::gui {
0019 
0020 class ImportExportDialog
0021 {
0022 
0023 public:
0024     ImportExportDialog(const io::Options& options, QWidget* parent)
0025         : parent(parent)
0026     {
0027         io_options_ = options;
0028 
0029     }
0030 
0031     const io::Options& io_options() const
0032     {
0033         return io_options_;
0034     }
0035 
0036     bool export_dialog(model::Composition* comp)
0037     {
0038         QFileDialog dialog(parent);
0039         dialog.setWindowTitle(i18n("Save file"));
0040         dialog.setAcceptMode(QFileDialog::AcceptSave);
0041         dialog.setFileMode(QFileDialog::AnyFile);
0042         dialog.setOption(QFileDialog::DontUseNativeDialog, !app::settings::get<bool>("open_save", "native_dialog"));
0043         setup_file_dialog(dialog, io::IoRegistry::instance().exporters(), io_options_.format, false);
0044         while ( true )
0045         {
0046             if ( !show_file_dialog(dialog, io::IoRegistry::instance().exporters(), io::ImportExport::Export) )
0047                 return false;
0048 
0049             // For some reason the file dialog shows the option to do this automatically but it's disabled
0050             if ( QFileInfo(io_options_.filename).completeSuffix().isEmpty() )
0051             {
0052                 io_options_.filename += "." + io_options_.format->extensions()[0];
0053 
0054                 QFileInfo finfo(io_options_.filename);
0055                 if ( finfo.exists() )
0056                 {
0057                     QMessageBox overwrite(
0058                         QMessageBox::Question,
0059                         i18n("Overwrite File?"),
0060                         i18n("The file \"%1\" already exists. Do you wish to overwrite it?")
0061                             .arg(finfo.baseName()),
0062                         QMessageBox::Yes|QMessageBox::No,
0063                         parent
0064                     );
0065                     overwrite.setDefaultButton(QMessageBox::Yes);
0066                     if ( overwrite.exec() != QMessageBox::Yes )
0067                         continue;
0068                 }
0069             }
0070 
0071             break;
0072         }
0073 
0074         auto ok =  options_dialog(io_options_.format->save_settings(comp));
0075         io_options_.settings["default_time"] = comp->animation->last_frame.get();
0076         return ok;
0077     }
0078 
0079     bool import_dialog()
0080     {
0081         QFileDialog dialog(parent);
0082         dialog.setWindowTitle(i18n("Open file"));
0083         dialog.setAcceptMode(QFileDialog::AcceptOpen);
0084         dialog.setFileMode(QFileDialog::ExistingFile);
0085         dialog.setOption(QFileDialog::DontUseNativeDialog, !app::settings::get<bool>("open_save", "native_dialog"));
0086         setup_file_dialog(dialog, io::IoRegistry::instance().importers(), io_options_.format, true);
0087         if ( show_file_dialog(dialog, io::IoRegistry::instance().importers(), io::ImportExport::Import) )
0088             return options_dialog(io_options_.format->open_settings());
0089         return false;
0090     }
0091 
0092     bool options_dialog(std::unique_ptr<app::settings::SettingsGroup> settings)
0093     {
0094         if ( !io_options_.format )
0095             return false;
0096 
0097         if ( !settings || settings->settings().empty() )
0098             return true;
0099 
0100         app::settings::WidgetBuilder widget_builder;
0101         QString title = i18n("%1 Options", io_options_.format->name());
0102         return widget_builder.show_dialog(settings->settings(), io_options_.settings, title, parent);
0103     }
0104 
0105 private:
0106 
0107     bool show_file_dialog(QFileDialog& dialog, const std::vector<io::ImportExport*>& formats, io::ImportExport::Direction direction)
0108     {
0109         io_options_.format = nullptr;
0110 
0111 #ifdef Q_OS_ANDROID
0112         dialog.setWindowFlags(Qt::Window);
0113         dialog.setOption(QFileDialog::DontUseNativeDialog, false);
0114         dialog.setFixedSize(dialog.parentWidget()->size());
0115         dialog.setWindowState(dialog.windowState() | Qt::WindowFullScreen);
0116 #else
0117         dialog.setOption(QFileDialog::DontUseNativeDialog, !app::settings::get<bool>("open_save", "native_dialog"));
0118 #endif
0119 
0120         if ( dialog.exec() == QDialog::Rejected )
0121             return false;
0122 
0123         io_options_.filename = dialog.selectedFiles()[0];
0124         io_options_.path = dialog.directory();
0125 
0126         int filter = filters.indexOf(dialog.selectedNameFilter());
0127         if ( filter >= 0 && filter < int(formats.size()) )
0128         {
0129             io_options_.format = formats[filter];
0130         }
0131         else
0132         {
0133             io_options_.format = io::IoRegistry::instance().from_filename(io_options_.filename, direction);
0134         }
0135 
0136         if ( !io_options_.format )
0137             return false;
0138 
0139         return true;
0140     }
0141 
0142     void setup_file_dialog(QFileDialog& dialog, const std::vector<io::ImportExport*>& formats,
0143                            io::ImportExport* selected, bool add_all)
0144     {
0145         dialog.setDirectory(io_options_.path);
0146         dialog.selectFile(io_options_.filename);
0147 
0148         filters.clear();
0149 
0150         QString all;
0151         for ( const auto& reg : formats )
0152         {
0153             for ( const QString& ext : reg->extensions() )
0154             {
0155                 all += "*." + ext + " ";
0156             }
0157 
0158             filters << reg->name_filter();
0159         }
0160 
0161         dialog.setNameFilters(filters);
0162 
0163         if ( add_all )
0164         {
0165             all.resize(all.size() - 1);
0166             QString all_filter = i18n("All files (%1)", all);
0167             filters << all_filter;
0168             dialog.setNameFilters(filters);
0169             dialog.selectNameFilter(all_filter);
0170         }
0171         else if ( selected )
0172         {
0173             dialog.selectNameFilter(selected->name_filter());
0174         }
0175 
0176     }
0177 
0178     QWidget* parent;
0179     QStringList filters;
0180     io::Options io_options_;
0181 };
0182 
0183 } // namespace glaxnimate::gui