This source file includes following definitions.
- free_list
- add_item
- fselect_sort
- sort_list
- chk_ext
- chk_prefix
- chk_name
- is_parent
- is_current
- is_raw
- is_jpg
- delete_file
- delete_dir
- opendir_fselect
- copy_file
- fs_readdir
- process_dir
- fselect_goto_prev
- fselect_goto_next
- gui_fselect_free_data
- gui_fselect_read_dir
- gui_fselect_find_start_dir
- gui_fselect_init
- gui_fselect_draw
- fselect_delete_file_cb
- find_jpg
- purge_file
- purge_file_DCIM
- fselect_purge_cb_DCIM
- fselect_purge_cb_dir
- fselect_purge_cb_file
- fselect_delete_folder_cb
- confirm_delete_directory
- fselect_marked_toggle
- gui_fselect_marked_free_data
- fselect_marked_copy_list
- fselect_marked_paste_cb
- fselect_real_marked_count
- fselect_marked_count
- fselect_marked_delete_cb
- fselect_chdk_replace_cb
- fselect_marked_inverse_selection
- process_raw_files
- fselect_subtract_cb
- setup_batch_subtract
- process_dng_to_raw_files
- fselect_mpopup_rawop_cb
- mkdir_cb
- rename_cb
- isPurgeDCIM
- isPurgeDir
- fselect_mpopup_cb
- finalize_fselect
- exit_fselect
- gui_fselect_kbd_process
- gui_fselect_kbd_process_menu_btn
- _module_unloader
- _module_can_unload
- _module_exit_alt
1 #include "camera_info.h"
2 #include "keyboard.h"
3 #include "modes.h"
4 #include "sd_card.h"
5 #include "debug_led.h"
6 #include "lang.h"
7 #include "gui.h"
8 #include "gui_draw.h"
9 #include "gui_lang.h"
10 #include "gui_mbox.h"
11 #include "raw.h"
12 #include "conf.h"
13 #include "time.h"
14 #include "dirent.h"
15 #include "ctype.h"
16
17 #include "gui_fselect.h"
18 #include "raw_merge.h"
19 #include "dng.h"
20 #include "gui_mpopup.h"
21 #include "gui_tbox.h"
22 #include "gui_read.h"
23
24 #include "module_load.h"
25
26
27
28
29
30 int gui_fselect_kbd_process();
31 void gui_fselect_kbd_process_menu_btn();
32 void gui_fselect_draw(int enforce_redraw);
33
34 gui_handler GUI_MODE_FSELECT_MODULE =
35 { GUI_MODE_FSELECT, gui_fselect_draw, gui_fselect_kbd_process, gui_fselect_kbd_process_menu_btn, 0, 0 };
36
37
38 #define BODY_LINES 12
39 #define BODY_FONT_LINES BODY_LINES * FONT_HEIGHT
40
41 #define NAME_SIZE camera_screen.fselect_name_size
42 #define SIZE_SIZE camera_screen.fselect_size_size
43 #define TIME_SIZE camera_screen.fselect_time_size
44
45 #define NAME_FONT_SIZE NAME_SIZE * FONT_WIDTH
46 #define EXTE_FONT_SIZE EXTE_SIZE * FONT_WIDTH
47 #define SIZE_FONT_SIZE SIZE_SIZE * FONT_WIDTH
48 #define TIME_FONT_SIZE TIME_SIZE * FONT_WIDTH
49
50 #define SPACING 4
51 #define TAB_DIVIDER 1
52 #define BORDER 2
53 #define SCROLLBAR 4
54
55 #define MARKED_OP_NONE 0
56 #define MARKED_OP_CUT 1
57 #define MARKED_OP_COPY 2
58
59
60
61 static int running = 0;
62 static gui_handler *gui_fselect_mode_old;
63
64 #define MAX_PATH_LEN 100
65
66
67 static char selected_file[MAX_PATH_LEN];
68 static char buf[MAX_PATH_LEN];
69
70
71 typedef struct _fitem
72 {
73 struct _fitem *prev, *next;
74 unsigned long size;
75 unsigned long mtime;
76 unsigned short n;
77 unsigned char marked;
78 unsigned char isdir;
79 unsigned char isparent;
80 unsigned char isvalid;
81 char name[1];
82
83
84 } fitem;
85
86
87 typedef struct
88 {
89 fitem *head;
90 fitem *tail;
91 unsigned short count;
92 char dir[MAX_PATH_LEN];
93 } flist;
94
95 static flist items;
96 static flist marked_items;
97
98 static fitem *top;
99 static fitem *selected;
100
101 static char marked_operation;
102
103 #define MAIN_H (FONT_HEIGHT + TAB_DIVIDER + BODY_FONT_LINES + TAB_DIVIDER + FONT_HEIGHT)
104
105 static coord main_x, main_y, main_w;
106 static coord body_y;
107 static coord foot_y;
108
109 static int gui_fselect_redraw;
110 static int gui_fselect_readdir;
111 static char *fselect_title;
112
113 static void (*fselect_on_select)(const char *fn);
114 static char raw_operation;
115
116
117 #define MPOPUP_CUT 0x0001
118 #define MPOPUP_COPY 0x0002
119 #define MPOPUP_PASTE 0x0004
120 #define MPOPUP_DELETE 0x0008
121 #define MPOPUP_SELINV 0x0010
122 #define MPOPUP_RAWOPS 0x0020
123 #define MPOPUP_PURGE_DCIM 0x0040
124 #define MPOPUP_PURGE_DIR 0x0080
125 #define MPOPUP_PURGE_FILE 0x0100
126 #define MPOPUP_RMDIR 0x0200
127 #define MPOPUP_MKDIR 0x0400
128 #define MPOPUP_RENAME 0x0800
129 #define MPOPUP_EDITOR 0x1000
130 #define MPOPUP_CHDK_REPLACE 0x2000
131
132 static struct mpopup_item popup[]= {
133 { MPOPUP_CUT, LANG_POPUP_CUT },
134 { MPOPUP_COPY, LANG_POPUP_COPY },
135 { MPOPUP_PASTE, LANG_POPUP_PASTE },
136 { MPOPUP_DELETE, LANG_POPUP_DELETE },
137 { MPOPUP_RMDIR, LANG_POPUP_RMDIR },
138 { MPOPUP_PURGE_DCIM, LANG_POPUP_PURGE },
139 { MPOPUP_PURGE_DIR, LANG_POPUP_PURGE },
140 { MPOPUP_PURGE_FILE, LANG_POPUP_PURGE },
141 { MPOPUP_MKDIR, LANG_POPUP_MKDIR },
142 { MPOPUP_RENAME, LANG_POPUP_RENAME },
143 { MPOPUP_SELINV, LANG_POPUP_SELINV },
144 { MPOPUP_EDITOR, (int)"Edit" },
145 { MPOPUP_CHDK_REPLACE, (int)"Set this CHDK" },
146 { MPOPUP_RAWOPS, (int)"Raw ops ->" },
147 { 0, 0 },
148 };
149
150 #define MPOPUP_RAW_ADD 0x0020
151 #define MPOPUP_RAW_AVERAGE 0x0040
152 #define MPOPUP_SUBTRACT 0x0100
153 #define MPOPUP_RAW_DEVELOP 0x0200
154 #define MPOPUP_DNG_TO_CRW 0x0400
155
156 static struct mpopup_item popup_rawop[]= {
157 { MPOPUP_RAW_ADD, LANG_POPUP_RAW_SUM},
158 { MPOPUP_RAW_AVERAGE, LANG_POPUP_RAW_AVERAGE },
159 { MPOPUP_RAW_DEVELOP, LANG_MENU_RAW_DEVELOP },
160 { MPOPUP_SUBTRACT, LANG_POPUP_SUB_FROM_MARKED },
161 { MPOPUP_DNG_TO_CRW, (int)"DNG -> CHDK RAW"},
162 { 0, 0 },
163 };
164
165
166
167
168 static void free_list(flist *list)
169 {
170 fitem *ptr = list->head;
171
172 while (ptr)
173 {
174 fitem *prev = ptr;
175 ptr = ptr->next;
176 free(prev);
177 }
178
179 list->head = list->tail = 0;
180 list->count = 0;
181 }
182
183 static void add_item(flist *list, const char *name,
184 unsigned long size, unsigned long mtime,
185 unsigned char marked, unsigned char isdir, unsigned char isparent, unsigned char isvalid)
186 {
187 fitem *p = malloc(sizeof(fitem) + strlen(name));
188 if (p)
189 {
190 p->n = list->count;
191 strcpy(p->name, name);
192 p->size = size;
193 p->mtime = mtime;
194 p->marked = marked;
195 p->isdir = isdir;
196 p->isparent = isparent;
197 p->isvalid = isvalid;
198
199 p->next = 0;
200 p->prev = list->tail;
201 if (list->tail)
202 list->tail->next = p;
203 list->tail = p;
204 if (list->head == 0)
205 list->head = p;
206
207 list->count++;
208 }
209 }
210
211 int fselect_sort(const void* v1, const void* v2)
212 {
213 fitem *i1 = *((fitem **)v1);
214 fitem *i2 = *((fitem **)v2);
215
216 if (i1->isdir)
217 {
218 if (i2->isdir)
219 {
220 if (i1->isparent)
221 {
222 return -1;
223 }
224 else if (i2->isparent)
225 {
226 return 1;
227 }
228 else
229 {
230 return strcmp(i1->name, i2->name);
231 }
232 }
233 else
234 {
235 return -1;
236 }
237 }
238 else
239 {
240 if (i2->isdir)
241 {
242 return 1;
243 }
244 else
245 {
246 return strcmp(i1->name, i2->name);
247 }
248 }
249 }
250
251 static void sort_list(flist *list)
252 {
253 if (list->count)
254 {
255
256 fitem **sbuf = malloc(list->count*sizeof(fitem*));
257 if (sbuf)
258 {
259 fitem *ptr = list->head;
260 int i = 0;
261 while (ptr)
262 {
263 sbuf[i++] = ptr;
264 ptr = ptr->next;
265 }
266
267 extern int fselect_sort_nothumb(const void* v1, const void* v2);
268 qsort(sbuf, list->count, sizeof(fitem*), fselect_sort_nothumb);
269
270 list->head = sbuf[0];
271 list->tail = sbuf[list->count-1];
272 for (i=0; i<list->count-1; i++)
273 {
274 sbuf[i]->n = i;
275 sbuf[i]->next = sbuf[i+1];
276 sbuf[i+1]->prev = sbuf[i];
277 }
278 list->head->prev = 0;
279 list->tail->next = 0;
280 list->tail->n = list->count - 1;
281
282 free(sbuf);
283 }
284 }
285 }
286
287
288
289
290
291 static int chk_ext(const char *ext, const char *tst)
292 {
293 if (ext && (*ext != '.'))
294 ext = strrchr(ext, '.');
295 if (ext)
296 {
297 ext++;
298 if (strlen(ext) == strlen(tst))
299 {
300 int i;
301 for (i=0; i<strlen(tst); i++)
302 if (toupper(ext[i]) != toupper(tst[i]))
303 return 0;
304 return 1;
305 }
306 }
307 return 0;
308 }
309
310
311 static int chk_prefix(const char *name, const char *prefix)
312 {
313 if (name && (strlen(name) >= strlen(prefix)))
314 {
315 int i;
316 for (i=0; i<strlen(prefix); i++)
317 if (toupper(prefix[i]) != toupper(name[i]))
318 return 0;
319 return 1;
320 }
321 return 0;
322 }
323
324
325 static int chk_name(const char *name, const char *tst)
326 {
327 if (name && (strlen(name) == strlen(tst)))
328 {
329 int i;
330 for (i=0; i<strlen(tst); i++)
331 if (toupper(tst[i]) != toupper(name[i]))
332 return 0;
333 return 1;
334 }
335 return 0;
336 }
337
338
339 static int is_parent(const char *name) { return (strcmp(name, "..") == 0); }
340 static int is_current(const char *name) { return (strcmp(name, ".") == 0); }
341
342
343 static int is_raw(const char *name)
344 {
345 return ((chk_prefix(name,"crw_") || (chk_prefix(name,"img_")))) &&
346 ((chk_ext(name,"cr2") || (chk_ext(name,"crw") || (chk_ext(name,"dng")))));
347 }
348
349
350 static int is_jpg(const char *name)
351 {
352 return (chk_prefix(name,"img_")) && (chk_ext(name,"jpg"));
353 }
354
355
356
357
358 static void delete_file(const char *path, const char *name)
359 {
360 sprintf(selected_file, "%s/%s", path, name);
361 remove(selected_file);
362 }
363
364 static void delete_dir(const char *path)
365 {
366 remove(path);
367 }
368
369
370 static DIR * opendir_fselect(const char *path) {
371 return opendir_chdk(path,(conf.disable_lfn_parser_ui?OPENDIR_FL_NONE:OPENDIR_FL_CHDK_LFN));
372 }
373
374
375
376 static unsigned char *ubuf = 0;
377 #define COPY_BUF_SIZE 16384
378
379 static int copy_file(const char *src_dir, const char *src_file, const char *dst_dir, const char *dst_file, int overwrite)
380 {
381 int rv = 0;
382
383
384 if (chk_name(src_dir, dst_dir) && chk_name(src_file, dst_file))
385 return 0;
386
387
388 sprintf(selected_file, "%s/%s", src_dir, src_file);
389 int fsrc = open(selected_file, O_RDONLY, 0777);
390
391 if (fsrc >= 0)
392 {
393
394 sprintf(selected_file,"%s/%s", dst_dir, dst_file);
395 if (!overwrite)
396 {
397 struct stat st;
398 if (stat(selected_file, &st) == 0)
399 {
400 close(fsrc);
401
402 return 0;
403 }
404 }
405 int fdst = open(selected_file, O_WRONLY|O_CREAT|O_TRUNC, 0777);
406
407 if (fdst >= 0)
408 {
409 int ss, sd = 0;
410
411
412 if (ubuf == 0)
413 {
414 ubuf = umalloc(COPY_BUF_SIZE);
415 if (ubuf == 0)
416 {
417
418 close(fdst);
419 close(fsrc);
420 return 0;
421 }
422 }
423
424
425 do
426 {
427 ss = read(fsrc, ubuf, COPY_BUF_SIZE);
428 if (ss > 0)
429 sd = write(fdst, ubuf, ss);
430 } while (ss > 0 && ss == sd);
431
432 if (ss == 0)
433 rv = 1;
434
435 close(fdst);
436
437 struct utimbuf t;
438 t.actime = t.modtime = selected->mtime;
439 utime(selected_file, &t);
440 }
441
442 close(fsrc);
443 }
444
445 return rv;
446 }
447
448
449
450 typedef struct
451 {
452 struct dirent *de;
453 unsigned long size;
454 unsigned long mtime;
455 unsigned char deleted;
456 unsigned char isdir;
457 unsigned char isparent;
458 unsigned char iscurrent;
459 unsigned char isvalid;
460 unsigned char ishidden;
461 } fs_dirent;
462
463
464
465
466 static int fs_readdir(DIR *d, fs_dirent *de, const char* path)
467 {
468
469
470 char pbuf[MAX_PATH_LEN];
471
472 de->de = readdir(d);
473 de->size = 0;
474 de->mtime = 0;
475 de->deleted = 0;
476 de->isparent = 0;
477 de->iscurrent = 0;
478 de->isdir = 0;
479 de->isvalid = 0;
480 de->ishidden = 0;
481
482 if (de->de)
483 {
484 if (de->de->d_name[0] == 0xE5)
485 {
486 de->deleted = 1;
487 }
488 else
489 {
490 de->isparent = is_parent(de->de->d_name);
491 de->iscurrent = is_current(de->de->d_name);
492
493 sprintf(pbuf, "%s/%s", path, de->de->d_name);
494 struct stat st;
495 if (de->isparent || de->iscurrent)
496 {
497 de->isdir = 1;
498 de->isvalid = 1;
499 }
500 else if (stat(pbuf, &st) == 0)
501 {
502 de->size = st.st_size;
503 de->mtime = st.st_mtime;
504 de->isvalid = 1;
505 de->isdir = ((st.st_attrib & DOS_ATTR_DIRECTORY) != 0);
506 de->ishidden = ((st.st_attrib & DOS_ATTR_HIDDEN) != 0);
507 }
508 }
509
510 return 1;
511 }
512
513 return 0;
514 }
515
516
517
518
519
520 static void process_dir(const char *parent, const char *name, int nested, void (*file_process)(const char *path, const char *file), void (*dir_process)(const char *path))
521 {
522 DIR *d;
523 fs_dirent de;
524
525
526 char *path;
527 if (name)
528 {
529 path = malloc(strlen(parent) + strlen(name) + 2);
530 sprintf(path, "%s/%s", parent, name);
531 }
532 else
533 {
534 path = (char*)parent;
535 }
536
537
538 d = opendir_fselect(path);
539
540 if (d)
541 {
542
543 while (fs_readdir(d, &de, path))
544 {
545 if (!de.deleted)
546 {
547
548 if (de.isdir)
549 {
550 if (!de.isparent && !de.iscurrent && nested)
551 process_dir(path, de.de->d_name, nested-1, file_process, dir_process);
552 }
553 else if (file_process)
554 {
555 file_process(path, de.de->d_name);
556 }
557 }
558 }
559 closedir(d);
560
561 if (dir_process)
562 dir_process(path);
563 }
564
565 if (name)
566 free(path);
567 }
568
569
570 static void fselect_goto_prev(int step)
571 {
572 int j;
573
574 for (j=0; j<step; ++j)
575 {
576 if (selected->prev)
577 {
578 selected = selected->prev;
579 if (selected == top && top->prev)
580 top = top->prev;
581 }
582 else if (step == 1)
583 {
584
585 selected = top = items.tail;
586 while (((selected->n - top->n) < (BODY_LINES - 1)) && top->prev)
587 top = top->prev;
588 }
589 }
590 }
591
592
593 static void fselect_goto_next(int step)
594 {
595 int j;
596 for (j=0; j<step; ++j)
597 {
598 if (selected->next)
599 {
600 selected = selected->next;
601 if (((selected->n - top->n) == (BODY_LINES - 1)) && selected->next)
602 top = top->next;
603 }
604 else if (step == 1)
605 {
606 selected = top = items.head;
607 }
608 }
609 }
610
611
612 static void gui_fselect_free_data()
613 {
614 free_list(&items);
615 top = selected = NULL;
616 }
617
618
619 static void gui_fselect_read_dir()
620 {
621 DIR *d;
622 fs_dirent de;
623 int fndParent = 0;
624
625 gui_fselect_free_data();
626
627 if ((items.dir[0] == 'A') && (items.dir[1] == 0))
628 d = opendir_fselect("A/");
629 else
630 d = opendir_fselect(items.dir);
631
632 if (d)
633 {
634 while (fs_readdir(d, &de, items.dir))
635 {
636 if (!de.deleted && !de.iscurrent && (conf.show_hiddenfiles || !de.ishidden))
637 {
638 add_item(&items, de.de->d_name, de.size, de.mtime, 0, de.isdir, de.isparent, de.isvalid);
639 if (de.isparent)
640 fndParent = 1;
641 }
642 }
643 closedir(d);
644 }
645
646
647 if ((strlen(items.dir) > 2) && !fndParent)
648 {
649 add_item(&items, "..", 0, 0, 0, 1, 1, 1);
650 }
651
652 sort_list(&items);
653
654 top = selected = items.head;
655 }
656
657
658
659
660
661 int gui_fselect_find_start_dir(const char* dir)
662 {
663 selected_file[0] = 0;
664 strcpy(items.dir, dir);
665
666
667 while (strlen(items.dir) > 0)
668 {
669
670 char *p = strrchr(items.dir,'/');
671
672 struct stat st;
673
674 if (stat(items.dir,&st) == 0)
675 {
676
677 if ((st.st_attrib & DOS_ATTR_DIRECTORY) == 0)
678 {
679
680 strcpy(selected_file, p+1);
681 *p = 0;
682 }
683 return 1;
684 }
685 else
686 {
687
688 if (p)
689 *p = 0;
690 else
691 return 0;
692 }
693 }
694
695 return 0;
696 }
697
698
699 void gui_fselect_init(int title, const char* prev_dir, const char* default_dir, void (*on_select)(const char *fn))
700 {
701 running = 1;
702
703 main_w = SPACING + NAME_FONT_SIZE + FONT_WIDTH + SIZE_FONT_SIZE + FONT_WIDTH + TIME_FONT_SIZE + SPACING + SCROLLBAR;
704 main_x = (camera_screen.width - main_w) >> 1;
705 main_y = (camera_screen.height - MAIN_H) >> 1;
706
707 body_y = main_y + FONT_HEIGHT + TAB_DIVIDER;
708 foot_y = body_y + BODY_FONT_LINES + TAB_DIVIDER;
709
710 fselect_title = lang_str(title);
711
712
713 if (!gui_fselect_find_start_dir(prev_dir))
714 if (!gui_fselect_find_start_dir(default_dir))
715 gui_fselect_find_start_dir("A");
716
717 gui_fselect_read_dir();
718
719
720 if (selected_file[0])
721 {
722 fitem *p = items.head;
723 while (p)
724 {
725 if (chk_name(p->name,selected_file))
726 {
727 break;
728 }
729 p = p->next;
730 fselect_goto_next(1);
731 }
732 if (!p) selected_file[0] = 0;
733 }
734
735 fselect_on_select = on_select;
736 marked_operation = MARKED_OP_NONE;
737 gui_fselect_redraw = 2;
738 gui_fselect_readdir = 0;
739 gui_fselect_mode_old = gui_set_mode(&GUI_MODE_FSELECT_MODULE);
740 }
741
742
743 void gui_fselect_draw(int enforce_redraw)
744 {
745 int i, j;
746 twoColors cl_marked;
747
748 if (gui_fselect_readdir)
749 {
750 gui_fselect_readdir = 0;
751 gui_fselect_read_dir();
752 }
753
754 if (enforce_redraw)
755 gui_fselect_redraw = 2;
756
757 if (gui_fselect_redraw)
758 {
759 char dbuf[46];
760
761 if (gui_fselect_redraw == 2)
762 {
763
764 draw_string_justified(main_x, main_y, fselect_title, MAKE_COLOR(COLOR_BLACK, COLOR_WHITE), 0, main_w, TEXT_CENTER|TEXT_FILL);
765
766 draw_rectangle(main_x-BORDER, main_y-BORDER, main_x+main_w+BORDER-1, main_y+MAIN_H+BORDER-1, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE), RECT_BORDER2);
767 draw_line(main_x, body_y-1, main_x+main_w-1, body_y-1, COLOR_WHITE);
768 draw_line(main_x, foot_y-1, main_x+main_w-1, foot_y-1, COLOR_WHITE);
769 }
770
771 int off_body_y = body_y;
772
773 fitem *ptr;
774 unsigned long sum_size = 0;
775 for (i=0, ptr=top; i<BODY_LINES && ptr; ++i, ptr=ptr->next, off_body_y += FONT_HEIGHT)
776 {
777 cl_marked = MAKE_COLOR((ptr==selected)?COLOR_RED:COLOR_GREY, (ptr->marked)?COLOR_YELLOW:COLOR_WHITE);
778
779
780 j = strlen(ptr->name);
781 strncpy(dbuf, ptr->name, NAME_SIZE);
782 if (j > NAME_SIZE)
783 dbuf[NAME_SIZE-1] = '~';
784
785 if (ptr->isdir && ptr->isvalid)
786 {
787 if (j < NAME_SIZE)
788 {
789 dbuf[j++] = '/';
790 }
791 else
792 {
793 dbuf[NAME_SIZE-2] = '~';
794 dbuf[NAME_SIZE-1] = '/';
795 }
796 }
797 for (; j < NAME_SIZE; j++)
798 dbuf[j] = ' ';
799 j = NAME_SIZE;
800 dbuf[j++] = 0x06;
801
802
803 if (ptr->isdir)
804 {
805 if (!ptr->isvalid)
806 {
807 sprintf(dbuf+j, " ??? ");
808 }
809 else if (ptr->isparent)
810 {
811 sprintf(dbuf+j, " <Up> ");
812 }
813 else
814 {
815 sprintf(dbuf+j, " <Dir>");
816 }
817 }
818 else
819 {
820 unsigned long n = ptr->size;
821
822 if (ptr->marked)
823 sum_size += n;
824
825 if (n < 1024)
826 sprintf(dbuf+j, "%5db", n);
827 else
828 {
829 static char* suffixes = "kMG";
830 int sfx = 0;
831 if (n >= 4294967245ul)
832 {
833 sfx = 2;
834 n = 4096;
835 }
836 else
837 {
838
839 n += 51;
840
841 while (n >= 1024*1024)
842 {
843 n >>= 10;
844 n += 51;
845 sfx += 1;
846 }
847 }
848 unsigned long f = ((n & 0x3FF) * 10) >> 10;
849 sprintf(dbuf+j, "%3d.%1d%c", n >> 10, f, suffixes[sfx]);
850 }
851 }
852 j += SIZE_SIZE;
853 dbuf[j++] = 0x06;
854
855
856 if (ptr->mtime)
857 {
858 struct tm *time = localtime(&(ptr->mtime));
859 sprintf(dbuf+j, "%02u.%02u'%02u %02u:%02u", time->tm_mday, time->tm_mon+1, (time->tm_year<100)?time->tm_year:time->tm_year-100, time->tm_hour, time->tm_min);
860 }
861 else
862 {
863 sprintf(dbuf+j, "%14s", "");
864 }
865 j += TIME_SIZE;
866 dbuf[j] = 0;
867
868 draw_string_justified(main_x, off_body_y, dbuf, cl_marked, SPACING, main_w-SCROLLBAR, TEXT_LEFT|TEXT_FILL);
869 }
870
871
872 if (i>0 && i<BODY_LINES)
873 {
874 draw_rectangle(main_x, off_body_y, main_x+main_w-SCROLLBAR-1, body_y+BODY_FONT_LINES-1, MAKE_COLOR(COLOR_GREY, COLOR_GREY), RECT_BORDER0|DRAW_FILLED);
875 }
876
877
878 int off_sbar_x = main_x + main_w - SCROLLBAR;
879 draw_rectangle(off_sbar_x, body_y, off_sbar_x+SCROLLBAR-1, body_y+BODY_FONT_LINES-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED);
880 if (items.count > BODY_LINES)
881 {
882 i = BODY_FONT_LINES - 1;
883 j = (i * BODY_LINES) / items.count;
884 if (j < 20) j = 20;
885 i = ((i - j) * selected->n) / (items.count-1);
886 draw_rectangle(off_sbar_x, body_y+i, off_sbar_x+SCROLLBAR-2, body_y+i+j, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE), RECT_BORDER0|DRAW_FILLED);
887 }
888
889
890 int max_footer_len = NAME_SIZE + SIZE_SIZE + SPACING;
891 i = strlen(items.dir);
892 if (i > max_footer_len)
893 {
894 strncpy(dbuf, items.dir+i-max_footer_len, max_footer_len);
895 dbuf[0] = '.';
896 dbuf[1] = '.';
897 }
898 else
899 {
900 strcpy(dbuf, items.dir);
901 }
902 draw_string_justified(main_x, foot_y, dbuf, MAKE_COLOR(COLOR_GREY, COLOR_WHITE), SPACING, main_w, TEXT_LEFT|TEXT_FILL);
903
904 if (sum_size)
905 {
906 sprintf(dbuf, "%d b", sum_size);
907 }
908 else
909 {
910 unsigned int fr = GetFreeCardSpaceKb();
911 unsigned int tot = GetTotalCardSpaceKb();
912 if (tot != 0)
913 tot = (fr * 100) / tot;
914
915 if (fr < 1024*1024)
916 sprintf(dbuf, "%dM (%d%%)", fr>>10, tot);
917 else
918 sprintf(dbuf, "%d.%dG (%d%%)", fr>>20, ((fr&0x000FFFFF)*100)>>20, tot);
919 }
920 draw_string(main_x+main_w-strlen(dbuf)*FONT_WIDTH-BORDER, foot_y, dbuf, MAKE_COLOR(COLOR_GREY, COLOR_WHITE));
921
922 gui_fselect_redraw = 0;
923 }
924 }
925
926
927 static void fselect_delete_file_cb(unsigned int btn)
928 {
929 if (btn==MBOX_BTN_YES)
930 {
931 started();
932 delete_file(items.dir, selected->name);
933 finished();
934 gui_fselect_readdir = 1;
935 }
936 gui_fselect_redraw = 2;
937 }
938
939
940
941
942 static int find_jpg(const char *folder, const char *match, int nested)
943 {
944 DIR *d;
945 fs_dirent de;
946 int rv = 0;
947
948
949 d = opendir_fselect(folder);
950
951 if (d)
952 {
953
954 while (fs_readdir(d, &de, folder) && !rv)
955 {
956 if (!de.deleted)
957 {
958
959 if (de.isdir)
960 {
961 if (!de.isparent && !de.iscurrent && nested)
962 {
963
964 char *path = malloc(strlen(folder) + strlen(de.de->d_name) + 2);
965 sprintf(path, "%s/%s", folder, de.de->d_name);
966 if (find_jpg(path, match, nested-1))
967 rv = 1;
968 free(path);
969 }
970 }
971 else
972 {
973
974 if (is_jpg(de.de->d_name) && (strncmp(match+4, de.de->d_name+4, 4) == 0))
975 rv = 1;
976 }
977 }
978 }
979 closedir(d);
980 }
981
982 return rv;
983 }
984
985
986
987 static void purge_file(const char *folder, const char *file)
988 {
989
990 if (is_raw(file))
991 if (!find_jpg(folder, file, 0))
992 delete_file(folder, file);
993 }
994
995
996
997
998
999 static void purge_file_DCIM(const char *folder, const char *file)
1000 {
1001
1002 if (is_raw(file))
1003 if (!find_jpg("A/DCIM", file, 1))
1004 delete_file(folder, file);
1005 }
1006
1007 static void fselect_purge_cb_DCIM(unsigned int btn)
1008 {
1009 if (btn == MBOX_BTN_YES)
1010 {
1011
1012 process_dir(items.dir, selected->name, 1, purge_file_DCIM, 0);
1013 }
1014 }
1015
1016 static void fselect_purge_cb_dir(unsigned int btn)
1017 {
1018 if (btn == MBOX_BTN_YES)
1019 {
1020
1021 process_dir(items.dir, selected->name, 0, purge_file, 0);
1022 }
1023 }
1024
1025 static void fselect_purge_cb_file(unsigned int btn)
1026 {
1027 if (btn == MBOX_BTN_YES)
1028 {
1029
1030 fitem *ptr, *ptr2;
1031
1032
1033 for (ptr=items.head; ptr; ptr=ptr->next)
1034 {
1035
1036 if (is_raw(ptr->name) && !ptr->marked)
1037 {
1038
1039 int found = 0;
1040
1041
1042 for (ptr2=items.head; ptr2; ptr2=ptr2->next)
1043 {
1044
1045 if (is_jpg(ptr2->name) && (strncmp(ptr->name+4, ptr2->name+4, 4) == 0))
1046 {
1047 found=1;
1048 break;
1049 }
1050 }
1051
1052
1053 if (found == 0)
1054 delete_file(items.dir, ptr->name);
1055 }
1056 }
1057 gui_fselect_readdir = 1;
1058 }
1059 gui_fselect_redraw = 2;
1060 }
1061
1062
1063
1064 static void fselect_delete_folder_cb(unsigned int btn)
1065 {
1066 if (btn==MBOX_BTN_YES)
1067 {
1068 process_dir(items.dir, selected->name, 999, delete_file, delete_dir);
1069 gui_fselect_readdir = 1;
1070 }
1071 gui_fselect_redraw = 2;
1072 }
1073
1074 static void confirm_delete_directory()
1075 {
1076 if (selected->isdir && !selected->isparent)
1077 gui_mbox_init(LANG_BROWSER_ERASE_DIR_TITLE, LANG_BROWSER_ERASE_DIR_TEXT,
1078 MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_delete_folder_cb);
1079 }
1080
1081
1082 static void fselect_marked_toggle()
1083 {
1084 if (selected && selected->isvalid && !selected->isdir)
1085 {
1086 selected->marked = !selected->marked;
1087 }
1088 }
1089
1090
1091 static void gui_fselect_marked_free_data()
1092 {
1093 free_list(&marked_items);
1094 marked_operation = MARKED_OP_NONE;
1095 }
1096
1097
1098 static void fselect_marked_copy_list()
1099 {
1100 gui_fselect_marked_free_data();
1101
1102 fitem *ptr;
1103
1104 for (ptr=items.head; ptr; ptr=ptr->next)
1105 if (ptr->marked)
1106 add_item(&marked_items, ptr->name, ptr->size, ptr->mtime, 1, ptr->isdir, ptr->isparent, ptr->isvalid);
1107
1108 if (!marked_items.count)
1109 if (selected && selected->isvalid && !selected->isdir)
1110 add_item(&marked_items, selected->name, selected->size, selected->mtime, 1, selected->isdir, selected->isparent, selected->isvalid);
1111
1112 strcpy(marked_items.dir, items.dir);
1113 }
1114
1115
1116 static void fselect_marked_paste_cb(unsigned int btn)
1117 {
1118 fitem *ptr;
1119 int i = 0;
1120
1121 if (btn != MBOX_BTN_YES) return;
1122
1123 if (strcmp(marked_items.dir, items.dir) != 0)
1124 {
1125 for (ptr=marked_items.head; ptr; ptr=ptr->next)
1126 {
1127 if (ptr->isvalid && !ptr->isdir)
1128 {
1129 started();
1130
1131 ++i;
1132 if (marked_items.count)
1133 gui_browser_progress_show(lang_str(LANG_FSELECT_PROGRESS_TITLE),i*100/marked_items.count);
1134
1135 int copied = copy_file(marked_items.dir, ptr->name, items.dir, ptr->name, 0);
1136
1137 if (copied && (marked_operation == MARKED_OP_CUT))
1138 {
1139 delete_file(marked_items.dir, ptr->name);
1140 }
1141
1142 finished();
1143 }
1144 }
1145 if (marked_operation == MARKED_OP_CUT)
1146 {
1147 gui_fselect_marked_free_data();
1148 }
1149 gui_fselect_readdir = 1;
1150 }
1151 gui_fselect_redraw = 2;
1152 }
1153
1154
1155 static inline unsigned int fselect_real_marked_count()
1156 {
1157 fitem *ptr;
1158 register unsigned int cnt = 0;
1159
1160 for (ptr=items.head; ptr; ptr=ptr->next)
1161 {
1162 if (ptr->isvalid && !ptr->isdir && ptr->marked)
1163 ++cnt;
1164 }
1165 return cnt;
1166 }
1167
1168
1169 static unsigned int fselect_marked_count()
1170 {
1171 register unsigned int cnt = fselect_real_marked_count();
1172
1173 if (!cnt)
1174 {
1175 if (selected && selected->isvalid && !selected->isdir)
1176 ++cnt;
1177 }
1178
1179 return cnt;
1180 }
1181
1182
1183 static void fselect_marked_delete_cb(unsigned int btn)
1184 {
1185 fitem *ptr;
1186 unsigned int del_cnt=0, cnt;
1187
1188 if (btn != MBOX_BTN_YES) return;
1189
1190 cnt = fselect_marked_count();
1191 for (ptr=items.head; ptr; ptr=ptr->next)
1192 if (ptr->marked && ptr->isvalid && !ptr->isdir)
1193 {
1194 started();
1195 ++del_cnt;
1196 if (cnt)
1197 gui_browser_progress_show(lang_str(LANG_FSELECT_PROGRESS_TITLE),del_cnt*100/cnt);
1198 delete_file(items.dir, ptr->name);
1199 finished();
1200 }
1201
1202 if (del_cnt == 0 && selected)
1203 {
1204 started();
1205 delete_file(items.dir, selected->name);
1206 finished();
1207 }
1208 gui_fselect_readdir = 1;
1209 gui_fselect_redraw = 2;
1210 }
1211
1212
1213 static void fselect_chdk_replace_cb(unsigned int btn)
1214 {
1215 if (btn == MBOX_BTN_YES)
1216 {
1217 copy_file(items.dir, selected->name, "A", "DISKBOOT.BIN", 1);
1218 gui_browser_progress_show("Please reboot",100);
1219 }
1220 }
1221
1222
1223 static void fselect_marked_inverse_selection()
1224 {
1225 fitem *ptr;
1226
1227 for (ptr=items.head; ptr; ptr=ptr->next)
1228 if (ptr->isvalid && !ptr->isdir)
1229 ptr->marked = !ptr->marked;
1230
1231 gui_fselect_redraw = 2;
1232 }
1233
1234
1235 void process_raw_files(void)
1236 {
1237 fitem *ptr;
1238
1239 if ((fselect_marked_count()>1) && librawop->raw_merge_start(raw_operation))
1240 {
1241 for (ptr=items.head; ptr; ptr=ptr->next)
1242 if (ptr->marked && ptr->isvalid && !ptr->isdir)
1243 {
1244 sprintf(selected_file, "%s/%s", items.dir, ptr->name);
1245 librawop->raw_merge_add_file(selected_file);
1246 }
1247 librawop->raw_merge_end();
1248 gui_fselect_readdir = 1;
1249 gui_fselect_redraw = 2;
1250 }
1251 }
1252
1253 static void fselect_subtract_cb(unsigned int btn)
1254 {
1255 fitem *ptr;
1256 if (btn != MBOX_BTN_YES) return;
1257
1258 for (ptr=items.head; ptr; ptr=ptr->next)
1259 {
1260 if (ptr->marked && ptr->isvalid && !ptr->isdir && chk_name(ptr->name,selected->name))
1261 {
1262 librawop->raw_subtract(ptr->name, items.dir, selected->name, items.dir);
1263 }
1264 }
1265 gui_fselect_readdir = 1;
1266 gui_fselect_redraw = 2;
1267 }
1268
1269 #define MAX_SUB_NAMES 6
1270 static void setup_batch_subtract(void)
1271 {
1272 fitem *ptr;
1273 int i;
1274 char *p = buf + sprintf(buf,"%s %s\n",selected->name,lang_str(LANG_FSELECT_SUB_FROM));
1275 for (ptr=items.head, i=0; ptr; ptr=ptr->next)
1276 {
1277 if (ptr->marked && ptr->isvalid && !ptr->isdir && (ptr->size >= camera_sensor.raw_size))
1278 {
1279 if ( i < MAX_SUB_NAMES )
1280 {
1281 sprintf(p, "%s\n",ptr->name);
1282
1283 if (i < MAX_SUB_NAMES - 1)
1284 {
1285 p += strlen(p);
1286 }
1287 }
1288 i++;
1289 }
1290 }
1291 if (i > MAX_SUB_NAMES)
1292 {
1293
1294 sprintf(p,lang_str(LANG_FSELECT_SUB_AND_MORE),i - (MAX_SUB_NAMES - 1));
1295 }
1296 gui_mbox_init(LANG_FSELECT_SUBTRACT, (int)buf,
1297 MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_subtract_cb);
1298 }
1299
1300 void process_dng_to_raw_files(void)
1301 {
1302 fitem *ptr;
1303 int i=0;
1304 started();
1305 msleep(100);
1306 finished();
1307
1308 if (fselect_real_marked_count())
1309 {
1310 for (ptr=items.head; ptr; ptr=ptr->next)
1311 if (ptr->marked && ptr->isvalid && !ptr->isdir)
1312 {
1313 sprintf(selected_file, "%s/%s", items.dir, ptr->name);
1314 gui_browser_progress_show(selected_file, (i++)*100/fselect_real_marked_count()) ;
1315 libdng->convert_dng_to_chdk_raw(selected_file);
1316 }
1317 }
1318 else
1319 {
1320 sprintf(selected_file, "%s/%s", items.dir, selected->name);
1321 libdng->convert_dng_to_chdk_raw(selected_file);
1322 }
1323 gui_fselect_readdir = 1;
1324 }
1325
1326 static void fselect_mpopup_rawop_cb(unsigned int actn)
1327 {
1328 switch (actn) {
1329 case MPOPUP_RAW_AVERAGE:
1330 raw_operation=RAW_OPERATION_AVERAGE;
1331 process_raw_files();
1332 break;
1333 case MPOPUP_RAW_ADD:
1334 raw_operation=RAW_OPERATION_SUM;
1335 process_raw_files();
1336 break;
1337 case MPOPUP_RAW_DEVELOP:
1338 sprintf(buf, "%s/%s", items.dir, selected->name);
1339 raw_prepare_develop(buf, 1);
1340 break;
1341 case MPOPUP_SUBTRACT:
1342 setup_batch_subtract();
1343 break;
1344 case MPOPUP_DNG_TO_CRW:
1345 process_dng_to_raw_files();
1346 break;
1347 }
1348 }
1349
1350 static void mkdir_cb(const char* name)
1351 {
1352 if (name)
1353 {
1354 sprintf(selected_file,"%s/%s", items.dir, name);
1355 mkdir(selected_file);
1356 gui_fselect_readdir = 1;
1357 gui_fselect_redraw = 2;
1358 }
1359 }
1360
1361 static void rename_cb(const char* name)
1362 {
1363 if (name)
1364 {
1365 sprintf(selected_file, "%s/%s", items.dir, selected->name);
1366 sprintf(buf, "%s/%s", items.dir, name);
1367 rename(selected_file, buf);
1368 gui_fselect_readdir = 1;
1369 gui_fselect_redraw = 2;
1370 }
1371 }
1372
1373 static int mpopup_rawop_flag;
1374
1375
1376
1377 static int isPurgeDCIM()
1378 {
1379 return (chk_name(items.dir, "A") && (chk_name(selected->name, "DCIM") || chk_name(selected->name, "RAW")));
1380 }
1381
1382
1383 static int isPurgeDir()
1384 {
1385 return (selected->isdir && !selected->isparent && ((chk_name(items.dir, "A/DCIM")) || (chk_name(items.dir, "A/RAW"))));
1386 }
1387
1388 static void fselect_mpopup_cb(unsigned int actn)
1389 {
1390 switch (actn)
1391 {
1392 case MPOPUP_CUT:
1393 fselect_marked_copy_list();
1394 marked_operation = MARKED_OP_CUT;
1395 break;
1396 case MPOPUP_COPY:
1397 fselect_marked_copy_list();
1398 marked_operation = MARKED_OP_COPY;
1399 break;
1400 case MPOPUP_PASTE:
1401 sprintf(buf, lang_str((marked_operation == MARKED_OP_CUT)?LANG_FSELECT_CUT_TEXT:LANG_FSELECT_COPY_TEXT), marked_items.count, marked_items.dir);
1402 gui_mbox_init((marked_operation == MARKED_OP_CUT)?LANG_FSELECT_CUT_TITLE:LANG_FSELECT_COPY_TITLE,
1403 (int)buf, MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_marked_paste_cb);
1404 break;
1405 case MPOPUP_DELETE:
1406 sprintf(buf, lang_str(LANG_FSELECT_DELETE_TEXT), fselect_marked_count());
1407 gui_mbox_init(LANG_FSELECT_DELETE_TITLE, (int)buf,
1408 MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_marked_delete_cb);
1409 break;
1410 case MPOPUP_RMDIR:
1411 confirm_delete_directory();
1412 break;
1413 case MPOPUP_MKDIR:
1414 libtextbox->textbox_init(LANG_POPUP_MKDIR, LANG_PROMPT_MKDIR, "", 15, mkdir_cb, 0);
1415 break;
1416 case MPOPUP_RENAME:
1417 libtextbox->textbox_init(LANG_POPUP_RENAME, LANG_PROMPT_RENAME, selected->name, 15, rename_cb, 0);
1418 break;
1419 case MPOPUP_PURGE_DCIM:
1420
1421 gui_mbox_init(LANG_FSELECT_PURGE_TITLE, LANG_FSELECT_PURGE_DCIM_TEXT, MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_purge_cb_DCIM);
1422 break;
1423 case MPOPUP_PURGE_DIR:
1424
1425 gui_mbox_init(LANG_FSELECT_PURGE_TITLE, LANG_FSELECT_PURGE_CANON_FOLDER_TEXT, MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_purge_cb_dir);
1426 break;
1427 case MPOPUP_PURGE_FILE:
1428
1429 gui_mbox_init(LANG_FSELECT_PURGE_TITLE, LANG_FSELECT_PURGE_LIST_TEXT, MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_purge_cb_file);
1430 break;
1431 case MPOPUP_SELINV:
1432 fselect_marked_inverse_selection();
1433 break;
1434 case MPOPUP_CANCEL:
1435 break;
1436
1437 case MPOPUP_RAWOPS:
1438 libmpopup->show_popup( popup_rawop, mpopup_rawop_flag, fselect_mpopup_rawop_cb);
1439 break;
1440
1441 case MPOPUP_CHDK_REPLACE:
1442 gui_mbox_init((int)"Replacing CHDK", (int)"Do you want to replace current CHDK with this file",
1443 MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_chdk_replace_cb);
1444 break;
1445 case MPOPUP_EDITOR:
1446 gui_mbox_init((int)"Editor", (int)"edit", MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1447 break;
1448 }
1449 gui_fselect_redraw = 2;
1450 }
1451
1452
1453 void finalize_fselect()
1454 {
1455 gui_fselect_free_data();
1456 gui_fselect_marked_free_data();
1457 }
1458
1459 static void exit_fselect(char* file)
1460 {
1461 finalize_fselect();
1462
1463 gui_set_mode(gui_fselect_mode_old);
1464
1465
1466 if (fselect_on_select)
1467 {
1468 fselect_on_select(file);
1469
1470 gui_fselect_redraw = 2;
1471 }
1472
1473 running = 0;
1474 }
1475
1476
1477 int gui_fselect_kbd_process()
1478 {
1479 int i;
1480 int do_exit = 0;
1481
1482 switch (kbd_get_autoclicked_key() | get_jogdial_direction())
1483 {
1484 case JOGDIAL_LEFT:
1485 case KEY_UP:
1486 if (selected)
1487 {
1488 if (camera_info.state.is_shutter_half_press) fselect_goto_prev(4);
1489 else fselect_goto_prev(1);
1490 gui_fselect_redraw = 1;
1491 }
1492 break;
1493 case KEY_DOWN:
1494 case JOGDIAL_RIGHT:
1495 if (selected)
1496 {
1497 if (camera_info.state.is_shutter_half_press) fselect_goto_next(4);
1498 else fselect_goto_next(1);
1499 gui_fselect_redraw = 1;
1500 }
1501 break;
1502 case KEY_ZOOM_OUT:
1503 if (selected)
1504 {
1505 fselect_goto_prev(BODY_LINES-1);
1506 gui_fselect_redraw = 1;
1507 }
1508 break;
1509 case KEY_ZOOM_IN:
1510 if (selected)
1511 {
1512 fselect_goto_next(BODY_LINES-1);
1513 gui_fselect_redraw = 1;
1514 }
1515 break;
1516 case KEY_RIGHT:
1517 if (selected)
1518 {
1519 fselect_marked_toggle();
1520 fselect_goto_next(1);
1521 gui_fselect_redraw = 1;
1522 }
1523 break;
1524 case KEY_LEFT:
1525 if (selected && selected->isvalid)
1526 {
1527 int marked_count = fselect_marked_count();
1528
1529 i = MPOPUP_SELINV|MPOPUP_MKDIR;
1530 mpopup_rawop_flag = 0;
1531
1532 if (marked_count > 0)
1533 {
1534 i |= MPOPUP_CUT|MPOPUP_COPY|MPOPUP_DELETE;
1535 if (marked_count > 1)
1536 mpopup_rawop_flag |= MPOPUP_RAW_ADD|MPOPUP_RAW_AVERAGE;
1537
1538 if (selected->marked == 0 && fselect_real_marked_count() > 0)
1539 mpopup_rawop_flag |= MPOPUP_SUBTRACT;
1540 }
1541
1542 if (marked_operation != MARKED_OP_NONE)
1543 i |= MPOPUP_PASTE;
1544
1545
1546 if (isPurgeDCIM())
1547 i |= MPOPUP_PURGE_DCIM;
1548 if (isPurgeDir())
1549 i |= MPOPUP_PURGE_DIR;
1550 if (is_raw(selected->name))
1551 i |= MPOPUP_PURGE_FILE;
1552
1553 if (selected->isdir && !selected->isparent)
1554 i |= MPOPUP_RMDIR;
1555
1556 if (!selected->isparent)
1557 i |= MPOPUP_RENAME;
1558
1559 if (selected->size >= camera_sensor.raw_size)
1560 mpopup_rawop_flag |= MPOPUP_RAW_DEVELOP;
1561
1562 if ((marked_count > 1) || (selected->size > camera_sensor.raw_size))
1563 mpopup_rawop_flag |= MPOPUP_DNG_TO_CRW;
1564
1565 if (chk_ext(selected->name, "bin"))
1566 i |= MPOPUP_CHDK_REPLACE;
1567
1568 if (mpopup_rawop_flag)
1569 i |= MPOPUP_RAWOPS;
1570
1571 libmpopup->show_popup( popup, i, fselect_mpopup_cb);
1572 }
1573 break;
1574 case KEY_SET:
1575 if (selected && selected->isvalid && gui_fselect_redraw==0)
1576 {
1577 if (selected->isdir)
1578 {
1579 if (selected->isparent)
1580 {
1581 char *s = strrchr(items.dir, '/');
1582 if (s) *s = 0;
1583 }
1584 else
1585 {
1586 sprintf(items.dir+strlen(items.dir), "/%s", selected->name);
1587 }
1588 gui_fselect_readdir = 1;
1589 gui_fselect_redraw = 1;
1590 }
1591 else
1592 {
1593 sprintf(selected_file, "%s/%s", items.dir, selected->name);
1594
1595 char *ext = strrchr(selected->name,'.');
1596 do_exit = 1;
1597
1598 if (!fselect_on_select)
1599 {
1600 if (chk_ext(ext,"txt") || chk_ext(ext,"log") || chk_ext(ext,"csv"))
1601 {
1602 fselect_on_select = (void (*)(const char*))libtxtread->read_file;
1603 }
1604 else if (chk_ext(ext,"flt"))
1605 {
1606 fselect_on_select = (void (*)(const char*))module_run;
1607 }
1608 }
1609 }
1610 }
1611 break;
1612 case KEY_ERASE:
1613 case KEY_DISPLAY:
1614 if (selected && selected->isvalid)
1615 {
1616 if (selected->isdir)
1617 {
1618 confirm_delete_directory();
1619 } else
1620 {
1621 gui_mbox_init(LANG_BROWSER_DELETE_FILE_TITLE, LANG_BROWSER_DELETE_FILE_TEXT,
1622 MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_delete_file_cb);
1623 }
1624 }
1625 break;
1626 }
1627
1628 if (do_exit)
1629 exit_fselect(selected_file);
1630
1631 return 0;
1632 }
1633
1634 void gui_fselect_kbd_process_menu_btn()
1635 {
1636
1637 exit_fselect(0);
1638 }
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650 int _module_unloader()
1651 {
1652
1653 if (ubuf)
1654 {
1655 ufree(ubuf);
1656 ubuf = 0;
1657 }
1658 finalize_fselect();
1659 return 0;
1660 }
1661
1662 int _module_can_unload()
1663 {
1664 return running == 0;
1665 }
1666
1667 int _module_exit_alt()
1668 {
1669 exit_fselect(0);
1670 return 0;
1671 }
1672
1673
1674
1675 libfselect_sym _libfselect =
1676 {
1677 {
1678 0, _module_unloader, _module_can_unload, _module_exit_alt, 0
1679 },
1680
1681 gui_fselect_init
1682 };
1683
1684 ModuleInfo _module_info = {
1685 MODULEINFO_V1_MAGICNUM,
1686 sizeof(ModuleInfo),
1687 GUI_FSELECT_VERSION,
1688
1689 ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,
1690 ANY_PLATFORM_ALLOWED,
1691
1692 -LANG_MENU_MISC_FILE_BROWSER,
1693 MTYPE_EXTENSION,
1694
1695 &_libfselect.base,
1696
1697 CONF_VERSION,
1698 CAM_SCREEN_VERSION,
1699 CAM_SENSOR_VERSION,
1700 CAM_INFO_VERSION,
1701
1702 0,
1703 };
1704
1705