| 1 | #include "stdlib.h" |
|---|
| 2 | #include "keyboard.h" |
|---|
| 3 | #include "platform.h" |
|---|
| 4 | #include "core.h" |
|---|
| 5 | #include "lang.h" |
|---|
| 6 | #include "gui.h" |
|---|
| 7 | #include "gui_draw.h" |
|---|
| 8 | #include "gui_lang.h" |
|---|
| 9 | #include "gui_mbox.h" |
|---|
| 10 | #include "gui_mpopup.h" |
|---|
| 11 | #include "gui_fselect.h" |
|---|
| 12 | #include "raw_merge.h" |
|---|
| 13 | |
|---|
| 14 | //------------------------------------------------------------------- |
|---|
| 15 | #define NUM_LINES 7 |
|---|
| 16 | #define NAME_SIZE 15 |
|---|
| 17 | #define SIZE_SIZE 7 |
|---|
| 18 | #define TIME_SIZE 14 |
|---|
| 19 | #define SPACING 1 |
|---|
| 20 | |
|---|
| 21 | #define MARKED_OP_NONE 0 |
|---|
| 22 | #define MARKED_OP_CUT 1 |
|---|
| 23 | #define MARKED_OP_COPY 2 |
|---|
| 24 | #define MARKED_BUF_SIZE 0x10000 |
|---|
| 25 | |
|---|
| 26 | //------------------------------------------------------------------- |
|---|
| 27 | static char current_dir[100], selected_file[100]; |
|---|
| 28 | static char buf[100]; |
|---|
| 29 | static char marked_dir[100]; |
|---|
| 30 | static enum Gui_Mode gui_fselect_mode_old; |
|---|
| 31 | struct fitem { |
|---|
| 32 | unsigned int n; |
|---|
| 33 | char *name; |
|---|
| 34 | unsigned char attr; |
|---|
| 35 | unsigned long size; |
|---|
| 36 | unsigned long mtime; |
|---|
| 37 | unsigned char marked; |
|---|
| 38 | struct fitem *prev, *next; |
|---|
| 39 | }; |
|---|
| 40 | static struct fitem *head=NULL, *top, *selected; |
|---|
| 41 | static unsigned int count; |
|---|
| 42 | static struct fitem *marked_head=NULL; |
|---|
| 43 | static unsigned int marked_count; |
|---|
| 44 | static char marked_operation; |
|---|
| 45 | static coord x, y, w, h; |
|---|
| 46 | static int gui_fselect_redraw; |
|---|
| 47 | static char *fselect_title; |
|---|
| 48 | static void (*fselect_on_select)(const char *fn); |
|---|
| 49 | static char raw_operation; |
|---|
| 50 | |
|---|
| 51 | //------------------------------------------------------------------- |
|---|
| 52 | static void gui_fselect_free_data() { |
|---|
| 53 | struct fitem *ptr = head, *prev; |
|---|
| 54 | |
|---|
| 55 | while (ptr) { |
|---|
| 56 | if (ptr->name) |
|---|
| 57 | free(ptr->name); |
|---|
| 58 | prev=ptr; |
|---|
| 59 | ptr=ptr->next; |
|---|
| 60 | free(prev); |
|---|
| 61 | } |
|---|
| 62 | head=top=selected=NULL; |
|---|
| 63 | count=0; |
|---|
| 64 | } |
|---|
| 65 | |
|---|
| 66 | //------------------------------------------------------------------- |
|---|
| 67 | extern int fselect_sort_nothumb(const void* v1, const void* v2); |
|---|
| 68 | int fselect_sort(const void* v1, const void* v2) { |
|---|
| 69 | struct fitem *i1=*((struct fitem **)v1), *i2=*((struct fitem **)v2); |
|---|
| 70 | |
|---|
| 71 | if (i1->attr & DOS_ATTR_DIRECTORY) { |
|---|
| 72 | if (i2->attr & DOS_ATTR_DIRECTORY) { |
|---|
| 73 | if (i1->name[0]=='.' && i1->name[1]=='.' && i1->name[2]==0) { |
|---|
| 74 | return -1; |
|---|
| 75 | } else if (i2->name[0]=='.' && i2->name[1]=='.' && i2->name[2]==0) { |
|---|
| 76 | return 1; |
|---|
| 77 | } else { |
|---|
| 78 | return strcmp(i1->name, i2->name); |
|---|
| 79 | } |
|---|
| 80 | } else { |
|---|
| 81 | return -1; |
|---|
| 82 | } |
|---|
| 83 | } else { |
|---|
| 84 | if (i2->attr & DOS_ATTR_DIRECTORY) { |
|---|
| 85 | return 1; |
|---|
| 86 | } else { |
|---|
| 87 | return strcmp(i1->name, i2->name); |
|---|
| 88 | } |
|---|
| 89 | } |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | //------------------------------------------------------------------- |
|---|
| 93 | static void gui_fselect_read_dir(const char* dir) { |
|---|
| 94 | DIR *d; |
|---|
| 95 | struct dirent *de; |
|---|
| 96 | static struct stat st; |
|---|
| 97 | struct fitem **ptr = &head, *prev = NULL; |
|---|
| 98 | int i; |
|---|
| 99 | |
|---|
| 100 | gui_fselect_free_data(); |
|---|
| 101 | |
|---|
| 102 | d = opendir(dir); |
|---|
| 103 | if (d) { |
|---|
| 104 | de = readdir(d); |
|---|
| 105 | while (de) { |
|---|
| 106 | if (de->name[0] != 0xE5 /* deleted entry */ && (de->name[0]!='.' || de->name[1]!=0)) { |
|---|
| 107 | *ptr = malloc(sizeof(struct fitem)); |
|---|
| 108 | if (*ptr) { |
|---|
| 109 | (*ptr)->n = count; |
|---|
| 110 | (*ptr)->name = malloc(strlen(de->name)+1); |
|---|
| 111 | if ((*ptr)->name) |
|---|
| 112 | strcpy((*ptr)->name, de->name); |
|---|
| 113 | sprintf(buf, "%s/%s", dir, de->name); |
|---|
| 114 | if (stat(buf, &st)==0) { |
|---|
| 115 | (*ptr)->attr=st.st_attrib; |
|---|
| 116 | (*ptr)->size=st.st_size; |
|---|
| 117 | (*ptr)->mtime=st.st_mtime; |
|---|
| 118 | } else { |
|---|
| 119 | (*ptr)->attr=(de->name[0]=='.' && de->name[1]=='.' && de->name[2]==0)?DOS_ATTR_DIRECTORY:0xFF; |
|---|
| 120 | (*ptr)->size=(*ptr)->mtime=0; |
|---|
| 121 | } |
|---|
| 122 | (*ptr)->marked=0; |
|---|
| 123 | (*ptr)->prev=prev; |
|---|
| 124 | prev=*ptr; |
|---|
| 125 | ptr = &((*ptr)->next); |
|---|
| 126 | ++count; |
|---|
| 127 | } |
|---|
| 128 | } |
|---|
| 129 | de = readdir(d); |
|---|
| 130 | } |
|---|
| 131 | closedir(d); |
|---|
| 132 | } |
|---|
| 133 | *ptr=NULL; |
|---|
| 134 | |
|---|
| 135 | if (count) { |
|---|
| 136 | // sort |
|---|
| 137 | ptr=malloc(count*sizeof(struct fitem*)); |
|---|
| 138 | if (ptr) { |
|---|
| 139 | prev=head; |
|---|
| 140 | count=0; |
|---|
| 141 | while (prev) { |
|---|
| 142 | ptr[count++]=prev; |
|---|
| 143 | prev=prev->next; |
|---|
| 144 | } |
|---|
| 145 | |
|---|
| 146 | qsort(ptr, count, sizeof(struct fitem*), fselect_sort_nothumb); |
|---|
| 147 | |
|---|
| 148 | for (i=0; i<count-1; ++i) { |
|---|
| 149 | ptr[i]->n=i; |
|---|
| 150 | ptr[i]->next=ptr[i+1]; |
|---|
| 151 | ptr[i+1]->prev=ptr[i]; |
|---|
| 152 | } |
|---|
| 153 | ptr[0]->prev=ptr[count-1]->next=NULL; |
|---|
| 154 | ptr[count-1]->n=count-1; |
|---|
| 155 | head=ptr[0]; |
|---|
| 156 | |
|---|
| 157 | free(ptr); |
|---|
| 158 | } |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | top = selected = head; |
|---|
| 162 | } |
|---|
| 163 | |
|---|
| 164 | //------------------------------------------------------------------- |
|---|
| 165 | void gui_fselect_init(int title, const char* dir, void (*on_select)(const char *fn)) { |
|---|
| 166 | int i; |
|---|
| 167 | |
|---|
| 168 | w = (1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1+1)*FONT_WIDTH; |
|---|
| 169 | h = FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT+4+FONT_HEIGHT; |
|---|
| 170 | x = (screen_width-w)>>1; |
|---|
| 171 | y = (screen_height-h)>>1; |
|---|
| 172 | |
|---|
| 173 | fselect_title = lang_str(title); |
|---|
| 174 | strcpy(current_dir, dir); |
|---|
| 175 | gui_fselect_read_dir(current_dir); |
|---|
| 176 | top = selected = head; |
|---|
| 177 | selected_file[0]=0; |
|---|
| 178 | fselect_on_select = on_select; |
|---|
| 179 | marked_operation = MARKED_OP_NONE; |
|---|
| 180 | gui_fselect_mode_old = gui_get_mode(); |
|---|
| 181 | gui_fselect_redraw = 2; |
|---|
| 182 | gui_set_mode(GUI_MODE_FSELECT); |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 185 | //------------------------------------------------------------------- |
|---|
| 186 | char* gui_fselect_result() { |
|---|
| 187 | if (selected_file[0]) |
|---|
| 188 | return selected_file; |
|---|
| 189 | else |
|---|
| 190 | return NULL; |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | //------------------------------------------------------------------- |
|---|
| 194 | void gui_fselect_draw_initilal() { |
|---|
| 195 | int i; |
|---|
| 196 | |
|---|
| 197 | draw_rect(x-3, y-3, x+w+5, y+h+5, COLOR_BLACK); //shadow |
|---|
| 198 | draw_rect(x-2, y-2, x+w+6, y+h+6, COLOR_BLACK); //shadow |
|---|
| 199 | draw_rect(x-1, y-1, x+w+7, y+h+7, COLOR_BLACK); //shadow |
|---|
| 200 | draw_filled_rect(x-4, y-4, x+w+4, y+h+4, MAKE_COLOR(COLOR_GREY, COLOR_WHITE)); // main box |
|---|
| 201 | draw_filled_rect(x-2, y-2, x+w+2, y+FONT_HEIGHT+2, MAKE_COLOR(COLOR_BLACK, COLOR_WHITE)); //title |
|---|
| 202 | draw_filled_rect(x-2, y+h-FONT_HEIGHT-2, x+w+2, y+h+2, MAKE_COLOR(COLOR_GREY, COLOR_WHITE)); //footer |
|---|
| 203 | draw_rect(x-2, y-2, x+w+2, y+h+2, COLOR_WHITE); //border |
|---|
| 204 | draw_rect(x-3, y-3, x+w+3, y+h+3, COLOR_WHITE); //border |
|---|
| 205 | i = strlen(fselect_title); |
|---|
| 206 | draw_string(x+((w-i*FONT_WIDTH)>>1), y, fselect_title, MAKE_COLOR(COLOR_BLACK, COLOR_WHITE)); //title text |
|---|
| 207 | } |
|---|
| 208 | |
|---|
| 209 | //------------------------------------------------------------------- |
|---|
| 210 | void gui_fselect_draw() { |
|---|
| 211 | int i, j; |
|---|
| 212 | struct fitem *ptr; |
|---|
| 213 | char buf[48]; |
|---|
| 214 | struct tm *time; |
|---|
| 215 | color cl_markered = ((mode_get()&MODE_MASK) == MODE_REC)?COLOR_YELLOW:0x66; |
|---|
| 216 | |
|---|
| 217 | if (gui_fselect_redraw) { |
|---|
| 218 | if (gui_fselect_redraw==2) |
|---|
| 219 | gui_fselect_draw_initilal(); |
|---|
| 220 | |
|---|
| 221 | for (i=0, ptr=top; i<NUM_LINES && ptr; ++i, ptr=ptr->next) { |
|---|
| 222 | // print name |
|---|
| 223 | for (j=0; j<NAME_SIZE && ptr->name[j]; ++j) |
|---|
| 224 | buf[j]=ptr->name[j]; |
|---|
| 225 | if (j==NAME_SIZE && ptr->name[j]) buf[NAME_SIZE-1]='>'; |
|---|
| 226 | if (ptr->attr & DOS_ATTR_DIRECTORY && ptr->attr != 0xFF) { |
|---|
| 227 | if (j<NAME_SIZE) { |
|---|
| 228 | buf[j++]='/'; |
|---|
| 229 | } else { |
|---|
| 230 | buf[NAME_SIZE-2]='>'; |
|---|
| 231 | buf[NAME_SIZE-1]='/'; |
|---|
| 232 | } |
|---|
| 233 | } |
|---|
| 234 | for (; j<NAME_SIZE && (buf[j++]=' ');); |
|---|
| 235 | buf[NAME_SIZE]=0; |
|---|
| 236 | draw_string(x+FONT_WIDTH, y+FONT_HEIGHT+4+i*FONT_HEIGHT, buf, MAKE_COLOR((ptr==selected)?COLOR_RED:COLOR_GREY, (ptr->marked)?cl_markered:COLOR_WHITE)); |
|---|
| 237 | |
|---|
| 238 | draw_string(x+(1+NAME_SIZE)*FONT_WIDTH, y+FONT_HEIGHT+4+i*FONT_HEIGHT, "\x06", MAKE_COLOR((ptr==selected)?COLOR_RED:COLOR_GREY, COLOR_WHITE)); |
|---|
| 239 | |
|---|
| 240 | // print size or <Dir> |
|---|
| 241 | if (ptr->attr & DOS_ATTR_DIRECTORY) { |
|---|
| 242 | if (ptr->attr == 0xFF) { |
|---|
| 243 | sprintf(buf, " ??? "); |
|---|
| 244 | } else if (ptr->name[0]=='.' && ptr->name[1]=='.' && ptr->name[2]==0) { |
|---|
| 245 | sprintf(buf, "<UpDir>"); |
|---|
| 246 | } else { |
|---|
| 247 | sprintf(buf, "< Dir >"); |
|---|
| 248 | } |
|---|
| 249 | } else { |
|---|
| 250 | if (ptr->size < 10000000) |
|---|
| 251 | sprintf(buf, "%7lu", ptr->size); |
|---|
| 252 | else if (ptr->size < 1024000000) |
|---|
| 253 | sprintf(buf, "%6luK", ptr->size>>10); |
|---|
| 254 | else |
|---|
| 255 | sprintf(buf, "%6luM", ptr->size>>20); |
|---|
| 256 | } |
|---|
| 257 | draw_string(x+(1+NAME_SIZE+SPACING)*FONT_WIDTH, y+FONT_HEIGHT+4+i*FONT_HEIGHT, buf, MAKE_COLOR((ptr==selected)?COLOR_RED:COLOR_GREY, (ptr->marked)?cl_markered:COLOR_WHITE)); |
|---|
| 258 | |
|---|
| 259 | draw_string(x+(1+NAME_SIZE+SPACING+SIZE_SIZE)*FONT_WIDTH, y+FONT_HEIGHT+4+i*FONT_HEIGHT, "\x06", MAKE_COLOR((ptr==selected)?COLOR_RED:COLOR_GREY, COLOR_WHITE)); |
|---|
| 260 | |
|---|
| 261 | // print modification time |
|---|
| 262 | if (ptr->mtime) { |
|---|
| 263 | time = localtime(&(ptr->mtime)); |
|---|
| 264 | sprintf(buf, "%2u/%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); |
|---|
| 265 | } else { |
|---|
| 266 | sprintf(buf, "%14s", ""); |
|---|
| 267 | } |
|---|
| 268 | draw_string(x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING)*FONT_WIDTH, y+FONT_HEIGHT+4+i*FONT_HEIGHT, buf, MAKE_COLOR((ptr==selected)?COLOR_RED:COLOR_GREY, (ptr->marked)?cl_markered:COLOR_WHITE)); |
|---|
| 269 | } |
|---|
| 270 | |
|---|
| 271 | if (i<NUM_LINES) { |
|---|
| 272 | draw_filled_rect(x+FONT_WIDTH, y+FONT_HEIGHT+4+i*FONT_HEIGHT, x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE)*FONT_WIDTH, |
|---|
| 273 | y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT-1, MAKE_COLOR(COLOR_GREY, COLOR_GREY)); |
|---|
| 274 | } |
|---|
| 275 | |
|---|
| 276 | i=strlen(current_dir); |
|---|
| 277 | if (i>NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE) { |
|---|
| 278 | i-=NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE -1; |
|---|
| 279 | draw_char(x+FONT_WIDTH, y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT+4, '<', MAKE_COLOR(COLOR_GREY, COLOR_WHITE)); |
|---|
| 280 | draw_string(x+FONT_WIDTH*2, y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT+4, current_dir+i, MAKE_COLOR(COLOR_GREY, COLOR_WHITE)); //current dir |
|---|
| 281 | } else { |
|---|
| 282 | draw_string(x+FONT_WIDTH, y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT+4, current_dir, MAKE_COLOR(COLOR_GREY, COLOR_WHITE)); //current dir |
|---|
| 283 | draw_filled_rect(x+(1+i)*FONT_WIDTH, y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT+4, |
|---|
| 284 | x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE)*FONT_WIDTH, y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT+4+FONT_HEIGHT, MAKE_COLOR(COLOR_GREY, COLOR_GREY)); // fill |
|---|
| 285 | if (strlen(current_dir)<=NAME_SIZE) { |
|---|
| 286 | unsigned int fr,tot; |
|---|
| 287 | fr=GetFreeCardSpaceKb()>>10; tot=GetTotalCardSpaceKb()>>10; |
|---|
| 288 | sprintf(buf,"%dM/%dM (%d%%)",fr, tot, tot? fr*100/tot: 0); |
|---|
| 289 | draw_string(x+(NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE-strlen(buf)+1)*FONT_WIDTH, y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT+4, buf, MAKE_COLOR(COLOR_GREY, COLOR_WHITE)); // free space |
|---|
| 290 | }; |
|---|
| 291 | } |
|---|
| 292 | |
|---|
| 293 | // scrollbar |
|---|
| 294 | if (count>NUM_LINES) { |
|---|
| 295 | i=NUM_LINES*FONT_HEIGHT-1 -1; |
|---|
| 296 | j=i*NUM_LINES/count; |
|---|
| 297 | if (j<20) j=20; |
|---|
| 298 | i=(i-j)*selected->n/(count-1); |
|---|
| 299 | draw_filled_rect(x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1)*FONT_WIDTH+2, y+FONT_HEIGHT+4+1, |
|---|
| 300 | x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1)*FONT_WIDTH+6, y+FONT_HEIGHT+4+1+i, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK)); |
|---|
| 301 | draw_filled_rect(x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1)*FONT_WIDTH+2, y+FONT_HEIGHT+4+i+j, |
|---|
| 302 | x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1)*FONT_WIDTH+6, y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT-1-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK)); |
|---|
| 303 | draw_filled_rect(x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1)*FONT_WIDTH+2, y+FONT_HEIGHT+4+1+i, |
|---|
| 304 | x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1)*FONT_WIDTH+6, y+FONT_HEIGHT+4+i+j, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE)); |
|---|
| 305 | } else { |
|---|
| 306 | draw_filled_rect(x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1)*FONT_WIDTH+2, y+FONT_HEIGHT+4+1, |
|---|
| 307 | x+(1+NAME_SIZE+SPACING+SIZE_SIZE+SPACING+TIME_SIZE+1)*FONT_WIDTH+6, y+FONT_HEIGHT+4+NUM_LINES*FONT_HEIGHT-1-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK)); |
|---|
| 308 | } |
|---|
| 309 | |
|---|
| 310 | gui_fselect_redraw = 0; |
|---|
| 311 | } |
|---|
| 312 | } |
|---|
| 313 | |
|---|
| 314 | //------------------------------------------------------------------- |
|---|
| 315 | static void fselect_delete_file_cb(unsigned int btn) { |
|---|
| 316 | if (btn==MBOX_BTN_YES) { |
|---|
| 317 | started(); |
|---|
| 318 | sprintf(selected_file, "%s/%s", current_dir, selected->name); |
|---|
| 319 | remove(selected_file); |
|---|
| 320 | finished(); |
|---|
| 321 | selected_file[0]=0; |
|---|
| 322 | gui_fselect_read_dir(current_dir); |
|---|
| 323 | } |
|---|
| 324 | gui_fselect_redraw = 2; |
|---|
| 325 | } |
|---|
| 326 | |
|---|
| 327 | //------------------------------------------------------------------- |
|---|
| 328 | static void fselect_delete_folder_cb(unsigned int btn) { |
|---|
| 329 | DIR *d; |
|---|
| 330 | struct dirent *de; |
|---|
| 331 | int i; |
|---|
| 332 | |
|---|
| 333 | if (btn==MBOX_BTN_YES) { |
|---|
| 334 | sprintf(current_dir+strlen(current_dir), "/%s", selected->name); |
|---|
| 335 | d = opendir(current_dir); |
|---|
| 336 | if (d) { |
|---|
| 337 | de = readdir(d); |
|---|
| 338 | while (de) { |
|---|
| 339 | if (de->name[0] != 0xE5 /* deleted entry */ && (de->name[0]!='.' || (de->name[1]!='.' && de->name[1]!=0) || (de->name[1]=='.' && de->name[2]!=0))) { |
|---|
| 340 | started(); |
|---|
| 341 | sprintf(selected_file, "%s/%s", current_dir, de->name); |
|---|
| 342 | remove(selected_file); |
|---|
| 343 | finished(); |
|---|
| 344 | } |
|---|
| 345 | de = readdir(d); |
|---|
| 346 | } |
|---|
| 347 | closedir(d); |
|---|
| 348 | } |
|---|
| 349 | started(); |
|---|
| 350 | remove(current_dir); |
|---|
| 351 | finished(); |
|---|
| 352 | i=strlen(current_dir); |
|---|
| 353 | while (current_dir[--i] != '/'); |
|---|
| 354 | current_dir[i]=0; |
|---|
| 355 | selected_file[0]=0; |
|---|
| 356 | gui_fselect_read_dir(current_dir); |
|---|
| 357 | } |
|---|
| 358 | gui_fselect_redraw = 2; |
|---|
| 359 | } |
|---|
| 360 | |
|---|
| 361 | //------------------------------------------------------------------- |
|---|
| 362 | static void fselect_goto_prev(int step) { |
|---|
| 363 | register int j; |
|---|
| 364 | |
|---|
| 365 | for (j=0; j<step; ++j) { |
|---|
| 366 | if (selected->prev==top && top->prev) |
|---|
| 367 | top=top->prev; |
|---|
| 368 | if (selected->prev) |
|---|
| 369 | selected=selected->prev; |
|---|
| 370 | } |
|---|
| 371 | } |
|---|
| 372 | |
|---|
| 373 | //------------------------------------------------------------------- |
|---|
| 374 | static void fselect_goto_next(int step) { |
|---|
| 375 | register int j, i; |
|---|
| 376 | struct fitem *ptr; |
|---|
| 377 | |
|---|
| 378 | for (j=0; j<step; ++j) { |
|---|
| 379 | for (i=0, ptr=top; i<NUM_LINES-1 && ptr; ++i, ptr=ptr->next); |
|---|
| 380 | if (i==NUM_LINES-1 && ptr && ptr->prev==selected && ptr->next) |
|---|
| 381 | top=top->next; |
|---|
| 382 | if (selected->next) |
|---|
| 383 | selected=selected->next; |
|---|
| 384 | } |
|---|
| 385 | } |
|---|
| 386 | |
|---|
| 387 | //------------------------------------------------------------------- |
|---|
| 388 | static void fselect_marked_toggle() { |
|---|
| 389 | if (selected && selected->attr != 0xFF && !(selected->attr & DOS_ATTR_DIRECTORY)) { |
|---|
| 390 | selected->marked = !selected->marked; |
|---|
| 391 | } |
|---|
| 392 | } |
|---|
| 393 | |
|---|
| 394 | //------------------------------------------------------------------- |
|---|
| 395 | static void gui_fselect_marked_free_data() { |
|---|
| 396 | struct fitem *ptr = marked_head, *prev; |
|---|
| 397 | |
|---|
| 398 | while (ptr) { |
|---|
| 399 | if (ptr->name) |
|---|
| 400 | free(ptr->name); |
|---|
| 401 | prev=ptr; |
|---|
| 402 | ptr=ptr->next; |
|---|
| 403 | free(prev); |
|---|
| 404 | } |
|---|
| 405 | marked_head=NULL; |
|---|
| 406 | marked_count=0; |
|---|
| 407 | marked_operation = MARKED_OP_NONE; |
|---|
| 408 | } |
|---|
| 409 | |
|---|
| 410 | //------------------------------------------------------------------- |
|---|
| 411 | static void fselect_marked_copy_list() { |
|---|
| 412 | gui_fselect_marked_free_data(); |
|---|
| 413 | |
|---|
| 414 | struct fitem *ptr, **marked_ptr=&marked_head, *prev = NULL; |
|---|
| 415 | |
|---|
| 416 | for (ptr=head; ptr; ptr=ptr->next) { |
|---|
| 417 | if (ptr->marked) { |
|---|
| 418 | *marked_ptr = malloc(sizeof(struct fitem)); |
|---|
| 419 | if (*marked_ptr) { |
|---|
| 420 | (*marked_ptr)->n = ptr->n; |
|---|
| 421 | (*marked_ptr)->name = malloc(strlen(ptr->name)+1); |
|---|
| 422 | if ((*marked_ptr)->name) |
|---|
| 423 | strcpy((*marked_ptr)->name, ptr->name); |
|---|
| 424 | (*marked_ptr)->attr=ptr->attr; |
|---|
| 425 | (*marked_ptr)->size=ptr->size; |
|---|
| 426 | (*marked_ptr)->mtime=ptr->mtime; |
|---|
| 427 | (*marked_ptr)->marked=ptr->marked; |
|---|
| 428 | (*marked_ptr)->prev=prev; |
|---|
| 429 | prev=*marked_ptr; |
|---|
| 430 | marked_ptr = &((*marked_ptr)->next); |
|---|
| 431 | *marked_ptr=NULL; |
|---|
| 432 | ++marked_count; |
|---|
| 433 | } |
|---|
| 434 | } |
|---|
| 435 | } |
|---|
| 436 | |
|---|
| 437 | if (!marked_count) |
|---|
| 438 | if (selected && selected->attr != 0xFF) |
|---|
| 439 | if (!(selected->attr & DOS_ATTR_DIRECTORY)) { |
|---|
| 440 | *marked_ptr = malloc(sizeof(struct fitem)); |
|---|
| 441 | if (*marked_ptr) { |
|---|
| 442 | (*marked_ptr)->n = selected->n; |
|---|
| 443 | (*marked_ptr)->name = malloc(strlen(selected->name)+1); |
|---|
| 444 | if ((*marked_ptr)->name) |
|---|
| 445 | strcpy((*marked_ptr)->name, selected->name); |
|---|
| 446 | (*marked_ptr)->attr=selected->attr; |
|---|
| 447 | (*marked_ptr)->size=selected->size; |
|---|
| 448 | (*marked_ptr)->mtime=selected->mtime; |
|---|
| 449 | (*marked_ptr)->marked=!(0); |
|---|
| 450 | (*marked_ptr)->prev=prev; |
|---|
| 451 | prev=*marked_ptr; |
|---|
| 452 | marked_ptr = &((*marked_ptr)->next); |
|---|
| 453 | *marked_ptr=NULL; |
|---|
| 454 | ++marked_count; |
|---|
| 455 | } |
|---|
| 456 | } |
|---|
| 457 | |
|---|
| 458 | sprintf(marked_dir, "%s", current_dir); |
|---|
| 459 | } |
|---|
| 460 | |
|---|
| 461 | //------------------------------------------------------------------- |
|---|
| 462 | static void fselect_marked_paste_cb(unsigned int btn) { |
|---|
| 463 | struct fitem *ptr; |
|---|
| 464 | int ss, sd, fsrc, fdst, i=0; |
|---|
| 465 | register int *buf; |
|---|
| 466 | unsigned char fend; |
|---|
| 467 | static struct utimbuf t; |
|---|
| 468 | |
|---|
| 469 | if (btn != MBOX_BTN_YES) return; |
|---|
| 470 | |
|---|
| 471 | if (strcmp(marked_dir, current_dir) != 0) { |
|---|
| 472 | buf = umalloc(MARKED_BUF_SIZE); |
|---|
| 473 | if (buf) { |
|---|
| 474 | for (ptr=marked_head; ptr; ptr=ptr->next) { |
|---|
| 475 | if (ptr->attr != 0xFF && !(ptr->attr & DOS_ATTR_DIRECTORY)) { |
|---|
| 476 | started(); |
|---|
| 477 | ++i; |
|---|
| 478 | if (marked_count) |
|---|
| 479 | gui_browser_progress_show(lang_str(LANG_FSELECT_PROGRESS_TITLE),i*100/marked_count); |
|---|
| 480 | sprintf(selected_file, "%s/%s", marked_dir, ptr->name); |
|---|
| 481 | fsrc = open(selected_file, O_RDONLY, 0777); |
|---|
| 482 | if (fsrc>=0) { |
|---|
| 483 | sprintf(selected_file, "%s/%s", current_dir, ptr->name); |
|---|
| 484 | // trying to open for read to check if file exists |
|---|
| 485 | fdst = open(selected_file, O_RDONLY, 0777); |
|---|
| 486 | if (fdst<0) { |
|---|
| 487 | fdst = open(selected_file, O_WRONLY|O_CREAT, 0777); |
|---|
| 488 | if (fdst>=0) { |
|---|
| 489 | do { |
|---|
| 490 | ss=read(fsrc, buf, MARKED_BUF_SIZE); |
|---|
| 491 | if (ss) sd=write(fdst, buf, ss); |
|---|
| 492 | } while (ss && ss==sd); |
|---|
| 493 | close(fdst); |
|---|
| 494 | t.actime = t.modtime = ptr->mtime; |
|---|
| 495 | utime(selected_file, &t); |
|---|
| 496 | if (marked_operation == MARKED_OP_CUT && ss==0) { |
|---|
| 497 | close(fsrc); fsrc = -1; |
|---|
| 498 | sprintf(selected_file, "%s/%s", marked_dir, ptr->name); |
|---|
| 499 | remove(selected_file); |
|---|
| 500 | } |
|---|
| 501 | } |
|---|
| 502 | } else { |
|---|
| 503 | close(fdst); |
|---|
| 504 | } |
|---|
| 505 | if (fsrc>=0) close(fsrc); |
|---|
| 506 | } |
|---|
| 507 | finished(); |
|---|
| 508 | selected_file[0]=0; |
|---|
| 509 | } |
|---|
| 510 | } |
|---|
| 511 | ufree(buf); |
|---|
| 512 | if (marked_operation == MARKED_OP_CUT) { |
|---|
| 513 | gui_fselect_marked_free_data(); |
|---|
| 514 | } |
|---|
| 515 | } |
|---|
| 516 | gui_fselect_read_dir(current_dir); |
|---|
| 517 | } |
|---|
| 518 | gui_fselect_redraw = 2; |
|---|
| 519 | } |
|---|
| 520 | |
|---|
| 521 | //------------------------------------------------------------------- |
|---|
| 522 | static unsigned int fselect_marked_count() { |
|---|
| 523 | struct fitem *ptr; |
|---|
| 524 | register unsigned int cnt=0; |
|---|
| 525 | |
|---|
| 526 | for (ptr=head; ptr; ptr=ptr->next) { |
|---|
| 527 | if (ptr->attr != 0xFF && !(ptr->attr & DOS_ATTR_DIRECTORY) && ptr->marked) |
|---|
| 528 | ++cnt; |
|---|
| 529 | } |
|---|
| 530 | |
|---|
| 531 | if (!cnt) { |
|---|
| 532 | if (selected && selected->attr != 0xFF && !(selected->attr & DOS_ATTR_DIRECTORY)) |
|---|
| 533 | ++cnt; |
|---|
| 534 | } |
|---|
| 535 | |
|---|
| 536 | return cnt; |
|---|
| 537 | } |
|---|
| 538 | |
|---|
| 539 | //------------------------------------------------------------------- |
|---|
| 540 | static void fselect_marked_delete_cb(unsigned int btn) { |
|---|
| 541 | struct fitem *ptr; |
|---|
| 542 | unsigned int del_cnt=0, cnt; |
|---|
| 543 | |
|---|
| 544 | if (btn != MBOX_BTN_YES) return; |
|---|
| 545 | |
|---|
| 546 | cnt=fselect_marked_count(); |
|---|
| 547 | for (ptr=head; ptr; ptr=ptr->next) |
|---|
| 548 | if (ptr->marked && ptr->attr != 0xFF && !(ptr->attr & DOS_ATTR_DIRECTORY)) { |
|---|
| 549 | started(); |
|---|
| 550 | ++del_cnt; |
|---|
| 551 | if (cnt) |
|---|
| 552 | gui_browser_progress_show(lang_str(LANG_FSELECT_PROGRESS_TITLE),del_cnt*100/cnt); |
|---|
| 553 | sprintf(selected_file, "%s/%s", current_dir, ptr->name); |
|---|
| 554 | remove(selected_file); |
|---|
| 555 | finished(); |
|---|
| 556 | selected_file[0]=0; |
|---|
| 557 | } |
|---|
| 558 | |
|---|
| 559 | if (del_cnt == 0 && selected) { |
|---|
| 560 | started(); |
|---|
| 561 | sprintf(selected_file, "%s/%s", current_dir, selected->name); |
|---|
| 562 | remove(selected_file); |
|---|
| 563 | finished(); |
|---|
| 564 | selected_file[0]=0; |
|---|
| 565 | } |
|---|
| 566 | gui_fselect_read_dir(current_dir); |
|---|
| 567 | gui_fselect_redraw = 2; |
|---|
| 568 | } |
|---|
| 569 | |
|---|
| 570 | //------------------------------------------------------------------- |
|---|
| 571 | static void fselect_marked_inverse_selection() { |
|---|
| 572 | struct fitem *ptr; |
|---|
| 573 | |
|---|
| 574 | for (ptr=head; ptr; ptr=ptr->next) |
|---|
| 575 | if (ptr->attr != 0xFF && !(ptr->attr & DOS_ATTR_DIRECTORY)) |
|---|
| 576 | ptr->marked = !ptr->marked; |
|---|
| 577 | |
|---|
| 578 | gui_fselect_redraw = 2; |
|---|
| 579 | } |
|---|
| 580 | |
|---|
| 581 | //------------------------------------------------------------------- |
|---|
| 582 | void process_raw_files(void){ |
|---|
| 583 | struct fitem *ptr; |
|---|
| 584 | if ((fselect_marked_count()>1) && raw_merge_start(raw_operation)) { |
|---|
| 585 | for (ptr=head; ptr; ptr=ptr->next) |
|---|
| 586 | if (ptr->marked && ptr->attr != 0xFF && !(ptr->attr & DOS_ATTR_DIRECTORY)) { |
|---|
| 587 | sprintf(selected_file, "%s/%s", current_dir, ptr->name); |
|---|
| 588 | raw_merge_add_file(selected_file); |
|---|
| 589 | } |
|---|
| 590 | raw_merge_end(); |
|---|
| 591 | gui_fselect_read_dir(current_dir); |
|---|
| 592 | } |
|---|
| 593 | } |
|---|
| 594 | |
|---|
| 595 | //------------------------------------------------------------------- |
|---|
| 596 | static void fselect_mpopup_cb(unsigned int actn) { |
|---|
| 597 | switch (actn) { |
|---|
| 598 | case MPOPUP_CUT: |
|---|
| 599 | fselect_marked_copy_list(); |
|---|
| 600 | marked_operation=MARKED_OP_CUT; |
|---|
| 601 | break; |
|---|
| 602 | case MPOPUP_COPY: |
|---|
| 603 | fselect_marked_copy_list(); |
|---|
| 604 | marked_operation=MARKED_OP_COPY; |
|---|
| 605 | break; |
|---|
| 606 | case MPOPUP_PASTE: |
|---|
| 607 | if (marked_operation == MARKED_OP_CUT) { |
|---|
| 608 | sprintf(buf, lang_str(LANG_FSELECT_CUT_TEXT), marked_count, marked_dir); |
|---|
| 609 | gui_mbox_init(LANG_FSELECT_CUT_TITLE, (int)buf, |
|---|
| 610 | MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_marked_paste_cb); |
|---|
| 611 | } |
|---|
| 612 | else { |
|---|
| 613 | sprintf(buf, lang_str(LANG_FSELECT_COPY_TEXT), marked_count, marked_dir); |
|---|
| 614 | gui_mbox_init(LANG_FSELECT_COPY_TITLE, (int)buf, |
|---|
| 615 | MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_marked_paste_cb); |
|---|
| 616 | } |
|---|
| 617 | break; |
|---|
| 618 | case MPOPUP_DELETE: |
|---|
| 619 | sprintf(buf, lang_str(LANG_FSELECT_DELETE_TEXT), fselect_marked_count()); |
|---|
| 620 | gui_mbox_init(LANG_FSELECT_DELETE_TITLE, (int)buf, |
|---|
| 621 | MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_marked_delete_cb); |
|---|
| 622 | break; |
|---|
| 623 | case MPOPUP_SELINV: |
|---|
| 624 | fselect_marked_inverse_selection(); |
|---|
| 625 | break; |
|---|
| 626 | case MPOPUP_CANCEL: |
|---|
| 627 | break; |
|---|
| 628 | case MPOPUP_RAW_AVERAGE: |
|---|
| 629 | raw_operation=RAW_OPERATIOM_AVERAGE; |
|---|
| 630 | process_raw_files(); |
|---|
| 631 | break; |
|---|
| 632 | case MPOPUP_RAW_ADD: |
|---|
| 633 | raw_operation=RAW_OPERATIOM_SUM; |
|---|
| 634 | process_raw_files(); |
|---|
| 635 | break; |
|---|
| 636 | } |
|---|
| 637 | gui_fselect_redraw = 2; |
|---|
| 638 | } |
|---|
| 639 | |
|---|
| 640 | //------------------------------------------------------------------- |
|---|
| 641 | void gui_fselect_kbd_process() { |
|---|
| 642 | int i; |
|---|
| 643 | |
|---|
| 644 | switch (kbd_get_autoclicked_key()) { |
|---|
| 645 | case KEY_UP: |
|---|
| 646 | if (selected) { |
|---|
| 647 | fselect_goto_prev(1); |
|---|
| 648 | gui_fselect_redraw = 1; |
|---|
| 649 | } |
|---|
| 650 | break; |
|---|
| 651 | case KEY_DOWN: |
|---|
| 652 | if (selected) { |
|---|
| 653 | fselect_goto_next(1); |
|---|
| 654 | gui_fselect_redraw = 1; |
|---|
| 655 | } |
|---|
| 656 | break; |
|---|
| 657 | case KEY_ZOOM_OUT: |
|---|
| 658 | if (selected) { |
|---|
| 659 | fselect_goto_prev(NUM_LINES-1); |
|---|
| 660 | gui_fselect_redraw = 1; |
|---|
| 661 | } |
|---|
| 662 | break; |
|---|
| 663 | case KEY_ZOOM_IN: |
|---|
| 664 | if (selected) { |
|---|
| 665 | fselect_goto_next(NUM_LINES-1); |
|---|
| 666 | gui_fselect_redraw = 1; |
|---|
| 667 | } |
|---|
| 668 | break; |
|---|
| 669 | case KEY_RIGHT: |
|---|
| 670 | if (selected) { |
|---|
| 671 | fselect_marked_toggle(); |
|---|
| 672 | fselect_goto_next(1); |
|---|
| 673 | gui_fselect_redraw = 1; |
|---|
| 674 | } |
|---|
| 675 | break; |
|---|
| 676 | case KEY_LEFT: |
|---|
| 677 | if (selected && selected->attr != 0xFF) { |
|---|
| 678 | i=MPOPUP_CUT|MPOPUP_COPY|MPOPUP_SELINV|MPOPUP_RAW_ADD|MPOPUP_RAW_AVERAGE; |
|---|
| 679 | if (fselect_marked_count() > 0) |
|---|
| 680 | i |= MPOPUP_DELETE; |
|---|
| 681 | if (marked_operation == MARKED_OP_CUT || marked_operation == MARKED_OP_COPY) |
|---|
| 682 | i |= MPOPUP_PASTE; |
|---|
| 683 | gui_mpopup_init(i, fselect_mpopup_cb); |
|---|
| 684 | } |
|---|
| 685 | break; |
|---|
| 686 | case KEY_SET: |
|---|
| 687 | if (selected && selected->attr != 0xFF) { |
|---|
| 688 | if (selected->attr & DOS_ATTR_DIRECTORY) { |
|---|
| 689 | i=strlen(current_dir); |
|---|
| 690 | if (selected->name[0]=='.' && selected->name[1]=='.' && selected->name[2]==0) { |
|---|
| 691 | while (current_dir[--i] != '/'); |
|---|
| 692 | current_dir[i]=0; |
|---|
| 693 | } else { |
|---|
| 694 | sprintf(current_dir+i, "/%s", selected->name); |
|---|
| 695 | } |
|---|
| 696 | gui_fselect_read_dir(current_dir); |
|---|
| 697 | gui_fselect_redraw = 1; |
|---|
| 698 | } else { |
|---|
| 699 | sprintf(selected_file, "%s/%s", current_dir, selected->name); |
|---|
| 700 | gui_fselect_free_data(); |
|---|
| 701 | gui_fselect_marked_free_data(); |
|---|
| 702 | gui_set_mode(gui_fselect_mode_old); |
|---|
| 703 | draw_restore(); |
|---|
| 704 | if (fselect_on_select) |
|---|
| 705 | fselect_on_select(selected_file); |
|---|
| 706 | } |
|---|
| 707 | } |
|---|
| 708 | break; |
|---|
| 709 | #if defined (CAMERA_ixus700_sd500) || defined (CAMERA_ixus800_sd700) || defined (CAMERA_a560) || defined (CAMERA_ixus850_sd800) || defined (CAMERA_ixus70_sd1000) || defined (CAMERA_a460) || defined(CAMERA_ixus55_sd450) || defined(CAMERA_a550) |
|---|
| 710 | case KEY_DISPLAY: |
|---|
| 711 | #else |
|---|
| 712 | case KEY_ERASE: |
|---|
| 713 | #endif |
|---|
| 714 | if (selected && selected->attr != 0xFF) { |
|---|
| 715 | if (selected->attr & DOS_ATTR_DIRECTORY) { |
|---|
| 716 | if (selected->name[0]!='.' || selected->name[1]!='.' || selected->name[2]!=0) |
|---|
| 717 | gui_mbox_init(LANG_BROWSER_ERASE_DIR_TITLE, LANG_BROWSER_ERASE_DIR_TEXT, |
|---|
| 718 | MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_delete_folder_cb); |
|---|
| 719 | } else { |
|---|
| 720 | gui_mbox_init(LANG_BROWSER_DELETE_FILE_TITLE, LANG_BROWSER_DELETE_FILE_TEXT, |
|---|
| 721 | MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, fselect_delete_file_cb); |
|---|
| 722 | } |
|---|
| 723 | } |
|---|
| 724 | break; |
|---|
| 725 | case KEY_MENU: |
|---|
| 726 | gui_fselect_free_data(); |
|---|
| 727 | gui_fselect_marked_free_data(); |
|---|
| 728 | gui_set_mode(gui_fselect_mode_old); |
|---|
| 729 | draw_restore(); |
|---|
| 730 | if (fselect_on_select) |
|---|
| 731 | fselect_on_select(NULL); |
|---|
| 732 | break; |
|---|
| 733 | } |
|---|
| 734 | } |
|---|
| 735 | |
|---|
| 736 | //------------------------------------------------------------------- |
|---|