File indexing completed on 2025-01-26 04:02:01
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "glaxnimate_app.hpp" 0008 0009 #include "app_info.hpp" 0010 0011 #include <QDir> 0012 #include <QStandardPaths> 0013 0014 using namespace glaxnimate::gui; 0015 using namespace glaxnimate; 0016 0017 #ifdef MOBILE_UI 0018 0019 #include <QScreen> 0020 0021 static qreal get_mult() 0022 { 0023 #ifndef Q_OS_ANDROID 0024 return 1; 0025 } 0026 #else 0027 auto sz = QApplication::primaryScreen()->size(); 0028 return qMin(sz.width(), sz.height()) / 240.; 0029 0030 } 0031 0032 QString GlaxnimateApp::data_file(const QString &name) const 0033 { 0034 return "assets:/share/glaxnimate/glaxnimate/" + name; 0035 } 0036 0037 #endif 0038 0039 qreal GlaxnimateApp::handle_size_multiplier() 0040 { 0041 static qreal mult = get_mult(); 0042 return mult; 0043 } 0044 0045 qreal GlaxnimateApp::handle_distance_multiplier() 0046 { 0047 return handle_size_multiplier() / 2.; 0048 } 0049 0050 void GlaxnimateApp::set_clipboard_data(QMimeData *data) 0051 { 0052 clipboard.reset(data); 0053 } 0054 0055 const QMimeData *GlaxnimateApp::get_clipboard_data() 0056 { 0057 return clipboard.get(); 0058 } 0059 0060 #else 0061 0062 #include <QPalette> 0063 #include <QClipboard> 0064 0065 #include <KLocalizedString> 0066 0067 #include "app/settings/settings.hpp" 0068 #include "app/settings/palette_settings.hpp" 0069 #include "app/settings/keyboard_shortcuts.hpp" 0070 #include "app/log/listener_file.hpp" 0071 #include "settings/plugin_settings_group.hpp" 0072 #include "settings/clipboard_settings.hpp" 0073 #include "settings/toolbar_settings.hpp" 0074 #include "settings/api_credentials.hpp" 0075 0076 static QVariantMap avail_icon_themes() 0077 { 0078 QVariantMap avail_icon_themes; 0079 avail_icon_themes[i18n("Glaxnimate Default")] = ""; 0080 for ( QDir search : QIcon::themeSearchPaths() ) 0081 { 0082 for ( const auto& avail : search.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot) ) 0083 { 0084 QDir subdir(avail.filePath()); 0085 if ( subdir.exists("index.theme") ) 0086 avail_icon_themes[avail.baseName()] = avail.baseName(); 0087 } 0088 } 0089 0090 return avail_icon_themes; 0091 } 0092 0093 static QString default_icon_theme() 0094 { 0095 QPalette palette = QGuiApplication::palette(); 0096 if ( palette.color(QPalette::Button).value() < 100 ) 0097 return "breeze-dark"; 0098 else 0099 return "breeze"; 0100 } 0101 0102 static void set_icon_theme(const QVariant& v) 0103 { 0104 QString theme_name = v.toString(); 0105 0106 if ( theme_name.isEmpty() ) 0107 theme_name = default_icon_theme(); 0108 0109 QIcon::setThemeName(theme_name); 0110 } 0111 0112 static QVariantMap avail_languages() 0113 { 0114 QVariantMap avail_languages; 0115 for ( const QString& name : app::TranslationService::instance().available_languages().keys() ) 0116 { 0117 avail_languages[name] = app::TranslationService::instance().available_languages()[name]; 0118 } 0119 0120 return avail_languages; 0121 } 0122 0123 static void set_language(const QVariant& v) 0124 { 0125 QString code = v.toString(); 0126 app::TranslationService::instance().change_lang_code(code); 0127 } 0128 0129 static void icon_theme_fixup() 0130 { 0131 QString default_theme = default_icon_theme(); 0132 QIcon::setFallbackThemeName(default_theme); 0133 0134 QString old = QIcon::themeName(); 0135 if ( old == "breeze" || old == "breeze-dark" ) 0136 QIcon::setThemeName(default_theme); 0137 else 0138 set_icon_theme(old); 0139 } 0140 0141 static void load_themes(GlaxnimateApp* app, app::settings::PaletteSettings* settings) 0142 { 0143 for ( QDir themedir : app->data_paths("themes") ) 0144 { 0145 for ( const auto& theme : themedir.entryList({"*.ini"}, QDir::Files|QDir::Readable, QDir::Name|QDir::IgnoreCase) ) 0146 { 0147 QSettings ini_parser(themedir.absoluteFilePath(theme), QSettings::IniFormat); 0148 settings->load_palette(ini_parser, true); 0149 } 0150 } 0151 } 0152 0153 void GlaxnimateApp::on_initialize() 0154 { 0155 0156 app::log::Logger::instance().add_listener<app::log::ListenerFile>(writable_data_path("log.txt")); 0157 app::log::Logger::instance().add_listener<app::log::ListenerStderr>(); 0158 store_logger = app::log::Logger::instance().add_listener<app::log::ListenerStore>(); 0159 0160 setWindowIcon(QIcon(data_file("images/logo.svg"))); 0161 0162 QDir().mkpath(backup_path()); 0163 } 0164 0165 void GlaxnimateApp::on_initialize_settings() 0166 { 0167 using namespace app::settings; 0168 QString curr_lang = app::TranslationService::instance().current_language_code(); 0169 0170 Settings::instance().add_group("ui", i18nc("@title settings group", "User Interface"), "preferences-desktop-theme", { 0171 // slug Label/Tooltip Type default choices side effects 0172 Setting("language", 0173 i18nc("@label:listbox", "Language"), 0174 i18nc("@info:tooltip", "Interface Language"), Setting::String, curr_lang, avail_languages(), set_language), 0175 Setting("icon_theme", i18nc("@label:listbox", "Icon Theme"), {}, Setting::String, "", avail_icon_themes(), ::set_icon_theme), 0176 // Setting("startup_dialog", i18nc("@option:check", "Show startup dialog"), {}, Setting::Bool, true), 0177 Setting("timeline_scroll_horizontal", 0178 i18nc("@option:check", "Horizontal Timeline Scroll"), 0179 i18nc("@info:tooltip", "If enabled, the timeline will scroll horizontally by default and vertically with Shift or Alt"), 0180 Setting::Bool, false), 0181 Setting("layout", {}, {}, Setting::Internal, 0), 0182 Setting("window_state", {}, {}, Setting::Internal, QByteArray{}), 0183 Setting("window_geometry", {}, {}, Setting::Internal, QByteArray{}), 0184 Setting("timeline_splitter", {}, {}, Setting::Internal, QByteArray{}), 0185 }); 0186 Settings::instance().add_group("defaults", i18nc("@title settings group", "New Animation Defaults"), "video-webm", { 0187 Setting("width", 0188 i18nc("@label:spinbox", "Width"), "", 0189 512, 0, 1000000), 0190 Setting("height", 0191 i18nc("@label:spinbox", "Height"), "", 0192 512, 0, 1000000), 0193 Setting("fps", 0194 i18nc("@label:spinbox", "FPS"), 0195 i18nc("@info:tooltip", "Frames per second"), 0196 60.f, 0.f, 1000.f), 0197 Setting("duration", 0198 i18nc("@label:spinbox", "Duration"), 0199 i18nc("@info:tooltip", "Duration in seconds"), 0200 3.f, 0.f, 90000.f), 0201 }); 0202 Settings::instance().add_group("open_save", i18nc("@title settings group", "Open / Save"), "kfloppy", { 0203 Setting("max_recent_files", i18nc("@label:spinbox", "Max Recent Files"), {}, 5, 0, 16), 0204 Setting("path", {}, {}, Setting::Internal, QString{}), 0205 Setting("recent_files", {}, {}, Setting::Internal, QStringList{}), 0206 Setting("backup_frequency", 0207 i18nc("@label:spinbox", "Backup Frequency"), 0208 i18nc("@info:tooltip", "How often to save a backup copy (in minutes)"), 5, 0, 60), 0209 Setting("render_path", {}, {}, Setting::Internal, QString{}), 0210 Setting("import_path", {}, {}, Setting::Internal, QString{}), 0211 Setting("native_dialog", i18nc("@option:check", "Use system file dialog"), {}, Setting::Bool, true), 0212 }); 0213 Settings::instance().add_group("scripting", i18nc("@title settings group", "Scripting"), "utilities-terminal", { 0214 // slug Label Tooltip Type default 0215 Setting("history", {}, {}, Setting::Internal, QStringList{}), 0216 Setting("max_history", {}, {}, Setting::Internal, 100), 0217 }); 0218 Settings::instance().add_group("tools", i18nc("@title settings group", "Tools"), "tools", { 0219 // slug Label Tooltip Type default 0220 Setting("shape_group", {}, {}, Setting::Internal, true), 0221 Setting("shape_fill", {}, {}, Setting::Internal, true), 0222 Setting("shape_stroke", {}, {}, Setting::Internal, true), 0223 Setting("edit_mask", {}, {}, Setting::Internal, false), 0224 Setting("color_main", {}, {}, Setting::Internal, "#ffffff"), 0225 Setting("color_secondary", {}, {}, Setting::Internal, "#000000"), 0226 Setting("stroke_width", {}, {}, Setting::Internal, 1.), 0227 Setting("stroke_cap", {}, {}, Setting::Internal, int(Qt::RoundCap)), 0228 Setting("stroke_join", {}, {}, Setting::Internal, int(Qt::RoundJoin)), 0229 Setting("stroke_miter", {}, {}, Setting::Internal, 4.), 0230 Setting("star_type", {}, {}, Setting::Internal, 1), 0231 Setting("star_ratio", {}, {}, Setting::Internal, 0.5), 0232 Setting("star_points", {}, {}, Setting::Internal, 5), 0233 }); 0234 // catch all 0235 Settings::instance().add_group("internal", "", "", {}); 0236 0237 app::settings::Settings::instance().add_group(std::make_unique<settings::ToolbarSettingsGroup>()); 0238 app::settings::Settings::instance().add_group(std::make_unique<settings::PluginSettingsGroup>(QStringList{ 0239 "AnimatedRaster", "ReplaceColor", "dotLottie", "FrameByFrame" 0240 })); 0241 app::settings::Settings::instance().add_group(std::make_unique<settings::ClipboardSettings>()); 0242 0243 auto palette_settings = std::make_unique<app::settings::PaletteSettings>(); 0244 load_themes(this, palette_settings.get()); 0245 app::settings::Settings::instance().add_group(std::move(palette_settings)); 0246 0247 auto sc_settings = std::make_unique<app::settings::ShortcutSettings>(); 0248 shortcut_settings = sc_settings.get(); 0249 app::settings::Settings::instance().add_group(std::move(sc_settings)); 0250 0251 app::settings::Settings::instance().add_group(std::make_unique<settings::ApiCredentials>()); 0252 0253 } 0254 0255 app::settings::ShortcutSettings * GlaxnimateApp::shortcuts() const 0256 { 0257 return shortcut_settings; 0258 } 0259 0260 void GlaxnimateApp::set_clipboard_data(QMimeData *data) 0261 { 0262 return QGuiApplication::clipboard()->setMimeData(data); 0263 } 0264 0265 const QMimeData *GlaxnimateApp::get_clipboard_data() 0266 { 0267 return QGuiApplication::clipboard()->mimeData(); 0268 } 0269 0270 void glaxnimate::gui::GlaxnimateApp::on_initialize_translations() 0271 { 0272 app::TranslationService::instance().initialize("en_US"); 0273 } 0274 0275 bool GlaxnimateApp::event(QEvent *event) 0276 { 0277 if ( event->type() == QEvent::ApplicationPaletteChange ) 0278 icon_theme_fixup(); 0279 0280 return app::Application::event(event); 0281 } 0282 0283 #endif 0284 0285 0286 0287 QString GlaxnimateApp::temp_path() 0288 { 0289 QDir tempdir = QDir::temp(); 0290 QString subdir = AppInfo::instance().slug(); 0291 0292 if ( !tempdir.exists(subdir) ) 0293 if ( !tempdir.mkpath(subdir) ) 0294 return ""; 0295 0296 return tempdir.filePath(subdir); 0297 } 0298 0299 QString GlaxnimateApp::backup_path() const 0300 { 0301 0302 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) 0303 + QLatin1String("/stalefiles/") 0304 + QCoreApplication::instance()->applicationName() 0305 ; 0306 }