r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / labels.C
bloba11287455a66e653dd51eec7c0c5eb285acd74c0
1 #include "clip.h"
2 #include "edl.h"
3 #include "edlsession.h"
4 #include "filexml.h"
5 #include "labels.h"
6 #include "mwindow.h"
7 #include "mwindowgui.h"
8 #include "patchbay.h"
9 #include "recordlabel.h"
10 #include "mainsession.h"
11 #include "stringfile.h"
12 #include "theme.h"
13 #include "timebar.h"
14 #include <string.h>
18 Labels::Labels(EDL *edl, char *xml_tag)
19  : List<Label>()
21         this->edl = edl;
22         this->xml_tag = xml_tag;
25 Labels::~Labels()
27         delete_all();
30 void Labels::dump()
32         for(Label *current = first; current; current = NEXT)
33         {
34                 printf("  label: %f\n", current->position);
35         }
38 void Labels::insert_labels(Labels *labels, double start, double length, int paste_silence)
40         Label *new_label;
41         Label *old_label;
44 //printf("Labels::insert_labels 1 %f\n", start);
46 // Insert silence in old labels
47         if(paste_silence)
48         {
49                 for(old_label = first; old_label; old_label = old_label->next)
50                 {
51                         if(old_label->position > start ||
52                                 edl->equivalent(old_label->position, start))
53                                 old_label->position += length;
54                 }
55         }
58 // Insert one new label at a time
59         for(new_label = labels->first; new_label; new_label = new_label->next)
60         {
61                 int exists = 0;
62 //printf("Labels::insert_labels 2 %f\n", new_label->position + start);
64 // Check every old label for existence
65                 for(old_label = first; old_label; old_label = old_label->next)
66                 {
67                         if(edl->equivalent(old_label->position, new_label->position + start))
68                         {
69                                 exists = 1;
70                                 break;
71                         }
72                         else
73                         if(old_label->position > new_label->position + start)
74                                 break;
75                 }
77                 if(!exists)
78                 {
79                         if(old_label)
80                                 insert_before(old_label, new Label(edl, this, new_label->position + start));
81                         else
82                                 append(new Label(edl, this, new_label->position + start));
83                 }
84         }
87 int Labels::toggle_label(double start, double end)
89         Label *current;
90 //printf("Labels::toggle_label 1 %f %f\n", start, end);
92 // handle selection start
93 // find label the selectionstart is after
94         for(current = first; 
95                 current && current->position < start && !edl->equivalent(current->position, start); 
96                 current = NEXT)
97         {
98 //printf("Labels::toggle_label 2 %f %f %f\n", start, end, current->position);
99                 ;
100         }
102         if(current)
103         {
104 //printf("Labels::toggle_label 3 %f %f %f\n", start, end, current->position);
105                 if(edl->equivalent(current->position, start))
106                 {        // remove it
107 //printf("Labels::toggle_label 1\n");
108                         remove(current);
109                 }
110                 else
111                 {        // insert before it
112                         current = insert_before(current, new Label(edl, this, start));
113                 }
114         }
115         else
116         {           // insert after last
117 //printf("Labels::toggle_label 1\n");
118                 current = append(new Label(edl, this, start));
119         }
121 // handle selection end
122         if(!EQUIV(start, end))
123         {
124 //printf("Labels::toggle_label 2 %.16e %.16e\n", start, end);
125 // find label the selectionend is after
126                 for(current = first; 
127                         current && current->position < end && !edl->equivalent(current->position, end); 
128                         current = NEXT)
129                 {
130                         ;
131                 }
133                 if(current)
134                 {
135                         if(edl->equivalent(current->position, end))
136                         {
137                                 remove(current);
138                         }
139                         else
140                         {
141                                 current = insert_before(current, new Label(edl, this, end));
142                         }
143                 }
144                 else
145                 {
146                         current = append(new Label(edl, this, end));
147                 }
148         }
149         return 0;
152 int Labels::delete_all()
154         while(last)
155                 remove(last);
156         return 0;
159 int Labels::copy(double start, double end, FileXML *xml)
161         char string[BCTEXTLEN];
162         xml->tag.set_title(xml_tag);
163         xml->append_tag();
164         xml->append_newline();
166         Label *current;
167         sprintf(string, xml_tag);
168         string[strlen(string) - 1] = 0;
169         for(current = label_of(start); 
170                 current && current->position <= end; 
171                 current = NEXT)
172         {
173                 xml->tag.set_title(string);
174                 xml->tag.set_property("SAMPLE", (double)current->position - start);
175 //printf("Labels::copy %f\n", current->position - start);
176                 xml->append_tag();
177         }
178         
179         sprintf(string, "/%s", xml_tag);
180         xml->tag.set_title(string);
181         xml->append_tag();
182         xml->append_newline();
183         xml->append_newline();
184         return 0;
187 int Labels::copy_length(long start, long end) // return number of Labels in selection
189         int result = 0;
190         Label *current;
191         
192         for(current = label_of(start); current && current->position <= end; current = NEXT)
193         {
194                 result++;
195         }
196         return result;
201 Labels& Labels::operator=(Labels &that)
203         while(last) delete last;
205         for(Label *current = that.first; current; current = NEXT)
206         {
207                 append(new Label(edl, this, current->position));
208         }
210         return *this;
214 int Labels::save(FileXML *xml)
216         xml->tag.set_title("LABELS");
217         xml->append_tag();
218         xml->append_newline();
220         Label *current;
222         for(current = first; current; current = NEXT)
223         {
224                 xml->tag.set_title("LABEL");
225                 xml->tag.set_property("SAMPLE", (double)current->position);
226                 xml->append_tag();
227         }
228         
229         xml->append_newline();
230         xml->tag.set_title("/LABELS");
231         xml->append_tag();
232         xml->append_newline();
233         xml->append_newline();
234         return 0;
237 int Labels::load(FileXML *xml, uint32_t load_flags)
239         int result = 0;
240         char string1[BCTEXTLEN], string2[BCTEXTLEN];
242         sprintf(string1, "/%s", xml_tag);
243         strcpy(string2, xml_tag);
244         string2[strlen(string2) - 1] = 0;
246         do{
247                 result = xml->read_tag();
248                 if(!result)
249                 {
250                         if(xml->tag.title_is(string1))
251                         {
252                                 result = 1;
253                         }
254                         else
255                         if(xml->tag.title_is(string2))
256                         {
257                                 double position = xml->tag.get_property("SAMPLE", (double)-1);
258 //printf("Labels::load %f\n", position);
259                                 if(position > -1)
260                                 {
261                                         Label *current = label_of(position);
262                                         current = insert_before(current, new Label(edl, this, position));
263                                 }
264                         }
265                         else
266                         if(xml->tag.title_is("INPOINT"))
267                         {
268                                 double position = xml->tag.get_property("SAMPLE", (double)-1);
269                                 if(position > -1)
270                                 {
271                                         ;
272                                 }
273                         }
274                         else
275                         if(xml->tag.title_is("OUTPOINT"))
276                         {
277                                 double position = xml->tag.get_property("SAMPLE", (double)-1);
278                                 if(position > -1)
279                                 {
280                                         ;
281                                 }
282                         }
283                 }
284         }while(!result);
285         return 0;
290 int Labels::clear(double start, double end, int follow)
292         Label *current;
293         Label *next;
295 //printf("Labels::clear 1\n");
296         current = label_of(start);
297 //printf("Labels::clear 2\n");
298 // remove selected labels
299         while(current && current->position < end)
300         {
301                 next = NEXT;
302                 delete current;              
303                 current = next;
304         }
305 // Shift later labels
306 //printf("Labels::clear 3\n");
307         if(follow)
308         {
309                 while(current)
310                 {
311                         current->position -= end - start;   // shift labels forward
312                         current = NEXT;
313                 }
314 //printf("Labels::clear 4\n");
315                 optimize();
316 //printf("Labels::clear 5\n");
317         }
319         return 0;
323 Label* Labels::prev_label(double position)
325         Label *current;
327 // Test for label under cursor position
328         for(current = first; 
329                 current && !edl->equivalent(current->position, position); 
330                 current = NEXT)
331                 ;
333 // Test for label after cursor position
334         if(!current)
335                 for(current = first;
336                         current && current->position < position;
337                         current = NEXT)
338                         ;
340 // Test for label before cursor position
341         if(!current) 
342                 current = last;
343         else
344 // Get previous label
345                 current = PREVIOUS;
347         return current;
350 Label* Labels::next_label(double position)
352         Label *current;
354 // Test for label under cursor position
355         for(current = first; 
356                 current && !edl->equivalent(current->position, position); 
357                 current = NEXT)
358                 ;
360 // Test for label before cursor position
361         if(!current)
362                 for(current = last;
363                         current && current->position > position;
364                         current = PREVIOUS)
365                         ;
367 // Test for label after cursor position
368         if(!current)
369                 current = first;
370         else
371 // Get next label
372                 current = NEXT;
374         return current;
377 int Labels::insert(double start, double length)
378 {      // shift every label including the first one back
379         Label *current;
381         for(current = label_of(start); current; current = NEXT)
382         {
383                 current->position += length;
384         }
385         return 0;
388 int Labels::paste_silence(double start, double end)
390         insert(start, end - start);
391         optimize();
392         return 0;
395 int Labels::modify_handles(double oldposition, 
396         double newposition, 
397         int currentend, 
398         int handle_mode,
399         int edit_labels)
401         if(edit_labels &&
402                 handle_mode == MOVE_ALL_EDITS)
403         {
404                 if(currentend == 0)          // left handle
405                 {
406                         if(newposition < oldposition)
407                         {
408                                 insert(oldposition, oldposition - newposition);    // shift all labels right
409                         }
410                         else
411                         {
412                                 clear(oldposition, newposition);   // clear selection
413                         }
414                 }
415                 else
416                 {                            // right handle
417                         if(newposition < oldposition)
418                         {
419                                 clear(newposition, oldposition);
420                         }
421                         else
422                         {
423                                 insert(oldposition, newposition - oldposition);
424                         }
425                 }
426         }
427         return 0;
430 int Labels::optimize()
432         int result = 1;
433         Label *current;
435         while(result)
436         {
437                 result = 0;
438                 
439                 for(current = first; current && NEXT && !result;)
440                 {
441                         Label *next = NEXT;
442                         if(current->position == next->position)
443                         {
444                                 delete current;
445                                 result  = 1;
446                         }
447                         current = next;
448                 }
449         }
450         return 0;
453 Label* Labels::label_of(double position)
455         Label *current;
457         for(current = first; current; current = NEXT)
458         {
459                 if(current->position >= position) return current;
460         }
461         return 0;
473 Label::Label()
474  : ListItem<Label>()
478 Label::Label(EDL *edl, Labels *labels, double position)
479  : ListItem<Label>()
481         this->edl = edl;
482         this->labels = labels;
483         this->position = position;
487 Label::~Label()
489 //      if(toggle) delete toggle;
492 LabelToggle::LabelToggle(MWindow *mwindow, 
493         Label *label, 
494         int x, 
495         int y, 
496         long position)
497  : BC_Label(x, y, 0)
499         this->mwindow = mwindow;
500         this->label = label;
503 LabelToggle::~LabelToggle() { }
505 int LabelToggle::handle_event()
507         return 0;