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