r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / guicast / bcfilebox.C
blob2cb508255082e9cc4ff91ed7d977a720ebca0b7b
1 #include "bcfilebox.h"
2 #include "bcpixmap.h"
3 #include "bcresources.h"
4 #include "bctitle.h"
5 #include "clip.h"
6 #include "filesystem.h"
7 #include "bclistboxitem.h"
8 #include <string.h>
9 #include <sys/stat.h>
12 #include <libintl.h>
13 #define _(String) gettext(String)
14 #define gettext_noop(String) String
15 #define N_(String) gettext_noop (String)
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(), 
22         x, 
23         y, 
24         320, 
25         120, 
26         0, 
27         0, 
28         0, 
29         0, 
30         1)
34 BC_NewFolder::~BC_NewFolder()
39 int BC_NewFolder::create_objects()
41         int x = 10, y = 10;
42         add_tool(new BC_Title(x, y, _("Enter the name of the folder:")));
43         y += 20;
44         add_subwindow(textbox = new BC_TextBox(x, y, 300, 1, _("Untitled")));
45         y += 30;
46         add_subwindow(new BC_OKButton(this));
47         x = get_w() - 100;
48         add_subwindow(new BC_CancelButton(this));
49         show_window();
50         return 0;
53 char* BC_NewFolder::get_text()
55         return textbox->get_text();
59 BC_NewFolderThread::BC_NewFolderThread(BC_FileBox *filebox)
60  : Thread(0, 0, 0)
62         this->filebox = filebox;
63         window = 0;
66 BC_NewFolderThread::~BC_NewFolderThread() 
68         interrupt();
71 void BC_NewFolderThread::run()
73         change_lock.lock();
74         window = new BC_NewFolder(filebox->get_abs_cursor_x(), 
75                 filebox->get_abs_cursor_y(),
76                 filebox);
77         window->create_objects();
78         change_lock.unlock();
81         int result = window->run_window();
83         if(!result)
84         {
85                 char new_folder[BCTEXTLEN];
86                 filebox->fs->join_names(new_folder, filebox->fs->get_current_dir(), window->get_text());
87                 mkdir(new_folder, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
88                 filebox->lock_window();
89                 filebox->refresh();
90                 filebox->unlock_window();
91         }
93         change_lock.lock();
94         delete window;
95         window = 0;
96         change_lock.unlock();
98         completion_lock.unlock();
101 int BC_NewFolderThread::interrupt()
103         change_lock.lock();
104         if(window)
105         {
106                 window->lock_window();
107                 window->set_done(1);
108                 window->unlock_window();
109         }
111         change_lock.unlock();
113         completion_lock.lock();
114         completion_lock.unlock();
115         return 0;
118 int BC_NewFolderThread::start_new_folder()
120         change_lock.lock();
122         if(window)
123         {
124                 window->lock_window();
125                 window->raise_window();
126                 window->unlock_window();
127                 change_lock.unlock();
128         }
129         else
130         {
131                 change_lock.unlock();
132                 completion_lock.lock();
134                 Thread::start();
135         }
138         return 0;
147 BC_FileBoxListBox::BC_FileBoxListBox(int x, int y, BC_FileBox *filebox)
148  : BC_ListBox(x, 
149                         y, 
150                         filebox->get_listbox_w(), 
151                         filebox->get_listbox_h(y), 
152                         filebox->get_display_mode(), 
153                         filebox->list_column, 
154                         filebox->column_titles,
155                         filebox->column_width,
156                         FILEBOX_COLUMNS,
157                         0,
158                         0,
159                         filebox->select_multiple ? LISTBOX_MULTIPLE : LISTBOX_SINGLE,
160                         ICON_LEFT,
161                         0)
163         this->filebox = filebox; 
166 BC_FileBoxListBox::~BC_FileBoxListBox() {}
168 int BC_FileBoxListBox::handle_event()
170         filebox->submit_file(filebox->textbox->get_text(), 0);
171         return 1;
174 int BC_FileBoxListBox::selection_changed()
176         BC_ListBoxItem *item = get_selection(0, 0);
177         if(item)
178                 filebox->textbox->update(item->get_text());
179         return 0;
183 int BC_FileBoxListBox::evaluate_query(int list_item, char *string)
185         return(filebox->list_column[0].values[list_item]->get_color() != DIRECTORY_COLOR && 
186                 strcmp(string, filebox->list_column[0].values[list_item]->get_text()) <= 0);
192 BC_FileBoxTextBox::BC_FileBoxTextBox(int x, int y, BC_FileBox *filebox)
193  : BC_TextBox(x, y, filebox->get_w() - 20, 1, filebox->filename)
195         this->filebox = filebox; 
198 BC_FileBoxTextBox::~BC_FileBoxTextBox()
202 int BC_FileBoxTextBox::handle_event()
204         
205         return 1;
214 BC_FileBoxFilterText::BC_FileBoxFilterText(int x, int y, BC_FileBox *filebox)
215  : BC_TextBox(x, y, filebox->get_w() - 50, 1, filebox->get_resources()->filebox_filter)
217         this->filebox = filebox;
220 int BC_FileBoxFilterText::handle_event()
222         filebox->update_filter(get_text());
223         return 0;
229 BC_FileBoxFilterMenu::BC_FileBoxFilterMenu(int x, int y, BC_FileBox *filebox)
230  : BC_ListBox(x, 
231         y, 
232         filebox->get_w() - 30, 
233         120, 
234         LISTBOX_TEXT, 
235         &filebox->filter_list, 
236         0, 
237         0, 
238         1, 
239         0, 
240         1)
242         this->filebox = filebox;
243         set_tooltip(_("Change the filter"));
246 int BC_FileBoxFilterMenu::handle_event()
248         filebox->filter_text->update(get_selection(0, 0)->get_text());
249         filebox->update_filter(get_selection(0, 0)->get_text());
250         return 0;
262 BC_FileBoxCancel::BC_FileBoxCancel(BC_FileBox *filebox)
263  : BC_CancelButton(filebox)
265         this->filebox = filebox;
266         set_tooltip(_("Cancel the operation"));
269 BC_FileBoxCancel::~BC_FileBoxCancel()
273 int BC_FileBoxCancel::handle_event()
275         filebox->submit_file(filebox->textbox->get_text(), 0);
276         filebox->newfolder_thread->interrupt();
277         filebox->set_done(1);
278         return 1;
287 BC_FileBoxUseThis::BC_FileBoxUseThis(BC_FileBox *filebox)
288  : BC_Button(filebox->get_w() / 2 - 50, 
289         filebox->get_h() - 35, 
290         BC_WindowBase::get_resources()->usethis_button_images)
292         this->filebox = filebox; 
293         set_tooltip(_("Submit the directory"));
296 BC_FileBoxUseThis::~BC_FileBoxUseThis()
300 int BC_FileBoxUseThis::handle_event()
302         filebox->submit_file(filebox->textbox->get_text(), 0, 1);
303         return 1;
310 BC_FileBoxOK::BC_FileBoxOK(BC_FileBox *filebox)
311  : BC_OKButton(filebox)
313         this->filebox = filebox; 
314         set_tooltip(_("Submit the file"));
317 BC_FileBoxOK::~BC_FileBoxOK()
321 int BC_FileBoxOK::handle_event()
323         filebox->submit_file(filebox->textbox->get_text(), 0);
324         return 1;
332 BC_FileBoxText::BC_FileBoxText(int x, int y, BC_FileBox *filebox)
333  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_text_images)
335         this->filebox = filebox; 
336         set_tooltip(_("Display text"));
338 int BC_FileBoxText::handle_event()
340         filebox->create_listbox(filebox->listbox->get_x(), filebox->listbox->get_y(), LISTBOX_TEXT);
341         return 1;
345 BC_FileBoxIcons::BC_FileBoxIcons(int x, int y, BC_FileBox *filebox)
346  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_icons_images)
348         this->filebox = filebox; 
349         set_tooltip(_("Display icons"));
351 int BC_FileBoxIcons::handle_event()
353         filebox->create_listbox(filebox->listbox->get_x(), filebox->listbox->get_y(), LISTBOX_ICONS);
354         return 1;
358 BC_FileBoxNewfolder::BC_FileBoxNewfolder(int x, int y, BC_FileBox *filebox)
359  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_newfolder_images)
361         this->filebox = filebox; 
362         set_tooltip(_("Create new folder"));
364 int BC_FileBoxNewfolder::handle_event()
366         filebox->newfolder_thread->start_new_folder();
367         return 1;
370 BC_FileBoxUpdir::BC_FileBoxUpdir(int x, int y, BC_FileBox *filebox)
371  : BC_Button(x, y, BC_WindowBase::get_resources()->filebox_updir_images)
373         this->filebox = filebox; 
374         set_tooltip(_("Up a directory"));
376 int BC_FileBoxUpdir::handle_event()
378 // Need a temp so submit_file can expand it
379         sprintf(string, _(".."));
380         filebox->submit_file(string, 0);
381         return 1;
391 char* BC_FileBox::column_titles[FILEBOX_COLUMNS] = 
393         "File",
394         "Size"
397 BC_FileBox::BC_FileBox(int x, 
398                 int y, 
399                 char *init_path,
400                 char *title,
401                 char *caption,
402                 int show_all_files,
403                 int want_directory,
404                 int multiple_files,
405                 int h_padding)
406  : BC_Window(title, 
407         x,
408         y,
409         BC_WindowBase::get_resources()->filebox_w, 
410         BC_WindowBase::get_resources()->filebox_h, 
411         10, 
412         10,
413         1,
414         0,
415         1)
417         fs = new FileSystem;
418         strcpy(this->caption, caption);
420         strcpy(this->path, init_path);
421         if(show_all_files) fs->set_show_all();
422         if(want_directory) fs->set_want_directory();
423         this->want_directory = want_directory;
424         select_multiple = multiple_files;
425         fs->complete_path(this->path);
426         fs->extract_dir(directory, this->path);
427         fs->extract_name(filename, this->path);
429 // Test directory
430         if(fs->update(directory))
431         {
432                 sprintf(this->path, "~");
433                 fs->complete_path(this->path);
434                 fs->update(this->path);
435                 strcpy(directory, fs->get_current_dir());
436                 sprintf(filename, "");
437         }
438         this->h_padding = h_padding;
441 BC_FileBox::~BC_FileBox()
443 // this has to be destroyed before tables, because it can call for an update!
444         delete newfolder_thread;  
445         delete fs;
446         delete_tables();
447         for(int i = 0; i < TOTAL_ICONS; i++)
448                 delete icons[i];
449         filter_list.remove_all_objects();
452 int BC_FileBox::create_objects()
454         int x = 10, y = 10;
456         column_width[0] = get_listbox_w() - 120;
457         column_width[1] = 120;
458         filter_list.append(new BC_ListBoxItem("*"));
459         filter_list.append(new BC_ListBoxItem("[*.ifo][*.vob]"));
460         filter_list.append(new BC_ListBoxItem("[*.mp2][*.mp3][*.wav]"));
461         filter_list.append(new BC_ListBoxItem("[*.avi][*.mpg][*.m2v][*.m1v][*.mov]"));
462         filter_list.append(new BC_ListBoxItem("heroine*"));
463         filter_list.append(new BC_ListBoxItem("*.xml"));
464         fs->set_filter(get_resources()->filebox_filter);
465         fs->update(directory);
467         create_icons();
468         create_tables();
470         add_subwindow(ok_button = new BC_FileBoxOK(this));
471         if(want_directory)
472                 add_subwindow(usethis_button = new BC_FileBoxUseThis(this));
473         add_subwindow(cancel_button = new BC_FileBoxCancel(this));
475         add_subwindow(new BC_Title(x, y, caption));
477         add_subwindow(directory_title = 
478                 new BC_Title(x, y + 20, fs->get_current_dir()));
479         x = get_w() - 50;
480         add_subwindow(icon_button = new BC_FileBoxIcons(x, y, this));
481         x -= icon_button->get_w();
482         add_subwindow(text_button = new BC_FileBoxText(x, y, this));
483         x -= text_button->get_w();
484         add_subwindow(folder_button = new BC_FileBoxNewfolder(x, y, this));
485         x -= folder_button->get_w();
486         add_subwindow(updir_button = new BC_FileBoxUpdir(x, y, this));
488         x = 10;
489         y = MAX(updir_button->get_y() + updir_button->get_h() + 5, 
490                 directory_title->get_h() + directory_title->get_y());
491         listbox = 0;
493         create_listbox(x, y, get_display_mode());
494         y += listbox->get_h() + 10;
495         add_subwindow(textbox = new BC_FileBoxTextBox(x, y, this));
496         y += textbox->get_h() + 10;
497         add_subwindow(filter_text = new BC_FileBoxFilterText(x, y, this));
498         add_subwindow(filter_popup = 
499                 new BC_FileBoxFilterMenu(x + filter_text->get_w(), y, this));
501 // listbox has to be active because refresh might be called from newfolder_thread
502         listbox->activate();    
503         newfolder_thread = new BC_NewFolderThread(this);
504         
505         show_window();
506         return 0;
509 int BC_FileBox::get_listbox_w()
511         return get_w() - 20;
514 int BC_FileBox::get_listbox_h(int y)
516         return get_h() - y - h_padding - 110;
519 int BC_FileBox::create_icons()
521         for(int i = 0; i < TOTAL_ICONS; i++)
522         {
523                 icons[i] = new BC_Pixmap(this, 
524                         BC_WindowBase::get_resources()->type_to_icon[i],
525                         PIXMAP_ALPHA);
526         }
527         return 0;
530 int BC_FileBox::resize_event(int w, int h)
532         draw_background(0, 0, w, h);
533         flash();
535 // OK button handles resize event itself
536 //      ok_button->reposition_window(ok_button->get_x(), 
537 //              h - (get_h() - ok_button->get_y()));
538 //      cancel_button->reposition_window(w - (get_w() - cancel_button->get_x()), 
539 //              h - (get_h() - cancel_button->get_y()));
540         if(want_directory)
541                 usethis_button->reposition_window(w / 2 - 50, h - (get_h() - usethis_button->get_y()));
542         filter_popup->reposition_window(w - (get_w() - filter_popup->get_x()), 
543                 h - (get_h() - filter_popup->get_y()),
544                 w - 30);
545         filter_text->reposition_window(filter_text->get_x(), 
546                 h - (get_h() - filter_text->get_y()),
547                 w - (get_w() - filter_text->get_w()),
548                 1);
549         textbox->reposition_window(textbox->get_x(), 
550                 h - (get_h() - textbox->get_y()),
551                 w - (get_w() - textbox->get_w()),
552                 1);
553         listbox->reposition_window(listbox->get_x(),
554                 listbox->get_y(),
555                 w - (get_w() - listbox->get_w()),
556                 h - (get_h() - listbox->get_h()));
557         icon_button->reposition_window(w - (get_w() - icon_button->get_x()), 
558                 icon_button->get_y());
559         text_button->reposition_window(w - (get_w() - text_button->get_x()), 
560                 text_button->get_y());
561         folder_button->reposition_window(w - (get_w() - folder_button->get_x()), 
562                 folder_button->get_y());
563         updir_button->reposition_window(w - (get_w() - updir_button->get_x()), 
564                 updir_button->get_y());
565         set_w(w);
566         set_h(h);
567         get_resources()->filebox_w = get_w();
568         get_resources()->filebox_h = get_h();
569         return 1;
572 int BC_FileBox::keypress_event()
574         switch(get_keypress())
575         {
576                 case 'w':
577                         if(ctrl_down()) set_done(1);
578                         return 1;
579                         break;
580         }
581         return 0;
584 int BC_FileBox::close_event()
586         set_done(1);
587         return 1;
591 int BC_FileBox::create_tables()
593         delete_tables();
594         char string[BCTEXTLEN];
595         BC_ListBoxItem *new_item;
597         fs->update(0);
598         for(int i = 0; i < fs->total_files(); i++)
599         {
600                 int is_dir = fs->get_entry(i)->is_dir;
601                 BC_Pixmap* icon = get_icon(fs->get_entry(i)->name, is_dir);
603 // Name entry
604                 new_item = new BC_ListBoxItem(fs->get_entry(i)->name,
605                         icon, 
606                         is_dir ? DIRECTORY_COLOR : FILE_COLOR);
607                 list_column[0].append(new_item);
608                 if(is_dir) new_item->set_searchable(0);
610 // Size entry
611                 if(!is_dir)
612                 {
613                         sprintf(string, "%lld", fs->get_entry(i)->size);
614                         new_item = new BC_ListBoxItem(string, FILE_COLOR);
615                 }
616                 else
617                 {
618                         new_item = new BC_ListBoxItem("", FILE_COLOR);
619                 }
621                 list_column[1].append(new_item);
622         }
623         return 0;
626 int BC_FileBox::delete_tables()
628         for(int j = 0; j < FILEBOX_COLUMNS; j++)
629         {
630                 list_column[j].remove_all_objects();
631         }
632         return 0;
635 BC_Pixmap* BC_FileBox::get_icon(char *path, int is_dir)
637         char *suffix = strrchr(path, '.');
638         int icon_type = ICON_UNKNOWN;
640         if(is_dir) return icons[ICON_FOLDER];
642         if(suffix)
643         {
644                 suffix++;
645                 if(*suffix != 0)
646                 {
647                         for(int i = 0; i < TOTAL_SUFFIXES; i++)
648                         {
649                                 if(!strcasecmp(suffix, BC_WindowBase::get_resources()->suffix_to_type[i].suffix)) 
650                                 {
651                                         icon_type = BC_WindowBase::get_resources()->suffix_to_type[i].icon_type;
652                                         break;
653                                 }
654                         }
655                 }
656         }
658         return icons[icon_type];
661 int BC_FileBox::refresh()
663         create_tables();
664         listbox->update(list_column, 
665                 column_titles, 
666                 column_width,
667                 FILEBOX_COLUMNS, 
668                 0, 
669                 0,
670                 -1, 
671                 1);
673         return 0;
676 int BC_FileBox::update_filter(char *filter)
678         fs->set_filter(filter);
679         fs->update();
680         refresh();
681         strcpy(get_resources()->filebox_filter, filter);
683         return 0;
686 int BC_FileBox::submit_file(char *path, int return_value, int use_this)
688         if(!path[0]) return 1;   // blank
690 // is a directory, change directories
691         if(!fs->is_dir(path) && !use_this)
692         {
693                 fs->change_dir(path);
694                 refresh();
695                 directory_title->update(fs->get_current_dir());
696                 strcpy(this->path, fs->get_current_dir());
697                 strcpy(this->directory, fs->get_current_dir());
698                 filename[0] = 0;
699                 if(want_directory)
700                         textbox->update(fs->get_current_dir());
701                 else
702                         textbox->update("");
703                 listbox->reset_query();
704                 return 1;
705         }
706         else
707 // Is a file or desired directory.  Quit the operation.
708         {
709 //printf("BC_FileBox::submit_file 1\n");
710                 fs->extract_dir(directory, path);     // save directory for defaults
711                 fs->extract_name(filename, path);     // save filename
712                 fs->complete_path(path);
713                 strcpy(this->path, path);          // save complete path
714                 newfolder_thread->interrupt();
715                 set_done(return_value);
716                 return 0;
717         }
718         return 0;
721 int BC_FileBox::get_display_mode()
723         return top_level->get_resources()->filebox_mode;
726 void BC_FileBox::create_listbox(int x, int y, int mode)
728         if(listbox && listbox->get_display_mode() != mode)
729         {
730                 delete listbox;
731                 listbox = 0;
732                 top_level->get_resources()->filebox_mode = mode;
733         }
735         if(!listbox)
736                 add_subwindow(listbox = new BC_FileBoxListBox(x, y, this));
739 char* BC_FileBox::get_path(int selection)
741         if(selection == 0)
742         {
743                 return get_path();
744         }
745         else
746         {
747                 BC_ListBoxItem *item = listbox->get_selection(0, selection - 1);
748                 if(item) 
749                 {
750                         fs->join_names(string, directory, item->get_text());
751                         return string;
752                 }
753         }
754         return 0;
757 char* BC_FileBox::get_path()
759         return path;
762 char* BC_FileBox::get_newfolder_title()
764         char *letter2 = strchr(title, ':');
765         new_folder_title[0] = 0;
766         if(letter2)
767         {
768                 memcpy(new_folder_title, title, letter2 - title);
769                 new_folder_title[letter2 - title] = 0;
770         }
772         strcat(new_folder_title, _(": New folder"));
774         return new_folder_title;