(partly) rewrote delete.c for the new framework and re-added the deletion feature

This commit is contained in:
Yorhel 2009-04-19 11:35:24 +02:00
parent daba2128fc
commit ba4d06e09e
5 changed files with 218 additions and 141 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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();
}
struct dir *deleteDir(struct dir *dr) {
struct dir *nxt, *cur;
int ch, sel = 0;
char file[PATH_MAX];
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;
}
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 r;
char file[PATH_MAX];
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);
/* check for input or screen resizes */
strcpy(curfile, file);
if(input_handle(1))
return root;
/* 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;
}
/* 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);
r = 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:
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);
/* 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;
}
doit:
lastupdate = 999; /* just some random high value as initialisation */
ret = deleteDir(dr);
return(ret == NULL ? dr : ret);
return freedir(dr);
}
void delete_process() {
/* confirm */
seloption = 1;
while(state == DS_CONFIRM && !noconfirm)
if(input_handle(0))
return browse_init(root);
/* delete */
lastupdate = 999;
seloption = 0;
return browse_init(delete_dir(root));
}
void delete_init(struct dir *dr) {
state = DS_CONFIRM;
root = dr;
pstate = ST_DEL;
}

39
src/delete.h Normal file
View file

@ -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

View file

@ -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;
}