I'm not sure the way to get the program directory we use is ok for beos, but the official way of doing that is using C++ code. Maybe it's time to switch to some more unix way to store the config files... This should also fix watcom build (very untested as i'm using mingw to cross compile windows builds now) Also added begasus to the credits screen. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@325 416bcca6-2ee7-4201-b75f-2eb2f807beb1
704 lines
21 KiB
C
704 lines
21 KiB
C
/* Grafx2 - The Ultimate 256-color bitmap paint program
|
|
|
|
Copyright 2008 Peter Gordon
|
|
Copyright 2008 Yves Rizoud
|
|
Copyright 2007 Adrien Destugues
|
|
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
|
|
|
|
Grafx2 is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; version 2
|
|
of the License.
|
|
|
|
Grafx2 is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Grafx2; if not, see <http://www.gnu.org/licenses/> or
|
|
write to the Free Software Foundation, Inc.,
|
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
#include "const.h"
|
|
#include "struct.h"
|
|
#include "global.h"
|
|
#include "graph.h"
|
|
#include "divers.h"
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#ifdef __amigaos4__
|
|
#include <proto/dos.h>
|
|
#endif
|
|
|
|
#include "erreurs.h"
|
|
#include "linux.h"
|
|
#include "io.h"
|
|
|
|
|
|
#if defined(__linux__)||defined(__BEOS__)||defined(__HAIKU__)
|
|
#include <dirent.h>
|
|
#define isHidden(Enreg) ((Enreg)->d_name[0]=='.')
|
|
#elif defined(__amigaos4__)
|
|
#include <dirent.h>
|
|
#define isHidden(Enreg) (0)
|
|
#elif defined(__WATCOMC__)
|
|
#include <direct.h>
|
|
#define isHidden(Enreg) ((Enreg)->d_attr & _A_HIDDEN)
|
|
#elif defined(__MINGW32__)
|
|
#include <dirent.h>
|
|
#include <windows.h>
|
|
#define isHidden(Enreg) (GetFileAttributesA((Enreg)->d_name)&FILE_ATTRIBUTE_HIDDEN)
|
|
#endif
|
|
|
|
#define COULEUR_FICHIER_NORMAL CM_Clair // Couleur du texte pour une ligne de fichier non sélectionné
|
|
#define COULEUR_REPERTOIRE_NORMAL CM_Fonce // Couleur du texte pour une ligne de répertoire non sélectionné
|
|
#define COULEUR_FOND_NORMAL CM_Noir // Couleur du fond pour une ligne non sélectionnée
|
|
#define COULEUR_FICHIER_SELECT CM_Blanc // Couleur du texte pour une ligne de fichier sélectionnée
|
|
#define COULEUR_REPERTOIRE_SELECT CM_Clair // Couleur du texte pour une ligne de repértoire sélectionnée
|
|
#define COULEUR_FOND_SELECT CM_Fonce // Couleur du fond pour une ligne sélectionnée
|
|
|
|
#define FILENAMESPACE 13
|
|
|
|
int Determiner_repertoire_courant(void)
|
|
// Modifie Principal_Repertoire_courant en y mettant sa nouvelle valeur (avec le nom du
|
|
// disque)
|
|
//
|
|
// Renvoie 1 s'il y a eu une erreur d'accès
|
|
{
|
|
return (getcwd(Principal_Repertoire_courant,256)==NULL);
|
|
}
|
|
|
|
|
|
int Repertoire_existe(char * Repertoire)
|
|
// Détermine si un répertoire passé en paramètre existe ou non dans le
|
|
// répertoire courant.
|
|
{
|
|
DIR* Enreg; // Structure de lecture des éléments
|
|
|
|
if (strcmp(Repertoire,"..")==0)
|
|
return 1;
|
|
else
|
|
{
|
|
// On va chercher si le répertoire existe à l'aide d'un Opendir. S'il
|
|
// renvoie NULL c'est que le répertoire n'est pas accessible...
|
|
|
|
Enreg=opendir(Repertoire);
|
|
if (Enreg==NULL)
|
|
return 0;
|
|
else
|
|
{
|
|
closedir(Enreg);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int Fichier_existe(char * Fichier)
|
|
// Détermine si un fichier passé en paramètre existe ou non dans le
|
|
// répertoire courant.
|
|
{
|
|
struct stat buf;
|
|
int Resultat;
|
|
|
|
Resultat=stat(Fichier,&buf);
|
|
if (Resultat!=0)
|
|
return(errno!=ENOENT);
|
|
else
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Conventions:
|
|
//
|
|
// * Le fileselect modifie le répertoire courant. Ceci permet de n'avoir
|
|
// qu'un findfirst dans le répertoire courant à faire:
|
|
|
|
|
|
// -- Déstruction de la liste chaînée ---------------------------------------
|
|
void Detruire_liste_du_fileselect(void)
|
|
// Cette procédure détruit la chaine des fichiers. Elle doit être appelée
|
|
// avant de rappeler la fonction Lire_liste_des_fichiers, ainsi qu'en fin de
|
|
// programme.
|
|
{
|
|
// Pointeur temporaire de destruction
|
|
struct Element_de_liste_de_fileselect * Element_temporaire;
|
|
|
|
while (Liste_du_fileselect!=NULL)
|
|
{
|
|
// On mémorise l'adresse du premier élément de la liste
|
|
Element_temporaire =Liste_du_fileselect;
|
|
// On fait avancer la tête de la liste
|
|
Liste_du_fileselect=Liste_du_fileselect->Suivant;
|
|
// Et on efface l'ancien premier élément de la liste
|
|
free(Element_temporaire);
|
|
}
|
|
}
|
|
|
|
|
|
// -- Formatage graphique des noms de fichier / répertoire ------------------
|
|
char * Nom_formate(char * Nom, int Type)
|
|
{
|
|
static char Resultat[13];
|
|
int Curseur;
|
|
int Autre_curseur;
|
|
int Pos_DernierPoint;
|
|
|
|
if (strcmp(Nom,"..")==0)
|
|
{
|
|
strcpy(Resultat,".. ");
|
|
}
|
|
else if (Nom[0]=='.' || Type==2)
|
|
{
|
|
// Fichiers ".quelquechose" ou lecteurs: Calé à gauche sur 12 caractères maximum.
|
|
strcpy(Resultat," ");
|
|
for (Curseur=0;Nom[Curseur]!='\0' && Curseur < 12;Curseur++)
|
|
Resultat[Curseur]=Nom[Curseur];
|
|
// Un caractère spécial pour indiquer que l'affichage est tronqué
|
|
if (Curseur >= 12)
|
|
Resultat[11]=CARACTERE_TRIANGLE_DROIT;
|
|
}
|
|
else
|
|
{
|
|
strcpy(Resultat," . ");
|
|
// On commence par recopier la partie précédent le point:
|
|
for (Curseur=0;( (Nom[Curseur]!='.') && (Nom[Curseur]!='\0') );Curseur++)
|
|
{
|
|
if (Curseur < 8)
|
|
Resultat[Curseur]=Nom[Curseur];
|
|
}
|
|
// Un caractère spécial pour indiquer que l'affichage est tronqué
|
|
if (Curseur > 8)
|
|
Resultat[7]=CARACTERE_TRIANGLE_DROIT;
|
|
// On recherche le dernier point dans le reste du nom
|
|
for (Pos_DernierPoint = Curseur; Nom[Curseur]!='\0'; Curseur++)
|
|
if (Nom[Curseur]=='.')
|
|
Pos_DernierPoint = Curseur;
|
|
|
|
// Ensuite on recopie la partie qui suit le point (si nécessaire):
|
|
if (Nom[Pos_DernierPoint])
|
|
{
|
|
for (Curseur = Pos_DernierPoint+1,Autre_curseur=9;Nom[Curseur]!='\0' && Autre_curseur < 12;Curseur++,Autre_curseur++)
|
|
Resultat[Autre_curseur]=Nom[Curseur];
|
|
}
|
|
}
|
|
return Resultat;
|
|
}
|
|
|
|
|
|
// -- Rajouter a la liste des elements de la liste un element ---------------
|
|
void Ajouter_element_a_la_liste(char * Nom, int Type)
|
|
// Cette procedure ajoute a la liste chainee un fichier passé en argument.
|
|
{
|
|
// Pointeur temporaire d'insertion
|
|
struct Element_de_liste_de_fileselect * Element_temporaire;
|
|
|
|
// On alloue de la place pour un nouvel element
|
|
Element_temporaire=(struct Element_de_liste_de_fileselect *)malloc(sizeof(struct Element_de_liste_de_fileselect));
|
|
|
|
// On met a jour le nouvel emplacement:
|
|
strcpy(Element_temporaire->NomAbrege,Nom_formate(Nom, Type));
|
|
strcpy(Element_temporaire->NomComplet,Nom);
|
|
Element_temporaire->Type = Type;
|
|
|
|
Element_temporaire->Suivant =Liste_du_fileselect;
|
|
Element_temporaire->Precedent=NULL;
|
|
|
|
if (Liste_du_fileselect!=NULL)
|
|
Liste_du_fileselect->Precedent=Element_temporaire;
|
|
Liste_du_fileselect=Element_temporaire;
|
|
}
|
|
|
|
// -- Vérification si un fichier a l'extension demandée.
|
|
// Autorise les '?', et '*' si c'est le seul caractère.
|
|
int VerifieExtension(const char *NomFichier, char * Filtre)
|
|
{
|
|
int Pos_DernierPoint = -1;
|
|
int Curseur = 0;
|
|
|
|
if (Filtre[0] == '*')
|
|
return 1;
|
|
// On recherche la position du dernier . dans le nom
|
|
for (Curseur = 0; NomFichier[Curseur]!='\0'; Curseur++)
|
|
if (NomFichier[Curseur]=='.')
|
|
Pos_DernierPoint = Curseur;
|
|
// Fichier sans extension (ca arrive)
|
|
if (Pos_DernierPoint == -1)
|
|
return (Filtre[0] == '\0');
|
|
|
|
// Vérification caractère par caractère, case-insensitive.
|
|
Curseur = 0;
|
|
do
|
|
{
|
|
if (Filtre[Curseur] != '?' &&
|
|
tolower(Filtre[Curseur]) != tolower(NomFichier[Pos_DernierPoint + 1 + Curseur]))
|
|
return 0;
|
|
|
|
Curseur++;
|
|
} while (Filtre[Curseur++] != '\0');
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
// -- Lecture d'une liste de fichiers ---------------------------------------
|
|
void Lire_liste_des_fichiers(byte Format_demande)
|
|
// Cette procédure charge dans la liste chainée les fichiers dont l'extension
|
|
// correspond au format demandé.
|
|
{
|
|
DIR* Repertoire_Courant; //Répertoire courant
|
|
struct dirent* Enreg; // Structure de lecture des éléments
|
|
char * Filtre = "*"; // Extension demandée
|
|
struct stat Infos_enreg;
|
|
char * Chemin_courant;
|
|
|
|
// Tout d'abord, on déduit du format demandé un filtre à utiliser:
|
|
if (Format_demande) // Format (extension) spécifique
|
|
Filtre = Format_Extension[Format_demande-1];
|
|
|
|
// Ensuite, on vide la liste actuelle:
|
|
Detruire_liste_du_fileselect();
|
|
// Après effacement, il ne reste ni fichier ni répertoire dans la liste
|
|
Liste_Nb_fichiers=0;
|
|
Liste_Nb_repertoires=0;
|
|
|
|
// On lit tous les répertoires:
|
|
Chemin_courant=getcwd(NULL,0);
|
|
Repertoire_Courant=opendir(Chemin_courant);
|
|
while ((Enreg=readdir(Repertoire_Courant)))
|
|
{
|
|
// On ignore le répertoire courant
|
|
if ( !strcmp(Enreg->d_name, "."))
|
|
{
|
|
continue;
|
|
}
|
|
stat(Enreg->d_name,&Infos_enreg);
|
|
// et que l'élément trouvé est un répertoire
|
|
if( S_ISDIR(Infos_enreg.st_mode) &&
|
|
// et que c'est ".."
|
|
(!strcmp(Enreg->d_name, "..") ||
|
|
// ou qu'il n'est pas caché
|
|
Config.Lire_les_repertoires_caches ||
|
|
!isHidden(Enreg)))
|
|
{
|
|
// On rajoute le répertoire à la liste
|
|
Ajouter_element_a_la_liste(Enreg->d_name, 1);
|
|
Liste_Nb_repertoires++;
|
|
}
|
|
else if (S_ISREG(Infos_enreg.st_mode) && //Il s'agit d'un fichier
|
|
(Config.Lire_les_fichiers_caches || //Il n'est pas caché
|
|
!isHidden(Enreg)))
|
|
{
|
|
if (VerifieExtension(Enreg->d_name, Filtre))
|
|
{
|
|
// On rajoute le fichier à la liste
|
|
Ajouter_element_a_la_liste(Enreg->d_name, 0);
|
|
Liste_Nb_fichiers++;
|
|
}
|
|
}
|
|
}
|
|
|
|
closedir(Repertoire_Courant);
|
|
free(Chemin_courant);
|
|
|
|
Liste_Nb_elements=Liste_Nb_repertoires+Liste_Nb_fichiers;
|
|
}
|
|
|
|
#ifdef __amigaos4__
|
|
void bstrtostr( BSTR in, STRPTR out, TEXT max )
|
|
{
|
|
STRPTR iptr;
|
|
uint32 i;
|
|
|
|
iptr = BADDR( in );
|
|
|
|
if( max > iptr[0] ) max = iptr[0];
|
|
|
|
for( i=0; i<max; i++ ) out[i] = iptr[i+1];
|
|
out[i] = 0;
|
|
}
|
|
#endif
|
|
|
|
// -- Lecture d'une liste de lecteurs / volumes -----------------------------
|
|
void Lire_liste_des_lecteurs(void)
|
|
{
|
|
int Indice;
|
|
|
|
// Empty the current content of fileselector:
|
|
Detruire_liste_du_fileselect();
|
|
// Reset number of items
|
|
Liste_Nb_fichiers=0;
|
|
Liste_Nb_repertoires=0;
|
|
|
|
// AmigaOS4
|
|
#ifdef __amigaos4__
|
|
{
|
|
struct DosList *dl;
|
|
char tmp[256];
|
|
|
|
dl = IDOS->LockDosList( LDF_VOLUMES | LDF_READ );
|
|
if( dl )
|
|
{
|
|
while( ( dl = IDOS->NextDosEntry( dl, LDF_VOLUMES | LDF_READ ) ) )
|
|
{
|
|
bstrtostr( dl->dol_Name, tmp, 254 );
|
|
strcat( tmp, ":" );
|
|
Ajouter_element_a_la_liste( tmp, 2 );
|
|
Liste_Nb_repertoires++;
|
|
}
|
|
IDOS->UnLockDosList( LDF_VOLUMES | LDF_READ );
|
|
}
|
|
}
|
|
|
|
// Other platforms: simply read the "static" list of Drives.
|
|
#else
|
|
for (Indice=0; Indice<Nb_drives; Indice++)
|
|
{
|
|
// Add the drive's name ("c:\\", "/" etc.) to the list
|
|
Ajouter_element_a_la_liste(Drive[Indice].Chemin, 2);
|
|
Liste_Nb_repertoires++;
|
|
}
|
|
#endif
|
|
|
|
Liste_Nb_elements=Liste_Nb_repertoires+Liste_Nb_fichiers;
|
|
}
|
|
|
|
|
|
// -- Tri de la liste des fichiers et répertoires ---------------------------
|
|
void Trier_la_liste_des_fichiers(void)
|
|
// Tri la liste chainée existante dans l'ordre suivant:
|
|
//
|
|
// * Les répertoires d'abord, dans l'ordre alphabétique de leur nom
|
|
// * Les fichiers ensuite, dans l'ordre alphabétique de leur nom
|
|
{
|
|
byte La_liste_est_triee; // Booléen "La liste est triée"
|
|
byte Inversion; // Booléen "Il faut inverser les éléments"
|
|
struct Element_de_liste_de_fileselect * Element_precedent;
|
|
struct Element_de_liste_de_fileselect * Element_courant;
|
|
struct Element_de_liste_de_fileselect * Element_suivant;
|
|
struct Element_de_liste_de_fileselect * Element_suivant_le_suivant;
|
|
|
|
// Avant de trier quoi que ce soit, on vérifie qu'il y ait suffisamment
|
|
// d'éléments pour qu'il soit possibles qu'ils soient en désordre:
|
|
if (Liste_Nb_elements>1)
|
|
{
|
|
do
|
|
{
|
|
// Par défaut, on considère que la liste est triée
|
|
La_liste_est_triee=1;
|
|
|
|
Element_courant=Liste_du_fileselect;
|
|
Element_suivant=Element_courant->Suivant;
|
|
|
|
while ( (Element_courant!=NULL) && (Element_suivant!=NULL) )
|
|
{
|
|
// On commence par supposer qu'il n'y pas pas besoin d'inversion
|
|
Inversion=0;
|
|
|
|
// Ensuite, on vérifie si les deux éléments sont bien dans l'ordre ou
|
|
// non:
|
|
|
|
// Si l'élément courant est un fichier est que le suivant est
|
|
// un répertoire -> Inversion
|
|
if ( Element_courant->Type < Element_suivant->Type )
|
|
Inversion=1;
|
|
// Si les deux éléments sont de même type et que le nom du suivant
|
|
// est plus petit que celui du courant -> Inversion
|
|
else if ( (Element_courant->Type==Element_suivant->Type) &&
|
|
(strcmp(Element_courant->NomComplet,Element_suivant->NomComplet)>0) )
|
|
Inversion=1;
|
|
|
|
|
|
if (Inversion)
|
|
{
|
|
// Si les deux éléments nécessitent d'être inversé:
|
|
|
|
// On les inverses:
|
|
|
|
// On note avant tout les éléments qui encapsulent nos deux amis
|
|
Element_precedent =Element_courant->Precedent;
|
|
Element_suivant_le_suivant=Element_suivant->Suivant;
|
|
|
|
// On permute le chaînage des deux éléments entree eux
|
|
Element_courant->Suivant =Element_suivant_le_suivant;
|
|
Element_courant->Precedent=Element_suivant;
|
|
Element_suivant->Suivant =Element_courant;
|
|
Element_suivant->Precedent=Element_precedent;
|
|
|
|
// On tente un chaînage des éléments encapsulant les compères:
|
|
if (Element_precedent!=NULL)
|
|
Element_precedent->Suivant=Element_suivant;
|
|
if (Element_suivant_le_suivant!=NULL)
|
|
Element_suivant_le_suivant->Precedent=Element_courant;
|
|
|
|
// On fait bien attention à modifier la tête de liste en cas de besoin
|
|
if (Element_courant==Liste_du_fileselect)
|
|
Liste_du_fileselect=Element_suivant;
|
|
|
|
// Ensuite, on se prépare à étudier les éléments précédents:
|
|
Element_courant=Element_precedent;
|
|
|
|
// Et on constate que la liste n'était pas encore génialement triée
|
|
La_liste_est_triee=0;
|
|
}
|
|
else
|
|
{
|
|
// Si les deux éléments sont dans l'ordre:
|
|
|
|
// On passe aux suivants
|
|
Element_courant=Element_courant->Suivant;
|
|
Element_suivant=Element_suivant->Suivant;
|
|
}
|
|
}
|
|
}
|
|
while (!La_liste_est_triee);
|
|
}
|
|
}
|
|
|
|
|
|
// -- Affichage des éléments de la liste de fichier / répertoire ------------
|
|
void Afficher_la_liste_des_fichiers(short Decalage_premier,short Decalage_select)
|
|
//
|
|
// Decalage_premier = Décalage entre le premier fichier visible dans le
|
|
// sélecteur et le premier fichier de la liste
|
|
//
|
|
// Decalage_select = Décalage entre le premier fichier visible dans le
|
|
// sélecteur et le fichier sélectionné dans la liste
|
|
//
|
|
{
|
|
struct Element_de_liste_de_fileselect * Element_courant;
|
|
byte Indice; // Indice du fichier qu'on affiche (0 -> 9)
|
|
byte Couleur_texte;
|
|
byte Couleur_fond;
|
|
|
|
|
|
// On vérifie s'il y a au moins 1 fichier dans la liste:
|
|
if (Liste_Nb_elements>0)
|
|
{
|
|
// On commence par chercher à pointer sur le premier fichier visible:
|
|
Element_courant=Liste_du_fileselect;
|
|
for (;Decalage_premier>0;Decalage_premier--)
|
|
Element_courant=Element_courant->Suivant;
|
|
|
|
// Pour chacun des 10 éléments inscriptibles à l'écran
|
|
for (Indice=0;Indice<10;Indice++)
|
|
{
|
|
// S'il est sélectionné:
|
|
if (!Decalage_select)
|
|
{
|
|
// Si c'est un fichier
|
|
if (Element_courant->Type==0)
|
|
Couleur_texte=COULEUR_FICHIER_SELECT;
|
|
else
|
|
Couleur_texte=COULEUR_REPERTOIRE_SELECT;
|
|
|
|
Couleur_fond=COULEUR_FOND_SELECT;
|
|
}
|
|
else
|
|
{
|
|
// Si c'est un fichier
|
|
if (Element_courant->Type==0)
|
|
Couleur_texte=COULEUR_FICHIER_NORMAL;
|
|
else
|
|
Couleur_texte=COULEUR_REPERTOIRE_NORMAL;
|
|
|
|
Couleur_fond=COULEUR_FOND_NORMAL;
|
|
}
|
|
|
|
// On affiche l'élément
|
|
Print_dans_fenetre(9,90+FILENAMESPACE+(Indice<<3),Element_courant->NomAbrege,Couleur_texte,Couleur_fond);
|
|
|
|
// On passe à la ligne suivante
|
|
Decalage_select--;
|
|
Element_courant=Element_courant->Suivant;
|
|
if (!Element_courant)
|
|
break;
|
|
} // Fin de la boucle d'affichage
|
|
|
|
} // Fin du test d'existence de fichiers
|
|
}
|
|
|
|
|
|
// -- Récupérer le libellé d'un élément de la liste -------------------------
|
|
void Determiner_element_de_la_liste(short Decalage_premier,short Decalage_select,char * Libelle,int *Type)
|
|
//
|
|
// Decalage_premier = Décalage entre le premier fichier visible dans le
|
|
// sélecteur et le premier fichier de la liste
|
|
//
|
|
// Decalage_select = Décalage entre le premier fichier visible dans le
|
|
// sélecteur et le fichier à récupérer
|
|
//
|
|
// Libelle = Chaine de réception du libellé de l'élément
|
|
//
|
|
// Type = Récupération du type: 0 fichier, 1 repertoire, 2 lecteur.
|
|
// Passer NULL si pas interessé.
|
|
{
|
|
struct Element_de_liste_de_fileselect * Element_courant;
|
|
|
|
// On vérifie s'il y a au moins 1 fichier dans la liste:
|
|
if (Liste_Nb_elements>0)
|
|
{
|
|
// On commence par chercher à pointer sur le premier fichier visible:
|
|
Element_courant=Liste_du_fileselect;
|
|
for (;Decalage_premier>0;Decalage_premier--)
|
|
Element_courant=Element_courant->Suivant;
|
|
|
|
// Ensuite, on saute autant d'éléments que le décalage demandé:
|
|
for (;Decalage_select>0;Decalage_select--)
|
|
Element_courant=Element_courant->Suivant;
|
|
|
|
// On recopie la chaîne
|
|
strcpy(Libelle, Element_courant->NomComplet);
|
|
|
|
if (Type != NULL)
|
|
*Type=Element_courant->Type;
|
|
} // Fin du test d'existence de fichiers
|
|
}
|
|
|
|
|
|
// ----------------- Déplacements dans la liste de fichiers -----------------
|
|
|
|
void Select_Scroll_Down(short * Decalage_premier,short * Decalage_select)
|
|
// Fait scroller vers le bas le sélecteur de fichier... (si possible)
|
|
{
|
|
if ( ((*Decalage_select)<9)
|
|
&& ( (*Decalage_select)+1 < Liste_Nb_elements ) )
|
|
// Si la sélection peut descendre
|
|
Afficher_la_liste_des_fichiers(*Decalage_premier,++(*Decalage_select));
|
|
else // Sinon, descendre la fenêtre (si possible)
|
|
if ((*Decalage_premier)+10<Liste_Nb_elements)
|
|
Afficher_la_liste_des_fichiers(++(*Decalage_premier),*Decalage_select);
|
|
}
|
|
|
|
|
|
void Select_Scroll_Up(short * Decalage_premier,short * Decalage_select)
|
|
// Fait scroller vers le haut le sélecteur de fichier... (si possible)
|
|
{
|
|
if ((*Decalage_select)>0)
|
|
// Si la sélection peut monter
|
|
Afficher_la_liste_des_fichiers(*Decalage_premier,--(*Decalage_select));
|
|
else // Sinon, monter la fenêtre (si possible)
|
|
if ((*Decalage_premier)>0)
|
|
Afficher_la_liste_des_fichiers(--(*Decalage_premier),*Decalage_select);
|
|
}
|
|
|
|
|
|
void Select_Page_Down(short * Decalage_premier,short * Decalage_select)
|
|
{
|
|
if (Liste_Nb_elements-1>*Decalage_premier+*Decalage_select)
|
|
{
|
|
if (*Decalage_select<9)
|
|
{
|
|
if (Liste_Nb_elements<10)
|
|
{
|
|
*Decalage_premier=0;
|
|
*Decalage_select=Liste_Nb_elements-1;
|
|
}
|
|
else *Decalage_select=9;
|
|
}
|
|
else
|
|
{
|
|
if (Liste_Nb_elements>*Decalage_premier+18)
|
|
*Decalage_premier+=9;
|
|
else
|
|
{
|
|
*Decalage_premier=Liste_Nb_elements-10;
|
|
*Decalage_select=9;
|
|
}
|
|
}
|
|
}
|
|
Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select);
|
|
}
|
|
|
|
|
|
void Select_Page_Up(short * Decalage_premier,short * Decalage_select)
|
|
{
|
|
if (*Decalage_premier+*Decalage_select>0)
|
|
{
|
|
if (*Decalage_select>0)
|
|
*Decalage_select=0;
|
|
else
|
|
{
|
|
if (*Decalage_premier>9)
|
|
*Decalage_premier-=9;
|
|
else
|
|
*Decalage_premier=0;
|
|
}
|
|
}
|
|
Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select);
|
|
}
|
|
|
|
|
|
void Select_End(short * Decalage_premier,short * Decalage_select)
|
|
{
|
|
if (Liste_Nb_elements<10)
|
|
{
|
|
*Decalage_premier=0;
|
|
*Decalage_select=Liste_Nb_elements-1;
|
|
}
|
|
else
|
|
{
|
|
*Decalage_premier=Liste_Nb_elements-10;
|
|
*Decalage_select=9;
|
|
}
|
|
Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select);
|
|
}
|
|
|
|
|
|
void Select_Home(short * Decalage_premier,short * Decalage_select)
|
|
{
|
|
Afficher_la_liste_des_fichiers((*Decalage_premier)=0,(*Decalage_select)=0);
|
|
}
|
|
|
|
|
|
|
|
short Calculer_decalage_click_dans_fileselector(void)
|
|
/*
|
|
Renvoie le décalage dans le sélecteur de fichier sur lequel on a clické.
|
|
Renvoie le décalage du dernier fichier si on a clické au delà.
|
|
Renvoie -1 si le sélecteur est vide.
|
|
*/
|
|
{
|
|
short Decalage_calcule;
|
|
|
|
Decalage_calcule=(((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y)-(90+FILENAMESPACE))>>3;
|
|
if (Decalage_calcule>=Liste_Nb_elements)
|
|
Decalage_calcule=Liste_Nb_elements-1;
|
|
|
|
return Decalage_calcule;
|
|
}
|
|
|
|
void for_each_file(const char * Nom_repertoire, void Callback(const char *))
|
|
{
|
|
// Pour scan de répertoire
|
|
DIR* Repertoire_Courant; //Répertoire courant
|
|
struct dirent* Enreg; // Structure de lecture des éléments
|
|
char Nom_fichier_complet[TAILLE_CHEMIN_FICHIER];
|
|
int Position_nom_fichier;
|
|
strcpy(Nom_fichier_complet, Nom_repertoire);
|
|
Repertoire_Courant=opendir(Nom_repertoire);
|
|
strcat(Nom_fichier_complet, SEPARATEUR_CHEMIN);
|
|
Position_nom_fichier = strlen(Nom_fichier_complet);
|
|
while ((Enreg=readdir(Repertoire_Courant)))
|
|
{
|
|
struct stat Infos_enreg;
|
|
strcpy(&Nom_fichier_complet[Position_nom_fichier], Enreg->d_name);
|
|
stat(Nom_fichier_complet,&Infos_enreg);
|
|
if (S_ISREG(Infos_enreg.st_mode))
|
|
{
|
|
Callback(Nom_fichier_complet);
|
|
}
|
|
}
|
|
}
|