/************************************************************************ * * * READLINE (procédure permettant de saisir une chaîne de caractères) * * * ************************************************************************/ #include #include #include "const.h" #include "struct.h" #include "global.h" #include "graph.h" #include "divers.h" #include "erreurs.h" #include "const.h" #include "linux.h" #define COULEUR_TEXTE CM_Noir #define COULEUR_FOND CM_Clair #define COULEUR_TEXTE_CURSEUR CM_Noir #define COULEUR_FOND_CURSEUR CM_Fonce // Suppresion d'un caractère à une certaine POSITION dans une CHAINE. void Supprimer_caractere(char * Chaine, byte Position) { for (;Chaine[Position]!='\0';Position++) Chaine[Position]=Chaine[Position+1]; } void Inserer_caractere(char * Chaine, char Lettre, byte Position) // Insertion d'une LETTRE à une certaine POSITION // dans une CHAINE d'une certaine TAILLE. { char Char_tempo; for (;Lettre!='\0';Position++) { // On mémorise le caractère qui se trouve en "Position" Char_tempo=Chaine[Position]; // On splotch la lettre à insérer Chaine[Position]=Lettre; // On place le caractère mémorisé dans "Lettre" comme nouvelle lettre à insérer Lettre=Char_tempo; } // On termine la chaine Chaine[Position]='\0'; } int CaractereValide(int Caractere) { // Sous Linux: Seul le / est strictement interdit, mais beaucoup // d'autres poseront des problèmes au shell, alors on évite. // Sous Windows : c'est moins grave car le fopen() échouerait de toutes façons. #ifdef __linux__ char CaracteresInterdits[] = {'/', '|', '?', '*', '<', '>'}; #else char CaracteresInterdits[] = {'/', '|', '?', '*', '<', '>', ':', '\\'}; #endif if (Caractere < ' ' || Caractere > 255) return 0; int Position; for (Position=0; Position0) Chaine_affichee[0]=CARACTERE_TRIANGLE_GAUCHE; if (Taille_affichee + Offset + 1 < Taille ) Chaine_affichee[Taille_affichee-1]=CARACTERE_TRIANGLE_DROIT; Rafficher_toute_la_chaine(Pos_X,Pos_Y,Chaine_affichee,Position - Offset); while ((Touche_lue!=SDLK_RETURN) && (Touche_lue!=SDLK_ESCAPE)) { Touche_lue=Get_key(); switch (Touche_lue) { case SDLK_DELETE : // Suppr. if (Position0) { // Effacement de la chaîne if (Position==Taille) Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3),COULEUR_FOND); Position--; if (Offset > 0 && (Position == 0 || Position < (Offset + 1))) Offset--; goto affichage; } break; case SDLK_RIGHT : // Droite if ((Position Taille_affichee + Offset - 2) //if (Offset + Taille_affichee < Taille_maxi && (Position == Taille || (Position > Taille_affichee + Offset - 2))) if (Chaine_affichee[Position-Offset]==CARACTERE_TRIANGLE_DROIT || Position-Offset>=Taille_affichee) Offset++; goto affichage; } break; case SDLK_HOME : // Home if (Position) { // Effacement de la chaîne if (Position==Taille) Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3),COULEUR_FOND); Position = 0; Offset = 0; goto affichage; } break; case SDLK_END : // End if ((PositionTaille_affichee) Offset=Position-Taille_affichee+1; goto affichage; } break; case SDLK_BACKSPACE : if (Position) { Supprimer_caractere(Chaine,--Position); Taille--; // Effacement de la chaîne Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3),COULEUR_FOND); goto affichage; } break; case SDLK_RETURN : break; case SDLK_ESCAPE : // On restaure la chaine initiale strcpy(Chaine,Chaine_initiale); Taille=strlen(Chaine); break; default : if (Taille=' ' && Touche_lue<= 255) Touche_autorisee=1; break; case 1 : // Nombre if ( (Touche_lue>='0') && (Touche_lue<='9') ) Touche_autorisee=1; break; default : // Nom de fichier // On regarde si la touche est autorisée if ( CaractereValide(Touche_lue)) Touche_autorisee=1; } // Fin du "switch(Type_saisie)" // Si la touche était autorisée... if (Touche_autorisee) { // ... alors on l'insère ... Inserer_caractere(Chaine,Touche_lue,Position/*,Taille*/); // ce qui augmente la taille de la chaine Taille++; // et qui risque de déplacer le curseur vers la droite if (Taille Taille_affichee + Offset - 2 && !(Position Taille_affichee + Offset - 2))) if (Chaine_affichee[Position-Offset]==CARACTERE_TRIANGLE_DROIT || Position-Offset>=Taille_affichee) Offset++; } // Enfin, on raffiche la chaine goto affichage; } // Fin du test d'autorisation de touche } // Fin du test de place libre break; affichage: Taille=strlen(Chaine); // Formatage d'une partie de la chaine (si trop longue pour tenir) strncpy(Chaine_affichee, Chaine + Offset, Taille_affichee); Chaine_affichee[Taille_affichee]='\0'; if (Offset>0) Chaine_affichee[0]=CARACTERE_TRIANGLE_GAUCHE; if (Taille_affichee + Offset + 0 < Taille ) Chaine_affichee[Taille_affichee-1]=CARACTERE_TRIANGLE_DROIT; Rafficher_toute_la_chaine(Pos_X,Pos_Y,Chaine_affichee,Position - Offset); } // Fin du "switch(Touche_lue)" } // Fin du "while" // Effacement de la chaîne Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_maxi*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3),COULEUR_FOND); // On raffiche la chaine correctement if (Type_saisie==1) { if (Chaine[0]=='\0') { strcpy(Chaine,"0"); Taille=1; } Print_dans_fenetre(Pos_X+((Taille_maxi-Taille)<<3),Pos_Y,Chaine,COULEUR_TEXTE,COULEUR_FOND); } else Print_dans_fenetre(Pos_X,Pos_Y,Chaine,COULEUR_TEXTE,COULEUR_FOND); return (Touche_lue==SDLK_RETURN); }