7 #include "edlsession.h"
9 #include "filesystem.h"
10 #include "localsession.h"
12 #include "mainsession.h"
13 #include "trackcanvas.h"
15 #include "transition.h"
24 Edit::Edit(EDL *edl, Track *track)
29 if(track) this->edits = track->edits;
33 Edit::Edit(EDL *edl, Edits *edits)
38 if(edits) this->track = edits->track;
44 //printf("Edit::~Edit 1\n");
45 if(transition) delete transition;
46 //printf("Edit::~Edit 2\n");
63 int Edit::copy(int64_t start, int64_t end, FileXML *file, char *output_path)
66 //printf("Edit::copy 1\n");
68 int64_t endproject = startproject + length;
71 if((startproject >= start && startproject <= end) || // startproject in range
72 (endproject <= end && endproject >= start) || // endproject in range
73 (startproject <= start && endproject >= end)) // range in project
76 int64_t startproject_in_selection = startproject; // start of edit in selection in project
77 int64_t startsource_in_selection = startsource; // start of source in selection in source
78 int64_t endsource_in_selection = startsource + length; // end of source in selection
79 int64_t length_in_selection = length; // length of edit in selection
80 //printf("Edit::copy 2\n");
82 if(startproject < start)
83 { // start is after start of edit in project
84 int64_t length_difference = start - startproject;
86 startsource_in_selection += length_difference;
87 startproject_in_selection += length_difference;
88 length_in_selection -= length_difference;
90 //printf("Edit::copy 3\n");
93 { // end is before end of edit in project
94 length_in_selection = end - startproject_in_selection;
97 //printf("Edit::copy 4\n");
98 if(file) // only if not counting
100 file->tag.set_title("EDIT");
101 file->tag.set_property("STARTSOURCE", startsource_in_selection);
102 file->tag.set_property("CHANNEL", (int64_t)channel);
103 file->tag.set_property("LENGTH", length_in_selection);
104 if(user_title[0]) file->tag.set_property("USER_TITLE", user_title);
105 //printf("Edit::copy 5\n");
107 copy_properties_derived(file, length_in_selection);
110 // file->append_newline();
111 //printf("Edit::copy 6\n");
115 //printf("Edit::copy 6 %s\n", asset->path);
116 char stored_path[1024];
117 char asset_directory[1024], output_directory[1024];
120 //printf("Edit::copy 6 %s\n", asset->path);
121 fs.extract_dir(asset_directory, asset->path);
122 //printf("Edit::copy 6 %s\n", asset->path);
125 fs.extract_dir(output_directory, output_path);
127 output_directory[0] = 0;
128 //printf("Edit::copy %s, %s %s, %s\n", asset->path, asset_directory, output_path, output_directory);
130 if(output_path && !strcmp(asset_directory, output_directory))
131 fs.extract_name(stored_path, asset->path);
133 strcpy(stored_path, asset->path);
135 file->tag.set_title("FILE");
136 file->tag.set_property("SRC", stored_path);
138 file->tag.set_title("/FILE");
144 transition->save_xml(file);
147 //printf("Edit::copy 7\n");
148 file->tag.set_title("/EDIT");
150 file->append_newline();
151 //printf("Edit::copy 8\n");
153 //printf("Edit::copy 9\n");
160 //printf("Edit::copy 10\n");
165 int64_t Edit::get_source_end(int64_t default_)
170 void Edit::insert_transition(char *title)
172 //printf("Edit::insert_transition this=%p title=%p title=%s\n", this, title, title);
173 transition = new Transition(edl,
176 track->to_units(edl->session->default_transition_length, 1));
179 void Edit::detach_transition()
181 if(transition) delete transition;
194 void Edit::copy_from(Edit *edit)
196 this->asset = edl->assets->update(edit->asset);
197 this->startsource = edit->startsource;
198 this->startproject = edit->startproject;
199 this->length = edit->length;
200 strcpy (this->user_title, edit->user_title);
204 if(!transition) transition = new Transition(edl,
206 edit->transition->title,
207 edit->transition->length);
208 *this->transition = *edit->transition;
210 this->channel = edit->channel;
213 void Edit::equivalent_output(Edit *edit, int64_t *result)
215 // End of edit changed
216 if(startproject + length != edit->startproject + edit->length)
218 int64_t new_length = MIN(startproject + length, edit->startproject + edit->length);
219 if(*result < 0 || new_length < *result)
220 *result = new_length;
223 // Start of edit changed
225 // One is silence and one isn't
226 edit->asset == 0 && asset != 0 ||
227 edit->asset != 0 && asset == 0 ||
228 // One has transition and one doesn't
229 edit->transition == 0 && transition != 0 ||
230 edit->transition != 0 && transition == 0 ||
232 startproject != edit->startproject ||
233 startsource != edit->startsource ||
234 // Transition changed
237 !transition->identical(edit->transition)) ||
241 !asset->equivalent(*edit->asset, 1, 1))
244 if(*result < 0 || startproject < *result) *result = startproject;
249 Edit& Edit::operator=(Edit& edit)
251 //printf("Edit::operator= called\n");
256 void Edit::synchronize_params(Edit *edit)
262 // Comparison for ResourcePixmap drawing
263 int Edit::identical(Edit &edit)
265 int result = (this->asset == edit.asset &&
266 this->startsource == edit.startsource &&
267 this->startproject == edit.startproject &&
268 this->length == edit.length &&
269 this->transition == edit.transition &&
270 this->channel == edit.channel);
274 int Edit::operator==(Edit &edit)
276 return identical(edit);
279 double Edit::frames_per_picon()
281 return Units::round(picon_w()) / frame_w();
284 double Edit::frame_w()
286 return track->from_units(1) *
287 edl->session->sample_rate /
288 edl->local_session->zoom_sample;
291 double Edit::picon_w()
293 return (double)edl->local_session->zoom_track *
300 return edl->local_session->zoom_track;
306 printf(" EDIT %p\n", this); fflush(stdout);
307 printf(" asset %p\n", asset); fflush(stdout);
308 printf(" channel %d\n", channel);
311 printf(" TRANSITION %p\n", transition);
314 printf(" startsource %lld startproject %lld length %lld\n", startsource, startproject, length); fflush(stdout);
318 int Edit::load_properties(FileXML *file, int64_t &startproject)
320 startsource = file->tag.get_property("STARTSOURCE", (int64_t)0);
321 length = file->tag.get_property("LENGTH", (int64_t)0);
323 file->tag.get_property("USER_TITLE", user_title);
324 this->startproject = startproject;
325 load_properties_derived(file);
329 void Edit::shift(int64_t difference)
331 //printf("Edit::shift 1 %p %lld %lld\n", this, startproject, difference);
332 startproject += difference;
333 //printf("Edit::shift 2 %lld %lld\n", startproject, difference);
336 int Edit::shift_start_in(int edit_mode,
344 int64_t cut_length = newposition - oldposition;
345 int64_t end_previous_source, end_source;
347 if(edit_mode == MOVE_ALL_EDITS)
349 if(cut_length < length)
351 edits->clear_recursive(oldposition,
360 edits->clear_recursive(oldposition,
361 startproject + length,
369 if(edit_mode == MOVE_ONE_EDIT)
371 // Paste silence and cut
372 //printf("Edit::shift_start_in 1\n");
375 Edit *new_edit = edits->create_edit();
376 new_edit->startproject = this->startproject;
377 new_edit->length = 0;
378 edits->insert_before(this,
381 //printf("Edit::shift_start_in 2 %p\n", previous);
383 end_previous_source = previous->get_source_end(previous->startsource + previous->length + cut_length);
384 if(end_previous_source > 0 &&
385 previous->startsource + previous->length + cut_length > end_previous_source)
386 cut_length = end_previous_source - previous->startsource - previous->length;
388 if(cut_length < length)
390 startproject += cut_length;
391 startsource += cut_length;
392 length -= cut_length;
393 previous->length += cut_length;
394 //printf("Edit::shift_start_in 2\n");
397 { // Clear entire edit
399 previous->length += cut_length;
400 for(Edit* current_edit = this; current_edit; current_edit = current_edit->next)
402 current_edit->startproject += cut_length;
404 edits->clear_recursive(oldposition + cut_length,
405 startproject + cut_length,
411 //printf("Edit::shift_start_in 3\n");
414 if(edit_mode == MOVE_NO_EDITS)
416 end_source = get_source_end(startsource + length + cut_length);
417 if(end_source > 0 && startsource + length + cut_length > end_source)
418 cut_length = end_source - startsource - length;
420 startsource += cut_length;
425 int Edit::shift_start_out(int edit_mode,
433 int64_t cut_length = oldposition - newposition;
437 int64_t end_source = get_source_end(1);
439 //printf("Edit::shift_start_out 1 %lld %lld\n", startsource, cut_length);
440 if(end_source > 0 && startsource < cut_length)
442 cut_length = startsource;
446 if(edit_mode == MOVE_ALL_EDITS)
448 //printf("Edit::shift_start_out 10 %lld\n", cut_length);
449 startsource -= cut_length;
450 length += cut_length;
452 edits->shift_keyframes_recursive(startproject,
455 edits->shift_effects_recursive(startproject,
458 for(Edit* current_edit = next; current_edit; current_edit = current_edit->next)
460 current_edit->startproject += cut_length;
464 if(edit_mode == MOVE_ONE_EDIT)
468 if(cut_length < previous->length)
469 { // Cut into previous edit
470 previous->length -= cut_length;
471 startproject -= cut_length;
472 startsource -= cut_length;
473 length += cut_length;
474 printf("Edit::shift_start_out 2\n");
477 { // Clear entire previous edit
478 cut_length = previous->length;
479 previous->length = 0;
480 length += cut_length;
481 startsource -= cut_length;
482 startproject -= cut_length;
487 if(edit_mode == MOVE_NO_EDITS)
489 startsource -= cut_length;
492 // Fix infinite length files
493 if(startsource < 0) startsource = 0;
497 int Edit::shift_end_in(int edit_mode,
505 int64_t cut_length = oldposition - newposition;
507 if(edit_mode == MOVE_ALL_EDITS)
509 //printf("Edit::shift_end_in 1\n");
510 if(newposition > startproject)
511 { // clear partial edit
512 //printf("Edit::shift_end_in %p %p\n", track->edits, edits);
513 edits->clear_recursive(newposition,
521 { // clear entire edit
522 edits->clear_recursive(startproject,
531 if(edit_mode == MOVE_ONE_EDIT)
537 int64_t end_source = next->get_source_end(1);
539 if(end_source > 0 && next->startsource - cut_length < 0)
541 cut_length = next->startsource;
545 if(cut_length < length)
547 length -= cut_length;
548 next->startproject -= cut_length;
549 next->startsource -= cut_length;
550 next->length += cut_length;
551 //printf("Edit::shift_end_in 2 %d\n", cut_length);
556 next->length += cut_length;
557 next->startsource -= cut_length;
558 next->startproject -= cut_length;
559 length -= cut_length;
564 if(cut_length < length)
566 length -= cut_length;
571 edits->clear_recursive(startproject,
581 // Does nothing for plugins
582 if(edit_mode == MOVE_NO_EDITS)
584 //printf("Edit::shift_end_in 3\n");
585 int64_t end_source = get_source_end(1);
586 if(end_source > 0 && startsource < cut_length)
588 cut_length = startsource;
590 startsource -= cut_length;
595 int Edit::shift_end_out(int edit_mode,
603 int64_t cut_length = newposition - oldposition;
604 int64_t endsource = get_source_end(startsource + length + cut_length);
606 // check end of edit against end of source file
607 if(endsource > 0 && startsource + length + cut_length > endsource)
608 cut_length = endsource - startsource - length;
610 //printf("Edit::shift_end_out 1 %lld %d %d %d\n", oldposition, newposition, this->length, cut_length);
611 if(edit_mode == MOVE_ALL_EDITS)
614 this->length += cut_length;
616 // Effects are shifted in length extension
618 edits->shift_effects_recursive(oldposition /* startproject */,
620 edits->shift_keyframes_recursive(oldposition /* startproject */,
623 for(Edit* current_edit = next; current_edit; current_edit = current_edit->next)
625 current_edit->startproject += cut_length;
629 if(edit_mode == MOVE_ONE_EDIT)
633 if(cut_length < next->length)
635 length += cut_length;
636 next->startproject += cut_length;
637 next->startsource += cut_length;
638 next->length -= cut_length;
639 //printf("Edit::shift_end_out 2 %d\n", cut_length);
643 cut_length = next->length;
645 length += cut_length;
650 length += cut_length;
654 if(edit_mode == MOVE_NO_EDITS)
656 startsource += cut_length;
689 int Edit::popup_transition(float view_start, float zoom_units, int cursor_x, int cursor_y)
691 int64_t left, right, left_unit, right_unit;
692 if(!transition) return 0;
693 get_handle_parameters(left, right, left_unit, right_unit, view_start, zoom_units);
695 if(cursor_x > left && cursor_x < right)
697 // transition->popup_transition(cursor_x, cursor_y);
703 int Edit::select_handle(float view_start, float zoom_units, int cursor_x, int cursor_y, int64_t &selection)
705 int64_t left, right, left_unit, right_unit;
706 get_handle_parameters(left, right, left_unit, right_unit, view_start, zoom_units);
708 int64_t pixel1, pixel2;
710 pixel2 = pixel1 + 10;
713 // cursor_x is faked in acanvas
714 if(cursor_x >= pixel1 && cursor_x <= pixel2)
716 selection = left_unit;
717 return 1; // left handle
720 int64_t endproject = startproject + length;
722 pixel1 = pixel2 - 10;
725 if(cursor_x >= pixel1 && cursor_x <= pixel2)
727 selection = right_unit;
728 return 2; // right handle