diff --git a/src/Makefile.am b/src/Makefile.am index 1bf484e3cde1e5e36c5e668f198ca9a1a12317a0..e9d0b52f13a3242e0754d5461fa9d925cad95a7f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = ncdu -ncdu_SOURCES = browser.c calc.c exclude.c help.c main.c util.c +ncdu_SOURCES = browser.c calc.c delete.c exclude.c help.c main.c util.c -noinst_HEADERS = browser.h calc.h exclude.h help.h ncdu.h util.h +noinst_HEADERS = browser.h calc.h delete.h exclude.h help.h ncdu.h util.h diff --git a/src/browser.c b/src/browser.c index ff99847c678df3ec0a78a74921d6450852ed6ab4..089ffcfd2a1efabd9f2004946ea2632295c49221 100644 --- a/src/browser.c +++ b/src/browser.c @@ -27,6 +27,7 @@ #include "browser.h" #include "util.h" #include "calc.h" +#include "delete.h" #include "help.h" #include <string.h> @@ -443,17 +444,15 @@ int browse_key(int ch) { help_init(); nonfo++; break; - /* case 'd': - drawBrowser(0); - n = selected(); - if(n != bcur->parent) - bcur = showDelete(n); - if(bcur && bcur->parent) - bcur = bcur->parent->sub; + for(n=browse_dir; n!=NULL; n=n->next) + if(n->flags & FF_BSEL) + break; + if(n == NULL) + break; + delete_init(n); nonfo++; break; - */ } if(sort) @@ -470,6 +469,8 @@ void browse_init(struct dir *cur) { browse_dir = cur->sub; else browse_dir = cur; + if(browse_dir != NULL && browse_dir->parent->sub != browse_dir) + browse_dir = cur->parent->sub; browse_dir = browse_sort(browse_dir); } diff --git a/src/delete.c b/src/delete.c index 71093737e8a6ca9a2758a0a5935d2cc177e724da..e19b7e202bb3d9e92bbf054822b9940499ea3136 100644 --- a/src/delete.c +++ b/src/delete.c @@ -1,5 +1,5 @@ -/* ncdu - NCurses Disk Usage - +/* ncdu - NCurses Disk Usage + Copyright (c) 2007-2009 Yoran Heling Permission is hereby granted, free of charge, to any person obtaining @@ -9,10 +9,10 @@ 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. @@ -23,195 +23,227 @@ */ + #include "ncdu.h" +#include "util.h" +#include "browser.h" + +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/time.h> + + +#define DS_CONFIRM 0 +#define DS_PROGRESS 1 +#define DS_FAILED 2 + + +int delete_delay = 100; suseconds_t lastupdate; +struct dir *root; +char noconfirm = 0, + ignoreerr = 0, + state, seloption, curfile[PATH_MAX]; +int lasterrno; -void drawConfirm(struct dir *del, int sel) { +void delete_draw_confirm() { nccreate(6, 60, "Confirm delete"); ncprint(1, 2, "Are you sure you want to delete \"%s\"%c", - cropdir(del->name, 21), del->flags & FF_DIR ? ' ' : '?'); - if(del->flags & FF_DIR) + cropstr(root->name, 21), root->flags & FF_DIR ? ' ' : '?'); + if(root->flags & FF_DIR) ncprint(2, 18, "and all of its contents?"); - if(sel == 0) + if(seloption == 0) attron(A_REVERSE); ncaddstr(4, 15, "yes"); attroff(A_REVERSE); - if(sel == 1) + if(seloption == 1) attron(A_REVERSE); ncaddstr(4, 24, "no"); attroff(A_REVERSE); - if(sel == 2) + if(seloption == 2) attron(A_REVERSE); ncaddstr(4, 31, "don't ask me again"); attroff(A_REVERSE); - ncmove(4, sel == 0 ? 15 : sel == 1 ? 24 : 31); - - refresh(); + ncmove(4, seloption == 0 ? 15 : seloption == 1 ? 24 : 31); } -/* show progress */ -static void drawProgress(char *file) { +void delete_draw_progress() { nccreate(6, 60, "Deleting..."); - ncaddstr(1, 2, cropdir(file, 47)); + ncaddstr(1, 2, cropstr(curfile, 47)); ncaddstr(4, 41, "Press q to abort"); - - refresh(); } -/* show error dialog */ -static void drawError(int sel, char *file) { +void delete_draw_error() { nccreate(6, 60, "Error!"); - ncprint(1, 2, "Can't delete %s:", cropdir(file, 42)); - ncaddstr(2, 4, strerror(errno)); + ncprint(1, 2, "Can't delete %s:", cropstr(curfile, 42)); + ncaddstr(2, 4, strerror(lasterrno)); - if(sel == 0) + if(seloption == 0) attron(A_REVERSE); ncaddstr(4, 14, "abort"); attroff(A_REVERSE); - if(sel == 1) + if(seloption == 1) attron(A_REVERSE); ncaddstr(4, 23, "ignore"); attroff(A_REVERSE); - if(sel == 2) + if(seloption == 2) attron(A_REVERSE); ncaddstr(4, 33, "ignore all"); attroff(A_REVERSE); +} + - refresh(); +int delete_draw() { + struct timeval tv; + + switch(state) { + case DS_CONFIRM: + browse_draw(); + delete_draw_confirm(); + return 0; + case DS_PROGRESS: + gettimeofday(&tv, (void *)NULL); + tv.tv_usec = (1000*(tv.tv_sec % 1000) + (tv.tv_usec / 1000)) / delete_delay; + if(lastupdate != tv.tv_usec) { + browse_draw(); + delete_draw_progress(); + lastupdate = tv.tv_usec; + return 0; + } + return 1; + case DS_FAILED: + browse_draw(); + delete_draw_error(); + return 0; + } + return 1; } -struct dir *deleteDir(struct dir *dr) { +int delete_key(int ch) { + /* confirm */ + if(state == DS_CONFIRM) + switch(ch) { + case KEY_LEFT: + if(--seloption < 0) + seloption = 0; + break; + case KEY_RIGHT: + if(++seloption > 2) + seloption = 2; + break; + case '\n': + if(seloption == 1) + return 1; + if(seloption == 2) + noconfirm++; + state = DS_PROGRESS; + break; + case 'q': + return 1; + } + /* processing deletion */ + else if(state == DS_PROGRESS) + switch(ch) { + case 'q': + return 1; + } + /* error */ + else if(state == DS_FAILED) + switch(ch) { + case KEY_LEFT: + if(--seloption < 0) + seloption = 0; + break; + case KEY_RIGHT: + if(++seloption > 2) + seloption = 2; + break; + case 10: + if(seloption == 0) + return 1; + if(seloption == 2) + ignoreerr++; + state = DS_PROGRESS; + break; + case 'q': + return 1; + } + + return 0; +} + + +struct dir *delete_dir(struct dir *dr) { struct dir *nxt, *cur; - int ch, sel = 0; + int r; char file[PATH_MAX]; - struct timeval tv; getpath(dr, file); if(file[strlen(file)-1] != '/') strcat(file, "/"); strcat(file, dr->name); - /* check for input or screen resizes */ - nodelay(stdscr, 1); - while((ch = getch()) != ERR) { - if(ch == 'q') - return(NULL); - if(ch == KEY_RESIZE) { - ncresize(); - drawBrowser(0); - drawProgress(file); - } - } - nodelay(stdscr, 0); - - /* don't update the screen with shorter intervals than sdelay */ - gettimeofday(&tv, (void *)NULL); - tv.tv_usec = (1000*(tv.tv_sec % 1000) + (tv.tv_usec / 1000)) / sdelay; - if(lastupdate != tv.tv_usec) { - drawProgress(file); - lastupdate = tv.tv_usec; - } + /* check for input or screen resizes */ + strcpy(curfile, file); + if(input_handle(1)) + return root; - /* do the actual deleting */ + /* do the actual deleting */ if(dr->flags & FF_DIR) { if(dr->sub != NULL) { nxt = dr->sub; while(nxt != NULL) { cur = nxt; nxt = cur->next; - if(deleteDir(cur) == NULL) - return(NULL); + if(delete_dir(cur) == root) + return root; } } - ch = rmdir(file); + r = rmdir(file); } else - ch = unlink(file); - - /* error occured, ask user what to do */ - if(ch == -1 && !(sflags & SF_IGNE)) { - drawError(sel, file); - while((ch = getch())) { - switch(ch) { - case KEY_LEFT: - if(--sel < 0) - sel = 0; - break; - case KEY_RIGHT: - if(++sel > 2) - sel = 2; - break; - case 10: - if(sel == 0) - return(NULL); - if(sel == 2) - sflags |= SF_IGNE; - goto ignore; - case 'q': - return(NULL); - case KEY_RESIZE: - ncresize(); - drawBrowser(0); - break; - } - drawError(sel, file); - } - }; - ignore: + r = unlink(file); + + /* error occured, ask user what to do */ + if(r == -1 && !ignoreerr) { + state = DS_FAILED; + lasterrno = errno; + while(state == DS_FAILED) + if(input_handle(0)) + return root; + } - return(freedir(dr)); + return freedir(dr); } -struct dir *showDelete(struct dir *dr) { - int ch, sel = 1; - struct dir *ret; - - /* confirm */ - if(sflags & SF_NOCFM) - goto doit; - - drawConfirm(dr, sel); - while((ch = getch())) { - switch(ch) { - case KEY_LEFT: - if(--sel < 0) - sel = 0; - break; - case KEY_RIGHT: - if(++sel > 2) - sel = 2; - break; - case 10: - if(sel == 1) - return(dr); - if(sel == 2) - sflags |= SF_NOCFM; - goto doit; - case 'q': - return(dr); - case KEY_RESIZE: - ncresize(); - drawBrowser(0); - break; - } - drawConfirm(dr, sel); - } +void delete_process() { + /* confirm */ + seloption = 1; + while(state == DS_CONFIRM && !noconfirm) + if(input_handle(0)) + return browse_init(root); - doit: - lastupdate = 999; /* just some random high value as initialisation */ + /* delete */ + lastupdate = 999; + seloption = 0; + return browse_init(delete_dir(root)); +} - ret = deleteDir(dr); - return(ret == NULL ? dr : ret); +void delete_init(struct dir *dr) { + state = DS_CONFIRM; + root = dr; + pstate = ST_DEL; } diff --git a/src/delete.h b/src/delete.h new file mode 100644 index 0000000000000000000000000000000000000000..a994854d647f4672cbd3b72e8d4f8630c4b909e1 --- /dev/null +++ b/src/delete.h @@ -0,0 +1,39 @@ +/* ncdu - NCurses Disk Usage + + Copyright (c) 2007-2009 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. + +*/ + +#ifndef _delete_h +#define _delete_h + +#include "ncdu.h" + +extern int delete_delay; + +void delete_process(void); +int delete_key(int); +int delete_draw(void); +void delete_init(struct dir *); + + +#endif diff --git a/src/main.c b/src/main.c index 888aaade35a568c8470653623b280b43437b6c73..a3ef9492566bc5d61e8ce482e9fa0f161eeab310 100644 --- a/src/main.c +++ b/src/main.c @@ -27,6 +27,7 @@ #include "exclude.h" #include "util.h" #include "calc.h" +#include "delete.h" #include "browser.h" #include <stdlib.h> @@ -46,6 +47,7 @@ void screen_draw() { case ST_CALC: n = calc_draw(); break; case ST_BROWSE: n = browse_draw(); break; case ST_HELP: n = help_draw(); break; + case ST_DEL: n = delete_draw(); break; } if(!n) refresh(); @@ -68,6 +70,7 @@ int input_handle(int wait) { case ST_CALC: return calc_key(ch); case ST_BROWSE: return browse_key(ch); case ST_HELP: return help_key(ch); + case ST_DEL: return delete_key(ch); } screen_draw(); } @@ -106,7 +109,7 @@ void argv_parse(int argc, char **argv, char *dir) { for(j=1; j<len; j++) switch(argv[i][j]) { case 'x': calc_smfs = 1; break; - case 'q': calc_delay = 2000; break; + case 'q': calc_delay = delete_delay = 2000; break; case '?': case 'h': printf("ncdu [-hqvx] [--exclude PATTERN] [-X FILE] directory\n\n"); @@ -154,6 +157,8 @@ int main(int argc, char **argv) { while(pstate != ST_QUIT) { if(pstate == ST_CALC) calc_process(); + if(pstate == ST_DEL) + delete_process(); else if(input_handle(0)) break; }