2 #include "bclistboxitem.h"
4 #include "bcresources.h"
8 #include "filesystem.h"
12 #include "bcrecentlist.h"
17 #define DIRECTORY_COLOR BLUE
18 #define FILE_COLOR BLACK
20 BC_NewFolder::BC_NewFolder(int x, int y, BC_FileBox *filebox)
21 : BC_Window(filebox->get_newfolder_title(),
34 BC_NewFolder::~BC_NewFolder()
39 int BC_NewFolder::create_objects()
42 add_tool(new BC_Title(x, y, _("Enter the name of the folder:")));
44 add_subwindow(textbox = new BC_TextBox(x, y, 300, 1, _("Untitled")));
46 add_subwindow(new BC_OKButton(this));
48 add_subwindow(new BC_CancelButton(this));
53 char* BC_NewFolder::get_text()
55 return textbox->get_text();
59 BC_NewFolderThread::BC_NewFolderThread(BC_FileBox *filebox)
62 this->filebox = filebox;
64 change_lock = new Mutex("BC_NewFolderThread::change_lock");
65 completion_lock = new Condition(1, "BC_NewFolderThread::completion_lock");
68 BC_NewFolderThread::~BC_NewFolderThread()
72 delete completion_lock;
75 void BC_NewFolderThread::run()
77 int x = filebox->get_abs_cursor_x(1);
78 int y = filebox->get_abs_cursor_y(1);
79 change_lock->lock("BC_NewFolderThread::run 1");
80 window = new BC_NewFolder(x,
83 window->create_objects();
84 change_lock->unlock();
87 int result = window->run_window();
91 char new_folder[BCTEXTLEN];
92 filebox->fs->join_names(new_folder, filebox->fs->get_current_dir(), window->get_text());
93 mkdir(new_folder, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
94 filebox->lock_window("BC_NewFolderThread::run");
96 filebox->unlock_window();
99 change_lock->lock("BC_NewFolderThread::run 2");
102 change_lock->unlock();
104 completion_lock->unlock();
107 int BC_NewFolderThread::interrupt()
109 change_lock->lock("BC_NewFolderThread::interrupt");
112 window->lock_window("BC_NewFolderThread::interrupt");
114 window->unlock_window();
117 change_lock->unlock();
119 completion_lock->lock("BC_NewFolderThread::interrupt");
120 completion_lock->unlock();
124 int BC_NewFolderThread::start_new_folder()
130 window->lock_window("BC_NewFolderThread::start_new_folder");
131 window->raise_window();
132 window->unlock_window();
133 change_lock->unlock();
137 change_lock->unlock();
138 completion_lock->lock("BC_NewFolderThread::start_new_folder");
153 BC_FileBoxListBox::BC_FileBoxListBox(int x, int y, BC_FileBox *filebox)
156 filebox->get_listbox_w(),
157 filebox->get_listbox_h(y),
158 filebox->get_display_mode(),
159 filebox->list_column,
160 filebox->column_titles,
161 filebox->column_width,
165 filebox->select_multiple ? LISTBOX_MULTIPLE : LISTBOX_SINGLE,
169 this->filebox = filebox;
170 set_sort_column(filebox->sort_column);
171 set_sort_order(filebox->sort_order);
172 set_allow_drag_column(1);
175 BC_FileBoxListBox::~BC_FileBoxListBox()
179 int BC_FileBoxListBox::handle_event()
181 filebox->submit_file(filebox->textbox->get_text(), 0);
185 int BC_FileBoxListBox::selection_changed()
187 BC_ListBoxItem *item = get_selection(
188 filebox->column_of_type(FILEBOX_NAME), 0);
191 filebox->textbox->update(item->get_text());
195 int BC_FileBoxListBox::column_resize_event()
197 for(int i = 0; i < FILEBOX_COLUMNS; i++)
198 BC_WindowBase::get_resources()->filebox_columnwidth[i] =
199 filebox->column_width[i] =
204 int BC_FileBoxListBox::sort_order_event()
206 get_resources()->filebox_sortcolumn = filebox->sort_column = get_sort_column();
207 get_resources()->filebox_sortorder = filebox->sort_order = get_sort_order();
212 int BC_FileBoxListBox::move_column_event()
214 filebox->move_column(get_from_column(), get_to_column());
218 int BC_FileBoxListBox::evaluate_query(int list_item, char *string)
220 ArrayList<BC_ListBoxItem*> *column =
221 &filebox->list_column[filebox->column_of_type(FILEBOX_NAME)];
222 return(column->values[list_item]->get_color() != DIRECTORY_COLOR &&
223 strcmp(string, column->values[list_item]->get_text()) <= 0);
229 BC_FileBoxTextBox::BC_FileBoxTextBox(int x, int y, BC_FileBox *filebox)
230 : BC_TextBox(x, y, filebox->get_w() - 50, 1, filebox->filename)
232 this->filebox = filebox;
235 BC_FileBoxTextBox::~BC_FileBoxTextBox()
239 int BC_FileBoxTextBox::handle_event()
245 BC_FileBoxDirectoryText::BC_FileBoxDirectoryText(int x, int y, BC_FileBox *filebox)
246 : BC_TextBox(x, y, filebox->get_w() - 183, 1, filebox->fs->get_current_dir())
248 this->filebox = filebox;
251 int BC_FileBoxDirectoryText::handle_event()
255 // is a directory, change directories
256 if(!filebox->fs->is_dir(path))
258 filebox->fs->change_dir(path);
260 update(strcat(filebox->fs->get_current_dir(),"/"));
261 filebox->refresh_fs_change();
266 BC_FileBoxFilterText::BC_FileBoxFilterText(int x, int y, BC_FileBox *filebox)
267 : BC_TextBox(x, y, filebox->get_w() - 50, 1, filebox->get_resources()->filebox_filter)
269 this->filebox = filebox;
272 int BC_FileBoxFilterText::handle_event()
274 filebox->update_filter(get_text());
279 BC_FileBoxFilterMenu::BC_FileBoxFilterMenu(int x, int y, BC_FileBox *filebox)
282 filebox->get_w() - 30,
285 &filebox->filter_list,
292 this->filebox = filebox;
293 set_tooltip(_("Change the filter"));
296 int BC_FileBoxFilterMenu::handle_event()
298 filebox->filter_text->update(
299 get_selection(filebox->column_of_type(FILEBOX_NAME), 0)->get_text());
300 filebox->update_filter(
301 get_selection(filebox->column_of_type(FILEBOX_NAME), 0)->get_text());
314 BC_FileBoxCancel::BC_FileBoxCancel(BC_FileBox *filebox)
315 : BC_CancelButton(filebox)
317 this->filebox = filebox;
318 set_tooltip(_("Cancel the operation"));
321 BC_FileBoxCancel::~BC_FileBoxCancel()
325 int BC_FileBoxCancel::handle_event()
327 // filebox->submit_file(filebox->textbox->get_text(), 0);
328 filebox->newfolder_thread->interrupt();
329 filebox->set_done(1);
339 BC_FileBoxUseThis::BC_FileBoxUseThis(BC_FileBox *filebox)
340 : BC_Button(filebox->get_w() / 2 - 50,
341 filebox->get_h() - 35,
342 BC_WindowBase::get_resources()->usethis_button_images)
344 this->filebox = filebox;
345 set_tooltip(_("Submit the directory"));
348 BC_FileBoxUseThis::~BC_FileBoxUseThis()
352 int BC_FileBoxUseThis::handle_event()
354 filebox->submit_file(filebox->textbox->get_text(), 0, 1);
362 BC_FileBoxOK::BC_FileBoxOK(BC_FileBox *filebox)
363 : BC_OKButton(filebox)
365 this->filebox = filebox;
366 set_tooltip(_("Submit the file"));
369 BC_FileBoxOK::~BC_FileBoxOK()
373 int BC_FileBoxOK::handle_event()
375 filebox->submit_file(filebox->textbox->get_text(), 0);
384 BC_FileBoxText::BC_FileBoxText(int x, int y, BC_FileBox *filebox)
385 : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_text_images)
387 this->filebox = filebox;
388 set_tooltip(_("Display text"));
390 int BC_FileBoxText::handle_event()
392 filebox->create_listbox(filebox->listbox->get_x(), filebox->listbox->get_y(), LISTBOX_TEXT);
397 BC_FileBoxIcons::BC_FileBoxIcons(int x, int y, BC_FileBox *filebox)
398 : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_icons_images)
400 this->filebox = filebox;
401 set_tooltip(_("Display icons"));
403 int BC_FileBoxIcons::handle_event()
405 filebox->create_listbox(filebox->listbox->get_x(), filebox->listbox->get_y(), LISTBOX_ICONS);
410 BC_FileBoxNewfolder::BC_FileBoxNewfolder(int x, int y, BC_FileBox *filebox)
411 : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_newfolder_images)
413 this->filebox = filebox;
414 set_tooltip(_("Create new folder"));
416 int BC_FileBoxNewfolder::handle_event()
418 filebox->newfolder_thread->start_new_folder();
422 BC_FileBoxUpdir::BC_FileBoxUpdir(int x, int y, BC_FileBox *filebox)
423 : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_updir_images)
425 this->filebox = filebox;
426 set_tooltip(_("Up a directory"));
428 int BC_FileBoxUpdir::handle_event()
430 // Need a temp so submit_file can expand it
431 sprintf(string, _(".."));
432 filebox->submit_file(string, 0);
443 BC_FileBox::BC_FileBox(int x,
449 const char *recent_prefix,
457 BC_WindowBase::get_resources()->filebox_w,
458 BC_WindowBase::get_resources()->filebox_h,
466 list_column = new ArrayList<BC_ListBoxItem*>[FILEBOX_COLUMNS];
467 column_type = new int[FILEBOX_COLUMNS];
468 column_width = new int[FILEBOX_COLUMNS];
473 strcpy(this->caption, caption);
474 strcpy(this->current_path, init_path);
475 strcpy(this->submitted_path, init_path);
476 select_multiple = multiple_files;
477 this->want_directory = want_directory;
478 if(show_all_files) fs->set_show_all();
479 if(want_directory) fs->set_want_directory();
480 fs->complete_path(this->current_path);
481 fs->complete_path(this->submitted_path);
482 fs->extract_dir(directory, this->current_path);
483 fs->extract_name(filename, this->current_path);
486 for(int i = 0; i < FILEBOX_COLUMNS; i++)
488 column_type[i] = get_resources()->filebox_columntype[i];
489 column_width[i] = get_resources()->filebox_columnwidth[i];
490 column_titles[i] = BC_FileBox::columntype_to_text(column_type[i]);
493 sort_column = get_resources()->filebox_sortcolumn;
494 sort_order = get_resources()->filebox_sortorder;
497 if(fs->update(directory))
499 sprintf(this->current_path, "~");
500 fs->complete_path(this->current_path);
501 fs->update(this->current_path);
502 strcpy(directory, fs->get_current_dir());
503 sprintf(filename, "");
507 this->h_padding = h_padding;
508 this->defaults = defaults;
509 this->recent_prefix = recent_prefix;
513 BC_FileBox::~BC_FileBox()
515 // this has to be destroyed before tables, because it can call for an update!
516 delete newfolder_thread;
519 for(int i = 0; i < TOTAL_ICONS; i++)
521 filter_list.remove_all_objects();
522 delete [] list_column;
523 delete [] column_type;
524 delete [] column_width;
525 if (recent) delete recent;
528 int BC_FileBox::create_objects()
532 filter_list.append(new BC_ListBoxItem("*"));
533 filter_list.append(new BC_ListBoxItem("[*.ifo][*.vob]"));
534 filter_list.append(new BC_ListBoxItem("[*.mp2][*.mp3][*.wav]"));
535 filter_list.append(new BC_ListBoxItem("[*.avi][*.mpg][*.m2v][*.m1v][*.mov]"));
536 filter_list.append(new BC_ListBoxItem("heroine*"));
537 filter_list.append(new BC_ListBoxItem("*.xml"));
538 fs->set_filter(get_resources()->filebox_filter);
539 fs->update(directory);
543 add_subwindow(ok_button = new BC_FileBoxOK(this));
545 add_subwindow(usethis_button = new BC_FileBoxUseThis(this));
546 add_subwindow(cancel_button = new BC_FileBoxCancel(this));
548 add_subwindow(new BC_Title(x, y, caption));
549 add_subwindow(directory_title = new BC_FileBoxDirectoryText(x, y + 20, this));
551 add_subwindow(icon_button = new BC_FileBoxIcons(x, y, this));
552 x -= icon_button->get_w();
553 add_subwindow(text_button = new BC_FileBoxText(x, y, this));
554 x -= text_button->get_w();
555 add_subwindow(folder_button = new BC_FileBoxNewfolder(x, y, this));
556 x -= folder_button->get_w();
557 add_subwindow(updir_button = new BC_FileBoxUpdir(x, y, this));
560 y = MAX(updir_button->get_y() + updir_button->get_h() + 5,
561 directory_title->get_h() + directory_title->get_y());
564 create_listbox(x, y, get_display_mode());
565 y += listbox->get_h() + 10;
566 add_subwindow(textbox = new BC_FileBoxTextBox(x, y, this));
568 recent = new BC_RecentList("PATH", defaults, textbox);
569 add_subwindow(recent);
570 recent->load_items(recent_prefix);
573 y += textbox->get_h() + 10;
574 add_subwindow(filter_text = new BC_FileBoxFilterText(x, y, this));
575 add_subwindow(filter_popup =
576 new BC_FileBoxFilterMenu(x + filter_text->get_w(), y, this));
578 // listbox has to be active because refresh might be called from newfolder_thread
580 newfolder_thread = new BC_NewFolderThread(this);
586 int BC_FileBox::get_listbox_w()
591 int BC_FileBox::get_listbox_h(int y)
593 return get_h() - y - h_padding - 110;
596 int BC_FileBox::create_icons()
598 for(int i = 0; i < TOTAL_ICONS; i++)
600 icons[i] = new BC_Pixmap(this,
601 BC_WindowBase::get_resources()->type_to_icon[i],
607 int BC_FileBox::resize_event(int w, int h)
609 draw_background(0, 0, w, h);
612 // OK button handles resize event itself
613 // ok_button->reposition_window(ok_button->get_x(),
614 // h - (get_h() - ok_button->get_y()));
615 // cancel_button->reposition_window(w - (get_w() - cancel_button->get_x()),
616 // h - (get_h() - cancel_button->get_y()));
618 usethis_button->reposition_window(w / 2 - 50, h - (get_h() - usethis_button->get_y()));
619 filter_popup->reposition_window(w - (get_w() - filter_popup->get_x()),
620 h - (get_h() - filter_popup->get_y()),
622 filter_text->reposition_window(filter_text->get_x(),
623 h - (get_h() - filter_text->get_y()),
624 w - (get_w() - filter_text->get_w()),
626 directory_title->reposition_window(directory_title->get_x(),
627 directory_title->get_y(),
630 textbox->reposition_window(textbox->get_x(),
631 h - (get_h() - textbox->get_y()),
632 w - (get_w() - textbox->get_w()),
634 recent->reposition_window(textbox->get_x() + textbox->get_w(),
635 h - (get_h() - recent->get_y()));
636 listbox->reposition_window(listbox->get_x(),
638 w - (get_w() - listbox->get_w()),
639 h - (get_h() - listbox->get_h()));
640 icon_button->reposition_window(w - (get_w() - icon_button->get_x()),
641 icon_button->get_y());
642 text_button->reposition_window(w - (get_w() - text_button->get_x()),
643 text_button->get_y());
644 folder_button->reposition_window(w - (get_w() - folder_button->get_x()),
645 folder_button->get_y());
646 updir_button->reposition_window(w - (get_w() - updir_button->get_x()),
647 updir_button->get_y());
650 get_resources()->filebox_w = get_w();
651 get_resources()->filebox_h = get_h();
655 int BC_FileBox::keypress_event()
657 switch(get_keypress())
660 if(ctrl_down()) set_done(1);
667 int BC_FileBox::close_event()
673 int BC_FileBox::extract_extension(char *out, const char *in)
677 for(i = strlen(in)-1; i > 0 && in[i] != '.'; i--)
690 int BC_FileBox::create_tables()
693 char string[BCTEXTLEN];
694 BC_ListBoxItem *new_item;
696 fs->set_sort_order(sort_order);
697 fs->set_sort_field(column_type[sort_column]);
698 // Directory is entered before this from a random source
700 for(int i = 0; i < fs->total_files(); i++)
702 FileItem *file_item = fs->get_entry(i);
703 int is_dir = file_item->is_dir;
704 BC_Pixmap* icon = get_icon(file_item->name, is_dir);
707 new_item = new BC_ListBoxItem(file_item->name,
709 is_dir ? DIRECTORY_COLOR : FILE_COLOR);
710 if(is_dir) new_item->set_searchable(0);
711 list_column[column_of_type(FILEBOX_NAME)].append(new_item);
716 sprintf(string, "%lld", file_item->size);
717 new_item = new BC_ListBoxItem(string, FILE_COLOR);
721 new_item = new BC_ListBoxItem("", DIRECTORY_COLOR);
724 list_column[column_of_type(FILEBOX_SIZE)].append(new_item);
729 static char *month_text[13] =
747 month_text[file_item->month],
750 new_item = new BC_ListBoxItem(string, FILE_COLOR);
754 new_item = new BC_ListBoxItem("", DIRECTORY_COLOR);
757 list_column[column_of_type(FILEBOX_DATE)].append(new_item);
762 extract_extension(string, file_item->name);
763 new_item = new BC_ListBoxItem(string, FILE_COLOR);
767 new_item = new BC_ListBoxItem("", FILE_COLOR);
769 list_column[column_of_type(FILEBOX_EXTENSION)].append(new_item);
775 int BC_FileBox::delete_tables()
777 for(int j = 0; j < FILEBOX_COLUMNS; j++)
779 list_column[j].remove_all_objects();
784 BC_Pixmap* BC_FileBox::get_icon(char *path, int is_dir)
786 char *suffix = strrchr(path, '.');
787 int icon_type = ICON_UNKNOWN;
789 if(is_dir) return icons[ICON_FOLDER];
796 for(int i = 0; i < TOTAL_SUFFIXES; i++)
798 if(!strcasecmp(suffix, BC_WindowBase::get_resources()->suffix_to_type[i].suffix))
800 icon_type = BC_WindowBase::get_resources()->suffix_to_type[i].icon_type;
807 return icons[icon_type];
810 char* BC_FileBox::columntype_to_text(int type)
815 return FILEBOX_NAME_TEXT;
818 return FILEBOX_SIZE_TEXT;
821 return FILEBOX_DATE_TEXT;
823 case FILEBOX_EXTENSION:
824 return FILEBOX_EXTENSION_TEXT;
830 int BC_FileBox::column_of_type(int type)
832 for(int i = 0; i < FILEBOX_COLUMNS; i++)
833 if(column_type[i] == type) return i;
838 int BC_FileBox::refresh_fs_change()
840 strcpy(this->current_path, fs->get_current_dir());
841 strcpy(this->submitted_path, fs->get_current_dir());
842 strcpy(this->directory, fs->get_current_dir());
843 listbox->reset_query();
847 int BC_FileBox::refresh()
850 listbox->set_master_column(column_of_type(FILEBOX_NAME), 0);
851 listbox->update(list_column,
863 int BC_FileBox::update_filter(char *filter)
865 fs->set_filter(filter);
868 strcpy(get_resources()->filebox_filter, filter);
874 void BC_FileBox::move_column(int src, int dst)
876 ArrayList<BC_ListBoxItem*> *new_columns =
877 new ArrayList<BC_ListBoxItem*>[FILEBOX_COLUMNS];
878 int *new_types = new int[FILEBOX_COLUMNS];
879 int *new_widths = new int[FILEBOX_COLUMNS];
881 // Fill in remaining columns with consecutive data
882 for(int out_column = 0, in_column = 0;
883 out_column < FILEBOX_COLUMNS;
887 // Copy destination column from src column
888 if(out_column == dst)
890 for(int i = 0; i < list_column[src].total; i++)
892 new_columns[out_column].append(list_column[src].values[i]);
894 new_types[out_column] = column_type[src];
895 new_widths[out_column] = column_width[src];
900 // Skip source column
901 if(in_column == src) in_column++;
902 for(int i = 0; i < list_column[src].total; i++)
904 new_columns[out_column].append(list_column[in_column].values[i]);
906 new_types[out_column] = column_type[in_column];
907 new_widths[out_column] = column_width[in_column];
912 delete [] list_column;
913 delete [] column_type;
914 delete [] column_width;
915 list_column = new_columns;
916 column_type = new_types;
917 column_width = new_widths;
919 for(int i = 0; i < FILEBOX_COLUMNS; i++)
921 get_resources()->filebox_columntype[i] = column_type[i];
922 get_resources()->filebox_columnwidth[i] = column_width[i];
923 column_titles[i] = BC_FileBox::columntype_to_text(column_type[i]);
931 int BC_FileBox::submit_file(char *path, int return_value, int use_this)
933 // blank. Take the current directory as the desired file.
936 // save complete path
937 strcpy(this->current_path, directory);
938 // save complete path
939 strcpy(this->submitted_path, directory);
942 set_done(return_value);
946 //printf("BC_FileBox::submit_file 1 %s\n", path);
947 // is a directory, change directories
948 if(!fs->is_dir(path) && !use_this)
950 fs->change_dir(path);
952 directory_title->update(strcat(fs->get_current_dir(),"/"));
953 strcpy(this->current_path, fs->get_current_dir());
954 strcpy(this->submitted_path, fs->get_current_dir());
955 strcpy(this->directory, fs->get_current_dir());
958 textbox->update(fs->get_current_dir());
961 listbox->reset_query();
965 // Is a file or desired directory. Quit the operation.
967 //printf("BC_FileBox::submit_file 1\n");
968 fs->extract_dir(directory, path); // save directory for defaults
969 fs->extract_name(filename, path); // save filename
970 fs->complete_path(path);
971 strcpy(this->current_path, path); // save complete path
972 strcpy(this->submitted_path, path); // save complete path
973 newfolder_thread->interrupt();
974 set_done(return_value);
980 int BC_FileBox::get_display_mode()
982 return top_level->get_resources()->filebox_mode;
985 void BC_FileBox::create_listbox(int x, int y, int mode)
987 if(listbox && listbox->get_display_mode() != mode)
991 top_level->get_resources()->filebox_mode = mode;
995 add_subwindow(listbox = new BC_FileBoxListBox(x, y, this));
998 char* BC_FileBox::get_path(int selection)
1002 return get_submitted_path();
1006 BC_ListBoxItem *item = listbox->get_selection(
1007 column_of_type(FILEBOX_NAME), selection - 1);
1010 fs->join_names(string, directory, item->get_text());
1017 char* BC_FileBox::get_submitted_path()
1019 //printf("BC_FileBox::get_submitted_path 1 %s\n", submitted_path);
1020 return submitted_path;
1023 char* BC_FileBox::get_current_path()
1025 //printf("BC_FileBox::get_current_path 1 %s\n", current_path);
1026 return current_path;
1029 char* BC_FileBox::get_newfolder_title()
1031 char *letter2 = strchr(title, ':');
1032 new_folder_title[0] = 0;
1035 memcpy(new_folder_title, title, letter2 - title);
1036 new_folder_title[letter2 - title] = 0;
1039 strcat(new_folder_title, _(": New folder"));
1041 return new_folder_title;