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"
38 Labels::Labels(EDL *edl, const char *xml_tag)
42 this->xml_tag = xml_tag;
50 void Labels::dump(FILE *fp)
52 for(Label *current = first; current; current = NEXT)
54 fprintf(fp, " label: %f '%s'\n", current->position, current->textstr);
58 void Labels::insert_labels(Labels *labels, double start, double length, int paste_silence)
64 //printf("Labels::insert_labels 1 %f\n", start);
66 // Insert silence in old labels
69 for(old_label = first; old_label; old_label = old_label->next)
71 if(old_label->position > start ||
72 edl->equivalent(old_label->position, start))
73 old_label->position += length;
78 // Insert one new label at a time
79 for(new_label = labels->first; new_label; new_label = new_label->next)
82 //printf("Labels::insert_labels 2 %f\n", new_label->position + start);
84 // Check every old label for existence
85 for(old_label = first; old_label; old_label = old_label->next)
87 if(edl->equivalent(old_label->position, new_label->position + start))
93 if(old_label->position > new_label->position + start)
100 insert_before(old_label, new Label(edl, this, new_label->position + start, new_label->textstr));
102 append(new Label(edl, this, new_label->position + start, new_label->textstr));
108 void Labels::insert_label(double position)
111 Label *old_label = 0;
113 // Check every old label for existence
114 for(old_label = first; old_label; old_label = old_label->next)
116 if(edl->equivalent(old_label->position, position))
122 if(old_label->position > position)
129 insert_before(old_label, new Label(edl, this, position));
131 append(new Label(edl, this, position));
136 int Labels::toggle_label(double start, double end)
139 //printf("Labels::toggle_label 1 %f %f\n", start, end);
141 // handle selection start
142 // find label the selectionstart is after
144 current && current->position < start && !edl->equivalent(current->position, start);
147 //printf("Labels::toggle_label 2 %f %f %f\n", start, end, current->position);
153 //printf("Labels::toggle_label 3 %f %f %f\n", start, end, current->position);
154 if(edl->equivalent(current->position, start))
156 //printf("Labels::toggle_label 1\n");
160 { // insert before it
161 current = insert_before(current, new Label(edl, this, start, ""));
165 { // insert after last
166 //printf("Labels::toggle_label 1\n");
167 current = append(new Label(edl, this, start, ""));
170 // handle selection end
171 if(!EQUIV(start, end))
173 //printf("Labels::toggle_label 2 %.16e %.16e\n", start, end);
174 // find label the selectionend is after
176 current && current->position < end && !edl->equivalent(current->position, end);
184 if(edl->equivalent(current->position, end))
190 current = insert_before(current, new Label(edl, this, end, ""));
195 current = append(new Label(edl, this, end, ""));
201 Label *Labels::add_label(double position)
205 current && current->position < position;
208 if( edl->equivalent(current->position, position) ) return 0;
213 current = insert_before(current, new Label(edl, this, position));
217 current = append(new Label(edl, this, position));
222 int Labels::delete_all()
229 int Labels::copy(double start, double end, FileXML *xml)
231 xml->tag.set_title("LABELS");
233 xml->append_newline();
236 for(current = label_of(start);
237 current && current->position <= end;
240 xml->tag.set_title("LABEL");
241 xml->tag.set_property("TIME", (double)current->position - start);
242 xml->tag.set_property("TEXTSTR", current->textstr);
243 //printf("Labels::copy %f\n", current->position - start);
245 xml->tag.set_title("/LABEL");
247 xml->append_newline();
250 xml->tag.set_title("/LABELS");
252 xml->append_newline();
253 xml->append_newline();
257 int Labels::copy_length(long start, long end) // return number of Labels in selection
262 for(current = label_of(start); current && current->position <= end; current = NEXT)
269 void Labels::copy_from(Labels *labels)
271 while(last) delete last;
273 for(Label *current = labels->first; current; current = NEXT)
275 Label *new_label = new Label(edl, this, current->position, current->textstr);
276 new_label->orig_id = current->orig_id;
282 Labels& Labels::operator=(Labels &that)
285 printf("Labels::operator= 1\n");
290 int Labels::save(FileXML *xml)
291 // Note: Normally the saving of Labels is done by Labels::copy()
293 xml->tag.set_title("LABELS");
295 xml->append_newline();
299 for(current = first; current; current = NEXT)
301 xml->tag.set_title("LABEL");
302 xml->tag.set_property("TIME", (double)current->position);
303 xml->tag.set_property("TEXTSTR", current->textstr);
305 xml->tag.set_title("/LABEL");
307 xml->append_newline();
310 xml->append_newline();
311 xml->tag.set_title("/LABELS");
313 xml->append_newline();
314 xml->append_newline();
318 int Labels::load(FileXML *xml, uint32_t load_flags)
321 char string1[BCTEXTLEN], string2[BCTEXTLEN];
323 sprintf(string1, "/%s", xml_tag);
324 strcpy(string2, xml_tag);
325 string2[strlen(string2) - 1] = 0;
328 result = xml->read_tag();
331 if(xml->tag.title_is(string1))
336 if(xml->tag.title_is(string2))
338 double position = xml->tag.get_property("TIME", (double)-1);
340 position = xml->tag.get_property("SAMPLE", (double)-1);
341 //printf("Labels::load %f\n", position);
344 Label *current = label_of(position);
345 current = insert_before(current, new Label(edl, this, position, ""));
346 xml->tag.get_property("TEXTSTR", current->textstr);
350 if(xml->tag.title_is("INPOINT"))
352 double position = xml->tag.get_property("TIME", (double)-1);
354 position = xml->tag.get_property("SAMPLE", (double)-1);
361 if(xml->tag.title_is("OUTPOINT"))
363 double position = xml->tag.get_property("TIME", (double)-1);
365 position = xml->tag.get_property("SAMPLE", (double)-1);
378 int Labels::clear(double start, double end, int follow)
383 //printf("Labels::clear 1\n");
384 current = label_of(start);
385 //printf("Labels::clear 2\n");
386 // remove selected labels
387 while(current && current->position < end)
393 // Shift later labels
394 //printf("Labels::clear 3\n");
399 current->position -= end - start; // shift labels forward
402 //printf("Labels::clear 4\n");
404 //printf("Labels::clear 5\n");
411 Label* Labels::prev_label(double position)
415 // Test for label under cursor position
417 current && !edl->equivalent(current->position, position);
421 // Test for label after cursor position
424 current && current->position < position;
428 // Test for label before cursor position
432 // Get previous label
438 Label* Labels::next_label(double position)
442 // Test for label under cursor position
444 current && !edl->equivalent(current->position, position);
448 // Test for label before cursor position
451 current && current->position > position;
455 // Test for label after cursor position
465 Label* Labels::get_label(int id)
467 Label *current = first;
468 while( current && current->orig_id != id ) current = NEXT;
472 int Labels::insert(double start, double length)
473 { // shift every label including the first one back
476 for(current = label_of(start); current; current = NEXT)
478 current->position += length;
483 int Labels::paste_silence(double start, double end)
485 insert(start, end - start);
490 int Labels::modify_handles(double oldposition, double newposition, int currentend)
492 if( !currentend ) { // left handle
493 if( newposition < oldposition )
494 insert(oldposition, oldposition - newposition); // shift all labels right
496 clear(oldposition, newposition); // clear selection
498 else { // right handle
499 if( newposition < oldposition )
500 clear(newposition, oldposition);
502 insert(oldposition, newposition - oldposition);
507 int Labels::optimize()
516 for(current = first; current && NEXT && !result;)
519 if(current->position == next->position)
530 Label* Labels::label_of(double position)
534 for(current = first; current; current = NEXT)
536 if(current->position >= position) return current;
557 Label::Label(EDL *edl, Labels *labels, double position, const char *textstr)
561 this->labels = labels;
562 this->position = position;
563 strcpy(this->textstr, textstr ? textstr : "");
571 // if(toggle) delete toggle;
574 LabelToggle::LabelToggle(MWindow *mwindow,
581 this->mwindow = mwindow;
585 LabelToggle::~LabelToggle() { }
587 int LabelToggle::handle_event()