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