1 /* vifm
2  * Copyright (C) 2001 Ken Steen.
3  * Copyright (C) 2011 xaizek.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include "change_dialog.h"
21 
22 #include <curses.h>
23 
24 #include <assert.h>
25 #include <string.h>
26 
27 #include "../../cfg/config.h"
28 #include "../../compat/curses.h"
29 #include "../../engine/keys.h"
30 #include "../../engine/mode.h"
31 #include "../../ui/colors.h"
32 #include "../../ui/ui.h"
33 #include "../../utils/macros.h"
34 #include "../../fops_misc.h"
35 #include "../../fops_rename.h"
36 #include "../../status.h"
37 #include "../modes.h"
38 #include "../wk.h"
39 #include "attr_dialog.h"
40 
41 static void leave_change_mode(int clear_selection);
42 static void cmd_ctrl_c(key_info_t key_info, keys_info_t *keys_info);
43 static void cmd_return(key_info_t key_info, keys_info_t *keys_info);
44 static void cmd_G(key_info_t key_info, keys_info_t *keys_info);
45 static void cmd_gg(key_info_t key_info, keys_info_t *keys_info);
46 static void cmd_j(key_info_t key_info, keys_info_t *keys_info);
47 static void cmd_k(key_info_t key_info, keys_info_t *keys_info);
48 static void cmd_n(key_info_t key_info, keys_info_t *keys_info);
49 static void cmd_o(key_info_t key_info, keys_info_t *keys_info);
50 static void cmd_g(key_info_t key_info, keys_info_t *keys_info);
51 static void cmd_p(key_info_t key_info, keys_info_t *keys_info);
52 static void goto_line(int line);
53 static void print_at_pos(void);
54 static void clear_at_pos(void);
55 
56 static view_t *view;
57 static int top, bottom, step, curr, col;
58 
59 static keys_add_info_t builtin_cmds[] = {
60 	{WK_C_c,    {{&cmd_ctrl_c}, .descr = "close the dialog"}},
61 	{WK_CR,     {{&cmd_return}, .descr = "perform selected action"}},
62 	{WK_C_n,    {{&cmd_j},      .descr = "go to item below"}},
63 	{WK_C_p,    {{&cmd_k},      .descr = "go to item above"}},
64 	{WK_ESC,    {{&cmd_ctrl_c}, .descr = "close the dialog"}},
65 	{WK_G,      {{&cmd_G},      .descr = "go to the last item"}},
66 	{WK_Z WK_Q, {{&cmd_ctrl_c}, .descr = "close the dialog"}},
67 	{WK_Z WK_Z, {{&cmd_ctrl_c}, .descr = "close the dialog"}},
68 	{WK_g WK_g, {{&cmd_gg},     .descr = "go to the first item"}},
69 	{WK_j,      {{&cmd_j},      .descr = "go to item below"}},
70 	{WK_k,      {{&cmd_k},      .descr = "go to item above"}},
71 	{WK_l,      {{&cmd_return}, .descr = "perform selected action"}},
72 	{WK_q,      {{&cmd_ctrl_c}, .descr = "close the dialog"}},
73 	{WK_n,      {{&cmd_n},      .descr = "rename file"}},
74 	{WK_o,      {{&cmd_o},      .descr = "change owner"}},
75 	{WK_g,      {{&cmd_g},      .descr = "change group"}},
76 	{WK_p,      {{&cmd_p},      .descr = "change file permissions/attributes"}},
77 #ifdef ENABLE_EXTENDED_KEYS
78 	{{K(KEY_UP)},    {{&cmd_k},      .descr = "go to item above"}},
79 	{{K(KEY_DOWN)},  {{&cmd_j},      .descr = "go to item below"}},
80 	{{K(KEY_RIGHT)}, {{&cmd_return}, .descr = "perform selected action"}},
81 	{{K(KEY_HOME)},  {{&cmd_gg},     .descr = "go to the first item"}},
82 	{{K(KEY_END)},   {{&cmd_G},      .descr = "go to the last item"}},
83 #endif /* ENABLE_EXTENDED_KEYS */
84 };
85 
86 void
init_change_dialog_mode(void)87 init_change_dialog_mode(void)
88 {
89 	int ret_code;
90 
91 	ret_code = vle_keys_add(builtin_cmds, ARRAY_LEN(builtin_cmds), CHANGE_MODE);
92 	assert(ret_code == 0);
93 
94 	(void)ret_code;
95 }
96 
97 void
enter_change_mode(view_t * active_view)98 enter_change_mode(view_t *active_view)
99 {
100 	if(curr_stats.load_stage < 2)
101 		return;
102 
103 	view = active_view;
104 	vle_mode_set(CHANGE_MODE, VMT_SECONDARY);
105 
106 	curs_set(0);
107 	update_all_windows();
108 
109 	top = 2;
110 #ifndef _WIN32
111 	bottom = 8;
112 #else
113 	bottom = 4;
114 #endif
115 	curr = 2;
116 	col = 5;
117 	step = 2;
118 
119 	redraw_change_dialog();
120 }
121 
122 void
redraw_change_dialog(void)123 redraw_change_dialog(void)
124 {
125 	int x, y;
126 
127 	wresize(change_win, bottom + 3, 25);
128 
129 	getmaxyx(change_win, y, x);
130 	werase(change_win);
131 	box(change_win, 0, 0);
132 
133 	mvwaddstr(change_win, 0, (x - 20)/2, " Change Current File ");
134 	mvwaddstr(change_win, 2, 3, " [ ] n Name");
135 #ifndef _WIN32
136 	mvwaddstr(change_win, 4, 3, " [ ] o Owner");
137 	mvwaddstr(change_win, 6, 3, " [ ] g Group");
138 	mvwaddstr(change_win, 8, 3, " [ ] p Permissions");
139 #else
140 	mvwaddstr(change_win, 4, 3, " [ ] p Properties");
141 #endif
142 	print_at_pos();
143 
144 	getmaxyx(stdscr, y, x);
145 	mvwin(change_win, (y - getmaxy(change_win))/2, (x - getmaxx(change_win))/2);
146 	ui_refresh_win(change_win);
147 }
148 
149 static void
leave_change_mode(int clear_selection)150 leave_change_mode(int clear_selection)
151 {
152 	vle_mode_set(NORMAL_MODE, VMT_PRIMARY);
153 
154 	if(clear_selection)
155 	{
156 		ui_view_reset_selection_and_reload(view);
157 	}
158 
159 	update_all_windows();
160 }
161 
162 static void
cmd_ctrl_c(key_info_t key_info,keys_info_t * keys_info)163 cmd_ctrl_c(key_info_t key_info, keys_info_t *keys_info)
164 {
165 	leave_change_mode(1);
166 }
167 
168 static void
cmd_return(key_info_t key_info,keys_info_t * keys_info)169 cmd_return(key_info_t key_info, keys_info_t *keys_info)
170 {
171 	leave_change_mode(0);
172 
173 	if(curr == 2)
174 		fops_rename_current(view, 0);
175 #ifndef _WIN32
176 	else if(curr == 4)
177 		fops_chuser();
178 	else if(curr == 6)
179 		fops_chgroup();
180 	else if(curr == 8)
181 		enter_attr_mode(view);
182 #else
183 	else if(curr == 4)
184 		enter_attr_mode(view);
185 #endif
186 }
187 
188 static void
cmd_G(key_info_t key_info,keys_info_t * keys_info)189 cmd_G(key_info_t key_info, keys_info_t *keys_info)
190 {
191 	if(key_info.count == NO_COUNT_GIVEN)
192 		goto_line(bottom);
193 	else
194 		goto_line(key_info.count);
195 }
196 
197 static void
cmd_gg(key_info_t key_info,keys_info_t * keys_info)198 cmd_gg(key_info_t key_info, keys_info_t *keys_info)
199 {
200 	if(key_info.count == NO_COUNT_GIVEN)
201 		goto_line(1);
202 	else
203 		goto_line(key_info.count);
204 }
205 
206 static void
cmd_j(key_info_t key_info,keys_info_t * keys_info)207 cmd_j(key_info_t key_info, keys_info_t *keys_info)
208 {
209 	if(key_info.count == NO_COUNT_GIVEN)
210 		key_info.count = 1;
211 
212 	clear_at_pos();
213 	curr += key_info.count*step;
214 	if(curr > bottom)
215 		curr = bottom;
216 
217 	print_at_pos();
218 	ui_refresh_win(change_win);
219 }
220 
221 static void
cmd_k(key_info_t key_info,keys_info_t * keys_info)222 cmd_k(key_info_t key_info, keys_info_t *keys_info)
223 {
224 	if(key_info.count == NO_COUNT_GIVEN)
225 		key_info.count = 1;
226 
227 	clear_at_pos();
228 	curr -= key_info.count*step;
229 	if(curr < top)
230 		curr = top;
231 
232 	print_at_pos();
233 	ui_refresh_win(change_win);
234 }
235 
236 static void
cmd_n(key_info_t key_info,keys_info_t * keys_info)237 cmd_n(key_info_t key_info, keys_info_t *keys_info)
238 {
239 	goto_line(1);
240 	cmd_return(key_info, keys_info);
241 }
242 
243 static void
cmd_o(key_info_t key_info,keys_info_t * keys_info)244 cmd_o(key_info_t key_info, keys_info_t *keys_info)
245 {
246 	goto_line(2);
247 	cmd_return(key_info, keys_info);
248 }
249 
250 static void
cmd_g(key_info_t key_info,keys_info_t * keys_info)251 cmd_g(key_info_t key_info, keys_info_t *keys_info)
252 {
253 	goto_line(3);
254 	cmd_return(key_info, keys_info);
255 }
256 
257 static void
cmd_p(key_info_t key_info,keys_info_t * keys_info)258 cmd_p(key_info_t key_info, keys_info_t *keys_info)
259 {
260 	goto_line(4);
261 	cmd_return(key_info, keys_info);
262 }
263 
264 /* Moves cursor to the specified line and updates the dialog. */
265 static void
goto_line(int line)266 goto_line(int line)
267 {
268 	line = top + (line - 1)*step;
269 	if(line > bottom)
270 	{
271 		line = bottom;
272 	}
273 	if(curr == line)
274 	{
275 		return;
276 	}
277 
278 	clear_at_pos();
279 	curr = line;
280 	print_at_pos();
281 	ui_refresh_win(change_win);
282 }
283 
284 static void
print_at_pos(void)285 print_at_pos(void)
286 {
287 	mvwaddstr(change_win, curr, col, "*");
288 	checked_wmove(change_win, curr, col);
289 }
290 
291 static void
clear_at_pos(void)292 clear_at_pos(void)
293 {
294 	mvwaddstr(change_win, curr, col, " ");
295 }
296 
297 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
298 /* vim: set cinoptions+=t0 filetype=c : */
299