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