diff --git a/src/Makefile.am b/src/Makefile.am index bf6a74614af001dd3dcecac2a516344e019de257..3047a5ef5d30ffac9b9bfca3f7c0eda86633ce2e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = ncdu -ncdu_SOURCES = browser.c calc.c delete.c exclude.c help.c main.c path.c util.c +ncdu_SOURCES = browser.c calc.c delete.c dirlist.c exclude.c help.c main.c path.c util.c -noinst_HEADERS = browser.h calc.h delete.h exclude.h global.h help.h path.h util.h +noinst_HEADERS = browser.h calc.h delete.h dirlist.h exclude.h global.h help.h path.h util.h diff --git a/src/browser.c b/src/browser.c index 76c3ebdd8a582db16f9e42e18d8afd6f00157625..84b42cb98d57fc394b5aa74dfc0cd0542f464728 100644 --- a/src/browser.c +++ b/src/browser.c @@ -30,103 +30,12 @@ #include <ncurses.h> -#define BF_NAME 0x01 -#define BF_SIZE 0x02 -#define BF_NDIRF 0x04 /* Normally, dirs before files, setting this disables it */ -#define BF_DESC 0x08 -#define BF_HIDE 0x10 /* don't show hidden files... */ -#define BF_AS 0x40 /* show apparent sizes instead of disk usage */ -#define BF_INFO 0x80 /* show file information window */ - -struct dir *browse_dir = NULL; -unsigned char graph = 0, - flags = BF_SIZE | BF_DESC, - info_page = 0, info_start = 0; - - -#define ishidden(x) (flags & BF_HIDE && (\ - (x->next != browse_dir && (x->name[0] == '.' || x->name[strlen(x->name)-1] == '~'))\ - || x->flags & FF_EXL)) - - -int browse_cmp(struct dir *x, struct dir *y) { - struct dir *a, *b; - int r = 0; - - if(flags & BF_DESC) { - a = y; b = x; - } else { - b = y; a = x; - } - if(!(flags & BF_NDIRF) && y->flags & FF_DIR && !(x->flags & FF_DIR)) - return(1); - if(!(flags & BF_NDIRF) && !(y->flags & FF_DIR) && x->flags & FF_DIR) - return(-1); - - if(flags & BF_NAME) - r = strcmp(a->name, b->name); - if(flags & BF_AS) { - if(r == 0) - r = a->asize > b->asize ? 1 : (a->asize == b->asize ? 0 : -1); - if(r == 0) - r = a->size > b->size ? 1 : (a->size == b->size ? 0 : -1); - } else { - if(r == 0) - r = a->size > b->size ? 1 : (a->size == b->size ? 0 : -1); - if(r == 0) - r = a->asize > b->asize ? 1 : (a->asize == b->asize ? 0 : -1); - } - if(r == 0) - r = strcmp(x->name, y->name); - return(r); -} - +int graph = 0, + show_as = 0, + info_show = 0, + info_page = 0, + info_start = 0; -struct dir *browse_sort(struct dir *list) { - struct dir *p, *q, *e, *tail; - int insize, nmerges, psize, qsize, i; - - insize = 1; - while(1) { - p = list; - list = NULL; - tail = NULL; - nmerges = 0; - while(p) { - nmerges++; - q = p; - psize = 0; - for(i=0; i<insize; i++) { - psize++; - q = q->next; - if(!q) break; - } - qsize = insize; - while(psize > 0 || (qsize > 0 && q)) { - if(psize == 0) { - e = q; q = q->next; qsize--; - } else if(qsize == 0 || !q) { - e = p; p = p->next; psize--; - } else if(browse_cmp(p,q) <= 0) { - e = p; p = p->next; psize--; - } else { - e = q; q = q->next; qsize--; - } - if(tail) tail->next = e; - else list = e; - tail = e; - } - p = q; - } - tail->next = NULL; - if(nmerges <= 1) { - if(list->parent) - list->parent->sub = list; - return list; - } - insize *= 2; - } -} void browse_draw_info(struct dir *dr) { @@ -181,7 +90,7 @@ void browse_draw_info(struct dir *dr) { } -void browse_draw_item(struct dir *n, int row, off_t max, int ispar) { +void browse_draw_item(struct dir *n, int row) { char *line, ct, dt, *size, gr[11]; int i, o; float pc; @@ -190,7 +99,7 @@ void browse_draw_item(struct dir *n, int row, off_t max, int ispar) { attron(A_REVERSE); /* reference to parent dir has a different format */ - if(ispar) { + if(n == dirlist_parent) { mvhline(row, 0, ' ', wincols); o = graph == 0 ? 12 : graph == 1 ? 24 : @@ -214,17 +123,21 @@ void browse_draw_item(struct dir *n, int row, off_t max, int ispar) { && n->sub == NULL ? 'e' : ' ' ; dt = n->flags & FF_DIR ? '/' : ' '; - size = formatsize(flags & BF_AS ? n->asize : n->size); + size = formatsize(show_as ? n->asize : n->size); /* create graph (if necessary) */ - if((pc = (float)(flags & BF_AS ? n->parent->asize : n->parent->size)) < 1) - pc = 1.0f; - pc = ((float)(flags & BF_AS ? n->asize : n->size) / pc) * 100.0f; - if(graph == 1 || graph == 3) { - o = (int)(10.0f*(float)(flags & BF_AS ? n->asize : n->size) / (float)max); - for(i=0; i<10; i++) - gr[i] = i < o ? '#' : ' '; - gr[10] = '\0'; + if(graph) { + /* percentage */ + if((pc = (float)(show_as ? n->parent->asize : n->parent->size)) < 1) + pc = 1.0f; + pc = ((float)(show_as ? n->asize : n->size) / pc) * 100.0f; + /* graph */ + if(graph == 1 || graph == 3) { + o = (int)(10.0f*(float)(show_as ? n->asize : n->size) / (float)(show_as ? dirlist_maxa : dirlist_maxs)); + for(i=0; i<10; i++) + gr[i] = i < o ? '#' : ' '; + gr[10] = '\0'; + } } /* format and add item to the list */ @@ -254,134 +167,74 @@ void browse_draw_item(struct dir *n, int row, off_t max, int ispar) { void browse_draw() { - struct dir *n, ref, *cur, *sel = NULL; - char *line, *tmp; + struct dir *t; + char fmtsize[9], *tmp; int selected, i; - off_t max = 1; erase(); - cur = browse_dir; + t = dirlist_get(0); - /* create header and status bar */ + /* top line - basic info */ attron(A_REVERSE); mvhline(0, 0, ' ', wincols); mvhline(winrows-1, 0, ' ', wincols); mvprintw(0,0,"%s %s ~ Use the arrow keys to navigate, press ? for help", PACKAGE_NAME, PACKAGE_VERSION); - - if(cur) { - line = malloc(winrows+1); - strcpy(line, formatsize(cur->parent->size)); - mvprintw(winrows-1, 0, " Total disk usage: %s Apparent size: %s Items: %d", - line, formatsize(cur->parent->asize), cur->parent->items); - free(line); - } else - mvaddstr(winrows-1, 0, " No items to display."); attroff(A_REVERSE); + /* second line - the path */ mvhline(1, 0, '-', wincols); - if(cur) { + if(t) { mvaddch(1, 3, ' '); - tmp = getpath(cur->parent); + tmp = getpath(t->parent); mvaddstr(1, 4, cropstr(tmp, wincols-8)); mvaddch(1, 4+((int)strlen(tmp) > wincols-8 ? wincols-8 : (int)strlen(tmp)), ' '); } - if(!cur) - return; + /* bottom line - stats */ + attron(A_REVERSE); + if(t) { + strcpy(fmtsize, formatsize(t->parent->size)); + mvprintw(winrows-1, 0, " Total disk usage: %s Apparent size: %s Items: %d", + fmtsize, formatsize(t->parent->asize), t->parent->items); + } else + mvaddstr(winrows-1, 0, " No items to display."); + attroff(A_REVERSE); - /* add reference to parent dir */ - memset(&ref, 0, sizeof(struct dir)); - if(cur->parent->parent) { - ref.name = ".."; - ref.next = cur; - ref.parent = cur->parent; - cur = &ref; - } + /* nothing to display? stop here. */ + if(!t) + return; - /* get maximum size and selected item */ - for(n=cur, selected=-1, i=0; n!=NULL; n=n->next) { - if(ishidden(n)) - continue; - if(n->flags & FF_BSEL) { - selected = i; - sel = n; - } - if((flags & BF_AS ? n->asize : n->size) > max) - max = flags & BF_AS ? n->asize : n->size; - i++; - } - if(selected < 0) - cur->flags |= FF_BSEL; - - /* determine start position */ - for(n=cur,i=0; n!=NULL; n=n->next) { - if(ishidden(n)) - continue; - if(i == (selected / (winrows-3)) * (winrows-3)) - break; - i++; - } - selected -= i; + /* get start position */ + t = dirlist_get(-1*((winrows)/2)); + if(t == dirlist_next(NULL)) + t = NULL; /* print the list to the screen */ - for(i=0; n!=NULL && i<winrows-3; n=n->next) { - if(ishidden(n)) - continue; - browse_draw_item(n, 2+i++, max, n == &ref); + for(i=0; (t=dirlist_next(t)) && i<winrows-3; i++) { + browse_draw_item(t, 2+i); + /* save the selected row number for later */ + if(t->flags & FF_BSEL) + selected = i; } /* draw information window */ - if(sel && (flags & BF_INFO) && sel != &ref) - browse_draw_info(sel); + t = dirlist_get(0); + if(info_show && t != dirlist_parent) + browse_draw_info(t); /* move cursor to selected row for accessibility */ move(selected+2, 0); } -void browse_key_sel(int change) { - struct dir *n, *cur, par; - int i, max; - - if((cur = browse_dir) == NULL) - return; - par.next = cur; - par.flags = 0; - if(cur->parent->parent) - cur = ∥ - - i = 0; - max = -1; - for(n=cur; n!=NULL; n=n->next) { - if(!ishidden(n)) { - max++; - if(n->flags & FF_BSEL) - i = max; - } - n->flags &= ~FF_BSEL; - } - i += change; - i = i<0 ? 0 : i>max ? max : i; - - for(n=cur; n!=NULL; n=n->next) - if(!ishidden(n) && !i--) - n->flags |= FF_BSEL; -} - - -#define toggle(x,y) if(x & y) x -=y; else x |= y - int browse_key(int ch) { - char sort = 0, nonfo = 0, catch = 0; - struct dir *r, *sel; - int i; + struct dir *t, *sel; + int i, catch = 0; - for(sel=browse_dir; sel!=NULL; sel=sel->next) - if(sel->flags & FF_BSEL) - break; + sel = dirlist_get(0); /* info window overwrites a few keys */ - if(flags & BF_INFO && sel) + if(info_show && sel) switch(ch) { case '1': info_page = 0; @@ -416,7 +269,7 @@ int browse_key(int ch) { case 'j': case ' ': if(sel->hlnk && info_page == 1) { - for(i=0,r=sel->hlnk; r!=sel; r=r->hlnk) + for(i=0,t=sel->hlnk; t!=sel; t=t->hlnk) i++; if(i > info_start+6) info_start++; @@ -430,155 +283,120 @@ int browse_key(int ch) { /* selecting items */ case KEY_UP: case 'k': - browse_key_sel(-1); + dirlist_select(dirlist_get(-1)); info_start = 0; break; case KEY_DOWN: case 'j': - browse_key_sel(1); + dirlist_select(dirlist_get(1)); info_start = 0; break; case KEY_HOME: - browse_key_sel(-1*(1<<30)); + dirlist_select(dirlist_next(NULL)); info_start = 0; break; case KEY_LL: case KEY_END: - browse_key_sel(1<<30); + dirlist_select(dirlist_get(1<<30)); info_start = 0; break; case KEY_PPAGE: - browse_key_sel(-1*(winrows-3)); + dirlist_select(dirlist_get(-1*(winrows-3))); info_start = 0; break; case KEY_NPAGE: - browse_key_sel(winrows-3); + dirlist_select(dirlist_get(winrows-3)); info_start = 0; break; /* sorting items */ case 'n': - if(flags & BF_NAME) - toggle(flags, BF_DESC); - else - flags = (flags & BF_HIDE) + (flags & BF_NDIRF) + BF_NAME; - sort++; - nonfo++; + dirlist_set_sort(DL_COL_NAME, dirlist_sort_col == DL_COL_NAME ? !dirlist_sort_desc : DL_NOCHANGE, DL_NOCHANGE); + info_show = 0; break; case 's': - if(flags & BF_SIZE) - toggle(flags, BF_DESC); - else - flags = (flags & BF_HIDE) + (flags & BF_NDIRF) + BF_SIZE + BF_DESC; - sort++; - nonfo++; + i = show_as ? DL_COL_ASIZE : DL_COL_SIZE; + dirlist_set_sort(i, dirlist_sort_col == i ? !dirlist_sort_desc : DL_NOCHANGE, DL_NOCHANGE); + info_show = 0; break; case 'e': - toggle(flags, BF_HIDE); - browse_key_sel(0); - nonfo++; + dirlist_set_hidden(!dirlist_hidden); + info_show = 0; break; case 't': - toggle(flags, BF_NDIRF); - sort++; - nonfo++; + dirlist_set_sort(DL_NOCHANGE, DL_NOCHANGE, dirlist_sort_df); + info_show = 0; break; case 'a': - toggle(flags, BF_AS); - nonfo++; + show_as = !show_as; + if(dirlist_sort_col == DL_COL_ASIZE || dirlist_sort_col == DL_COL_SIZE) + dirlist_set_sort(show_as ? DL_COL_ASIZE : DL_COL_SIZE, DL_NOCHANGE, DL_NOCHANGE); + info_show = 0; break; /* browsing */ case 10: case KEY_RIGHT: case 'l': - if(sel != NULL && sel->sub != NULL) { - browse_dir = sel->sub; - sort++; - } - if(sel == NULL && browse_dir != NULL && browse_dir->parent->parent) { - browse_dir = browse_dir->parent->parent->sub; - sort++; - } - browse_key_sel(0); - nonfo++; + if(sel != NULL && sel->sub != NULL) + dirlist_open(sel->sub); + info_show = 0; break; case KEY_LEFT: case 'h': case '<': - if(browse_dir != NULL && browse_dir->parent->parent != NULL) { - browse_dir = browse_dir->parent->parent->sub; - sort++; - } - browse_key_sel(0); - nonfo++; + if(sel != NULL && sel->parent->parent != NULL) + dirlist_open(sel->parent); + info_show = 0; break; /* and other stuff */ case 'r': - if(browse_dir != NULL) - calc_init(getpath(browse_dir->parent), browse_dir->parent); - nonfo++; + if(sel != NULL) + calc_init(getpath(sel->parent), sel->parent); + info_show = 0; break; case 'q': - if(flags & BF_INFO) - nonfo++; + if(info_show) + info_show = 0; else return 1; break; case 'g': if(++graph > 3) graph = 0; - nonfo++; + info_show = 0; break; case 'i': - toggle(flags, BF_INFO); + info_show = !info_show; break; case '?': help_init(); - nonfo++; + info_show = 0; break; case 'd': - if(sel == NULL) + if(sel == NULL || sel == dirlist_parent) break; - nonfo++; - /* quirky method of getting the next selected dir without actually selecting it */ - browse_key_sel(sel->next ? 1 : -1); - for(r=browse_dir; r!=NULL; r=r->next) - if(r->flags & FF_BSEL) - break; - browse_key_sel(sel->next ? -1 : 1); - delete_init(sel, r); + info_show = 0; + if((t = dirlist_get(1)) == sel) + t = dirlist_get(-1); + delete_init(sel, t); break; } - if(sort && browse_dir != NULL) - browse_dir = browse_sort(browse_dir); - if(nonfo) { - flags &= ~BF_INFO; - info_start = 0; - } - if(flags & BF_INFO) { - for(sel=browse_dir; sel!=NULL; sel=sel->next) - if(sel->flags & FF_BSEL) - break; - if(sel && !sel->hlnk) - info_page = 0; - } + /* make sure the info_* options are correct */ + sel = dirlist_get(0); + if(!info_show || sel == dirlist_parent) + info_show = info_page = info_start = 0; + else if(sel && !sel->hlnk) + info_page = info_start = 0; + return 0; } void browse_init(struct dir *cur) { pstate = ST_BROWSE; - if(cur != NULL && cur->parent == NULL) - browse_dir = cur->sub; - else - browse_dir = cur; - if(browse_dir != NULL && browse_dir->parent->sub != browse_dir) - browse_dir = cur->parent->sub; - if(browse_dir != NULL) - browse_dir = browse_sort(browse_dir); - browse_key_sel(0); + dirlist_open(cur); } diff --git a/src/dirlist.c b/src/dirlist.c new file mode 100644 index 0000000000000000000000000000000000000000..ed1d1da7a3ad0e154df01217f2a320745f0755a8 --- /dev/null +++ b/src/dirlist.c @@ -0,0 +1,293 @@ +/* ncdu - NCurses Disk Usage + + Copyright (c) 2007-2010 Yoran Heling + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#include "global.h" + +#include <string.h> + + +/* public variables */ +struct dir *dirlist_parent = NULL; +off_t dirlist_maxs = 0, + dirlist_maxa = 0; + +int dirlist_sort_desc = 1, + dirlist_sort_col = DL_COL_SIZE, + dirlist_sort_df = 0, + dirlist_hidden = 0; + +/* private state vars */ +struct dir dirlist_parent_alloc; +struct dir *head, *head_real, *selected; + + + +#define ISHIDDEN(d) (dirlist_hidden && (d) != dirlist_parent && (\ + (d)->flags & FF_EXL || (d)->name[0] == '.' || (d)->name[strlen((d)->name)-1] == '~'\ + )) + + + +int dirlist_cmp(struct dir *x, struct dir *y) { + int r; + + /* dirs are always before files when that option is set */ + if(dirlist_sort_df) { + if(y->flags & FF_DIR && !(x->flags & FF_DIR)) + return 1; + else if(!(y->flags & FF_DIR) && x->flags & FF_DIR) + return -1; + } + + /* sort columns: + * 1 -> 2 -> 3 + * NAME: name -> size -> asize + * SIZE: size -> asize -> name + * ASIZE: asize -> size -> name + * + * Note that the method used below is supposed to be fast, not readable :-) + */ +#define CMP_NAME strcmp(x->name, y->name) +#define CMP_SIZE (x->size > y->size ? 1 : (x->size == y->size ? 0 : -1)) +#define CMP_ASIZE (x->asize > y->asize ? 1 : (x->asize == y->asize ? 0 : -1)) + + /* try 1 */ + r = dirlist_sort_col == DL_COL_NAME ? CMP_NAME : dirlist_sort_col == DL_COL_SIZE ? CMP_SIZE : CMP_ASIZE; + /* try 2 */ + if(!r) + r = dirlist_sort_col == DL_COL_SIZE ? CMP_ASIZE : CMP_SIZE; + /* try 3 */ + if(!r) + r = dirlist_sort_col == DL_COL_NAME ? CMP_ASIZE : CMP_NAME; + + /* reverse when sorting in descending order */ + if(dirlist_sort_desc && r != 0) + r = r < 0 ? 1 : -1; + + return r; +} + + +struct dir *dirlist_sort(struct dir *list) { + struct dir *p, *q, *e, *tail; + int insize, nmerges, psize, qsize, i; + + insize = 1; + while(1) { + p = list; + list = NULL; + tail = NULL; + nmerges = 0; + while(p) { + nmerges++; + q = p; + psize = 0; + for(i=0; i<insize; i++) { + psize++; + q = q->next; + if(!q) break; + } + qsize = insize; + while(psize > 0 || (qsize > 0 && q)) { + if(psize == 0) { + e = q; q = q->next; qsize--; + } else if(qsize == 0 || !q) { + e = p; p = p->next; psize--; + } else if(dirlist_cmp(p,q) <= 0) { + e = p; p = p->next; psize--; + } else { + e = q; q = q->next; qsize--; + } + if(tail) tail->next = e; + else list = e; + tail = e; + } + p = q; + } + tail->next = NULL; + if(nmerges <= 1) { + if(list->parent) + list->parent->sub = list; + return list; + } + insize *= 2; + } +} + + +/* passes through the dir listing once and: + * - makes sure one, and only one, visible item is selected + * - updates the dirlist_(maxs|maxa) values + * - makes sure that the FF_BSEL bits are correct */ +void dirlist_fixup() { + struct dir *t; + + /* we're going to determine the selected items from the list itself, so reset this one */ + selected = NULL; + + for(t=head; t; t=t->next) { + /* not visible? not selected! */ + if(ISHIDDEN(t)) + t->flags &= ~FF_BSEL; + else { + /* visible and selected? make sure only one item is selected */ + if(t->flags & FF_BSEL) { + if(!selected) + selected = t; + else + t->flags &= ~FF_BSEL; + } + } + + /* update dirlist_(maxs|maxa) */ + if(t->size > dirlist_maxs) + dirlist_maxs = t->size; + if(t->asize > dirlist_maxa) + dirlist_maxa = t->asize; + } + + /* no selected items found after one pass? select the first visible item */ + if(!selected) { + selected = dirlist_next(NULL); + selected->flags |= FF_BSEL; + } +} + + +void dirlist_open(struct dir *d) { + /* set the head of the list */ + head_real = head = d == NULL ? NULL : d->parent == NULL ? d->sub : d->parent->sub; + + /* reset internal status */ + dirlist_maxs = dirlist_maxa = 0; + + /* stop if this is not a directory list we can work with */ + if(head == NULL) { + dirlist_parent = NULL; + return; + } + + /* sort the dir listing */ + head_real = head = dirlist_sort(head); + + /* set the reference to the parent dir */ + if(head->parent->parent) { + dirlist_parent = &dirlist_parent_alloc; + dirlist_parent->name = ".."; + dirlist_parent->next = head; + dirlist_parent->parent = head->parent; + dirlist_parent->sub = head->parent; + head = dirlist_parent; + } else + dirlist_parent = NULL; + + dirlist_fixup(); +} + + +struct dir *dirlist_next(struct dir *d) { + if(!head) + return NULL; + if(!d) { + if(!ISHIDDEN(head)) + return head; + else + d = head; + } + while((d = d->next)) { + if(!ISHIDDEN(d)) + return d; + } + return NULL; +} + + +/* this function assumes that 'selected' is valid and points to a visible item */ +struct dir *dirlist_get(int i) { + struct dir *t = selected, *d; + int j; + + if(!head) + return NULL; + + /* i == 0? return the selected item */ + if(!i) + return selected; + + /* positive number? simply move forward */ + while(i > 0) { + d = dirlist_next(t); + if(!d) + return t; + t = d; + if(!--i) + return t; + } + + /* negative number? start from beginning to get the index of the selected + * item, and then start all over to get the requested item before that. + * XXX: This can obviously be optimized by using a doubly linked list. */ + for(j=0,t=NULL; (t=dirlist_next(t)); j++) + if(t == selected) + break; + for(t=NULL,j+=i; (t=dirlist_next(t))&&j>0; j--) + ; + return t; +} + + +void dirlist_select(struct dir *d) { + if(!head || ISHIDDEN(d) || d->parent != head->parent) + return; + + selected->flags &= ~FF_BSEL; + selected = d; + selected->flags |= FF_BSEL; +} + + +void dirlist_set_sort(int col, int desc, int df) { + /* update config */ + if(col != DL_NOCHANGE) + dirlist_sort_col = col; + if(desc != DL_NOCHANGE) + dirlist_sort_desc = desc; + if(df != DL_NOCHANGE) + dirlist_sort_df = df; + + /* sort the list (excluding the parent, which is always on top) */ + head_real = dirlist_sort(head_real); + if(dirlist_parent) + dirlist_parent->next = head_real; + else + head = head_real; +} + + +void dirlist_set_hidden(int hidden) { + dirlist_hidden = hidden; + dirlist_fixup(); +} + diff --git a/src/dirlist.h b/src/dirlist.h new file mode 100644 index 0000000000000000000000000000000000000000..f3e7c585d1a8bc6df1a8e00c332766925b05d3a5 --- /dev/null +++ b/src/dirlist.h @@ -0,0 +1,78 @@ +/* ncdu - NCurses Disk Usage + + Copyright (c) 2007-2010 Yoran Heling + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +/* Note: all functions below include a 'reference to parent dir' node at the + * top of the list. */ + +#ifndef _dirlist_h +#define _dirlist_h + +#include "global.h" + + +#define DL_NOCHANGE -1 +#define DL_COL_NAME 0 +#define DL_COL_SIZE 1 +#define DL_COL_ASIZE 2 + + +void dirlist_open(struct dir *); + +/* Get the next non-hidden item, + * NULL = get first non-hidden item */ +struct dir *dirlist_next(struct dir *); + +/* Get the struct dir item relative to the selected item, or the item nearest to the requested item + * i = 0 get selected item + * hidden items aren't considered */ +struct dir *dirlist_get(int i); + +/* Set selected dir (must be in the currently opened directory, obviously) */ +void dirlist_select(struct dir *); + +/* Change sort column (arguments should have a NO_CHANGE option) */ +void dirlist_set_sort(int column, int desc, int df); + +/* Set the hidden thingy */ +void dirlist_set_hidden(int hidden); + + +/* DO NOT WRITE TO ANY OF THE BELOW VARIABLES FROM OUTSIDE OF dirlist.c! */ + +/* The 'reference to parent dir' */ +extern struct dir *dirlist_parent; + +/* current sorting configuration (set with dirlist_set_sort()) */ +extern int dirlist_sort_desc, dirlist_sort_col, dirlist_sort_df; + +/* set with dirlist_set_hidden() */ +extern int dirlist_hidden; + +/* maximum size of an item in the opened dir */ +extern off_t dirlist_maxs, dirlist_maxa; + + +#endif + diff --git a/src/global.h b/src/global.h index 0ca5d437b7b49071b22f7620f4d9f510f49c4b53..66f0107198756193efa4a5bd23e0f840719f687d 100644 --- a/src/global.h +++ b/src/global.h @@ -78,5 +78,6 @@ int input_handle(int); #include "browser.h" #include "help.h" #include "path.h" +#include "dirlist.h" #endif