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