add bluray dv, misc fixes
[goodguy/history.git] / cinelerra-5.1 / cinelerra / exportedl.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2006 Andraz Tori
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 "bchash.h"
24 #include "condition.h"
25 #include "confirmsave.h"
26 #include "edits.h"
27 #include "edl.h"
28 #include "edlsession.h"
29 #include "errorbox.h"
30 #include "file.h"
31 #include "filesystem.h"
32 #include "filexml.h"
33 #include "language.h"
34 #include "localsession.h"
35 #include "mainsession.h"
36 #include "mutex.h"
37 #include "mwindowgui.h"
38 #include "mwindow.h"
39 #include "exportedl.h"
40 #include "tracks.h"
41 #include "transition.h"
42
43 #include <libintl.h>
44 #define _(String) gettext(String)
45 #define gettext_noop(String) String
46 #define N_(String) gettext_noop (String)
47
48
49
50 #include <ctype.h>
51 #include <string.h>
52
53 ExportEDLAsset::ExportEDLAsset(MWindow *mwindow, EDL *edl)
54 {
55         this->mwindow = mwindow;
56         this->edl = edl;
57
58         path[0] = 0;
59         edl_type = EDLTYPE_CMX3600;
60         track_number = -1;
61 }
62
63 ExportEDLAsset::~ExportEDLAsset()
64 {
65 }
66
67 void ExportEDLAsset::double_to_CMX3600(double seconds, double frame_rate, char *str)
68 {
69         char tmp[20];
70         Units::totext(tmp,
71                         seconds,
72                         TIME_HMSF,
73                         0, // sample_rate ... unnecessary
74                         frame_rate,
75                         0);    // frames per foot
76         if ((int)(seconds / 3600) <= 9)
77         {
78                 str[0]='0';
79                 strcpy(str+1, tmp);
80         } else
81         {
82                 strcpy(str, tmp);
83         }
84
85 //      str[8]='.';
86
87         //sprintf(str, "%02d:%02d:%02d:%02d", hour, minute, second, hundredths);
88 }
89
90 int ExportEDLAsset::edit_to_timecodes(Edit *edit, char *sourceinpoint, char *sourceoutpoint, char *destinpoint, char *destoutpoint, char *reel_name)
91 {
92         Asset *asset = edit->asset;
93         Track *track = edit->track;
94         double frame_rate = edit->track->edl->session->frame_rate;
95
96         double edit_sourcestart;
97         double edit_sourceend;
98         double edit_deststart;
99         double edit_destend;
100
101         if (asset)
102         {
103                 // reelname should be 8 chars long
104
105                 strncpy(reel_name, asset->reel_name, 9);
106                 if (strlen(asset->reel_name) > 8)
107                 {
108                         printf(_("Warning: chopping the reel name to eight characters!\n"));
109                 };
110                 reel_name[8] = 0;
111                 for (int i = strlen(reel_name); i<8; i++)
112                         reel_name[i] = ' ';
113
114                 edit_sourcestart = (double)asset->tcstart / asset->frame_rate
115                         + track->from_units(edit->startsource);
116                 edit_sourceend = (double)asset->tcstart / asset->frame_rate
117                         + track->from_units(edit->startsource + edit->length);
118
119         } else
120         {
121                 strcpy(reel_name, "   BL   ");
122                 edit_sourcestart = 0;
123                 edit_sourceend = track->from_units(edit->length);
124         }
125
126         edit_deststart = track->from_units(edit->startproject);
127         edit_destend = track->from_units(edit->startproject + edit->length);
128
129         double_to_CMX3600(edit_sourcestart, frame_rate, sourceinpoint);
130         double_to_CMX3600(edit_sourceend, frame_rate, sourceoutpoint);
131         double_to_CMX3600(edit_deststart, frame_rate, destinpoint);
132         double_to_CMX3600(edit_destend, frame_rate, destoutpoint);
133
134         return 0;
135 }
136
137
138 void ExportEDLAsset::export_it()
139 {
140         FILE *fh;
141         fh = fopen(path, "w+");
142
143 // We currently only support exporting one track at a time
144 // Find the track...
145         int serial = 0;
146         Track *track;
147         for(track = edl->tracks->first;
148                 track;
149                 track = track->next)
150         {
151                 if (serial == track_number)
152                         break;
153                 serial ++;
154         }
155
156
157         int last_dissolve = 1;
158
159         if (edl_type == EDLTYPE_CMX3600)
160         {
161
162                 // TODO: Find docs about exact header for CMX3600
163                 fprintf(fh, "TITLE: Cinproj   FORMAT: CMX 3600 4-Ch\n");
164
165                 int colnum = 1;
166
167
168                 for (Edit *edit = track->edits->first;
169                         edit;
170                         edit = edit->next)
171                 {
172                         char reel_name[BCTEXTLEN];
173                         char avselect[5];
174                         char edittype[5] = "C   ";
175                         char cutinfo[4] = "   ";
176                         char sourceinpoint[12];
177                         char sourceoutpoint[12];
178                         char destinpoint[12];
179                         char destoutpoint[12];
180                         if (track->data_type == TRACK_AUDIO)
181                                 strcpy(avselect, "A   ");
182                         else
183                                 strcpy(avselect, "V   ");
184
185                         //if (edit->transition)
186                         //      printf("title: %s, length: %i\n", edit->transition->title, edit->transition->length);
187                         if (edit->transition && !strcmp(edit->transition->title, "Dissolve"))
188                         {
189                                 char last_sourceout[12];
190                                 edit_to_timecodes(edit->previous, sourceinpoint, last_sourceout, destinpoint, destoutpoint, reel_name);
191                                 edit_to_timecodes(edit, sourceinpoint, sourceoutpoint, destinpoint, destoutpoint, reel_name);
192
193                                 if (last_dissolve)
194                                 {
195                                         fprintf(fh, "%03d %8s %s %4s %3s", colnum, reel_name, avselect, edittype, cutinfo);
196                                         fprintf(fh, " %s %s", last_sourceout, last_sourceout);
197                                         fprintf(fh, " %s %s", destinpoint, destinpoint);
198                                         fprintf(fh,"\n");
199                                 } else
200                                 {
201                                         colnum --;
202                                 }
203                                 edittype[0] = 'D';
204                                 fprintf(fh, "%03d %8s %s %4s %03jd", colnum, reel_name, avselect, edittype, edit->transition->length);
205                                 fprintf(fh, " %s %s", sourceinpoint, sourceoutpoint);
206                                 fprintf(fh, " %s %s", destinpoint, destoutpoint);
207                                 fprintf(fh,"\n");
208                                 last_dissolve = 1;
209                         } else
210                         {
211                                                         edit_to_timecodes(edit, sourceinpoint, sourceoutpoint, destinpoint, destoutpoint, reel_name);
212                                 fprintf(fh, "%03d %8s %s %4s %3s", colnum, reel_name, avselect, edittype, cutinfo);
213                                 fprintf(fh, " %s %s", sourceinpoint, sourceoutpoint);
214                                 fprintf(fh, " %s %s", destinpoint, destoutpoint);
215                                 fprintf(fh,"\n");
216                                 last_dissolve = 0;
217                         }
218
219                         colnum ++;
220
221                 }
222
223         }
224
225         fclose(fh);
226
227
228 }
229
230
231
232 int ExportEDLAsset::load_defaults()
233 {
234         mwindow->defaults->get("EDLEXPORT_PATH", path);
235         mwindow->defaults->get("EDLEXPORT_TYPE", edl_type);
236         mwindow->defaults->get("EDLEXPORT_TRACKNUMBER", track_number);
237         //load_mode = mwindow->defaults->get("RENDER_LOADMODE", LOADMODE_NEW_TRACKS);
238
239
240         return 0;
241 }
242
243 int ExportEDLAsset::save_defaults()
244 {
245         mwindow->defaults->update("EDLEXPORT_PATH", path);
246         mwindow->defaults->update("EDLEXPORT_TYPE", edl_type);
247         mwindow->defaults->update("EDLEXPORT_TRACKNUMBER", track_number);
248         return 0;
249 }
250
251
252
253
254 ExportEDLItem::ExportEDLItem(MWindow *mwindow)
255  : BC_MenuItem(_("Export EDL..."), "Shift-E", 'E')
256 {
257         this->mwindow = mwindow;
258         set_shift(1);
259 }
260
261 int ExportEDLItem::handle_event()
262 {
263         mwindow->exportedl->start_interactive();
264         return 1;
265 }
266
267
268
269
270
271 ExportEDL::ExportEDL(MWindow *mwindow)
272  : Thread(0, 0, 0)
273 {
274         this->mwindow = mwindow;
275 //      package_lock = new Mutex("ExportEDL::package_lock");
276 //      counter_lock = new Mutex("ExportEDL::counter_lock");
277 //      completion = new Condition(0, "ExportEDL::completion");
278 //      progress_timer = new Timer;
279 }
280
281 ExportEDL::~ExportEDL()
282 {
283 //      delete package_lock;
284 //      delete counter_lock;
285 //      delete completion;
286 ///     if(preferences) delete preferences;
287 //      delete progress_timer;
288 }
289
290 void ExportEDL::start_interactive()
291 {
292         if(!Thread::running())
293         {
294                 Thread::start();
295         }
296 }
297
298 void ExportEDL::run()
299 {
300         int result = 0;
301         exportasset = new ExportEDLAsset(mwindow, mwindow->edl);
302
303         exportasset->load_defaults();
304
305 // Get format from user
306                 result = 0;
307                 int filesok;
308
309                 do {
310                 // FIX
311                         filesok = 0;
312                         exportedl_window = new ExportEDLWindow(mwindow, this, exportasset);
313                         exportedl_window->create_objects();
314                         result = exportedl_window->run_window();
315                         if (! result) {
316                                 // add to recentlist only on OK
317                                 // Fix "EDL"!
318                                 exportedl_window->path_recent->add_item("EDLPATH", exportasset->path);
319                         }
320                         exportasset->track_number = exportedl_window->track_list->get_selection_number(0, 0);
321
322                         delete exportedl_window;
323                         exportedl_window = 0;
324                         if (!result)
325                         {
326                                 ArrayList<char*> paths;
327
328                                 paths.append(exportasset->path);
329                                 filesok = ConfirmSave::test_files(mwindow, &paths);
330                         }
331
332                 } while (!result && filesok);
333         mwindow->save_defaults();
334         exportasset->save_defaults();
335
336 // FIX
337         if(!result) exportasset->export_it();
338
339
340         delete exportasset;
341
342 }
343
344
345
346
347
348
349
350
351 #define WIDTH 410
352 #define HEIGHT 400
353
354 static const char *list_titles[] =
355 {
356         N_("No."),
357         N_("Track name")
358 };
359
360
361 static int list_widths[] =
362 {
363         40,
364         200
365 };
366
367 ExportEDLWindow::ExportEDLWindow(MWindow *mwindow, ExportEDL *exportedl, ExportEDLAsset *exportasset)
368  : BC_Window(_(PROGRAM_NAME ": Export EDL"),
369         mwindow->gui->get_screen_w(1, 0) / 2 - WIDTH / 2,
370         mwindow->gui->get_root_h(1) / 2 - HEIGHT / 2,
371         WIDTH,
372         HEIGHT,
373         (int)BC_INFINITY,
374         (int)BC_INFINITY,
375         0,
376         0,
377         1)
378 {
379         this->mwindow = mwindow;
380         this->exportasset = exportasset;
381 }
382
383 ExportEDLWindow::~ExportEDLWindow()
384 {
385 //      delete format_tools;
386 //      delete loadmode;
387 }
388
389
390
391 void ExportEDLWindow::create_objects()
392 {
393         int x = 5, y = 5;
394         add_subwindow(new BC_Title(x,
395                 y,
396                         _("Select a file to export to:")));
397         y += 25;
398
399         add_subwindow(path_textbox = new ExportEDLPathText(x, y, this));
400         x += 300;
401         path_recent = new BC_RecentList("EDLPATH", mwindow->defaults,
402                                         path_textbox, 10, x, y, 300, 100);
403         add_subwindow(path_recent);
404 // FIX
405         path_recent->load_items("EDLPATH");
406
407         x += 24;
408         add_subwindow(path_button = new BrowseButton(
409                 mwindow->theme, this, path_textbox, x, y - 4, exportasset->path,
410                 _("Output to file"), _("Select a file to write to:"), 0));
411
412         y += 34;
413         x = 5;
414         add_subwindow(new BC_Title(x, y, _("Select track to be exported:")));
415         y += 25;
416
417
418         items_tracks[0].remove_all_objects();
419         items_tracks[1].remove_all_objects();
420         int serial = 0;
421         if (exportasset->track_number == -1)
422                 exportasset->track_number = 0;
423         for(Track *track = mwindow->edl->tracks->first;
424                 track;
425                 track = track->next)
426         {
427
428                 char tmp[10];
429                 sprintf(tmp, "%i\n", serial+1);
430
431                 BC_ListBoxItem *listitem = new BC_ListBoxItem(tmp);
432                 if (serial == exportasset->track_number)
433                         listitem->set_selected(1);
434                 items_tracks[0].append(listitem);
435                 items_tracks[1].append(new BC_ListBoxItem(track->title));
436                 serial ++;
437
438         }
439
440
441         add_subwindow(track_list = new ExportEDLWindowTrackList(this, x, y, 400, 200, items_tracks));
442
443         y += 5 + track_list->get_h();
444         add_subwindow(new BC_Title(x, y, _("Currently only CMX 3600 format is supported")));
445
446
447         add_subwindow(new BC_OKButton(this));
448         add_subwindow(new BC_CancelButton(this));
449         show_window();
450 }
451
452
453 ExportEDLPathText::ExportEDLPathText(int x, int y, ExportEDLWindow *window)
454  : BC_TextBox(x, y, 300, 1, window->exportasset->path)
455 {
456         this->window = window;
457 }
458 ExportEDLPathText::~ExportEDLPathText()
459 {
460 }
461 int ExportEDLPathText::handle_event()
462 {
463         strcpy(window->exportasset->path, get_text());
464 //      window->handle_event();
465         return 1;
466 }
467
468 ExportEDLWindowTrackList::ExportEDLWindowTrackList(ExportEDLWindow *window,
469         int x,
470         int y,
471         int w,
472         int h,
473         ArrayList<BC_ListBoxItem*> *track_list)
474  : BC_ListBox(x,
475                 y,
476                 w,
477                 h,
478                 LISTBOX_TEXT,
479                 track_list,
480                 list_titles,
481                 list_widths,
482                 2)
483 {
484         this->window = window;
485 }
486
487 int ExportEDLWindowTrackList::handle_event()
488 {
489 //      window->exportasset->track_number = get_selection_number(0, 0);
490 //      printf("aaaaa %i\n", window->exportasset->track_number );
491 //      window->set_done(0);
492         return 1;
493 }
494
495
496