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 '%s'\n", current->position, current->textstr);
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, new_label->textstr));
00081 else
00082 append(new Label(edl, this, new_label->position + start, new_label->textstr));
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, "/%s", 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+1);
00174 xml->tag.set_property("TIME", (double)current->position - start);
00175 xml->tag.set_property("TEXTSTR", current->textstr);
00176
00177 xml->append_tag();
00178 xml->tag.set_title(string);
00179 xml->append_tag();
00180 xml->append_newline();
00181 }
00182
00183 sprintf(string, "/%s", xml_tag);
00184 xml->tag.set_title(string);
00185 xml->append_tag();
00186 xml->append_newline();
00187 xml->append_newline();
00188 return 0;
00189 }
00190
00191 int Labels::copy_length(long start, long end)
00192 {
00193 int result = 0;
00194 Label *current;
00195
00196 for(current = label_of(start); current && current->position <= end; current = NEXT)
00197 {
00198 result++;
00199 }
00200 return result;
00201 }
00202
00203 void Labels::copy_from(Labels *labels)
00204 {
00205 while(last) delete last;
00206
00207 for(Label *current = labels->first; current; current = NEXT)
00208 {
00209 append(new Label(edl, this, current->position, current->textstr));
00210 }
00211 }
00212
00213
00214 Labels& Labels::operator=(Labels &that)
00215 {
00216 copy_from(&that);
00217 printf("Labels::operator= 1\n");
00218 return *this;
00219 }
00220
00221
00222 int Labels::save(FileXML *xml)
00223
00224 {
00225 xml->tag.set_title("LABELS");
00226 xml->append_tag();
00227 xml->append_newline();
00228
00229 Label *current;
00230
00231 for(current = first; current; current = NEXT)
00232 {
00233 xml->tag.set_title("LABEL");
00234 xml->tag.set_property("TIME", (double)current->position);
00235 xml->tag.set_property("TEXTSTR", current->textstr);
00236 xml->append_tag();
00237 xml->tag.set_title("/LABEL");
00238 xml->append_tag();
00239 xml->append_newline();
00240 }
00241
00242 xml->append_newline();
00243 xml->tag.set_title("/LABELS");
00244 xml->append_tag();
00245 xml->append_newline();
00246 xml->append_newline();
00247 return 0;
00248 }
00249
00250 int Labels::load(FileXML *xml, uint32_t load_flags)
00251 {
00252 int result = 0;
00253 char string1[BCTEXTLEN], string2[BCTEXTLEN];
00254
00255 sprintf(string1, "/%s", xml_tag);
00256 strcpy(string2, xml_tag);
00257 string2[strlen(string2) - 1] = 0;
00258
00259 do{
00260 result = xml->read_tag();
00261 if(!result)
00262 {
00263 if(xml->tag.title_is(string1))
00264 {
00265 result = 1;
00266 }
00267 else
00268 if(xml->tag.title_is(string2))
00269 {
00270 double position = xml->tag.get_property("TIME", (double)-1);
00271 if(position < 0)
00272 position = xml->tag.get_property("SAMPLE", (double)-1);
00273
00274 if(position > -1)
00275 {
00276 Label *current = label_of(position);
00277 current = insert_before(current, new Label(edl, this, position, ""));
00278 xml->tag.get_property("TEXTSTR", current->textstr);
00279 }
00280 }
00281 else
00282 if(xml->tag.title_is("INPOINT"))
00283 {
00284 double position = xml->tag.get_property("TIME", (double)-1);
00285 if(position < 0)
00286 position = xml->tag.get_property("SAMPLE", (double)-1);
00287 if(position > -1)
00288 {
00289 ;
00290 }
00291 }
00292 else
00293 if(xml->tag.title_is("OUTPOINT"))
00294 {
00295 double position = xml->tag.get_property("TIME", (double)-1);
00296 if(position < 0)
00297 position = xml->tag.get_property("SAMPLE", (double)-1);
00298 if(position > -1)
00299 {
00300 ;
00301 }
00302 }
00303 }
00304 }while(!result);
00305 return 0;
00306 }
00307
00308
00309
00310 int Labels::clear(double start, double end, int follow)
00311 {
00312 Label *current;
00313 Label *next;
00314
00315
00316 current = label_of(start);
00317
00318
00319 while(current && current->position < end)
00320 {
00321 next = NEXT;
00322 delete current;
00323 current = next;
00324 }
00325
00326
00327 if(follow)
00328 {
00329 while(current)
00330 {
00331 current->position -= end - start;
00332 current = NEXT;
00333 }
00334
00335 optimize();
00336
00337 }
00338
00339 return 0;
00340 }
00341
00342
00343 Label* Labels::prev_label(double position)
00344 {
00345 Label *current;
00346
00347
00348 for(current = first;
00349 current && !edl->equivalent(current->position, position);
00350 current = NEXT)
00351 ;
00352
00353
00354 if(!current)
00355 for(current = first;
00356 current && current->position < position;
00357 current = NEXT)
00358 ;
00359
00360
00361 if(!current)
00362 current = last;
00363 else
00364
00365 current = PREVIOUS;
00366
00367 return current;
00368 }
00369
00370 Label* Labels::next_label(double position)
00371 {
00372 Label *current;
00373
00374
00375 for(current = first;
00376 current && !edl->equivalent(current->position, position);
00377 current = NEXT)
00378 ;
00379
00380
00381 if(!current)
00382 for(current = last;
00383 current && current->position > position;
00384 current = PREVIOUS)
00385 ;
00386
00387
00388 if(!current)
00389 current = first;
00390 else
00391
00392 current = NEXT;
00393
00394 return current;
00395 }
00396
00397 int Labels::insert(double start, double length)
00398 {
00399 Label *current;
00400
00401 for(current = label_of(start); current; current = NEXT)
00402 {
00403 current->position += length;
00404 }
00405 return 0;
00406 }
00407
00408 int Labels::paste_silence(double start, double end)
00409 {
00410 insert(start, end - start);
00411 optimize();
00412 return 0;
00413 }
00414
00415 int Labels::modify_handles(double oldposition,
00416 double newposition,
00417 int currentend,
00418 int handle_mode,
00419 int edit_labels)
00420 {
00421 if(edit_labels &&
00422 handle_mode == MOVE_ALL_EDITS)
00423 {
00424 if(currentend == 0)
00425 {
00426 if(newposition < oldposition)
00427 {
00428 insert(oldposition, oldposition - newposition);
00429 }
00430 else
00431 {
00432 clear(oldposition, newposition);
00433 }
00434 }
00435 else
00436 {
00437 if(newposition < oldposition)
00438 {
00439 clear(newposition, oldposition);
00440 }
00441 else
00442 {
00443 insert(oldposition, newposition - oldposition);
00444 }
00445 }
00446 }
00447 return 0;
00448 }
00449
00450 int Labels::optimize()
00451 {
00452 int result = 1;
00453 Label *current;
00454
00455 while(result)
00456 {
00457 result = 0;
00458
00459 for(current = first; current && NEXT && !result;)
00460 {
00461 Label *next = NEXT;
00462 if(current->position == next->position)
00463 {
00464 delete current;
00465 result = 1;
00466 }
00467 current = next;
00468 }
00469 }
00470 return 0;
00471 }
00472
00473 Label* Labels::label_of(double position)
00474 {
00475 Label *current;
00476
00477 for(current = first; current; current = NEXT)
00478 {
00479 if(current->position >= position) return current;
00480 }
00481 return 0;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 Label::Label()
00494 : ListItem<Label>()
00495 {
00496 }
00497
00498 Label::Label(EDL *edl, Labels *labels, double position, char *textstr = 0)
00499 : ListItem<Label>()
00500 {
00501 this->edl = edl;
00502 this->labels = labels;
00503 this->position = position;
00504 if (textstr)
00505 strcpy(this->textstr, textstr);
00506 else
00507 strcpy(this->textstr, "");
00508 }
00509
00510
00511 Label::~Label()
00512 {
00513
00514 }
00515
00516 LabelToggle::LabelToggle(MWindow *mwindow,
00517 Label *label,
00518 int x,
00519 int y,
00520 long position)
00521 : BC_Label(x, y, 0)
00522 {
00523 this->mwindow = mwindow;
00524 this->label = label;
00525 }
00526
00527 LabelToggle::~LabelToggle() { }
00528
00529 int LabelToggle::handle_event()
00530 {
00531 return 0;
00532 }
00533