Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

edits.C

Go to the documentation of this file.
00001 #include "aedit.h"
00002 #include "asset.h"
00003 #include "assets.h"
00004 #include "automation.h"
00005 #include "cache.h"
00006 #include "clip.h"
00007 #include "edit.h"
00008 #include "edits.h"
00009 #include "edl.h"
00010 #include "edlsession.h"
00011 #include "file.h"
00012 #include "filexml.h"
00013 #include "filesystem.h"
00014 #include "localsession.h"
00015 #include "plugin.h"
00016 #include "strategies.inc"
00017 #include "track.h"
00018 #include "transition.h"
00019 #include "transportque.inc"
00020 
00021 #include <string.h>
00022 
00023 Edits::Edits(EDL *edl, Track *track)
00024  : List<Edit>()
00025 {
00026         this->edl = edl;
00027         this->track = track;
00028 }
00029 
00030 Edits::~Edits()
00031 {
00032 }
00033 
00034 
00035 void Edits::equivalent_output(Edits *edits, int64_t *result)
00036 {
00037 // For the case of plugin sets, a new plugin set may be created with
00038 // plugins only starting after 0.  We only want to restart brender at
00039 // the first plugin in this case.
00040         for(Edit *current = first, *that_current = edits->first; 
00041                 current || that_current; 
00042                 current = NEXT,
00043                 that_current = that_current->next)
00044         {
00045 //printf("Edits::equivalent_output 1 %d\n", *result);
00046                 if(!current && that_current)
00047                 {
00048                         int64_t position1 = (last ? last->startproject + last->length : 0);
00049                         int64_t position2 = that_current->startproject;
00050                         if(*result < 0 || *result > MIN(position1, position2))
00051                                 *result = MIN(position1, position2);
00052                         break;
00053                 }
00054                 else
00055                 if(current && !that_current)
00056                 {
00057                         int64_t position1 = (edits->last ? edits->last->startproject + edits->last->length : 0);
00058                         int64_t position2 = current->startproject;
00059                         if(*result < 0 || *result > MIN(position1, position2))
00060                                 *result = MIN(position1, position2);
00061                         break;
00062                 }
00063                 else
00064                 {
00065 //printf("Edits::equivalent_output 2 %d\n", *result);
00066                         current->equivalent_output(that_current, result);
00067 //printf("Edits::equivalent_output 3 %d\n", *result);
00068                 }
00069         }
00070 }
00071 
00072 void Edits::copy_from(Edits *edits)
00073 {
00074         while(last) delete last;
00075         for(Edit *current = edits->first; current; current = NEXT)
00076         {
00077                 Edit *new_edit = append(create_edit());
00078                 new_edit->copy_from(current);
00079         }
00080 }
00081 
00082 
00083 Edits& Edits::operator=(Edits& edits)
00084 {
00085 printf("Edits::operator= 1\n");
00086         copy_from(&edits);
00087         return *this;
00088 }
00089 
00090 
00091 void Edits::insert_asset(Asset *asset,
00092         int64_t length,
00093         int64_t position,
00094         int track_number)
00095 {
00096         Edit *new_edit = insert_new_edit(position);
00097 
00098         new_edit->asset = asset;
00099         new_edit->startsource = 0;
00100         new_edit->startproject = position;
00101         new_edit->length = length;
00102 
00103         if(asset->audio_data)
00104                 new_edit->channel = track_number % asset->channels;
00105         else
00106         if(asset->video_data)
00107                 new_edit->channel = track_number % asset->layers;
00108 
00109 //printf("Edits::insert_asset %d %d\n", new_edit->channel, new_edit->length);
00110         for(Edit *current = new_edit->next; current; current = NEXT)
00111         {
00112                 current->startproject += length;
00113         }
00114 }
00115 
00116 void Edits::insert_edits(Edits *source_edits, int64_t position)
00117 {
00118         int64_t clipboard_length = 
00119                 track->to_units(source_edits->edl->local_session->clipboard_length, 1);
00120         int64_t clipboard_end = position + clipboard_length;
00121 
00122 
00123 // Fill region between end of edit table and beginning of pasted segment
00124 // with silence.  Can't call from insert_new_edit because it's recursive.
00125         if(position > length())
00126         {
00127                 paste_silence(length(), position);
00128         }
00129 
00130 
00131         for(Edit *source_edit = source_edits->first;
00132                 source_edit;
00133                 source_edit = source_edit->next)
00134         {
00135 // Update Assets
00136                 Asset *dest_asset = edl->assets->update(source_edit->asset);
00137 // Open destination area
00138                 Edit *dest_edit = insert_new_edit(position + source_edit->startproject);
00139 
00140                 dest_edit->copy_from(source_edit);
00141                 dest_edit->asset = dest_asset;
00142                 dest_edit->startproject = position + source_edit->startproject;
00143 
00144 
00145 
00146 // Shift keyframes in source edit to their position in the
00147 // destination edit for plugin case
00148                 dest_edit->shift_keyframes(position);
00149 
00150 
00151 
00152 // Shift following edits and keyframes in following edits by length
00153 // in current source edit.
00154                 for(Edit *future_edit = dest_edit->next;
00155                         future_edit;
00156                         future_edit = future_edit->next)
00157                 {
00158                         future_edit->startproject += dest_edit->length;
00159                         future_edit->shift_keyframes(dest_edit->length);
00160                 }
00161 
00162 // Fill clipboard length with silence
00163                 if(!source_edit->next && 
00164                         dest_edit->startproject + dest_edit->length < clipboard_end)
00165                 {
00166                         paste_silence(dest_edit->startproject + dest_edit->length,
00167                                 clipboard_end);
00168                 }
00169         }
00170 }
00171 
00172 
00173 // Native units
00174 // Can't paste silence in here because it's used by paste_silence.
00175 Edit* Edits::insert_new_edit(int64_t position)
00176 {
00177         Edit *current = 0;
00178 //printf("Edits::insert_new_edit 1\n");
00179         current = split_edit(position);
00180         
00181         // FIXME: This check can go out now... since split_edit always returns an edit!
00182         if(current) current = PREVIOUS;
00183 
00184 //printf("Edits::insert_new_edit 1\n");
00185         Edit *new_edit = create_edit();
00186 //printf("Edits::insert_new_edit 1\n");
00187         insert_after(current, new_edit);
00188         new_edit->startproject = position;
00189 //printf("Edits::insert_new_edit 2\n");
00190         return new_edit;
00191 }
00192 
00193 
00194 Edit* Edits::split_edit(int64_t position)
00195 {
00196 // Get edit containing position
00197         Edit *edit = editof(position, PLAY_FORWARD, 0);
00198 
00199 // No edit found
00200         if(!edit)
00201                 if (!last || last->startproject + last->length <= position)
00202                 {
00203                         // Even when track is completely empty or split is beyond last edit, return correct edit
00204                         Edit *empty = create_edit();
00205                         if (last)
00206                                 empty->startproject = last->startproject + last->length; // end of last edit
00207                         else
00208                                 empty->startproject = 0; // empty track
00209                         empty->length = position - empty->startproject;
00210                         insert_after(last, empty);
00211                         edit = empty;
00212                 } else
00213                 {  // now we are now surely in situation where we have a) broken edit list or b) negative position... report error!
00214                         printf("ERROR!\n");       
00215                         printf("Trying to insert edit at position, but failed: %lli\n", position);
00216                         printf("Dump is here:\n");
00217                         track->dump();
00218                         return 0;
00219                 }       
00220 // Split would have created a 0 length
00221 //      if(edit->startproject == position) return edit;
00222 // Create anyway so the return value comes before position
00223 
00224         Edit *new_edit = create_edit();
00225         insert_after(edit, new_edit);
00226         new_edit->copy_from(edit);
00227         new_edit->length = new_edit->startproject + new_edit->length - position;
00228         edit->length = position - edit->startproject;
00229         new_edit->startproject = edit->startproject + edit->length;
00230         new_edit->startsource += edit->length;
00231 
00232 
00233 // Decide what to do with the transition
00234         if(edit->length && edit->transition)
00235         {
00236                 delete new_edit->transition;
00237                 new_edit->transition = 0;
00238         }
00239 
00240         if(edit->transition && edit->transition->length > edit->length) 
00241                 edit->transition->length = edit->length;
00242         if(new_edit->transition && new_edit->transition->length > new_edit->length)
00243                 new_edit->transition->length = new_edit->length;
00244         return new_edit;
00245 }
00246 
00247 int Edits::save(FileXML *xml, char *output_path)
00248 {
00249         copy(0, length(), xml, output_path);
00250         return 0;
00251 }
00252 
00253 void Edits::resample(double old_rate, double new_rate)
00254 {
00255         for(Edit *current = first; current; current = NEXT)
00256         {
00257                 current->startproject = Units::to_int64((double)current->startproject / 
00258                         old_rate * 
00259                         new_rate);
00260                 if(PREVIOUS) PREVIOUS->length = current->startproject - PREVIOUS->startproject;
00261                 current->startsource = Units::to_int64((double)current->startsource /
00262                         old_rate *
00263                         new_rate);
00264                 if(!NEXT) current->length = Units::to_int64((double)current->length /
00265                         old_rate *
00266                         new_rate);
00267                 if(current->transition)
00268                 {
00269                         current->transition->length = Units::to_int64(
00270                                 (double)current->transition->length /
00271                                 old_rate *
00272                                 new_rate);
00273                 }
00274                 current->resample(old_rate, new_rate);
00275         }
00276 }
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 int Edits::optimize()
00292 {
00293         int result = 1;
00294         Edit *current;
00295 
00296 //return 0;
00297 // Sort edits by starting point
00298         while(result)
00299         {
00300                 result = 0;
00301                 
00302                 for(current = first; current; current = NEXT)
00303                 {
00304                         Edit *next_edit = NEXT;
00305                         
00306                         if(next_edit && next_edit->startproject < current->startproject)
00307                         {
00308                                 swap(next_edit, current);
00309                                 result = 1;
00310                         }
00311                 }
00312         }
00313 
00314 // Insert silence between edits which aren't consecutive
00315         for(current = last; current; current = current->previous)
00316         {
00317                 if(current->previous)
00318                 {
00319                         Edit *previous_edit = current->previous;
00320                         if(current->startproject - 
00321                                 previous_edit->startproject -
00322                                 previous_edit->length > 0)
00323                         {
00324                                 Edit *new_edit = create_edit();
00325                                 insert_before(current, new_edit);
00326                                 new_edit->startproject = previous_edit->startproject + previous_edit->length;
00327                                 new_edit->length = current->startproject - 
00328                                         previous_edit->startproject -
00329                                         previous_edit->length;
00330                         }
00331                 }
00332                 else
00333                 if(current->startproject > 0)
00334                 {
00335                         Edit *new_edit = create_edit();
00336                         insert_before(current, new_edit);
00337                         new_edit->length = current->startproject;
00338                 }
00339         }
00340 
00341         result = 1;
00342         while(result)
00343         {
00344                 result = 0;
00345 
00346 
00347 // delete 0 length edits
00348                 for(current = first; 
00349                         current && !result; )
00350                 {
00351                         if(current->length == 0)
00352                         {
00353                                 Edit* next = current->next;
00354                                 delete current;
00355                                 result = 1;
00356                                 current = next;
00357                         }
00358                         else
00359                                 current = current->next;
00360                 }
00361 
00362 // merge same files or transitions
00363                 for(current = first; 
00364                         current && current->next && !result; )
00365                 {
00366 // assets identical
00367                         Edit *next_edit = current->next;
00368                 if(current->asset == next_edit->asset && 
00369                         (!current->asset ||
00370                                         (current->startsource + current->length == next_edit->startsource &&
00371                                 current->channel == next_edit->channel)
00372                                 )
00373                         )
00374                 {       
00375 // source positions are consecutive
00376                         current->length += next_edit->length;
00377                         remove(next_edit);
00378                         result = 1;
00379                 }
00380 
00381                 current = (Plugin*)current->next;
00382                 }
00383 
00384 // delete last edit of 0 length or silence
00385                 if(last && 
00386                         (last->silence() || 
00387                         !last->length))
00388                 {
00389                         delete last;
00390                         result = 1;
00391                 }
00392         }
00393 
00394 //track->dump();
00395         return 0;
00396 }
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 // ===================================== file operations
00418 
00419 int Edits::load(FileXML *file, int track_offset)
00420 {
00421         int result = 0;
00422         int64_t startproject = 0;
00423 
00424         do{
00425                 result = file->read_tag();
00426 
00427 //printf("Edits::load 1 %s\n", file->tag.get_title());
00428                 if(!result)
00429                 {
00430                         if(!strcmp(file->tag.get_title(), "EDIT"))
00431                         {
00432                                 load_edit(file, startproject, track_offset);
00433                         }
00434                         else
00435                         if(!strcmp(file->tag.get_title(), "/EDITS"))
00436                         {
00437                                 result = 1;
00438                         }
00439                 }
00440         }while(!result);
00441 
00442 //track->dump();
00443         optimize();
00444 }
00445 
00446 int Edits::load_edit(FileXML *file, int64_t &startproject, int track_offset)
00447 {
00448         Edit* current;
00449 
00450 //printf("Edits::load_edit 1 %d\n", total());
00451         current = append_new_edit();
00452 //printf("Edits::load_edit 2 %d\n", total());
00453 
00454         current->load_properties(file, startproject);
00455 
00456         startproject += current->length;
00457 
00458         int result = 0;
00459 //printf("Edits::load_edit 1\n");
00460 
00461         do{
00462 //printf("Edits::load_edit 2\n");
00463                 result = file->read_tag();
00464 //printf("Edits::load_edit 3 %s\n", file->tag.get_title());
00465 
00466                 if(!result)
00467                 {
00468                         if(file->tag.title_is("FILE"))
00469                         {
00470                                 char filename[1024];
00471                                 sprintf(filename, SILENCE);
00472                                 file->tag.get_property("SRC", filename);
00473 // Extend path
00474 //printf("Edits::load_edit 4 %s\n", filename);
00475                                 if(strcmp(filename, SILENCE))
00476                                 {
00477                                         char directory[BCTEXTLEN], edl_directory[BCTEXTLEN];
00478                                         FileSystem fs;
00479                                         fs.set_current_dir("");
00480                                         fs.extract_dir(directory, filename);
00481                                         if(!strlen(directory))
00482                                         {
00483                                                 fs.extract_dir(edl_directory, file->filename);
00484                                                 fs.join_names(directory, edl_directory, filename);
00485                                                 strcpy(filename, directory);
00486                                         }
00487                                         current->asset = edl->assets->get_asset(filename);
00488                                 }
00489                                 else
00490                                 {
00491                                         current->asset = edl->assets->get_asset(SILENCE);
00492                                 }
00493 //printf("Edits::load_edit 5\n");
00494                         }
00495                         else
00496                         if(file->tag.title_is("TRANSITION"))
00497                         {
00498                                 current->transition = new Transition(edl,
00499                                         current, 
00500                                         "",
00501                                         track->to_units(edl->session->default_transition_length, 1));
00502                                 current->transition->load_xml(file);
00503                         }
00504                         else
00505                         if(file->tag.title_is(SILENCE))
00506                         {
00507 //printf("Edits::load_edit 6\n");
00508                                 current->asset = edl->assets->get_asset(SILENCE);
00509 //printf("Edits::load_edit 7\n");
00510                         }
00511                         else
00512                         if(file->tag.title_is("/EDIT"))
00513                         {
00514                                 result = 1;
00515                         }
00516                 }
00517 //printf("Edits::load_edit 8\n");
00518         }while(!result);
00519 
00520 //printf("Edits::load_edit 5\n");
00521 // in case of incomplete edit tag
00522         if(!current->asset) current->asset = edl->assets->get_asset(SILENCE);
00523         return 0;
00524 }
00525 
00526 // ============================================= accounting
00527 
00528 int64_t Edits::length()
00529 {
00530         if(last) 
00531                 return last->startproject + last->length;
00532         else 
00533                 return 0;
00534 }
00535 // 
00536 // int64_t Edits::total_length() 
00537 // {
00538 //      int64_t total = 0;
00539 //      Edit* current;
00540 //      for(current = first; current; current = NEXT)
00541 //      {
00542 //              total += current->length;
00543 //      }
00544 //      return total; 
00545 // };
00546 
00547 Edit* Edits::editof(int64_t position, int direction, int use_nudge)
00548 {
00549         Edit *current = 0;
00550         if(use_nudge && track) position += track->nudge;
00551 
00552         if(direction == PLAY_FORWARD)
00553         {
00554                 for(current = last; current; current = PREVIOUS)
00555                 {
00556                         if(current->startproject <= position && current->startproject + current->length > position)
00557                                 return current;
00558                 }
00559         }
00560         else
00561         if(direction == PLAY_REVERSE)
00562         {
00563                 for(current = first; current; current = NEXT)
00564                 {
00565                         if(current->startproject < position && current->startproject + current->length >= position)
00566                                 return current;
00567                 }
00568         }
00569 
00570         return 0;     // return 0 on failure
00571 }
00572 
00573 Edit* Edits::get_playable_edit(int64_t position, int use_nudge)
00574 {
00575         Edit *current;
00576         if(track && use_nudge) position += track->nudge;
00577 
00578 // Get the current edit
00579         for(current = first; current; current = NEXT)
00580         {
00581                 if(current->startproject <= position && 
00582                         current->startproject + current->length > position)
00583                         break;
00584         }
00585 
00586 // Get the edit's asset
00587         if(current)
00588         {
00589                 if(!current->asset)
00590                         current = 0;
00591         }
00592 
00593         return current;     // return 0 on failure
00594 }
00595 
00596 // ================================================ editing
00597 
00598 
00599 
00600 int Edits::copy(int64_t start, int64_t end, FileXML *file, char *output_path)
00601 {
00602         Edit *current_edit;
00603 
00604         file->tag.set_title("EDITS");
00605         file->append_tag();
00606         file->append_newline();
00607 
00608         for(current_edit = first; current_edit; current_edit = current_edit->next)
00609         {
00610                 current_edit->copy(start, end, file, output_path);
00611         }
00612 
00613         file->tag.set_title("/EDITS");
00614         file->append_tag();
00615         file->append_newline();
00616 }
00617 
00618 
00619 
00620 void Edits::clear(int64_t start, int64_t end)
00621 {
00622         Edit* edit1 = editof(start, PLAY_FORWARD, 0);
00623         Edit* edit2 = editof(end, PLAY_FORWARD, 0);
00624         Edit* current_edit;
00625 
00626         if(end == start) return;        // nothing selected
00627         if(!edit1 && !edit2) return;       // nothing selected
00628 
00629 
00630         if(!edit2)
00631         {                // edit2 beyond end of track
00632                 edit2 = last;
00633                 end = this->length();
00634         }
00635 
00636         if(edit1 != edit2)
00637         {
00638 // in different edits
00639 
00640 //printf("Edits::clear 3.5 %d %d %d %d\n", edit1->startproject, edit1->length, edit2->startproject, edit2->length);
00641                 edit1->length = start - edit1->startproject;
00642                 edit2->length -= end - edit2->startproject;
00643                 edit2->startsource += end - edit2->startproject;
00644                 edit2->startproject += end - edit2->startproject;
00645 
00646 // delete
00647                 for(current_edit = edit1->next; current_edit && current_edit != edit2;)
00648                 {
00649                         Edit* next = current_edit->next;
00650                         remove(current_edit);
00651                         current_edit = next;
00652                 }
00653 // shift
00654                 for(current_edit = edit2; current_edit; current_edit = current_edit->next)
00655                 {
00656                         current_edit->startproject -= end - start;
00657                 }
00658         }
00659         else
00660         {
00661 // in same edit. paste_edit depends on this
00662 // create a new edit
00663                 current_edit = split_edit(start);
00664 
00665                 current_edit->length -= end - start;
00666                 current_edit->startsource += end - start;
00667 
00668 // shift
00669                 for(current_edit = current_edit->next; 
00670                         current_edit; 
00671                         current_edit = current_edit->next)
00672                 {            
00673                         current_edit->startproject -= end - start;
00674                 }
00675         }
00676 
00677         optimize();
00678 }
00679 
00680 // Used by edit handle and plugin handle movement but plugin handle movement
00681 // can only effect other plugins.
00682 void Edits::clear_recursive(int64_t start, 
00683         int64_t end, 
00684         int edit_edits,
00685         int edit_labels, 
00686         int edit_plugins,
00687         Edits *trim_edits)
00688 {
00689 //printf("Edits::clear_recursive 1\n");
00690         track->clear(start, 
00691                 end, 
00692                 edit_edits,
00693                 edit_labels,
00694                 edit_plugins,
00695                 0,
00696                 trim_edits);
00697 }
00698 
00699 
00700 int Edits::clear_handle(double start, 
00701         double end, 
00702         int edit_plugins, 
00703         double &distance)
00704 {
00705         Edit *current_edit;
00706 
00707         distance = 0.0; // if nothing is found, distance is 0!
00708         for(current_edit = first; 
00709                 current_edit && current_edit->next; 
00710                 current_edit = current_edit->next)
00711         {
00712 
00713 
00714 
00715                 if(current_edit->asset && 
00716                         current_edit->next->asset)
00717                 {
00718 
00719                         if(current_edit->asset->equivalent(*current_edit->next->asset,
00720                                 0,
00721                                 0))
00722                         {
00723 
00724 // Got two consecutive edits in same source
00725                                 if(edl->equivalent(track->from_units(current_edit->next->startproject), 
00726                                         start))
00727                                 {
00728 // handle selected
00729                                         int length = -current_edit->length;
00730                                         current_edit->length = current_edit->next->startsource - current_edit->startsource;
00731                                         length += current_edit->length;
00732 
00733 // Lengthen automation
00734                                         track->automation->paste_silence(current_edit->next->startproject, 
00735                                                 current_edit->next->startproject + length);
00736 
00737 // Lengthen effects
00738                                         if(edit_plugins)
00739                                                 track->shift_effects(current_edit->next->startproject, 
00740                                                         length,
00741                                                         0);
00742 
00743                                         for(current_edit = current_edit->next; current_edit; current_edit = current_edit->next)
00744                                         {
00745                                                 current_edit->startproject += length;
00746                                         }
00747 
00748                                         distance = track->from_units(length);
00749                                         optimize();
00750                                         break;
00751                                 }
00752                         }
00753                 }
00754         }
00755 
00756         return 0;
00757 }
00758 
00759 int Edits::modify_handles(double oldposition, 
00760         double newposition, 
00761         int currentend,
00762         int edit_mode, 
00763         int edit_edits,
00764         int edit_labels,
00765         int edit_plugins,
00766         Edits *trim_edits)
00767 {
00768         int result = 0;
00769         Edit *current_edit;
00770 
00771 //printf("Edits::modify_handles 1 %d %f %f\n", currentend, newposition, oldposition);
00772         if(currentend == 0)
00773         {
00774 // left handle
00775                 for(current_edit = first; current_edit && !result;)
00776                 {
00777                         if(edl->equivalent(track->from_units(current_edit->startproject), 
00778                                 oldposition))
00779                         {
00780 // edit matches selection
00781 //printf("Edits::modify_handles 3 %f %f\n", newposition, oldposition);
00782                                 oldposition = track->from_units(current_edit->startproject);
00783                                 result = 1;
00784 
00785                                 if(newposition >= oldposition)
00786                                 {
00787 //printf("Edits::modify_handle 1 %s %f %f\n", track->title, oldposition, newposition);
00788 // shift start of edit in
00789                                         current_edit->shift_start_in(edit_mode, 
00790                                                 track->to_units(newposition, 0), 
00791                                                 track->to_units(oldposition, 0),
00792                                                 edit_edits,
00793                                                 edit_labels,
00794                                                 edit_plugins,
00795                                                 trim_edits);
00796                                 }
00797                                 else
00798                                 {
00799 //printf("Edits::modify_handle 2 %s\n", track->title);
00800 // move start of edit out
00801                                         current_edit->shift_start_out(edit_mode, 
00802                                                 track->to_units(newposition, 0), 
00803                                                 track->to_units(oldposition, 0),
00804                                                 edit_edits,
00805                                                 edit_labels,
00806                                                 edit_plugins,
00807                                                 trim_edits);
00808                                 }
00809                         }
00810 
00811                         if(!result) current_edit = current_edit->next;
00812                 }
00813         }
00814         else
00815         {
00816 // right handle selected
00817                 for(current_edit = first; current_edit && !result;)
00818                 {
00819                         if(edl->equivalent(track->from_units(current_edit->startproject) + 
00820                                 track->from_units(current_edit->length), oldposition))
00821                         {
00822                 oldposition = track->from_units(current_edit->startproject) + 
00823                                         track->from_units(current_edit->length);
00824                                 result = 1;
00825 
00826 //printf("Edits::modify_handle 3\n");
00827                                 if(newposition <= oldposition)
00828                                 {     
00829 // shift end of edit in
00830 //printf("Edits::modify_handle 4\n");
00831                                         current_edit->shift_end_in(edit_mode, 
00832                                                 track->to_units(newposition, 0), 
00833                                                 track->to_units(oldposition, 0),
00834                                                 edit_edits,
00835                                                 edit_labels,
00836                                                 edit_plugins,
00837                                                 trim_edits);
00838 //printf("Edits::modify_handle 5\n");
00839                                 }
00840                                 else
00841                                 {     
00842 // move end of edit out
00843 //printf("Edits::modify_handle 6\n");
00844                                         current_edit->shift_end_out(edit_mode, 
00845                                                 track->to_units(newposition, 0), 
00846                                                 track->to_units(oldposition, 0),
00847                                                 edit_edits,
00848                                                 edit_labels,
00849                                                 edit_plugins,
00850                                                 trim_edits);
00851 //printf("Edits::modify_handle 7\n");
00852                                 }
00853                         }
00854 
00855                         if(!result) current_edit = current_edit->next;
00856 //printf("Edits::modify_handle 8\n");
00857                 }
00858         }
00859 
00860         optimize();
00861         return 0;
00862 }
00863 
00864 
00865 // Paste silence should not return anything - since pasting silence to an empty track should produce no edits
00866 // If we need rutine to create new edit by pushing others forward, write new rutine and call it properly
00867 // This are two distinctive functions
00868 // This rutine leaves edits in optimized state!
00869 void Edits::paste_silence(int64_t start, int64_t end)
00870 {
00871         // paste silence does not do anything if 
00872         // a) paste silence is on empty track
00873         // b) paste silence is after last edit
00874         // in both cases editof returns NULL
00875         Edit *new_edit = editof(start, PLAY_FORWARD, 0);
00876         if (!new_edit) return;
00877 
00878         if (!new_edit->asset)
00879         { // in this case we extend already existing edit
00880                 new_edit->length += end - start;
00881         } else
00882         { // we are in fact creating a new edit
00883                 new_edit = insert_new_edit(start);
00884                 new_edit->length = end - start;
00885         }
00886         for(Edit *current = new_edit->next; current; current = NEXT)
00887         {
00888                 current->startproject += end - start;
00889         }
00890         return;
00891 }
00892 
00893 // Used by other editing commands so don't optimize
00894 // This is separate from paste_silence, since it has to wrok also on empty tracks/beyond end of track
00895 Edit *Edits::create_and_insert_edit(int64_t start, int64_t end)
00896 {
00897         Edit *new_edit = insert_new_edit(start);
00898         new_edit->length = end - start;
00899         for(Edit *current = new_edit->next; current; current = NEXT)
00900         {
00901                 current->startproject += end - start;
00902         }
00903         return new_edit;
00904 }
00905                                      
00906 Edit* Edits::shift(int64_t position, int64_t difference)
00907 {
00908         Edit *new_edit = split_edit(position);
00909 
00910         for(Edit *current = first; 
00911                 current; 
00912                 current = NEXT)
00913         {
00914                 if(current->startproject >= position)
00915                 {
00916                         current->shift(difference);
00917                 }
00918         }
00919         return new_edit;
00920 }
00921 
00922 
00923 void Edits::shift_keyframes_recursive(int64_t position, int64_t length)
00924 {
00925         track->shift_keyframes(position, length, 0);
00926 }
00927 
00928 void Edits::shift_effects_recursive(int64_t position, int64_t length)
00929 {
00930         track->shift_effects(position, length, 0);
00931 }
00932 

Generated on Sun Jan 8 13:38:53 2006 for Cinelerra-svn by  doxygen 1.4.4