6 #include "edlsession.h"
8 #include "filesystem.h"
9 #include "localsession.h"
11 #include "mainsession.h"
12 #include "trackcanvas.h"
14 #include "transition.h"
23 Edit::Edit(EDL *edl, Track *track)
28 if(track) this->edits = track->edits;
32 Edit::Edit(EDL *edl, Edits *edits)
37 if(edits) this->track = edits->track;
43 //printf("Edit::~Edit 1\n");
44 if(transition) delete transition;
45 //printf("Edit::~Edit 2\n");
61 int Edit::copy(int64_t start, int64_t end, FileXML *file, char *output_path)
64 //printf("Edit::copy 1\n");
66 int64_t endproject = startproject + length;
69 if((startproject >= start && startproject <= end) || // startproject in range
70 (endproject <= end && endproject >= start) || // endproject in range
71 (startproject <= start && endproject >= end)) // range in project
74 int64_t startproject_in_selection = startproject; // start of edit in selection in project
75 int64_t startsource_in_selection = startsource; // start of source in selection in source
76 int64_t endsource_in_selection = startsource + length; // end of source in selection
77 int64_t length_in_selection = length; // length of edit in selection
78 //printf("Edit::copy 2\n");
80 if(startproject < start)
81 { // start is after start of edit in project
82 int64_t length_difference = start - startproject;
84 startsource_in_selection += length_difference;
85 startproject_in_selection += length_difference;
86 length_in_selection -= length_difference;
88 //printf("Edit::copy 3\n");
91 { // end is before end of edit in project
92 length_in_selection = end - startproject_in_selection;
95 //printf("Edit::copy 4\n");
96 if(file) // only if not counting
98 file->tag.set_title("EDIT");
99 file->tag.set_property("STARTSOURCE", startsource_in_selection);
100 file->tag.set_property("CHANNEL", (int64_t)channel);
101 file->tag.set_property("LENGTH", length_in_selection);
102 //printf("Edit::copy 5\n");
104 copy_properties_derived(file, length_in_selection);
107 // file->append_newline();
108 //printf("Edit::copy 6\n");
112 //printf("Edit::copy 6 %s\n", asset->path);
113 char stored_path[1024];
114 char asset_directory[1024], output_directory[1024];
117 //printf("Edit::copy 6 %s\n", asset->path);
118 fs.extract_dir(asset_directory, asset->path);
119 //printf("Edit::copy 6 %s\n", asset->path);
122 fs.extract_dir(output_directory, output_path);
124 output_directory[0] = 0;
125 //printf("Edit::copy %s, %s %s, %s\n", asset->path, asset_directory, output_path, output_directory);
127 if(output_path && !strcmp(asset_directory, output_directory))
128 fs.extract_name(stored_path, asset->path);
130 strcpy(stored_path, asset->path);
132 file->tag.set_title("FILE");
133 file->tag.set_property("SRC", stored_path);
139 transition->save_xml(file);
142 //printf("Edit::copy 7\n");
143 file->tag.set_title("/EDIT");
145 file->append_newline();
146 //printf("Edit::copy 8\n");
148 //printf("Edit::copy 9\n");
155 //printf("Edit::copy 10\n");
160 int64_t Edit::get_source_end(int64_t default_)
165 void Edit::insert_transition(char *title)
167 //printf("Edit::insert_transition this=%p title=%p title=%s\n", this, title, title);
168 transition = new Transition(edl,
171 track->to_units(edl->session->default_transition_length, 1));
174 void Edit::detach_transition()
176 if(transition) delete transition;
189 void Edit::copy_from(Edit *edit)
191 this->asset = edl->assets->update(edit->asset);
192 this->startsource = edit->startsource;
193 this->startproject = edit->startproject;
194 this->length = edit->length;
197 if(!transition) transition = new Transition(edl,
199 edit->transition->title,
200 edit->transition->length);
201 *this->transition = *edit->transition;
203 this->channel = edit->channel;
206 void Edit::equivalent_output(Edit *edit, int64_t *result)
208 // End of edit changed
209 if(startproject + length != edit->startproject + edit->length)
211 int64_t new_length = MIN(startproject + length, edit->startproject + edit->length);
212 if(*result < 0 || new_length < *result)
213 *result = new_length;
216 // Start of edit changed
218 // One is silence and one isn't
219 edit->asset == 0 && asset != 0 ||
220 edit->asset != 0 && asset == 0 ||
221 // One has transition and one doesn't
222 edit->transition == 0 && transition != 0 ||
223 edit->transition != 0 && transition == 0 ||
225 startproject != edit->startproject ||
226 startsource != edit->startsource ||
227 // Transition changed
230 !transition->identical(edit->transition)) ||
234 !asset->equivalent(*edit->asset, 1, 1))
237 if(*result < 0 || startproject < *result) *result = startproject;
242 Edit& Edit::operator=(Edit& edit)
244 //printf("Edit::operator= called\n");
249 void Edit::synchronize_params(Edit *edit)
255 // Comparison for ResourcePixmap drawing
256 int Edit::identical(Edit &edit)
258 int result = (this->asset == edit.asset &&
259 this->startsource == edit.startsource &&
260 this->startproject == edit.startproject &&
261 this->length == edit.length &&
262 this->transition == edit.transition &&
263 this->channel == edit.channel);
267 int Edit::operator==(Edit &edit)
269 return identical(edit);
272 double Edit::frames_per_picon()
274 return picon_w() / frame_w();
277 double Edit::frame_w()
279 return track->from_units(1) * edl->session->sample_rate / edl->local_session->zoom_sample;
282 double Edit::picon_w()
284 return (double)edl->local_session->zoom_track * asset->width / asset->height;
289 return edl->local_session->zoom_track;
295 printf(" EDIT %p\n", this); fflush(stdout);
296 printf(" asset %p\n", asset); fflush(stdout);
297 printf(" channel %d\n", channel);
300 printf(" TRANSITION %p\n", transition);
303 printf(" startsource %lld startproject %lld length %lld\n", startsource, startproject, length); fflush(stdout);
307 int Edit::load_properties(FileXML *file, int64_t &startproject)
309 startsource = file->tag.get_property("STARTSOURCE", (int64_t)0);
310 length = file->tag.get_property("LENGTH", (int64_t)0);
311 this->startproject = startproject;
312 load_properties_derived(file);
316 void Edit::shift(int64_t difference)
318 //printf("Edit::shift 1 %p %lld %lld\n", this, startproject, difference);
319 startproject += difference;
320 //printf("Edit::shift 2 %lld %lld\n", startproject, difference);
323 int Edit::shift_start_in(int edit_mode,
330 int64_t cut_length = newposition - oldposition;
331 int64_t end_previous_source, end_source;
333 if(edit_mode == MOVE_ALL_EDITS)
335 if(cut_length < length)
337 edits->clear_recursive(oldposition,
345 edits->clear_recursive(oldposition,
346 startproject + length,
353 if(edit_mode == MOVE_ONE_EDIT)
355 // Paste silence and cut
356 //printf("Edit::shift_start_in 1\n");
359 Edit *new_edit = edits->create_edit();
360 new_edit->startproject = this->startproject;
361 new_edit->length = 0;
362 edits->insert_before(this,
365 //printf("Edit::shift_start_in 2 %p\n", previous);
367 end_previous_source = previous->get_source_end(previous->startsource + previous->length + cut_length);
368 if(end_previous_source > 0 &&
369 previous->startsource + previous->length + cut_length > end_previous_source)
370 cut_length = end_previous_source - previous->startsource - previous->length;
372 if(cut_length < length)
374 startproject += cut_length;
375 startsource += cut_length;
376 length -= cut_length;
377 previous->length += cut_length;
378 //printf("Edit::shift_start_in 2\n");
381 { // Clear entire edit
383 previous->length += cut_length;
384 for(Edit* current_edit = this; current_edit; current_edit = current_edit->next)
386 current_edit->startproject += cut_length;
388 edits->clear_recursive(oldposition + cut_length,
389 startproject + cut_length,
394 //printf("Edit::shift_start_in 3\n");
397 if(edit_mode == MOVE_NO_EDITS)
399 end_source = get_source_end(startsource + length + cut_length);
400 if(end_source > 0 && startsource + length + cut_length > end_source)
401 cut_length = end_source - startsource - length;
403 startsource += cut_length;
408 int Edit::shift_start_out(int edit_mode,
415 int64_t cut_length = oldposition - newposition;
419 int64_t end_source = get_source_end(1);
421 //printf("Edit::shift_start_out 1 %lld %lld\n", startsource, cut_length);
422 if(end_source > 0 && startsource < cut_length)
424 cut_length = startsource;
428 if(edit_mode == MOVE_ALL_EDITS)
430 //printf("Edit::shift_start_out 10 %lld\n", cut_length);
431 startsource -= cut_length;
432 length += cut_length;
434 edits->shift_keyframes_recursive(startproject,
437 edits->shift_effects_recursive(startproject,
440 for(Edit* current_edit = next; current_edit; current_edit = current_edit->next)
442 current_edit->startproject += cut_length;
446 if(edit_mode == MOVE_ONE_EDIT)
450 if(cut_length < previous->length)
451 { // Cut into previous edit
452 previous->length -= cut_length;
453 startproject -= cut_length;
454 startsource -= cut_length;
455 length += cut_length;
456 printf("Edit::shift_start_out 2\n");
459 { // Clear entire previous edit
460 cut_length = previous->length;
461 previous->length = 0;
462 length += cut_length;
463 startsource -= cut_length;
464 startproject -= cut_length;
469 if(edit_mode == MOVE_NO_EDITS)
471 startsource -= cut_length;
474 // Fix infinite length files
475 if(startsource < 0) startsource = 0;
479 int Edit::shift_end_in(int edit_mode,
486 int64_t cut_length = oldposition - newposition;
488 if(edit_mode == MOVE_ALL_EDITS)
490 //printf("Edit::shift_end_in 1\n");
491 if(newposition > startproject)
492 { // clear partial edit
493 //printf("Edit::shift_end_in %p %p\n", track->edits, edits);
494 edits->clear_recursive(newposition,
501 { // clear entire edit
502 edits->clear_recursive(startproject,
510 if(edit_mode == MOVE_ONE_EDIT)
516 int64_t end_source = next->get_source_end(1);
518 if(end_source > 0 && next->startsource - cut_length < 0)
520 cut_length = next->startsource;
524 if(cut_length < length)
526 length -= cut_length;
527 next->startproject -= cut_length;
528 next->startsource -= cut_length;
529 next->length += cut_length;
530 //printf("Edit::shift_end_in 2 %d\n", cut_length);
535 next->length += cut_length;
536 next->startsource -= cut_length;
537 next->startproject -= cut_length;
538 length -= cut_length;
543 if(cut_length < length)
545 length -= cut_length;
550 edits->clear_recursive(startproject,
559 // Does nothing for plugins
560 if(edit_mode == MOVE_NO_EDITS)
562 //printf("Edit::shift_end_in 3\n");
563 int64_t end_source = get_source_end(1);
564 if(end_source > 0 && startsource < cut_length)
566 cut_length = startsource;
568 startsource -= cut_length;
573 int Edit::shift_end_out(int edit_mode,
580 int64_t cut_length = newposition - oldposition;
581 int64_t endsource = get_source_end(startsource + length + cut_length);
583 // check end of edit against end of source file
584 if(endsource > 0 && startsource + length + cut_length > endsource)
585 cut_length = endsource - startsource - length;
587 //printf("Edit::shift_end_out 1 %lld %d %d %d\n", oldposition, newposition, this->length, cut_length);
588 if(edit_mode == MOVE_ALL_EDITS)
591 this->length += cut_length;
593 // Effects are shifted in length extension
595 edits->shift_effects_recursive(oldposition /* startproject */,
597 edits->shift_keyframes_recursive(oldposition /* startproject */,
600 for(Edit* current_edit = next; current_edit; current_edit = current_edit->next)
602 current_edit->startproject += cut_length;
606 if(edit_mode == MOVE_ONE_EDIT)
610 if(cut_length < next->length)
612 length += cut_length;
613 next->startproject += cut_length;
614 next->startsource += cut_length;
615 next->length -= cut_length;
616 //printf("Edit::shift_end_out 2 %d\n", cut_length);
620 cut_length = next->length;
622 length += cut_length;
627 length += cut_length;
631 if(edit_mode == MOVE_NO_EDITS)
633 startsource += cut_length;
666 int Edit::popup_transition(float view_start, float zoom_units, int cursor_x, int cursor_y)
668 int64_t left, right, left_unit, right_unit;
669 if(!transition) return 0;
670 get_handle_parameters(left, right, left_unit, right_unit, view_start, zoom_units);
672 if(cursor_x > left && cursor_x < right)
674 // transition->popup_transition(cursor_x, cursor_y);
680 int Edit::select_handle(float view_start, float zoom_units, int cursor_x, int cursor_y, int64_t &selection)
682 int64_t left, right, left_unit, right_unit;
683 get_handle_parameters(left, right, left_unit, right_unit, view_start, zoom_units);
685 int64_t pixel1, pixel2;
687 pixel2 = pixel1 + 10;
690 // cursor_x is faked in acanvas
691 if(cursor_x >= pixel1 && cursor_x <= pixel2)
693 selection = left_unit;
694 return 1; // left handle
697 int64_t endproject = startproject + length;
699 pixel1 = pixel2 - 10;
702 if(cursor_x >= pixel1 && cursor_x <= pixel2)
704 selection = right_unit;
705 return 2; // right handle