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