Wallpaper Finer
===============

:date: 2021-06-20
:tags: blog, qt, portage, c++
:keywords: wallpaper finer, portage, C++, Qt5, Qt4
:slug: wallpaper-finer
:url: wallpaper-finer

Wallpaper finer est un petit logiciel libre et open source (GPLv2), permettant de redimensionner et recadrer très facilement et rapidement une image. Son principal défaut ? Il utilise encore Qt 4.

Comment modifier le code de ce logiciel pour utiliser Qt5 ? Réponse dans cet article.

TL;DR (trop long, flemme de tout lire) : le code source du portage vers Qt5 est disponible ici :

https://gitlab.com/chibinah/wallpaperfiner

Compilation :

. code-block:: bash

   mkdir build
   cd build
   qmake ../WallpaperFiner.pro
   make

Vérification que ça utilise bien qt5 :

. code-block:: bash

   ldd wallpaperfiner

Exécution :

. code-block:: bash

   ./wallpaperfiner


Introduction
------------

Tout est parti d'un pouët de @TritTriton[ref] `<https://shelter.moe/@TritTriton/106436810381701106>`_ [/ref], qui parlait d'un petit logiciel permettant de recadrer et redimensionner une image facilement. Son seul reproche, c'est que c'est en Qt4[ref]qui date quand même de 2005, et dont la dernière mise à jour date de 2012.[/ref]. Cela impose donc de garder un framework[ref]En français, on est censé parler de cadriciel, mais personne ne connait ça sous ce nom[/ref] ancien sur sa machine.

. image:: images/wpfiner/wpfiner.jpg

L'application (une fois le portage vers Qt5 effectué) en action.

Le code source
--------------

. note:: Tout a été rédigé avec GNU/Linux, notamment Debian, en tête. Rien n'a été testé sous Windows, aucune aide ni support ne sera apporté de ma part pour ce système d'exploitation.

. note:: Ici, j'ai utilisé Qt Creator pour des raisons pratiques[ref]Même si je n'aime pas la disposition de l'environnement de développement intégré (IDE), ni sa traduction inconsistente (c'est à moitié traduit en français).[/ref]. J'aurais pu utiliser geany, vscode, vim, emacs ou autre éditeur de texte.

Le code source de Wallpaper Finer est disponible sur le site du développeur, Péter Deák[ref] `<http://hyperprog.com/wpfiner/index.html>`_ [/ref], et est sous licence GPL v2. La dernière version date du mois d'août 2012[ref]ce qui correspond à Qt 4.8, Qt 5 étant sorti après[/ref].

Le projet s'ouvre sans souci avec Qt Creator[ref]Ça peut être utile d'installer Qt5, les outils de développement, etc. Se référer à la documentation ou au gestionnaire de paquets de la distribution utilisée. Idem : je n'apporterai aucune aide sur comment installer et ou configurer le tout.[/ref]. Le projet étant créé avec Qt4, il faut modifier la configuration pour utiliser la bonne version de Qt. Lors de la rédaction de l'article, on en était à la version 5.15.2[ref]En tout cas, sous Debian GNU/Linux[/ref].

. image:: images/wpfiner/qtcreator1.jpg

Lors de l'ouverture du projet, Qt Creator demande de le configurer, notamment la cible, ici Desktop (Qt5).

Il faut quand même vérifier si c'est bien la bonne version de Qt qui est sélectionnée, pour éviter toute surprise si jamais on a plusieurs versions du framework[ref]Cadriciel. Ce terme est barbant, je vais laisser framework partout dans l'article.[/ref].

. image:: images/wpfiner/qtcreator2.jpg

Liste des kits de développement (SDK) paramétrés. Ayant fait du ménage dedans, il n'y a plus que Desktop (Qt5).

. image:: images/wpfiner/qtcreator3.jpg

Versions de Qt installées. Version 4.8.7 (Qt4) et version 5.15.2 (Qt5).

Tout est bon ? On peut continuer.

Cliquer sur le bouton "Configure project".

Au bout de quelques instants, le projet s'affiche sous Projets, en haut à gauche.

. image:: images/wpfiner/qtcreator4.jpg

Par défaut, tous les nœuds de l'arborescence sont repliés.

Adaptations à faire
-------------------

Projet
~~~~~~

Il y a quelques modifications à faire dans WallpaperFiner.pro.

Ajouter *widgets* à droite, sur la ligne QT :

. code-block:: c++

   QT       += core gui widgets

Pour la traduction en français, ajouter *wpfiner_fr.ts* à droite, sur la ligne TRANSLATIONS :

. code-block:: c++

   TRANSLATIONS = wpfiner_hu.ts wpfiner_pl.ts wpfiner_fr.ts


. image:: images/wpfiner/qtcreator5.jpg

Modifications effectuées dans WallpaperFiner.pro.

Enregistrer et fermer le fichier.

Traduction fr
~~~~~~~~~~~~~

On va tout de suite ajouter la traduction en français.

* Ouvrir le nœud Other files.
* Dupliquer le fichier wpfiner_pl.ts.
* Nommer le fichier wpfiner_fr.ts.

. image:: images/wpfiner/qtcreator6.jpg

Duplication du fichier pour la traduction.

. image:: images/wpfiner/qtcreator7.jpg

Nommage du fichier.

Ouvrir le fichier *wpfiner_fr.ts* en double-cliquant dessus. On va faire une modification dans ce fichier xml.

Dans *TS*, changer la langue de *pl_PL* à *fr_FR*, pour *language* et *sourceLanguage*.

. code-block:: xml

   <TS version="2.0" language="fr_FR" sourcelanguage="fr_FR">

. image:: images/wpfiner/qtcreator8.jpg

Modifications effectuées.


Enregistrer et fermer le fichier.


Ouvrir maintenant le fichier *wpfiner_fr.ts* avec Qt Linguist (l'outil dédié pour la traduction).

. Note:: On peut aussi éditer le fichier xml à la main. Mais ce n'est pas forcément pratique et c'est source d'erreurs.

. image:: images/wpfiner/qtcreator9.jpg

Menu contextuel -> Ouvrir avec

. image:: images/wpfiner/qtlinguist1.jpg

Qt Linguist. Comparé à un outil léger comme PoEdit, l'interface semble compliquée.

Faire la traduction des différents textes et messages. Je ne m'attarderai pas dessus, ce n'est pas très difficile.

. image:: images/wpfiner/qtlinguist2.jpg

Traduction française terminée.

Cliquer sur le menu Fichier -> Publier pour générer le fichier wpfiner_fr.qm. On en aura besoin par la suite.

. image:: images/wpfiner/qtlinguist3.jpg

Menu Fichier -> Publier.

Fermer Qt Linguist.

Dans Qt Creator, ouvrir le nœud Resources, wpfiner.qrc, /

Faire un clic droit sur / -> Ajouter des fichiers existants…

. image:: images/wpfiner/qtcreator10.jpg

Menu contextuel -> Ajouter des fichiers existants…

Sélectionner le fichier wpfiner_fr.qm et cliquer sur Ouvrir.

. image:: images/wpfiner/qtcreator11.jpg

Boîte de dialogue de sélection de fichiers.


Entête (wpfiner.h)
~~~~~~~~~~~~~~~~~~~

Ouvrir le fichier *wpfiner.h*.

Modifier le numéro de version en 0.95 (la version étant 0.94).

. code-block:: c++

   #define VERSION "0.95"

Dans ce fichier, il y a une erreur (indiquée en rouge) :

* expected class name.

Pour corriger cette erreur, il faut ajouter des #includes supplémentaires.

. note:: S'aider de la documentation du SDK Qt, notamment les pages de migration Qt4 vers Qt5.

Les entêtes à ajouter sous #include <QtCore> sont :

. code-block:: c++

   #include <QMainWindow>
   #include <QFrame>
   #include <QMenu>
   #include <QMenuBar>
   #include <QMessageBox>
   #include <QFileDialog>

. image:: images/wpfiner/qtcreator12.jpg

Modifications effectuées.

. note:: il reste un warning (ligne jaune), ne pas en tenir compte pour le moment[ref]En fait, j'ai carrément ignoré tous les warnings dans le code source, cela concerne des fonctions ou des instructions dépréciées.[/ref]

Enregistrer et fermer le fichier wpfiner.h.

C++ (main.cpp)
~~~~~~~~~~~~~~

Ouvrir le fichier *main.cpp*.

Il y a deux erreurs dans ce fichier :

* QtGui/QApplication: No such file or directory ;
* variable has incomplete type 'QApplication'.

Pour corriger ces erreurs, il faut également modifier les includes.

Supprimer cet include :

. code-block:: c++

   #include <QtGui/QApplication>

Cet include n'existe plus dans Qt5.

Ajouter les deux includes suivants :

. code-block:: c++

   #include <QtWidgets>
   #include <QMainWindow>

Profiton-en pour ajouter la traduction française dans la liste des traductions.

Modifier la ligne #define INSTALLED_LANGNUM en remplaçant la valeur 3 par 4

. code-block:: c++

   #define INSTALLED_LANGNUM  4

Modifier la liste des langues en remplaçant également [3] par [4], et en ajoutant une ligne supplémentaire référençant la langue française.

. code-block:: c++

   char langs[INSTALLED_LANGNUM][4][30] = {
       {"English"  ,"en",""},
       {"French"   ,"fr",":/wpfiner_fr.qm"},
       {"Hungarian","hu",":/wpfiner_hu.qm"},
       {"Polish"   ,"pl",":/wpfiner_pl.qm"}
   };

. image:: images/wpfiner/qtcreator13.jpg

Modifications effectuées.

Enregistrer et fermer le fichier main.cpp.

. note:: Comme je ne tiens pas compte de la version Windows[ref]Comme indiqué au début de l'article[/ref], tout le code défini dans #ifdef Q_WS_WIN n'a pas été modifié. Il y a de fortes chances pour que la traduction française ne fonctionne pas sous Windows. Il faudra modifier le code en conséquence.


C++ (wpfiner.cpp)
~~~~~~~~~~~~~~~~~

Ouvrir le fichier *wpfiner.cpp*.

Quatre erreurs sont présentes ici (en fait, il n'y en a que deux, les deux autres en découlent) :

* invalid use of incomplete type class 'QDesktopWidget'
* class 'QString' has no member named 'toAscii'
* member access into incomplete type 'QDesktopWidget'
* no member named 'toAscii' in 'QString'

Pour la première erreur, c'est encore un problème d'include. Remplacer QtGui par QtWidgets.

Supprimer cet include :

. code-block:: c++

   #include <QtGui>

Ajouter cet include :

. code-block:: c++

   #include <QtWidgets>

. image:: images/wpfiner/qtcreator14.jpg

Modifications effectuées côté include.

Concernant la seconde erreur, la méthode toAscii() n'existe plus. On va utiliser toLatin1() à la place

Descendre vers la ligne 339[ref]tout dépend de la présence de sauts de lignes supplémentaires côté code.[/ref].

Remplacer :

. code-block:: c++

   finedImage.save(&finedFile,save_format.toAscii().data());

par :

. code-block:: c++

   finedImage.save(&finedFile,save_format.toLatin1().data());

. image:: images/wpfiner/qtcreator15.jpg

Appel de la méthode corrigée


Enregistrer et fermer le fichier wpfiner.cpp.


Compilation
~~~~~~~~~~~

C'est bon ? On peut compiler le projet.

Pour cela, cliquer sur le petit marteau en bas à gauche, ou passer par le menu Compiler -> Build all projects

Un petit Build devrait apparaître en bas, vers la droite, pour indiquer que le projet est en cours de compilation.

. image:: images/wpfiner/qtcreator16.jpg

Compilation en cours.

Une fois la compilation terminée, cliquer sur l'onglet *Problèmes* en bas.

Normalement, si tout a été modifié correctement, il ne devrait pas y avoir d'erreurs en rouge. Juste quelques avertissements (warnings) en jaune, notamment des appels dépréciés qu'il faudrait remplacer.

. image:: images/wpfiner/qtcreator17.jpg

Liste des problèmes trouvés. Aucune erreur, uniquement des avertissements.

Test
~~~~

C'est bon ? On peut tester ?

On peut.

Cliquer sur le triangle en bas à gauche (celui du haut, pas celui du bas avec un insecte dessus).

L'application doit se lancer sans problème.

. image:: images/wpfiner/wpfiner2.jpg

L'application a démarré.

Ouvrir une image ou la glisser-déposer sur la fenêtre, et vérifier le bon fonctionnement du redimensionnement et du recadrage de l'image. Vérifier aussi que l'enregistrement de l'image fonctionne aussi.


. note:: Le bouton « Définir comme fond d'écran[ref]To Desktop en anglais[/ref] » crée un répertoire *WpFiner* dans le répertoire $home, enregistre l'image dedans, mais n'effectue pas le changement de fond d'écran. Cela ne fonctionnerait que sous Windows. C'est l'une des limitations de la version GNU/Linux.

Compilation et installation
---------------------------

Pourquoi le titre Compilation ? Pourquoi en plus un changement de niveau de titre alors qu'on vient de compiler et de tester ?

On a compilé via Qt Creator, en Debug. Maintenant, on va compiler en release.

Pourquoi ? Parce que la version de debug, qui se trouve dans ../build-WallpaperFiner-Desktop-Debug pèse 2 Mo, et la version Release ne pèse que dans les 155 ko.

. note:: On peut compiler en release avec Qt Creator, en changeant Debug en Release, en bas à gauche. Cependant, la compilation depuis un terminal intéressera plus de personnes, parce que c'est automatisable/plus simple à gérer avec aur/insérer ici une autre raison pour préférer la ligne de commande.


Lancer un terminal. Se déplacer dans le répertoire du projet.

Dans le répertoire du projet, créer un répertoire build, via le terminal ou via un gestionnaire de fichiers.

. image:: images/wpfiner/term1.jpg

Création du répertoire build.

Se déplacer dans ce répertoire.

Taper la commande suivante pour générer le fichier Makefile :

. code-block:: bash

   qmake ../WallpaperFiner.pro


. image:: images/wpfiner/term2.jpg

Création du Makefile.

Pas d'erreur ? Parfait.

Taper simplement make pour compiler l'application. Des lignes vont défiler, c'est normal.

. code-block:: bash

   make

. image:: images/wpfiner/term3.jpg

Compilation en cours. Les avertissements (warnings) apparaissent à l'écran, c'est normal.

Une fois terminé, vérifier que le fichier wallpaperfiner a bien été généré, et ne fait que 155 ko (environ, tout dépend si c'est compté en ko ou kio).

. image:: images/wpfiner/term4.jpg

Ici, c'est bon. Le fichier exécutable (en vert) fait la taille attendue.

On va vérifier que c'est bien Qt5 qui est utilisé, via la commande ldd.

. code-block:: bash

   ldd wallpaperfiner

. image:: images/wpfiner/term5.jpg

Résultat ? ::

   libQt5Widgets.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 (0x00007f0a08314000)
   libQt5Gui.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5 (0x00007f0a07c52000)
   libQt5Core.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 (0x00007f0a07707000)

C'est bon, c'est bien Qt5.

On peut lancer l'application et refaire quelques tests, pour confirmer le bon fonctionnement.

. code-block:: bash

   ./wallpaperfiner

. image:: images/wpfiner/term6.jpg

Parfait, aucun problème rencontré.

Pour l'installation, il suffit de copier l'exécutable dans un répertoire défini dans $PATH, comme /usr/local/bin

Par exemple via sudo cp

. code-block:: bash

   sudo cp wallpaperfiner /usr/local/bin/

. image:: images/wpfiner/term7.jpg

Ici, j'ai utilisé en plus la commande *whereis wallpaperfiner* pour confirmer que wallpaperfiner est bien reconnu et est situé au bon endroit.


. note:: On peut créer une entrée de menu.

   Pour cela :

   * soit passer par un éditeur comme *alacarte*, *MenuLibre* ou équivalent
   * soit modifier le fichier *wallpaperfiner.desktop* situé dans le répertoire Desktop, notamment changer les chemins et ajouter la traduction en français de la description, le copier dans /usr/local/share/applications et copier l'icône wpfiner.png dans /usr/local/share/pixmaps/.

Conclusion
----------

Concrètement, le portage vers Qt5 se fait en moins d'une demi-heure, lecture de documentation comprise. C'est relativement simple, sans prise de tête.

Remerciements à `@TritTriton <https://shelter.moe/@TritTriton>`_ pour son pouët montrant cet outil, pour avoir pu compiler la version Qt5 et avoir confirmé son bon fonctionnement.


Modification dimanche 11 juillet 2021.

Le code source est désormais versionné et est disponible sur Shelter.

Modification samedi 20 novembre 2021.

Le service gitlab sur Shelter devant fermer sous peu, le code source versionné est maintenant disponible sur gitlab.com : https://gitlab.com/chibinah/wallpaperfiner

--