00001 #include "clip.h"
00002 #include "edl.h"
00003 #include "edlsession.h"
00004 #include "filexml.h"
00005 #include "labels.h"
00006 #include "mwindow.h"
00007 #include "mwindowgui.h"
00008 #include "patchbay.h"
00009 #include "recordlabel.h"
00010 #include "mainsession.h"
00011 #include "stringfile.h"
00012 #include "theme.h"
00013 #include "timebar.h"
00014 #include <string.h>
00015
00016
00017
00018 Labels::Labels(EDL *edl, char *xml_tag)
00019 : List<Label>()
00020 {
00021 this->edl = edl;
00022 this->xml_tag = xml_tag;
00023 }
00024
00025 Labels::~Labels()
00026 {
00027 delete_all();
00028 }
00029
00030 void Labels::dump()
00031 {
00032 for(Label *current = first; current; current = NEXT)
00033 {
00034 printf(" label: %f\n", current->position);
00035 }
00036 }
00037
00038 void Labels::insert_labels(Labels *labels, double start, double length, int paste_silence)
00039 {
00040 Label *new_label;
00041 Label *old_label;
00042
00043
00044
00045
00046
00047 if(paste_silence)
00048 {
00049 for(old_label = first; old_label; old_label = old_label->next)
00050 {
00051 if(old_label->position > start ||
00052 edl->equivalent(old_label->position, start))
00053 old_label->position += length;
00054 }
00055 }
00056
00057
00058
00059 for(new_label = labels->first; new_label; new_label = new_label->next)
00060 {
00061 int exists = 0;
00062
00063
00064
00065 for(old_label = first; old_label; old_label = old_label->next)
00066 {
00067 if(edl->equivalent(old_label->position, new_label->position + start))
00068 {
00069 exists = 1;
00070 break;
00071 }
00072 else
00073 if(old_label->position > new_label->position + start)
00074 break;
00075 }
00076
00077 if(!exists)
00078 {
00079 if(old_label)
00080 insert_before(old_label, new Label(edl, this, new_label->position + start));
00081 else
00082 append(new Label(edl, this, new_label->position + start));
00083 }
00084 }
00085 }
00086
00087 int Labels::toggle_label(double start, double end)
00088 {
00089 Label *current;
00090
00091
00092
00093
00094 for(current = first;
00095 current && current->position < start && !edl->equivalent(current->position, start);
00096 current = NEXT)
00097 {
00098
00099 ;
00100 }
00101
00102 if(current)
00103 {
00104
00105 if(edl->equivalent(current->position, start))
00106 {
00107
00108 remove(current);
00109 }
00110 else
00111 {
00112 current = insert_before(current, new Label(edl, this, start));
00113 }
00114 }
00115 else
00116 {
00117
00118 current = append(new Label(edl, this, start));
00119 }
00120
00121
00122 if(!EQUIV(start, end))
00123 {
00124
00125
00126 for(current = first;
00127 current && current->position < end && !edl->equivalent(current->position, end);
00128 current = NEXT)
00129 {
00130 ;
00131 }
00132
00133 if(current)
00134 {
00135 if(edl->equivalent(current->position, end))
00136 {
00137 remove(current);
00138 }
00139 else
00140 {
00141 current = insert_before(current, new Label(edl, this, end));
00142 }
00143 }
00144 else
00145 {
00146 current = append(new Label(edl, this, end));
00147 }
00148 }
00149 return 0;
00150 }
00151
00152 int Labels::delete_all()
00153 {
00154 while(last)
00155 remove(last);
00156 return 0;
00157 }
00158
00159 int Labels::copy(double start, double end, FileXML *xml)
00160 {
00161 char string[BCTEXTLEN];
00162 xml->tag.set_title(xml_tag);
00163 xml->append_tag();
00164 xml->append_newline();
00165
00166 Label *current;
00167 sprintf(string, xml_tag);
00168 string[strlen(string) - 1] = 0;
00169 for(current = label_of(start);
00170 current && current->position <= end;
00171 current = NEXT)
00172 {
00173 xml->tag.set_title(string);
00174 xml->tag.set_property("SAMPLE", (double)current->position - start);
00175
00176 xml->append_tag();
00177 }
00178
00179 sprintf(string, "/%s", xml_tag);
00180 xml->tag.set_title(string);
00181 xml->append_tag();
00182 xml->append_newline();
00183 xml->append_newline();
00184 return 0;
00185 }
00186
00187 int Labels::copy_length(long start, long end)
00188 {
00189 int result = 0;
00190 Label *current;
00191
00192 for(current = label_of(start); current && current->position <= end; current = NEXT)
00193 {
00194 result++;
00195 }
00196 return result;
00197 }
00198
00199 void Labels::copy_from(Labels *labels)
00200 {
00201 while(last) delete last;
00202
00203 for(Label *current = labels->first; current; current = NEXT)
00204 {
00205 append(new Label(edl, this, current->position));
00206 }
00207 }
00208
00209
00210 Labels& Labels::operator=(Labels &that)
00211 {
00212 copy_from(&that);
00213 printf("Labels::operator= 1\n");
00214 return *this;
00215 }
00216
00217
00218 int Labels::save(FileXML *xml)
00219 {
00220 xml->tag.set_title("LABELS");
00221 xml->append_tag();
00222 xml->append_newline();
00223
00224 Label *current;
00225
00226 for(current = first; current; current = NEXT)
00227 {
00228 xml->tag.set_title("LABEL");
00229 xml->tag.set_property("SAMPLE", (double)current->position);
00230 xml->append_tag();
00231 }
00232
00233 xml->append_newline();
00234 xml->tag.set_title("/LABELS");
00235 xml->append_tag();
00236 xml->append_newline();
00237 xml->append_newline();
00238 return 0;
00239 }
00240
00241 int Labels::load(FileXML *xml, uint32_t load_flags)
00242 {
00243 int result = 0;
00244 char string1[BCTEXTLEN], string2[BCTEXTLEN];
00245
00246 sprintf(string1, "/%s", xml_tag);
00247 strcpy(string2, xml_tag);
00248 string2[strlen(string2) - 1] = 0;
00249
00250 do{
00251 result = xml->read_tag();
00252 if(!result)
00253 {
00254 if(xml->tag.title_is(string1))
00255 {
00256 result = 1;
00257 }
00258 else
00259 if(xml->tag.title_is(string2))
00260 {
00261 double position = xml->tag.get_property("SAMPLE", (double)-1);
00262
00263 if(position > -1)
00264 {
00265 Label *current = label_of(position);
00266 current = insert_before(current, new Label(edl, this, position));
00267 }
00268 }
00269 else
00270 if(xml->tag.title_is("INPOINT"))
00271 {
00272 double position = xml->tag.get_property("SAMPLE", (double)-1);
00273 if(position > -1)
00274 {
00275 ;
00276 }
00277 }
00278 else
00279 if(xml->tag.title_is("OUTPOINT"))
00280 {
00281 double position = xml->tag.get_property("SAMPLE", (double)-1);
00282 if(position > -1)
00283 {
00284 ;
00285 }
00286 }
00287 }
00288 }while(!result);
00289 return 0;
00290 }
00291
00292
00293
00294 int Labels::clear(double start, double end, int follow)
00295 {
00296 Label *current;
00297 Label *next;
00298
00299
00300 current = label_of(start);
00301
00302
00303 while(current && current->position < end)
00304 {
00305 next = NEXT;
00306 delete current;
00307 current = next;
00308 }
00309
00310
00311 if(follow)
00312 {
00313 while(current)
00314 {
00315 current->position -= end - start;
00316 current = NEXT;
00317 }
00318
00319 optimize();
00320
00321 }
00322
00323 return 0;
00324 }
00325
00326
00327 Label* Labels::prev_label(double position)
00328 {
00329 Label *current;
00330
00331
00332 for(current = first;
00333 current && !edl->equivalent(current->position, position);
00334 current = NEXT)
00335 ;
00336
00337
00338 if(!current)
00339 for(current = first;
00340 current && current->position < position;
00341 current = NEXT)
00342 ;
00343
00344
00345 if(!current)
00346 current = last;
00347 else
00348
00349 current = PREVIOUS;
00350
00351 return current;
00352 }
00353
00354 Label* Labels::next_label(double position)
00355 {
00356 Label *current;
00357
00358
00359 for(current = first;
00360 current && !edl->equivalent(current->position, position);
00361 current = NEXT)
00362 ;
00363
00364
00365 if(!current)
00366 for(current = last;
00367 current && current->position > position;
00368 current = PREVIOUS)
00369 ;
00370
00371
00372 if(!current)
00373 current = first;
00374 else
00375
00376 current = NEXT;
00377
00378 return current;
00379 }
00380
00381 int Labels::insert(double start, double length)
00382 {
00383 Label *current;
00384
00385 for(current = label_of(start); current; current = NEXT)
00386 {
00387 current->position += length;
00388 }
00389 return 0;
00390 }
00391
00392 int Labels::paste_silence(double start, double end)
00393 {
00394 insert(start, end - start);
00395 optimize();
00396 return 0;
00397 }
00398
00399 int Labels::modify_handles(double oldposition,
00400 double newposition,
00401 int currentend,
00402 int handle_mode,
00403 int edit_labels)
00404 {
00405 if(edit_labels &&
00406 handle_mode == MOVE_ALL_EDITS)
00407 {
00408 if(currentend == 0)
00409 {
00410 if(newposition < oldposition)
00411 {
00412 insert(oldposition, oldposition - newposition);
00413 }
00414 else
00415 {
00416 clear(oldposition, newposition);
00417 }
00418 }
00419 else
00420 {
00421 if(newposition < oldposition)
00422 {
00423 clear(newposition, oldposition);
00424 }
00425 else
00426 {
00427 insert(oldposition, newposition - oldposition);
00428 }
00429 }
00430 }
00431 return 0;
00432 }
00433
00434 int Labels::optimize()
00435 {
00436 int result = 1;
00437 Label *current;
00438
00439 while(result)
00440 {
00441 result = 0;
00442
00443 for(current = first; current && NEXT && !result;)
00444 {
00445 Label *next = NEXT;
00446 if(current->position == next->position)
00447 {
00448 delete current;
00449 result = 1;
00450 }
00451 current = next;
00452 }
00453 }
00454 return 0;
00455 }
00456
00457 Label* Labels::label_of(double position)
00458 {
00459 Label *current;
00460
00461 for(current = first; current; current = NEXT)
00462 {
00463 if(current->position >= position) return current;
00464 }
00465 return 0;
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 Label::Label()
00478 : ListItem<Label>()
00479 {
00480 }
00481
00482 Label::Label(EDL *edl, Labels *labels, double position)
00483 : ListItem<Label>()
00484 {
00485 this->edl = edl;
00486 this->labels = labels;
00487 this->position = position;
00488 }
00489
00490
00491 Label::~Label()
00492 {
00493
00494 }
00495
00496 LabelToggle::LabelToggle(MWindow *mwindow,
00497 Label *label,
00498 int x,
00499 int y,
00500 long position)
00501 : BC_Label(x, y, 0)
00502 {
00503 this->mwindow = mwindow;
00504 this->label = label;
00505 }
00506
00507 LabelToggle::~LabelToggle() { }
00508
00509 int LabelToggle::handle_event()
00510 {
00511 return 0;
00512 }
00513