803f2fc465542afec39b9179c744f0de2e44cd08
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bcfilebox.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2017 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcdelete.h"
23 #include "bcfilebox.h"
24 #include "bclistboxitem.h"
25 #include "bcnewfolder.h"
26 #include "bcpixmap.h"
27 #include "bcrename.h"
28 #include "bcresources.h"
29 #include "bcsignals.h"
30 #include "bctitle.h"
31 #include "clip.h"
32 #include "condition.h"
33 #include "filesystem.h"
34 #include "keys.h"
35 #include "language.h"
36 #include "mutex.h"
37 #include <string.h>
38 #include <sys/stat.h>
39
40
41
42
43
44
45
46 BC_FileBoxRecent::BC_FileBoxRecent(BC_FileBox *filebox, int x, int y)
47  : BC_ListBox(x, y, 250,
48                 filebox->get_text_height(MEDIUMFONT) * FILEBOX_HISTORY_SIZE +
49                 BC_ScrollBar::get_span(SCROLL_HORIZ) +
50                 LISTBOX_MARGIN * 2, LISTBOX_TEXT, &filebox->recent_dirs,
51                 0, 0, 1, 0, 1)
52 {
53         this->filebox = filebox;
54         set_tooltip(_("Recent paths"));
55 }
56
57 int BC_FileBoxRecent::handle_event()
58 {
59         BC_ListBoxItem *selection = get_selection(0, 0);
60         if( selection != 0 ) {
61                 char *path = selection->get_text();
62                 filebox->submit_dir(path);
63         }
64         return 1;
65 }
66
67
68
69
70
71
72
73
74
75
76
77 BC_FileBoxListBox::BC_FileBoxListBox(int x, int y, BC_FileBox *filebox)
78  : BC_ListBox(x, y, filebox->get_listbox_w(), filebox->get_listbox_h(y),
79                 filebox->get_display_mode(), filebox->list_column,
80                 filebox->column_titles, filebox->column_width,
81                 filebox->columns, 0, 0,
82                 filebox->select_multiple ? LISTBOX_MULTIPLE : LISTBOX_SINGLE,
83                 ICON_LEFT, 0)
84 {
85         this->filebox = filebox;
86         set_sort_column(filebox->sort_column);
87         set_sort_order(filebox->sort_order);
88         set_allow_drag_column(1);
89 }
90
91 BC_FileBoxListBox::~BC_FileBoxListBox()
92 {
93 }
94
95 int BC_FileBoxListBox::handle_event()
96 {
97         filebox->submit_file(filebox->textbox->get_text());
98         return 1;
99 }
100
101 int BC_FileBoxListBox::selection_changed()
102 {
103         BC_ListBoxItem *item = get_selection(
104                 filebox->column_of_type(FILEBOX_NAME), 0);
105
106         if(item) {
107                 char path[BCTEXTLEN];
108                 strcpy(path, item->get_text());
109                 filebox->textbox->update(path);
110                 filebox->fs->extract_dir(filebox->directory, path);
111                 filebox->fs->extract_name(filebox->filename, path);
112                 filebox->fs->complete_path(path);
113                 strcpy(filebox->current_path, path);
114                 strcpy(filebox->submitted_path, path);
115         }
116         return 1;
117 }
118
119 int BC_FileBoxListBox::column_resize_event()
120 {
121         for(int i = 0; i < filebox->columns; i++)
122                 BC_WindowBase::get_resources()->filebox_columnwidth[i] =
123                         filebox->column_width[i] =
124                         get_column_width(i);
125         return 1;
126 }
127
128 int BC_FileBoxListBox::sort_order_event()
129 {
130         get_resources()->filebox_sortcolumn = filebox->sort_column = get_sort_column();
131         get_resources()->filebox_sortorder = filebox->sort_order = get_sort_order();
132         filebox->refresh(-1);
133         return 1;
134 }
135
136 int BC_FileBoxListBox::move_column_event()
137 {
138         filebox->move_column(get_from_column(), get_to_column());
139         return 1;
140 }
141
142 int BC_FileBoxListBox::evaluate_query(char *string)
143 {
144 // Search name column
145         ArrayList<BC_ListBoxItem*> *column =
146                 &filebox->list_column[filebox->column_of_type(FILEBOX_NAME)];
147 // Get current selection
148         int current_selection = get_selection_number(0, 0);
149
150 // Get best score in remaining items
151         int lowest_score = 0x7fffffff;
152         int best_item = -1;
153         if(current_selection < 0) current_selection = 0;
154 //      for(int i = current_selection + 1; i < column->size(); i++)
155         for(int i = current_selection; i < column->size(); i++)
156         {
157                 int len1 = strlen(string);
158                 int len2 = strlen(column->get(i)->get_text());
159                 int current_score = strncasecmp(string,
160                         column->get(i)->get_text(),
161                         MIN(len1, len2));
162 //printf(" %d i=%d %d %s %s\n", __LINE__, i, current_score, string, column->get(i)->get_text());
163
164                 if(abs(current_score) < lowest_score)
165                 {
166                         lowest_score = abs(current_score);
167                         best_item = i;
168                 }
169         }
170
171
172         return best_item;
173 }
174
175
176 BC_FileBoxTextBox::BC_FileBoxTextBox(int x, int y, BC_FileBox *filebox)
177  : BC_TextBox(x, y, filebox->get_w() - x - 20, 1,
178         filebox->want_directory ?  filebox->directory : filebox->filename)
179 {
180         this->filebox = filebox;
181 }
182
183 BC_FileBoxTextBox::~BC_FileBoxTextBox()
184 {
185 }
186
187 int BC_FileBoxTextBox::handle_event()
188 {
189         int result = 0;
190         if(get_keypress() != RETURN)
191         {
192                 result = calculate_suggestions(&filebox->list_column[0]);
193         }
194         return result;
195 }
196
197
198 BC_FileBoxDirectoryText::BC_FileBoxDirectoryText(int x, int y, int w, BC_FileBox *filebox)
199  : BC_TextBox(x, y, w, 1, filebox->fs->get_current_dir())
200 {
201         this->filebox = filebox;
202 }
203
204 int BC_FileBoxDirectoryText::handle_event()
205 {
206         const char *path = get_text();
207         if( !filebox->fs->is_dir(path) ) return 0;
208         const char *cp = path;
209         while( *cp ) ++cp;
210         if( cp > path && *--cp != '/' ) return 0;
211         char *file_path = FileSystem::basepath(path);
212         char *dir_path = FileSystem::basepath(filebox->directory);
213         int ret = !strcmp(file_path, dir_path) ? 0 : 1;
214         if( ret ) {
215                 strcpy(filebox->directory, file_path);
216                 filebox->update_history();
217                 filebox->fs->change_dir(file_path);
218                 filebox->refresh(1);
219         }
220         delete [] dir_path;
221         delete [] file_path;
222         return ret;
223 }
224
225
226 BC_FileBoxSearchText::BC_FileBoxSearchText(int x, int y, BC_FileBox *filebox)
227  : BC_TextBox(x, y, filebox->get_w() - x - 40, 1, "")
228 {
229         this->filebox = filebox;
230 }
231
232 int BC_FileBoxSearchText::handle_event()
233 {
234         filebox->refresh();
235         return 1;
236 }
237
238
239 BC_FileBoxFilterText::BC_FileBoxFilterText(int x, int y, BC_FileBox *filebox)
240  : BC_TextBox(x, y, filebox->get_w() - x - 50, 1, filebox->get_resources()->filebox_filter)
241 {
242         this->filebox = filebox;
243 }
244
245 int BC_FileBoxFilterText::handle_event()
246 {
247         filebox->update_filter(get_text());
248         return 1;
249 }
250
251
252 BC_FileBoxFilterMenu::BC_FileBoxFilterMenu(int x, int y, BC_FileBox *filebox)
253  : BC_ListBox(x, y, filebox->get_w() - 30, 120,
254         LISTBOX_TEXT, &filebox->filter_list, 0, 0, 1, 0, 1)
255 {
256         this->filebox = filebox;
257         set_tooltip(_("Change the filter"));
258 }
259
260 int BC_FileBoxFilterMenu::handle_event()
261 {
262         filebox->filter_text->update(
263                 get_selection(filebox->column_of_type(FILEBOX_NAME), 0)->get_text());
264         filebox->update_filter(
265                 get_selection(filebox->column_of_type(FILEBOX_NAME), 0)->get_text());
266         return 1;
267 }
268
269
270 BC_FileBoxSizeFormat::BC_FileBoxSizeFormat(int x, int y, BC_FileBox *file_box)
271  : BC_Button(x, y, &BC_WindowBase::get_resources()->
272                 filebox_szfmt_images[3*file_box->size_format])
273 {
274         this->file_box = file_box;
275         set_tooltip(_("Size numeric format"));
276 }
277 BC_FileBoxSizeFormat::~BC_FileBoxSizeFormat()
278 {
279 }
280
281 int BC_FileBoxSizeFormat::handle_event()
282 {
283         if( ++file_box->size_format > FILEBOX_SIZE_THOU )
284                 file_box->size_format = FILEBOX_SIZE_RAW;
285         BC_WindowBase::get_resources()->filebox_size_format = file_box->size_format;
286         set_images(&BC_WindowBase::get_resources()->
287                 filebox_szfmt_images[3*file_box->size_format]);
288         draw_face(0);
289         file_box->refresh(0);
290         return 1;
291 }
292
293
294 BC_FileBoxUseThis::BC_FileBoxUseThis(BC_FileBox *filebox)
295  : BC_Button(filebox->get_w() / 2 -
296                 BC_WindowBase::get_resources()->usethis_button_images[0]->get_w() / 2,
297         filebox->ok_button->get_y(),
298         BC_WindowBase::get_resources()->usethis_button_images)
299 {
300         this->filebox = filebox;
301         set_tooltip(_("Submit the directory"));
302 }
303
304 BC_FileBoxUseThis::~BC_FileBoxUseThis()
305 {
306 }
307
308 int BC_FileBoxUseThis::handle_event()
309 {
310 // printf("BC_FileBoxUseThis::handle_event %d '%s'\n",
311 // __LINE__,
312 // filebox->textbox->get_text());
313         filebox->submit_file(filebox->textbox->get_text(), 1);
314         return 1;
315 }
316
317
318 BC_FileBoxOK::BC_FileBoxOK(BC_FileBox *filebox)
319  : BC_OKButton(filebox,
320         !filebox->want_directory ?
321                 BC_WindowBase::get_resources()->ok_images :
322                 BC_WindowBase::get_resources()->filebox_descend_images)
323 {
324         this->filebox = filebox;
325         if(filebox->want_directory)
326                 set_tooltip(_("Descend directory"));
327         else
328                 set_tooltip(_("Submit the file"));
329 }
330
331 BC_FileBoxOK::~BC_FileBoxOK()
332 {
333 }
334
335 int BC_FileBoxOK::handle_event()
336 {
337 //printf("BC_FileBoxOK::handle_event %d\n", __LINE__);
338         const char *path = filebox->textbox->get_text();
339         if( *path ) filebox->submit_file(path);
340         return 1;
341 }
342
343 BC_FileBoxCancel::BC_FileBoxCancel(BC_FileBox *filebox)
344  : BC_CancelButton(filebox)
345 {
346         this->filebox = filebox;
347         set_tooltip(_("Cancel the operation"));
348 }
349
350 BC_FileBoxCancel::~BC_FileBoxCancel()
351 {
352 }
353
354 int BC_FileBoxCancel::handle_event()
355 {
356 //      filebox->submit_file(filebox->textbox->get_text());
357         filebox->newfolder_thread->interrupt();
358         filebox->set_done(1);
359         return 1;
360 }
361
362
363
364 BC_FileBoxText::BC_FileBoxText(int x, int y, BC_FileBox *filebox)
365  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_text_images)
366 {
367         this->filebox = filebox;
368         set_tooltip(_("Display text"));
369 }
370 int BC_FileBoxText::handle_event()
371 {
372         filebox->create_listbox(filebox->listbox->get_x(), filebox->listbox->get_y(), LISTBOX_TEXT);
373         filebox->listbox->show_window(1);
374         return 1;
375 }
376
377
378 BC_FileBoxIcons::BC_FileBoxIcons(int x, int y, BC_FileBox *filebox)
379  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_icons_images)
380 {
381         this->filebox = filebox;
382         set_tooltip(_("Display icons"));
383 }
384 int BC_FileBoxIcons::handle_event()
385 {
386         filebox->create_listbox(filebox->listbox->get_x(), filebox->listbox->get_y(), LISTBOX_ICONS);
387         filebox->listbox->show_window(1);
388         return 1;
389 }
390
391
392 BC_FileBoxNewfolder::BC_FileBoxNewfolder(int x, int y, BC_FileBox *filebox)
393  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_newfolder_images)
394 {
395         this->filebox = filebox;
396         set_tooltip(_("Create new folder"));
397 }
398 int BC_FileBoxNewfolder::handle_event()
399 {
400         filebox->newfolder_thread->start_new_folder();
401         return 1;
402 }
403
404
405 BC_FileBoxRename::BC_FileBoxRename(int x, int y, BC_FileBox *filebox)
406  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_rename_images)
407 {
408         this->filebox = filebox;
409         set_tooltip(_("Rename file"));
410 }
411 int BC_FileBoxRename::handle_event()
412 {
413         filebox->rename_thread->start_rename();
414         return 1;
415 }
416
417 BC_FileBoxUpdir::BC_FileBoxUpdir(int x, int y, BC_FileBox *filebox)
418  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_updir_images)
419 {
420         this->filebox = filebox;
421         set_tooltip(_("Up a directory"));
422 }
423 int BC_FileBoxUpdir::handle_event()
424 {
425 // Need a temp so submit_file can expand it
426         sprintf(string, "..");
427         filebox->submit_file(string);
428         return 1;
429 }
430
431 BC_FileBoxDelete::BC_FileBoxDelete(int x, int y, BC_FileBox *filebox)
432  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_delete_images)
433 {
434         this->filebox = filebox;
435         set_tooltip(_("Delete files"));
436 }
437 int BC_FileBoxDelete::handle_event()
438 {
439         filebox->unlock_window();
440         filebox->delete_thread->start();
441         filebox->lock_window("BC_FileBoxDelete::handle_event");
442         return 1;
443 }
444
445 BC_FileBoxReload::BC_FileBoxReload(int x, int y, BC_FileBox *filebox)
446  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_reload_images)
447 {
448         this->filebox = filebox;
449         set_tooltip(_("Refresh"));
450 }
451 int BC_FileBoxReload::handle_event()
452 {
453         filebox->refresh();
454         return 1;
455 }
456
457
458
459 BC_FileBox::BC_FileBox(int x, int y, const char *init_path,
460                 const char *title, const char *caption, int show_all_files,
461                 int want_directory, int multiple_files, int h_padding)
462  : BC_Window(title, x, y,
463         BC_WindowBase::get_resources()->filebox_w,
464         BC_WindowBase::get_resources()->filebox_h,
465         400, 300, 1, 0, 1)
466 {
467         fs = new FileSystem;
468 //      if(want_directory)
469 //      {
470 //              fs->set_want_directory();
471 //              columns = DIRBOX_COLUMNS;
472 //              columns = FILEBOX_COLUMNS;
473 //      }
474 //      else
475         {
476                 columns = FILEBOX_COLUMNS;
477         }
478
479         list_column = new ArrayList<BC_ListBoxItem*>[columns];
480         column_type = new int[columns];
481         column_width = new int[columns];
482
483         filter_title = 0;
484         filter_text = 0;
485         filter_popup = 0;
486         usethis_button = 0;
487         size_format = BC_WindowBase::get_resources()->filebox_size_format;
488
489         strcpy(this->caption, caption);
490         strcpy(this->current_path, init_path);
491         strcpy(this->submitted_path, init_path);
492         select_multiple = multiple_files;
493         this->want_directory = want_directory;
494         if(show_all_files) fs->set_show_all();
495         fs->complete_path(this->current_path);
496         strcpy(this->submitted_path, this->current_path);
497         fs->extract_dir(directory, this->current_path);
498         fs->extract_name(filename, this->current_path);
499
500 // printf("BC_FileBox::BC_FileBox %d '%s' '%s' '%s'\n",
501 // __LINE__,
502 // this->submitted_path,
503 // directory,
504 // filename);
505
506 //      if(want_directory)
507 //      {
508 //              for(int i = 0; i < columns; i++)
509 //              {
510 //                      column_type[i] = get_resources()->dirbox_columntype[i];
511 //                      column_width[i] = get_resources()->dirbox_columnwidth[i];
512 //                      column_titles[i] = BC_FileBox::columntype_to_text(column_type[i]);
513 //              }
514 //              sort_column = get_resources()->dirbox_sortcolumn;
515 //              sort_order = get_resources()->dirbox_sortorder;
516 //      }
517 //      else
518         {
519                 for(int i = 0; i < columns; i++)
520                 {
521                         column_type[i] = get_resources()->filebox_columntype[i];
522                         column_width[i] = get_resources()->filebox_columnwidth[i];
523                         column_titles[i] = (char*)BC_FileBox::columntype_to_text(column_type[i]);
524                 }
525                 sort_column = get_resources()->filebox_sortcolumn;
526                 sort_order = get_resources()->filebox_sortorder;
527         }
528
529
530
531 // Test if current directory exists
532         if(!fs->is_dir(directory))
533         {
534                 sprintf(directory, "~");
535                 fs->complete_path(directory);
536                 strcpy(current_path,directory);
537                 filename[0] = 0;
538         }
539         fs->set_current_dir(directory);
540
541         if(h_padding == -1)
542         {
543                 h_padding = BC_WindowBase::get_resources()->ok_images[0]->get_h() -
544                         20;
545         }
546         this->h_padding = h_padding;
547         delete_thread = new BC_DeleteThread(this);
548         rename_thread = 0;
549         y_margin = 0;
550 }
551
552 BC_FileBox::~BC_FileBox()
553 {
554 // this has to be destroyed before tables, because it can call for an update!
555         delete newfolder_thread;
556         delete fs;
557         delete_tables();
558         for(int i = 0; i < TOTAL_ICONS; i++)
559                 delete icons[i];
560         filter_list.remove_all_objects();
561         delete [] list_column;
562         delete [] column_type;
563         delete [] column_width;
564         delete delete_thread;
565         delete rename_thread;
566         recent_dirs.remove_all_objects();
567 }
568
569 void BC_FileBox::create_objects()
570 {
571         lock_window("BC_FileBox::create_objects");
572         int x = 10, y = 10;
573         BC_Resources *resources = BC_WindowBase::get_resources();
574         int directory_title_margin = MAX(20,
575                 resources->filebox_text_images[0]->get_h());
576
577 // Directories aren't filtered in FileSystem so skip this
578         if(!want_directory)
579         {
580                 filter_list.append(new BC_ListBoxItem("*"));
581                 filter_list.append(new BC_ListBoxItem("[*.mkv][*.webm]"));
582                 filter_list.append(new BC_ListBoxItem("[*.mp4][*.MP4]"));
583                 filter_list.append(new BC_ListBoxItem("[*.mp2][*.mp3][*.wav]"));
584                 filter_list.append(new BC_ListBoxItem("[*.avi][*.mpg][*.m2v][*.m1v][*.mov]"));
585                 filter_list.append(new BC_ListBoxItem("[*.jpg][*.JPG][*.png][*.gif][*.tiff]"));
586                 filter_list.append(new BC_ListBoxItem("*.xml"));
587                 fs->set_filter(get_resources()->filebox_filter);
588         }
589
590         create_icons();
591         create_tables(0);
592
593         add_subwindow(ok_button = new BC_FileBoxOK(this));
594         if(want_directory)
595                 add_subwindow(usethis_button = new BC_FileBoxUseThis(this));
596         add_subwindow(cancel_button = new BC_FileBoxCancel(this));
597
598         add_subwindow(new BC_Title(x, y, caption));
599
600         x = get_w() - resources->filebox_icons_images[0]->get_w() - 10;
601
602         add_subwindow(icon_button = new BC_FileBoxIcons(x, y, this));
603         x -= resources->filebox_text_images[0]->get_w() + 5;
604
605         add_subwindow(text_button = new BC_FileBoxText(x, y, this));
606         x -= resources->filebox_newfolder_images[0]->get_w() + 5;
607
608         add_subwindow(folder_button = new BC_FileBoxNewfolder(x, y, this));
609         x -= resources->filebox_delete_images[0]->get_w() + 5;
610
611         add_subwindow(rename_button = new BC_FileBoxRename(x, y, this));
612         x -= resources->filebox_delete_images[0]->get_w() + 5;
613
614         add_subwindow(delete_button = new BC_FileBoxDelete(x, y, this));
615         x -= resources->filebox_reload_images[0]->get_w() + 5;
616
617         add_subwindow(reload_button = new BC_FileBoxReload(x, y, this));
618         x -= resources->filebox_updir_images[0]->get_w() + 5;
619
620         add_subwindow(updir_button = new BC_FileBoxUpdir(x, y, this));
621         x -= resources->filebox_szfmt_images[0]->get_w() + 5;
622
623         add_subwindow(szfmt_button = new BC_FileBoxSizeFormat(x, y, this));
624
625         x = 10;
626         y += directory_title_margin + 3;
627
628         add_subwindow(recent_popup = new BC_FileBoxRecent(this, x, y));
629         BC_Title *dir_title;
630         add_subwindow(dir_title = new BC_Title(x, y, _("Directory:")));
631         int x1 = x + dir_title->get_w() + 10, w1 = get_w()-x1 - recent_popup->get_w()-20;
632         add_subwindow(directory_title = new BC_FileBoxDirectoryText(x1, y, w1, this));
633         x1 += directory_title->get_w() + 8;
634         recent_popup->reposition_window(x1, y, directory_title->get_w(), 200);
635
636         x = 10;
637         y += directory_title->get_h() + 5;
638
639         BC_Title *search_title;
640         add_subwindow(search_title = new BC_Title(x, y, _("Search:")));
641         x += search_title->get_w() + 10;
642         add_subwindow(search_text = new BC_FileBoxSearchText(x, y, this));
643
644         x = 10;
645         y += search_text->get_h() + 5;
646
647         int newest_id = 0, newest = -1;
648         for(int i = 0; i < FILEBOX_HISTORY_SIZE; i++) {
649                 if( !resources->filebox_history[i].path[0] ) continue;
650                 if( resources->filebox_history[i].id > newest_id ) {
651                         newest_id = resources->filebox_history[i].id;
652                         newest = i;
653                 }
654         }
655         if( newest >= 0 ) {
656                 strcpy(directory, resources->filebox_history[newest].path);
657                 fs->change_dir(directory, 0);
658                 strcpy(directory, fs->get_current_dir());
659                 directory_title->update(fs->get_current_dir());
660         }
661         fs->set_sort_order(sort_order);
662         fs->set_sort_field(column_type[sort_column]);
663         fs->update(directory);
664
665 // Create recent dir list
666         create_history();
667         update_history();
668
669         listbox = 0;
670         create_listbox(x, y, get_display_mode());
671         y += listbox->get_h() + 10;
672         add_subwindow(file_title = new BC_Title(x, y, _("File:")));
673         x1 = x + file_title->get_w() + 10;
674         add_subwindow(textbox = new BC_FileBoxTextBox(x1, y, this));
675         y += textbox->get_h() + 10;
676
677         if(!want_directory) {
678                 add_subwindow(filter_title = new BC_Title(x, y, _("Specify filter:")));
679                 int x1 = x + filter_title->get_w() + 10;
680                 add_subwindow(filter_text = new BC_FileBoxFilterText(x1, y, this));
681                 add_subwindow(filter_popup =
682                         new BC_FileBoxFilterMenu(x1 + filter_text->get_w(), y, this));
683                 y += filter_text->get_h() + 10;
684         }
685         y_margin = y;
686
687 // listbox has to be active because refresh might be called from newfolder_thread
688         listbox->activate();
689         newfolder_thread = new BC_NewFolderThread(this);
690
691         rename_thread = new BC_RenameThread(this);
692
693         refresh();
694         show_window();
695         raise_window();
696         unlock_window();
697 }
698
699 int BC_FileBox::get_listbox_w()
700 {
701         return get_w() - 20;
702 }
703
704 int BC_FileBox::get_listbox_h(int y)
705 {
706         int result = get_h() - y - h_padding - 10;
707         if(want_directory)
708                 result -= BC_WindowBase::get_resources()->dirbox_margin;
709         else
710                 result -= BC_WindowBase::get_resources()->filebox_margin;
711
712         return result;
713 }
714
715 int BC_FileBox::create_icons()
716 {
717         for(int i = 0; i < TOTAL_ICONS; i++)
718         {
719                 icons[i] = new BC_Pixmap(this,
720                         BC_WindowBase::get_resources()->type_to_icon[i],
721                         PIXMAP_ALPHA);
722         }
723         return 0;
724 }
725
726 int BC_FileBox::resize_event(int w, int h)
727 {
728         draw_background(0, 0, w, h);
729         flash(0);
730
731 // OK button handles resize event itself
732 //      ok_button->reposition_window(ok_button->get_x(),
733 //              h - (get_h() - ok_button->get_y()));
734 //      cancel_button->reposition_window(w - (get_w() - cancel_button->get_x()),
735 //              h - (get_h() - cancel_button->get_y()));
736         if(usethis_button)
737                 usethis_button->reposition_window(w / 2 - 50,
738                         h - (get_h() - usethis_button->get_y()));
739
740
741         if(filter_popup) filter_popup->reposition_window(w - (get_w() - filter_popup->get_x()),
742                 h - (get_h() - filter_popup->get_y()),
743                 w - 30,
744                 0);
745
746         if(filter_title) filter_title->reposition_window(filter_title->get_x(),
747                 h - (get_h() - filter_title->get_y()));
748         if(filter_text) filter_text->reposition_window(filter_text->get_x(),
749                 h - (get_h() - filter_text->get_y()),
750                 w - (get_w() - filter_text->get_w()),
751                 1);
752         directory_title->reposition_window(
753                 directory_title->get_x(), directory_title->get_y(),
754                 get_w()-directory_title->get_x() - recent_popup->get_w()-20, 1);
755         recent_popup->reposition_window(
756                 directory_title->get_x() + directory_title->get_w() + 8,
757                 directory_title->get_y(),
758                 directory_title->get_w() + recent_popup->get_w(), 200);
759         search_text->reposition_window(
760                 search_text->get_x(),
761                 search_text->get_y(),
762                 get_w() - search_text->get_x() -  40,
763                 1);
764         file_title->reposition_window(file_title->get_x(),
765                 h - (get_h() - file_title->get_y()));
766         textbox->reposition_window(textbox->get_x(),
767                 h - (get_h() - textbox->get_y()),
768                 w - (get_w() - textbox->get_w()),
769                 1);
770         listbox->reposition_window(listbox->get_x(),
771                 listbox->get_y(),
772                 w - (get_w() - listbox->get_w()),
773                 h - (get_h() - listbox->get_h()),
774                 0);
775         int dx = w - get_w();
776         icon_button->reposition_window(icon_button->get_x()+dx, icon_button->get_y());
777         text_button->reposition_window(text_button->get_x()+dx, text_button->get_y());
778         folder_button->reposition_window(folder_button->get_x()+dx, folder_button->get_y());
779         rename_button->reposition_window(rename_button->get_x()+dx, rename_button->get_y());
780         reload_button->reposition_window(reload_button->get_x()+dx, reload_button->get_y());
781         delete_button->reposition_window(delete_button->get_x()+dx, delete_button->get_y());
782         updir_button->reposition_window(updir_button->get_x()+dx, updir_button->get_y());
783         szfmt_button->reposition_window(szfmt_button->get_x()+dx, szfmt_button->get_y());
784         set_w(w);  set_h(h);
785         get_resources()->filebox_w = get_w();
786         get_resources()->filebox_h = get_h();
787         y_margin = filter_text ?
788                 filter_text->get_y() + filter_text->get_h() + 10 :
789                 textbox->get_y() + textbox->get_h() + 10 ;
790         flush();
791         return 1;
792 }
793
794 int BC_FileBox::keypress_event()
795 {
796         switch(get_keypress()) {
797         case 'a':
798                 if( !ctrl_down() ) break;
799                 refresh(0, 1);
800                 return 1;
801         case 'z':
802                 if( !ctrl_down() ) break;
803                 refresh(0, 0);
804                 return 1;
805         case 'w':
806                 if( !ctrl_down() ) break;
807                 set_done(1);
808                 return 1;
809         }
810         return 0;
811 }
812
813 int BC_FileBox::close_event()
814 {
815         set_done(1);
816         return 1;
817 }
818
819 int BC_FileBox::handle_event()
820 {
821         return 0;
822 }
823
824 int BC_FileBox::extract_extension(char *out, const char *in)
825 {
826         *out = 0;
827         int i = strlen(in);
828         while( --i>=0 && in[i]!='.' );
829         if( i >= 0 ) strcpy(out, &in[++i]);
830         return 0;
831 }
832
833 static inline int64_t ipow(int m, int n)
834 {
835         int64_t v = 1;
836         for( int64_t vv=m; n>0; vv*=vv,n>>=1 ) if( n & 1 ) v *= vv;
837         return v;
838 }
839 static inline int ilen(int64_t v)
840 {
841         int len = 1;
842         while( len<16 && (v/=10)>0 ) ++len;
843         return len;
844 }
845
846 int BC_FileBox::create_tables(int select_all)
847 {
848         int preload_textbox = select_all;
849         delete_tables();
850         char string[BCTEXTLEN];
851         BC_ListBoxItem *new_item;
852
853         fs->set_sort_order(sort_order);
854         fs->set_sort_field(column_type[sort_column]);
855
856         for(int i = 0; i < fs->total_files(); i++)
857         {
858                 FileItem *file_item = fs->get_entry(i);
859                 const char *text = search_text->get_text();
860                 if( text && text[0] && !bstrcasestr(file_item->name, text) )
861                         continue;
862                 int is_dir = file_item->is_dir;
863                 BC_Pixmap* icon = get_icon(file_item->name, is_dir);
864
865 // Name entry
866                 new_item = new BC_ListBoxItem(file_item->name,
867                         icon,
868                         is_dir ? get_resources()->directory_color : get_resources()->file_color);
869                 if(is_dir) new_item->set_searchable(0);
870                 list_column[column_of_type(FILEBOX_NAME)].append(new_item);
871
872 // Size entry
873 //              if(!want_directory)
874 //              {
875                         if(!is_dir)
876                         {
877                                 if( preload_textbox ) {
878                                         preload_textbox = 0;
879                                         textbox->update(new_item->get_text());
880                                 }
881                                 int64_t size = file_item->size;
882                                 if( (size_format == FILEBOX_SIZE_1000 && size >= 1000) ||
883                                     (size_format == FILEBOX_SIZE_1024 && size >= 1024) ) {
884                                         static const char *suffix[] = { "", "K", "M", "G", "T", "P" };
885                                         if( size_format == FILEBOX_SIZE_1024 ) {
886                                                 static const long double kk = logl(1000.)/logl(1024.);
887                                                 size = expl(kk*logl((long double)size)) + 0.5;
888                                         }
889                                         int len = ilen(size), drop = len-3, round = 1;
890                                         if( round && drop > 0 ) { //round
891                                                 size += ipow(10,drop)/2;
892                                                 len = ilen(size);  drop = len-3;
893                                         }
894                                         size /= ipow(10,drop);
895                                         int sfx = (len-1)/3;
896                                         int digits = (sfx+1)*3 - len;
897                                         int64_t frac = ipow(10,digits);
898                                         int mant  = size / frac;
899                                         int fraction = size - mant*frac;
900                                         sfx = *suffix[sfx];
901                                         if( sfx && size_format == FILEBOX_SIZE_1000 ) sfx += 'a'-'A';
902                                         if( digits )
903                                                 sprintf(string, "%d.%0*d%c", mant, digits, fraction, sfx);
904                                         else
905                                                 sprintf(string, "%d%c", mant, sfx);
906                                 }
907                                 else {
908                                         sprintf(string, "%jd", size);
909                                         if( size_format == FILEBOX_SIZE_THOU )
910                                                 Units::punctuate(string);
911                                 }
912                                 new_item = new BC_ListBoxItem(string, get_resources()->file_color);
913                         }
914                         else
915                         {
916                                 new_item = new BC_ListBoxItem("", get_resources()->directory_color);
917                         }
918
919                         list_column[column_of_type(FILEBOX_SIZE)].append(new_item);
920 //              }
921
922 // Date entry
923                 if(!is_dir || 1)
924                 {
925                         struct tm mod_time;
926                         localtime_r(&file_item->mtime, &mod_time);
927                         sprintf(string, "%04d.%02d.%02d  %02d:%02d:%02d",
928                                 mod_time.tm_year+1900, mod_time.tm_mon+1, mod_time.tm_mday,
929                                 mod_time.tm_hour, mod_time.tm_min, mod_time.tm_sec);
930                         new_item = new BC_ListBoxItem(string, get_resources()->file_color);
931                 }
932                 else
933                 {
934                         new_item = new BC_ListBoxItem("", get_resources()->directory_color);
935                 }
936
937                 list_column[column_of_type(FILEBOX_DATE)].append(new_item);
938
939 // Extension entry
940 //              if(!want_directory)
941 //              {
942                         if(!is_dir) {
943                                 extract_extension(string, file_item->name);
944                                 new_item = new BC_ListBoxItem(string, get_resources()->file_color);
945                         }
946                         else {
947                                 new_item = new BC_ListBoxItem("", get_resources()->directory_color);
948                         }
949                         list_column[column_of_type(FILEBOX_EXTENSION)].append(new_item);
950 //              }
951
952                 if( !is_dir && select_all ) {
953                         int k = list_column[0].size()-1;
954                         for( int j=0; j<columns; ++j )
955                                 list_column[j][k]->set_selected(1);
956                 }
957         }
958
959         return 0;
960 }
961
962 int BC_FileBox::delete_tables()
963 {
964         for(int j = 0; j < columns; j++)
965         {
966                 list_column[j].remove_all_objects();
967         }
968         return 0;
969 }
970
971 BC_Pixmap* BC_FileBox::get_icon(char *path, int is_dir)
972 {
973         if( is_dir ) return icons[ICON_FOLDER];
974         int icon_type = ICON_UNKNOWN;
975         char *suffix = strrchr(path, '.');
976         if( suffix && *++suffix ) {
977                 suffix_to_type_t *stp = &BC_WindowBase::get_resources()->suffix_to_type[0];
978                 while( stp->suffix && strcasecmp(stp->suffix, suffix) ) ++stp;
979                 if( stp->icon_type ) icon_type = stp->icon_type;
980         }
981
982         return icons[icon_type];
983 }
984
985 const char* BC_FileBox::columntype_to_text(int type)
986 {
987         switch(type) {
988                 case FILEBOX_NAME: return FILEBOX_NAME_TEXT;
989                 case FILEBOX_SIZE: return FILEBOX_SIZE_TEXT;
990                 case FILEBOX_DATE: return FILEBOX_DATE_TEXT;
991                 case FILEBOX_EXTENSION: return FILEBOX_EXTENSION_TEXT;
992         }
993         return "";
994 }
995
996 int BC_FileBox::column_of_type(int type)
997 {
998         for(int i = 0; i < columns; i++)
999                 if(column_type[i] == type) return i;
1000         return 0;
1001 }
1002
1003
1004
1005 int BC_FileBox::refresh(int reset, int select_all)
1006 {
1007         fs->set_sort_order(sort_order);
1008         fs->set_sort_field(column_type[sort_column]);
1009         if( reset >= 0 )
1010                 fs->update(0);
1011         else
1012                 fs->update_sort();
1013         create_tables(select_all);
1014         listbox->set_master_column(column_of_type(FILEBOX_NAME), 0);
1015         listbox->update(list_column, column_titles, column_width, columns,
1016                 reset>0 ? 0 : listbox->get_xposition(),
1017                 reset>0 ? 0 : listbox->get_yposition(),
1018                 -1, 1);
1019         return 0;
1020 }
1021
1022 int BC_FileBox::update_filter(const char *filter)
1023 {
1024         fs->set_filter(filter);
1025 //      fs->update(0);
1026         refresh();
1027         strcpy(get_resources()->filebox_filter, filter);
1028
1029         return 0;
1030 }
1031
1032
1033 void BC_FileBox::move_column(int src, int dst)
1034 {
1035         if(src != dst)
1036         {
1037                 ArrayList<BC_ListBoxItem*> *new_columns =
1038                         new ArrayList<BC_ListBoxItem*>[columns];
1039                 int *new_types = new int[columns];
1040                 int *new_widths = new int[columns];
1041
1042         // Fill in remaining columns with consecutive data
1043                 for(int out_column = 0, in_column = 0;
1044                         out_column < columns;
1045                         out_column++,
1046                         in_column++)
1047                 {
1048         // Copy destination column from src column
1049                         if(out_column == dst)
1050                         {
1051                                 for(int i = 0; i < list_column[src].total; i++)
1052                                 {
1053                                         new_columns[out_column].append(list_column[src].values[i]);
1054                                 }
1055                                 new_types[out_column] = column_type[src];
1056                                 new_widths[out_column] = column_width[src];
1057                                 in_column--;
1058                         }
1059                         else
1060                         {
1061         // Skip source column
1062                                 if(in_column == src) in_column++;
1063                                 for(int i = 0; i < list_column[src].total; i++)
1064                                 {
1065                                         new_columns[out_column].append(list_column[in_column].values[i]);
1066                                 }
1067                                 new_types[out_column] = column_type[in_column];
1068                                 new_widths[out_column] = column_width[in_column];
1069                         }
1070                 }
1071
1072         // Swap tables
1073                 delete [] list_column;
1074                 delete [] column_type;
1075                 delete [] column_width;
1076                 list_column = new_columns;
1077                 column_type = new_types;
1078                 column_width = new_widths;
1079
1080                 for(int i = 0; i < columns; i++)
1081                 {
1082                         get_resources()->filebox_columntype[i] = column_type[i];
1083                         get_resources()->filebox_columnwidth[i] = column_width[i];
1084                         column_titles[i] = (char*)BC_FileBox::columntype_to_text(column_type[i]);
1085                 }
1086         }
1087
1088         refresh();
1089 }
1090
1091
1092 int BC_FileBox::submit_dir(char *dir)
1093 {
1094         strcpy(directory, dir);
1095         fs->join_names(current_path, directory, filename);
1096
1097 // printf("BC_FileBox::submit_dir %d '%s' '%s' '%s'\n",
1098 // __LINE__,
1099 // current_path,
1100 // directory,
1101 // filename);
1102         strcpy(submitted_path, current_path);
1103         fs->change_dir(dir, 0);
1104         refresh(1);
1105         directory_title->update(fs->get_current_dir());
1106         if(want_directory)
1107                 textbox->update(fs->get_current_dir());
1108         else
1109                 textbox->update(filename);
1110         listbox->reset_query();
1111         return 0;
1112 }
1113
1114 int BC_FileBox::submit_file(const char *path, int use_this)
1115 {
1116         char path1[BCTEXTLEN];
1117         strcpy(path1, path);
1118         char *cp = strchr(path1,'\n');
1119         if( cp ) *cp = 0;
1120
1121 // Deactivate textbox to hide suggestions
1122         textbox->deactivate();
1123
1124 // If file wanted, take the current directory as the desired file.
1125 // If directory wanted, ignore it.
1126         if(!path1[0] && !want_directory)
1127         {
1128 // save complete path
1129                 strcpy(this->current_path, directory);
1130 // save complete path
1131                 strcpy(this->submitted_path, directory);
1132                 update_history();
1133 // Zero out filename
1134                 filename[0] = 0;
1135                 set_done(0);
1136                 return 0;
1137         }
1138
1139 // is a directory, change directories
1140         if(fs->is_dir(path1) && !use_this)
1141         {
1142                 fs->change_dir(path1, 0);
1143                 refresh(1);
1144                 directory_title->update(fs->get_current_dir());
1145                 strcpy(this->current_path, fs->get_current_dir());
1146                 strcpy(this->submitted_path, fs->get_current_dir());
1147                 strcpy(this->directory, fs->get_current_dir());
1148                 update_history();
1149                 filename[0] = 0;
1150                 if(want_directory)
1151                         textbox->update(fs->get_current_dir());
1152                 else
1153                         textbox->update("");
1154                 listbox->reset_query();
1155                 return 1;
1156         }
1157         else
1158 // Is a file or desired directory.  Quit the operation.
1159         {
1160                 char path2[BCTEXTLEN];
1161                 strcpy(path2, path1);
1162
1163 // save directory for defaults
1164                 fs->extract_dir(directory, path2);
1165
1166 // Just take the directory
1167                 if(want_directory)
1168                 {
1169                         filename[0] = 0;
1170                         strcpy(path2, directory);
1171                 }
1172                 else
1173 // Take the complete path
1174                 {
1175                         fs->extract_name(filename, path2);     // save filename
1176                 }
1177
1178                 fs->complete_path(path2);
1179                 strcpy(this->current_path, path2);          // save complete path
1180                 strcpy(this->submitted_path, path2);          // save complete path
1181                 update_history();
1182                 newfolder_thread->interrupt();
1183                 set_done(0);
1184                 return 0;
1185         }
1186         return 0;
1187 }
1188
1189 void BC_FileBox::update_history()
1190 {
1191 // Look for path already in history
1192         BC_Resources *resources = get_resources();
1193         char path[BCTEXTLEN];
1194         strcpy(path, directory);
1195 // enfore one trailing slash
1196         char *cp = path;
1197         while( *cp && *cp != '\n' ) ++cp;
1198         while( cp > path && *(cp-1) == '/' ) --cp;
1199         *cp++ = '/';  *cp = 0;
1200
1201 //      int new_slot = FILEBOX_HISTORY_SIZE - 1;
1202
1203         for(int i = FILEBOX_HISTORY_SIZE - 1; i >= 0; i--)
1204         {
1205                 if(resources->filebox_history[i].path[0] &&
1206                         !strcmp(resources->filebox_history[i].path, path))
1207                 {
1208 // Got matching path.
1209 // Update ID.
1210                         resources->filebox_history[i].id = resources->get_filebox_id();
1211                         return;
1212                 }
1213 // // Shift down from this point.
1214 //                      while(i > 0)
1215 //                      {
1216 //                              strcpy(resources->filebox_history[i],
1217 //                                      resources->filebox_history[i - 1]);
1218 //                              if(resources->filebox_history[i][0]) new_slot--;
1219 //                              i--;
1220 //                      }
1221 //                      break;
1222 //              }
1223 //              else
1224 //                      if(resources->filebox_history[i][0])
1225 //                              new_slot--;
1226 //              else
1227 //                      break;
1228         }
1229
1230 // Remove oldest entry if full
1231         if(resources->filebox_history[FILEBOX_HISTORY_SIZE - 1].path[0])
1232         {
1233                 int oldest_id = 0x7fffffff;
1234                 int oldest = 0;
1235                 for(int i = 0; i < FILEBOX_HISTORY_SIZE; i++)
1236                 {
1237                         if(resources->filebox_history[i].path[0] &&
1238                                 resources->filebox_history[i].id < oldest_id)
1239                         {
1240                                 oldest_id = resources->filebox_history[i].id;
1241                                 oldest = i;
1242                         }
1243                 }
1244
1245                 for(int i = oldest; i < FILEBOX_HISTORY_SIZE - 1; i++)
1246                 {
1247                         strcpy(resources->filebox_history[i].path,
1248                                 resources->filebox_history[i + 1].path);
1249                         resources->filebox_history[i].id =
1250                                 resources->filebox_history[i + 1].id;
1251                 }
1252         }
1253
1254 // Create new entry
1255         strcpy(resources->filebox_history[FILEBOX_HISTORY_SIZE - 1].path, path);
1256         resources->filebox_history[FILEBOX_HISTORY_SIZE - 1].id = resources->get_filebox_id();
1257
1258 // Alphabetize
1259         int done = 0;
1260         while(!done)
1261         {
1262                 done = 1;
1263                 for(int i = 1; i < FILEBOX_HISTORY_SIZE; i++)
1264                 {
1265                         if( (resources->filebox_history[i - 1].path[0] &&
1266                                 resources->filebox_history[i].path[0] &&
1267                                 strcasecmp(resources->filebox_history[i - 1].path,
1268                                         resources->filebox_history[i].path) > 0) ||
1269                                 (resources->filebox_history[i - 1].path[0] == 0 &&
1270                                         resources->filebox_history[i].path[0]) )
1271                         {
1272                                 done = 0;
1273                                 char temp[BCTEXTLEN];
1274                                 int id_temp;
1275                                 strcpy(temp, resources->filebox_history[i - 1].path);
1276                                 id_temp = resources->filebox_history[i - 1].id;
1277                                 strcpy(resources->filebox_history[i - 1].path,
1278                                         resources->filebox_history[i].path);
1279                                 resources->filebox_history[i - 1].id =
1280                                         resources->filebox_history[i].id;
1281                                 strcpy(resources->filebox_history[i].path, temp);
1282                                 resources->filebox_history[i].id = id_temp;
1283                         }
1284                 }
1285         }
1286
1287 //      if(new_slot < 0)
1288 //      {
1289 //              for(int i = FILEBOX_HISTORY_SIZE - 1; i > 0; i--)
1290 //              {
1291 //                      strcpy(resources->filebox_history[i],
1292 //                                      resources->filebox_history[i - 1]);
1293 //              }
1294 //              new_slot = 0;
1295 //      }
1296 //
1297 //      strcpy(resources->filebox_history[new_slot], path);
1298
1299         create_history();
1300         recent_popup->update(&recent_dirs, 0, 0, 1);
1301 }
1302
1303 void BC_FileBox::create_history()
1304 {
1305         BC_Resources *resources = get_resources();
1306         recent_dirs.remove_all_objects();
1307         for(int i = 0; i < FILEBOX_HISTORY_SIZE; i++) {
1308                 if(resources->filebox_history[i].path[0]) {
1309                         recent_dirs.append(new BC_ListBoxItem(resources->filebox_history[i].path));
1310                 }
1311         }
1312 }
1313
1314
1315 int BC_FileBox::get_display_mode()
1316 {
1317         return top_level->get_resources()->filebox_mode;
1318 }
1319
1320 void BC_FileBox::create_listbox(int x, int y, int mode)
1321 {
1322         if(listbox && listbox->get_display_mode() != mode)
1323         {
1324                 delete listbox;
1325                 listbox = 0;
1326                 top_level->get_resources()->filebox_mode = mode;
1327         }
1328
1329         if(!listbox)
1330                 add_subwindow(listbox = new BC_FileBoxListBox(x, y, this));
1331 }
1332
1333 int BC_FileBox::get_y_margin()
1334 {
1335         return y_margin;
1336 }
1337
1338 char* BC_FileBox::get_path(int selection)
1339 {
1340         if(selection == 0)
1341         {
1342                 return get_submitted_path();
1343         }
1344         else
1345         {
1346                 BC_ListBoxItem *item = listbox->get_selection(
1347                         column_of_type(FILEBOX_NAME), selection - 1);
1348                 if(item)
1349                 {
1350                         fs->join_names(string, directory, item->get_text());
1351                         return string;
1352                 }
1353         }
1354         return 0;
1355 }
1356
1357 char* BC_FileBox::get_submitted_path()
1358 {
1359         return submitted_path;
1360 }
1361
1362 char* BC_FileBox::get_current_path()
1363 {
1364 //printf("BC_FileBox::get_current_path 1 %s\n", current_path);
1365         return current_path;
1366 }
1367
1368 char* BC_FileBox::get_newfolder_title()
1369 {
1370         char *letter2 = strchr(title, ':');
1371         new_folder_title[0] = 0;
1372         if(letter2)
1373         {
1374                 memcpy(new_folder_title, title, letter2 - title);
1375                 new_folder_title[letter2 - title] = 0;
1376         }
1377
1378         strcat(new_folder_title, _(": New folder"));
1379
1380         return new_folder_title;
1381 }
1382
1383 char* BC_FileBox::get_rename_title()
1384 {
1385         char *letter2 = strchr(title, ':');
1386         new_folder_title[0] = 0;
1387         if(letter2)
1388         {
1389                 memcpy(new_folder_title, title, letter2 - title);
1390                 new_folder_title[letter2 - title] = 0;
1391         }
1392
1393         strcat(new_folder_title, _(": Rename"));
1394
1395         return new_folder_title;
1396 }
1397
1398 char* BC_FileBox::get_delete_title()
1399 {
1400         char *letter2 = strchr(title, ':');
1401         new_folder_title[0] = 0;
1402         if(letter2)
1403         {
1404                 memcpy(new_folder_title, title, letter2 - title);
1405                 new_folder_title[letter2 - title] = 0;
1406         }
1407
1408         strcat(new_folder_title, _(": Delete"));
1409
1410         return new_folder_title;
1411 }
1412
1413 void BC_FileBox::delete_files()
1414 {
1415 // Starting at 1 causes it to ignore what's in the textbox.
1416         int i = 1;
1417         char *path;
1418         FileSystem fs;
1419         while((path = get_path(i)))
1420         {
1421 // Not directory.  Remove it.
1422                 if(!fs.is_dir(path))
1423                 {
1424 //printf("BC_FileBox::delete_files: removing \"%s\"\n", path);
1425                         remove(path);
1426                 }
1427                 i++;
1428         }
1429         refresh();
1430 }
1431
1432 BC_Button* BC_FileBox::get_ok_button()
1433 {
1434         return ok_button;
1435 }
1436
1437 BC_Button* BC_FileBox::get_cancel_button()
1438 {
1439         return cancel_button;
1440 }
1441