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
|
||||
|
||||
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 "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);
|
||||
}
|
||||
|
||||
|
|
|
|||
284
src/delete.c
284
src/delete.c
|
|
@ -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
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 "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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue