opengl dot() fix, add file dates, sort file name/time, fix icon image lookup, sync...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / assetpopup.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2012 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 "asset.h"
23 #include "assetedit.h"
24 #include "assetpopup.h"
25 #include "assetremove.h"
26 #include "awindow.h"
27 #include "awindowgui.h"
28 #include "bcdisplayinfo.h"
29 #include "bcsignals.h"
30 #include "clipedit.h"
31 #include "cstrdup.h"
32 #include "cwindow.h"
33 #include "cwindowgui.h"
34 #include "edl.h"
35 #include "edlsession.h"
36 #include "filexml.h"
37 #include "language.h"
38 #include "localsession.h"
39 #include "mainerror.h"
40 #include "mainindexes.h"
41 #include "mainsession.h"
42 #include "mwindow.h"
43 #include "mwindowgui.h"
44 #include "tracks.h"
45 #include "vwindow.h"
46 #include "vwindowgui.h"
47 #include "zwindow.h"
48
49
50 AssetPopup::AssetPopup(MWindow *mwindow, AWindowGUI *gui)
51  : BC_PopupMenu(0, 0, 0, "", 0)
52 {
53         this->mwindow = mwindow;
54         this->gui = gui;
55 }
56
57 AssetPopup::~AssetPopup()
58 {
59 }
60
61 void AssetPopup::create_objects()
62 {
63         BC_MenuItem *menu_item;
64         BC_SubMenu *submenu;
65         add_item(info = new AssetPopupInfo(mwindow, this));
66         add_item(format = new AWindowListFormat(mwindow, gui));
67         add_item(menu_item = new BC_MenuItem(_("Sort...")));
68         menu_item->add_submenu(submenu = new BC_SubMenu());
69         submenu->add_submenuitem(new AssetPopupSortNames(mwindow, this));
70         submenu->add_submenuitem(new AssetPopupSortTimes(mwindow, this));
71         add_item(index = new AssetPopupBuildIndex(mwindow, this));
72         add_item(view = new AssetPopupView(mwindow, this));
73         add_item(view_window = new AssetPopupViewWindow(mwindow, this));
74         add_item(mixer = new AssetPopupMixer(mwindow, this));
75         add_item(new AssetPopupPaste(mwindow, this));
76         add_item(menu_item = new BC_MenuItem(_("Match...")));
77         menu_item->add_submenu(submenu = new BC_SubMenu());
78         submenu->add_submenuitem(new AssetMatchSize(mwindow, this));
79         submenu->add_submenuitem(new AssetMatchRate(mwindow, this));
80         submenu->add_submenuitem(new AssetMatchAll(mwindow, this));
81         add_item(menu_item = new BC_MenuItem(_("Remove...")));
82         menu_item->add_submenu(submenu = new BC_SubMenu());
83         submenu->add_submenuitem(new AssetPopupProjectRemove(mwindow, this));
84         submenu->add_submenuitem(new AssetPopupDiskRemove(mwindow, this));
85 }
86
87 void AssetPopup::paste_assets()
88 {
89 // Collect items into the drag vectors for temporary storage
90         gui->lock_window("AssetPopup::paste_assets");
91         mwindow->gui->lock_window("AssetPopup::paste_assets");
92         mwindow->cwindow->gui->lock_window("AssetPopup::paste_assets");
93
94         gui->collect_assets();
95         mwindow->paste_assets(mwindow->edl->local_session->get_selectionstart(1),
96                 mwindow->edl->tracks->first,
97                 0);   // do not overwrite
98
99         gui->unlock_window();
100         mwindow->gui->unlock_window();
101         mwindow->cwindow->gui->unlock_window();
102 }
103
104 void AssetPopup::match_size()
105 {
106 // Collect items into the drag vectors for temporary storage
107         gui->collect_assets();
108         mwindow->gui->lock_window("AssetPopup::match_size");
109         mwindow->asset_to_size();
110         mwindow->gui->unlock_window();
111 }
112
113 void AssetPopup::match_rate()
114 {
115 // Collect items into the drag vectors for temporary storage
116         gui->collect_assets();
117         mwindow->gui->lock_window("AssetPopup::match_rate");
118         mwindow->asset_to_rate();
119         mwindow->gui->unlock_window();
120 }
121
122 void AssetPopup::match_all()
123 {
124 // Collect items into the drag vectors for temporary storage
125         gui->collect_assets();
126         mwindow->gui->lock_window("AssetPopup::match_rate");
127         mwindow->asset_to_all();
128         mwindow->gui->unlock_window();
129 }
130
131 int AssetPopup::update()
132 {
133         format->update();
134         gui->collect_assets();
135         return 0;
136 }
137
138
139 AssetPopupInfo::AssetPopupInfo(MWindow *mwindow, AssetPopup *popup)
140  : BC_MenuItem(_("Info..."))
141 {
142         this->mwindow = mwindow;
143         this->popup = popup;
144 }
145
146 AssetPopupInfo::~AssetPopupInfo()
147 {
148 }
149
150 int AssetPopupInfo::handle_event()
151 {
152         int cur_x, cur_y;
153         popup->gui->get_abs_cursor(cur_x, cur_y);
154         if( mwindow->session->drag_assets->size() ) {
155                 AssetEdit *asset_edit = mwindow->awindow->get_asset_editor();
156                 asset_edit->edit_asset(
157                         mwindow->session->drag_assets->values[0], cur_x, cur_y);
158         }
159         else if( mwindow->session->drag_clips->size() ) {
160                 popup->gui->awindow->clip_edit->edit_clip(
161                         mwindow->session->drag_clips->values[0], cur_x, cur_y);
162         }
163         return 1;
164 }
165
166
167 AssetPopupBuildIndex::AssetPopupBuildIndex(MWindow *mwindow, AssetPopup *popup)
168  : BC_MenuItem(_("Rebuild index"))
169 {
170         this->mwindow = mwindow;
171         this->popup = popup;
172 }
173
174 AssetPopupBuildIndex::~AssetPopupBuildIndex()
175 {
176 }
177
178 int AssetPopupBuildIndex::handle_event()
179 {
180 //printf("AssetPopupBuildIndex::handle_event 1\n");
181         mwindow->rebuild_indices();
182         return 1;
183 }
184
185
186 AssetPopupSortNames::AssetPopupSortNames(MWindow *mwindow, AssetPopup *popup)
187  : BC_MenuItem(_("Sort names"))
188 {
189         this->mwindow = mwindow;
190         this->popup = popup;
191 }
192
193 AssetPopupSortNames::~AssetPopupSortNames()
194 {
195 }
196
197 int AssetPopupSortNames::handle_event()
198 {
199         mwindow->awindow->gui->sort_assets(0);
200         return 1;
201 }
202
203 AssetPopupSortTimes::AssetPopupSortTimes(MWindow *mwindow, AssetPopup *popup)
204  : BC_MenuItem(_("Sort times"))
205 {
206         this->mwindow = mwindow;
207         this->popup = popup;
208 }
209
210 AssetPopupSortTimes::~AssetPopupSortTimes()
211 {
212 }
213
214 int AssetPopupSortTimes::handle_event()
215 {
216         mwindow->awindow->gui->sort_assets(1);
217         return 1;
218 }
219
220
221 AssetPopupView::AssetPopupView(MWindow *mwindow, AssetPopup *popup)
222  : BC_MenuItem(_("View"))
223 {
224         this->mwindow = mwindow;
225         this->popup = popup;
226 }
227
228 AssetPopupView::~AssetPopupView()
229 {
230 }
231
232 int AssetPopupView::handle_event()
233 {
234         VWindow *vwindow = mwindow->get_viewer(1, DEFAULT_VWINDOW);
235         vwindow->gui->lock_window("AssetPopupView::handle_event");
236
237         if( mwindow->session->drag_assets->total )
238                 vwindow->change_source(
239                         mwindow->session->drag_assets->values[0]);
240         else
241         if( mwindow->session->drag_clips->total )
242                 vwindow->change_source(
243                         mwindow->session->drag_clips->values[0]);
244
245         vwindow->gui->unlock_window();
246         return 1;
247 }
248
249
250 AssetPopupViewWindow::AssetPopupViewWindow(MWindow *mwindow, AssetPopup *popup)
251  : BC_MenuItem(_("View in new window"))
252 {
253         this->mwindow = mwindow;
254         this->popup = popup;
255 }
256
257 AssetPopupViewWindow::~AssetPopupViewWindow()
258 {
259 }
260
261 int AssetPopupViewWindow::handle_event()
262 {
263 // Find window with nothing
264         VWindow *vwindow = mwindow->get_viewer(1);
265
266 // TODO: create new vwindow or change current vwindow
267         vwindow->gui->lock_window("AssetPopupView::handle_event");
268
269         if( mwindow->session->drag_assets->total )
270                 vwindow->change_source(
271                         mwindow->session->drag_assets->values[0]);
272         else
273         if( mwindow->session->drag_clips->total )
274                 vwindow->change_source(
275                         mwindow->session->drag_clips->values[0]);
276
277         vwindow->gui->unlock_window();
278         return 1;
279 }
280
281 AssetPopupMixer::AssetPopupMixer(MWindow *mwindow, AssetPopup *popup)
282  : BC_MenuItem(_("Open Mixers"))
283 {
284         this->mwindow = mwindow;
285         this->popup = popup;
286 }
287
288 AssetPopupMixer::~AssetPopupMixer()
289 {
290 }
291
292 int AssetPopupMixer::handle_event()
293 {
294         ArrayList<ZWindow *>new_mixers;
295
296         mwindow->select_zwindow(0);
297         for( int i=0; i<mwindow->session->drag_assets->total; ++i ) {
298                 Indexable *indexable = mwindow->session->drag_assets->values[i];
299                 ArrayList<Indexable*> new_assets;
300                 new_assets.append(indexable);
301                 Track *track = mwindow->edl->tracks->last;
302                 mwindow->load_assets(&new_assets, -1, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 0);
303                 track = !track ? mwindow->edl->tracks->first : track->next;
304                 Mixer *mixer = 0;
305                 ZWindow *zwindow = mwindow->get_mixer(mixer);
306                 while( track ) {
307                         track->play = track->record = 0;
308                         if( track->data_type == TRACK_VIDEO ) {
309                                 sprintf(track->title, _("Mixer %d"), zwindow->idx);
310                         }
311                         mixer->mixer_ids.append(track->get_mixer_id());
312                         track = track->next;
313                 }
314                 char *path = indexable->path;
315                 char *tp = strrchr(path, '/');
316                 if( !tp ) tp = path; else ++tp;
317                 zwindow->set_title(tp);
318                 new_mixers.append(zwindow);
319         }
320
321         mwindow->tile_mixers();
322         for( int i=0; i<new_mixers.size(); ++i )
323                 new_mixers[i]->start();
324
325         mwindow->refresh_mixers();
326         mwindow->resync_guis();
327         return 1;
328 }
329
330 AssetPopupPaste::AssetPopupPaste(MWindow *mwindow, AssetPopup *popup)
331  : BC_MenuItem(_("Paste"))
332 {
333         this->mwindow = mwindow;
334         this->popup = popup;
335 }
336
337 AssetPopupPaste::~AssetPopupPaste()
338 {
339 }
340
341 int AssetPopupPaste::handle_event()
342 {
343         popup->paste_assets();
344         return 1;
345 }
346
347
348 AssetMatchSize::AssetMatchSize(MWindow *mwindow, AssetPopup *popup)
349  : BC_MenuItem(_("Match project size"))
350 {
351         this->mwindow = mwindow;
352         this->popup = popup;
353 }
354
355 int AssetMatchSize::handle_event()
356 {
357         popup->match_size();
358         return 1;
359 }
360
361 AssetMatchRate::AssetMatchRate(MWindow *mwindow, AssetPopup *popup)
362  : BC_MenuItem(_("Match frame rate"))
363 {
364         this->mwindow = mwindow;
365         this->popup = popup;
366 }
367
368 int AssetMatchRate::handle_event()
369 {
370         popup->match_rate();
371         return 1;
372 }
373
374 AssetMatchAll::AssetMatchAll(MWindow *mwindow, AssetPopup *popup)
375  : BC_MenuItem(_("Match all"))
376 {
377         this->mwindow = mwindow;
378         this->popup = popup;
379 }
380
381 int AssetMatchAll::handle_event()
382 {
383         popup->match_all();
384         return 1;
385 }
386
387
388 AssetPopupProjectRemove::AssetPopupProjectRemove(MWindow *mwindow, AssetPopup *popup)
389  : BC_MenuItem(_("Remove from project"))
390 {
391         this->mwindow = mwindow;
392         this->popup = popup;
393 }
394
395 AssetPopupProjectRemove::~AssetPopupProjectRemove()
396 {
397 }
398
399 int AssetPopupProjectRemove::handle_event()
400 {
401         mwindow->remove_assets_from_project(1, 1,
402                 mwindow->session->drag_assets,
403                 mwindow->session->drag_clips);
404         return 1;
405 }
406
407
408 AssetPopupDiskRemove::AssetPopupDiskRemove(MWindow *mwindow, AssetPopup *popup)
409  : BC_MenuItem(_("Remove from disk"))
410 {
411         this->mwindow = mwindow;
412         this->popup = popup;
413 }
414
415
416 AssetPopupDiskRemove::~AssetPopupDiskRemove()
417 {
418 }
419
420 int AssetPopupDiskRemove::handle_event()
421 {
422         mwindow->awindow->asset_remove->start();
423         return 1;
424 }
425
426
427 AssetListMenu::AssetListMenu(MWindow *mwindow, AWindowGUI *gui)
428  : BC_PopupMenu(0, 0, 0, "", 0)
429 {
430         this->mwindow = mwindow;
431         this->gui = gui;
432 }
433
434 AssetListMenu::~AssetListMenu()
435 {
436 }
437
438 void AssetListMenu::create_objects()
439 {
440         add_item(format = new AWindowListFormat(mwindow, gui));
441         add_item(new AWindowListSort(mwindow, gui));
442         add_item(new AssetListCopy(mwindow, gui));
443         add_item(new AssetListPaste(mwindow, gui));
444         update_titles();
445 }
446
447 void AssetListMenu::update_titles()
448 {
449         format->update();
450 }
451
452 AssetListCopy::AssetListCopy(MWindow *mwindow, AWindowGUI *gui)
453  : BC_MenuItem(_("Copy file list"))
454 {
455         this->mwindow = mwindow;
456         this->gui = gui;
457         copy_dialog = 0;
458 }
459 AssetListCopy::~AssetListCopy()
460 {
461         delete copy_dialog;
462 }
463
464 int AssetListCopy::handle_event()
465 {
466         int len = 0;
467         MWindowGUI *gui = mwindow->gui;
468         gui->lock_window("AssetListCopy::handle_event");
469         mwindow->awindow->gui->collect_assets();
470         int n = mwindow->session->drag_assets->total;
471         for( int i=0; i<n; ++i ) {
472                 Indexable *indexable = mwindow->session->drag_assets->values[i];
473                 const char *path = indexable->path;
474                 if( !*path ) continue;
475                 len += strlen(path) + 1;
476         }
477         char *text = new char[len+1], *cp = text;
478         for( int i=0; i<n; ++i ) {
479                 Indexable *indexable = mwindow->session->drag_assets->values[i];
480                 const char *path = indexable->path;
481                 if( !*path ) continue;
482                 cp += sprintf(cp, "%s\n", path);
483         }
484         *cp = 0;
485         int cur_x, cur_y;
486         gui->get_abs_cursor(cur_x, cur_y, 0);
487         gui->unlock_window(); 
488
489         if( n ) {
490                 if( !copy_dialog )
491                         copy_dialog = new AssetCopyDialog(this);
492                 copy_dialog->start(text, cur_x, cur_y);
493         }
494         else {
495                 eprintf(_("Nothing selected"));
496                 delete [] text;
497         }
498         return 1;
499 }
500
501 AssetCopyDialog::AssetCopyDialog(AssetListCopy *copy)
502  : BC_DialogThread()
503 {
504         this->copy = copy;
505         copy_window = 0;
506 }
507
508 void AssetCopyDialog::start(char *text, int x, int y)
509 {
510         close_window();
511         this->text = text;
512         this->x = x;  this->y = y;
513         BC_DialogThread::start();
514 }
515
516 AssetCopyDialog::~AssetCopyDialog()
517 {
518         close_window();
519 }
520
521 BC_Window* AssetCopyDialog::new_gui()
522 {
523         BC_DisplayInfo display_info;
524
525         copy_window = new AssetCopyWindow(this);
526         copy_window->create_objects();
527         return copy_window;
528 }
529
530 void AssetCopyDialog::handle_done_event(int result)
531 {
532         delete [] text;  text = 0;
533 }
534
535 void AssetCopyDialog::handle_close_event(int result)
536 {
537         copy_window = 0;
538 }
539
540
541 AssetCopyWindow::AssetCopyWindow(AssetCopyDialog *copy_dialog)
542  : BC_Window(_(PROGRAM_NAME ": Copy File List"),
543         copy_dialog->x - 500/2, copy_dialog->y - 200/2,
544         500, 200, 500, 200, 1, 0, 1)
545 {
546         this->copy_dialog = copy_dialog;
547 }
548
549 AssetCopyWindow::~AssetCopyWindow()
550 {
551 }
552
553 void AssetCopyWindow::create_objects()
554 {
555         BC_Title *title;
556         int x = 10, y = 10, pad = 5;
557         add_subwindow(title = new BC_Title(x, y, _("List of asset paths:")));
558         y += title->get_h() + pad;
559         int text_w = get_w() - x - 10;
560         int text_h = get_h() - y - BC_OKButton::calculate_h() - pad;
561         int text_rows = BC_TextBox::pixels_to_rows(this, MEDIUMFONT, text_h);
562         char *text = copy_dialog->text;
563         int len = strlen(text) + BCTEXTLEN;
564         file_list = new BC_ScrollTextBox(this, x, y, text_w, text_rows, text, len);
565         file_list->create_objects();
566
567         add_subwindow(new BC_OKButton(this));
568         show_window();
569 }
570
571 int AssetCopyWindow::resize_event(int w, int h)
572 {
573         int fx = file_list->get_x(), fy = file_list->get_y(), pad = 5;
574         int text_w = w - fx - 10;
575         int text_h = h - fy - BC_OKButton::calculate_h() - pad;
576         int text_rows = BC_TextBox::pixels_to_rows(this, MEDIUMFONT, text_h);
577         file_list->reposition_window(fx, fy, text_w, text_rows);
578         return 0;
579 }
580
581 AssetListPaste::AssetListPaste(MWindow *mwindow, AWindowGUI *gui)
582  : BC_MenuItem(_("Paste file list"))
583 {
584         this->mwindow = mwindow;
585         this->gui = gui;
586         paste_dialog = 0;
587 }
588 AssetListPaste::~AssetListPaste()
589 {
590         delete paste_dialog;
591 }
592
593 int AssetListPaste::handle_event()
594 {
595         if( !paste_dialog )
596                 paste_dialog = new AssetPasteDialog(this);
597         else
598                 paste_dialog->close_window();
599         int cur_x, cur_y;
600         gui->get_abs_cursor(cur_x, cur_y, 0);
601         paste_dialog->start(cur_x, cur_y);
602         return 1;
603 }
604
605 AssetPasteDialog::AssetPasteDialog(AssetListPaste *paste)
606  : BC_DialogThread()
607 {
608         this->paste = paste;
609         paste_window = 0;
610 }
611
612 AssetPasteDialog::~AssetPasteDialog()
613 {
614         close_window();
615 }
616
617 BC_Window* AssetPasteDialog::new_gui()
618 {
619         paste_window = new AssetPasteWindow(this);
620         paste_window->create_objects();
621         return paste_window;
622 }
623
624 void AssetPasteDialog::handle_done_event(int result)
625 {
626         if( result ) return;
627         const char *bp = paste_window->file_list->get_text(), *ep = bp+strlen(bp);
628         ArrayList<char*> path_list;
629         path_list.set_array_delete();
630
631         for( const char *cp=bp; cp<ep && *cp; ) {
632                 const char *dp = strchr(cp, '\n');
633                 if( !dp ) dp = ep;
634                 char path[BCTEXTLEN], *pp = path;
635                 int len = sizeof(path)-1;
636                 while( --len>0 && cp<dp ) *pp++ = *cp++;
637                 if( *cp ) ++cp;
638                 *pp = 0;
639                 if( !strlen(path) ) continue;
640                 path_list.append(cstrdup(path));
641         }
642         if( !path_list.size() ) return;
643
644         MWindow *mwindow = paste->mwindow;
645         mwindow->interrupt_indexes();
646         mwindow->gui->lock_window("AssetPasteDialog::handle_done_event");
647         result = mwindow->load_filenames(&path_list, LOADMODE_RESOURCESONLY, 0);
648         mwindow->gui->unlock_window();
649         path_list.remove_all_objects();
650         mwindow->save_backup();
651         mwindow->restart_brender();
652         mwindow->session->changes_made = 1;
653 }
654
655 void AssetPasteDialog::handle_close_event(int result)
656 {
657         paste_window = 0;
658 }
659
660 void AssetPasteDialog::start(int x, int y)
661 {
662         this->x = x;  this->y = y;
663         BC_DialogThread::start();
664 }
665
666 AssetPasteWindow::AssetPasteWindow(AssetPasteDialog *paste_dialog)
667  : BC_Window(_(PROGRAM_NAME ": Paste File List"),
668         paste_dialog->x - 500/2, paste_dialog->y - 200/2,
669         500, 200, 500, 200, 1, 0, 1)
670 {
671         this->paste_dialog = paste_dialog;
672 }
673
674 AssetPasteWindow::~AssetPasteWindow()
675 {
676 }
677
678 void AssetPasteWindow::create_objects()
679 {
680         BC_Title *title;
681         int x = 10, y = 10, pad = 5;
682         add_subwindow(title = new BC_Title(x, y, _("Enter list of asset paths:")));
683         y += title->get_h() + pad;
684         int text_w = get_w() - x - 10;
685         int text_h = get_h() - y - BC_OKButton::calculate_h() - pad;
686         int text_rows = BC_TextBox::pixels_to_rows(this, MEDIUMFONT, text_h);
687         file_list = new BC_ScrollTextBox(this, x, y, text_w, text_rows, (char*)0, 65536);
688         file_list->create_objects();
689         add_subwindow(new BC_OKButton(this));
690         add_subwindow(new BC_CancelButton(this));
691         show_window();
692 }
693
694 int AssetPasteWindow::resize_event(int w, int h)
695 {
696         int fx = file_list->get_x(), fy = file_list->get_y(), pad = 5;
697         int text_w = w - fx - 10;
698         int text_h = h - fy - BC_OKButton::calculate_h() - pad;
699         int text_rows = BC_TextBox::pixels_to_rows(this, MEDIUMFONT, text_h);
700         file_list->reposition_window(fx, fy, text_w, text_rows);
701         return 0;
702 }
703