5 * by JH <jheinonen@users.sourceforge.net>
7 * Copyright (C) Jaakko Heinonen
12 /*#undef USE_FILESEL*/
21 # include "abook_curses.h"
31 #if defined(HAVE_LOCALE_H) || defined(HAVE_SETLOCALE)
35 * this is a quick and dirty hack and it is
36 * not likely to work well
40 # define iscntrl(X) (X < 32)
41 # define isprint(X) (!iscntrl(X))
45 * hmmm, these should be universal and nice :)
48 #define XCTRL(x) ((x) & 31)
50 #define ENTER_KEY KEY_ENTER
51 #define BACKSPACE_KEY KEY_BACKSPACE
52 #define CANCEL_KEY XCTRL('g')
57 # define MALLOC(X) abook_malloc(X)
58 # define REALLOC(X, XX) abook_realloc(X, XX)
60 # define MALLOC(X) malloc(X)
61 # define REALLOC(X, XX) realloc(X, XX)
64 /* introduce filesel */
69 #define INITIAL_BUFSIZE 100
72 wenter_string(WINDOW *win, const int maxlen, const int flags)
78 int size = maxlen > 0 ? maxlen + 1 : INITIAL_BUFSIZE;
81 str = (char *)MALLOC(size);
83 for( ;; ) { /* main loop */
84 if(flags & ESTR_DONT_WRAP && x+i > COLS-2) {
85 mvwaddnstr(win, y, x, str+(1+x+i-COLS), COLS-x-1);
86 wmove(win, y, COLS-1);
93 switch( (ch = getch()) ) {
101 mvwdelch(win, y, x + --i);
111 if( ! (flags & ESTR_USE_FILESEL) )
119 if( !isprint(ch) || iscntrl(ch)
120 || (maxlen > 0 && i + 1 > maxlen) )
125 str = (char *)REALLOC( str, size *= 2 );
128 if( i >= 0 && str != NULL )
139 * by JH <jheinonen@users.sourceforge.net>
141 * Copyright (C) Jaakko Heinonen
147 #include <sys/stat.h>
151 #define FILESEL_STATUSLINE 2
153 #define FILESEL_LIST_TOP 4
154 #define FILESEL_LIST_BOTTOM (LINES-2)
156 #define FILESEL_LIST_LINES (FILESEL_LIST_BOTTOM-FILESEL_LIST_TOP)
157 #define FILESEL_LIST_COLS COLS
159 #define FILESEL_LAST_LIST_ITEM ( filesel_first_list_item + FILESEL_LIST_LINES - 1 )
162 #define FLSL_TYPE_DIR 0
163 #define FLSL_TYPE_OTHER 1
165 struct filesel_list_item {
182 while( getcwd(dir, size) == NULL && errno == ERANGE )
183 dir = REALLOC(dir, size *= 2);
193 #define FILESEL_LAST_ITEM (filesel_items -1)
195 int filesel_curitem = -1;
196 int filesel_first_list_item = -1;
199 struct filesel_list_item *lst = NULL ;
201 int filesel_list_capacity = 0;
203 WINDOW *filesel_list;
211 filesel_first_list_item = filesel_curitem = -1;
212 filesel_list_capacity = 0;
218 filesel_list = newwin(FILESEL_LIST_LINES, FILESEL_LIST_COLS,
219 FILESEL_LIST_TOP, 0);
231 intrflush(stdscr, FALSE);
232 keypad(stdscr, TRUE);
240 filesel_close_list();
241 delwin(filesel_list);
250 if( filesel_curitem < 0 && filesel_first_list_item < 0 && filesel_items > 0 )
251 filesel_curitem = filesel_first_list_item = 0;
256 filesel_add_filesel_list_item(struct filesel_list_item item)
258 if( ++filesel_items > filesel_list_capacity) {
259 filesel_list_capacity =
260 filesel_list_capacity < 1 ? 30:filesel_list_capacity << 1;
261 lst = (struct filesel_list_item *)REALLOC(lst,
262 filesel_list_capacity *
263 sizeof(struct filesel_list_item) );
266 lst[FILESEL_LAST_ITEM] = item;
268 filesel_check_list();
274 #define FILESEL_DIRS_FIRST
275 #define FILESEL_ALPHABETIC_ORDER
277 #ifdef FILESEL_ALPHABETIC_ORDER
278 # ifndef FILESEL_DIRS_FIRST
279 # define FILESEL_DIRS_FIRST
283 #ifdef FILESEL_ALPHABETIC_ORDER
285 filenamecmp(const void *a, const void *b)
287 return strcmp( ((struct filesel_list_item *)a) -> filename,
288 ((struct filesel_list_item *)b) -> filename );
295 #ifdef FILESEL_DIRS_FIRST
297 struct filesel_list_item tmp;
299 while(lst[fdp].type == FLSL_TYPE_DIR)
300 if( ++fdp >= FILESEL_LAST_ITEM )
303 for(i = fdp + 1; i < filesel_items; i++) {
304 if(lst[i].type == FLSL_TYPE_DIR ) {
307 for( j = i; j > fdp ; j--)
313 #ifdef FILESEL_ALPHABETIC_ORDER
315 if( options_get_int("filesel_sort") ) {
318 qsort((void *)lst, fdp, sizeof(struct filesel_list_item),
321 qsort((void *)(&lst[fdp]),
322 FILESEL_LAST_ITEM - fdp + 1,
323 sizeof(struct filesel_list_item),
333 filesel_refresh_statusline()
337 move(FILESEL_STATUSLINE,0);
340 mvaddnstr(FILESEL_STATUSLINE, 5,
341 ( p = my_getcwd() ), COLS-5 );
347 filesel_highlight_line(WINDOW *win, int line)
351 wattron(win, A_STANDOUT);
354 for(i = 0; i < FILESEL_LIST_COLS; i++)
359 filesel_print_list_line(int i, int line)
361 if( lst[i].type == FLSL_TYPE_DIR ) {
362 mvwaddch(filesel_list, line, 3, 'd');
364 wattron(filesel_list, A_BOLD);
368 mvwaddnstr(filesel_list, line, 5, lst[i].filename, COLS - 5);
372 filesel_refresh_list()
376 werase(filesel_list);
378 if( filesel_first_list_item < 0 || filesel_items < 1 ) {
380 wrefresh(filesel_list);
384 for( line = 0, i = filesel_first_list_item ;
385 i <= FILESEL_LAST_LIST_ITEM && i < filesel_items; line++, i++ ) {
387 if(i == filesel_curitem) {
388 filesel_highlight_line(filesel_list, line);
389 wattron(filesel_list, A_STANDOUT);
391 wattrset(filesel_list, 0);
393 filesel_print_list_line(i, line);
397 wrefresh(filesel_list);
403 if( filesel_curitem < 1 )
407 if( filesel_first_list_item > 0 && filesel_curitem < filesel_first_list_item )
408 filesel_first_list_item--;
410 filesel_refresh_list();
414 filesel_scroll_down()
416 if( filesel_curitem > filesel_items - 2 )
420 if( filesel_curitem > FILESEL_LAST_LIST_ITEM )
421 filesel_first_list_item++;
423 filesel_refresh_list();
430 if( filesel_curitem < 1 )
433 if( filesel_curitem == filesel_first_list_item ) {
434 filesel_curitem = (filesel_curitem -= FILESEL_LIST_LINES) < 0 ? 0 : filesel_curitem;
435 filesel_first_list_item = filesel_curitem;
437 filesel_curitem = filesel_first_list_item;
439 filesel_refresh_list();
445 if( filesel_curitem > filesel_items - 2 )
448 if( filesel_curitem == FILESEL_LAST_LIST_ITEM ) {
449 filesel_curitem = (filesel_curitem += FILESEL_LIST_LINES) > FILESEL_LAST_ITEM ?
450 FILESEL_LAST_ITEM : filesel_curitem;
451 filesel_first_list_item = filesel_curitem - FILESEL_LIST_LINES + 1;
452 if( filesel_first_list_item < 0 )
453 filesel_first_list_item = 0;
455 filesel_curitem = FILESEL_LAST_LIST_ITEM < FILESEL_LAST_ITEM ?
456 FILESEL_LAST_LIST_ITEM : FILESEL_LAST_ITEM;
458 filesel_refresh_list();
465 if(filesel_items > 0) {
466 filesel_first_list_item = 0;
469 filesel_refresh_list();
475 if(filesel_items > 0) {
476 filesel_curitem = FILESEL_LAST_ITEM;
477 filesel_first_list_item = filesel_curitem - FILESEL_LIST_LINES + 1;
478 if( filesel_first_list_item < 0 )
479 filesel_first_list_item = 0;
481 filesel_refresh_list();
489 struct dirent *entry;
491 struct filesel_list_item item;
495 entry = readdir(dir);
500 stat(entry->d_name, &st);
501 strcpy(item.filename, entry->d_name);
502 item.type = S_ISDIR(st.st_mode) ?
503 FLSL_TYPE_DIR : FLSL_TYPE_OTHER;
504 filesel_add_filesel_list_item(item);
509 filesel_check_list();
510 filesel_refresh_statusline();
511 filesel_refresh_list();
521 if(lst[filesel_curitem].type == FLSL_TYPE_DIR) {
523 newdir = (char *)MALLOC(strlen(dir) +
524 strlen(lst[filesel_curitem].filename) +2 );
527 strcat(newdir,lst[filesel_curitem].filename);
529 if( (chdir(newdir)) != -1) {
530 filesel_close_list();
540 filesel_goto_item(int ch)
544 for(i=filesel_curitem+1; i<filesel_items; i++)
545 if( lst[i].filename[0] == ch ) {
550 if( filesel_curitem > FILESEL_LAST_LIST_ITEM)
551 filesel_first_list_item=filesel_curitem;
553 filesel_refresh_list();
563 switch( (ch = getch()) ) {
566 case 'R': filesel_close_list(); filesel_read_dir();
569 case KEY_UP: filesel_scroll_up(); break;
571 case KEY_DOWN: filesel_scroll_down(); break;
573 case KEY_PPAGE: filesel_page_up(); break;
575 case KEY_NPAGE: filesel_page_down(); break;
577 case KEY_HOME: filesel_goto_home(); break;
578 case KEY_END: filesel_goto_end(); break;
581 case '\r': if( filesel_enter() ) {
585 default: filesel_goto_item(ch);
593 char *dir, *tmp, *ptr = NULL;
598 if( !filesel_loop() ) {
600 tmp = (char *)MALLOC(strlen(dir) +
601 strlen(lst[filesel_curitem].filename) + 2);
604 strcat(tmp, lst[filesel_curitem].filename);
615 #endif /* USE_FILESEL */