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