diff options
-rw-r--r-- | apps/fileop.c | 344 | ||||
-rw-r--r-- | apps/fileop.h | 19 | ||||
-rw-r--r-- | apps/onplay.c | 245 | ||||
-rw-r--r-- | apps/onplay.h | 2 |
4 files changed, 300 insertions, 310 deletions
diff --git a/apps/fileop.c b/apps/fileop.c index 0d2dc774b9..c4bdc5aa18 100644 --- a/apps/fileop.c +++ b/apps/fileop.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * __________ __ ___. | 2 | * __________ __ ___. |
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2002 Björn Stenberg | 10 | * Copyright (C) 2002 Björn Stenberg |
@@ -50,6 +50,17 @@ struct file_op_params | |||
50 | size_t append; /* Append position in 'path' for stack push */ | 50 | size_t append; /* Append position in 'path' for stack push */ |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static int prompt_name(char* buf, size_t bufsz) | ||
54 | { | ||
55 | if (kbd_input(buf, bufsz, NULL) < 0) | ||
56 | return FORC_CANCELLED; | ||
57 | /* at least prevent escapes out of the base directory from keyboard- | ||
58 | entered filenames; the file code should reject other invalidities */ | ||
59 | if (*buf != '\0' && !strchr(buf, PATH_SEPCH) && !is_dotdir_name(buf)) | ||
60 | return FORC_SUCCESS; | ||
61 | return FORC_UNKNOWN_FAILURE; | ||
62 | } | ||
63 | |||
53 | static bool poll_cancel_action(const char *path, int operation, int current, int total) | 64 | static bool poll_cancel_action(const char *path, int operation, int current, int total) |
54 | { | 65 | { |
55 | const char *op_str = ""; | 66 | const char *op_str = ""; |
@@ -75,7 +86,7 @@ static bool poll_cancel_action(const char *path, int operation, int current, int | |||
75 | return ACTION_STD_CANCEL == get_action(CONTEXT_STD, TIMEOUT_NOBLOCK); | 86 | return ACTION_STD_CANCEL == get_action(CONTEXT_STD, TIMEOUT_NOBLOCK); |
76 | } | 87 | } |
77 | 88 | ||
78 | static struct file_op_params* init_file_op(struct file_op_params *param, | 89 | static void init_file_op(struct file_op_params *param, |
79 | const char *basename, | 90 | const char *basename, |
80 | const char *selected_file) | 91 | const char *selected_file) |
81 | { | 92 | { |
@@ -90,8 +101,6 @@ static struct file_op_params* init_file_op(struct file_op_params *param, | |||
90 | param->is_dir = dir_exists(param->path); | 101 | param->is_dir = dir_exists(param->path); |
91 | param->objects = 0; /* how many files and subdirectories*/ | 102 | param->objects = 0; /* how many files and subdirectories*/ |
92 | param->processed = 0; | 103 | param->processed = 0; |
93 | |||
94 | return param; | ||
95 | } | 104 | } |
96 | 105 | ||
97 | /* counts file objects, deletes file objects */ | 106 | /* counts file objects, deletes file objects */ |
@@ -144,7 +153,7 @@ static int directory_fileop(struct file_op_params *param, enum file_op_current f | |||
144 | 153 | ||
145 | if (info.attribute & ATTR_DIRECTORY) { | 154 | if (info.attribute & ATTR_DIRECTORY) { |
146 | /* remove a subdirectory */ | 155 | /* remove a subdirectory */ |
147 | rc = directory_fileop(param, fileop); | 156 | rc = directory_fileop(param, fileop); /* recursion */ |
148 | } else { | 157 | } else { |
149 | /* remove a file */ | 158 | /* remove a file */ |
150 | if (poll_cancel_action(param->path, FOC_DELETE, param->processed, param->objects)) | 159 | if (poll_cancel_action(param->path, FOC_DELETE, param->processed, param->objects)) |
@@ -165,8 +174,8 @@ static int directory_fileop(struct file_op_params *param, enum file_op_current f | |||
165 | } | 174 | } |
166 | 175 | ||
167 | if (info.attribute & ATTR_DIRECTORY) { | 176 | if (info.attribute & ATTR_DIRECTORY) { |
168 | /* remove a subdirectory */ | 177 | /* enter subdirectory */ |
169 | rc = directory_fileop(param, FOC_COUNT); | 178 | rc = directory_fileop(param, FOC_COUNT); /* recursion */ |
170 | } else { | 179 | } else { |
171 | if (poll_cancel_action(param->path, FOC_COUNT, param->objects, 0)) | 180 | if (poll_cancel_action(param->path, FOC_COUNT, param->objects, 0)) |
172 | { | 181 | { |
@@ -195,150 +204,42 @@ static int directory_fileop(struct file_op_params *param, enum file_op_current f | |||
195 | return rc; | 204 | return rc; |
196 | } | 205 | } |
197 | 206 | ||
207 | /* Walk a directory tree and count the number of objects (dirs & files) | ||
208 | * also check that enough resources exist to do an operation */ | ||
198 | static int check_count_fileobjects(struct file_op_params *param) | 209 | static int check_count_fileobjects(struct file_op_params *param) |
199 | { | 210 | { |
211 | cpu_boost(true); | ||
200 | int rc = directory_fileop(param, FOC_COUNT); | 212 | int rc = directory_fileop(param, FOC_COUNT); |
213 | cpu_boost(false); | ||
201 | DEBUGF("%s res:(%d) objects %d \n", __func__, rc, param->objects); | 214 | DEBUGF("%s res:(%d) objects %d \n", __func__, rc, param->objects); |
202 | return rc; | 215 | return rc; |
203 | } | 216 | } |
204 | 217 | ||
205 | static bool check_new_name(const char *basename) | 218 | /* Attempt to just rename a file or directory */ |
206 | { | ||
207 | /* at least prevent escapes out of the base directory from keyboard- | ||
208 | entered filenames; the file code should reject other invalidities */ | ||
209 | return *basename != '\0' && !strchr(basename, PATH_SEPCH) && | ||
210 | !is_dotdir_name(basename); | ||
211 | } | ||
212 | |||
213 | int create_dir(void) | ||
214 | { | ||
215 | int rc = FORC_UNKNOWN_FAILURE; | ||
216 | char dirname[MAX_PATH]; | ||
217 | size_t pathlen = path_append(dirname, getcwd(NULL, 0), PA_SEP_HARD, | ||
218 | sizeof (dirname)); | ||
219 | char *basename = dirname + pathlen; | ||
220 | |||
221 | if (pathlen >= sizeof (dirname)) { | ||
222 | /* Too long */ | ||
223 | } else if (kbd_input(basename, sizeof (dirname) - pathlen, NULL) < 0) { | ||
224 | rc = FORC_CANCELLED; | ||
225 | } else if (check_new_name(basename)) { | ||
226 | rc = mkdir(dirname); | ||
227 | } | ||
228 | |||
229 | return rc; | ||
230 | } | ||
231 | |||
232 | /************************************************************************************/ | ||
233 | /* share code for file and directory deletion, saves space */ | ||
234 | static int delete_file_dir(struct file_op_params *param) | ||
235 | { | ||
236 | /* Note: delete_file_dir() will happily delete whatever | ||
237 | * path is passed (after confirmation) */ | ||
238 | if (confirm_delete_yesno(param->path) != YESNO_YES) { | ||
239 | return FORC_CANCELLED; | ||
240 | } | ||
241 | |||
242 | clear_screen_buffer(true); | ||
243 | poll_cancel_action(param->path, FOC_DELETE, param->processed, param->objects); | ||
244 | |||
245 | int rc = FORC_UNKNOWN_FAILURE; | ||
246 | |||
247 | if (param->is_dir) { /* if directory */ | ||
248 | cpu_boost(true); | ||
249 | rc = directory_fileop(param, FOC_DELETE); | ||
250 | cpu_boost(false); | ||
251 | } else { | ||
252 | rc = remove(param->path); | ||
253 | } | ||
254 | |||
255 | return rc; | ||
256 | } | ||
257 | |||
258 | int delete_fileobject(const char *selected_file) | ||
259 | { | ||
260 | struct file_op_params param; | ||
261 | if (init_file_op(¶m, selected_file, NULL)->is_dir == true) | ||
262 | { | ||
263 | int rc = check_count_fileobjects(¶m); | ||
264 | DEBUGF("%s res: %d, ct: %d, %s", __func__, rc, param.objects, param.path); | ||
265 | if (rc != FORC_SUCCESS) | ||
266 | return rc; | ||
267 | } | ||
268 | |||
269 | return delete_file_dir(¶m); | ||
270 | } | ||
271 | |||
272 | int rename_file(const char *selected_file) | ||
273 | { | ||
274 | int rc = FORC_UNKNOWN_FAILURE; | ||
275 | char newname[MAX_PATH]; | ||
276 | const char *oldbase, *selection = selected_file; | ||
277 | |||
278 | path_basename(selection, &oldbase); | ||
279 | size_t pathlen = oldbase - selection; | ||
280 | char *newbase = newname + pathlen; | ||
281 | |||
282 | if (strmemccpy(newname, selection, sizeof (newname)) == NULL) { | ||
283 | /* Too long */ | ||
284 | } else if (kbd_input(newbase, sizeof (newname) - pathlen, NULL) < 0) { | ||
285 | rc = FORC_CANCELLED; | ||
286 | } else if (!strcmp(oldbase, newbase)) { | ||
287 | rc = FORC_NOOP; /* No change at all */ | ||
288 | } else if (check_new_name(newbase)) { | ||
289 | switch (relate(selection, newname)) | ||
290 | { | ||
291 | case RELATE_DIFFERENT: | ||
292 | if (file_exists(newname)) { | ||
293 | break; /* don't overwrite */ | ||
294 | } | ||
295 | /* Fall-through */ | ||
296 | case RELATE_SAME: | ||
297 | rc = rename(selection, newname); | ||
298 | break; | ||
299 | case RELATE_PREFIX: | ||
300 | default: | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | return rc; | ||
306 | } | ||
307 | |||
308 | static int move_by_rename(const char *src_path, | 219 | static int move_by_rename(const char *src_path, |
309 | const char *dst_path, | 220 | const char *dst_path, |
310 | unsigned int *pflags) | 221 | unsigned int *pflags) |
311 | { | 222 | { |
312 | unsigned int flags = *pflags; | 223 | unsigned int flags = *pflags; |
313 | int rc = FORC_UNKNOWN_FAILURE; | 224 | int rc = FORC_UNKNOWN_FAILURE; |
314 | while (!(flags & (PASTE_COPY | PASTE_EXDEV))) { | 225 | if (!(flags & (PASTE_COPY | PASTE_EXDEV))) { |
315 | if ((flags & PASTE_OVERWRITE) || !file_exists(dst_path)) { | 226 | if ((flags & PASTE_OVERWRITE) || !file_exists(dst_path)) { |
316 | /* Just try to move the directory / file */ | 227 | /* Just try to move the directory / file */ |
317 | if (poll_cancel_action(src_path, FOC_MOVE, 0 , 0)) { | 228 | if (poll_cancel_action(src_path, FOC_MOVE, 0 , 0)) { |
318 | rc = FORC_CANCELLED; | 229 | rc = FORC_CANCELLED; |
319 | } else { | 230 | } else { |
320 | rc = rename(src_path, dst_path); | 231 | rc = rename(src_path, dst_path); |
321 | } | 232 | #ifdef HAVE_MULTIVOLUME |
322 | 233 | if (rc < FORC_SUCCESS && errno == EXDEV) { | |
323 | if (rc < 0) { | 234 | /* Failed because cross volume rename doesn't work */ |
324 | int errnum = errno; | 235 | *pflags |= PASTE_EXDEV; /* force a move instead */ |
325 | if (errnum == ENOTEMPTY && (flags & PASTE_OVERWRITE)) { | ||
326 | /* Directory is not empty thus rename() will not do a quick | ||
327 | overwrite */ | ||
328 | break; | ||
329 | } | 236 | } |
330 | #ifdef HAVE_MULTIVOLUME | 237 | #endif /* HAVE_MULTIVOLUME */ |
331 | else if (errnum == EXDEV) { | 238 | /* if (errno == ENOTEMPTY && (flags & PASTE_OVERWRITE)) { |
332 | /* Failed because cross volume rename doesn't work; force | 239 | * Directory is not empty thus rename() will not do a quick overwrite */ |
333 | a move instead */ | ||
334 | *pflags |= PASTE_EXDEV; | ||
335 | break; | ||
336 | } | ||
337 | #endif /* HAVE_MULTIVOLUME */ | ||
338 | } | 240 | } |
339 | } | 241 | } |
340 | 242 | ||
341 | break; | ||
342 | } | 243 | } |
343 | return rc; | 244 | return rc; |
344 | } | 245 | } |
@@ -365,8 +266,7 @@ static int copy_move_file(const char *src_path, const char *dst_path, unsigned i | |||
365 | return FORC_NO_BUFFER_AVAIL; | 266 | return FORC_NO_BUFFER_AVAIL; |
366 | } | 267 | } |
367 | 268 | ||
368 | buffersize &= ~0x1ff; /* Round buffer size to multiple of sector | 269 | buffersize &= ~0x1ff; /* Round buffer size to multiple of sector size */ |
369 | size */ | ||
370 | 270 | ||
371 | int src_fd = open(src_path, O_RDONLY); | 271 | int src_fd = open(src_path, O_RDONLY); |
372 | if (src_fd >= 0) { | 272 | if (src_fd >= 0) { |
@@ -423,9 +323,12 @@ static int copy_move_file(const char *src_path, const char *dst_path, unsigned i | |||
423 | } | 323 | } |
424 | 324 | ||
425 | if (rc == FORC_SUCCESS) { | 325 | if (rc == FORC_SUCCESS) { |
426 | /* If overwriting, set the correct length if original was | 326 | if (total_size != src_sz) |
427 | longer */ | 327 | rc = FORC_UNKNOWN_FAILURE; |
428 | rc = ftruncate(dst_fd, total_size) * 10; | 328 | else { |
329 | /* If overwriting, set the correct length if original was longer */ | ||
330 | rc = ftruncate(dst_fd, total_size) * 10; | ||
331 | } | ||
429 | } | 332 | } |
430 | 333 | ||
431 | close(dst_fd); | 334 | close(dst_fd); |
@@ -449,20 +352,19 @@ static int copy_move_file(const char *src_path, const char *dst_path, unsigned i | |||
449 | 352 | ||
450 | /* Paste a directory */ | 353 | /* Paste a directory */ |
451 | static int copy_move_directory(struct file_op_params *src, | 354 | static int copy_move_directory(struct file_op_params *src, |
452 | struct file_op_params *dst, | 355 | struct file_op_params *dst, |
453 | unsigned int flags) | 356 | unsigned int flags) |
454 | { | 357 | { |
455 | int rc = FORC_UNKNOWN_FAILURE; | ||
456 | |||
457 | DIR *srcdir = opendir(src->path); | 358 | DIR *srcdir = opendir(src->path); |
458 | 359 | ||
459 | if (srcdir) { | 360 | if (!srcdir) |
460 | /* Make a directory to copy things to */ | 361 | return FORC_PATH_NOT_EXIST; |
461 | rc = mkdir(dst->path) * 10; | 362 | |
462 | if (rc < 0 && errno == EEXIST && (flags & PASTE_OVERWRITE)) { | 363 | /* Make a directory to copy things to */ |
463 | /* Exists and overwrite was approved */ | 364 | int rc = mkdir(dst->path) * 10; |
464 | rc = FORC_SUCCESS; | 365 | if (rc < 0 && errno == EEXIST && (flags & PASTE_OVERWRITE)) { |
465 | } | 366 | /* Exists and overwrite was approved */ |
367 | rc = FORC_SUCCESS; | ||
466 | } | 368 | } |
467 | 369 | ||
468 | size_t srcap = src->append, dstap = dst->append; | 370 | size_t srcap = src->append, dstap = dst->append; |
@@ -488,7 +390,7 @@ static int copy_move_directory(struct file_op_params *src, | |||
488 | /* Append names to current directories */ | 390 | /* Append names to current directories */ |
489 | src->append = srcap + | 391 | src->append = srcap + |
490 | path_append(&src->path[srcap], PA_SEP_HARD, entry->d_name, | 392 | path_append(&src->path[srcap], PA_SEP_HARD, entry->d_name, |
491 | sizeof(src->path) - srcap); | 393 | sizeof (src->path) - srcap); |
492 | 394 | ||
493 | dst->append = dstap + | 395 | dst->append = dstap + |
494 | path_append(&dst->path[dstap], PA_SEP_HARD, entry->d_name, | 396 | path_append(&dst->path[dstap], PA_SEP_HARD, entry->d_name, |
@@ -538,13 +440,16 @@ static int copy_move_directory(struct file_op_params *src, | |||
538 | return rc; | 440 | return rc; |
539 | } | 441 | } |
540 | 442 | ||
443 | /************************************************************************************/ | ||
444 | /* PUBLIC FUNCTIONS */ | ||
445 | /************************************************************************************/ | ||
446 | |||
447 | /* Copy or move a file or directory see: file_op_flags */ | ||
541 | int copy_move_fileobject(const char *src_path, const char *dst_path, unsigned int flags) | 448 | int copy_move_fileobject(const char *src_path, const char *dst_path, unsigned int flags) |
542 | { | 449 | { |
543 | if (!src_path[0]) | 450 | if (!src_path[0]) |
544 | return FORC_NOOP; | 451 | return FORC_NOOP; |
545 | 452 | ||
546 | int rc = FORC_UNKNOWN_FAILURE; | ||
547 | |||
548 | struct file_op_params src, dst; | 453 | struct file_op_params src, dst; |
549 | 454 | ||
550 | /* Figure out the name of the selection */ | 455 | /* Figure out the name of the selection */ |
@@ -553,40 +458,37 @@ int copy_move_fileobject(const char *src_path, const char *dst_path, unsigned in | |||
553 | 458 | ||
554 | /* Final target is current directory plus name of selection */ | 459 | /* Final target is current directory plus name of selection */ |
555 | init_file_op(&dst, dst_path, nameptr); | 460 | init_file_op(&dst, dst_path, nameptr); |
461 | if (dst.append >= sizeof (dst.path)) | ||
462 | return FORC_PATH_TOO_LONG; | ||
556 | 463 | ||
557 | switch (dst.append < sizeof (dst.path) ? | 464 | int rel = relate(src_path, dst.path); |
558 | relate(src_path, dst.path) : FORC_PATH_TOO_LONG) | 465 | if (rel == RELATE_SAME) |
559 | { | 466 | return FORC_NOOP; |
560 | case RELATE_SAME: | ||
561 | rc = FORC_NOOP; | ||
562 | break; | ||
563 | 467 | ||
564 | case RELATE_DIFFERENT: | 468 | if (rel == RELATE_DIFFERENT) { |
469 | int rc; | ||
565 | if (file_exists(dst.path)) { | 470 | if (file_exists(dst.path)) { |
566 | /* If user chooses not to overwrite, cancel */ | 471 | /* If user chooses not to overwrite, cancel */ |
567 | if (confirm_overwrite_yesno() == YESNO_NO) { | 472 | if (confirm_overwrite_yesno() == YESNO_NO) { |
568 | rc = FORC_NOOVERWRT; | 473 | return FORC_NOOVERWRT; |
569 | break; | ||
570 | } | 474 | } |
571 | 475 | ||
572 | flags |= PASTE_OVERWRITE; | 476 | flags |= PASTE_OVERWRITE; |
573 | } | 477 | } |
574 | 478 | ||
479 | init_file_op(&src, src_path, NULL); | ||
480 | if (src.append >= sizeof (src.path)) | ||
481 | return FORC_PATH_TOO_LONG; | ||
575 | /* Now figure out what we're doing */ | 482 | /* Now figure out what we're doing */ |
576 | cpu_boost(true); | 483 | cpu_boost(true); |
577 | |||
578 | init_file_op(&src, src_path, NULL); | ||
579 | |||
580 | if (src.is_dir) { | 484 | if (src.is_dir) { |
581 | /* Copy or move a subdirectory */ | 485 | /* Copy or move a subdirectory */ |
582 | 486 | /* Try renaming first */ | |
583 | if (src.append < sizeof (src.path)) { | 487 | rc = move_by_rename(src.path, dst.path, &flags); |
584 | /* Try renaming first */ | 488 | if (rc < FORC_SUCCESS) { |
585 | rc = move_by_rename(src.path, dst.path, &flags); | 489 | rc = check_count_fileobjects(&src); |
586 | if (rc != FORC_SUCCESS && rc != FORC_CANCELLED) { | 490 | if (rc == FORC_SUCCESS) { |
587 | if (check_count_fileobjects(&src) == FORC_SUCCESS) { | 491 | rc = copy_move_directory(&src, &dst, flags); |
588 | rc = copy_move_directory(&src, &dst, flags); | ||
589 | } | ||
590 | } | 492 | } |
591 | } | 493 | } |
592 | } else { | 494 | } else { |
@@ -595,12 +497,102 @@ int copy_move_fileobject(const char *src_path, const char *dst_path, unsigned in | |||
595 | } | 497 | } |
596 | 498 | ||
597 | cpu_boost(false); | 499 | cpu_boost(false); |
598 | break; | 500 | DEBUGF("%s res: %d, ct: %d/%d %s\n", |
501 | __func__, rc, src.objects, src.processed, src.path); | ||
502 | return rc; | ||
503 | } | ||
504 | |||
505 | /* Else Some other relation / failure */ | ||
506 | DEBUGF("%s res: %d, rel: %d\n", __func__, rc, rel); | ||
507 | return FORC_UNKNOWN_FAILURE; | ||
508 | } | ||
509 | |||
510 | int create_dir(void) | ||
511 | { | ||
512 | int rc; | ||
513 | char dirname[MAX_PATH]; | ||
514 | size_t pathlen = path_append(dirname, getcwd(NULL, 0), PA_SEP_HARD, | ||
515 | sizeof (dirname)); | ||
516 | char *basename = dirname + pathlen; | ||
517 | |||
518 | if (pathlen >= sizeof (dirname)) | ||
519 | return FORC_PATH_TOO_LONG; | ||
520 | |||
521 | rc = prompt_name(basename, sizeof (dirname) - pathlen); | ||
522 | if (rc == FORC_SUCCESS) | ||
523 | rc = mkdir(dirname) * 10; | ||
524 | return rc; | ||
525 | } | ||
599 | 526 | ||
600 | case RELATE_PREFIX: | 527 | /* share code for file and directory deletion, saves space */ |
601 | default: /* Some other relation / failure */ | 528 | int delete_fileobject(const char *selected_file) |
602 | break; | 529 | { |
530 | int rc; | ||
531 | struct file_op_params param; | ||
532 | init_file_op(¶m, selected_file, NULL); | ||
533 | if (param.append >= sizeof (param.path)) | ||
534 | return FORC_PATH_TOO_LONG; | ||
535 | |||
536 | if (param.is_dir) { | ||
537 | int rc = check_count_fileobjects(¶m); | ||
538 | DEBUGF("%s res: %d, ct: %d, %s", __func__, rc, param.objects, param.path); | ||
539 | if (rc != FORC_SUCCESS) | ||
540 | return rc; | ||
541 | } | ||
542 | |||
543 | /* Note: delete_fileobject() will happily delete whatever | ||
544 | * path is passed (after confirmation) */ | ||
545 | if (confirm_delete_yesno(param.path) != YESNO_YES) { | ||
546 | return FORC_CANCELLED; | ||
547 | } | ||
548 | |||
549 | clear_screen_buffer(true); | ||
550 | if (poll_cancel_action(param.path, FOC_DELETE, param.processed, param.objects)) | ||
551 | return FORC_CANCELLED; | ||
552 | |||
553 | if (param.is_dir) { /* if directory */ | ||
554 | cpu_boost(true); | ||
555 | rc = directory_fileop(¶m, FOC_DELETE); | ||
556 | cpu_boost(false); | ||
557 | } else { | ||
558 | rc = remove(param.path) * 10; | ||
603 | } | 559 | } |
604 | 560 | ||
605 | return rc; | 561 | return rc; |
606 | } | 562 | } |
563 | |||
564 | int rename_file(const char *selected_file) | ||
565 | { | ||
566 | int rc; | ||
567 | char newname[MAX_PATH]; | ||
568 | const char *oldbase, *selection = selected_file; | ||
569 | |||
570 | path_basename(selection, &oldbase); | ||
571 | size_t pathlen = oldbase - selection; | ||
572 | char *newbase = newname + pathlen; | ||
573 | |||
574 | if (strmemccpy(newname, selection, sizeof (newname)) == NULL) | ||
575 | return FORC_PATH_TOO_LONG; | ||
576 | |||
577 | rc = prompt_name(newbase, sizeof (newname) - pathlen); | ||
578 | |||
579 | if (rc != FORC_SUCCESS) | ||
580 | return rc; | ||
581 | |||
582 | if (!strcmp(oldbase, newbase)) | ||
583 | return FORC_NOOP; /* No change at all */ | ||
584 | |||
585 | int rel = relate(selection, newname); | ||
586 | if (rel == RELATE_DIFFERENT) | ||
587 | { | ||
588 | if (file_exists(newname)) { /* don't overwrite */ | ||
589 | return FORC_PATH_EXISTS; | ||
590 | } | ||
591 | return rename(selection, newname) * 10; | ||
592 | } | ||
593 | if (rel == RELATE_SAME) | ||
594 | return rename(selection, newname) * 10; | ||
595 | |||
596 | /* Else Some other relation / failure */ | ||
597 | return FORC_UNKNOWN_FAILURE; | ||
598 | } | ||
diff --git a/apps/fileop.h b/apps/fileop.h index f8237dc64f..f477549977 100644 --- a/apps/fileop.h +++ b/apps/fileop.h | |||
@@ -1,10 +1,10 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * __________ __ ___. | 2 | * __________ __ ___. |
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2002 Björn Stenberg | 10 | * Copyright (C) 2002 Björn Stenberg |
@@ -26,6 +26,7 @@ | |||
26 | /* result codes of various file operations */ | 26 | /* result codes of various file operations */ |
27 | enum fileop_result_code | 27 | enum fileop_result_code |
28 | { | 28 | { |
29 | FORC_PATH_EXISTS = -8, | ||
29 | FORC_READ_FAILURE = -7, | 30 | FORC_READ_FAILURE = -7, |
30 | FORC_WRITE_FAILURE = -6, | 31 | FORC_WRITE_FAILURE = -6, |
31 | FORC_NO_BUFFER_AVAIL = -5, | 32 | FORC_NO_BUFFER_AVAIL = -5, |
@@ -55,7 +56,6 @@ enum file_op_current | |||
55 | FOC_MOVE, | 56 | FOC_MOVE, |
56 | FOC_COPY, | 57 | FOC_COPY, |
57 | FOC_DELETE, | 58 | FOC_DELETE, |
58 | FOC_CREATE, | ||
59 | }; | 59 | }; |
60 | 60 | ||
61 | int create_dir(void); | 61 | int create_dir(void); |
@@ -64,7 +64,8 @@ int rename_file(const char *selected_file); | |||
64 | 64 | ||
65 | int delete_fileobject(const char *selected_file); | 65 | int delete_fileobject(const char *selected_file); |
66 | 66 | ||
67 | int copy_move_fileobject(const char *src_path, const char *dst_path, | 67 | int copy_move_fileobject(const char *src_path, |
68 | unsigned int flags); | 68 | const char *dst_path, |
69 | unsigned int flags); | ||
69 | 70 | ||
70 | #endif /* FILEOP_H */ | 71 | #endif /* FILEOP_H */ |
diff --git a/apps/onplay.c b/apps/onplay.c index 4880af58f3..d468c0a545 100644 --- a/apps/onplay.c +++ b/apps/onplay.c | |||
@@ -65,12 +65,9 @@ | |||
65 | #include "shortcuts.h" | 65 | #include "shortcuts.h" |
66 | #include "misc.h" | 66 | #include "misc.h" |
67 | 67 | ||
68 | static int context; | ||
69 | static const char *selected_file = NULL; | ||
70 | static char selected_file_path[MAX_PATH]; | ||
71 | static int selected_file_attr = 0; | ||
72 | static int onplay_result = ONPLAY_OK; | 68 | static int onplay_result = ONPLAY_OK; |
73 | static bool in_queue_submenu = false; | 69 | static bool in_queue_submenu = false; |
70 | |||
74 | static bool (*ctx_current_playlist_insert)(int position, bool queue, bool create_new); | 71 | static bool (*ctx_current_playlist_insert)(int position, bool queue, bool create_new); |
75 | static int (*ctx_add_to_playlist)(const char* playlist, bool new_playlist); | 72 | static int (*ctx_add_to_playlist)(const char* playlist, bool new_playlist); |
76 | extern struct menu_item_ex file_menu; /* settings_menu.c */ | 73 | extern struct menu_item_ex file_menu; /* settings_menu.c */ |
@@ -84,6 +81,14 @@ extern struct menu_item_ex file_menu; /* settings_menu.c */ | |||
84 | MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \ | 81 | MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \ |
85 | { (void*)name##_},{.callback_and_desc = & name##__}}; | 82 | { (void*)name##_},{.callback_and_desc = & name##__}}; |
86 | 83 | ||
84 | static struct selected_file | ||
85 | { | ||
86 | char buf[MAX_PATH]; | ||
87 | const char *path; | ||
88 | int attr; | ||
89 | int context; | ||
90 | } selected_file; | ||
91 | |||
87 | static struct clipboard | 92 | static struct clipboard |
88 | { | 93 | { |
89 | char path[MAX_PATH]; /* Clipped file's path */ | 94 | char path[MAX_PATH]; /* Clipped file's path */ |
@@ -91,6 +96,14 @@ static struct clipboard | |||
91 | unsigned int flags; /* Operation type flags */ | 96 | unsigned int flags; /* Operation type flags */ |
92 | } clipboard; | 97 | } clipboard; |
93 | 98 | ||
99 | /* set selected file (doesn't touch buffer) */ | ||
100 | static void selected_file_set(int context, const char *path, int attr) | ||
101 | { | ||
102 | selected_file.path = path; | ||
103 | selected_file.attr = attr; | ||
104 | selected_file.context = context; | ||
105 | } | ||
106 | |||
94 | /* Empty the clipboard */ | 107 | /* Empty the clipboard */ |
95 | static void clipboard_clear_selection(struct clipboard *clip) | 108 | static void clipboard_clear_selection(struct clipboard *clip) |
96 | { | 109 | { |
@@ -149,20 +162,18 @@ static int bookmark_menu_callback(int action, | |||
149 | struct gui_synclist *this_list) | 162 | struct gui_synclist *this_list) |
150 | { | 163 | { |
151 | (void) this_list; | 164 | (void) this_list; |
152 | switch (action) | 165 | if (action == ACTION_REQUEST_MENUITEM) |
153 | { | 166 | { |
154 | case ACTION_REQUEST_MENUITEM: | 167 | /* hide loading bookmarks menu if no bookmarks exist */ |
155 | /* hide loading bookmarks menu if no bookmarks exist */ | 168 | if (this_item == &bookmark_load_menu_item) |
156 | if (this_item == &bookmark_load_menu_item) | 169 | { |
157 | { | 170 | if (!bookmark_exists()) |
158 | if (!bookmark_exists()) | 171 | return ACTION_EXIT_MENUITEM; |
159 | return ACTION_EXIT_MENUITEM; | 172 | } |
160 | } | ||
161 | break; | ||
162 | case ACTION_EXIT_MENUITEM: | ||
163 | settings_save(); | ||
164 | break; | ||
165 | } | 173 | } |
174 | else if (action == ACTION_EXIT_MENUITEM) | ||
175 | settings_save(); | ||
176 | |||
166 | return action; | 177 | return action; |
167 | } | 178 | } |
168 | 179 | ||
@@ -244,20 +255,20 @@ static struct add_to_pl_param addtopl_replace_shuffled = {PLAYLIST_INSERT_LAST_S | |||
244 | static void op_playlist_insert_selected(int position, bool queue) | 255 | static void op_playlist_insert_selected(int position, bool queue) |
245 | { | 256 | { |
246 | #ifdef HAVE_TAGCACHE | 257 | #ifdef HAVE_TAGCACHE |
247 | if (context == CONTEXT_STD && ctx_current_playlist_insert != NULL) | 258 | if (selected_file.context == CONTEXT_STD && ctx_current_playlist_insert != NULL) |
248 | { | 259 | { |
249 | ctx_current_playlist_insert(position, queue, false); | 260 | ctx_current_playlist_insert(position, queue, false); |
250 | return; | 261 | return; |
251 | } | 262 | } |
252 | #endif | 263 | #endif |
253 | if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) | 264 | if ((selected_file.attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) |
254 | playlist_insert_track(NULL, selected_file, position, queue, true); | 265 | playlist_insert_track(NULL, selected_file.path, position, queue, true); |
255 | else if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U) | 266 | else if ((selected_file.attr & FILE_ATTR_MASK) == FILE_ATTR_M3U) |
256 | playlist_insert_playlist(NULL, selected_file, position, queue); | 267 | playlist_insert_playlist(NULL, selected_file.path, position, queue); |
257 | else if (selected_file_attr & ATTR_DIRECTORY) | 268 | else if (selected_file.attr & ATTR_DIRECTORY) |
258 | { | 269 | { |
259 | #ifdef HAVE_TAGCACHE | 270 | #ifdef HAVE_TAGCACHE |
260 | if (context == CONTEXT_ID3DB) | 271 | if (selected_file.context == CONTEXT_ID3DB) |
261 | { | 272 | { |
262 | tagtree_current_playlist_insert(position, queue); | 273 | tagtree_current_playlist_insert(position, queue); |
263 | return; | 274 | return; |
@@ -269,14 +280,14 @@ static void op_playlist_insert_selected(int position, bool queue) | |||
269 | 280 | ||
270 | const char *lines[] = { | 281 | const char *lines[] = { |
271 | ID2P(LANG_RECURSE_DIRECTORY_QUESTION), | 282 | ID2P(LANG_RECURSE_DIRECTORY_QUESTION), |
272 | selected_file | 283 | selected_file.path |
273 | }; | 284 | }; |
274 | const struct text_message message={lines, 2}; | 285 | const struct text_message message={lines, 2}; |
275 | /* Ask if user wants to recurse directory */ | 286 | /* Ask if user wants to recurse directory */ |
276 | recurse = (gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES); | 287 | recurse = (gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES); |
277 | } | 288 | } |
278 | 289 | ||
279 | playlist_insert_directory(NULL, selected_file, position, queue, | 290 | playlist_insert_directory(NULL, selected_file.path, position, queue, |
280 | recurse == RECURSE_ON); | 291 | recurse == RECURSE_ON); |
281 | } | 292 | } |
282 | } | 293 | } |
@@ -336,7 +347,7 @@ static bool view_playlist(void) | |||
336 | { | 347 | { |
337 | bool result; | 348 | bool result; |
338 | 349 | ||
339 | result = playlist_viewer_ex(selected_file, NULL); | 350 | result = playlist_viewer_ex(selected_file.path, NULL); |
340 | 351 | ||
341 | if (result == PLAYLIST_VIEWER_OK && | 352 | if (result == PLAYLIST_VIEWER_OK && |
342 | onplay_result == ONPLAY_OK) | 353 | onplay_result == ONPLAY_OK) |
@@ -431,7 +442,7 @@ static int treeplaylist_callback(int action, | |||
431 | struct gui_synclist *this_list) | 442 | struct gui_synclist *this_list) |
432 | { | 443 | { |
433 | (void)this_list; | 444 | (void)this_list; |
434 | int sel_file_attr = (selected_file_attr & FILE_ATTR_MASK); | 445 | int sel_file_attr = (selected_file.attr & FILE_ATTR_MASK); |
435 | 446 | ||
436 | switch (action) | 447 | switch (action) |
437 | { | 448 | { |
@@ -440,7 +451,7 @@ static int treeplaylist_callback(int action, | |||
440 | { | 451 | { |
441 | if (sel_file_attr != FILE_ATTR_AUDIO && | 452 | if (sel_file_attr != FILE_ATTR_AUDIO && |
442 | sel_file_attr != FILE_ATTR_M3U && | 453 | sel_file_attr != FILE_ATTR_M3U && |
443 | (selected_file_attr & ATTR_DIRECTORY) == 0) | 454 | (selected_file.attr & ATTR_DIRECTORY) == 0) |
444 | return ACTION_EXIT_MENUITEM; | 455 | return ACTION_EXIT_MENUITEM; |
445 | } | 456 | } |
446 | else if (this_item == &queue_menu) | 457 | else if (this_item == &queue_menu) |
@@ -471,7 +482,7 @@ static int treeplaylist_callback(int action, | |||
471 | return ACTION_EXIT_MENUITEM; | 482 | return ACTION_EXIT_MENUITEM; |
472 | 483 | ||
473 | if (sel_file_attr != FILE_ATTR_M3U && | 484 | if (sel_file_attr != FILE_ATTR_M3U && |
474 | (selected_file_attr & ATTR_DIRECTORY) == 0) | 485 | (selected_file.attr & ATTR_DIRECTORY) == 0) |
475 | return ACTION_EXIT_MENUITEM; | 486 | return ACTION_EXIT_MENUITEM; |
476 | } | 487 | } |
477 | 488 | ||
@@ -494,10 +505,8 @@ static int treeplaylist_callback(int action, | |||
494 | 505 | ||
495 | void onplay_show_playlist_menu(const char* path, int attr, void (*playlist_insert_cb)) | 506 | void onplay_show_playlist_menu(const char* path, int attr, void (*playlist_insert_cb)) |
496 | { | 507 | { |
497 | context = CONTEXT_STD; | ||
498 | ctx_current_playlist_insert = playlist_insert_cb; | 508 | ctx_current_playlist_insert = playlist_insert_cb; |
499 | selected_file = path; | 509 | selected_file_set(CONTEXT_STD, path, attr); |
500 | selected_file_attr = attr; | ||
501 | in_queue_submenu = false; | 510 | in_queue_submenu = false; |
502 | do_menu(&tree_playlist_menu, NULL, NULL, false); | 511 | do_menu(&tree_playlist_menu, NULL, NULL, false); |
503 | } | 512 | } |
@@ -505,13 +514,13 @@ void onplay_show_playlist_menu(const char* path, int attr, void (*playlist_inser | |||
505 | /* playlist catalog options */ | 514 | /* playlist catalog options */ |
506 | static bool cat_add_to_a_playlist(void) | 515 | static bool cat_add_to_a_playlist(void) |
507 | { | 516 | { |
508 | return catalog_add_to_a_playlist(selected_file, selected_file_attr, | 517 | return catalog_add_to_a_playlist(selected_file.path, selected_file.attr, |
509 | false, NULL, ctx_add_to_playlist); | 518 | false, NULL, ctx_add_to_playlist); |
510 | } | 519 | } |
511 | 520 | ||
512 | static bool cat_add_to_a_new_playlist(void) | 521 | static bool cat_add_to_a_new_playlist(void) |
513 | { | 522 | { |
514 | return catalog_add_to_a_playlist(selected_file, selected_file_attr, | 523 | return catalog_add_to_a_playlist(selected_file.path, selected_file.attr, |
515 | true, NULL, ctx_add_to_playlist); | 524 | true, NULL, ctx_add_to_playlist); |
516 | } | 525 | } |
517 | 526 | ||
@@ -529,10 +538,8 @@ MAKE_ONPLAYMENU(cat_playlist_menu, ID2P(LANG_ADD_TO_PL), | |||
529 | 538 | ||
530 | void onplay_show_playlist_cat_menu(const char* track_name, int attr, void (*add_to_pl_cb)) | 539 | void onplay_show_playlist_cat_menu(const char* track_name, int attr, void (*add_to_pl_cb)) |
531 | { | 540 | { |
532 | context = CONTEXT_STD; | ||
533 | ctx_add_to_playlist = add_to_pl_cb; | 541 | ctx_add_to_playlist = add_to_pl_cb; |
534 | selected_file = track_name; | 542 | selected_file_set(CONTEXT_STD, track_name, attr); |
535 | selected_file_attr = attr; | ||
536 | do_menu(&cat_playlist_menu, NULL, NULL, false); | 543 | do_menu(&cat_playlist_menu, NULL, NULL, false); |
537 | } | 544 | } |
538 | 545 | ||
@@ -542,24 +549,22 @@ static int cat_playlist_callback(int action, | |||
542 | { | 549 | { |
543 | (void)this_item; | 550 | (void)this_item; |
544 | (void)this_list; | 551 | (void)this_list; |
545 | if (!selected_file || | 552 | if (!selected_file.path || |
546 | (((selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) && | 553 | (((selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) && |
547 | ((selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) && | 554 | ((selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) && |
548 | ((selected_file_attr & ATTR_DIRECTORY) == 0))) | 555 | ((selected_file.attr & ATTR_DIRECTORY) == 0))) |
549 | { | 556 | { |
550 | return ACTION_EXIT_MENUITEM; | 557 | return ACTION_EXIT_MENUITEM; |
551 | } | 558 | } |
552 | 559 | ||
553 | switch (action) | 560 | if (action == ACTION_REQUEST_MENUITEM) |
554 | { | 561 | { |
555 | case ACTION_REQUEST_MENUITEM: | 562 | if ((audio_status() & AUDIO_STATUS_PLAY) |
556 | if ((audio_status() & AUDIO_STATUS_PLAY) || context != CONTEXT_WPS) | 563 | || selected_file.context != CONTEXT_WPS) |
557 | { | 564 | { |
558 | return action; | 565 | return action; |
559 | } | 566 | } |
560 | else | 567 | return ACTION_EXIT_MENUITEM; |
561 | return ACTION_EXIT_MENUITEM; | ||
562 | break; | ||
563 | } | 568 | } |
564 | return action; | 569 | return action; |
565 | } | 570 | } |
@@ -579,13 +584,13 @@ static void splash_failed(int lang_what, int err) | |||
579 | 584 | ||
580 | static bool clipboard_cut(void) | 585 | static bool clipboard_cut(void) |
581 | { | 586 | { |
582 | return clipboard_clip(&clipboard, selected_file, selected_file_attr, | 587 | return clipboard_clip(&clipboard, selected_file.path, selected_file.attr, |
583 | PASTE_CUT); | 588 | PASTE_CUT); |
584 | } | 589 | } |
585 | 590 | ||
586 | static bool clipboard_copy(void) | 591 | static bool clipboard_copy(void) |
587 | { | 592 | { |
588 | return clipboard_clip(&clipboard, selected_file, selected_file_attr, | 593 | return clipboard_clip(&clipboard, selected_file.path, selected_file.attr, |
589 | PASTE_COPY); | 594 | PASTE_COPY); |
590 | } | 595 | } |
591 | 596 | ||
@@ -597,9 +602,6 @@ static int clipboard_paste(void) | |||
597 | 602 | ||
598 | int rc = copy_move_fileobject(clipboard.path, getcwd(NULL, 0), clipboard.flags); | 603 | int rc = copy_move_fileobject(clipboard.path, getcwd(NULL, 0), clipboard.flags); |
599 | 604 | ||
600 | |||
601 | clear_screen_buffer(true); | ||
602 | |||
603 | switch (rc) | 605 | switch (rc) |
604 | { | 606 | { |
605 | case FORC_CANCELLED: | 607 | case FORC_CANCELLED: |
@@ -643,13 +645,10 @@ static int ratingitem_callback(int action, | |||
643 | { | 645 | { |
644 | (void)this_item; | 646 | (void)this_item; |
645 | (void)this_list; | 647 | (void)this_list; |
646 | switch (action) | 648 | if (action == ACTION_REQUEST_MENUITEM) |
647 | { | 649 | { |
648 | case ACTION_REQUEST_MENUITEM: | 650 | if (!selected_file.path || !global_settings.runtimedb || !tagcache_is_usable()) |
649 | if (!selected_file || !global_settings.runtimedb || | 651 | return ACTION_EXIT_MENUITEM; |
650 | !tagcache_is_usable()) | ||
651 | return ACTION_EXIT_MENUITEM; | ||
652 | break; | ||
653 | } | 652 | } |
654 | return action; | 653 | return action; |
655 | } | 654 | } |
@@ -676,13 +675,10 @@ static int view_cue_item_callback(int action, | |||
676 | (void)this_item; | 675 | (void)this_item; |
677 | (void)this_list; | 676 | (void)this_list; |
678 | struct mp3entry* id3 = audio_current_track(); | 677 | struct mp3entry* id3 = audio_current_track(); |
679 | switch (action) | 678 | if (action == ACTION_REQUEST_MENUITEM) |
680 | { | 679 | { |
681 | case ACTION_REQUEST_MENUITEM: | 680 | if (!selected_file.path || !id3 || !id3->cuesheet) |
682 | if (!selected_file | 681 | return ACTION_EXIT_MENUITEM; |
683 | || !id3 || !id3->cuesheet) | ||
684 | return ACTION_EXIT_MENUITEM; | ||
685 | break; | ||
686 | } | 682 | } |
687 | return action; | 683 | return action; |
688 | } | 684 | } |
@@ -712,7 +708,7 @@ MENUITEM_FUNCTION(pitch_screen_item, 0, ID2P(LANG_PITCH), | |||
712 | 708 | ||
713 | static int clipboard_delete_selected_fileobject(void) | 709 | static int clipboard_delete_selected_fileobject(void) |
714 | { | 710 | { |
715 | int rc = delete_fileobject(selected_file); | 711 | int rc = delete_fileobject(selected_file.path); |
716 | if (rc < FORC_SUCCESS) { | 712 | if (rc < FORC_SUCCESS) { |
717 | splash_failed(LANG_DELETE, rc); | 713 | splash_failed(LANG_DELETE, rc); |
718 | } else if (rc == FORC_CANCELLED) { | 714 | } else if (rc == FORC_CANCELLED) { |
@@ -747,7 +743,7 @@ static int clipboard_create_dir(void) | |||
747 | 743 | ||
748 | static int clipboard_rename_selected_file(void) | 744 | static int clipboard_rename_selected_file(void) |
749 | { | 745 | { |
750 | int rc = rename_file(selected_file); | 746 | int rc = rename_file(selected_file.path); |
751 | 747 | ||
752 | show_result(rc, LANG_RENAME); | 748 | show_result(rc, LANG_RENAME); |
753 | 749 | ||
@@ -777,7 +773,7 @@ MENUITEM_FUNCTION(create_dir_item, 0, ID2P(LANG_CREATE_DIR), | |||
777 | /* other items */ | 773 | /* other items */ |
778 | static bool list_viewers(void) | 774 | static bool list_viewers(void) |
779 | { | 775 | { |
780 | int ret = filetype_list_viewers(selected_file); | 776 | int ret = filetype_list_viewers(selected_file.path); |
781 | if (ret == PLUGIN_USB_CONNECTED) | 777 | if (ret == PLUGIN_USB_CONNECTED) |
782 | onplay_result = ONPLAY_RELOAD_DIR; | 778 | onplay_result = ONPLAY_RELOAD_DIR; |
783 | return false; | 779 | return false; |
@@ -786,19 +782,19 @@ static bool list_viewers(void) | |||
786 | #ifdef HAVE_TAGCACHE | 782 | #ifdef HAVE_TAGCACHE |
787 | static bool prepare_database_sel(void *param) | 783 | static bool prepare_database_sel(void *param) |
788 | { | 784 | { |
789 | if (context == CONTEXT_ID3DB && | 785 | if (selected_file.context == CONTEXT_ID3DB && |
790 | (selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) | 786 | (selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) |
791 | { | 787 | { |
792 | if (!strcmp(param, "properties")) | 788 | if (!strcmp(param, "properties")) |
793 | strmemccpy(selected_file_path, MAKE_ACT_STR(ACTIVITY_DATABASEBROWSER), | 789 | strmemccpy(selected_file.buf, MAKE_ACT_STR(ACTIVITY_DATABASEBROWSER), |
794 | sizeof(selected_file_path)); | 790 | sizeof(selected_file.buf)); |
795 | else if (!tagtree_get_subentry_filename(selected_file_path, MAX_PATH)) | 791 | else if (!tagtree_get_subentry_filename(selected_file.buf, MAX_PATH)) |
796 | { | 792 | { |
797 | onplay_result = ONPLAY_RELOAD_DIR; | 793 | onplay_result = ONPLAY_RELOAD_DIR; |
798 | return false; | 794 | return false; |
799 | } | 795 | } |
800 | 796 | ||
801 | selected_file = selected_file_path; | 797 | selected_file.path = selected_file.buf; |
802 | } | 798 | } |
803 | return true; | 799 | return true; |
804 | } | 800 | } |
@@ -810,7 +806,7 @@ static bool onplay_load_plugin(void *param) | |||
810 | if (!prepare_database_sel(param)) | 806 | if (!prepare_database_sel(param)) |
811 | return false; | 807 | return false; |
812 | #endif | 808 | #endif |
813 | int ret = filetype_load_plugin((const char*)param, selected_file); | 809 | int ret = filetype_load_plugin((const char*)param, selected_file.path); |
814 | if (ret == PLUGIN_USB_CONNECTED) | 810 | if (ret == PLUGIN_USB_CONNECTED) |
815 | onplay_result = ONPLAY_RELOAD_DIR; | 811 | onplay_result = ONPLAY_RELOAD_DIR; |
816 | else if (ret == PLUGIN_GOTO_PLUGIN) | 812 | else if (ret == PLUGIN_GOTO_PLUGIN) |
@@ -835,7 +831,7 @@ MENUITEM_FUNCTION_W_PARAM(pictureflow_item, 0, ID2P(LANG_ONPLAY_PICTUREFLOW), | |||
835 | #endif | 831 | #endif |
836 | static bool onplay_add_to_shortcuts(void) | 832 | static bool onplay_add_to_shortcuts(void) |
837 | { | 833 | { |
838 | shortcuts_add(SHORTCUT_BROWSER, selected_file); | 834 | shortcuts_add(SHORTCUT_BROWSER, selected_file.path); |
839 | return false; | 835 | return false; |
840 | } | 836 | } |
841 | MENUITEM_FUNCTION(add_to_faves_item, 0, ID2P(LANG_ADD_TO_FAVES), | 837 | MENUITEM_FUNCTION(add_to_faves_item, 0, ID2P(LANG_ADD_TO_FAVES), |
@@ -844,7 +840,7 @@ MENUITEM_FUNCTION(add_to_faves_item, 0, ID2P(LANG_ADD_TO_FAVES), | |||
844 | 840 | ||
845 | static void set_dir_helper(char* dirnamebuf, size_t bufsz) | 841 | static void set_dir_helper(char* dirnamebuf, size_t bufsz) |
846 | { | 842 | { |
847 | path_append(dirnamebuf, selected_file, PA_SEP_HARD, bufsz); | 843 | path_append(dirnamebuf, selected_file.path, PA_SEP_HARD, bufsz); |
848 | settings_save(); | 844 | settings_save(); |
849 | } | 845 | } |
850 | 846 | ||
@@ -882,7 +878,7 @@ MENUITEM_FUNCTION(set_startdir_item, 0, ID2P(LANG_START_DIR), | |||
882 | 878 | ||
883 | static bool set_catalogdir(void) | 879 | static bool set_catalogdir(void) |
884 | { | 880 | { |
885 | catalog_set_directory(selected_file); | 881 | catalog_set_directory(selected_file.path); |
886 | settings_save(); | 882 | settings_save(); |
887 | return false; | 883 | return false; |
888 | } | 884 | } |
@@ -893,7 +889,7 @@ MENUITEM_FUNCTION(set_catalogdir_item, 0, ID2P(LANG_PLAYLIST_DIR), | |||
893 | static bool set_databasedir(void) | 889 | static bool set_databasedir(void) |
894 | { | 890 | { |
895 | struct tagcache_stat *tc_stat = tagcache_get_stat(); | 891 | struct tagcache_stat *tc_stat = tagcache_get_stat(); |
896 | if (strcasecmp(selected_file, tc_stat->db_path)) | 892 | if (strcasecmp(selected_file.path, tc_stat->db_path)) |
897 | { | 893 | { |
898 | splash(HZ, ID2P(LANG_PLEASE_REBOOT)); | 894 | splash(HZ, ID2P(LANG_PLEASE_REBOOT)); |
899 | } | 895 | } |
@@ -927,7 +923,7 @@ static int clipboard_callback(int action, | |||
927 | case ACTION_REQUEST_MENUITEM: | 923 | case ACTION_REQUEST_MENUITEM: |
928 | #ifdef HAVE_MULTIVOLUME | 924 | #ifdef HAVE_MULTIVOLUME |
929 | /* no rename+delete for volumes */ | 925 | /* no rename+delete for volumes */ |
930 | if ((selected_file_attr & ATTR_VOLUME) && | 926 | if ((selected_file.attr & ATTR_VOLUME) && |
931 | (this_item == &rename_file_item || | 927 | (this_item == &rename_file_item || |
932 | this_item == &delete_dir_item || | 928 | this_item == &delete_dir_item || |
933 | this_item == &clipboard_cut_item || | 929 | this_item == &clipboard_cut_item || |
@@ -935,7 +931,7 @@ static int clipboard_callback(int action, | |||
935 | return ACTION_EXIT_MENUITEM; | 931 | return ACTION_EXIT_MENUITEM; |
936 | #endif | 932 | #endif |
937 | #ifdef HAVE_TAGCACHE | 933 | #ifdef HAVE_TAGCACHE |
938 | if (context == CONTEXT_ID3DB) | 934 | if (selected_file.context == CONTEXT_ID3DB) |
939 | { | 935 | { |
940 | if (this_item == &track_info_item || | 936 | if (this_item == &track_info_item || |
941 | this_item == &pictureflow_item) | 937 | this_item == &pictureflow_item) |
@@ -953,21 +949,21 @@ static int clipboard_callback(int action, | |||
953 | { | 949 | { |
954 | return action; | 950 | return action; |
955 | } | 951 | } |
956 | else if (selected_file) | 952 | else if (selected_file.path) |
957 | { | 953 | { |
958 | /* requires an actual file */ | 954 | /* requires an actual file */ |
959 | if (this_item == &rename_file_item || | 955 | if (this_item == &rename_file_item || |
960 | this_item == &clipboard_cut_item || | 956 | this_item == &clipboard_cut_item || |
961 | this_item == &clipboard_copy_item || | 957 | this_item == &clipboard_copy_item || |
962 | (this_item == &track_info_item && | 958 | (this_item == &track_info_item && |
963 | (selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) || | 959 | (selected_file.attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) || |
964 | (this_item == &properties_item && | 960 | (this_item == &properties_item && |
965 | (selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) || | 961 | (selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) || |
966 | this_item == &add_to_faves_item) | 962 | this_item == &add_to_faves_item) |
967 | { | 963 | { |
968 | return action; | 964 | return action; |
969 | } | 965 | } |
970 | else if ((selected_file_attr & ATTR_DIRECTORY)) | 966 | else if ((selected_file.attr & ATTR_DIRECTORY)) |
971 | { | 967 | { |
972 | /* only for directories */ | 968 | /* only for directories */ |
973 | if (this_item == &delete_dir_item || | 969 | if (this_item == &delete_dir_item || |
@@ -992,7 +988,7 @@ static int clipboard_callback(int action, | |||
992 | #if LCD_DEPTH > 1 | 988 | #if LCD_DEPTH > 1 |
993 | else if (this_item == &set_backdrop_item) | 989 | else if (this_item == &set_backdrop_item) |
994 | { | 990 | { |
995 | char *suffix = strrchr(selected_file, '.'); | 991 | char *suffix = strrchr(selected_file.path, '.'); |
996 | if (suffix) | 992 | if (suffix) |
997 | { | 993 | { |
998 | if (strcasecmp(suffix, ".bmp") == 0) | 994 | if (strcasecmp(suffix, ".bmp") == 0) |
@@ -1066,8 +1062,8 @@ static int onplaymenu_callback(int action, | |||
1066 | case ACTION_REQUEST_MENUITEM: | 1062 | case ACTION_REQUEST_MENUITEM: |
1067 | if (this_item == &view_playlist_item) | 1063 | if (this_item == &view_playlist_item) |
1068 | { | 1064 | { |
1069 | if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U && | 1065 | if ((selected_file.attr & FILE_ATTR_MASK) == FILE_ATTR_M3U && |
1070 | context == CONTEXT_TREE) | 1066 | selected_file.context == CONTEXT_TREE) |
1071 | return action; | 1067 | return action; |
1072 | } | 1068 | } |
1073 | return ACTION_EXIT_MENUITEM; | 1069 | return ACTION_EXIT_MENUITEM; |
@@ -1075,6 +1071,8 @@ static int onplaymenu_callback(int action, | |||
1075 | case ACTION_EXIT_MENUITEM: | 1071 | case ACTION_EXIT_MENUITEM: |
1076 | return ACTION_EXIT_AFTER_THIS_MENUITEM; | 1072 | return ACTION_EXIT_AFTER_THIS_MENUITEM; |
1077 | break; | 1073 | break; |
1074 | default: | ||
1075 | break; | ||
1078 | } | 1076 | } |
1079 | return action; | 1077 | return action; |
1080 | } | 1078 | } |
@@ -1085,13 +1083,13 @@ static bool hotkey_delete_item(void) | |||
1085 | { | 1083 | { |
1086 | #ifdef HAVE_MULTIVOLUME | 1084 | #ifdef HAVE_MULTIVOLUME |
1087 | /* no delete for volumes */ | 1085 | /* no delete for volumes */ |
1088 | if (selected_file_attr & ATTR_VOLUME) | 1086 | if (selected_file.attr & ATTR_VOLUME) |
1089 | return false; | 1087 | return false; |
1090 | #endif | 1088 | #endif |
1091 | 1089 | ||
1092 | #ifdef HAVE_TAGCACHE | 1090 | #ifdef HAVE_TAGCACHE |
1093 | if (context == CONTEXT_ID3DB && | 1091 | if (selected_file.context == CONTEXT_ID3DB && |
1094 | (selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) | 1092 | (selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) |
1095 | return false; | 1093 | return false; |
1096 | #endif | 1094 | #endif |
1097 | 1095 | ||
@@ -1101,10 +1099,10 @@ static bool hotkey_delete_item(void) | |||
1101 | static bool hotkey_open_with(void) | 1099 | static bool hotkey_open_with(void) |
1102 | { | 1100 | { |
1103 | /* only open files */ | 1101 | /* only open files */ |
1104 | if (selected_file_attr & ATTR_DIRECTORY) | 1102 | if (selected_file.attr & ATTR_DIRECTORY) |
1105 | return false; | 1103 | return false; |
1106 | #ifdef HAVE_MULTIVOLUME | 1104 | #ifdef HAVE_MULTIVOLUME |
1107 | if (selected_file_attr & ATTR_VOLUME) | 1105 | if (selected_file.attr & ATTR_VOLUME) |
1108 | return false; | 1106 | return false; |
1109 | #endif | 1107 | #endif |
1110 | return list_viewers(); | 1108 | return list_viewers(); |
@@ -1113,8 +1111,8 @@ static bool hotkey_open_with(void) | |||
1113 | static int hotkey_tree_pl_insert_shuffled(void) | 1111 | static int hotkey_tree_pl_insert_shuffled(void) |
1114 | { | 1112 | { |
1115 | if ((audio_status() & AUDIO_STATUS_PLAY) || | 1113 | if ((audio_status() & AUDIO_STATUS_PLAY) || |
1116 | (selected_file_attr & ATTR_DIRECTORY) || | 1114 | (selected_file.attr & ATTR_DIRECTORY) || |
1117 | ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U)) | 1115 | ((selected_file.attr & FILE_ATTR_MASK) == FILE_ATTR_M3U)) |
1118 | { | 1116 | { |
1119 | add_to_playlist(&addtopl_insert_shuf); | 1117 | add_to_playlist(&addtopl_insert_shuf); |
1120 | } | 1118 | } |
@@ -1127,7 +1125,7 @@ static int hotkey_tree_run_plugin(void *param) | |||
1127 | if (!prepare_database_sel(param)) | 1125 | if (!prepare_database_sel(param)) |
1128 | return ONPLAY_RELOAD_DIR; | 1126 | return ONPLAY_RELOAD_DIR; |
1129 | #endif | 1127 | #endif |
1130 | if (filetype_load_plugin((const char*)param, selected_file) == PLUGIN_GOTO_WPS) | 1128 | if (filetype_load_plugin((const char*)param, selected_file.path) == PLUGIN_GOTO_WPS) |
1131 | return ONPLAY_START_PLAY; | 1129 | return ONPLAY_START_PLAY; |
1132 | 1130 | ||
1133 | return ONPLAY_RELOAD_DIR; | 1131 | return ONPLAY_RELOAD_DIR; |
@@ -1253,15 +1251,15 @@ static int execute_hotkey(bool is_wps) | |||
1253 | } | 1251 | } |
1254 | #endif /* HOTKEY */ | 1252 | #endif /* HOTKEY */ |
1255 | 1253 | ||
1256 | int onplay(char* file, int attr, int from, bool hotkey) | 1254 | int onplay(char* file, int attr, int from_context, bool hotkey) |
1257 | { | 1255 | { |
1258 | const struct menu_item_ex *menu; | 1256 | const struct menu_item_ex *menu; |
1259 | onplay_result = ONPLAY_OK; | 1257 | onplay_result = ONPLAY_OK; |
1260 | context = from; | ||
1261 | ctx_current_playlist_insert = NULL; | 1258 | ctx_current_playlist_insert = NULL; |
1262 | selected_file = NULL; | 1259 | selected_file_set(from_context, NULL, attr); |
1260 | |||
1263 | #ifdef HAVE_TAGCACHE | 1261 | #ifdef HAVE_TAGCACHE |
1264 | if (context == CONTEXT_ID3DB && | 1262 | if (from_context == CONTEXT_ID3DB && |
1265 | (attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) | 1263 | (attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) |
1266 | { | 1264 | { |
1267 | ctx_add_to_playlist = tagtree_add_to_playlist; | 1265 | ctx_add_to_playlist = tagtree_add_to_playlist; |
@@ -1269,8 +1267,8 @@ int onplay(char* file, int attr, int from, bool hotkey) | |||
1269 | { | 1267 | { |
1270 | /* add a leading slash so that catalog_add_to_a_playlist | 1268 | /* add a leading slash so that catalog_add_to_a_playlist |
1271 | later prefills the name when creating a new playlist */ | 1269 | later prefills the name when creating a new playlist */ |
1272 | snprintf(selected_file_path, MAX_PATH, "/%s", file); | 1270 | snprintf(selected_file.buf, MAX_PATH, "/%s", file); |
1273 | selected_file = selected_file_path; | 1271 | selected_file.path = selected_file.buf; |
1274 | } | 1272 | } |
1275 | } | 1273 | } |
1276 | else | 1274 | else |
@@ -1279,22 +1277,22 @@ int onplay(char* file, int attr, int from, bool hotkey) | |||
1279 | ctx_add_to_playlist = NULL; | 1277 | ctx_add_to_playlist = NULL; |
1280 | if (file != NULL) | 1278 | if (file != NULL) |
1281 | { | 1279 | { |
1282 | strmemccpy(selected_file_path, file, MAX_PATH); | 1280 | strmemccpy(selected_file.buf, file, MAX_PATH); |
1283 | selected_file = selected_file_path; | 1281 | selected_file.path = selected_file.buf; |
1284 | } | 1282 | } |
1285 | 1283 | ||
1286 | } | 1284 | } |
1287 | selected_file_attr = attr; | ||
1288 | int menu_selection; | 1285 | int menu_selection; |
1286 | |||
1289 | #ifdef HAVE_HOTKEY | 1287 | #ifdef HAVE_HOTKEY |
1290 | if (hotkey) | 1288 | if (hotkey) |
1291 | return execute_hotkey(context == CONTEXT_WPS); | 1289 | return execute_hotkey(from_context == CONTEXT_WPS); |
1292 | #else | 1290 | #else |
1293 | (void)hotkey; | 1291 | (void)hotkey; |
1294 | #endif | 1292 | #endif |
1295 | 1293 | ||
1296 | push_current_activity(ACTIVITY_CONTEXTMENU); | 1294 | push_current_activity(ACTIVITY_CONTEXTMENU); |
1297 | if (context == CONTEXT_WPS) | 1295 | if (from_context == CONTEXT_WPS) |
1298 | menu = &wps_onplay_menu; | 1296 | menu = &wps_onplay_menu; |
1299 | else | 1297 | else |
1300 | menu = &tree_onplay_menu; | 1298 | menu = &tree_onplay_menu; |
@@ -1303,23 +1301,22 @@ int onplay(char* file, int attr, int from, bool hotkey) | |||
1303 | if (get_current_activity() == ACTIVITY_CONTEXTMENU) /* Activity may have been */ | 1301 | if (get_current_activity() == ACTIVITY_CONTEXTMENU) /* Activity may have been */ |
1304 | pop_current_activity(); /* popped already by menu item */ | 1302 | pop_current_activity(); /* popped already by menu item */ |
1305 | 1303 | ||
1306 | switch (menu_selection) | 1304 | |
1307 | { | 1305 | if (menu_selection == GO_TO_WPS) |
1308 | case GO_TO_WPS: | 1306 | return ONPLAY_START_PLAY; |
1309 | return ONPLAY_START_PLAY; | 1307 | if (menu_selection == GO_TO_ROOT) |
1310 | case GO_TO_ROOT: | 1308 | return ONPLAY_MAINMENU; |
1311 | case GO_TO_MAINMENU: | 1309 | if (menu_selection == GO_TO_MAINMENU) |
1312 | return ONPLAY_MAINMENU; | 1310 | return ONPLAY_MAINMENU; |
1313 | case GO_TO_PLAYLIST_VIEWER: | 1311 | if (menu_selection == GO_TO_PLAYLIST_VIEWER) |
1314 | return ONPLAY_PLAYLIST; | 1312 | return ONPLAY_PLAYLIST; |
1315 | case GO_TO_PLUGIN: | 1313 | if (menu_selection == GO_TO_PLUGIN) |
1316 | return ONPLAY_PLUGIN; | 1314 | return ONPLAY_PLUGIN; |
1317 | default: | 1315 | |
1318 | return onplay_result; | 1316 | return onplay_result; |
1319 | } | ||
1320 | } | 1317 | } |
1321 | 1318 | ||
1322 | int get_onplay_context(void) | 1319 | int get_onplay_context(void) |
1323 | { | 1320 | { |
1324 | return context; | 1321 | return selected_file.context; |
1325 | } | 1322 | } |
diff --git a/apps/onplay.h b/apps/onplay.h index ea1c2e6c38..74dc045db3 100644 --- a/apps/onplay.h +++ b/apps/onplay.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "menu.h" | 25 | #include "menu.h" |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | int onplay(char* file, int attr, int from_screen, bool hotkey); | 28 | int onplay(char* file, int attr, int from_context, bool hotkey); |
29 | int get_onplay_context(void); | 29 | int get_onplay_context(void); |
30 | 30 | ||
31 | enum { | 31 | enum { |