mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-13 01:08:41 -09:00
(partly) rewrote delete.c for the new framework and re-added the deletion feature
This commit is contained in:
parent
daba2128fc
commit
ba4d06e09e
5 changed files with 218 additions and 141 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
bin_PROGRAMS = ncdu
|
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
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "browser.h"
|
#include "browser.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "calc.h"
|
#include "calc.h"
|
||||||
|
#include "delete.h"
|
||||||
#include "help.h"
|
#include "help.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -443,17 +444,15 @@ int browse_key(int ch) {
|
||||||
help_init();
|
help_init();
|
||||||
nonfo++;
|
nonfo++;
|
||||||
break;
|
break;
|
||||||
/*
|
|
||||||
case 'd':
|
case 'd':
|
||||||
drawBrowser(0);
|
for(n=browse_dir; n!=NULL; n=n->next)
|
||||||
n = selected();
|
if(n->flags & FF_BSEL)
|
||||||
if(n != bcur->parent)
|
break;
|
||||||
bcur = showDelete(n);
|
if(n == NULL)
|
||||||
if(bcur && bcur->parent)
|
break;
|
||||||
bcur = bcur->parent->sub;
|
delete_init(n);
|
||||||
nonfo++;
|
nonfo++;
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sort)
|
if(sort)
|
||||||
|
|
@ -470,6 +469,8 @@ void browse_init(struct dir *cur) {
|
||||||
browse_dir = cur->sub;
|
browse_dir = cur->sub;
|
||||||
else
|
else
|
||||||
browse_dir = cur;
|
browse_dir = cur;
|
||||||
|
if(browse_dir != NULL && browse_dir->parent->sub != browse_dir)
|
||||||
|
browse_dir = cur->parent->sub;
|
||||||
browse_dir = browse_sort(browse_dir);
|
browse_dir = browse_sort(browse_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
262
src/delete.c
262
src/delete.c
|
|
@ -23,104 +23,181 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "ncdu.h"
|
#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;
|
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");
|
nccreate(6, 60, "Confirm delete");
|
||||||
|
|
||||||
ncprint(1, 2, "Are you sure you want to delete \"%s\"%c",
|
ncprint(1, 2, "Are you sure you want to delete \"%s\"%c",
|
||||||
cropdir(del->name, 21), del->flags & FF_DIR ? ' ' : '?');
|
cropstr(root->name, 21), root->flags & FF_DIR ? ' ' : '?');
|
||||||
if(del->flags & FF_DIR)
|
if(root->flags & FF_DIR)
|
||||||
ncprint(2, 18, "and all of its contents?");
|
ncprint(2, 18, "and all of its contents?");
|
||||||
|
|
||||||
if(sel == 0)
|
if(seloption == 0)
|
||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
ncaddstr(4, 15, "yes");
|
ncaddstr(4, 15, "yes");
|
||||||
attroff(A_REVERSE);
|
attroff(A_REVERSE);
|
||||||
if(sel == 1)
|
if(seloption == 1)
|
||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
ncaddstr(4, 24, "no");
|
ncaddstr(4, 24, "no");
|
||||||
attroff(A_REVERSE);
|
attroff(A_REVERSE);
|
||||||
if(sel == 2)
|
if(seloption == 2)
|
||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
ncaddstr(4, 31, "don't ask me again");
|
ncaddstr(4, 31, "don't ask me again");
|
||||||
attroff(A_REVERSE);
|
attroff(A_REVERSE);
|
||||||
|
|
||||||
ncmove(4, sel == 0 ? 15 : sel == 1 ? 24 : 31);
|
ncmove(4, seloption == 0 ? 15 : seloption == 1 ? 24 : 31);
|
||||||
|
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* show progress */
|
void delete_draw_progress() {
|
||||||
static void drawProgress(char *file) {
|
|
||||||
nccreate(6, 60, "Deleting...");
|
nccreate(6, 60, "Deleting...");
|
||||||
|
|
||||||
ncaddstr(1, 2, cropdir(file, 47));
|
ncaddstr(1, 2, cropstr(curfile, 47));
|
||||||
ncaddstr(4, 41, "Press q to abort");
|
ncaddstr(4, 41, "Press q to abort");
|
||||||
|
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* show error dialog */
|
void delete_draw_error() {
|
||||||
static void drawError(int sel, char *file) {
|
|
||||||
nccreate(6, 60, "Error!");
|
nccreate(6, 60, "Error!");
|
||||||
|
|
||||||
ncprint(1, 2, "Can't delete %s:", cropdir(file, 42));
|
ncprint(1, 2, "Can't delete %s:", cropstr(curfile, 42));
|
||||||
ncaddstr(2, 4, strerror(errno));
|
ncaddstr(2, 4, strerror(lasterrno));
|
||||||
|
|
||||||
if(sel == 0)
|
if(seloption == 0)
|
||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
ncaddstr(4, 14, "abort");
|
ncaddstr(4, 14, "abort");
|
||||||
attroff(A_REVERSE);
|
attroff(A_REVERSE);
|
||||||
if(sel == 1)
|
if(seloption == 1)
|
||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
ncaddstr(4, 23, "ignore");
|
ncaddstr(4, 23, "ignore");
|
||||||
attroff(A_REVERSE);
|
attroff(A_REVERSE);
|
||||||
if(sel == 2)
|
if(seloption == 2)
|
||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
ncaddstr(4, 33, "ignore all");
|
ncaddstr(4, 33, "ignore all");
|
||||||
attroff(A_REVERSE);
|
attroff(A_REVERSE);
|
||||||
|
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dir *deleteDir(struct dir *dr) {
|
int delete_draw() {
|
||||||
struct dir *nxt, *cur;
|
|
||||||
int ch, sel = 0;
|
|
||||||
char file[PATH_MAX];
|
|
||||||
struct timeval tv;
|
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);
|
getpath(dr, file);
|
||||||
if(file[strlen(file)-1] != '/')
|
if(file[strlen(file)-1] != '/')
|
||||||
strcat(file, "/");
|
strcat(file, "/");
|
||||||
strcat(file, dr->name);
|
strcat(file, dr->name);
|
||||||
|
|
||||||
/* check for input or screen resizes */
|
/* check for input or screen resizes */
|
||||||
nodelay(stdscr, 1);
|
strcpy(curfile, file);
|
||||||
while((ch = getch()) != ERR) {
|
if(input_handle(1))
|
||||||
if(ch == 'q')
|
return root;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do the actual deleting */
|
/* do the actual deleting */
|
||||||
if(dr->flags & FF_DIR) {
|
if(dr->flags & FF_DIR) {
|
||||||
|
|
@ -129,89 +206,44 @@ struct dir *deleteDir(struct dir *dr) {
|
||||||
while(nxt != NULL) {
|
while(nxt != NULL) {
|
||||||
cur = nxt;
|
cur = nxt;
|
||||||
nxt = cur->next;
|
nxt = cur->next;
|
||||||
if(deleteDir(cur) == NULL)
|
if(delete_dir(cur) == root)
|
||||||
return(NULL);
|
return root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ch = rmdir(file);
|
r = rmdir(file);
|
||||||
} else
|
} else
|
||||||
ch = unlink(file);
|
r = unlink(file);
|
||||||
|
|
||||||
/* error occured, ask user what to do */
|
/* error occured, ask user what to do */
|
||||||
if(ch == -1 && !(sflags & SF_IGNE)) {
|
if(r == -1 && !ignoreerr) {
|
||||||
drawError(sel, file);
|
state = DS_FAILED;
|
||||||
while((ch = getch())) {
|
lasterrno = errno;
|
||||||
switch(ch) {
|
while(state == DS_FAILED)
|
||||||
case KEY_LEFT:
|
if(input_handle(0))
|
||||||
if(--sel < 0)
|
return root;
|
||||||
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));
|
return freedir(dr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dir *showDelete(struct dir *dr) {
|
void delete_process() {
|
||||||
int ch, sel = 1;
|
|
||||||
struct dir *ret;
|
|
||||||
|
|
||||||
/* confirm */
|
/* confirm */
|
||||||
if(sflags & SF_NOCFM)
|
seloption = 1;
|
||||||
goto doit;
|
while(state == DS_CONFIRM && !noconfirm)
|
||||||
|
if(input_handle(0))
|
||||||
|
return browse_init(root);
|
||||||
|
|
||||||
drawConfirm(dr, sel);
|
/* delete */
|
||||||
while((ch = getch())) {
|
lastupdate = 999;
|
||||||
switch(ch) {
|
seloption = 0;
|
||||||
case KEY_LEFT:
|
return browse_init(delete_dir(root));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doit:
|
|
||||||
lastupdate = 999; /* just some random high value as initialisation */
|
|
||||||
|
|
||||||
ret = deleteDir(dr);
|
void delete_init(struct dir *dr) {
|
||||||
|
state = DS_CONFIRM;
|
||||||
return(ret == NULL ? dr : ret);
|
root = dr;
|
||||||
|
pstate = ST_DEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
39
src/delete.h
Normal file
39
src/delete.h
Normal 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
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "exclude.h"
|
#include "exclude.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "calc.h"
|
#include "calc.h"
|
||||||
|
#include "delete.h"
|
||||||
#include "browser.h"
|
#include "browser.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -46,6 +47,7 @@ void screen_draw() {
|
||||||
case ST_CALC: n = calc_draw(); break;
|
case ST_CALC: n = calc_draw(); break;
|
||||||
case ST_BROWSE: n = browse_draw(); break;
|
case ST_BROWSE: n = browse_draw(); break;
|
||||||
case ST_HELP: n = help_draw(); break;
|
case ST_HELP: n = help_draw(); break;
|
||||||
|
case ST_DEL: n = delete_draw(); break;
|
||||||
}
|
}
|
||||||
if(!n)
|
if(!n)
|
||||||
refresh();
|
refresh();
|
||||||
|
|
@ -68,6 +70,7 @@ int input_handle(int wait) {
|
||||||
case ST_CALC: return calc_key(ch);
|
case ST_CALC: return calc_key(ch);
|
||||||
case ST_BROWSE: return browse_key(ch);
|
case ST_BROWSE: return browse_key(ch);
|
||||||
case ST_HELP: return help_key(ch);
|
case ST_HELP: return help_key(ch);
|
||||||
|
case ST_DEL: return delete_key(ch);
|
||||||
}
|
}
|
||||||
screen_draw();
|
screen_draw();
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +109,7 @@ void argv_parse(int argc, char **argv, char *dir) {
|
||||||
for(j=1; j<len; j++)
|
for(j=1; j<len; j++)
|
||||||
switch(argv[i][j]) {
|
switch(argv[i][j]) {
|
||||||
case 'x': calc_smfs = 1; break;
|
case 'x': calc_smfs = 1; break;
|
||||||
case 'q': calc_delay = 2000; break;
|
case 'q': calc_delay = delete_delay = 2000; break;
|
||||||
case '?':
|
case '?':
|
||||||
case 'h':
|
case 'h':
|
||||||
printf("ncdu [-hqvx] [--exclude PATTERN] [-X FILE] directory\n\n");
|
printf("ncdu [-hqvx] [--exclude PATTERN] [-X FILE] directory\n\n");
|
||||||
|
|
@ -154,6 +157,8 @@ int main(int argc, char **argv) {
|
||||||
while(pstate != ST_QUIT) {
|
while(pstate != ST_QUIT) {
|
||||||
if(pstate == ST_CALC)
|
if(pstate == ST_CALC)
|
||||||
calc_process();
|
calc_process();
|
||||||
|
if(pstate == ST_DEL)
|
||||||
|
delete_process();
|
||||||
else if(input_handle(0))
|
else if(input_handle(0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue