2009-04-13 19:25:46 +04:00
|
|
|
/* ncdu - NCurses Disk Usage
|
|
|
|
|
2010-02-27 17:20:57 +03:00
|
|
|
Copyright (c) 2007-2010 Yoran Heling
|
2007-07-20 15:15:46 +04:00
|
|
|
|
|
|
|
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:
|
2009-04-13 19:25:46 +04:00
|
|
|
|
2007-07-20 15:15:46 +04:00
|
|
|
The above copyright notice and this permission notice shall be included
|
|
|
|
in all copies or substantial portions of the Software.
|
2009-04-13 19:25:46 +04:00
|
|
|
|
2007-07-20 15:15:46 +04:00
|
|
|
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.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2009-04-26 13:08:40 +04:00
|
|
|
#include "global.h"
|
2007-07-20 15:15:46 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <ncurses.h>
|
2007-07-20 15:15:46 +04:00
|
|
|
|
|
|
|
|
2009-04-18 17:23:33 +04:00
|
|
|
#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;
|
2010-02-27 17:15:25 +03:00
|
|
|
unsigned char graph = 0,
|
|
|
|
flags = BF_SIZE | BF_DESC,
|
|
|
|
info_page = 0, info_start = 0;
|
2009-04-18 17:23:33 +04:00
|
|
|
|
|
|
|
|
|
|
|
#define ishidden(x) (flags & BF_HIDE && (\
|
|
|
|
(x->next != browse_dir && (x->name[0] == '.' || x->name[strlen(x->name)-1] == '~'))\
|
|
|
|
|| x->flags & FF_EXL))
|
2009-04-13 19:25:46 +04:00
|
|
|
|
|
|
|
|
|
|
|
int browse_cmp(struct dir *x, struct dir *y) {
|
2007-07-20 15:15:46 +04:00
|
|
|
struct dir *a, *b;
|
|
|
|
int r = 0;
|
2007-07-24 11:58:22 +04:00
|
|
|
|
2009-04-18 17:23:33 +04:00
|
|
|
if(flags & BF_DESC) {
|
2007-07-20 15:15:46 +04:00
|
|
|
a = y; b = x;
|
|
|
|
} else {
|
|
|
|
b = y; a = x;
|
|
|
|
}
|
2009-04-18 17:23:33 +04:00
|
|
|
if(!(flags & BF_NDIRF) && y->flags & FF_DIR && !(x->flags & FF_DIR))
|
2007-07-24 12:53:55 +04:00
|
|
|
return(1);
|
2009-04-18 17:23:33 +04:00
|
|
|
if(!(flags & BF_NDIRF) && !(y->flags & FF_DIR) && x->flags & FF_DIR)
|
2007-07-24 12:53:55 +04:00
|
|
|
return(-1);
|
|
|
|
|
2009-04-18 17:23:33 +04:00
|
|
|
if(flags & BF_NAME)
|
2007-07-20 15:15:46 +04:00
|
|
|
r = strcmp(a->name, b->name);
|
2009-04-18 17:23:33 +04:00
|
|
|
if(flags & BF_AS) {
|
2008-12-11 20:13:03 +03:00
|
|
|
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);
|
|
|
|
}
|
2007-07-24 12:53:55 +04:00
|
|
|
if(r == 0)
|
2007-07-26 20:37:33 +04:00
|
|
|
r = strcmp(x->name, y->name);
|
2007-07-20 15:15:46 +04:00
|
|
|
return(r);
|
|
|
|
}
|
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
|
|
|
|
struct dir *browse_sort(struct dir *list) {
|
2007-07-20 15:15:46 +04:00
|
|
|
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--;
|
2009-04-13 19:25:46 +04:00
|
|
|
} else if(browse_cmp(p,q) <= 0) {
|
2007-07-20 15:15:46 +04:00
|
|
|
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;
|
2009-04-18 17:45:26 +04:00
|
|
|
if(nmerges <= 1) {
|
|
|
|
if(list->parent)
|
|
|
|
list->parent->sub = list;
|
2007-07-20 15:15:46 +04:00
|
|
|
return list;
|
2009-04-18 17:45:26 +04:00
|
|
|
}
|
2007-07-20 15:15:46 +04:00
|
|
|
insize *= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-18 18:02:46 +04:00
|
|
|
void browse_draw_info(struct dir *dr) {
|
2010-02-27 17:15:25 +03:00
|
|
|
struct dir *t;
|
2010-02-28 12:13:12 +03:00
|
|
|
int i;
|
2010-02-27 17:15:25 +03:00
|
|
|
|
2009-04-18 18:02:46 +04:00
|
|
|
nccreate(11, 60, "Item info");
|
|
|
|
|
2010-02-27 17:15:25 +03:00
|
|
|
if(dr->hlnk) {
|
|
|
|
if(info_page == 0)
|
|
|
|
attron(A_REVERSE);
|
|
|
|
ncaddstr(0, 41, "1:Info");
|
|
|
|
attroff(A_REVERSE);
|
|
|
|
if(info_page == 1)
|
|
|
|
attron(A_REVERSE);
|
|
|
|
ncaddstr(0, 50, "2:Links");
|
|
|
|
attroff(A_REVERSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(info_page) {
|
|
|
|
case 0:
|
|
|
|
attron(A_BOLD);
|
|
|
|
ncaddstr(2, 3, "Name:");
|
|
|
|
ncaddstr(3, 3, "Path:");
|
|
|
|
ncaddstr(4, 3, "Type:");
|
|
|
|
ncaddstr(6, 3, " Disk usage:");
|
|
|
|
ncaddstr(7, 3, "Apparent size:");
|
|
|
|
attroff(A_BOLD);
|
|
|
|
|
|
|
|
ncaddstr(2, 9, cropstr(dr->name, 49));
|
|
|
|
ncaddstr(3, 9, cropstr(getpath(dr->parent), 49));
|
|
|
|
ncaddstr(4, 9, dr->flags & FF_DIR ? "Directory"
|
|
|
|
: dr->flags & FF_FILE ? "File" : "Other (link, device, socket, ..)");
|
|
|
|
ncprint(6, 18, "%s (%s B)", formatsize(dr->size), fullsize(dr->size));
|
|
|
|
ncprint(7, 18, "%s (%s B)", formatsize(dr->asize), fullsize(dr->asize));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
for(i=0,t=dr->hlnk; t!=dr; t=t->hlnk,i++) {
|
|
|
|
if(info_start > i)
|
|
|
|
continue;
|
|
|
|
if(i-info_start > 5)
|
|
|
|
break;
|
|
|
|
ncaddstr(2+i-info_start, 3, cropstr(getpath(t), 54));
|
|
|
|
}
|
|
|
|
if(t!=dr)
|
|
|
|
ncaddstr(8, 25, "-- more --");
|
|
|
|
break;
|
|
|
|
}
|
2009-04-18 18:02:46 +04:00
|
|
|
|
|
|
|
ncaddstr(9, 32, "Press i to hide this window");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
void browse_draw_item(struct dir *n, int row, off_t max, int ispar) {
|
2009-04-26 13:18:45 +04:00
|
|
|
char *line, ct, dt, *size, gr[11];
|
2009-04-13 19:25:46 +04:00
|
|
|
int i, o;
|
|
|
|
float pc;
|
2007-07-20 15:15:46 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
if(n->flags & FF_BSEL)
|
|
|
|
attron(A_REVERSE);
|
|
|
|
|
|
|
|
/* reference to parent dir has a different format */
|
|
|
|
if(ispar) {
|
|
|
|
mvhline(row, 0, ' ', wincols);
|
2009-08-03 16:26:10 +04:00
|
|
|
o = graph == 0 ? 12 :
|
|
|
|
graph == 1 ? 24 :
|
|
|
|
graph == 2 ? 20 :
|
|
|
|
31 ;
|
2009-04-13 19:25:46 +04:00
|
|
|
mvaddstr(row, o, "/..");
|
|
|
|
if(n->flags & FF_BSEL)
|
|
|
|
attroff(A_REVERSE);
|
|
|
|
return;
|
|
|
|
}
|
2007-07-20 15:15:46 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
/* determine indication character */
|
|
|
|
ct = n->flags & FF_EXL ? '<' :
|
|
|
|
n->flags & FF_ERR ? '!' :
|
|
|
|
n->flags & FF_SERR ? '.' :
|
|
|
|
n->flags & FF_OTHFS ? '>' :
|
2010-02-27 13:29:36 +03:00
|
|
|
n->flags & FF_HLNKC ? 'H' :
|
2009-04-13 19:25:46 +04:00
|
|
|
!(n->flags & FF_FILE
|
|
|
|
|| n->flags & FF_DIR) ? '@' :
|
|
|
|
n->flags & FF_DIR
|
|
|
|
&& n->sub == NULL ? 'e' :
|
|
|
|
' ' ;
|
|
|
|
dt = n->flags & FF_DIR ? '/' : ' ';
|
2009-04-18 17:23:33 +04:00
|
|
|
size = formatsize(flags & BF_AS ? n->asize : n->size);
|
2009-04-13 19:25:46 +04:00
|
|
|
|
|
|
|
/* create graph (if necessary) */
|
2009-05-01 11:07:28 +04:00
|
|
|
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;
|
2009-04-18 17:23:33 +04:00
|
|
|
if(graph == 1 || graph == 3) {
|
|
|
|
o = (int)(10.0f*(float)(flags & BF_AS ? n->asize : n->size) / (float)max);
|
2009-04-13 19:25:46 +04:00
|
|
|
for(i=0; i<10; i++)
|
|
|
|
gr[i] = i < o ? '#' : ' ';
|
|
|
|
gr[10] = '\0';
|
|
|
|
}
|
2007-07-24 11:58:22 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
/* format and add item to the list */
|
2009-04-26 13:18:45 +04:00
|
|
|
line = malloc(winrows+1);
|
2009-04-18 17:23:33 +04:00
|
|
|
switch(graph) {
|
2009-04-13 19:25:46 +04:00
|
|
|
case 0:
|
2009-08-03 16:26:10 +04:00
|
|
|
sprintf(line, "%%c %%8s %%c%%-%ds", wincols-13);
|
|
|
|
mvprintw(row, 0, line, ct, size, dt, cropstr(n->name, wincols-13));
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case 1:
|
2009-08-03 16:26:10 +04:00
|
|
|
sprintf(line, "%%c %%8s [%%10s] %%c%%-%ds", wincols-25);
|
|
|
|
mvprintw(row, 0, line, ct, size, gr, dt, cropstr(n->name, wincols-25));
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case 2:
|
2009-08-03 16:26:10 +04:00
|
|
|
sprintf(line, "%%c %%8s [%%5.1f%%%%] %%c%%-%ds", wincols-21);
|
|
|
|
mvprintw(row, 0, line, ct, size, pc, dt, cropstr(n->name, wincols-21));
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case 3:
|
2009-08-03 16:26:10 +04:00
|
|
|
sprintf(line, "%%c %%8s [%%5.1f%%%% %%10s] %%c%%-%ds", wincols-32);
|
|
|
|
mvprintw(row, 0, line, ct, size, pc, gr, dt, cropstr(n->name, wincols-32));
|
2009-04-13 19:25:46 +04:00
|
|
|
}
|
2009-04-26 13:18:45 +04:00
|
|
|
free(line);
|
2009-04-13 19:25:46 +04:00
|
|
|
|
|
|
|
if(n->flags & FF_BSEL)
|
|
|
|
attroff(A_REVERSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-26 11:49:51 +04:00
|
|
|
void browse_draw() {
|
2009-04-18 18:02:46 +04:00
|
|
|
struct dir *n, ref, *cur, *sel = NULL;
|
2009-04-26 13:18:45 +04:00
|
|
|
char *line, *tmp;
|
2009-04-13 19:25:46 +04:00
|
|
|
int selected, i;
|
2007-07-29 14:50:48 +04:00
|
|
|
off_t max = 1;
|
2007-07-20 15:15:46 +04:00
|
|
|
|
2007-07-24 11:58:22 +04:00
|
|
|
erase();
|
2009-04-18 17:23:33 +04:00
|
|
|
cur = browse_dir;
|
2007-07-20 15:15:46 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
/* create header and status bar */
|
2007-07-20 15:15:46 +04:00
|
|
|
attron(A_REVERSE);
|
2007-07-24 11:58:22 +04:00
|
|
|
mvhline(0, 0, ' ', wincols);
|
|
|
|
mvhline(winrows-1, 0, ' ', wincols);
|
2007-07-20 15:15:46 +04:00
|
|
|
mvprintw(0,0,"%s %s ~ Use the arrow keys to navigate, press ? for help", PACKAGE_NAME, PACKAGE_VERSION);
|
|
|
|
|
2009-04-18 17:34:47 +04:00
|
|
|
if(cur) {
|
2009-04-26 13:18:45 +04:00
|
|
|
line = malloc(winrows+1);
|
|
|
|
strcpy(line, formatsize(cur->parent->size));
|
2009-04-18 17:34:47 +04:00
|
|
|
mvprintw(winrows-1, 0, " Total disk usage: %s Apparent size: %s Items: %d",
|
2009-04-26 13:18:45 +04:00
|
|
|
line, formatsize(cur->parent->asize), cur->parent->items);
|
|
|
|
free(line);
|
2009-04-18 17:34:47 +04:00
|
|
|
} else
|
|
|
|
mvaddstr(winrows-1, 0, " No items to display.");
|
2007-08-01 17:17:26 +04:00
|
|
|
attroff(A_REVERSE);
|
2009-04-13 19:25:46 +04:00
|
|
|
|
2007-07-24 11:58:22 +04:00
|
|
|
mvhline(1, 0, '-', wincols);
|
2009-04-18 17:34:47 +04:00
|
|
|
if(cur) {
|
|
|
|
mvaddch(1, 3, ' ');
|
2009-04-26 13:18:45 +04:00
|
|
|
tmp = getpath(cur->parent);
|
|
|
|
mvaddstr(1, 4, cropstr(tmp, wincols-8));
|
|
|
|
mvaddch(1, 4+((int)strlen(tmp) > wincols-8 ? wincols-8 : (int)strlen(tmp)), ' ');
|
2009-04-18 17:34:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!cur)
|
2009-04-26 11:49:51 +04:00
|
|
|
return;
|
2007-07-24 11:58:22 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
/* add reference to parent dir */
|
2007-08-12 13:52:24 +04:00
|
|
|
memset(&ref, 0, sizeof(struct dir));
|
2009-04-13 19:25:46 +04:00
|
|
|
if(cur->parent->parent) {
|
2007-08-12 13:52:24 +04:00
|
|
|
ref.name = "..";
|
2009-04-13 19:25:46 +04:00
|
|
|
ref.next = cur;
|
|
|
|
ref.parent = cur->parent;
|
|
|
|
cur = &ref;
|
2007-08-12 13:52:24 +04:00
|
|
|
}
|
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
/* get maximum size and selected item */
|
2009-05-02 15:01:12 +04:00
|
|
|
for(n=cur, selected=-1, i=0; n!=NULL; n=n->next) {
|
2009-04-13 19:25:46 +04:00
|
|
|
if(ishidden(n))
|
|
|
|
continue;
|
2009-04-18 18:02:46 +04:00
|
|
|
if(n->flags & FF_BSEL) {
|
2007-07-24 11:58:22 +04:00
|
|
|
selected = i;
|
2009-04-18 18:02:46 +04:00
|
|
|
sel = n;
|
|
|
|
}
|
2009-04-18 17:23:33 +04:00
|
|
|
if((flags & BF_AS ? n->asize : n->size) > max)
|
|
|
|
max = flags & BF_AS ? n->asize : n->size;
|
2009-04-13 19:25:46 +04:00
|
|
|
i++;
|
2007-07-20 15:15:46 +04:00
|
|
|
}
|
2009-05-02 15:01:12 +04:00
|
|
|
if(selected < 0)
|
2009-04-13 19:25:46 +04:00
|
|
|
cur->flags |= FF_BSEL;
|
2007-07-20 15:15:46 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
/* determine start position */
|
|
|
|
for(n=cur,i=0; n!=NULL; n=n->next) {
|
|
|
|
if(ishidden(n))
|
|
|
|
continue;
|
2007-07-24 11:58:22 +04:00
|
|
|
if(i == (selected / (winrows-3)) * (winrows-3))
|
|
|
|
break;
|
2009-04-13 19:25:46 +04:00
|
|
|
i++;
|
2007-07-24 11:58:22 +04:00
|
|
|
}
|
2009-04-26 13:22:24 +04:00
|
|
|
selected -= i;
|
2007-07-24 11:58:22 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
/* print the list to the screen */
|
|
|
|
for(i=0; n!=NULL && i<winrows-3; n=n->next) {
|
|
|
|
if(ishidden(n))
|
2007-07-20 15:15:46 +04:00
|
|
|
continue;
|
2009-04-13 19:25:46 +04:00
|
|
|
browse_draw_item(n, 2+i++, max, n == &ref);
|
2007-07-20 15:15:46 +04:00
|
|
|
}
|
2007-08-12 13:52:24 +04:00
|
|
|
|
2009-04-18 18:02:46 +04:00
|
|
|
/* draw information window */
|
|
|
|
if(sel && (flags & BF_INFO) && sel != &ref)
|
|
|
|
browse_draw_info(sel);
|
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
/* move cursor to selected row for accessibility */
|
2008-08-02 17:31:21 +04:00
|
|
|
move(selected+2, 0);
|
2009-04-13 19:25:46 +04:00
|
|
|
}
|
|
|
|
|
2008-08-02 17:31:21 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
void browse_key_sel(int change) {
|
|
|
|
struct dir *n, *cur, par;
|
|
|
|
int i, max;
|
|
|
|
|
2009-04-25 17:46:00 +04:00
|
|
|
if((cur = browse_dir) == NULL)
|
|
|
|
return;
|
2009-04-13 19:25:46 +04:00
|
|
|
par.next = cur;
|
2009-05-02 15:01:12 +04:00
|
|
|
par.flags = 0;
|
2009-04-18 17:23:33 +04:00
|
|
|
if(cur->parent->parent)
|
2009-04-13 19:25:46 +04:00
|
|
|
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;
|
2008-09-20 13:35:21 +04:00
|
|
|
}
|
2009-04-13 19:25:46 +04:00
|
|
|
i += change;
|
|
|
|
i = i<0 ? 0 : i>max ? max : i;
|
2008-09-20 13:35:21 +04:00
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
for(n=cur; n!=NULL; n=n->next)
|
|
|
|
if(!ishidden(n) && !i--)
|
|
|
|
n->flags |= FF_BSEL;
|
2007-07-24 11:58:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-13 21:32:40 +04:00
|
|
|
#define toggle(x,y) if(x & y) x -=y; else x |= y
|
|
|
|
|
2009-04-13 19:25:46 +04:00
|
|
|
int browse_key(int ch) {
|
2010-02-27 17:15:25 +03:00
|
|
|
char sort = 0, nonfo = 0, catch = 0;
|
|
|
|
struct dir *r, *sel;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(sel=browse_dir; sel!=NULL; sel=sel->next)
|
|
|
|
if(sel->flags & FF_BSEL)
|
|
|
|
break;
|
2007-07-24 11:58:22 +04:00
|
|
|
|
2010-02-27 17:15:25 +03:00
|
|
|
/* info window overwrites a few keys */
|
|
|
|
if(flags & BF_INFO && sel)
|
|
|
|
switch(ch) {
|
|
|
|
case '1':
|
|
|
|
info_page = 0;
|
|
|
|
break;
|
|
|
|
case '2':
|
|
|
|
if(sel->hlnk)
|
|
|
|
info_page = 1;
|
|
|
|
break;
|
|
|
|
case KEY_RIGHT:
|
|
|
|
case 'l':
|
|
|
|
if(sel->hlnk) {
|
|
|
|
info_page = 1;
|
|
|
|
catch++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case KEY_LEFT:
|
|
|
|
case 'h':
|
|
|
|
if(sel->hlnk) {
|
|
|
|
info_page = 0;
|
|
|
|
catch++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case KEY_UP:
|
|
|
|
case 'k':
|
|
|
|
if(sel->hlnk && info_page == 1) {
|
|
|
|
if(info_start > 0)
|
|
|
|
info_start--;
|
|
|
|
catch++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case KEY_DOWN:
|
|
|
|
case 'j':
|
|
|
|
case ' ':
|
|
|
|
if(sel->hlnk && info_page == 1) {
|
|
|
|
for(i=0,r=sel->hlnk; r!=sel; r=r->hlnk)
|
|
|
|
i++;
|
|
|
|
if(i > info_start+6)
|
|
|
|
info_start++;
|
|
|
|
catch++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!catch)
|
|
|
|
switch(ch) {
|
2009-04-13 19:25:46 +04:00
|
|
|
/* selecting items */
|
|
|
|
case KEY_UP:
|
2009-10-18 14:52:00 +04:00
|
|
|
case 'k':
|
2009-04-13 19:25:46 +04:00
|
|
|
browse_key_sel(-1);
|
2010-02-27 17:15:25 +03:00
|
|
|
info_start = 0;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case KEY_DOWN:
|
2009-10-18 14:52:00 +04:00
|
|
|
case 'j':
|
2009-04-13 19:25:46 +04:00
|
|
|
browse_key_sel(1);
|
2010-02-27 17:15:25 +03:00
|
|
|
info_start = 0;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case KEY_HOME:
|
|
|
|
browse_key_sel(-1*(1<<30));
|
2010-02-27 17:15:25 +03:00
|
|
|
info_start = 0;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case KEY_LL:
|
|
|
|
case KEY_END:
|
|
|
|
browse_key_sel(1<<30);
|
2010-02-27 17:15:25 +03:00
|
|
|
info_start = 0;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case KEY_PPAGE:
|
|
|
|
browse_key_sel(-1*(winrows-3));
|
2010-02-27 17:15:25 +03:00
|
|
|
info_start = 0;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case KEY_NPAGE:
|
|
|
|
browse_key_sel(winrows-3);
|
2010-02-27 17:15:25 +03:00
|
|
|
info_start = 0;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
2007-07-24 11:58:22 +04:00
|
|
|
|
2009-04-26 11:55:23 +04:00
|
|
|
/* sorting items */
|
2009-04-13 19:25:46 +04:00
|
|
|
case 'n':
|
2009-04-18 17:23:33 +04:00
|
|
|
if(flags & BF_NAME)
|
|
|
|
toggle(flags, BF_DESC);
|
2009-04-13 19:25:46 +04:00
|
|
|
else
|
2009-04-18 17:23:33 +04:00
|
|
|
flags = (flags & BF_HIDE) + (flags & BF_NDIRF) + BF_NAME;
|
2009-04-18 17:45:26 +04:00
|
|
|
sort++;
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case 's':
|
2009-04-18 17:23:33 +04:00
|
|
|
if(flags & BF_SIZE)
|
|
|
|
toggle(flags, BF_DESC);
|
2009-04-13 19:25:46 +04:00
|
|
|
else
|
2009-04-18 17:23:33 +04:00
|
|
|
flags = (flags & BF_HIDE) + (flags & BF_NDIRF) + BF_SIZE + BF_DESC;
|
2009-04-18 17:45:26 +04:00
|
|
|
sort++;
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
2009-10-18 14:52:00 +04:00
|
|
|
case 'e':
|
2009-04-18 17:23:33 +04:00
|
|
|
toggle(flags, BF_HIDE);
|
2009-04-13 19:25:46 +04:00
|
|
|
browse_key_sel(0);
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case 't':
|
2009-04-18 17:23:33 +04:00
|
|
|
toggle(flags, BF_NDIRF);
|
2009-04-18 17:45:26 +04:00
|
|
|
sort++;
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case 'a':
|
2009-04-18 17:23:33 +04:00
|
|
|
toggle(flags, BF_AS);
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
|
2009-04-26 11:55:23 +04:00
|
|
|
/* browsing */
|
2009-04-13 19:25:46 +04:00
|
|
|
case 10:
|
|
|
|
case KEY_RIGHT:
|
2009-10-18 14:52:00 +04:00
|
|
|
case 'l':
|
2010-02-27 17:15:25 +03:00
|
|
|
if(sel != NULL && sel->sub != NULL) {
|
|
|
|
browse_dir = sel->sub;
|
2009-04-26 11:55:23 +04:00
|
|
|
sort++;
|
|
|
|
}
|
2010-02-27 17:15:25 +03:00
|
|
|
if(sel == NULL && browse_dir != NULL && browse_dir->parent->parent) {
|
2009-04-18 17:23:33 +04:00
|
|
|
browse_dir = browse_dir->parent->parent->sub;
|
2009-04-26 11:55:23 +04:00
|
|
|
sort++;
|
|
|
|
}
|
2009-05-02 15:01:12 +04:00
|
|
|
browse_key_sel(0);
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case KEY_LEFT:
|
2009-10-18 14:52:00 +04:00
|
|
|
case 'h':
|
|
|
|
case '<':
|
2009-04-26 11:55:23 +04:00
|
|
|
if(browse_dir != NULL && browse_dir->parent->parent != NULL) {
|
2009-04-18 17:23:33 +04:00
|
|
|
browse_dir = browse_dir->parent->parent->sub;
|
2009-04-26 11:55:23 +04:00
|
|
|
sort++;
|
|
|
|
}
|
2009-05-02 15:01:12 +04:00
|
|
|
browse_key_sel(0);
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
|
2009-04-26 13:08:40 +04:00
|
|
|
/* and other stuff */
|
2009-04-13 19:25:46 +04:00
|
|
|
case 'r':
|
2009-04-25 17:46:00 +04:00
|
|
|
if(browse_dir != NULL)
|
|
|
|
calc_init(getpath(browse_dir->parent), browse_dir->parent);
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case 'q':
|
2009-04-19 12:06:33 +04:00
|
|
|
if(flags & BF_INFO)
|
|
|
|
nonfo++;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
break;
|
2009-04-13 19:25:46 +04:00
|
|
|
case 'g':
|
2009-04-18 18:02:46 +04:00
|
|
|
if(++graph > 3)
|
|
|
|
graph = 0;
|
|
|
|
nonfo++;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
toggle(flags, BF_INFO);
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case '?':
|
2009-04-19 12:03:42 +04:00
|
|
|
help_init();
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
|
|
|
case 'd':
|
2010-02-27 17:15:25 +03:00
|
|
|
if(sel == NULL)
|
2009-04-19 13:35:24 +04:00
|
|
|
break;
|
2009-04-18 18:02:46 +04:00
|
|
|
nonfo++;
|
2009-04-19 15:16:31 +04:00
|
|
|
/* quirky method of getting the next selected dir without actually selecting it */
|
2010-02-27 17:15:25 +03:00
|
|
|
browse_key_sel(sel->next ? 1 : -1);
|
2009-04-19 15:16:31 +04:00
|
|
|
for(r=browse_dir; r!=NULL; r=r->next)
|
|
|
|
if(r->flags & FF_BSEL)
|
|
|
|
break;
|
2010-02-27 17:15:25 +03:00
|
|
|
browse_key_sel(sel->next ? -1 : 1);
|
|
|
|
delete_init(sel, r);
|
2009-04-13 19:25:46 +04:00
|
|
|
break;
|
2010-02-27 17:15:25 +03:00
|
|
|
}
|
2009-04-18 17:45:26 +04:00
|
|
|
|
2009-04-25 17:46:00 +04:00
|
|
|
if(sort && browse_dir != NULL)
|
2009-04-18 17:45:26 +04:00
|
|
|
browse_dir = browse_sort(browse_dir);
|
2010-02-27 17:15:25 +03:00
|
|
|
if(nonfo) {
|
2009-04-18 18:02:46 +04:00
|
|
|
flags &= ~BF_INFO;
|
2010-02-27 17:15:25 +03:00
|
|
|
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;
|
|
|
|
}
|
2009-04-13 19:25:46 +04:00
|
|
|
return 0;
|
2007-07-20 15:15:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-18 17:23:33 +04:00
|
|
|
void browse_init(struct dir *cur) {
|
|
|
|
pstate = ST_BROWSE;
|
2009-04-18 17:34:47 +04:00
|
|
|
if(cur != NULL && cur->parent == NULL)
|
|
|
|
browse_dir = cur->sub;
|
|
|
|
else
|
|
|
|
browse_dir = cur;
|
2009-04-19 13:35:24 +04:00
|
|
|
if(browse_dir != NULL && browse_dir->parent->sub != browse_dir)
|
|
|
|
browse_dir = cur->parent->sub;
|
2009-04-25 14:11:53 +04:00
|
|
|
if(browse_dir != NULL)
|
|
|
|
browse_dir = browse_sort(browse_dir);
|
2009-05-02 15:01:12 +04:00
|
|
|
browse_key_sel(0);
|
2009-04-18 17:23:33 +04:00
|
|
|
}
|
|
|
|
|