|  | @@ -3812,13 +3812,14 @@ void la_FreeDiffCommand(laDiffCommand* dc, laDiff* d, int FromLeft){
 | 
											
												
													
														|  |      memFree(dc);
 |  |      memFree(dc);
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  void la_FreeDifference(laDiff* d, int FromLeft){
 |  |  void la_FreeDifference(laDiff* d, int FromLeft){
 | 
											
												
													
														|  | -    laDiffCommand* dc; laDiffExtraTouched* det;
 |  | 
 | 
											
												
													
														|  | 
 |  | +    laDiffCommand* dc; laDiffCommandCustom* dcc; laDiffExtraTouched* det;
 | 
											
												
													
														|  |      while(dc=lstPopItem(&d->Commands)){ la_FreeDiffCommand(dc,d,FromLeft); }
 |  |      while(dc=lstPopItem(&d->Commands)){ la_FreeDiffCommand(dc,d,FromLeft); }
 | 
											
												
													
														|  | 
 |  | +    while(dcc=lstPopItem(&d->CustomCommands)){ if(dcc->Free) dcc->Free(dcc->Data, FromLeft); }
 | 
											
												
													
														|  |      while(det=lstPopItem(&d->ExtraTouched)){ memFree(det); }
 |  |      while(det=lstPopItem(&d->ExtraTouched)){ memFree(det); }
 | 
											
												
													
														|  |      if(d->Description&&d->Description->Ptr){printf("%s\n",d->Description->Ptr);}
 |  |      if(d->Description&&d->Description->Ptr){printf("%s\n",d->Description->Ptr);}
 | 
											
												
													
														|  |      strSafeDestroy(&d->Description);
 |  |      strSafeDestroy(&d->Description);
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  | -void la_FreeNewerDifferences(){
 |  | 
 | 
											
												
													
														|  | 
 |  | +void laFreeNewerDifferences(){
 | 
											
												
													
														|  |      laDiff* PrevD;
 |  |      laDiff* PrevD;
 | 
											
												
													
														|  |      if(MAIN.HeadDifference==MAIN.Differences.pLast) return;
 |  |      if(MAIN.HeadDifference==MAIN.Differences.pLast) return;
 | 
											
												
													
														|  |      for(laDiff* d=MAIN.Differences.pLast;d;d=PrevD){
 |  |      for(laDiff* d=MAIN.Differences.pLast;d;d=PrevD){
 | 
											
										
											
												
													
														|  | @@ -3828,7 +3829,7 @@ void la_FreeNewerDifferences(){
 | 
											
												
													
														|  |          if(MAIN.HeadDifference==d){ MAIN.HeadDifference=PrevD; laPushDifferenceOnly(0,0); break; }
 |  |          if(MAIN.HeadDifference==d){ MAIN.HeadDifference=PrevD; laPushDifferenceOnly(0,0); break; }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  | -void la_FreeOlderDifferences(int KeepHowMany){
 |  | 
 | 
											
												
													
														|  | 
 |  | +void laFreeOlderDifferences(int KeepHowMany){
 | 
											
												
													
														|  |      laDiff* endd; int count=0;
 |  |      laDiff* endd; int count=0;
 | 
											
												
													
														|  |      for(endd=MAIN.HeadDifference;endd;endd=endd->Item.pPrev){
 |  |      for(endd=MAIN.HeadDifference;endd;endd=endd->Item.pPrev){
 | 
											
												
													
														|  |          if(count>=KeepHowMany) break; count++; 
 |  |          if(count>=KeepHowMany) break; count++; 
 | 
											
										
											
												
													
														|  | @@ -3842,8 +3843,8 @@ void la_FreeOlderDifferences(int KeepHowMany){
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  void la_FreeAllDifferences(){
 |  |  void la_FreeAllDifferences(){
 | 
											
												
													
														|  | -    la_FreeNewerDifferences();
 |  | 
 | 
											
												
													
														|  | -    la_FreeOlderDifferences(1);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    laFreeNewerDifferences();
 | 
											
												
													
														|  | 
 |  | +    laFreeOlderDifferences(1);
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  void la_NoLongerRecordUndo(){
 |  |  void la_NoLongerRecordUndo(){
 | 
											
												
													
														|  |      la_FreeAllDifferences();
 |  |      la_FreeAllDifferences();
 | 
											
										
											
												
													
														|  | @@ -4336,6 +4337,9 @@ laDiff* laSwapDBState(int Redo){
 | 
											
												
													
														|  |          laPropPack PP={0}; laPropStep PS={0}; PP.LastPs=&PS; PS.p=dbp->p; PS.UseInstance=dc->Instance->OriginalInstance;
 |  |          laPropPack PP={0}; laPropStep PS={0}; PP.LastPs=&PS; PS.p=dbp->p; PS.UseInstance=dc->Instance->OriginalInstance;
 | 
											
												
													
														|  |          laNotifyUsersPP(&PP);
 |  |          laNotifyUsersPP(&PP);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  | 
 |  | +    for(laDiffCommandCustom* dcc=diff->CustomCommands.pFirst;dcc;dcc=dcc->Item.pNext){
 | 
											
												
													
														|  | 
 |  | +        if(Redo){ if(dcc->Redo) dcc->Redo(dcc->Data); } else { if(dcc->Undo) dcc->Undo(dcc->Data); }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |      if(Redo){ MAIN.HeadDifference=diff->Item.pNext; }
 |  |      if(Redo){ MAIN.HeadDifference=diff->Item.pNext; }
 | 
											
												
													
														|  |      else{ MAIN.HeadDifference=diff; }
 |  |      else{ MAIN.HeadDifference=diff; }
 | 
											
												
													
														|  |      return diff;
 |  |      return diff;
 | 
											
										
											
												
													
														|  | @@ -4411,6 +4415,11 @@ laDBProp* laFindStartingDBProp(laProp* p, void* Instance, laPropContainer* Insta
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      return 0;
 |  |      return 0;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  | 
 |  | +void laRecordCustomDifferences(void* Data, laDiffCommandUndoF Undo, laDiffCommandRedoF Redo, laDiffCommandFreeF Free){
 | 
											
												
													
														|  | 
 |  | +    laDiffCommandCustom* dcc=memAcquire(sizeof(laDiffCommandCustom));
 | 
											
												
													
														|  | 
 |  | +    dcc->Data=Data; dcc->Undo=Undo; dcc->Redo=Redo; dcc->Free=Free;
 | 
											
												
													
														|  | 
 |  | +    lstAppendItem(&MAIN.HeadDifference->CustomCommands,dcc);
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  int laRecordDifferences(laPropPack* base, char* path){
 |  |  int laRecordDifferences(laPropPack* base, char* path){
 | 
											
												
													
														|  |      laPropPack PP={0};
 |  |      laPropPack PP={0};
 | 
											
												
													
														|  |      la_GetPropFromPath(&PP,base,path,0);
 |  |      la_GetPropFromPath(&PP,base,path,0);
 | 
											
										
											
												
													
														|  | @@ -4422,7 +4431,7 @@ int laRecordDifferences(laPropPack* base, char* path){
 | 
											
												
													
														|  |      laDBProp* dbp=laFindStartingDBProp(PP.LastPs->p, PP.LastPs->UseInstance, PP.LastPs->p->Container, &FromDBI);
 |  |      laDBProp* dbp=laFindStartingDBProp(PP.LastPs->p, PP.LastPs->UseInstance, PP.LastPs->p->Container, &FromDBI);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      if(FromDBI && dbp){
 |  |      if(FromDBI && dbp){
 | 
											
												
													
														|  | -        la_FreeNewerDifferences();
 |  | 
 | 
											
												
													
														|  | 
 |  | +        laFreeNewerDifferences();
 | 
											
												
													
														|  |          laIterateDB(FromDBI, &PP, MAIN.HeadDifference, dbp);
 |  |          laIterateDB(FromDBI, &PP, MAIN.HeadDifference, dbp);
 | 
											
												
													
														|  |          if(MAIN.HeadDifference->Commands.pFirst){ success = 1; }
 |  |          if(MAIN.HeadDifference->Commands.pFirst){ success = 1; }
 | 
											
												
													
														|  |      }else{
 |  |      }else{
 | 
											
										
											
												
													
														|  | @@ -4441,7 +4450,7 @@ int laRecordInstanceDifferences(void* instance, const char* container){
 | 
											
												
													
														|  |      for(laProp* p=pc->Props.pFirst;p;p=p->Item.pNext){
 |  |      for(laProp* p=pc->Props.pFirst;p;p=p->Item.pNext){
 | 
											
												
													
														|  |          PS.p = p; laDBProp* dbp=laFindDBProp(FromDBI, p, 0,0);
 |  |          PS.p = p; laDBProp* dbp=laFindDBProp(FromDBI, p, 0,0);
 | 
											
												
													
														|  |          if(FromDBI && dbp){
 |  |          if(FromDBI && dbp){
 | 
											
												
													
														|  | -            if(!freed){ la_FreeNewerDifferences(); freed=1; }
 |  | 
 | 
											
												
													
														|  | 
 |  | +            if(!freed){ laFreeNewerDifferences(); freed=1; }
 | 
											
												
													
														|  |              any+=laIterateDB(FromDBI, &PP, MAIN.HeadDifference, dbp);
 |  |              any+=laIterateDB(FromDBI, &PP, MAIN.HeadDifference, dbp);
 | 
											
												
													
														|  |              if(MAIN.HeadDifference->Commands.pFirst){ success = 1; }
 |  |              if(MAIN.HeadDifference->Commands.pFirst){ success = 1; }
 | 
											
												
													
														|  |          }
 |  |          }
 |