heic2jpg

git clone git://archive.git.mtrnord.blog/MTRNord/heic2jpg.git
Log | Files | Refs | README | LICENSE

commit 1411a3a7cb17ef68cf60b49a596520e65d6a609e
parent fa12b068886107bb42ea3ca2674cd8539d284fa6
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sun, 10 Nov 2024 14:59:26 +0100

Missing UI added and fixing some issue as well as adding translations

Diffstat:
D.gitlab-ci.yml | 43-------------------------------------------
MREADME.md | 71+++--------------------------------------------------------------------
Mbuild-aux/dev.nordgedanken.heic2jpg.Devel.json | 2+-
Mdata/dev.nordgedanken.heic2jpg.desktop.in.in | 4++--
Mdata/dev.nordgedanken.heic2jpg.metainfo.xml.in.in | 11+++++------
Mdata/resources/screenshots/screenshot1.png | 0
Mpo/LINGUAS | 2++
Mpo/POTFILES.in | 8++++++--
Apo/de.po | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apo/en.po | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apo/heic2jpg.pot | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/app.rs | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/conversion_worker.rs | 21+++++++++++++++++++++
Msrc/main.rs | 4++--
Msrc/select_folder.rs | 13+++++++------
15 files changed, 611 insertions(+), 162 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml @@ -1,43 +0,0 @@ -stages: - - check - - test - -flatpak: - image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-46' - stage: test - tags: - - flatpak - variables: - BUNDLE: "heic2jpg-nightly.flatpak" - MANIFEST_PATH: "build-aux/dev.nordgedanken.heic2jpg.Devel.json" - FLATPAK_MODULE: "heic2jpg" - APP_ID: "dev.nordgedanken.heic2jpg.Devel" - RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo" - script: - - flatpak install --user --noninteractive flathub org.freedesktop.Sdk.Extension.llvm16//23.08 - - > - xvfb-run -a -s "-screen 0 1024x768x24" - flatpak-builder --keep-build-dirs --user --disable-rofiles-fuse flatpak_app --repo=repo ${BRANCH:+--default-branch=$BRANCH} ${MANIFEST_PATH} - - flatpak build-bundle repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} ${APP_ID} ${BRANCH} - artifacts: - name: 'Flatpak artifacts' - expose_as: 'Get Flatpak bundle here' - when: 'always' - paths: - - "${BUNDLE}" - - '.flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/meson-logs/meson-log.txt' - - '.flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/meson-logs/testlog.txt' - expire_in: 14 days - -# Configure and run rustfmt -# Exits and builds fails if on bad format -rustfmt: - image: "rust:slim" - script: - - rustup component add rustfmt - # Create blank versions of our configured files - # so rustfmt does not yell about non-existent files or completely empty files - - echo -e "" >> src/config.rs - - rustc -Vv && cargo -Vv - - cargo fmt --version - - cargo fmt --all -- --color=always --check diff --git a/README.md b/README.md @@ -1,60 +1,4 @@ -# GTK + Rust + Relm4 + Meson + Flatpak = <3 - -> This is a fork of [gtk-rust-template](https://gitlab.gnome.org/World/Rust/gtk-rust-template) that adapts the code for Relm4 while trying to change as little as possible. - -A boilerplate template to get started with GTK, Rust, Meson, Flatpak made for GNOME. It can be adapted for other desktop environments like elementary. - -<div align="center"> - -![Main window](data/resources/screenshots/screenshot1.png "Main window") -</div> - -## What does it contains? - -- A simple window with a headerbar -- Bunch of useful files that you SHOULD ship with your application on Linux: - - Metainfo: describe your application for the different application stores out there; - - Desktop: the application launcher; - - Icons: This repo contains three icons, a normal, a nightly & monochromatic icon (symbolic) per the GNOME HIG, exported using [App Icon Preview](https://flathub.org/apps/details/org.gnome.design.AppIconPreview). -- Flatpak Manifest for nightly builds -- Dual installation support -- Uses Meson for building the application -- Bundles the UI files & the CSS using gresources -- A pre-commit hook to run rustfmt on your code -- Tests to validate your Metainfo, Schemas & Desktop files -- Gsettings to store the window state, more settings could be added -- Gitlab CI to produce flatpak nightlies -- i18n support - -## How to init a project ? - -The template ships a simple python script to init a project easily. It asks you a few questions and replaces & renames all the necessary files. - -The script requires having `git` installed on your system. - -If you clone this repository, you can run it with: - -```shell -python3 create-project.py -``` - -If you don't want to clone the repository, you can run it with: - -```shell -python3 -c "$(wget -q -O - https://raw.githubusercontent.com/Relm4/relm4-template/main/create-project.py)" --online -``` - -```shell -➜ python3 create-project.py -Welcome to GTK Rust Template -Name: Contrast -Project Name: contrast -Application ID (e.g. org.domain.MyAwesomeApp, see: https://developer.gnome.org/ChooseApplicationID/): org.gnome.design.Contrast -Author: Bilal Elmoussaoui -Email: bil.elmoussaoui@gmail.com -``` - -A new directory named `contrast` containing the generated project +# HEIC2JPG ## Building the project @@ -73,15 +17,6 @@ Once the project is build, run the command below. Replace Replace `<application_ flatpak-builder --run flatpak_app build-aux/<application_id>.Devel.json <project_name> ``` -## Community - -Join the GNOME and gtk-rs community! - -- [Matrix chat](https://matrix.to/#/#rust:gnome.org): chat with other developers using gtk-rs -- [Discourse forum](https://discourse.gnome.org/tag/rust): topics tagged with `rust` on the GNOME forum. -- [GNOME circle](https://circle.gnome.org/): take inspiration from applications and libraries already extending the GNOME ecosystem. - -## Credits +## Extract gettext strings -- [Podcasts](https://gitlab.gnome.org/World/podcasts) -- [Shortwave](https://gitlab.gnome.org/World/Shortwave) +`xgettext --package-name=heic2jpg --package-version=main --msgid-bugs-address=https://github.com/MTRNord/heic2jpg/issues --files-from=po/POTFILES.in --output=po/heic2jpg.pot` diff --git a/build-aux/dev.nordgedanken.heic2jpg.Devel.json b/build-aux/dev.nordgedanken.heic2jpg.Devel.json @@ -10,6 +10,7 @@ "command": "heic2jpg", "finish-args": [ "--share=ipc", + "--filesystem=host:create", "--socket=fallback-x11", "--socket=wayland", "--device=dri", @@ -52,4 +53,3 @@ } ] } - diff --git a/data/dev.nordgedanken.heic2jpg.desktop.in.in b/data/dev.nordgedanken.heic2jpg.desktop.in.in @@ -5,8 +5,8 @@ Type=Application Exec=heic2jpg Terminal=false Categories=Graphics; -# Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +# TRANSLATORS: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! Keywords=Gnome;GTK; -# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +# TRANSLATORS: Do NOT translate or transliterate this text (this is an icon file name)! Icon=@icon@ StartupNotify=true diff --git a/data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in b/data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in @@ -3,12 +3,11 @@ <component type="desktop-application"> <id>@app-id@</id> <metadata_license>CC0</metadata_license> - <!-- Insert your license of choice here --> - <!-- <project_license>MIT</project_license> --> + <project_license>AGPL-3.0</project_license> <name>Heic2JPG</name> - <summary>Write a GTK + Rust application</summary> + <summary>A small app to batch convert heic images to jpg</summary> <description> - <p>A boilerplate template for GTK + Rust. It uses Meson as a build system and has flatpak support by default.</p> + <p>A small app to batch convert heic images to jpg.</p> </description> <categories> <category>Graphics</category> @@ -19,8 +18,8 @@ <caption>Main window</caption> </screenshot> </screenshots> - <url type="homepage">https://gitlab.gnome.org/bilelmoussaoui/heic2jpg</url> - <url type="bugtracker">https://gitlab.gnome.org/bilelmoussaoui/heic2jpg/issues</url> + <url type="homepage">https://github.com/MTRNord/heic2jpg</url> + <url type="bugtracker">https://github.com/MTRNord/heic2jpg/issues</url> <content_rating type="oars-1.1" /> <releases> <release version="0.1.0" date="2019-07-11" /> diff --git a/data/resources/screenshots/screenshot1.png b/data/resources/screenshots/screenshot1.png Binary files differ. diff --git a/po/LINGUAS b/po/LINGUAS @@ -0,0 +1,2 @@ +en +de diff --git a/po/POTFILES.in b/po/POTFILES.in @@ -2,5 +2,9 @@ data/dev.nordgedanken.heic2jpg.desktop.in.in data/dev.nordgedanken.heic2jpg.gschema.xml.in data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in data/resources/ui/shortcuts.ui -data/resources/ui/window.ui -src/application.rs +src/app.rs +src/main.rs +src/select_folder.rs +src/conversion_worker.rs +src/modals/about.rs +src/modals/mod.rs diff --git a/po/de.po b/po/de.po @@ -0,0 +1,146 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: heic2jpg main\n" +"Report-Msgid-Bugs-To: https://github.com/MTRNord/heic2jpg/issues\n" +"POT-Creation-Date: 2024-11-10 14:37+0100\n" +"PO-Revision-Date: 2024-11-10 14:38+0100\n" +"Last-Translator: MTRNord <mtrnord@nordgedanken.dev>\n" +"Language-Team: \n" +"Language: de_DE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.4\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:3 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:7 +msgid "Heic2JPG" +msgstr "Heic2JPG" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:4 +msgid "An application to convert heic images to JPG images" +msgstr "Eine Anwendung um heic bilder in JPG Bilder umzuwandeln" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:10 +msgid "Gnome;GTK;" +msgstr "Gnome;GTK;" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:6 +msgid "Window width" +msgstr "Fenster Breite" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:10 +msgid "Window height" +msgstr "Fenster Höhe" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:14 +msgid "Window maximized state" +msgstr "Fenster Maximierungszustand" + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:8 +msgid "A small app to batch convert heic images to jpg" +msgstr "Eine kleine Anwendung um viele heic bilder nach jpg umzuwandeln" + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:10 +msgid "A small app to batch convert heic images to jpg." +msgstr "Eine kleine Anwendung um viele heic bilder nach jpg umzuwandeln." + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:18 +msgid "Main window" +msgstr "Haupt Fenster" + +#. developer_name tag deprecated with Appstream 1.0 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:36 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:39 +msgid "MTRNord" +msgstr "MTRNord" + +#: data/resources/ui/shortcuts.ui:11 +msgctxt "shortcut window" +msgid "General" +msgstr "Allgemein" + +#: data/resources/ui/shortcuts.ui:14 +msgctxt "shortcut window" +msgid "Show Shortcuts" +msgstr "Zeige Tastaurbefehle" + +#: data/resources/ui/shortcuts.ui:20 +msgctxt "shortcut window" +msgid "Quit" +msgstr "Beenden" + +#: src/app.rs:104 +msgid "Convert Heic to JPG" +msgstr "Wandle Heic nach JPG" + +#: src/app.rs:117 +msgid "Converting" +msgstr "Umwandeln" + +#: src/app.rs:118 +msgid "Please wait while the conversion is in progress" +msgstr "Bitte warte während die Umwandlung stattfindet" + +#: src/app.rs:129 +msgid "Conversion Complete" +msgstr "Umwandlung vollständig" + +#: src/app.rs:130 +msgid "The conversion was successful" +msgstr "Die Umwandlung war erfolgreich" + +#: src/app.rs:144 +msgid "Conversion Failed" +msgstr "Umwandlung fehlgeschlagen" + +#: src/app.rs:148 +msgid "Close" +msgstr "Schließen" + +#: src/app.rs:173 +msgid "Start Conversion" +msgstr "Umwandlung beginnen" + +#: src/app.rs:174 +msgid "Click the button below to start the conversion" +msgstr "Drücke den Knopf um die Umwandlung zu beginnen" + +#: src/app.rs:181 +msgid "Convert" +msgstr "Umwandeln" + +#: src/app.rs:300 +msgid "Please select both input and output folders" +msgstr "Bitte wähle sowohl Eingabe- als auch Ausgabe-Ordner aus" + +#: src/select_folder.rs:48 +msgid "Select Folder" +msgstr "Verzeichnis wählen" + +#: src/select_folder.rs:68 +msgid "Abort" +msgstr "Abbrechen" + +#: src/select_folder.rs:84 +msgid "Select the folder where the Heic files can be found" +msgstr "Wähle einen Ordner in dem sich die Heic Dateien befinden" + +#: src/select_folder.rs:85 +msgid "Select input directory" +msgstr "Wähle das Eingabeverzeichnis" + +#: src/select_folder.rs:88 +msgid "Select the folder where the JPG files are meant to be saved" +msgstr "Wähle einen Ordner in dem die JPG Dateien gespeichert werden sollen" + +#: src/select_folder.rs:89 +msgid "Select output directory" +msgstr "Wähle das Ausgabeverzeichnis" diff --git a/po/en.po b/po/en.po @@ -0,0 +1,146 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: heic2jpg main\n" +"Report-Msgid-Bugs-To: https://github.com/MTRNord/heic2jpg/issues\n" +"POT-Creation-Date: 2024-11-10 14:37+0100\n" +"PO-Revision-Date: 2024-11-10 14:38+0100\n" +"Last-Translator: MTRNord <mtrnord@nordgedanken.dev>\n" +"Language-Team: \n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.4\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:3 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:7 +msgid "Heic2JPG" +msgstr "Heic2JPG" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:4 +msgid "An application to convert heic images to JPG images" +msgstr "An application to convert heic images to JPG images" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:10 +msgid "Gnome;GTK;" +msgstr "Gnome;GTK;" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:6 +msgid "Window width" +msgstr "Window width" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:10 +msgid "Window height" +msgstr "Window height" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:14 +msgid "Window maximized state" +msgstr "Window maximized state" + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:8 +msgid "A small app to batch convert heic images to jpg" +msgstr "A small app to batch convert heic images to jpg" + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:10 +msgid "A small app to batch convert heic images to jpg." +msgstr "A small app to batch convert heic images to jpg." + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:18 +msgid "Main window" +msgstr "Main window" + +#. developer_name tag deprecated with Appstream 1.0 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:36 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:39 +msgid "MTRNord" +msgstr "MTRNord" + +#: data/resources/ui/shortcuts.ui:11 +msgctxt "shortcut window" +msgid "General" +msgstr "General" + +#: data/resources/ui/shortcuts.ui:14 +msgctxt "shortcut window" +msgid "Show Shortcuts" +msgstr "Show Shortcuts" + +#: data/resources/ui/shortcuts.ui:20 +msgctxt "shortcut window" +msgid "Quit" +msgstr "Quit" + +#: src/app.rs:104 +msgid "Convert Heic to JPG" +msgstr "Convert Heic to JPG" + +#: src/app.rs:117 +msgid "Converting" +msgstr "Converting" + +#: src/app.rs:118 +msgid "Please wait while the conversion is in progress" +msgstr "Please wait while the conversion is in progress" + +#: src/app.rs:129 +msgid "Conversion Complete" +msgstr "Conversion Complete" + +#: src/app.rs:130 +msgid "The conversion was successful" +msgstr "The conversion was successful" + +#: src/app.rs:144 +msgid "Conversion Failed" +msgstr "Conversion Failed" + +#: src/app.rs:148 +msgid "Close" +msgstr "Close" + +#: src/app.rs:173 +msgid "Start Conversion" +msgstr "Start Conversion" + +#: src/app.rs:174 +msgid "Click the button below to start the conversion" +msgstr "Click the button below to start the conversion" + +#: src/app.rs:181 +msgid "Convert" +msgstr "Convert" + +#: src/app.rs:300 +msgid "Please select both input and output folders" +msgstr "Please select both input and output folders" + +#: src/select_folder.rs:48 +msgid "Select Folder" +msgstr "Select Folder" + +#: src/select_folder.rs:68 +msgid "Abort" +msgstr "Abort" + +#: src/select_folder.rs:84 +msgid "Select the folder where the Heic files can be found" +msgstr "Select the folder where the Heic files can be found" + +#: src/select_folder.rs:85 +msgid "Select input directory" +msgstr "Select input directory" + +#: src/select_folder.rs:88 +msgid "Select the folder where the JPG files are meant to be saved" +msgstr "Select the folder where the JPG files are meant to be saved" + +#: src/select_folder.rs:89 +msgid "Select output directory" +msgstr "Select output directory" diff --git a/po/heic2jpg.pot b/po/heic2jpg.pot @@ -0,0 +1,144 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the heic2jpg package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: heic2jpg main\n" +"Report-Msgid-Bugs-To: https://github.com/MTRNord/heic2jpg/issues\n" +"POT-Creation-Date: 2024-11-10 14:37+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:3 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:7 +msgid "Heic2JPG" +msgstr "" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:4 +msgid "An application to convert heic images to JPG images" +msgstr "" + +#: data/dev.nordgedanken.heic2jpg.desktop.in.in:10 +msgid "Gnome;GTK;" +msgstr "" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:6 +msgid "Window width" +msgstr "" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:10 +msgid "Window height" +msgstr "" + +#: data/dev.nordgedanken.heic2jpg.gschema.xml.in:14 +msgid "Window maximized state" +msgstr "" + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:8 +msgid "A small app to batch convert heic images to jpg" +msgstr "" + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:10 +msgid "A small app to batch convert heic images to jpg." +msgstr "" + +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:18 +msgid "Main window" +msgstr "" + +#. developer_name tag deprecated with Appstream 1.0 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:36 +#: data/dev.nordgedanken.heic2jpg.metainfo.xml.in.in:39 +msgid "MTRNord" +msgstr "" + +#: data/resources/ui/shortcuts.ui:11 +msgctxt "shortcut window" +msgid "General" +msgstr "" + +#: data/resources/ui/shortcuts.ui:14 +msgctxt "shortcut window" +msgid "Show Shortcuts" +msgstr "" + +#: data/resources/ui/shortcuts.ui:20 +msgctxt "shortcut window" +msgid "Quit" +msgstr "" + +#: src/app.rs:104 +msgid "Convert Heic to JPG" +msgstr "" + +#: src/app.rs:117 +msgid "Converting" +msgstr "" + +#: src/app.rs:118 +msgid "Please wait while the conversion is in progress" +msgstr "" + +#: src/app.rs:129 +msgid "Conversion Complete" +msgstr "" + +#: src/app.rs:130 +msgid "The conversion was successful" +msgstr "" + +#: src/app.rs:144 +msgid "Conversion Failed" +msgstr "" + +#: src/app.rs:148 +msgid "Close" +msgstr "" + +#: src/app.rs:173 +msgid "Start Conversion" +msgstr "" + +#: src/app.rs:174 +msgid "Click the button below to start the conversion" +msgstr "" + +#: src/app.rs:181 +msgid "Convert" +msgstr "" + +#: src/app.rs:300 +msgid "Please select both input and output folders" +msgstr "" + +#: src/select_folder.rs:48 +msgid "Select Folder" +msgstr "" + +#: src/select_folder.rs:68 +msgid "Abort" +msgstr "" + +#: src/select_folder.rs:84 +msgid "Select the folder where the Heic files can be found" +msgstr "" + +#: src/select_folder.rs:85 +msgid "Select input directory" +msgstr "" + +#: src/select_folder.rs:88 +msgid "Select the folder where the JPG files are meant to be saved" +msgstr "" + +#: src/select_folder.rs:89 +msgid "Select output directory" +msgstr "" diff --git a/src/app.rs b/src/app.rs @@ -2,6 +2,7 @@ use crate::config::{APP_ID, PROFILE}; use crate::conversion_worker::{ConversionWorker, ConversionWorkerInputMsg, ConversionWorkerMsg}; use crate::modals::about::AboutDialog; use crate::select_folder::{InOut, SelectFolder, SelectFolderOut}; +use gettextrs::gettext; use gtk::prelude::*; use gtk::{gio, glib}; use relm4::{ @@ -11,6 +12,15 @@ use relm4::{ }; use std::path::PathBuf; +enum Mode { + InputSelection, + OutputSelection, + ConversionSelection, + Progressing, + Finished, + Failed, +} + pub(super) struct App { about_dialog: Controller<AboutDialog>, input_folder_selector: Controller<SelectFolder>, @@ -18,6 +28,9 @@ pub(super) struct App { input_folder: Option<PathBuf>, output_folder: Option<PathBuf>, conversion_worker: WorkerController<ConversionWorker>, + mode: Mode, + progress: f64, + failure: Option<String>, } #[derive(Debug)] @@ -27,6 +40,9 @@ pub(super) enum AppMsg { DeselectInputFolder, DeselectOutputFolder, Convert, + ProgressUpdate(f64), + ConversionComplete, + ConversionFailed(String), Quit, Noop, } @@ -85,7 +101,7 @@ impl SimpleComponent for App { adw::HeaderBar { #[wrap(Some)] set_title_widget = &adw::WindowTitle { - set_title: "Convert Heic to JPG", + set_title: &gettext("Convert Heic to JPG"), }, pack_end = &gtk::MenuButton { set_icon_name: "open-menu-symbolic", @@ -93,40 +109,86 @@ impl SimpleComponent for App { } }, - // If no folder is selected, show the folder selector - if model.input_folder.is_some() && model.output_folder.is_some() { - adw::StatusPage { - set_hexpand: true, - set_vexpand: true, - set_title: "Start Conversion", - set_description: Some("Press the button to start the conversion"), + match model.mode { + Mode::Progressing => { + adw::StatusPage { + set_hexpand: true, + set_vexpand: true, + set_title: &gettext("Converting"), + set_description: Some(&gettext("Please wait while the conversion is in progress")), + + gtk::ProgressBar { + #[watch] + set_fraction: model.progress, + } + } + } + Mode::Finished => { + adw::StatusPage { + set_hexpand: true, + set_vexpand: true, + set_title: &gettext("Conversion Complete"), + set_description: Some(&gettext("The conversion was successful")), + + gtk::Button { + set_label: "Close", + connect_clicked[sender] => move |_| { + sender.input(AppMsg::Quit); + } + } + } + } + Mode::Failed => { + adw::StatusPage { + set_hexpand: true, + set_vexpand: true, + set_title: &gettext("Conversion Failed"), + #[watch] + set_description: model.failure.as_deref(), - gtk::Box { - set_halign: gtk::Align::Center, - set_orientation: gtk::Orientation::Horizontal, - set_spacing: 24, gtk::Button { - set_label: "Convert", + set_label: &gettext("Close"), connect_clicked[sender] => move |_| { - sender.input(AppMsg::Convert); + sender.input(AppMsg::Quit); } } } } - } else if model.input_folder.is_none() { - gtk::Box { - set_vexpand: true, - set_hexpand: true, - append = model.input_folder_selector.widget(), + Mode::InputSelection => { + gtk::Box { + set_vexpand: true, + set_hexpand: true, + append = model.input_folder_selector.widget(), + } } - } else { - gtk::Box { - set_vexpand: true, - set_hexpand: true, - append = model.output_folder_selector.widget(), + Mode::OutputSelection => { + gtk::Box { + set_vexpand: true, + set_hexpand: true, + append = model.output_folder_selector.widget(), + } + } + Mode::ConversionSelection => { + adw::StatusPage { + set_hexpand: true, + set_vexpand: true, + set_title: &gettext("Start Conversion"), + set_description: Some(&gettext("Click the button below to start the conversion")), + + gtk::Box { + set_halign: gtk::Align::Center, + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 24, + gtk::Button { + set_label: &gettext("Convert"), + connect_clicked[sender] => move |_| { + sender.input(AppMsg::Convert); + } + } + } + } } } - } } @@ -160,9 +222,9 @@ impl SimpleComponent for App { .detach_worker(()) .forward(sender.input_sender(), |msg| match msg { ConversionWorkerMsg::ConversionStarted => AppMsg::Noop, - ConversionWorkerMsg::ProgressUpdate(_) => AppMsg::Noop, - ConversionWorkerMsg::ConversionComplete => AppMsg::Noop, - ConversionWorkerMsg::ConversionFailed(_) => AppMsg::Noop, + ConversionWorkerMsg::ProgressUpdate(number) => AppMsg::ProgressUpdate(number), + ConversionWorkerMsg::ConversionComplete => AppMsg::ConversionComplete, + ConversionWorkerMsg::ConversionFailed(e) => AppMsg::ConversionFailed(e), }); let model = Self { @@ -172,6 +234,9 @@ impl SimpleComponent for App { conversion_worker, input_folder: None, output_folder: None, + mode: Mode::InputSelection, + progress: 0.0, + failure: None, }; let widgets = view_output!(); @@ -203,10 +268,22 @@ impl SimpleComponent for App { fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) { match message { - AppMsg::InputFolderSelected(path) => self.input_folder = Some(path), - AppMsg::DeselectInputFolder => self.input_folder = None, - AppMsg::OutputFolderSelected(path) => self.output_folder = Some(path), - AppMsg::DeselectOutputFolder => self.output_folder = None, + AppMsg::InputFolderSelected(path) => { + self.input_folder = Some(path); + self.mode = Mode::OutputSelection + } + AppMsg::DeselectInputFolder => { + self.input_folder = None; + self.mode = Mode::InputSelection + } + AppMsg::OutputFolderSelected(path) => { + self.output_folder = Some(path); + self.mode = Mode::ConversionSelection + } + AppMsg::DeselectOutputFolder => { + self.output_folder = None; + self.mode = Mode::OutputSelection + } AppMsg::Quit => main_application().quit(), AppMsg::Convert => { if let (Some(input_folder), Some(output_folder)) = @@ -218,8 +295,25 @@ impl SimpleComponent for App { output_folder.clone(), ), ); + self.mode = Mode::Progressing; + } else { + self.mode = Mode::Failed; + self.failure = + Some(gettext("Please select both input and output folders").to_string()); } } + AppMsg::ProgressUpdate(progress) => { + if let Mode::Progressing = self.mode { + self.progress = progress; + } + } + AppMsg::ConversionComplete => { + self.mode = Mode::Finished; + } + AppMsg::ConversionFailed(e) => { + self.mode = Mode::Failed; + self.failure = Some(e); + } AppMsg::Noop => {} } } diff --git a/src/conversion_worker.rs b/src/conversion_worker.rs @@ -1,6 +1,7 @@ use magick_rust::{MagickError, MagickWand}; use std::path::PathBuf; use std::result::Result; +use tracing::info; use walkdir::WalkDir; use relm4::{ComponentSender, Worker}; @@ -33,11 +34,13 @@ impl Worker for ConversionWorker { match msg { ConversionWorkerInputMsg::ConvertFolder(input_path, output_path) => { // Start the conversion + info!("Starting conversion of folder {:?}", input_path); sender .output(ConversionWorkerMsg::ConversionStarted) .unwrap(); // Walk directory, find all heic files, convert them to jpg and update progress + info!("Converting folder {:?}", input_path); let result = self.convert_folder(input_path, output_path, |progress| { sender .output(ConversionWorkerMsg::ProgressUpdate(progress)) @@ -65,12 +68,25 @@ impl ConversionWorker { output_path: PathBuf, progress_callback: F, ) -> Result<(), MagickError> { + info!("Converting folder {:?} to {:?}", input_path, output_path); + // List files in folder for debugging + for entry in WalkDir::new(&input_path) + .follow_links(true) + .same_file_system(false) + { + let entry = entry.unwrap(); + info!("Found {:?}", entry.path()); + } + // Use walkdir to find all heic files in the input directory let heic_files: Vec<PathBuf> = WalkDir::new(input_path) + .follow_links(true) + .same_file_system(false) .into_iter() .filter_map(|entry| { let entry = entry.ok()?; let path = entry.path(); + info!("Checking file {:?}", path); if path.is_file() && path.extension().map_or(false, |ext| ext == "heic") { Some(path.to_path_buf()) } else { @@ -78,9 +94,11 @@ impl ConversionWorker { } }) .collect(); + info!("Found {} heic files", heic_files.len()); // Convert each heic file to jpg for (index, heic_file) in heic_files.iter().enumerate() { + info!("Converting file {:?}", heic_file); let output_file = output_path .join(heic_file.file_stem().unwrap()) .with_extension("jpg"); @@ -91,6 +109,7 @@ impl ConversionWorker { // Update the progress progress_callback((index + 1) as f64 / heic_files.len() as f64); } + info!("Conversion complete"); Ok(()) } @@ -103,10 +122,12 @@ impl ConversionWorker { let mut wand = MagickWand::new(); // Read the input file + info!("Reading file {:?}", input_file); wand.read_image(input_file.to_str().unwrap())?; // Convert the image to jpg wand.set_image_format("jpg")?; + info!("Converting to jpg"); wand.write_image(output_file.to_str().unwrap())?; Ok(()) diff --git a/src/main.rs b/src/main.rs @@ -6,7 +6,7 @@ mod modals; mod select_folder; use config::{APP_ID, GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE}; -use gettextrs::{gettext, LocaleCategory}; +use gettextrs::LocaleCategory; use gtk::prelude::ApplicationExt; use gtk::{gio, glib}; use magick_rust::magick_wand_genesis; @@ -41,7 +41,7 @@ fn main() { gettextrs::bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain"); gettextrs::textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain"); - glib::set_application_name(&gettext("Heic2JPG")); + glib::set_application_name("Heic2JPG"); let res = gio::Resource::load(RESOURCES_FILE).expect("Could not load gresource file"); gio::resources_register(&res); diff --git a/src/select_folder.rs b/src/select_folder.rs @@ -1,3 +1,4 @@ +use gettextrs::gettext; use gtk::prelude::*; use relm4::{ adw, gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, @@ -44,7 +45,7 @@ impl SimpleComponent for SelectFolder { adw::StatusPage { set_hexpand: true, set_vexpand: true, - set_title: "Select Folder", + set_title: &gettext("Select Folder"), set_description: Some(&model.description), gtk::Box { @@ -64,7 +65,7 @@ impl SimpleComponent for SelectFolder { gtk::Button { set_visible: model.direction == InOut::Output, set_halign: gtk::Align::Center, - set_label: "Abort", + set_label: &gettext("Abort"), connect_clicked[sender] => move |_| { let _ = sender.output(SelectFolderOut::AbortLast); } @@ -80,12 +81,12 @@ impl SimpleComponent for SelectFolder { ) -> ComponentParts<Self> { let (description, button_label) = match init { InOut::Input => ( - "Select the folder where the Heic files can be found", - "Select input directory", + gettext("Select the folder where the Heic files can be found"), + gettext("Select input directory"), ), InOut::Output => ( - "Select the folder where the JPG files are meant to be saved", - "Select output directory", + gettext("Select the folder where the JPG files are meant to be saved"), + gettext("Select output directory"), ), };