/* sel_file.c ---------- old site --> http://tboudet.free.fr/hexdiff/ */ #include #include #include #include #include #include #include #include #include /* nasty hack */ char *strdup(char *); /* end of hack */ #include #include #include "hexdiff.h" /*----------------------------------------------------------------*/ /* private vars of this module */ typedef struct { long taille; char *nom; int idx; } FICH; static FICH *liste; static int taille; /* taille de la liste */ static int nombre; /* nbre d'entrees dans la liste */ #define TCHONK 42 /*----------------------------------------------------------------*/ static int teste_dirent(const struct dirent *de, struct stat *pstat) { int foo; foo = stat(de->d_name, pstat); if (foo) perror(__func__); if (S_ISDIR(pstat->st_mode)) return 0; if (config.show_hidden==0 && de->d_name[0]=='.') return 0; return 1; } /*----------------------------------------------------------------*/ static int compare_nom_asc(const void *pa, const void *pb) { return strcmp( ((FICH *)pa)->nom, ((FICH *)pb)->nom); } static int compare_nom_desc(const void *pa, const void *pb) { return strcmp( ((FICH *)pb)->nom, ((FICH *)pa)->nom); } static int compare_taille_asc(const void *pa, const void *pb) { return ((FICH *)pa)->taille - ((FICH *)pb)->taille; } static int compare_taille_desc(const void *pa, const void *pb) { return ((FICH *)pb)->taille - ((FICH *)pa)->taille; } static int compare_idx(const void *pa, const void *pb) { return ((FICH *)pa)->idx - ((FICH *)pb)->idx; } #define PAR_NOM_ASC 1 #define PAR_NOM_DESC 2 #define PAR_TAILLE_ASC 3 #define PAR_TAILLE_DESC 4 #define PAR_IDX 5 #define PAR_PLOP 6 static int trier_la_liste(int comment) { switch (comment) { case PAR_NOM_ASC: qsort(liste, nombre, sizeof(FICH), compare_nom_asc); break; case PAR_NOM_DESC: qsort(liste, nombre, sizeof(FICH), compare_nom_desc); break; case PAR_TAILLE_ASC: qsort(liste, nombre, sizeof(FICH), compare_taille_asc); break; case PAR_TAILLE_DESC: qsort(liste, nombre, sizeof(FICH), compare_taille_desc); break; case PAR_IDX: qsort(liste, nombre, sizeof(FICH), compare_idx); break; } return 0; } /*----------------------------------------------------------------*/ static int liste_fichiers(WINDOW *win, int flag) { DIR *dir; struct dirent *de; struct stat statbuf; /* * initializing local vars, for list-of-files */ if ( NULL == (liste = malloc(TCHONK*sizeof(FICH))) ) { wprintw(win, "no mem for file list"); wrefresh(win); return 1; } taille = TCHONK; dir = opendir("."); if (dir == NULL) { wprintw(win, "error on 'opendir'"); wrefresh(win); return 1; } nombre = 0; while ( (de=readdir(dir)) != NULL) { if ( ! teste_dirent(de, &statbuf) ) { continue; } /* strdup is a 'non-portable' function ? */ liste[nombre].nom = strdup(de->d_name); liste[nombre].taille = statbuf.st_size; liste[nombre].idx = nombre; nombre++; wrefresh(win); /* * if needed, increase the size of the list */ if (nombre >= taille) { liste = realloc(liste, sizeof(FICH)*(taille+TCHONK)); taille += TCHONK; } } closedir(dir); return nombre; } /*----------------------------------------------------------------*/ char *txt_aide_fs[] = { "\n WARNING !\n\n", " this file selector is a 'quick and dirty' hack\n", " and code was written with a 'Spleyt' spirit :)\n\n", "\n", " smart keys are:\n\n", " a -> sort by name ascending\n", " A -> sort by name reversing\n", " s -> sort by size\n", " S -> sort reverse by size\n", " n -> no sort\n", "", "sort by date is a work in progress..." }; int help_on_file_selector(WINDOW *win, int flag) { int foo; werase(win); for (foo=0; foo<(sizeof(txt_aide_fs)/sizeof(char *)); foo++) { wprintw(win, txt_aide_fs[foo]); wrefresh(win); } foo = getch(); return 0; } /*----------------------------------------------------------------*/ /* * new, 2005 June: now, we get the max usable length for *nomfich. */ int select_new_file(char *nomfich, int t_nom, int flags) { int ligmax, largmax, affh, idx = -1; WINDOW *fen_1, *fen_2; int foo, first, curseur, flag_exit, key; char chaine[T_NOM]; /* * quick'n'dirty security check, need more work. */ if (t_nom > T_NOM) { fprintf(stderr, "\n%s:%d possible buffer overflow\n", __FILE__, __LINE__); exit(1); } ligmax = LINES-8; /* taille verticale de la popup */ largmax = 62; fen_1 = newwin(ligmax, largmax, 2, 12); bordure(fen_1); wrefresh(fen_1); /* * first line of popup display active win number * and current win directory. as this time, we can't * select another directory ;-( */ wstandout(fen_1); for (foo=1; foo", fenetre_active); mvwaddstr(fen_1, 1, 2, chaine); */ if (getcwd(chaine,99)!=NULL) mvwaddstr(fen_1, 1, 3, chaine); else mvwaddstr(fen_1, 1, 9, " can't get cwd, sorry... "); mvwaddstr(fen_1, ligmax-2, 4, "'Q' to abort, to select, '?' for help"); wstandend(fen_1); wrefresh(fen_1); /* * create a subwindow for the scrolling selector */ fen_2 = derwin(fen_1, ligmax-4, largmax-2, 2, 1); scrollok(fen_2, 1); affh = ligmax-4; /* XXX need a valid value :) */ foo = liste_fichiers(fen_2, 0); #if TRACE wprintw(fen_2, "ret liste fichiers = %d\n", foo); wrefresh(fen_2); getch(); #endif trier_la_liste(PAR_NOM_ASC); /* * now, the file list is built, so display the selector. */ first = curseur = 0; flag_exit = 0; do { werase(fen_2); for (foo=0; foo= nombre) break; if (curseur==foo) wstandout(fen_2); mvwprintw(fen_2, foo, 1, " %-46s %9ld ", liste[idx].nom, liste[idx].taille); if (curseur==foo) wstandend(fen_2); } wrefresh(fen_2); #if TRACE mvwprintw(fen_1, 1, 2, "curs %3d first %3d ", curseur, first); wrefresh(fen_1); #endif /* * user interaction */ key = getch(); switch (key) { case KEY_UP: if (curseur) curseur--; else if (first>0) first--; break; case KEY_DOWN: if ((curseur+first) >= (nombre-1)) break; if (curseur < affh-1) curseur++; else if (first<(nombre-affh)) first++; break; /* SORT operations */ case 'a': trier_la_liste(PAR_NOM_ASC); break; case 'A': trier_la_liste(PAR_NOM_DESC); break; case 's': trier_la_liste(PAR_TAILLE_ASC); break; case 'S': trier_la_liste(PAR_TAILLE_DESC); break; case '?': help_on_file_selector(fen_2, 0); break; case '\r': idx = curseur+first; flag_exit = 1; break; case 'Q': flag_exit = -1; break; } } while ( ! flag_exit ); delwin(fen_1); if (flag_exit == 1) { strcpy(nomfich, liste[idx].nom); } /* * free the memory used by our list */ for (foo=0; foo