1 /*
2 ** 1998-09-12 -	This is GETSIZE, a recursive size computation command. It will assign
3 **		the size of all contained files to directories.
4 ** 1998-12-19 -	Rewritten to use the new fut_dir_size() function, rather than its own
5 **		routine. Simpler.
6 ** 1999-03-06 -	Adjusted for the new selection handling.
7 ** 1999-04-09 -	Added the cmd_clearsize() function, implementing the ClearSize command.
8 */
9 
10 #include "gentoo.h"
11 
12 #include <fcntl.h>
13 
14 #include "fileutil.h"
15 #include "dirpane.h"
16 #include "errors.h"
17 #include "progress.h"
18 #include "cmdseq_config.h"
19 
20 #include "cmd_getsize.h"
21 
22 #define	CMD_ID	"getsize"
23 #define	CMD_ID2	"clearsize"
24 
25 /* ----------------------------------------------------------------------------------------- */
26 
27 typedef struct {
28 	gboolean	modified;
29 	gboolean	unselect;		/* Unselect rows when done computing size? */
30 } OptGetSize;
31 
32 static OptGetSize	getsize_options;
33 static CmdCfg		*getsize_cmc = NULL;
34 
35 /* ----------------------------------------------------------------------------------------- */
36 
37 /* 1998-09-12 -	Recursive directory sizer.
38 ** 1999-04-09 -	Now also updates the blocks field of the directory's stat buffer.
39 */
cmd_getsize(MainInfo * min,DirPane * src,DirPane * dst,const CmdArg * ca)40 gint cmd_getsize(MainInfo *min, DirPane *src, DirPane *dst, const CmdArg *ca)
41 {
42 	GtkTreeModel	*m = dp_get_tree_model(src);
43 	GSList		*slist, *iter;
44 	guint		num = 0;
45 	FUCount		fuc;
46 	gboolean	ok = TRUE;
47 	GError		*err = NULL;
48 
49 	if((slist = dp_get_selection(src)) == NULL)
50 		return 1;
51 	pgs_progress_begin(min, _("Getting sizes..."), PFLG_BUSY_MODE);
52 	for(iter = slist; ok && (iter != NULL); iter = g_slist_next(iter))
53 	{
54 		if(dp_row_get_file_type(m, iter->data, TRUE) == G_FILE_TYPE_DIRECTORY)
55 		{
56 			GFile	*here = dp_get_file_from_row(src, iter->data);
57 
58 			if((ok = fut_size_gfile(min, here, NULL, &fuc, &err)))
59 			{
60 				dp_row_set_size(m, iter->data, fuc.num_bytes);
61 				dp_row_set_flag(m, iter->data, DPRF_HAS_SIZE);
62 				num++;
63 				if(getsize_options.unselect)
64 					dp_unselect(src, iter->data);
65 			}
66 			else
67 				err_set_gerror(min, &err, CMD_ID, here);
68 		}
69 	}
70 	pgs_progress_end(min);
71 	dp_free_selection(slist);
72 
73 	if(num)
74 	{
75 		dp_update_stats(src);
76 		dp_show_stats(src);
77 	}
78 	return ok;
79 }
80 
81 /* ----------------------------------------------------------------------------------------- */
82 
83 /* 1999-04-09 -	Clear the recursive sizes from all selected directories. Ignores files, but
84 **		unselects them.
85 */
cmd_clearsize(MainInfo * min,DirPane * src,DirPane * dst,const CmdArg * ca)86 gint cmd_clearsize(MainInfo *min, DirPane *src, DirPane *dst, const CmdArg *ca)
87 {
88 	GtkTreeModel	*m = dp_get_tree_model(src);
89 	GSList		*slist, *iter;
90 	guint		num = 0;
91 	GError		*err = NULL;
92 	gboolean	ok = TRUE;
93 
94 	if((slist = dp_get_selection(src)) == NULL)
95 		return 1;
96 
97 	for(iter = slist; ok && (iter != NULL); iter = g_slist_next(iter))
98 	{
99 		if(dp_row_get_file_type(m, iter->data, TRUE) == G_FILE_TYPE_DIRECTORY && dp_row_get_flags(m, iter->data, DPRF_HAS_SIZE))
100 		{
101 			/* Now, we need to re-scan the file's info, and replace it in the model. Interesting, but
102 			** clearly a nitty job that needs to be done inside the dirpane module, not inline here.
103 			*/
104 			ok = dp_rescan_row(src, iter->data, &err);
105 			if(!ok)
106 				err_set_gerror(min, &err, CMD_ID2, dp_get_file_from_row(src, iter->data));
107 			num++;
108 		}
109 		if(getsize_options.unselect)
110 			dp_unselect(src, iter->data);
111 	}
112 	dp_free_selection(slist);
113 
114 	if(num)
115 	{
116 		dp_update_stats(src);
117 		dp_show_stats(src);
118 	}
119 	return ok;
120 }
121 
122 /* ----------------------------------------------------------------------------------------- */
123 
124 /* 1999-04-25 -	Configure the GetSize command's (few) options. */
cfg_getsize(MainInfo * min)125 void cfg_getsize(MainInfo *min)
126 {
127 	if(getsize_cmc == NULL)
128 	{
129 		getsize_options.modified = FALSE;
130 		getsize_options.unselect = TRUE;
131 
132 		getsize_cmc = cmc_config_new("GetSize", &getsize_options);
133 		cmc_field_add_boolean(getsize_cmc, "modified", NULL, offsetof(OptGetSize, modified));
134 		cmc_field_add_boolean(getsize_cmc, "unselect", _("Unselect Rows When Done?"), offsetof(OptGetSize, unselect));
135 		cmc_config_register(getsize_cmc);
136 	}
137 }
138