f7d690acfb89fcf5ba265824d449caf995e037df
[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 = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];
301                                 }
302                         }
303                         else {
304                                 icon = gui->video_icon;
305                                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];
306                         }
307                 }
308                 else
309                 if( asset->audio_data ) {
310                         icon = gui->audio_icon;
311                         icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_SOUND];
312                 }
313
314         }
315         else
316         if( indexable && !indexable->is_asset ) {
317                 icon = gui->video_icon;
318                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];
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 = BC_WindowBase::get_resources()->type_to_icon[ICON_LABEL];
377                 set_icon(icon);
378                 set_icon_vframe(icon_vframe);
379         }
380         if( !icon ) {
381                 icon = gui->file_icon;
382                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_UNKNOWN];
383         }
384         set_icon(icon);
385         set_icon_vframe(icon_vframe);
386 }
387
388 AWindowGUI::AWindowGUI(MWindow *mwindow, AWindow *awindow)
389  : BC_Window(_(PROGRAM_NAME ": Resources"),
390         mwindow->session->awindow_x, mwindow->session->awindow_y,
391         mwindow->session->awindow_w, mwindow->session->awindow_h,
392         100, 100, 1, 1, 1)
393 {
394         this->mwindow = mwindow;
395         this->awindow = awindow;
396
397         file_vframe = 0;                file_icon = 0;
398         folder_vframe = 0;              folder_icon = 0;
399         audio_vframe = 0;               audio_icon = 0;
400         video_vframe = 0;               video_icon = 0;
401         label_vframe = 0;               label_icon = 0;
402
403         atransition_vframe = 0;         atransition_icon = 0;
404         vtransition_vframe = 0;         vtransition_icon = 0;
405         aeffect_vframe = 0;             aeffect_icon = 0;
406         ladspa_vframe = 0;              ladspa_icon = 0;
407         veffect_vframe = 0;             veffect_icon = 0;
408         ff_aud_vframe = 0;              ff_aud_icon = 0;
409         ff_vid_vframe = 0;              ff_vid_icon = 0;
410
411         aeffect_folder_vframe = 0;      aeffect_folder_icon = 0;
412         atransition_folder_vframe = 0;  atransition_folder_icon = 0;
413         clip_folder_vframe = 0;         clip_folder_icon = 0;
414         label_folder_vframe = 0;        label_folder_icon = 0;
415         media_folder_vframe = 0;        media_folder_icon = 0;
416         proxy_folder_vframe = 0;        proxy_folder_icon = 0;
417         veffect_folder_vframe = 0;      veffect_folder_icon = 0;
418         vtransition_folder_vframe = 0;  vtransition_folder_icon = 0;
419
420         ladspa_vframe = 0;              ladspa_icon = 0;
421         ff_aud_vframe = 0;              ff_aud_icon = 0;
422         ff_vid_vframe = 0;              ff_vid_icon = 0;
423
424         clip_vframe = 0;                clip_icon = 0;
425         atransition_vframe = 0;         atransition_icon = 0;
426         vtransition_vframe = 0;         vtransition_icon = 0;
427         aeffect_vframe = 0;             aeffect_icon = 0;
428         veffect_vframe = 0;             veffect_icon = 0;
429
430         plugin_visibility = ((uint64_t)1<<(8*sizeof(uint64_t)-1))-1;
431         newfolder_thread = 0;
432         asset_menu = 0;
433         effectlist_menu = 0;
434         assetlist_menu = 0;
435         cliplist_menu = 0;
436         labellist_menu = 0;
437         folderlist_menu = 0;
438         temp_picon = 0;
439         allow_iconlisting = 1;
440         remove_plugin = 0;
441         vicon_thread = 0;
442         vicon_drawing = 1;
443         displayed_folder = AW_NO_FOLDER;
444 }
445
446 AWindowGUI::~AWindowGUI()
447 {
448         assets.remove_all_objects();
449         folders.remove_all_objects();
450         aeffects.remove_all_objects();
451         veffects.remove_all_objects();
452         atransitions.remove_all_objects();
453         vtransitions.remove_all_objects();
454         labellist.remove_all_objects();
455         displayed_assets[1].remove_all_objects();
456
457         delete vicon_thread;
458         delete newfolder_thread;
459
460         delete asset_menu;
461         delete clip_menu;
462         delete label_menu;
463         delete effectlist_menu;
464         delete assetlist_menu;
465         delete cliplist_menu;
466         delete labellist_menu;
467         delete folderlist_menu;
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 + 5;
618         int w1 = mwindow->theme->alist_w, h1 = mwindow->theme->alist_h;
619         search_text = new AWindowSearchText(mwindow, this, x1, y1);
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 + 5;
722         int w1 = mwindow->theme->alist_w, h1 = mwindow->theme->alist_h;
723         search_text->reposition_window(x1, y1, 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                 ArrayList<BC_ListBoxItem*> *folder =
839                         plugin->audio ? plugin->transition ?
840                                 &awindow->gui->atransitions :
841                                 &awindow->gui->aeffects :
842                         plugin->video ?  plugin->transition ?
843                                 &awindow->gui->vtransitions :
844                                 &awindow->gui->veffects :
845                         0;
846                 if( folder ) remove_plugin(plugin, *folder);
847                 char plugin_path[BCTEXTLEN];
848                 strcpy(plugin_path, plugin->path);
849                 MWindow *mwindow = awindow->mwindow;
850                 mwindow->plugindb->remove(plugin);
851                 remove(plugin_path);
852                 char index_path[BCTEXTLEN];
853                 snprintf(index_path, sizeof(index_path), "%s/%s",
854                         mwindow->preferences->plugin_dir, PLUGIN_FILE);
855                 remove(index_path);
856                 char picon_path[BCTEXTLEN];
857                 FileSystem fs;
858                 snprintf(picon_path, sizeof(picon_path), "%s/picon",
859                         File::get_plugin_path());
860                 char png_name[BCSTRLEN], png_path[BCTEXTLEN];
861                 plugin->get_plugin_png_name(png_name);
862                 fs.update(picon_path);
863                 for( int i=0; i<fs.dir_list.total; ++i ) {
864                         char *fs_path = fs.dir_list[i]->path;
865                         if( !fs.is_dir(fs_path) ) continue;
866                         snprintf(png_path, sizeof(picon_path), "%s/%s",
867                                 fs_path, png_name);
868                         remove(png_path);
869                 }
870                 delete plugin;  plugin = 0;
871                 awindow->gui->async_update_assets();
872         }
873 }
874
875 AWindowRemovePlugin::
876 AWindowRemovePlugin(AWindow *awindow, PluginServer *plugin)
877  : BC_DialogThread()
878 {
879         this->awindow = awindow;
880         this->plugin = plugin;
881 }
882
883 AWindowRemovePlugin::
884 ~AWindowRemovePlugin()
885 {
886         close_window();
887 }
888
889 BC_Window* AWindowRemovePlugin::new_gui()
890 {
891         int x = awindow->gui->get_abs_cursor_x(0);
892         int y = awindow->gui->get_abs_cursor_y(0);
893         AWindowRemovePluginGUI *gui = new AWindowRemovePluginGUI(awindow, this, x, y, plugin);
894         gui->create_objects();
895         return gui;
896 }
897
898 int AWindowGUI::keypress_event()
899 {
900         switch( get_keypress() ) {
901         case 'w': case 'W':
902                 if( ctrl_down() ) {
903                         close_event();
904                         return 1;
905                 }
906                 break;
907         case DELETE:
908                 if( shift_down() ) {
909                         PluginServer* plugin = selected_plugin();
910                         if( !plugin ) break;
911                         remove_plugin = new AWindowRemovePlugin(awindow, plugin);
912                         unlock_window();
913                         remove_plugin->start();
914                         lock_window();
915                 }
916         }
917         return 0;
918 }
919
920
921
922 int AWindowGUI::create_custom_xatoms()
923 {
924         UpdateAssetsXAtom = create_xatom("CWINDOWGUI_UPDATE_ASSETS");
925         return 0;
926 }
927 int AWindowGUI::recieve_custom_xatoms(xatom_event *event)
928 {
929         if( event->message_type == UpdateAssetsXAtom ) {
930                 update_assets();
931                 return 1;
932         }
933         return 0;
934 }
935
936 void AWindowGUI::async_update_assets()
937 {
938         xatom_event event;
939         event.message_type = UpdateAssetsXAtom;
940         send_custom_xatom(&event);
941 }
942
943
944 void AWindowGUI::update_folder_list()
945 {
946         stop_vicon_drawing();
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         start_vicon_drawing();
986 }
987
988 void AWindowGUI::create_persistent_folder(ArrayList<BC_ListBoxItem*> *output,
989         int do_audio, int do_video, int is_realtime, int is_transition)
990 {
991         ArrayList<PluginServer*> plugin_list;
992 // Get pointers to plugindb entries
993         mwindow->search_plugindb(do_audio, do_video, is_realtime, is_transition,
994                         0, plugin_list);
995
996         for( int i = 0; i < plugin_list.total; i++ ) {
997                 PluginServer *server = plugin_list.values[i];
998                 int visible = plugin_visibility & (1<<server->dir_idx);
999                 if( !visible ) continue;
1000 // Create new listitem
1001                 AssetPicon *picon = new AssetPicon(mwindow, this, server);
1002                 picon->create_objects();
1003                 output->append(picon);
1004         }
1005 }
1006
1007 void AWindowGUI::create_label_folder()
1008 {
1009         Label *current;
1010         for( current = mwindow->edl->labels->first; current; current = NEXT ) {
1011                 AssetPicon *picon = new AssetPicon(mwindow, this, current);
1012                 picon->create_objects();
1013                 labellist.append(picon);
1014         }
1015 }
1016
1017
1018 void AWindowGUI::update_asset_list()
1019 {
1020         for( int i = 0; i < assets.total; i++ ) {
1021                 AssetPicon *picon = (AssetPicon*)assets.values[i];
1022                 picon->in_use = 0;
1023         }
1024
1025 // Synchronize EDL clips
1026         for( int i = 0; i < mwindow->edl->clips.total; i++ ) {
1027                 int exists = 0;
1028
1029 // Look for clip in existing listitems
1030                 for( int j = 0; j < assets.total && !exists; j++ ) {
1031                         AssetPicon *picon = (AssetPicon*)assets.values[j];
1032
1033                         if( picon->id == mwindow->edl->clips.values[i]->id ) {
1034                                 picon->edl = mwindow->edl->clips.values[i];
1035                                 picon->set_text(mwindow->edl->clips.values[i]->local_session->clip_title);
1036                                 exists = 1;
1037                                 picon->in_use = 1;
1038                         }
1039                 }
1040
1041 // Create new listitem
1042                 if( !exists ) {
1043                         AssetPicon *picon = new AssetPicon(mwindow,
1044                                 this, mwindow->edl->clips.values[i]);
1045                         picon->create_objects();
1046                         assets.append(picon);
1047                 }
1048         }
1049
1050 // Synchronize EDL assets
1051         for( Asset *current = mwindow->edl->assets->first;
1052                 current;
1053                 current = NEXT ) {
1054                 int exists = 0;
1055
1056 // Look for asset in existing listitems
1057                 for( int j = 0; j < assets.total && !exists; j++ ) {
1058                         AssetPicon *picon = (AssetPicon*)assets.values[j];
1059
1060                         if( picon->id == current->id ) {
1061                                 picon->indexable = current;
1062                                 exists = 1;
1063                                 picon->in_use = 1;
1064                                 break;
1065                         }
1066                 }
1067
1068 // Create new listitem
1069                 if( !exists ) {
1070                         AssetPicon *picon = new AssetPicon(mwindow,
1071                                 this, current);
1072                         picon->create_objects();
1073                         assets.append(picon);
1074                 }
1075         }
1076
1077         mwindow->gui->lock_window("AWindowGUI::update_asset_list");
1078         mwindow->gui->default_message();
1079         mwindow->gui->unlock_window();
1080
1081 // Synchronize nested EDLs
1082         for( int i = 0; i < mwindow->edl->nested_edls->size(); i++ ) {
1083                 int exists = 0;
1084                 Indexable *indexable = mwindow->edl->nested_edls->get(i);
1085
1086 // Look for asset in existing listitems
1087                 for( int j = 0; j < assets.total && !exists; j++ ) {
1088                         AssetPicon *picon = (AssetPicon*)assets.values[j];
1089
1090                         if( picon->id == indexable->id ) {
1091                                 picon->indexable = indexable;
1092                                 exists = 1;
1093                                 picon->in_use = 1;
1094                                 break;
1095                         }
1096                 }
1097
1098 // Create new listitem
1099                 if( !exists ) {
1100                         AssetPicon *picon = new AssetPicon(mwindow,
1101                                 this, indexable);
1102                         picon->create_objects();
1103                         assets.append(picon);
1104                 }
1105         }
1106
1107         for( int i = assets.size() - 1; i >= 0; i-- ) {
1108                 AssetPicon *picon = (AssetPicon*)assets.get(i);
1109                 if( !picon->in_use ) {
1110                         delete picon;
1111                         assets.remove_number(i);
1112                 }
1113         }
1114 }
1115
1116 void AWindowGUI::update_picon(Indexable *indexable)
1117 {
1118         VIcon *vicon = 0;
1119         for( int i = 0; i < assets.total; i++ ) {
1120                 AssetPicon *picon = (AssetPicon*)assets.values[i];
1121                 if( picon->indexable == indexable ||
1122                     picon->edl == (EDL *)indexable ) {
1123                         char name[BCTEXTLEN];
1124                         FileSystem fs;
1125                         fs.extract_name(name, indexable->path);
1126                         picon->set_text(name);
1127                         vicon = picon->vicon;
1128                         break;
1129                 }
1130         }
1131         if( vicon ) {
1132                 stop_vicon_drawing();
1133                 vicon->clear_images();
1134                 vicon->reset(indexable->get_frame_rate());
1135                 start_vicon_drawing();
1136         }
1137 }
1138
1139 void AWindowGUI::sort_assets()
1140 {
1141         switch( mwindow->edl->session->awindow_folder ) {
1142         case AW_AEFFECT_FOLDER:
1143                 sort_picons(&aeffects);
1144                 break;
1145         case AW_VEFFECT_FOLDER:
1146                 sort_picons(&veffects);
1147                 break;
1148         case AW_ATRANSITION_FOLDER:
1149                 sort_picons(&atransitions);
1150                 break;
1151         case AW_VTRANSITION_FOLDER:
1152                 sort_picons(&vtransitions);
1153                 break;
1154         case AW_LABEL_FOLDER:
1155                 sort_picons(&labellist);
1156                 break;
1157         default:
1158                 sort_picons(&assets);
1159         }
1160 // reset xyposition
1161         asset_list->update_format(asset_list->get_format(), 0);
1162         update_assets();
1163 }
1164
1165 void AWindowGUI::sort_folders()
1166 {
1167         sort_picons(&folders);
1168         folder_list->update_format(folder_list->get_format(), 0);
1169         update_assets();
1170 }
1171
1172 void AWindowGUI::collect_assets()
1173 {
1174         int i = 0;
1175         mwindow->session->drag_assets->remove_all();
1176         mwindow->session->drag_clips->remove_all();
1177         while(1)
1178         {
1179                 AssetPicon *result = (AssetPicon*)asset_list->get_selection(0, i++);
1180                 if( !result ) break;
1181
1182                 if( result->indexable ) mwindow->session->drag_assets->append(result->indexable);
1183                 if( result->edl ) mwindow->session->drag_clips->append(result->edl);
1184         }
1185 }
1186
1187 void AWindowGUI::copy_picons(ArrayList<BC_ListBoxItem*> *dst,
1188         ArrayList<BC_ListBoxItem*> *src, int folder)
1189 {
1190 // Remove current pointers
1191         dst[0].remove_all();
1192         dst[1].remove_all_objects();
1193
1194 // Create new pointers
1195         for( int i = 0; i < src->total; i++ ) {
1196                 AssetPicon *picon = (AssetPicon*)src->values[i];
1197                 if( folder < 0 ||
1198                     (picon->indexable && picon->indexable->awindow_folder == folder) ||
1199                     (picon->edl && picon->edl->local_session->awindow_folder == folder) ) {
1200                         const char *text = search_text->get_text();
1201                         if( text && text[0] && !strstr(picon->get_text(), text) ) 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         update_folder_list();
1283         update_asset_list();
1284         labellist.remove_all_objects();
1285         create_label_folder();
1286         filter_displayed_assets();
1287
1288         if( mwindow->edl->session->folderlist_format != folder_list->get_format() ) {
1289                 folder_list->update_format(mwindow->edl->session->folderlist_format, 0);
1290         }
1291         int folder_xposition = folder_list->get_xposition();
1292         int folder_yposition = folder_list->get_yposition();
1293         folder_list->update(&folders, 0, 0, 1, folder_xposition, folder_yposition, -1);
1294
1295         if( mwindow->edl->session->assetlist_format != asset_list->get_format() ) {
1296                 asset_list->update_format(mwindow->edl->session->assetlist_format, 0);
1297         }
1298         int asset_xposition = asset_list->get_xposition();
1299         int asset_yposition = asset_list->get_yposition();
1300         if( displayed_folder != mwindow->edl->session->awindow_folder ) {
1301                 displayed_folder = mwindow->edl->session->awindow_folder;
1302                 asset_xposition = asset_yposition = 0;
1303         }
1304         asset_list->update(displayed_assets, asset_titles,
1305                 mwindow->edl->session->asset_columns, ASSET_COLUMNS,
1306                 asset_xposition, asset_yposition, -1, 0);
1307         asset_list->center_selection();
1308
1309         flush();
1310         return;
1311 }
1312
1313 void AWindowGUI::update_effects()
1314 {
1315         aeffects.remove_all_objects();
1316         create_persistent_folder(&aeffects, 1, 0, 1, 0);
1317         veffects.remove_all_objects();
1318         create_persistent_folder(&veffects, 0, 1, 1, 0);
1319         atransitions.remove_all_objects();
1320         create_persistent_folder(&atransitions, 1, 0, 0, 1);
1321         vtransitions.remove_all_objects();
1322         create_persistent_folder(&vtransitions, 0, 1, 0, 1);
1323 }
1324
1325 int AWindowGUI::folder_number(const char *name)
1326 {
1327         for( int i = 0; i < AWINDOW_FOLDERS; i++ ) {
1328                 if( !strcasecmp(name, folder_names[i]) ) return i;
1329         }
1330         return AW_NO_FOLDER;
1331 }
1332
1333 int AWindowGUI::drag_motion()
1334 {
1335         if( get_hidden() ) return 0;
1336
1337         int result = 0;
1338         return result;
1339 }
1340
1341 int AWindowGUI::drag_stop()
1342 {
1343         if( get_hidden() ) return 0;
1344
1345         return 0;
1346 }
1347
1348 Indexable* AWindowGUI::selected_asset()
1349 {
1350         AssetPicon *picon = (AssetPicon*)asset_list->get_selection(0, 0);
1351         return picon ? picon->indexable : 0;
1352 }
1353
1354 PluginServer* AWindowGUI::selected_plugin()
1355 {
1356         AssetPicon *picon = (AssetPicon*)asset_list->get_selection(0, 0);
1357         return picon ? picon->plugin : 0;
1358 }
1359
1360 AssetPicon* AWindowGUI::selected_folder()
1361 {
1362         AssetPicon *picon = (AssetPicon*)folder_list->get_selection(0, 0);
1363         return picon;
1364 }
1365
1366
1367
1368
1369
1370
1371
1372
1373 AWindowDivider::AWindowDivider(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1374  : BC_SubWindow(x, y, w, h)
1375 {
1376         this->mwindow = mwindow;
1377         this->gui = gui;
1378 }
1379 AWindowDivider::~AWindowDivider()
1380 {
1381 }
1382
1383 int AWindowDivider::button_press_event()
1384 {
1385         if( is_event_win() && cursor_inside() ) {
1386                 mwindow->session->current_operation = DRAG_PARTITION;
1387                 return 1;
1388         }
1389         return 0;
1390 }
1391
1392 int AWindowDivider::cursor_motion_event()
1393 {
1394         if( mwindow->session->current_operation == DRAG_PARTITION ) {
1395                 int wmin = 25;
1396                 int wmax = mwindow->session->awindow_w - mwindow->theme->adivider_w - wmin;
1397                 int fw = gui->get_relative_cursor_x();
1398                 if( fw > wmax ) fw = wmax;
1399                 if( fw < wmin ) fw = wmin;
1400                 mwindow->session->afolders_w = fw;
1401                 mwindow->theme->get_awindow_sizes(gui);
1402                 gui->reposition_objects();
1403                 gui->flush();
1404         }
1405         return 0;
1406 }
1407
1408 int AWindowDivider::button_release_event()
1409 {
1410         if( mwindow->session->current_operation == DRAG_PARTITION ) {
1411                 mwindow->session->current_operation = NO_OPERATION;
1412                 return 1;
1413         }
1414         return 0;
1415 }
1416
1417
1418
1419
1420
1421
1422 AWindowFolders::AWindowFolders(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1423  : BC_ListBox(x, y, w, h,
1424                 mwindow->edl->session->folderlist_format == ASSETS_ICONS ?
1425                         LISTBOX_ICONS : LISTBOX_TEXT,
1426                 &gui->folders,    // Each column has an ArrayList of BC_ListBoxItems.
1427                 0,                // Titles for columns.  Set to 0 for no titles
1428                 0,                // width of each column
1429                 1,                // Total columns.
1430                 0,                // Pixel of top of window.
1431                 0,                // If this listbox is a popup window
1432                 LISTBOX_SINGLE,   // Select one item or multiple items
1433                 ICON_TOP,         // Position of icon relative to text of each item
1434                 1)                // Allow drags
1435 {
1436         this->mwindow = mwindow;
1437         this->gui = gui;
1438         set_drag_scroll(0);
1439 }
1440
1441 AWindowFolders::~AWindowFolders()
1442 {
1443 }
1444
1445 int AWindowFolders::selection_changed()
1446 {
1447         AssetPicon *picon = (AssetPicon*)get_selection(0, 0);
1448         if( picon ) {
1449                 gui->stop_vicon_drawing();
1450
1451                 if( get_button_down() && get_buttonpress() == 3 ) {
1452                         gui->folderlist_menu->update_titles();
1453                         gui->folderlist_menu->activate_menu();
1454                 }
1455
1456                 mwindow->edl->session->awindow_folder = picon->foldernum;
1457                 gui->asset_list->draw_background();
1458                 gui->async_update_assets();
1459
1460                 gui->start_vicon_drawing();
1461         }
1462         return 1;
1463 }
1464
1465 int AWindowFolders::button_press_event()
1466 {
1467         int result = 0;
1468
1469         result = BC_ListBox::button_press_event();
1470
1471         if( !result ) {
1472                 if( get_buttonpress() == 3 && is_event_win() && cursor_inside() ) {
1473                         gui->folderlist_menu->update_titles();
1474                         gui->folderlist_menu->activate_menu();
1475                         result = 1;
1476                 }
1477         }
1478
1479
1480         return result;
1481 }
1482
1483
1484
1485
1486
1487
1488
1489 AWindowAssets::AWindowAssets(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1490  : BC_ListBox(x, y, w, h,
1491                 (mwindow->edl->session->assetlist_format == ASSETS_ICONS && gui->allow_iconlisting ) ?
1492                         LISTBOX_ICONS : LISTBOX_TEXT,
1493                 &gui->assets,     // Each column has an ArrayList of BC_ListBoxItems.
1494                 gui->asset_titles,// Titles for columns.  Set to 0 for no titles
1495                 mwindow->edl->session->asset_columns, // width of each column
1496                 1,                // Total columns.
1497                 0,                // Pixel of top of window.
1498                 0,                // If this listbox is a popup window
1499                 LISTBOX_MULTIPLE, // Select one item or multiple items
1500                 ICON_TOP,         // Position of icon relative to text of each item
1501                 -1)               // Allow drags, require shift for scrolling
1502 {
1503         this->mwindow = mwindow;
1504         this->gui = gui;
1505         set_drag_scroll(0);
1506         set_scroll_stretch(1, 1);
1507 }
1508
1509 AWindowAssets::~AWindowAssets()
1510 {
1511 }
1512
1513 int AWindowAssets::button_press_event()
1514 {
1515         int result = 0;
1516
1517         result = BC_ListBox::button_press_event();
1518
1519         if( !result && get_buttonpress() == 3 && is_event_win() && cursor_inside() ) {
1520                 BC_ListBox::deactivate_selection();
1521                 int folder = mwindow->edl->session->awindow_folder;
1522                 switch( folder ) {
1523                 case AW_AEFFECT_FOLDER:
1524                 case AW_VEFFECT_FOLDER:
1525                 case AW_ATRANSITION_FOLDER:
1526                 case AW_VTRANSITION_FOLDER:
1527                         gui->effectlist_menu->update();
1528                         gui->effectlist_menu->activate_menu();
1529                         break;
1530                 case AW_LABEL_FOLDER:
1531                         gui->labellist_menu->update();
1532                         gui->labellist_menu->activate_menu();
1533                         break;
1534                 case AW_CLIP_FOLDER:
1535                         gui->cliplist_menu->update();
1536                         gui->cliplist_menu->activate_menu();
1537                         break;
1538                 case AW_MEDIA_FOLDER:
1539                 case AW_PROXY_FOLDER:
1540                         gui->assetlist_menu->update_titles();
1541                         gui->assetlist_menu->activate_menu();
1542                         break;
1543                 }
1544                 result = 1;
1545         }
1546
1547         return result;
1548 }
1549
1550
1551 int AWindowAssets::handle_event()
1552 {
1553         AssetPicon *asset_picon = (AssetPicon *)get_selection(0, 0);
1554         if( !asset_picon ) return 0;
1555         switch( mwindow->edl->session->awindow_folder ) {
1556         case AW_AEFFECT_FOLDER:
1557         case AW_VEFFECT_FOLDER:
1558         case AW_ATRANSITION_FOLDER:
1559         case AW_VTRANSITION_FOLDER: return 1;
1560         }
1561         VWindow *vwindow = mwindow->vwindows.size() > DEFAULT_VWINDOW ?
1562                 mwindow->vwindows.get(DEFAULT_VWINDOW) : 0;
1563         if( !vwindow || !vwindow->is_running() ) return 1;
1564
1565         vwindow->gui->lock_window("AWindowAssets::handle_event");
1566         if( asset_picon->indexable )
1567                 vwindow->change_source(asset_picon->indexable);
1568         else if( asset_picon->edl )
1569                 vwindow->change_source(asset_picon->edl);
1570         vwindow->gui->unlock_window();
1571         return 1;
1572 }
1573
1574 int AWindowAssets::selection_changed()
1575 {
1576 // Show popup window
1577         AssetPicon *item;
1578         if( get_button_down() && get_buttonpress() == 3 &&
1579             (item = (AssetPicon*)get_selection(0, 0)) ) {
1580                 int folder = mwindow->edl->session->awindow_folder;
1581                 switch( folder ) {
1582                 case AW_AEFFECT_FOLDER:
1583                 case AW_VEFFECT_FOLDER:
1584                 case AW_ATRANSITION_FOLDER:
1585                 case AW_VTRANSITION_FOLDER:
1586                         gui->effectlist_menu->update();
1587                         gui->effectlist_menu->activate_menu();
1588                         break;
1589                 case AW_LABEL_FOLDER:
1590                         if( !item->label ) break;
1591                         gui->label_menu->activate_menu();
1592                         break;
1593                 case AW_CLIP_FOLDER:
1594                         if( !item->indexable && !item->edl ) break;
1595                         gui->clip_menu->update();
1596                         gui->clip_menu->activate_menu();
1597                         break;
1598                 default:
1599                         if( !item->indexable && !item->edl ) break;
1600                         gui->asset_menu->update();
1601                         gui->asset_menu->activate_menu();
1602                         break;
1603                 }
1604
1605                 BC_ListBox::deactivate_selection();
1606                 return 1;
1607         }
1608         else if( get_button_down() && get_buttonpress() == 1 &&
1609                  (item = (AssetPicon*)get_selection(0, 0)) ) {
1610                 VIcon *vicon = 0;
1611                 if( !gui->vicon_thread->viewing ) {
1612                         vicon = item->vicon;
1613                 }
1614                 gui->vicon_thread->set_view_popup(vicon);
1615
1616         }
1617         return 0;
1618 }
1619
1620 void AWindowAssets::draw_background()
1621 {
1622         clear_box(0,0,get_w(),get_h(),get_bg_surface());
1623         set_color(BC_WindowBase::get_resources()->audiovideo_color);
1624         set_font(LARGEFONT);
1625         int aw_folder = mwindow->edl->session->awindow_folder;
1626         if( aw_folder < 0 ) return;
1627         const char *aw_name = _(AWindowGUI::folder_names[aw_folder]);
1628         draw_text(get_w() - get_text_width(LARGEFONT, aw_name) - 4, 30,
1629                 aw_name, -1, get_bg_surface());
1630 }
1631
1632 int AWindowAssets::drag_start_event()
1633 {
1634         int collect_pluginservers = 0;
1635         int collect_assets = 0;
1636
1637         if( BC_ListBox::drag_start_event() ) {
1638                 switch( mwindow->edl->session->awindow_folder ) {
1639                 case AW_AEFFECT_FOLDER:
1640                         mwindow->session->current_operation = DRAG_AEFFECT;
1641                         collect_pluginservers = 1;
1642                         break;
1643                 case AW_VEFFECT_FOLDER:
1644                         mwindow->session->current_operation = DRAG_VEFFECT;
1645                         collect_pluginservers = 1;
1646                         break;
1647                 case AW_ATRANSITION_FOLDER:
1648                         mwindow->session->current_operation = DRAG_ATRANSITION;
1649                         collect_pluginservers = 1;
1650                         break;
1651                 case AW_VTRANSITION_FOLDER:
1652                         mwindow->session->current_operation = DRAG_VTRANSITION;
1653                         collect_pluginservers = 1;
1654                         break;
1655                 case AW_LABEL_FOLDER:
1656                         // do nothing!
1657                         break;
1658                 default:
1659                         mwindow->session->current_operation = DRAG_ASSET;
1660                         collect_assets = 1;
1661                         break;
1662                 }
1663
1664                 if( collect_pluginservers ) {
1665                         int i = 0;
1666                         mwindow->session->drag_pluginservers->remove_all();
1667                         while(1)
1668                         {
1669                                 AssetPicon *result = (AssetPicon*)get_selection(0, i++);
1670                                 if( !result ) break;
1671
1672                                 mwindow->session->drag_pluginservers->append(result->plugin);
1673                         }
1674                 }
1675
1676                 if( collect_assets ) {
1677                         gui->collect_assets();
1678                 }
1679
1680                 return 1;
1681         }
1682         return 0;
1683 }
1684
1685 int AWindowAssets::drag_motion_event()
1686 {
1687         BC_ListBox::drag_motion_event();
1688         unlock_window();
1689
1690         mwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1691         mwindow->gui->drag_motion();
1692         mwindow->gui->unlock_window();
1693
1694         for( int i = 0; i < mwindow->vwindows.size(); i++ ) {
1695                 VWindow *vwindow = mwindow->vwindows.get(i);
1696                 if( !vwindow->is_running() ) continue;
1697                 vwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1698                 vwindow->gui->drag_motion();
1699                 vwindow->gui->unlock_window();
1700         }
1701
1702         mwindow->cwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1703         mwindow->cwindow->gui->drag_motion();
1704         mwindow->cwindow->gui->unlock_window();
1705
1706         lock_window("AWindowAssets::drag_motion_event");
1707         return 0;
1708 }
1709
1710 int AWindowAssets::drag_stop_event()
1711 {
1712         int result = 0;
1713
1714         result = gui->drag_stop();
1715
1716         unlock_window();
1717
1718         if( !result ) {
1719                 mwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1720                 result = mwindow->gui->drag_stop();
1721                 mwindow->gui->unlock_window();
1722         }
1723
1724         if( !result ) {
1725                 for( int i = 0; !result && i < mwindow->vwindows.size(); i++ ) {
1726                         VWindow *vwindow = mwindow->vwindows.get(i);
1727                         if( !vwindow ) continue;
1728                         if( !vwindow->is_running() ) continue;
1729                         if( vwindow->gui->is_hidden() ) continue;
1730                         vwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1731                         if( vwindow->gui->cursor_above() &&
1732                             vwindow->gui->get_cursor_over_window() ) {
1733                                 result = vwindow->gui->drag_stop();
1734                         }
1735                         vwindow->gui->unlock_window();
1736                 }
1737         }
1738
1739         if( !result ) {
1740                 mwindow->cwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1741                 result = mwindow->cwindow->gui->drag_stop();
1742                 mwindow->cwindow->gui->unlock_window();
1743         }
1744
1745         lock_window("AWindowAssets::drag_stop_event");
1746
1747         if( result ) get_drag_popup()->set_animation(0);
1748
1749         BC_ListBox::drag_stop_event();
1750         mwindow->session->current_operation = ::NO_OPERATION; // since NO_OPERATION is also defined in listbox, we have to reach for global scope...
1751         return 0;
1752 }
1753
1754 int AWindowAssets::column_resize_event()
1755 {
1756         mwindow->edl->session->asset_columns[0] = get_column_width(0);
1757         mwindow->edl->session->asset_columns[1] = get_column_width(1);
1758         return 1;
1759 }
1760
1761 int AWindowAssets::focus_in_event()
1762 {
1763         gui->start_vicon_drawing();
1764         return 0;
1765 }
1766
1767 int AWindowAssets::focus_out_event()
1768 {
1769         gui->stop_vicon_drawing();
1770         return BC_ListBox::focus_out_event();
1771 }
1772
1773 AWindowSearchTextBox::AWindowSearchTextBox(AWindowSearchText *search_text, int x, int y, int w)
1774  : BC_TextBox(x, y, w, 1, "")
1775 {
1776         this->search_text = search_text;
1777 }
1778
1779 int AWindowSearchTextBox::handle_event()
1780 {
1781         return search_text->handle_event();
1782 }
1783
1784 AWindowSearchText::AWindowSearchText(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1785 {
1786         this->mwindow = mwindow;
1787         this->gui = gui;
1788         this->x = x;
1789         this->y = y;
1790 }
1791
1792 void AWindowSearchText::create_objects()
1793 {
1794         int x1 = x, y1 = y, margin = 10;
1795         gui->add_subwindow(text_title = new BC_Title(x1, y1, _("Search:")));
1796         x1 += text_title->get_w() + margin;
1797         int w1 = gui->get_w() - x1 - 2*margin;
1798         gui->add_subwindow(text_box = new AWindowSearchTextBox(this, x1, y1, w1));
1799 }
1800
1801 int AWindowSearchText::handle_event()
1802 {
1803         gui->async_update_assets();
1804         return 1;
1805 }
1806
1807 int AWindowSearchText::get_w()
1808 {
1809         return text_box->get_w() + text_title->get_w() + 10;
1810 }
1811
1812 int AWindowSearchText::get_h()
1813 {
1814         return bmax(text_box->get_h(),text_title->get_h());
1815 }
1816
1817 void AWindowSearchText::reposition_window(int x, int y, int w)
1818 {
1819         int x1 = x, y1 = y, margin = 10;
1820         text_title->reposition_window(x1, y1);
1821         x1 += text_title->get_w() + margin;
1822         int w1 = gui->get_w() - x1 - 2*margin;
1823         text_box->reposition_window(x1, y1, w1);
1824 }
1825
1826 const char *AWindowSearchText::get_text()
1827 {
1828         return text_box->get_text();
1829 }
1830
1831 AWindowNewFolder::AWindowNewFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1832  : BC_Button(x, y, mwindow->theme->newbin_data)
1833 {
1834         this->mwindow = mwindow;
1835         this->gui = gui;
1836         set_tooltip(_("New bin"));
1837 }
1838
1839 int AWindowNewFolder::handle_event()
1840 {
1841         gui->newfolder_thread->start_new_folder();
1842         return 1;
1843 }
1844
1845 AWindowDeleteFolder::AWindowDeleteFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1846  : BC_Button(x, y, mwindow->theme->deletebin_data)
1847 {
1848         this->mwindow = mwindow;
1849         this->gui = gui;
1850         set_tooltip(_("Delete bin"));
1851 }
1852
1853 int AWindowDeleteFolder::handle_event()
1854 {
1855         if( gui->folder_list->get_selection(0, 0) ) {
1856                 BC_ListBoxItem *folder = gui->folder_list->get_selection(0, 0);
1857                 mwindow->delete_folder(folder->get_text());
1858         }
1859         return 1;
1860 }
1861
1862 AWindowRenameFolder::AWindowRenameFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1863  : BC_Button(x, y, mwindow->theme->renamebin_data)
1864 {
1865         this->mwindow = mwindow;
1866         this->gui = gui;
1867         set_tooltip(_("Rename bin"));
1868 }
1869
1870 int AWindowRenameFolder::handle_event()
1871 {
1872         return 1;
1873 }
1874
1875 AWindowDeleteDisk::AWindowDeleteDisk(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1876  : BC_Button(x, y, mwindow->theme->deletedisk_data)
1877 {
1878         this->mwindow = mwindow;
1879         this->gui = gui;
1880         set_tooltip(_("Delete asset from disk"));
1881 }
1882
1883 int AWindowDeleteDisk::handle_event()
1884 {
1885         return 1;
1886 }
1887
1888 AWindowDeleteProject::AWindowDeleteProject(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1889  : BC_Button(x, y, mwindow->theme->deleteproject_data)
1890 {
1891         this->mwindow = mwindow;
1892         this->gui = gui;
1893         set_tooltip(_("Delete asset from project"));
1894 }
1895
1896 int AWindowDeleteProject::handle_event()
1897 {
1898         return 1;
1899 }
1900
1901 // AWindowInfo::AWindowInfo(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1902 //  : BC_Button(x, y, mwindow->theme->infoasset_data)
1903 // {
1904 //      this->mwindow = mwindow;
1905 //      this->gui = gui;
1906 //      set_tooltip(_("Edit information on asset"));
1907 // }
1908 // 
1909 // int AWindowInfo::handle_event()
1910 // {
1911 //      int cur_x, cur_y;
1912 //      gui->get_abs_cursor(cur_x, cur_y, 0);
1913 //      gui->awindow->asset_edit->edit_asset(gui->selected_asset(), cur_x, cur_y);
1914 //      return 1;
1915 // }
1916
1917 AWindowRedrawIndex::AWindowRedrawIndex(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1918  : BC_Button(x, y, mwindow->theme->redrawindex_data)
1919 {
1920         this->mwindow = mwindow;
1921         this->gui = gui;
1922         set_tooltip(_("Redraw index"));
1923 }
1924
1925 int AWindowRedrawIndex::handle_event()
1926 {
1927         return 1;
1928 }
1929
1930 AWindowPaste::AWindowPaste(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1931  : BC_Button(x, y, mwindow->theme->pasteasset_data)
1932 {
1933         this->mwindow = mwindow;
1934         this->gui = gui;
1935         set_tooltip(_("Paste asset on recordable tracks"));
1936 }
1937
1938 int AWindowPaste::handle_event()
1939 {
1940         return 1;
1941 }
1942
1943 AWindowAppend::AWindowAppend(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1944  : BC_Button(x, y, mwindow->theme->appendasset_data)
1945 {
1946         this->mwindow = mwindow;
1947         this->gui = gui;
1948         set_tooltip(_("Append asset in new tracks"));
1949 }
1950
1951 int AWindowAppend::handle_event()
1952 {
1953         return 1;
1954 }
1955
1956 AWindowView::AWindowView(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1957  : BC_Button(x, y, mwindow->theme->viewasset_data)
1958 {
1959         this->mwindow = mwindow;
1960         this->gui = gui;
1961         set_tooltip(_("View asset"));
1962 }
1963
1964 int AWindowView::handle_event()
1965 {
1966         return 1;
1967 }
1968
1969 AddTools::AddTools(MWindow *mwindow, AWindowGUI *gui, int x, int y, const char *title)
1970  : BC_PopupMenu(x, y, BC_Title::calculate_w(gui, title, MEDIUMFONT)+8, title, -1, 0, 4)
1971 {
1972         this->mwindow = mwindow;
1973         this->gui = gui;
1974 }
1975
1976 void AddTools::create_objects()
1977 {
1978         uint64_t vis = 0;
1979         add_item(new AddPluginItem(this, "ladspa", PLUGIN_LADSPA_ID));
1980         vis |= 1 << PLUGIN_LADSPA_ID;
1981         add_item(new AddPluginItem(this, "ffmpeg", PLUGIN_FFMPEG_ID));
1982         vis |= 1 << PLUGIN_FFMPEG_ID;
1983         for( int i=0; i<MWindow::plugindb->size(); ++i ) {
1984                 PluginServer *plugin = MWindow::plugindb->get(i);
1985                 if( !plugin->audio && !plugin->video ) continue;
1986                 int idx = plugin->dir_idx;
1987                 uint32_t msk = 1 << idx;
1988                 if( (msk & vis) != 0 ) continue;
1989                 vis |= msk;
1990                 char parent[BCTEXTLEN];
1991                 strcpy(parent, plugin->path);
1992                 char *bp = strrchr(parent, '/');
1993                 if( bp ) { *bp = 0;  bp = strrchr(parent, '/'); }
1994                 if( !bp ) bp = parent; else ++bp;
1995                 add_item(new AddPluginItem(this, bp, idx));
1996         }
1997 }
1998
1999 #if 0
2000 // plugin_dirs list from toplevel makefile include plugin_defs
2001 N_("ladspa")
2002 N_("ffmpeg")
2003 N_("audio_tools")
2004 N_("audio_transitions")
2005 N_("blending")
2006 N_("colors")
2007 N_("exotic")
2008 N_("transforms")
2009 N_("tv_effects")
2010 N_("video_tools")
2011 N_("video_transitions")
2012 #endif
2013
2014 AddPluginItem::AddPluginItem(AddTools *menu, char const *text, int idx)
2015  : BC_MenuItem(_(text))
2016 {
2017         this->menu = menu;
2018         this->idx = idx;
2019         uint64_t msk = (uint64_t)1 << idx, vis = menu->gui->plugin_visibility;
2020         int chk = (msk & vis) ? 1 : 0;
2021         set_checked(chk);
2022 }
2023
2024 int AddPluginItem::handle_event()
2025 {
2026         int chk = get_checked() ^ 1;
2027         set_checked(chk);
2028         uint64_t msk = (uint64_t)1 << idx, vis = menu->gui->plugin_visibility;
2029         menu->gui->plugin_visibility = chk ? vis | msk : vis & ~msk;
2030         menu->gui->update_effects();
2031         menu->gui->save_defaults(menu->mwindow->defaults);
2032         menu->gui->async_update_assets();
2033         return 1;
2034 }
2035
2036 AVIconDrawing::AVIconDrawing(AWindowGUI *agui, int x, int y, VFrame **images)
2037  : BC_Toggle(x, y, images, agui->vicon_drawing)
2038 {
2039         this->agui = agui;
2040         set_tooltip(_("draw vicons"));
2041 }
2042
2043 void AVIconDrawing::calculate_geometry(AWindowGUI *agui, VFrame **images, int *ww, int *hh)
2044 {
2045         int text_line = -1, toggle_x = -1, toggle_y = -1;
2046         int text_x = -1, text_y = -1, text_w = -1, text_h = -1;
2047         BC_Toggle::calculate_extents(agui, images, 1,
2048                 &text_line, ww, hh, &toggle_x, &toggle_y,
2049                 &text_x, &text_y, &text_w, &text_h, "", MEDIUMFONT);
2050 }
2051
2052 AVIconDrawing::~AVIconDrawing()
2053 {
2054 }
2055
2056 int AVIconDrawing::handle_event()
2057 {
2058         agui->vicon_drawing = get_value();
2059         if( agui->vicon_drawing )
2060                 agui->start_vicon_drawing();
2061         else
2062                 agui->stop_vicon_drawing();
2063         return 1;
2064 }
2065
2066
2067 AWindowListFormat::AWindowListFormat(MWindow *mwindow, AWindowGUI *gui)
2068  : BC_MenuItem("")
2069 {
2070         this->mwindow = mwindow;
2071         this->gui = gui;
2072 }
2073
2074 int AWindowListFormat::handle_event()
2075 {
2076         gui->stop_vicon_drawing();
2077
2078         EDLSession *session = mwindow->edl->session;
2079         switch( session->assetlist_format ) {
2080         case ASSETS_TEXT:
2081                 session->assetlist_format = ASSETS_ICONS;
2082                 break;
2083         case ASSETS_ICONS:
2084                 session->assetlist_format = ASSETS_TEXT;
2085                 break;
2086         }
2087
2088         gui->asset_list->update_format(session->assetlist_format, 1);
2089         if( !mwindow->awindow->gui->allow_iconlisting ) {
2090                 mwindow->edl->session->assetlist_format = ASSETS_TEXT;
2091         }
2092
2093         gui->start_vicon_drawing();
2094         return 1;
2095 }
2096
2097 void AWindowListFormat::update()
2098 {
2099         set_text(mwindow->edl->session->assetlist_format == ASSETS_TEXT ?
2100                 (char*)_("Display icons") : (char*)_("Display text"));
2101 }
2102
2103 AWindowListSort::AWindowListSort(MWindow *mwindow, AWindowGUI *gui)
2104  : BC_MenuItem(_("Sort items"))
2105 {
2106         this->mwindow = mwindow;
2107         this->gui = gui;
2108 }
2109
2110 int AWindowListSort::handle_event()
2111 {
2112         gui->sort_assets();
2113         return 1;
2114 }
2115