4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
24 #include "edlsession.h"
28 #include "mwindowgui.h"
30 #include "recordlabel.h"
31 #include "mainsession.h"
32 #include "stringfile.h"
39 Labels::Labels(EDL *edl, const char *xml_tag)
43 this->xml_tag = (char*)xml_tag;
51 void Labels::dump(FILE *fp)
53 for(Label *current = first; current; current = NEXT)
55 fprintf(fp," label: %f\n", current->position);
59 void Labels::insert_labels(Labels *labels, double start, double length, int paste_silence)
65 //printf("Labels::insert_labels 1 %d %d\n", __LINE__, paste_silence);
67 // Insert silence in old labels
70 for(old_label = first; old_label; old_label = old_label->next)
72 if(old_label->position > start ||
73 edl->equivalent(old_label->position, start))
74 old_label->position += length;
79 // Insert one new label at a time
80 for(new_label = labels->first; new_label; new_label = new_label->next)
83 //printf("Labels::insert_labels 2 %f\n", new_label->position + start);
85 // Check every old label for existence
86 for(old_label = first; old_label; old_label = old_label->next)
88 if(edl->equivalent(old_label->position, new_label->position + start))
94 if(old_label->position > new_label->position + start)
101 insert_before(old_label, new Label(edl, this, new_label->position + start));
103 append(new Label(edl, this, new_label->position + start));
109 void Labels::insert_label(double position)
112 Label *old_label = 0;
114 // Check every old label for existence
115 for(old_label = first; old_label; old_label = old_label->next)
117 if(edl->equivalent(old_label->position, position))
123 if(old_label->position > position)
130 insert_before(old_label, new Label(edl, this, position));
132 append(new Label(edl, this, position));
137 int Labels::toggle_label(double start, double end)
140 //printf("Labels::toggle_label 1 %f %f\n", start, end);
142 // handle selection start
143 // find label the selectionstart is after
145 current && current->position < start && !edl->equivalent(current->position, start);
148 //printf("Labels::toggle_label 2 %f %f %f\n", start, end, current->position);
154 //printf("Labels::toggle_label 3 %f %f %f\n", start, end, current->position);
155 if(edl->equivalent(current->position, start))
157 //printf("Labels::toggle_label 1\n");
161 { // insert before it
162 current = insert_before(current, new Label(edl, this, start));
166 { // insert after last
167 //printf("Labels::toggle_label 1\n");
168 current = append(new Label(edl, this, start));
171 // handle selection end
172 if(!EQUIV(start, end))
174 //printf("Labels::toggle_label 2 %.16e %.16e\n", start, end);
175 // find label the selectionend is after
177 current && current->position < end && !edl->equivalent(current->position, end);
185 if(edl->equivalent(current->position, end))
191 current = insert_before(current, new Label(edl, this, end));
196 current = append(new Label(edl, this, end));
202 Label *Labels::add_label(double position)
206 current && current->position < position;
209 if( edl->equivalent(current->position, position) ) return 0;
214 current = insert_before(current, new Label(edl, this, position));
218 current = append(new Label(edl, this, position));
223 int Labels::delete_all()
230 int Labels::copy(double start, double end, FileXML *xml)
232 char string[BCTEXTLEN];
233 xml->tag.set_title(xml_tag);
235 xml->append_newline();
238 strcpy(string, xml_tag);
239 string[strlen(string) - 1] = 0;
240 for(current = label_of(start);
241 current && current->position <= end;
244 xml->tag.set_title(string);
245 xml->tag.set_property("TIME", (double)current->position - start);
246 //printf("Labels::copy %f\n", current->position - start);
250 sprintf(string, "/%s", xml_tag);
251 xml->tag.set_title(string);
253 xml->append_newline();
254 xml->append_newline();
258 int Labels::copy_length(long start, long end) // return number of Labels in selection
263 for(current = label_of(start); current && current->position <= end; current = NEXT)
270 void Labels::copy_from(Labels *labels)
272 while(last) delete last;
274 for(Label *current = labels->first; current; current = NEXT)
276 append(new Label(edl, this, current->position));
281 Labels& Labels::operator=(Labels &that)
284 printf("Labels::operator= 1\n");
289 int Labels::save(FileXML *xml)
291 xml->tag.set_title("LABELS");
293 xml->append_newline();
297 for(current = first; current; current = NEXT)
299 xml->tag.set_title("LABEL");
300 xml->tag.set_property("TIME", (double)current->position);
304 xml->append_newline();
305 xml->tag.set_title("/LABELS");
307 xml->append_newline();
308 xml->append_newline();
312 int Labels::load(FileXML *xml, uint32_t load_flags)
315 char string1[BCTEXTLEN], string2[BCTEXTLEN];
317 sprintf(string1, "/%s", xml_tag);
318 strcpy(string2, xml_tag);
319 string2[strlen(string2) - 1] = 0;
322 result = xml->read_tag();
325 if(xml->tag.title_is(string1))
330 if(xml->tag.title_is(string2))
332 double position = xml->tag.get_property("TIME", (double)-1);
334 position = xml->tag.get_property("SAMPLE", (double)-1);
335 //printf("Labels::load %f\n", position);
338 Label *current = label_of(position);
339 current = insert_before(current, new Label(edl, this, position));
343 if(xml->tag.title_is("INPOINT"))
345 double position = xml->tag.get_property("TIME", (double)-1);
347 position = xml->tag.get_property("SAMPLE", (double)-1);
354 if(xml->tag.title_is("OUTPOINT"))
356 double position = xml->tag.get_property("TIME", (double)-1);
358 position = xml->tag.get_property("SAMPLE", (double)-1);
371 int Labels::clear(double start, double end, int follow)
376 //printf("Labels::clear 1\n");
377 current = label_of(start);
378 //printf("Labels::clear 2\n");
380 // remove selected labels
381 while(current && current->position < end)
388 // Shift later labels
393 //printf("Labels::clear %d %f %f\n", __LINE__, current->position, end - start);
394 current->position -= end - start; // shift labels forward
395 //printf("Labels::clear %d %f %f\n", __LINE__, current->position, end - start);
398 //printf("Labels::clear 4\n");
400 //printf("Labels::clear 5\n");
407 Label* Labels::prev_label(double position)
411 // Test for label under cursor position
413 current && !edl->equivalent(current->position, position);
417 // Test for label after cursor position
420 current && current->position < position;
424 // Test for label before cursor position
428 // Get previous label
434 Label* Labels::next_label(double position)
438 // Test for label under cursor position
440 current && !edl->equivalent(current->position, position);
444 // Test for label before cursor position
447 current && current->position > position;
451 // Test for label after cursor position
461 int Labels::insert(double start, double length)
463 // shift every label including the first one back
466 //printf("Labels::insert %d\n", __LINE__);
467 for(current = label_of(start); current; current = NEXT)
469 current->position += length;
474 int Labels::paste_silence(double start, double end)
476 insert(start, end - start);
481 int Labels::modify_handles(double oldposition,
488 handle_mode == MOVE_ALL_EDITS)
490 if(currentend == 0) // left handle
492 if(newposition < oldposition)
494 insert(oldposition, oldposition - newposition); // shift all labels right
498 clear(oldposition, newposition); // clear selection
503 if(newposition < oldposition)
505 clear(newposition, oldposition);
509 insert(oldposition, newposition - oldposition);
516 int Labels::optimize()
525 for(current = first; current && NEXT && !result;)
528 if(current->position == next->position)
539 Label* Labels::label_of(double position)
543 for(current = first; current; current = NEXT)
545 if(current->position >= position) return current;
564 Label::Label(EDL *edl, Labels *labels, double position)
568 this->labels = labels;
569 this->position = position;
575 // if(toggle) delete toggle;
578 LabelToggle::LabelToggle(MWindow *mwindow,
585 this->mwindow = mwindow;
589 LabelToggle::~LabelToggle() { }
591 int LabelToggle::handle_event()