add ffmpeg filters as plugins
[goodguy/history.git] / cinelerra-5.0 / cinelerra / awindowgui.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 "assets.h"
26 #include "awindowgui.h"
27 #include "awindowgui.inc"
28 #include "awindow.h"
29 #include "awindowmenu.h"
30 #include "bcsignals.h"
31 #include "bchash.h"
32 #include "cache.h"
33 #include "bccmodels.h"
34 #include "cursors.h"
35 #include "cwindowgui.h"
36 #include "cwindow.h"
37 #include "edl.h"
38 #include "edlsession.h"
39 #include "file.h"
40 #include "filesystem.h"
41 #include "indexable.h"
42 #include "keys.h"
43 #include "language.h"
44 #include "localsession.h"
45 #include "mainmenu.h"
46 #include "mainsession.h"
47 #include "mwindowgui.h"
48 #include "mwindow.h"
49 #include "nestededls.h"
50 #include "newfolder.h"
51 #include "preferences.h"
52 #include "theme.h"
53 #include "vframe.h"
54 #include "vwindowgui.h"
55 #include "vwindow.h"
56
57 #include "data/lad_picon_png.h"
58 #include "data/ff_audio_png.h"
59 #include "data/ff_video_png.h"
60
61 #include<stdio.h>
62 #include<unistd.h>
63 #include<fcntl.h>
64
65 AssetPicon::AssetPicon(MWindow *mwindow, 
66         AWindowGUI *gui, 
67         Indexable *indexable)
68  : BC_ListBoxItem()
69 {
70         reset();
71         this->mwindow = mwindow;
72         this->gui = gui;
73         this->indexable = indexable;
74         indexable->add_user();
75         this->id = indexable->id;
76 }
77
78 AssetPicon::AssetPicon(MWindow *mwindow, 
79         AWindowGUI *gui, 
80         EDL *edl)
81  : BC_ListBoxItem()
82 {
83         reset();
84         this->mwindow = mwindow;
85         this->gui = gui;
86         this->edl = edl;
87         edl->add_user();
88         this->id = edl->id;
89 }
90
91 AssetPicon::AssetPicon(MWindow *mwindow, 
92         AWindowGUI *gui, 
93         const char *folder)
94  : BC_ListBoxItem(folder, gui->folder_icon)
95 {
96         reset();
97         this->mwindow = mwindow;
98         this->gui = gui;
99 }
100
101 AssetPicon::AssetPicon(MWindow *mwindow, 
102         AWindowGUI *gui, 
103         PluginServer *plugin)
104  : BC_ListBoxItem()
105 {
106         reset();
107         this->mwindow = mwindow;
108         this->gui = gui;
109         this->plugin = plugin;
110 }
111
112
113 AssetPicon::~AssetPicon()
114 {
115         if(indexable) indexable->remove_user();
116         if(edl) edl->remove_user();
117         if( icon && !gui->protected_pixmap(icon) ) {
118                 delete icon;
119                 if( !plugin ) delete icon_vframe;
120         }
121 }
122
123 void AssetPicon::reset()
124 {
125         plugin = 0;
126         indexable = 0;
127         edl = 0;
128         icon = 0;
129         icon_vframe = 0;
130         in_use = 1;
131         id = 0;
132         persistent = 0;
133 }
134
135 void AssetPicon::create_objects()
136 {
137         FileSystem fs;
138         char name[BCTEXTLEN];
139         int pixmap_w, pixmap_h;
140         const int debug = 0;
141
142         pixmap_h = 50;
143
144         if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
145         if(indexable)
146         {
147                 fs.extract_name(name, indexable->path);
148                 set_text(name);
149         }
150         
151         if(indexable && indexable->is_asset)
152         {
153                 if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
154                 Asset *asset = (Asset*)indexable;
155                 if(asset->video_data)
156                 {
157                         if(mwindow->preferences->use_thumbnails)
158                         {
159                                 gui->unlock_window();
160                                 if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
161                                 File *file = mwindow->video_cache->check_out(asset, 
162                                         mwindow->edl,
163                                         1);
164                                 if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
165
166                                 if(file)
167                                 {
168                                         int height = asset->height > 0 ? asset->height : 1;
169                                         pixmap_w = pixmap_h * asset->width / height;
170
171                                         file->set_layer(0);
172                                         file->set_video_position(0, 0);
173
174                                         if(gui->temp_picon && 
175                                                 (gui->temp_picon->get_w() != asset->width ||
176                                                 gui->temp_picon->get_h() != asset->height))
177                                         {
178                                                 delete gui->temp_picon;
179                                                 gui->temp_picon = 0;
180                                         }
181
182                                         if(!gui->temp_picon)
183                                         {
184                                                 gui->temp_picon = new VFrame(0, -1,
185                                                         asset->width, asset->height, 
186                                                         BC_RGB888, -1);
187                                         }
188
189                                         file->read_frame(gui->temp_picon);
190                                         if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
191                                         mwindow->video_cache->check_in(asset);
192
193                                         gui->lock_window("AssetPicon::create_objects 1");
194                                         icon = new BC_Pixmap(gui, pixmap_w, pixmap_h);
195                                         icon->draw_vframe(gui->temp_picon,
196                                                 0, 0, pixmap_w, pixmap_h, 0, 0);
197 //printf("%d %d\n", gui->temp_picon->get_w(), gui->temp_picon->get_h());
198                                         icon_vframe = new VFrame(0,
199                                                 -1, pixmap_w, pixmap_h, BC_RGB888, -1);
200                                         BC_CModels::transfer(
201                                                 icon_vframe->get_rows(),
202                                                 gui->temp_picon->get_rows(),
203                                                 0, 0, 0, 0, 0, 0, 0, 0, 
204                                                 gui->temp_picon->get_w(), 
205                                                 gui->temp_picon->get_h(),
206                                                 0, 0, pixmap_w, pixmap_h,
207                                                 BC_RGB888, BC_RGB888,
208                                                 0, 0, 0);
209
210                                         if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
211
212                                 }
213                                 else
214                                 {
215                                         gui->lock_window("AssetPicon::create_objects 2");
216                                         icon = gui->video_icon;
217                                         icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];
218                                 }
219                         }
220                         else
221                         {
222                                 icon = gui->video_icon;
223                                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];                  
224                         }
225                 }
226                 else
227                 if(asset->audio_data)
228                 {
229                         icon = gui->audio_icon;
230                         icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_SOUND];
231                 }
232 //printf("AssetPicon::create_objects 2\n");
233
234                 if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
235         }
236         else
237         if(indexable && !indexable->is_asset)
238         {
239                 icon = gui->video_icon;
240                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];
241         }
242         else
243         if(edl)
244         {
245 //printf("AssetPicon::create_objects 4 %s\n", edl->local_session->clip_title);
246                 set_text(strcpy(name, edl->local_session->clip_title));
247                 icon = gui->clip_icon;
248                 icon_vframe = mwindow->theme->get_image("clip_icon");
249         }
250         else
251         if(plugin)
252         {
253                 strcpy(name, _(plugin->title));
254                 set_text(name);
255                 icon_vframe = plugin->get_picon();
256                 if( icon_vframe )
257                         icon = gui->create_pixmap(icon_vframe);
258                 else if( plugin->audio ) {
259                         if( plugin->transition ) {
260                                 icon = gui->atransition_icon;
261                                 icon_vframe = gui->atransition_vframe;
262                         }
263                         else if( plugin->is_ffmpeg() ) {
264                                 icon = gui->ff_aud_icon;
265                                 icon_vframe = gui->ff_aud_vframe;
266                         }
267                         else if( plugin->is_ladspa() ) {
268                                 icon = gui->ladspa_icon;
269                                 icon_vframe = gui->ladspa_vframe;
270                         }
271                         else {
272                                 icon = gui->aeffect_icon;
273                                 icon_vframe = gui->aeffect_vframe;
274                         }
275                 }
276                 else if( plugin->video ) {
277                         if( plugin->transition ) {
278                                 icon = gui->vtransition_icon;
279                                 icon_vframe = gui->vtransition_vframe;
280                         }
281                         else if( plugin->is_ffmpeg() ) {
282                                 icon = gui->ff_vid_icon;
283                                 icon_vframe = gui->ff_vid_vframe;
284                         }
285                         else {
286                                 icon = gui->veffect_icon;
287                                 icon_vframe = gui->veffect_vframe;
288                         }
289                 }
290         }
291         if( !icon ) {
292                 icon = gui->file_icon;
293                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_UNKNOWN];
294         }
295         set_icon(icon);
296         set_icon_vframe(icon_vframe);
297
298         if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
299 }
300
301
302
303
304
305
306 AWindowGUI::AWindowGUI(MWindow *mwindow, AWindow *awindow)
307  : BC_Window(PROGRAM_NAME ": Resources",
308         mwindow->session->awindow_x, 
309     mwindow->session->awindow_y, 
310     mwindow->session->awindow_w, 
311     mwindow->session->awindow_h,
312     100,
313     100,
314     1,
315     1,
316     1)
317 {
318 // printf("AWindowGUI::AWindowGUI %d %d %d %d\n",
319 // mwindow->session->awindow_x, 
320 // mwindow->session->awindow_y, 
321 // mwindow->session->awindow_w, 
322 // mwindow->session->awindow_h);
323         this->mwindow = mwindow;
324         this->awindow = awindow;
325         file_icon = 0;
326         audio_icon = 0;
327         video_icon = 0;
328         folder_icon = 0;
329         clip_icon = 0;
330         atransition_icon = 0;  atransition_vframe = 0;
331         vtransition_icon = 0;  vtransition_vframe = 0;
332         aeffect_icon = 0;      aeffect_vframe = 0;
333         ladspa_icon = 0;       ladspa_vframe = 0;
334         veffect_icon = 0;      veffect_vframe = 0;
335         ff_aud_icon = 0;       ff_aud_vframe = 0;
336         ff_vid_icon = 0;       ff_vid_vframe = 0;
337         plugin_visibility = ((uint64_t)1<<(8*sizeof(uint64_t)-1))-1;
338         newfolder_thread = 0;
339         asset_menu = 0;
340         assetlist_menu = 0;
341         folderlist_menu = 0;
342         temp_picon = 0;
343         remove_plugin = 0;
344 }
345
346 AWindowGUI::~AWindowGUI()
347 {
348         assets.remove_all_objects();
349         folders.remove_all_objects();
350         aeffects.remove_all_objects();
351         veffects.remove_all_objects();
352         atransitions.remove_all_objects();
353         vtransitions.remove_all_objects();
354         displayed_assets[1].remove_all_objects();
355
356         delete file_icon;
357         delete audio_icon;
358         delete video_icon;
359         delete folder_icon;
360         delete clip_icon;
361         delete atransition_icon;
362         delete vtransition_icon;
363         delete aeffect_icon;
364         delete ladspa_icon;
365         delete ladspa_vframe;
366         delete ff_aud_icon;
367         delete ff_aud_vframe;
368         delete ff_vid_icon;
369         delete ff_vid_vframe;
370         delete veffect_icon;
371         delete newfolder_thread;
372         delete asset_menu;
373         delete assetlist_menu;
374         delete folderlist_menu;
375         if(temp_picon) delete temp_picon;
376         delete remove_plugin;
377 }
378
379 bool AWindowGUI::protected_pixmap(BC_Pixmap *icon)
380 {
381         return  icon == file_icon ||
382                 icon == folder_icon ||
383                 icon == audio_icon ||
384                 icon == video_icon ||
385                 icon == clip_icon ||
386                 icon == vtransition_icon ||
387                 icon == atransition_icon ||
388                 icon == veffect_icon ||
389                 icon == aeffect_icon ||
390                 icon == ladspa_icon ||
391                 icon == ff_aud_icon ||
392                 icon == ff_vid_icon;
393 }
394
395 void AWindowGUI::create_objects()
396 {
397         AssetPicon *picon;
398
399         lock_window("AWindowGUI::create_objects");
400 SET_TRACE
401 //printf("AWindowGUI::create_objects 1\n");
402         asset_titles[0] = _("Title");
403         asset_titles[1] = _("Comments");
404
405 SET_TRACE
406
407         set_icon(mwindow->theme->get_image("awindow_icon"));
408         file_icon = new BC_Pixmap(this, 
409                 BC_WindowBase::get_resources()->type_to_icon[ICON_UNKNOWN],
410                 PIXMAP_ALPHA);
411
412         folder_icon = new BC_Pixmap(this, 
413                 BC_WindowBase::get_resources()->type_to_icon[ICON_FOLDER],
414                 PIXMAP_ALPHA);
415
416         audio_icon = new BC_Pixmap(this, 
417                 BC_WindowBase::get_resources()->type_to_icon[ICON_SOUND],
418                 PIXMAP_ALPHA);
419
420         video_icon = new BC_Pixmap(this, 
421                 BC_WindowBase::get_resources()->type_to_icon[ICON_FILM],
422                 PIXMAP_ALPHA);
423
424 SET_TRACE
425
426         clip_vframe = mwindow->theme->get_image("clip_icon");
427         clip_icon = new BC_Pixmap(this, clip_vframe, PIXMAP_ALPHA);
428         atransition_vframe = mwindow->theme->get_image("atransition_icon");
429         atransition_icon = new BC_Pixmap(this, atransition_vframe, PIXMAP_ALPHA);
430         vtransition_vframe = mwindow->theme->get_image("vtransition_icon");
431         vtransition_icon = new BC_Pixmap(this, vtransition_vframe, PIXMAP_ALPHA);
432         aeffect_vframe = mwindow->theme->get_image("aeffect_icon");
433         aeffect_icon = new BC_Pixmap(this, aeffect_vframe, PIXMAP_ALPHA);
434         ladspa_vframe = new VFrame(lad_picon_png);
435         ladspa_icon = new BC_Pixmap(this, ladspa_vframe, PIXMAP_ALPHA);
436         ff_aud_vframe = new VFrame(ff_audio_png);
437         ff_aud_icon = new BC_Pixmap(this, ff_aud_vframe, PIXMAP_ALPHA);
438         ff_vid_vframe = new VFrame(ff_video_png);
439         ff_vid_icon = new BC_Pixmap(this, ff_vid_vframe, PIXMAP_ALPHA);
440         veffect_vframe = mwindow->theme->get_image("veffect_icon");
441         veffect_icon = new BC_Pixmap(this, veffect_vframe, PIXMAP_ALPHA);
442
443 SET_TRACE
444
445 // Mandatory folders
446         folders.append(picon = new AssetPicon(mwindow,
447                 this,
448                 AEFFECT_FOLDER));
449         picon->persistent = 1;
450         folders.append(picon = new AssetPicon(mwindow,
451                 this,
452                 VEFFECT_FOLDER));
453         picon->persistent = 1;
454         folders.append(picon = new AssetPicon(mwindow,
455                 this,
456                 ATRANSITION_FOLDER));
457         picon->persistent = 1;
458         folders.append(picon = new AssetPicon(mwindow,
459                 this,
460                 VTRANSITION_FOLDER));
461         picon->persistent = 1;
462 SET_TRACE
463
464         mwindow->theme->get_awindow_sizes(this);
465         load_defaults(mwindow->defaults);
466
467 SET_TRACE
468         add_subwindow(asset_list = new AWindowAssets(mwindow,
469                 this,
470                 mwindow->theme->alist_x, 
471                 mwindow->theme->alist_y, 
472                 mwindow->theme->alist_w, 
473                 mwindow->theme->alist_h));
474
475 SET_TRACE
476         add_subwindow(divider = new AWindowDivider(mwindow,
477                 this,
478                 mwindow->theme->adivider_x,
479                 mwindow->theme->adivider_y,
480                 mwindow->theme->adivider_w,
481                 mwindow->theme->adivider_h));
482
483 SET_TRACE
484         divider->set_cursor(HSEPARATE_CURSOR, 0, 0);
485
486 SET_TRACE
487         int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y; 
488         int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h; 
489         add_subwindow(add_tools = new AddTools(mwindow, this, fx, fy, fw));
490         add_tools->create_objects();
491         fy += add_tools->get_h();  fh -= add_tools->get_h();
492 SET_TRACE
493         add_subwindow(folder_list = new AWindowFolders(mwindow,
494                 this, fx, fy, fw, fh));
495 SET_TRACE
496         update_effects();
497 SET_TRACE
498
499         //int x = mwindow->theme->abuttons_x;
500         //int y = mwindow->theme->abuttons_y;
501
502 SET_TRACE
503
504         newfolder_thread = new NewFolderThread(mwindow, this);
505
506         add_subwindow(asset_menu = new AssetPopup(mwindow, this));
507         asset_menu->create_objects();
508
509 SET_TRACE
510
511         add_subwindow(assetlist_menu = new AssetListMenu(mwindow, this));
512
513 SET_TRACE
514         assetlist_menu->create_objects();
515
516 SET_TRACE
517
518         add_subwindow(folderlist_menu = new FolderListMenu(mwindow, this));
519         folderlist_menu->create_objects();
520 //printf("AWindowGUI::create_objects 2\n");
521
522 SET_TRACE
523         unlock_window();
524 }
525
526 int AWindowGUI::resize_event(int w, int h)
527 {
528         mwindow->session->awindow_x = get_x();
529         mwindow->session->awindow_y = get_y();
530         mwindow->session->awindow_w = w;
531         mwindow->session->awindow_h = h;
532
533         mwindow->theme->get_awindow_sizes(this);
534         mwindow->theme->draw_awindow_bg(this);
535
536         asset_list->reposition_window(mwindow->theme->alist_x, 
537         mwindow->theme->alist_y, 
538         mwindow->theme->alist_w, 
539         mwindow->theme->alist_h);
540         divider->reposition_window(mwindow->theme->adivider_x,
541                 mwindow->theme->adivider_y,
542                 mwindow->theme->adivider_w,
543                 mwindow->theme->adivider_h);
544
545         int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y; 
546         int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h; 
547         add_tools->reposition_window(fx, fy, fw, add_tools->get_h());
548         fy += add_tools->get_h();  fh -= add_tools->get_h();
549         folder_list->reposition_window(fx, fy, fw, fh);
550         
551 //      int x = mwindow->theme->abuttons_x;
552 //      int y = mwindow->theme->abuttons_y;
553 //      new_bin->reposition_window(x, y);
554 //      x += new_bin->get_w();
555 //      delete_bin->reposition_window(x, y);
556 //      x += delete_bin->get_w();
557 //      rename_bin->reposition_window(x, y);
558 //      x += rename_bin->get_w();
559 //      delete_disk->reposition_window(x, y);
560 //      x += delete_disk->get_w();
561 //      delete_project->reposition_window(x, y);
562 //      x += delete_project->get_w();
563 //      info->reposition_window(x, y);
564 //      x += info->get_w();
565 //      redraw_index->reposition_window(x, y);
566 //      x += redraw_index->get_w();
567 //      paste->reposition_window(x, y);
568 //      x += paste->get_w();
569 //      append->reposition_window(x, y);
570 //      x += append->get_w();
571 //      view->reposition_window(x, y);
572
573         BC_WindowBase::resize_event(w, h);
574         return 1;
575 }
576
577 int AWindowGUI::translation_event()
578 {
579         mwindow->session->awindow_x = get_x();
580         mwindow->session->awindow_y = get_y();
581         return 0;
582 }
583
584 void AWindowGUI::reposition_objects()
585 {
586         mwindow->theme->get_awindow_sizes(this);
587         asset_list->reposition_window(mwindow->theme->alist_x, 
588         mwindow->theme->alist_y, 
589         mwindow->theme->alist_w, 
590         mwindow->theme->alist_h);
591         divider->reposition_window(mwindow->theme->adivider_x,
592                 mwindow->theme->adivider_y,
593                 mwindow->theme->adivider_w,
594                 mwindow->theme->adivider_h);
595         folder_list->reposition_window(mwindow->theme->afolders_x, 
596         mwindow->theme->afolders_y, 
597         mwindow->theme->afolders_w, 
598         mwindow->theme->afolders_h);
599         flush();
600 }
601
602 int AWindowGUI::save_defaults(BC_Hash *defaults)
603 {
604         defaults->update("PLUGIN_VISIBILTY", plugin_visibility);
605         return 0;
606 }
607
608 int AWindowGUI::load_defaults(BC_Hash *defaults)
609 {
610         plugin_visibility = defaults->get("PLUGIN_VISIBILTY", plugin_visibility);
611         return 0;
612 }
613
614
615 int AWindowGUI::close_event()
616 {
617         hide_window();
618         mwindow->session->show_awindow = 0;
619         unlock_window();
620
621         mwindow->gui->lock_window("AWindowGUI::close_event");
622         mwindow->gui->mainmenu->show_awindow->set_checked(0);
623         mwindow->gui->unlock_window();
624
625         lock_window("AWindowGUI::close_event");
626         save_defaults(mwindow->defaults);
627         mwindow->save_defaults();
628         return 1;
629 }
630
631 AWindowRemovePluginGUI::
632 AWindowRemovePluginGUI(AWindow *awindow, AWindowRemovePlugin *thread,
633         int x, int y, PluginServer *plugin)
634  : BC_Window(PROGRAM_NAME ": Remove plugin", x,y, 500,200, 50, 50, 1, 0, 1, -1, "", 1)
635 {
636         this->awindow = awindow;
637         this->thread = thread;
638         this->plugin = plugin;
639         VFrame *vframe = plugin->get_picon();
640         icon = vframe ? create_pixmap(vframe) : 0;
641         plugin_list.append(new BC_ListBoxItem(plugin->title, icon));
642 }
643
644 AWindowRemovePluginGUI::
645 ~AWindowRemovePluginGUI()
646 {
647         if( !awindow->gui->protected_pixmap(icon) )
648                 delete icon;
649         plugin_list.remove_all();
650 }
651
652 void AWindowRemovePluginGUI::create_objects()
653 {
654         BC_Button *ok_button = new BC_OKButton(this);
655         add_subwindow(ok_button);
656         BC_Button *cancel_button = new BC_CancelButton(this);
657         add_subwindow(cancel_button);
658         int x = 10, y = 10;
659         BC_Title *title = new BC_Title(x, y, _("remove plugin?"));
660         add_subwindow(title);
661         y += title->get_h() + 5;
662         list = new BC_ListBox(x, y,
663                 get_w() - 20, ok_button->get_y() - y - 5, LISTBOX_TEXT, &plugin_list,
664                 0, 0, 1, 0, 0, LISTBOX_SINGLE, ICON_LEFT, 0);
665         add_subwindow(list);
666         show_window();
667 }
668
669 int AWindowRemovePlugin::remove_plugin(PluginServer *plugin, ArrayList<BC_ListBoxItem*> &folder)
670 {
671         int ret = 0;
672         for( int i=0; i<folder.size(); ) {
673                 AssetPicon *picon = (AssetPicon *)folder[i];
674                 if( picon->plugin == plugin ) {
675                         folder.remove_object_number(i);
676                         ++ret;
677                         continue;
678                 }
679                 ++i;
680         }
681         return ret;
682 }
683
684 void AWindowRemovePlugin::handle_close_event(int result)
685 {
686         if( !result ) {
687                 printf("remove %s\n", plugin->path);
688                 ArrayList<BC_ListBoxItem*> *folder = 
689                         plugin->audio ? plugin->transition ?
690                                 &awindow->gui->atransitions :
691                                 &awindow->gui->aeffects :
692                         plugin->video ?  plugin->transition ?
693                                 &awindow->gui->vtransitions :
694                                 &awindow->gui->veffects :
695                         0;
696                 if( folder ) remove_plugin(plugin, *folder);
697                 awindow->gui->update_assets();
698                 char png_path[BCTEXTLEN], plugin_path[BCTEXTLEN], index_path[BCTEXTLEN];
699                 strcpy(plugin_path, plugin->path);
700                 if( !plugin->get_plugin_png_path(png_path) ) png_path[0] = 0;
701                 MWindow *mwindow = awindow->mwindow;
702                 sprintf(index_path, "%s/%s", mwindow->preferences->plugin_dir, PLUGIN_FILE);
703                 mwindow->plugindb->remove(plugin);
704                 plugin->delete_this();
705                 remove(plugin_path);
706                 if( png_path[0] ) remove(png_path);
707                 remove(index_path);
708         }
709 }
710
711 AWindowRemovePlugin::
712 AWindowRemovePlugin(AWindow *awindow, PluginServer *plugin)
713  : BC_DialogThread()
714 {
715         this->awindow = awindow;
716         this->plugin = plugin;
717 }
718
719 AWindowRemovePlugin::
720 ~AWindowRemovePlugin()
721 {
722         close_window();
723 }
724
725 BC_Window* AWindowRemovePlugin::new_gui()
726 {
727         int x = awindow->gui->get_abs_cursor_x(0);
728         int y = awindow->gui->get_abs_cursor_y(0);
729         AWindowRemovePluginGUI *gui = new AWindowRemovePluginGUI(awindow, this, x, y, plugin);
730         gui->create_objects();
731         return gui;
732 }
733
734 int AWindowGUI::keypress_event()
735 {
736         switch(get_keypress()) {
737         case 'w': case 'W':
738                 if(ctrl_down()) {
739                         close_event();
740                         return 1;
741                 }
742                 break;
743         case DELETE:
744                 if(shift_down()) {
745                         PluginServer* plugin = selected_plugin();
746                         if( !plugin ) break;
747                         remove_plugin = new AWindowRemovePlugin(awindow, plugin);
748                         unlock_window();
749                         remove_plugin->start();
750                         lock_window();
751                 }
752         }
753         return 0;
754 }
755
756 void AWindowGUI::update_folder_list()
757 {
758 //printf("AWindowGUI::update_folder_list 1\n");
759         for(int i = 0; i < folders.total; i++)
760         {
761                 AssetPicon *picon = (AssetPicon*)folders.values[i];
762                 picon->in_use--;
763         }
764 //printf("AWindowGUI::update_folder_list 1\n");
765
766 // Search assets for folders
767         for(int i = 0; i < mwindow->edl->folders.total; i++)
768         {
769                 char *folder = mwindow->edl->folders.values[i];
770                 int exists = 0;
771 //printf("AWindowGUI::update_folder_list 1.1\n");
772
773                 for(int j = 0; j < folders.total; j++)
774                 {
775                         AssetPicon *picon = (AssetPicon*)folders.values[j];
776                         if(!strcasecmp(picon->get_text(), folder))
777                         {
778                                 exists = 1;
779                                 picon->in_use = 1;
780                                 break;
781                         }
782                 }
783
784                 if(!exists)
785                 {
786                         AssetPicon *picon = new AssetPicon(mwindow, this, folder);
787                         picon->create_objects();
788                         folders.append(picon);
789                 }
790 //printf("AWindowGUI::update_folder_list 1.3\n");
791         }
792 //printf("AWindowGUI::update_folder_list 1\n");
793 //for(int i = 0; i < folders.total; i++)
794 //      printf("AWindowGUI::update_folder_list %s\n", folders.values[i]->get_text());
795
796 // Delete excess
797         for(int i = folders.total - 1; i >= 0; i--)
798         {
799                 AssetPicon *picon = (AssetPicon*)folders.values[i];
800                 if(!picon->in_use && !picon->persistent)
801                 {
802                         delete picon;
803                         folders.remove_number(i);
804                 }
805         }
806 //for(int i = 0; i < folders.total; i++)
807 //      printf("AWindowGUI::update_folder_list %s\n", folders.values[i]->get_text());
808 //printf("AWindowGUI::update_folder_list 2\n");
809 }
810
811 void AWindowGUI::create_persistent_folder(ArrayList<BC_ListBoxItem*> *output, 
812         int do_audio, int do_video, int is_realtime, int is_transition)
813 {
814         ArrayList<PluginServer*> plugin_list;
815 // Get pointers to plugindb entries
816         mwindow->search_plugindb(do_audio, do_video, is_realtime, is_transition,
817                         0, plugin_list);
818
819         for(int i = 0; i < plugin_list.total; i++) {
820                 PluginServer *server = plugin_list.values[i];
821                 int visible = plugin_visibility & (1<<server->dir_idx);
822                 if(!visible) continue;
823 // Create new listitem
824                 AssetPicon *picon = new AssetPicon(mwindow, this, server);
825                 picon->create_objects();
826                 output->append(picon);
827         }
828 }
829
830 void AWindowGUI::update_asset_list()
831 {
832 //printf("AWindowGUI::update_asset_list 1\n");
833         for(int i = 0; i < assets.total; i++)
834         {
835                 AssetPicon *picon = (AssetPicon*)assets.values[i];
836                 picon->in_use--;
837         }
838
839
840
841
842
843 //printf("AWindowGUI::update_asset_list 2\n");
844
845
846 // Synchronize EDL clips
847         for(int i = 0; i < mwindow->edl->clips.total; i++)
848         {
849                 int exists = 0;
850                 
851 // Look for clip in existing listitems
852                 for(int j = 0; j < assets.total && !exists; j++)
853                 {
854                         AssetPicon *picon = (AssetPicon*)assets.values[j];
855                         
856                         if(picon->id == mwindow->edl->clips.values[i]->id)
857                         {
858                                 picon->edl = mwindow->edl->clips.values[i];
859                                 picon->set_text(mwindow->edl->clips.values[i]->local_session->clip_title);
860                                 exists = 1;
861                                 picon->in_use = 1;
862                         }
863                 }
864
865 // Create new listitem
866                 if(!exists)
867                 {
868                         AssetPicon *picon = new AssetPicon(mwindow, 
869                                 this, 
870                                 mwindow->edl->clips.values[i]);
871                         picon->create_objects();
872                         assets.append(picon);
873                 }
874         }
875
876
877
878
879
880 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
881
882
883 // Synchronize EDL assets
884         for(Asset *current = mwindow->edl->assets->first; 
885                 current; 
886                 current = NEXT)
887         {
888                 int exists = 0;
889
890 // Look for asset in existing listitems
891                 for(int j = 0; j < assets.total && !exists; j++)
892                 {
893                         AssetPicon *picon = (AssetPicon*)assets.values[j];
894
895                         if(picon->id == current->id)
896                         {
897                                 picon->indexable = current;
898                                 exists = 1;
899                                 picon->in_use = 1;
900                                 break;
901                         }
902                 }
903
904 // Create new listitem
905                 if(!exists)
906                 {
907 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
908                         AssetPicon *picon = new AssetPicon(mwindow, this, current);
909 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
910                         picon->create_objects();
911 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
912                         assets.append(picon);
913                 }
914         }
915
916
917
918 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
919
920
921 // Synchronize nested EDLs
922         for(int i = 0; i < mwindow->edl->nested_edls->size(); i++)
923         {
924                 int exists = 0;
925                 Indexable *indexable = mwindow->edl->nested_edls->get(i);
926
927 // Look for asset in existing listitems
928                 for(int j = 0; j < assets.total && !exists; j++)
929                 {
930                         AssetPicon *picon = (AssetPicon*)assets.values[j];
931
932                         if(picon->id == indexable->id)
933                         {
934                                 picon->indexable = indexable;
935                                 exists = 1;
936                                 picon->in_use = 1;
937                                 break;
938                         }
939                 }
940
941 // Create new listitem
942                 if(!exists)
943                 {
944                         AssetPicon *picon = new AssetPicon(mwindow, 
945                                 this, 
946                                 indexable);
947                         picon->create_objects();
948                         assets.append(picon);
949                 }
950         }
951
952
953
954
955
956
957
958
959
960 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
961         for(int i = assets.size() - 1; i >= 0; i--)
962         {
963                 AssetPicon *picon = (AssetPicon*)assets.get(i);
964 //printf("AWindowGUI::update_asset_list %s %d\n", picon->asset->path, picon->in_use);
965                 if(!picon->in_use)
966                 {
967                         delete picon;
968                         assets.remove_number(i);
969                 }
970         }
971 //printf("AWindowGUI::update_asset_list 7 %d\n", assets.total);
972 }
973
974
975
976
977
978 void AWindowGUI::sort_assets()
979 {
980 //printf("AWindowGUI::sort_assets 1 %s\n", mwindow->edl->session->current_folder);
981         if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER))
982                 sort_picons(&aeffects, 
983                         0);
984         else
985         if(!strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER))
986                 sort_picons(&veffects, 
987                         0);
988         else
989         if(!strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER))
990                 sort_picons(&atransitions, 
991                         0);
992         else
993         if(!strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
994                 sort_picons(&vtransitions, 
995                         0);
996         else
997                 sort_picons(&assets, 
998                         mwindow->edl->session->current_folder);
999
1000         update_assets();
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013 void AWindowGUI::collect_assets()
1014 {
1015         int i = 0;
1016         mwindow->session->drag_assets->remove_all();
1017         mwindow->session->drag_clips->remove_all();
1018         while(1)
1019         {
1020                 AssetPicon *result = (AssetPicon*)asset_list->get_selection(0, i++);
1021                 if(!result) break;
1022
1023                 if(result->indexable) mwindow->session->drag_assets->append(result->indexable);
1024                 if(result->edl) mwindow->session->drag_clips->append(result->edl);
1025         }
1026 }
1027
1028 void AWindowGUI::copy_picons(ArrayList<BC_ListBoxItem*> *dst, 
1029         ArrayList<BC_ListBoxItem*> *src, 
1030         char *folder)
1031 {
1032 // Remove current pointers
1033         dst[0].remove_all();
1034         dst[1].remove_all_objects();
1035
1036 // Create new pointers
1037 //if(folder) printf("AWindowGUI::copy_picons 1 %s\n", folder);
1038         for(int i = 0; i < src->total; i++)
1039         {
1040                 AssetPicon *picon = (AssetPicon*)src->values[i];
1041 //printf("AWindowGUI::copy_picons 2 %s\n", picon->asset->folder);
1042                 if(!folder ||
1043                         (folder && picon->indexable && !strcasecmp(picon->indexable->folder, folder)) ||
1044                         (folder && picon->edl && !strcasecmp(picon->edl->local_session->folder, folder)))
1045                 {
1046                         BC_ListBoxItem *item2, *item1;
1047                         dst[0].append(item1 = picon);
1048                         if(picon->edl)
1049                                 dst[1].append(item2 = new BC_ListBoxItem(picon->edl->local_session->clip_notes));
1050                         else
1051                                 dst[1].append(item2 = new BC_ListBoxItem(""));
1052                         item1->set_autoplace_text(1);
1053                         item2->set_autoplace_text(1);
1054 //printf("AWindowGUI::copy_picons 3 %s\n", picon->get_text());
1055                 }
1056         }
1057 }
1058
1059 void AWindowGUI::sort_picons(ArrayList<BC_ListBoxItem*> *src, 
1060                 char *folder)
1061 {
1062 //printf("AWindowGUI::sort_picons 1\n")
1063         int done = 0;
1064         while(!done)
1065         {
1066                 done = 1;
1067                 for(int i = 0; i < src->total - 1; i++)
1068                 {
1069                         BC_ListBoxItem *item1 = src->values[i];
1070                         BC_ListBoxItem *item2 = src->values[i + 1];
1071                         item1->set_autoplace_icon(1);
1072                         item2->set_autoplace_icon(1);
1073                         item1->set_autoplace_text(1);
1074                         item2->set_autoplace_text(1);
1075                         if(strcmp(item1->get_text(), item2->get_text()) > 0)
1076                         {
1077                                 src->values[i + 1] = item1;
1078                                 src->values[i] = item2;
1079                                 done = 0;
1080                         }
1081                 }
1082         }
1083 }
1084
1085
1086 void AWindowGUI::filter_displayed_assets()
1087 {
1088         if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER))
1089                 copy_picons(displayed_assets, 
1090                         &aeffects, 
1091                         0);
1092         else
1093         if(!strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER))
1094                 copy_picons(displayed_assets, 
1095                         &veffects, 
1096                         0);
1097         else
1098         if(!strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER))
1099                 copy_picons(displayed_assets, 
1100                         &atransitions, 
1101                         0);
1102         else
1103         if(!strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1104                 copy_picons(displayed_assets, 
1105                         &vtransitions, 
1106                         0);
1107         else
1108                 copy_picons(displayed_assets, 
1109                         &assets, 
1110                         mwindow->edl->session->current_folder);
1111 }
1112
1113
1114 void AWindowGUI::update_assets()
1115 {
1116 //printf("AWindowGUI::update_assets 1\n");
1117         update_folder_list();
1118 //printf("AWindowGUI::update_assets 2\n");
1119         update_asset_list();
1120 //printf("AWindowGUI::update_assets 3\n");
1121         filter_displayed_assets();
1122
1123 //for(int i = 0; i < folders.total; i++)
1124 //printf("AWindowGUI::update_assets 4\n");
1125 //      printf("AWindowGUI::update_assets %s\n", folders.values[i]->get_text());
1126         if(mwindow->edl->session->folderlist_format != folder_list->get_format())
1127                 folder_list->update_format(mwindow->edl->session->folderlist_format, 0);
1128         folder_list->update(&folders,
1129                 0,
1130                 0,
1131                 1,
1132                 folder_list->get_xposition(),
1133                 folder_list->get_yposition(),
1134                 -1);
1135 //printf("AWindowGUI::update_assets 5\n");
1136
1137         if(mwindow->edl->session->assetlist_format != asset_list->get_format())
1138                 asset_list->update_format(mwindow->edl->session->assetlist_format, 0);
1139
1140
1141 //printf("AWindowGUI::update_assets 6 %d\n", displayed_assets[0].total);
1142         asset_list->update(displayed_assets,
1143                 asset_titles,
1144                 mwindow->edl->session->asset_columns,
1145                 ASSET_COLUMNS, 
1146                 asset_list->get_xposition(),
1147                 asset_list->get_yposition(),
1148                 -1,
1149                 0);
1150 //printf("AWindowGUI::update_assets 7\n");
1151
1152         flush();
1153 //printf("AWindowGUI::update_assets 8\n");
1154         return;
1155 }
1156
1157 void AWindowGUI::update_effects()
1158 {
1159         aeffects.remove_all_objects();
1160         create_persistent_folder(&aeffects, 1, 0, 1, 0);
1161         veffects.remove_all_objects();
1162         create_persistent_folder(&veffects, 0, 1, 1, 0);
1163         atransitions.remove_all_objects();
1164         create_persistent_folder(&atransitions, 1, 0, 0, 1);
1165         vtransitions.remove_all_objects();
1166         create_persistent_folder(&vtransitions, 0, 1, 0, 1);
1167 }
1168
1169 int AWindowGUI::current_folder_number()
1170 {
1171         int result = -1;
1172         for(int i = 0; i < folders.total; i++)
1173         {
1174                 if(!strcasecmp(folders.values[i]->get_text(), mwindow->edl->session->current_folder))
1175                 {
1176                         result = i;
1177                         break;
1178                 }
1179         }
1180         return result;
1181 }
1182
1183 int AWindowGUI::drag_motion()
1184 {
1185         if(get_hidden()) return 0;
1186
1187         int result = 0;
1188         return result;
1189 }
1190
1191 int AWindowGUI::drag_stop()
1192 {
1193         if(get_hidden()) return 0;
1194
1195         return 0;
1196 }
1197
1198 Indexable* AWindowGUI::selected_asset()
1199 {
1200         AssetPicon *picon = (AssetPicon*)asset_list->get_selection(0, 0);
1201         return picon ? picon->indexable : 0;
1202 }
1203
1204 PluginServer* AWindowGUI::selected_plugin()
1205 {
1206         AssetPicon *picon = (AssetPicon*)asset_list->get_selection(0, 0);
1207         return picon ? picon->plugin : 0;
1208 }
1209
1210 AssetPicon* AWindowGUI::selected_folder()
1211 {
1212         AssetPicon *picon = (AssetPicon*)folder_list->get_selection(0, 0);
1213         return picon;
1214 }
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225 AWindowDivider::AWindowDivider(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1226  : BC_SubWindow(x, y, w, h)
1227 {
1228         this->mwindow = mwindow;
1229         this->gui = gui;
1230 }
1231 AWindowDivider::~AWindowDivider()
1232 {
1233 }
1234
1235 int AWindowDivider::button_press_event()
1236 {
1237         if(is_event_win() && cursor_inside())
1238         {
1239                 mwindow->session->current_operation = DRAG_PARTITION;
1240                 return 1;
1241         }
1242         return 0;
1243 }
1244
1245 int AWindowDivider::cursor_motion_event()
1246 {
1247         if(mwindow->session->current_operation == DRAG_PARTITION)
1248         {
1249                 mwindow->session->afolders_w = gui->get_relative_cursor_x();
1250                 gui->reposition_objects();
1251         }
1252         return 0;
1253 }
1254
1255 int AWindowDivider::button_release_event()
1256 {
1257         if(mwindow->session->current_operation == DRAG_PARTITION)
1258         {
1259                 mwindow->session->current_operation = NO_OPERATION;
1260                 return 1;
1261         }
1262         return 0;
1263 }
1264
1265
1266
1267
1268
1269
1270 AWindowFolders::AWindowFolders(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1271  : BC_ListBox(x, 
1272                 y, 
1273                 w, 
1274                 h,
1275                 mwindow->edl->session->folderlist_format == FOLDERS_ICONS ? 
1276                         LISTBOX_ICONS : LISTBOX_TEXT, 
1277                 &gui->folders, // Each column has an ArrayList of BC_ListBoxItems.
1278                 0,             // Titles for columns.  Set to 0 for no titles
1279                 0,                // width of each column
1280                 1,                      // Total columns.
1281                 0,                    // Pixel of top of window.
1282                 0,                        // If this listbox is a popup window
1283                 LISTBOX_SINGLE,  // Select one item or multiple items
1284                 ICON_TOP,        // Position of icon relative to text of each item
1285                 1)               // Allow drags
1286 {
1287         this->mwindow = mwindow;
1288         this->gui = gui;
1289         set_drag_scroll(0);
1290 }
1291
1292 AWindowFolders::~AWindowFolders()
1293 {
1294 }
1295         
1296 int AWindowFolders::selection_changed()
1297 {
1298         AssetPicon *picon = (AssetPicon*)get_selection(0, 0);
1299         if(picon)
1300         {
1301                 if(get_button_down() && get_buttonpress() == 3)
1302                 {
1303                         gui->folderlist_menu->update_titles();
1304                         gui->folderlist_menu->activate_menu();
1305                 }
1306
1307                 strcpy(mwindow->edl->session->current_folder, picon->get_text());
1308 //printf("AWindowFolders::selection_changed 1\n");
1309                 gui->asset_list->draw_background();
1310                 gui->update_assets();
1311         }
1312         return 1;
1313 }
1314
1315 int AWindowFolders::button_press_event()
1316 {
1317         int result = 0;
1318
1319         result = BC_ListBox::button_press_event();
1320
1321         if(!result)
1322         {
1323                 if(get_buttonpress() == 3 && is_event_win() && cursor_inside())
1324                 {
1325                         gui->folderlist_menu->update_titles();
1326                         gui->folderlist_menu->activate_menu();
1327                         result = 1;
1328                 }
1329         }
1330
1331
1332         return result;
1333 }
1334
1335
1336
1337
1338
1339
1340
1341 AWindowAssets::AWindowAssets(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1342  : BC_ListBox(x, 
1343                 y, 
1344                 w, 
1345                 h,
1346                 mwindow->edl->session->assetlist_format == ASSETS_ICONS ? 
1347                         LISTBOX_ICONS : LISTBOX_TEXT,
1348                 &gui->assets,     // Each column has an ArrayList of BC_ListBoxItems.
1349                 gui->asset_titles,             // Titles for columns.  Set to 0 for no titles
1350                 mwindow->edl->session->asset_columns,                // width of each column
1351                 1,                      // Total columns.
1352                 0,                    // Pixel of top of window.
1353                 0,                        // If this listbox is a popup window
1354                 LISTBOX_MULTIPLE,  // Select one item or multiple items
1355                 ICON_TOP,        // Position of icon relative to text of each item
1356                 1)               // Allow drag
1357 {
1358         this->mwindow = mwindow;
1359         this->gui = gui;
1360         set_drag_scroll(0);
1361 }
1362
1363 AWindowAssets::~AWindowAssets()
1364 {
1365 }
1366
1367 int AWindowAssets::button_press_event()
1368 {
1369         int result = 0;
1370
1371         result = BC_ListBox::button_press_event();
1372
1373         if(!result && get_buttonpress() == 3 && is_event_win() && cursor_inside())
1374         {
1375                 BC_ListBox::deactivate_selection();
1376                 gui->assetlist_menu->update_titles();
1377                 gui->assetlist_menu->activate_menu();
1378                 result = 1;
1379         }
1380
1381
1382         return result;
1383 }
1384
1385
1386 int AWindowAssets::handle_event()
1387 {
1388 //printf("AWindowAssets::handle_event 1 %d %d\n", get_buttonpress(), get_selection(0, 0));
1389         if(get_selection(0, 0))
1390         {
1391                 if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER))
1392                 {
1393                 }
1394                 else
1395                 if(!strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER))
1396                 {
1397                 }
1398                 else
1399                 if(!strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER))
1400                 {
1401                 }
1402                 else
1403                 if(!strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1404                 {
1405                 }
1406                 else
1407                 if(mwindow->vwindows.size())
1408                 {
1409 //printf("AWindowAssets::handle_event 2 %d %d\n", get_buttonpress(), get_selection(0, 0));
1410                         mwindow->vwindows.get(DEFAULT_VWINDOW)->gui->lock_window("AWindowAssets::handle_event");
1411                         
1412                         if(((AssetPicon*)get_selection(0, 0))->indexable)
1413                                 mwindow->vwindows.get(DEFAULT_VWINDOW)->change_source(((AssetPicon*)get_selection(0, 0))->indexable);
1414                         else
1415                         if(((AssetPicon*)get_selection(0, 0))->edl)
1416                                 mwindow->vwindows.get(DEFAULT_VWINDOW)->change_source(((AssetPicon*)get_selection(0, 0))->edl);
1417
1418                         mwindow->vwindows.get(DEFAULT_VWINDOW)->gui->unlock_window();
1419                 }
1420                 return 1;
1421         }
1422
1423         return 0;
1424 }
1425
1426 int AWindowAssets::selection_changed()
1427 {
1428 // Show popup window
1429         if(get_button_down() && get_buttonpress() == 3 && get_selection(0, 0))
1430         {
1431                 if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER) || 
1432                         !strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER) ||
1433                         !strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER) ||
1434                         !strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1435                 {
1436                         gui->assetlist_menu->update_titles();
1437                         gui->assetlist_menu->activate_menu();
1438                 }
1439                 else
1440                 {
1441                         if(((AssetPicon*)get_selection(0, 0))->indexable)
1442                                 gui->asset_menu->update();
1443                         else
1444                         if(((AssetPicon*)get_selection(0, 0))->edl)
1445                                 gui->asset_menu->update();
1446
1447
1448
1449                         gui->asset_menu->activate_menu();
1450                 }
1451
1452                 BC_ListBox::deactivate_selection();
1453                 return 1;
1454         }
1455         return 0;
1456 }
1457
1458 void AWindowAssets::draw_background()
1459 {
1460         clear_box(0,0,get_w(),get_h(),get_bg_surface());
1461         set_color(RED);
1462         set_font(LARGEFONT);
1463         draw_text(get_w() - 
1464                         get_text_width(LARGEFONT, mwindow->edl->session->current_folder) - 4, 
1465                 30, 
1466                 mwindow->edl->session->current_folder, 
1467                 -1, 
1468                 get_bg_surface());
1469 }
1470
1471 int AWindowAssets::drag_start_event()
1472 {
1473         int collect_pluginservers = 0;
1474         int collect_assets = 0;
1475
1476         if(BC_ListBox::drag_start_event())
1477         {
1478                 if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER))
1479                 {
1480                         mwindow->session->current_operation = DRAG_AEFFECT;
1481                         collect_pluginservers = 1;
1482                 }
1483                 else
1484                 if(!strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER))
1485                 {
1486                         mwindow->session->current_operation = DRAG_VEFFECT;
1487                         collect_pluginservers = 1;
1488                 }
1489                 else
1490                 if(!strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER))
1491                 {
1492                         mwindow->session->current_operation = DRAG_ATRANSITION;
1493                         collect_pluginservers = 1;
1494                 }
1495                 else
1496                 if(!strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1497                 {
1498                         mwindow->session->current_operation = DRAG_VTRANSITION;
1499                         collect_pluginservers = 1;
1500                 }
1501                 else
1502                 {
1503                         mwindow->session->current_operation = DRAG_ASSET;
1504                         collect_assets = 1;
1505                 }
1506                 
1507                 
1508                 if(collect_pluginservers)
1509                 {
1510                         int i = 0;
1511                         mwindow->session->drag_pluginservers->remove_all();
1512                         while(1)
1513                         {
1514                                 AssetPicon *result = (AssetPicon*)get_selection(0, i++);
1515                                 if(!result) break;
1516                                 
1517                                 mwindow->session->drag_pluginservers->append(result->plugin);
1518                         }
1519                 }
1520                 
1521                 if(collect_assets)
1522                 {
1523                         gui->collect_assets();
1524                 }
1525
1526                 return 1;
1527         }
1528         return 0;
1529 }
1530
1531 int AWindowAssets::drag_motion_event()
1532 {
1533         BC_ListBox::drag_motion_event();
1534         unlock_window();
1535
1536         mwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1537         mwindow->gui->drag_motion();
1538         mwindow->gui->unlock_window();
1539
1540         for(int i = 0; i < mwindow->vwindows.size(); i++)
1541         {
1542                 VWindow *vwindow = mwindow->vwindows.get(i);
1543                 vwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1544                 vwindow->gui->drag_motion();
1545                 vwindow->gui->unlock_window();
1546         }
1547
1548         mwindow->cwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1549         mwindow->cwindow->gui->drag_motion();
1550         mwindow->cwindow->gui->unlock_window();
1551
1552         lock_window("AWindowAssets::drag_motion_event");
1553         return 0;
1554 }
1555
1556 int AWindowAssets::drag_stop_event()
1557 {
1558         int result = 0;
1559
1560         result = gui->drag_stop();
1561
1562         unlock_window();
1563
1564         if(!result)
1565         {
1566                 mwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1567                 result = mwindow->gui->drag_stop();
1568                 mwindow->gui->unlock_window();
1569         }
1570
1571         if(!result) 
1572         {
1573                 for(int i = 0; i < mwindow->vwindows.size(); i++)
1574                 {
1575                         VWindow *vwindow = mwindow->vwindows.get(i);
1576                         vwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1577                         result = vwindow->gui->drag_stop();
1578                         vwindow->gui->unlock_window();
1579                 }
1580         }
1581
1582         if(!result) 
1583         {
1584                 mwindow->cwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1585                 result = mwindow->cwindow->gui->drag_stop();
1586                 mwindow->cwindow->gui->unlock_window();
1587         }
1588
1589         lock_window("AWindowAssets::drag_stop_event");
1590
1591         if(result) get_drag_popup()->set_animation(0);
1592
1593         BC_ListBox::drag_stop_event();
1594         mwindow->session->current_operation = ::NO_OPERATION; // since NO_OPERATION is also defined in listbox, we have to reach for global scope...
1595         return 0;
1596 }
1597
1598 int AWindowAssets::column_resize_event()
1599 {
1600         mwindow->edl->session->asset_columns[0] = get_column_width(0);
1601         mwindow->edl->session->asset_columns[1] = get_column_width(1);
1602         return 1;
1603 }
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616 AWindowNewFolder::AWindowNewFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1617  : BC_Button(x, y, mwindow->theme->newbin_data)
1618 {
1619         this->mwindow = mwindow;
1620         this->gui = gui;
1621         set_tooltip(_("New bin"));
1622 }
1623
1624 int AWindowNewFolder::handle_event()
1625 {
1626         gui->newfolder_thread->start_new_folder();
1627         return 1;
1628 }
1629
1630 AWindowDeleteFolder::AWindowDeleteFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1631  : BC_Button(x, y, mwindow->theme->deletebin_data)
1632 {
1633         this->mwindow = mwindow;
1634         this->gui = gui;
1635         set_tooltip(_("Delete bin"));
1636 }
1637
1638 int AWindowDeleteFolder::handle_event()
1639 {
1640         if(gui->folder_list->get_selection(0, 0))
1641         {
1642                 BC_ListBoxItem *folder = gui->folder_list->get_selection(0, 0);
1643                 mwindow->delete_folder(folder->get_text());
1644         }
1645         return 1;
1646 }
1647
1648 AWindowRenameFolder::AWindowRenameFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1649  : BC_Button(x, y, mwindow->theme->renamebin_data)
1650 {
1651         this->mwindow = mwindow;
1652         this->gui = gui;
1653         set_tooltip(_("Rename bin"));
1654 }
1655
1656 int AWindowRenameFolder::handle_event()
1657 {
1658         return 1;
1659 }
1660
1661 AWindowDeleteDisk::AWindowDeleteDisk(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1662  : BC_Button(x, y, mwindow->theme->deletedisk_data)
1663 {
1664         this->mwindow = mwindow;
1665         this->gui = gui;
1666         set_tooltip(_("Delete asset from disk"));
1667 }
1668
1669 int AWindowDeleteDisk::handle_event()
1670 {
1671         return 1;
1672 }
1673
1674 AWindowDeleteProject::AWindowDeleteProject(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1675  : BC_Button(x, y, mwindow->theme->deleteproject_data)
1676 {
1677         this->mwindow = mwindow;
1678         this->gui = gui;
1679         set_tooltip(_("Delete asset from project"));
1680 }
1681
1682 int AWindowDeleteProject::handle_event()
1683 {
1684         return 1;
1685 }
1686
1687 AWindowInfo::AWindowInfo(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1688  : BC_Button(x, y, mwindow->theme->infoasset_data)
1689 {
1690         this->mwindow = mwindow;
1691         this->gui = gui;
1692         set_tooltip(_("Edit information on asset"));
1693 }
1694
1695 int AWindowInfo::handle_event()
1696 {
1697         gui->awindow->asset_edit->edit_asset(gui->selected_asset());
1698         return 1;
1699 }
1700
1701 AWindowRedrawIndex::AWindowRedrawIndex(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1702  : BC_Button(x, y, mwindow->theme->redrawindex_data)
1703 {
1704         this->mwindow = mwindow;
1705         this->gui = gui;
1706         set_tooltip(_("Redraw index"));
1707 }
1708
1709 int AWindowRedrawIndex::handle_event()
1710 {
1711         return 1;
1712 }
1713
1714 AWindowPaste::AWindowPaste(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1715  : BC_Button(x, y, mwindow->theme->pasteasset_data)
1716 {
1717         this->mwindow = mwindow;
1718         this->gui = gui;
1719         set_tooltip(_("Paste asset on recordable tracks"));
1720 }
1721
1722 int AWindowPaste::handle_event()
1723 {
1724         return 1;
1725 }
1726
1727 AWindowAppend::AWindowAppend(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1728  : BC_Button(x, y, mwindow->theme->appendasset_data)
1729 {
1730         this->mwindow = mwindow;
1731         this->gui = gui;
1732         set_tooltip(_("Append asset in new tracks"));
1733 }
1734
1735 int AWindowAppend::handle_event()
1736 {
1737         return 1;
1738 }
1739
1740 AWindowView::AWindowView(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1741  : BC_Button(x, y, mwindow->theme->viewasset_data)
1742 {
1743         this->mwindow = mwindow;
1744         this->gui = gui;
1745         set_tooltip(_("View asset"));
1746 }
1747
1748 int AWindowView::handle_event()
1749 {
1750         return 1;
1751 }
1752
1753 AddTools::AddTools(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w)
1754  : BC_MenuBar(x, y, w)
1755 {
1756         this->mwindow = mwindow;
1757         this->gui = gui;
1758 }
1759
1760 void AddTools::create_objects()
1761 {
1762         add_menu(add_plugins = new AddPluginsMenu(mwindow, gui));
1763         add_plugins->create_objects();
1764 }
1765
1766 AddPluginsMenu::AddPluginsMenu(MWindow *mwindow, AWindowGUI *gui)
1767  : BC_Menu("Add Tools")
1768 {
1769         this->mwindow = mwindow;
1770         this->gui = gui;
1771 }
1772
1773 void AddPluginsMenu::create_objects()
1774 {
1775         uint64_t vis = 0;
1776         add_item(new AddPluginItem(this, "ladspa", PLUGIN_LADSPA_ID));
1777         vis |= 1 << PLUGIN_LADSPA_ID;
1778         add_item(new AddPluginItem(this, "ffmpeg", PLUGIN_FFMPEG_ID));
1779         vis |= 1 << PLUGIN_FFMPEG_ID;
1780         for( int i=0; i<MWindow::plugindb->size(); ++i ) {
1781                 PluginServer *plugin = MWindow::plugindb->get(i);
1782                 if( !plugin->audio && !plugin->video ) continue;
1783                 int idx = plugin->dir_idx;
1784                 uint32_t msk = 1 << idx;
1785                 if( (msk & vis) != 0 ) continue;
1786                 vis |= msk;
1787                 char parent[BCTEXTLEN];
1788                 strcpy(parent, plugin->path);
1789                 char *bp = strrchr(parent, '/');
1790                 if( bp ) { *bp = 0;  bp = strrchr(parent, '/'); }
1791                 if( !bp ) bp = parent; else ++bp;
1792                 add_item(new AddPluginItem(this, bp, idx));
1793         }
1794 }
1795
1796 AddPluginItem::AddPluginItem(AddPluginsMenu *menu, char const *text, int idx)
1797  : BC_MenuItem(text)
1798 {
1799         this->menu = menu;
1800         this->idx = idx;
1801         uint64_t msk = (uint64_t)1 << idx, vis = menu->gui->plugin_visibility;
1802         int chk = (msk & vis) ? 1 : 0;
1803         set_checked(chk);
1804 }
1805
1806 int AddPluginItem::handle_event()
1807 {
1808         int chk = get_checked() ^ 1;
1809         set_checked(chk);
1810         uint64_t msk = (uint64_t)1 << idx, vis = menu->gui->plugin_visibility;
1811         menu->gui->plugin_visibility = chk ? vis | msk : vis & ~msk;
1812         menu->gui->update_effects();
1813         menu->gui->update_assets();
1814         menu->gui->save_defaults(menu->mwindow->defaults);
1815         return 1;
1816 }
1817