initial commit
[goodguy/history.git] / cinelerra-5.0 / cinelerra / assetedit.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2010 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 "awindow.h"
25 #include "awindowgui.h"
26 #include "bcprogressbox.h"
27 #include "bcsignals.h"
28 #include "bitspopup.h"
29 #include "cache.h"
30 #include "clip.h"
31 #include "cplayback.h"
32 #include "cwindow.h"
33 #include "edl.h"
34 #include "edlsession.h"
35 #include "file.h"
36 #include "filempeg.h"
37 #include "fileffmpeg.h"
38 #include "filesystem.h"
39 #include "format.inc"
40 #include "indexable.h"
41 #include "indexfile.h"
42 #include "indexstate.h"
43 #include "language.h"
44 #include "mainindexes.h"
45 #include "mwindow.h"
46 #include "mwindowgui.h"
47 #include "new.h"
48 #include "preferences.h"
49 #include "resizetrackthread.h"
50 #include "removefile.h"
51 #include "theme.h"
52 #include "transportque.h"
53
54 #include <string.h>
55
56
57
58 AssetEdit::AssetEdit(MWindow *mwindow)
59  : BC_DialogThread()
60 {
61         this->mwindow = mwindow;
62         indexable = 0;
63         window = 0;
64         changed_params = new Asset;
65         //set_synchronous(0);
66 }
67
68
69 AssetEdit::~AssetEdit()
70 {
71         changed_params->remove_user();
72 }
73
74
75 void AssetEdit::edit_asset(Indexable *indexable)
76 {
77         if(this->indexable)
78         {
79                 BC_DialogThread::close_window();
80         }
81
82         this->indexable = indexable;
83         this->indexable->add_user();
84
85 // Copy asset parameters into temporary storage for editing.
86         if(indexable->is_asset)
87         {
88                 changed_params->copy_from((Asset*)indexable, 0);
89         }
90         else
91         {
92                 EDL *nested_edl = (EDL*)indexable;
93
94         strcpy(changed_params->path, nested_edl->path);
95                 changed_params->sample_rate = nested_edl->session->sample_rate;
96         changed_params->channels = nested_edl->session->audio_channels;
97
98 //printf("AssetEdit::edit_asset %d %f\n", __LINE__, nested_edl->session->frame_rate);
99                 changed_params->frame_rate = nested_edl->session->frame_rate;
100         changed_params->width = nested_edl->session->output_w;
101         changed_params->height = nested_edl->session->output_h;
102         }
103
104         BC_DialogThread::start();
105 }
106
107 void AssetEdit::handle_close_event(int result)
108 {
109         if(!result)
110         {
111                 int changed = 0;
112                 Asset *asset = 0;
113                 EDL *nested_edl = 0;
114
115                 if(indexable->is_asset)
116                 {
117                         asset = (Asset*)indexable;
118                         if(!changed_params->equivalent(*asset, 1, 1))
119                                 changed = 1;
120                 }
121                 else
122                 {
123                         nested_edl = (EDL*)indexable;
124                         if(strcmp(changed_params->path, nested_edl->path) 
125 //                ||
126 //                changed_params->sample_rate != nested_edl->session->sample_rate ||
127 //                              !EQUIV(changed_params->frame_rate, nested_edl->session->frame_rate)
128                 )
129                                 changed = 1;
130                 }
131 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
132
133                 if(changed)
134                 {
135                         mwindow->gui->lock_window();
136 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
137
138 // Omit index status from copy since an index rebuild may have been
139 // happening when new_asset was created but not be happening anymore.
140                         if(asset)
141                         {
142                         mwindow->remove_asset_from_caches(asset);
143 //printf("AssetEdit::handle_close_event %d %f\n", __LINE__, asset->get_frame_rate());
144                                 asset->copy_from(changed_params, 0);
145 //printf("AssetEdit::handle_close_event %d %d %d\n", __LINE__, changed_params->bits, asset->bits);
146                         }
147                         else
148                         {
149                                 strcpy(nested_edl->path, changed_params->path);
150 // Other parameters can't be changed because they're defined in the other EDL
151 //                nested_edl->session->frame_rate = changed_params->frame_rate;
152 //                nested_edl->session->sample_rate = changed_params->sample_rate;
153                         }
154 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
155
156                         mwindow->gui->update(0,
157                                 2,
158                                 0,
159                                 0,
160                                 0, 
161                                 0,
162                                 0);
163 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
164
165 // Start index rebuilding
166                         if( (asset && asset->audio_data) || nested_edl)
167                         {
168                                 char source_filename[BCTEXTLEN];
169                                 char index_filename[BCTEXTLEN];
170                                 IndexFile::get_index_filename(source_filename, 
171                                         mwindow->preferences->index_directory,
172                                         index_filename, 
173                                         indexable->path);
174                                 remove_file(index_filename);
175                                 indexable->index_state->index_status = INDEX_NOTTESTED;
176                                 mwindow->mainindexes->add_next_asset(0, indexable);
177                                 mwindow->mainindexes->start_build();
178                         }
179                         mwindow->gui->unlock_window();
180 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
181
182
183                         mwindow->awindow->gui->lock_window();
184                         mwindow->awindow->gui->update_assets();
185                         mwindow->awindow->gui->unlock_window();
186 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
187
188                         mwindow->restart_brender();
189                         mwindow->sync_parameters(CHANGE_ALL);
190 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
191                 }
192         }
193
194         this->indexable->remove_user();
195         this->indexable = 0;
196 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
197 }
198
199 BC_Window* AssetEdit::new_gui()
200 {
201         window = new AssetEditWindow(mwindow, this);
202         window->create_objects();
203         return window;
204 }
205
206
207
208
209
210
211
212
213
214 AssetEditWindow::AssetEditWindow(MWindow *mwindow, AssetEdit *asset_edit)
215  : BC_Window(PROGRAM_NAME ": Asset Info", 
216         mwindow->gui->get_abs_cursor_x(1) - 400 / 2, 
217         mwindow->gui->get_abs_cursor_y(1) - 500 / 2, 
218         400, 
219         530,
220         400,
221         530,
222         0,
223         0,
224         1)
225 {
226         this->mwindow = mwindow;
227         this->asset_edit = asset_edit;
228         bitspopup = 0;
229         path_text = 0;
230         path_button = 0;
231         hilo = 0;
232         lohi = 0;
233         allow_edits = 0;
234         detail_thread = 0;
235 }
236
237
238
239
240
241 AssetEditWindow::~AssetEditWindow()
242 {
243         lock_window("AssetEditWindow::~AssetEditWindow");
244         if(bitspopup) delete bitspopup;
245         if(detail_thread) delete detail_thread;
246         unlock_window();
247 }
248
249
250
251
252 void AssetEditWindow::create_objects()
253 {
254         int y = 10, x = 10, x1 = 10, x2 = 150;
255         char string[BCTEXTLEN];
256         int vmargin;
257         FileSystem fs;
258         BC_Title *title;
259         Asset *asset = 0;
260         EDL *nested_edl = 0;
261
262         if(asset_edit->indexable->is_asset)
263                 asset = (Asset*)asset_edit->indexable;
264         else
265                 nested_edl = (EDL*)asset_edit->indexable;
266
267         if(asset && asset->format == FILE_PCM)
268                 allow_edits = 1;
269         else
270                 allow_edits = 0;
271
272         lock_window("AssetEditWindow::create_objects");
273         if(allow_edits) 
274                 vmargin = 30;
275         else
276                 vmargin = 20;
277
278         add_subwindow(path_text = new AssetEditPathText(this, y));
279         add_subwindow(path_button = new AssetEditPath(mwindow, 
280                 this, 
281                 path_text, 
282                 y, 
283                 asset_edit->indexable->path, 
284                 PROGRAM_NAME ": Asset path", _("Select a file for this asset:")));
285         y += 30;
286
287         if(asset)
288         {
289                 add_subwindow(new BC_Title(x, y, _("File format:")));
290                 x = x2;
291                 add_subwindow(new BC_Title(x, y, File::formattostr(mwindow->plugindb, 
292                                 asset->format), 
293                         MEDIUMFONT, 
294                         mwindow->theme->assetedit_color));
295                 x = x1;
296                 y += 20;
297
298                 int64_t bytes = fs.get_size(asset->path);
299                 add_subwindow(new BC_Title(x, y, _("Bytes:")));
300                 sprintf(string, "" _LD "", bytes);
301                 Units::punctuate(string);
302         
303
304                 add_subwindow(new BC_Title(x2, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
305                 if(asset->format == FILE_MPEG || asset->format == FILE_FFMPEG)
306                 {
307                         detail_thread = new DetailAssetThread(mwindow);
308                         BC_GenericButton *detail = new DetailAssetButton(this, x2+120, y);
309                         add_subwindow(detail);
310                 }
311
312                 y += 20;
313                 x = x1;
314
315                 double length = 0.;
316                 y += 20;
317                 x = x1;
318
319                 if(asset->audio_length > 0)
320                         length = (double)asset->audio_length / asset->sample_rate;
321                 if(asset->video_length > 0)
322                         length = MAX(length, (double)asset->video_length / asset->frame_rate);
323                 int64_t bitrate;
324                 if(!EQUIV(length, 0))
325                         bitrate = (int64_t)(bytes * 8 / length);
326                 else
327                         bitrate = bytes;
328                 add_subwindow(new BC_Title(x, y, _("Bitrate (bits/sec):")));
329                 sprintf(string, "" _LD "", bitrate);
330
331                 Units::punctuate(string);
332                 add_subwindow(new BC_Title(x2, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
333
334                 y += 30;
335                 x = x1;
336         }
337
338         if((asset && asset->audio_data) || nested_edl)
339         {
340                 add_subwindow(new BC_Bar(x, y, get_w() - x * 2));
341                 y += 5;
342
343                 add_subwindow(new BC_Title(x, y, _("Audio:"), LARGEFONT, RED));
344
345                 y += 30;
346
347                 if(asset)
348                 {
349                         if(asset->get_compression_text(1, 0))
350                         {
351                                 add_subwindow(new BC_Title(x, y, _("Compression:")));
352                                 x = x2;
353                                 add_subwindow(new BC_Title(x, 
354                                         y, 
355                                         asset->get_compression_text(1, 0), 
356                                         MEDIUMFONT, 
357                                         mwindow->theme->assetedit_color));
358                                 y += vmargin;
359                                 x = x1;
360                         }
361                 }
362
363                 add_subwindow(new BC_Title(x, y, _("Channels:")));
364                 sprintf(string, "%d", asset_edit->changed_params->channels);
365
366                 x = x2;
367                 if(allow_edits)
368                 {
369                         BC_TumbleTextBox *textbox = new AssetEditChannels(this, 
370                                 string, 
371                                 x, 
372                                 y);
373                         textbox->create_objects();
374                         y += vmargin;
375                 }
376                 else
377                 {
378                         add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
379                         y += 20;
380                 }
381
382                 x = x1;
383                 add_subwindow(new BC_Title(x, y, _("Sample rate:")));
384                 sprintf(string, "%d", asset_edit->changed_params->sample_rate);
385
386                 x = x2;
387                 if(asset)
388                 {
389                         BC_TextBox *textbox;
390                         add_subwindow(textbox = new AssetEditRate(this, string, x, y));
391                         x += textbox->get_w();
392                         add_subwindow(new SampleRatePulldown(mwindow, textbox, x, y));
393                 }
394                 else
395                 {
396                         add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
397                 }
398
399                 y += 30;
400                 x = x1;
401
402                 if(asset)
403                 {
404                         add_subwindow(new BC_Title(x, y, _("Bits:")));
405                         x = x2;
406                         if(allow_edits)
407                         {
408                                 bitspopup = new BitsPopup(this, 
409                                         x, 
410                                         y, 
411                                         &asset_edit->changed_params->bits, 
412                                         1, 
413                                         1, 
414                                         1,
415                                         0,
416                                         1);
417                                 bitspopup->create_objects();
418                         }
419                         else
420                                 add_subwindow(new BC_Title(x, y, File::bitstostr(asset->bits), MEDIUMFONT, mwindow->theme->assetedit_color));
421
422
423                         x = x1;
424                         y += vmargin;
425                         add_subwindow(new BC_Title(x, y, _("Header length:")));
426                         sprintf(string, "%d", asset->header);
427
428                         x = x2;
429                         if(allow_edits)
430                                 add_subwindow(new AssetEditHeader(this, string, x, y));
431                         else
432                                 add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
433
434                         y += vmargin;
435                         x = x1;
436
437                         add_subwindow(new BC_Title(x, y, _("Byte order:")));
438
439                         if(allow_edits)
440                         {
441                                 x = x2;
442
443                                 add_subwindow(lohi = new AssetEditByteOrderLOHI(this, 
444                                         asset->byte_order, 
445                                         x, 
446                                         y));
447                                 x += 70;
448                                 add_subwindow(hilo = new AssetEditByteOrderHILO(this, 
449                                         !asset->byte_order, 
450                                         x, 
451                                         y));
452                                 y += vmargin;
453                         }
454                         else
455                         {
456                                 x = x2;
457                                 if(asset->byte_order)
458                                         add_subwindow(new BC_Title(x, y, _("Lo-Hi"), MEDIUMFONT, mwindow->theme->assetedit_color));
459                                 else
460                                         add_subwindow(new BC_Title(x, y, _("Hi-Lo"), MEDIUMFONT, mwindow->theme->assetedit_color));
461                                 y += vmargin;
462                         }
463
464
465                         x = x1;
466                         if(allow_edits)
467                         {
468         //                      add_subwindow(new BC_Title(x, y, _("Values are signed:")));
469                                 add_subwindow(new AssetEditSigned(this, asset->signed_, x, y));
470                         }
471                         else
472                         {
473                                 if(!asset->signed_ && asset->bits == 8)
474                                         add_subwindow(new BC_Title(x, y, _("Values are unsigned")));
475                                 else
476                                         add_subwindow(new BC_Title(x, y, _("Values are signed")));
477                         }
478
479                         y += 30;
480                 }
481         }
482
483         x = x1;
484         if((asset && asset->video_data) || nested_edl)
485         {
486                 add_subwindow(new BC_Bar(x, y, get_w() - x * 2));
487                 y += 5;
488
489                 add_subwindow(new BC_Title(x, y, _("Video:"), LARGEFONT, RED));
490                 y += 30;
491                 x = x1;
492
493
494                 if(asset && asset->get_compression_text(0,1))
495                 {
496                         add_subwindow(new BC_Title(x, y, _("Compression:")));
497                         x = x2;
498                         add_subwindow(new BC_Title(x, 
499                                 y, 
500                                 asset->get_compression_text(0,1), 
501                                 MEDIUMFONT, 
502                                 mwindow->theme->assetedit_color));
503                         y += vmargin;
504                         x = x1;
505                 }
506
507                 add_subwindow(new BC_Title(x, y, _("Frame rate:")));
508                 x = x2;
509                 sprintf(string, "%.2f", asset_edit->changed_params->frame_rate);
510
511 //printf("AssetEditWindow::create_objects %d %f\n", __LINE__, asset_edit->changed_params->frame_rate);
512                 if(asset)
513                 {
514                         BC_TextBox *framerate;
515                         add_subwindow(framerate = new AssetEditFRate(this, string, x, y));
516                         x += 105;
517                         add_subwindow(new FrameRatePulldown(mwindow, framerate, x, y));
518                 }
519                 else
520                 {
521                         add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
522                 }
523
524                 y += 30;
525                 x = x1;
526                 add_subwindow(new BC_Title(x, y, _("Width:")));
527                 x = x2;
528                 sprintf(string, "%d", asset_edit->changed_params->width);
529                 win_width = new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color);
530                 add_subwindow(win_width);
531
532                 y += vmargin;
533                 x = x1;
534                 add_subwindow(new BC_Title(x, y, _("Height:")));
535                 x = x2;
536                 sprintf(string, "%d", asset_edit->changed_params->height);
537                 win_height = new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color);
538                 add_subwindow(win_height);
539                 y += win_height->get_h() + 5;
540
541                 if(asset && (asset->format == FILE_MPEG || asset->format == FILE_FFMPEG ) )
542                 {
543                         y += 5;
544                         x = x1;
545                         add_subwindow(new BC_Title(x, y, _("Actual width:")));
546                         x = x2;
547                         sprintf(string, "%d", asset->actual_width);
548                         add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
549
550                         BC_GenericButton *resize = new ResizeAssetButton(this, x+64, y);
551                         add_subwindow(resize);
552
553                         y += vmargin;
554                         x = x1;
555                         add_subwindow(new BC_Title(x, y, _("Actual height:")));
556                         x = x2;
557                         sprintf(string, "%d", asset->actual_height);
558                         title = new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color);
559                         add_subwindow(title);
560                         y += title->get_h() + 5;
561                 }
562         }
563
564         add_subwindow(new BC_OKButton(this));
565         add_subwindow(new BC_CancelButton(this));
566         show_window();
567         unlock_window();
568 }
569
570 void AssetEditWindow::show_info_detail()
571 {
572         detail_thread->start((Asset*)asset_edit->indexable);
573 }
574
575
576 AssetEditChannels::AssetEditChannels(AssetEditWindow *fwindow, 
577         char *text, 
578         int x,
579         int y)
580  : BC_TumbleTextBox(fwindow, 
581                 (int)atol(text),
582                 (int)1,
583                 (int)MAXCHANNELS,
584                 x, 
585                 y, 
586                 50)
587 {
588         this->fwindow = fwindow;
589 }
590
591 int AssetEditChannels::handle_event()
592 {
593         Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
594         asset->channels = atol(get_text());
595         return 1;
596 }
597
598 AssetEditRate::AssetEditRate(AssetEditWindow *fwindow, char *text, int x, int y)
599  : BC_TextBox(x, y, 100, 1, text)
600 {
601         this->fwindow = fwindow;
602 }
603
604 int AssetEditRate::handle_event()
605 {
606         Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
607         asset->sample_rate = atol(get_text());
608         return 1;
609 }
610
611 AssetEditFRate::AssetEditFRate(AssetEditWindow *fwindow, char *text, int x, int y)
612  : BC_TextBox(x, y, 100, 1, text)
613 {
614         this->fwindow = fwindow;
615 }
616
617 int AssetEditFRate::handle_event()
618 {
619         Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
620         asset->frame_rate = atof(get_text());
621         return 1;
622 }
623
624 AssetEditHeader::AssetEditHeader(AssetEditWindow *fwindow, char *text, int x, int y)
625  : BC_TextBox(x, y, 100, 1, text)
626 {
627         this->fwindow = fwindow;
628 }
629
630 int AssetEditHeader::handle_event()
631 {
632         Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
633         asset->header = atol(get_text());
634         return 1;
635 }
636
637 AssetEditByteOrderLOHI::AssetEditByteOrderLOHI(AssetEditWindow *fwindow, 
638         int value, 
639         int x,
640         int y)
641  : BC_Radial(x, y, value, _("Lo-Hi"))
642 {
643         this->fwindow = fwindow;
644 }
645
646 int AssetEditByteOrderLOHI::handle_event()
647 {
648         Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
649         asset->byte_order = 1;
650         fwindow->hilo->update(0);
651         update(1);
652         return 1;
653 }
654
655 AssetEditByteOrderHILO::AssetEditByteOrderHILO(AssetEditWindow *fwindow, 
656         int value, 
657         int x, 
658         int y)
659  : BC_Radial(x, y, value, _("Hi-Lo"))
660 {
661         this->fwindow = fwindow;
662 }
663
664 int AssetEditByteOrderHILO::handle_event()
665 {
666         Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
667         asset->byte_order = 0;
668         fwindow->lohi->update(0);
669         update(1);
670         return 1;
671 }
672
673 AssetEditSigned::AssetEditSigned(AssetEditWindow *fwindow, 
674         int value, 
675         int x, 
676         int y)
677  : BC_CheckBox(x, y, value, _("Values are signed"))
678 {
679         this->fwindow = fwindow;
680 }
681
682 int AssetEditSigned::handle_event()
683 {
684         Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
685         asset->signed_ = get_value();
686         return 1;
687 }
688
689
690
691
692
693
694
695 AssetEditPathText::AssetEditPathText(AssetEditWindow *fwindow, int y)
696  : BC_TextBox(5, y, 300, 1, fwindow->asset_edit->changed_params->path) 
697 {
698         this->fwindow = fwindow; 
699 }
700 AssetEditPathText::~AssetEditPathText() 
701 {
702 }
703 int AssetEditPathText::handle_event() 
704 {
705         strcpy(fwindow->asset_edit->changed_params->path, get_text());
706         return 1;
707 }
708
709 AssetEditPath::AssetEditPath(MWindow *mwindow, 
710         AssetEditWindow *fwindow, 
711         BC_TextBox *textbox, 
712         int y, 
713         const char *text, 
714         const char *window_title, 
715         const char *window_caption)
716  : BrowseButton(mwindow, 
717         fwindow, 
718         textbox, 
719         310, 
720         y, 
721         text, 
722         window_title, 
723         window_caption, 
724         0) 
725
726         this->fwindow = fwindow; 
727 }
728 AssetEditPath::~AssetEditPath() {}
729
730
731
732
733
734
735 AssetEditFormat::AssetEditFormat(AssetEditWindow *fwindow, char* default_, int y)
736  : FormatPopup(fwindow->mwindow->plugindb, 90, y)
737
738         this->fwindow = fwindow; 
739 }
740 AssetEditFormat::~AssetEditFormat() 
741 {
742 }
743 int AssetEditFormat::handle_event()
744 {
745         Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
746         asset->format = File::strtoformat(fwindow->mwindow->plugindb, 
747                 get_selection(0, 0)->get_text());
748         return 1;
749 }
750
751
752
753
754 DetailAssetButton::DetailAssetButton(AssetEditWindow *fwindow, int x, int y)
755  : BC_GenericButton(x, y, _("Detail"))
756 {
757         this->fwindow = fwindow;
758         set_underline(0);
759 }
760
761 DetailAssetButton::~DetailAssetButton()
762 {
763 }
764
765 int DetailAssetButton::handle_event()
766 {
767         fwindow->show_info_detail();
768         return 1;
769 }
770
771 DetailAssetWindow::DetailAssetWindow(MWindow *mwindow, Asset *asset)
772  : BC_Window("Asset Detail",
773         mwindow->gui->get_abs_cursor_x(1) - 600/2,
774         mwindow->gui->get_abs_cursor_y(1) - 500/2,
775         600, 500)
776 {
777         this->mwindow = mwindow;
778         this->asset = asset;
779         asset->add_user();
780         info[0] = 0;
781         text = 0;
782 }
783
784 DetailAssetWindow::~DetailAssetWindow()
785 {
786         asset->remove_user();
787         delete text;
788 }
789
790 DetailAssetThread::DetailAssetThread(MWindow *mwindow)
791  : Thread(1, 0, 0)
792 {
793         this->mwindow = mwindow;
794         dwindow = 0;
795 }
796
797 DetailAssetThread::~DetailAssetThread()
798 {
799         if( Thread::running() ) {
800                 dwindow->lock_window("DetailAssetThread::~DetailAssetThread");
801                 dwindow->set_done(1);
802                 dwindow->unlock_window();
803                 Thread::join();
804         }
805 }
806
807 void DetailAssetWindow::create_objects()
808 {
809         int y = 10, x = 10;
810         char file_name[BCTEXTLEN];
811         int len = sizeof(info);
812         strncpy(info,"no info available",len);
813         if( !mwindow->preferences->get_asset_file_path(asset, file_name) ) {
814                 switch( asset->format ) {
815                 case FILE_MPEG:
816                         FileMPEG::get_info(asset->path, file_name, &info[0]);
817                         break;
818                 case FILE_FFMPEG:
819                         FileFFMPEG::get_info(asset->path, &info[0]);
820                         break;
821                 }
822         }
823         lock_window("DetailAssetThread::create_objects");
824         text = new BC_ScrollTextBox(this, x, y, get_w()-32, 23, info, -len);
825         text->create_objects();  text->set_text_row(0);
826         add_subwindow(new BC_OKButton(this));
827         show_window();
828         unlock_window();
829 }
830
831 void DetailAssetThread::start(Asset *asset)
832 {
833         if( !Thread::running() ) {
834                 delete dwindow;
835                 dwindow = new DetailAssetWindow(mwindow, asset);
836                 Thread::start();
837         }
838 }
839
840 void DetailAssetThread::run()
841 {
842 // Get length from TOC
843         dwindow->create_objects();
844         dwindow->run_window();
845         delete dwindow;
846         dwindow = 0;
847 }
848
849