fs-danaus
2023-03-30 665b0603d09890014f982fdfbd6ec47938f504b0
提交 | 用户 | age
25ab64 1 // -----------------------------------------------------------------------------------------------------------
F 2 // Functions for Undo / Redo
3 // -----------------------------------------------------------------------------------------------------------
4 // -----------------------------------------------------------------------------------------------------------
5 TGP.GetUndo = function(){ 
6 for(var G=this;G.MasterGrid;G=G.MasterGrid);
7 return G.OUndo;
8 }
9 // -----------------------------------------------------------------------------------------------------------
10 TGP.UndoStart = function(autoupdate){ 
11 MS.Undo;
12 for(var G=this;G.MasterGrid;G=G.MasterGrid);
13 if(G.InUndoStart){ G.InUndoStart++; return; }
14 if(autoupdate) { G.UndoAutoUpdate = G.AutoUpdate; G.AutoUpdate = 0; }
15 var OU = G.OUndo;
16 if(G.OUndo){ 
17    G.OUndoStart = OU;
18    if(OU.Pos) { G.OUndo = [{Type:"Void"},{Type:"Start"}]; G.OUndo.Pos = 2; } 
19    else { G.OUndo = [{Type:"Start"}]; G.OUndo.Pos = 1; }
20    if(OU.Pos!=G.OUndoStart.length) G.OUndo[G.OUndo.Pos] = {Type:"Void"}; 
21    
22    }
23 G.InUndoStart = 1;
24 ME.Undo;
25 }
26 // -----------------------------------------------------------------------------------------------------------
27 TGP.UndoEnd = function(autoupdate){ 
28 MS.Undo;
29 for(var G=this;G.MasterGrid;G=G.MasterGrid);
30 if(G.InUndoStart>1) { G.InUndoStart--; return; }
31 if(autoupdate) G.AutoUpdate = G.UndoAutoUpdate;
32 var NU = G.OUndo, OU = G.OUndoStart;
33 if(NU && NU.Pos){ 
34    G.OUndo = OU;
35    var p = NU[0].Type!="Start" ? 1 : 0; 
36    if(NU.Pos>p+1) { 
37       if(NU.Pos==p+2) OU[OU.Pos++] = NU[p+1]; 
38       else {
39          for(var i=p;i<NU.Pos;i++) OU[OU.Pos++] = NU[i];
40          OU[OU.Pos++] = { Type:"End" };
41          }
42       OU.length = OU.Pos;
43       }
44    }
45 G.OUndoStart = null;
46 G.InUndoStart = 0;
47 if(autoupdate && G.AutoUpdate) G.UploadChanges();
48 ME.Undo;
49 }
50 // -----------------------------------------------------------------------------------------------------------
51 TGP.AddUndo = function(U,merge){ 
52 MS.Undo;
53 var OU = this.GetUndo(); if(!OU) return;
54 if(OU.Merge) { merge = OU.Merge; OU.Merge = null; }
55 var calc = !OU.Pos||OU.Pos==1&&OU[0].Type=="Start"||OU.Pos!=OU.length;
56 if(OU.Pos!=OU.length&&this.Undo&128&&(U.Type=="Scroll"||U.Type=="Select"||U.Type=="Focus")) OU.splice(OU.Pos++,0,U);
57
58 else { OU[OU.Pos++] = U; OU.length = OU.Pos; }
59 if(merge==1) this.MergeUndo(U.Type);
60 else if(merge==2) this.MergeUndo();
61 else {
62    merge = this.UndoMergeParsed[U.Type]; 
63    if(merge) this.MergeUndo(merge); 
64    else if(this.UndoMergeParsed[""]) this.MergeUndo(U.Type);
65    }
66
67 if(calc) {
68    this.CalculateSpaces(1);
69    if(this.DetailSelected) for(var i=0;i<Grids.length;i++) if(Grids[i] && Grids[i].Undo && Grids[i].MasterGrid==this) Grids[i].CalculateSpaces(1);
70    }
71 ME.Undo;
72 }
73
74 // -----------------------------------------------------------------------------------------------------------
75 TGP.GetLastUndo = function(){ 
76 MS.Undo;
77 var OU = this.GetUndo(); if(OU) for(var i=OU.Pos-1;i;i--) if(OU[i].Type!="End") return OU[i];
78 ME.Undo;
79 }
80 // -----------------------------------------------------------------------------------------------------------
81 TGP.SetUndo = function(U){ 
82 MS.Undo;
83 var OU = this.GetUndo(); if(OU){ 
84    if(OU[OU.Pos-1].Type=="End") while(OU[OU.Pos-1].Type!="Start") OU.Pos--;
85    OU[OU.Pos-1] = U; OU.length = OU.Pos; 
86    } 
87 ME.Undo;
88 }
89 // -----------------------------------------------------------------------------------------------------------
90 TGP.ClearUndo = function(calc){
91 MS.Undo;
92 for(var G=this;G.MasterGrid;G=G.MasterGrid);
93 if(G.Undo){ G.OUndo = []; G.OUndo.Pos = 0; if(calc) G.CalculateSpaces(1); } 
94 ME.Undo;
95 }
96 // -----------------------------------------------------------------------------------------------------------
97 TGP.CanUndo = function(){ for(var G=this;G.MasterGrid;G=G.MasterGrid); return G.EditMode&&G.Edit ? G.Edit.CanUndo() : G.OUndo && (!G.AutoUpdate||G.Undo&32) && (G.OUndo.Pos>1||G.OUndo.Pos==1&&G.OUndo[0].Type!="Start") && (!G.Locked.length||G.CountUndo(1)) ? 1 : 0; }
98 TGP.CanRedo = function(){ for(var G=this;G.MasterGrid;G=G.MasterGrid); return G.EditMode&&G.Edit ? G.Edit.CanRedo() : G.OUndo && (!G.AutoUpdate||G.Undo&32) && G.OUndo.Pos < G.OUndo.length && (!G.Locked.length||G.CountRedo(1)) ? 1 : 0; }
99 // -----------------------------------------------------------------------------------------------------------
100 MS.Undo;
101 // -----------------------------------------------------------------------------------------------------------
102 TGP.SetMergeUndo = function(m){
103 this.UndoMerge = m; var o = {}; this.UndoMergeParsed = o;
104 if(!m) return;
105 m = m.slice(1).split(m.charAt(0));
106 for(var i=0;i<m.length;i++){
107    var n = m[i].split(","), p = {};
108    for(var j=0;j<n.length;j++) { p[n[j]] = 1; o[n[j]] = p; }
109    }
110 }
111 // -----------------------------------------------------------------------------------------------------------
112 TGP.StartUndo = TGP.UndoStart;
113 TGP.EndUndo = TGP.UndoEnd;
114 TGP.CustomUndo = function(U,undo,redo){ this.AddUndo( { Type:"Custom", Object:U, Undo:undo, Redo:redo } ); }
115 // -----------------------------------------------------------------------------------------------------------
116 TGP.MergeUndo = function(type,type2){
117 MS.Master; if(this.MasterGrid) return this.MasterGrid.MergeUndo(); ME.Master;
118 if(!this.OUndo) return;
119 var OU = this.OUndo, p = OU.Pos-1; if(p<0) return;
120 var t = null; 
121 if(type){
122    if(typeof(type)!="string") t = type;
123    else { t = {}; t[type] = 1; if(type2) t[type2] = 1; }
124    }
125 if(OU[p].Type!="End") {
126    p--; if(p<0) return;
127    if(OU[p].Type!="End"){ 
128       if(t&&!t[OU[p].Type]) return;
129       if(OU.length==OU.Pos){ OU[p+2] = OU[p+1]; OU[p+1] = OU[p]; OU[p] = { Type:"Start" }; OU[p+3] = { Type:"End" }; OU.Pos = OU.length; } 
130       else { OU.splice(p,2,{ Type:"Start" },OU[p],OU[p+1],{ Type:"End" }); OU.Pos += 2; }
131       }
132    else { 
133       if(t) for(var i=p-1;i&&OU[i].Type!="Start";i--) if(!t[OU[i].Type]) return; 
134       OU[p] = OU[p+1];
135       OU[p+1] = { Type:"End" };
136       }   
137    }
138 else { 
139    var n = 1; 
140    while(n&&p){ p--; if(OU[p].Type=="Start") n--; else if(OU[p].Type=="End") n++; }
141    p--; if(p<0) return;
142    if(OU[p].Type!="End") { 
143       if(t&&!t[OU[p].Type]) return;
144       OU[p+1] = OU[p];
145       OU[p] = { Type:"Start" };
146       }
147    else { 
148       if(t) for(var i=p-1;i&&OU[i].Type!="Start";i--) if(!t[OU[i].Type]) return; 
149       for(var i=p;i<OU.length-2;i++) OU[i] = OU[i+2];
150       OU.length -= 2;
151       if(OU.Pos>p) OU.Pos -= 2;
152       }
153    }
154 }
155 // -----------------------------------------------------------------------------------------------------------
156 TGP.CountUndo = function(cnt,blocks){
157 if(!cnt) cnt = 1e5;
158 var block = 0, items = 0, zal = cnt, L = this.Locked;
159 for(var i=this.OUndo.Pos-1;i>=0 && cnt;i--){
160    var t = this.OUndo[i].Type;
161    if(t=="End") block++;
162    else if(t=="Start") block--;
163    else if(L[CUndoLock[t]]) return 0;
164    else items++;
165    if(!block) cnt--;   
166    }
167 return blocks ? zal-cnt : items;   
168 }
169 // -----------------------------------------------------------------------------------------------------------
170 TGP.DoUndo = function(cnta,refresh,recur,hidemess){
171 MS.Master; if(this.MasterGrid) return this.MasterGrid.DoUndo(cnta,refresh); ME.Master;
172 if(this.EditMode&&this.Edit) { this.Edit.Undo(); return true; }
173 var OU = this.OUndo, upd = 0, recalc = 0;
174 if(!OU || !this.OUndo.Pos || this.AutoUpdate&&!(this.Undo&32)) return false;
175 var cnt = this.CountUndo(cnta);
176 if(!cnt) return false;
177 if(!recur && refresh && cnt>=this.SynchroCount) {
178    this.ShowMessage(this.GetText("DoUndo"));
179    var T = this; setTimeout(function(){ T.DoUndo(cnta,1,1,1); },10);
180    return;   
181    }
182 this.OUndo = null; 
183 var A = null, AC = null, anim = 0, slack = 0;
184 MS.Animate; 
185 if(!this.SuppressAnimations&&refresh&&this.AnimateUndo) { 
186    if(this.AnimateRows) { A = []; var T = this, FCnt = 0, F = [], FF = function(){ if(!--FCnt) T.ClearRows(F,1); } }        
187    if(this.AnimateCols) { AC = []; var T = this, FCCnt = 0, FC = [], FFC = function(){ if(!--FCCnt) T.DelColsUndo(FC); } }  
188    if(this.AnimateCells) anim = 1;
189    this.FinishAnimations();
190    }
191 ME.Animate;
192 this.InUndo = 1;
193 var autoupdate = this.AutoUpdate;
194 if(Grids.OnUndo) Grids.OnUndo(this,"Start");
195 if(cnt>3) { this.StartUpdate(); upd = 1; }
196 var auto = this.RemoveAutoPages, render = false, updhid = false, calctree = 0, dep = 0;
197 for(var oi=OU.Pos-1;oi>=0 && cnt;oi--,cnt--){
198    var U = OU[oi], t = U.Type;
199    if(auto && U.Row) while(U.Row.Removed==2) this.AddAutoPages();
200    switch(t){
201       case "Accept" :
202          if(OU.Rev) OU.Rev++; else OU.Rev = 1;
203          break;
204       case "Change" : 
205          if(U.Row.Removed) break; 
206          MS.Gantt; if(this.Gantt) this.CheckGantt(U.Row,U.Col,U.OldVal,1,1); ME.Gantt;
207          
208          if(OU.Rev) this.SetValue(U.Row,U.Col,U.OldVal,anim?"UndoChange":refresh);
209          else {
210             U.Row[U.Col+"Changed"] = U.CellChanged;
211             this.SetValue(U.Row,U.Col,U.OldVal,anim?"UndoChange":refresh,0,2,1,1,!U.CellChanged,null,U.UpdateHeight);
212             MS.Gantt; if(this.Gantt&&!slack) { if(cnt>20) slack = 1; else this.FillGanttSlack(U.Row,null,null,3); } ME.Gantt;
213             if(this.SaveOrder && !Is(U.Row,"NoUpload") && !U.CellChanged && U.Row.Kind!="Filter") this.SetChange({ Row:U.Row.id,Col:U.Col,Val:U.OldVal });
214             if(U.Row.Changed != U.RowChanged) { 
215                U.Row.Changed = U.RowChanged; 
216                if(this.ColorState&2) this.ColorRow(U.Row); 
217                MS.Master; if(U.Row.DetailRow) for(var i=0;i<U.Row.DetailRow.length;i++) { U.Row.DetailRow[i].Changed = 0; if(U.Row.DetailGrid[i].ColorState&2) U.Row.DetailGrid[i].ColorRow(U.Row.DetailRow[i]); } ME.Master;
218                }
219             }
220          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.NewVal);
221          recalc = 1;
222          break;
223       case "Add" :
224          if(U.Row.Removed) break; 
225          
226          if(OU.Rev){
227             var zal = U.Row.CanDelete; U.Row.CanDelete = 1;
228             this.DeleteRow(U.Row,2);
229             U.Row.CanDelete = zal;
230             }
231          else {
232             if(this.SaveOrder && !Is(U.Row,"NoUpload") && !U.Row.CPage) this.SetChange({ Row:U.Row.id,Deleted:1 });
233             if(refresh){
234                U.Row.Deleted = 1;
235                this.HideRow(U.Row,A?0:1,0,1);
236                this.Recalculate(U.Row,null,1);
237                MS.Animate; 
238                if(A) { A.push([U.Row,"UndoAdd",-1,FF]); F.push(U.Row); FCnt++; }
239                ME.Animate;
240                }
241             }
242          calctree = 1;
243          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Src);
244          if(!OU.Rev && (!refresh||!A)) this.DelRow(U.Row);
245          break;   
246       case "Remove" :
247       case "Delete" :
248          if(U.Row.Removed){ 
249             var P, N = U.NextId; if(N) N = this.Rows[N];
250             if(N) { 
251                P = N.parentNode;
252                if(U.Page && P.previousSibling) { P = P.previousSibling; N = null; }
253                }
254             else if(U.Page) P = this.XB.lastChild;
255             else if(U.Row.Fixed) P = U.Row.Fixed=="Head" ? this.XH : this.XF;
256             else P = this.Rows[U.ParentId];
257             if(P) { 
258                if(N) P.insertBefore(U.Row,N); else P.appendChild(U.Row); 
259                U.Row.Removed = null;
260                if(OU.Rev) U.Row.Added = 1; 
261                U.Row.Deleted = 0;
262                if(this.SetIds) this.Rows[U.Row.id] = U.Row;
263                this.LoadedCount++;
264                if(typeof(U.Row.Def)=="string") U.Row.Def = this.Def[U.Row.Def]; 
265                if(!U.Row.Def) U.Row.Def = this.Def.R;
266                U.Row.Visible = 0; if(!U.Row.Hidden) this.ShowRow(U.Row,null,null,1);
267                if(U.Row.Fixed&&!U.Row.r1) render = 1; 
268                if(P.Count!=null) P.Count++; 
269                }
270             if(t=="Remove"){
271                if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row);
272                break;
273                }
274             this.DeleteRowUndo(U.Row,"",refresh,upd);
275             }
276          else {
277             this.DeleteRowUndo(U.Row,U.Deleted,refresh);
278             if(U.Row.Fixed&&!U.Row.r1) render = 1; 
279             }
280          if(this.SaveOrder && !Is(U.Row,"NoUpload")) this.SetChange({ Row:U.Row.id,Deleted:0 });
281          if(!U.Row.Expanded && U.Expanded){
282             if(refresh) this.Expand(U.Row,null,null,null,1);
283             else U.Row.Expanded |= 1;
284             }
285          calctree = 1;
286          MS.Animate; if(A) A.push([U.Row,(U.Row.Deleted?"UndoUndelete":"UndoDelete")+(this.ShowDeleted?"Visible":""),-1]); ME.Animate;
287          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row);
288          break;   
289       case "Move" :
290          if(auto && U.OldParent) while(U.OldParent.Removed==2) this.AddAutoPages();
291          if(refresh) this.MoveRows(U.Row,U.OldNext?U.OldNext:U.OldParent,U.OldNext?1:2); 
292          else this.MoveRow(U.Row,U.OldParent,U.OldNext,refresh);
293          if(this.SaveOrder){
294             if(U.Moved&&typeof(U.Moved)=="object") for(var id in U.Moved) this.SetChange({ Row:this.Rows[id],Moved:U.Moved[id] });
295             else if(!Is(U.Row,"NoUpload")) this.SetChange({ Row:U.Row.id,Moved:U.Moved });
296             }
297          if(!autoupdate) {
298             function SetMoved(G,row,mov){
299                row.Moved = mov; if(refresh && G.ColorState&2) G.ColorRow(row);
300                if(row.DetailRow) for(var i=0;i<row.DetailRow.length;i++) SetMoved(row.DetailGrid[i],row.DetailRow[i],mov);
301                }
302             if(U.Moved&&typeof(U.Moved)=="object") for(var id in U.Moved) SetMoved(this,this.Rows[id],OU.Rev ? (U.Parent==U.OldParent&&U.Moved[id]!=2?1:2) : U.Moved[id]);
303             else SetMoved(this,U.Row,OU.Rev ? (U.Parent==U.OldParent&&U.Row.Moved!=2?1:2) : U.Moved);
304             }
305          calctree = 1;
306          MS.Animate; if(A) A.push([U.Row,"UndoMove",1]); ME.Animate;
307          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Parent,U.Next);
308          break;
309       case "DelPage":
310          this.XB.insertBefore(U.Page,U.Next);
311          this.AddBody(1,U.Page);
312          U.Page.State = 2;
313          U.Page.Removed = null;
314          
315          break;
316       case "Show":
317          this.HideRow(U.Row); calctree = 1; dep = 1;
318          MS.Animate; if(A) A.push([U.Row,"UndoShow",1]); ME.Animate;
319          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row);
320          break;
321       case "Hide":
322          this.ShowRow(U.Row); calctree = 1; dep = 1;
323          MS.Animate; if(A) A.push([U.Row,"UndoHide",1]); ME.Animate;
324          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row);
325          break;
326       case "Span" :
327          this.SplitSpanned(U.Row,U.Col);
328          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.Row2,U.Col2);
329          break;
330       case "Split" :
331       case "SplitAuto" : 
332          this.SpanRange(U.Row,U.Col,U.Row2,U.Col2);
333          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.Row2,U.Col2);
334          break;
335       case "ColsVisibility":
336          var zalren = this.Rendering; this.Rendering = 0;
337          this.ChangeColsVisibility(U.Hide,U.Show);
338          MS.Animate; if(AC) { if(U.Show) AC.push([U.Show,"UndoShowCol"+(U.Show.length>1?"s":"")],null,null,null,null,1); if(U.Hide) AC.push([U.Hide,"UndoHideCol"+(U.Hide.length>1?"s":"")]); } ME.Animate;
339          this.Rendering = zalren;
340          
341          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Show,U.Hide);
342          break;
343       case "MoveCol":
344          if(this.MoveCol(U.Col,U.ToOld,U.RightOld,null,1,null,1)) render = true;
345          
346          MS.Animate; if(AC) AC.push([U.Col,"UndoMoveCol"]); ME.Animate;
347          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Col,U.ToCol,U.Right);
348          break;
349       case "AddCol":
350          if(!AC||!this.FastColumns) this.DelCol(U.Col);
351          updhid = 1;
352          MS.Animate; if(AC&&this.FastColumns) { AC.push([U.Col,"UndoAddCol",FFC]); FC.push(U.Col); FCCnt++; } ME.Animate;
353          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Col,U.C);
354          break;
355       case "DeleteCol":
356          U.C.Deleted = 0;
357          if(U.C.Removed) { 
358             U.C.Removed = null; 
359             var pos = U.C.Pos;
360             for(var sec=U.C.Sec-1;sec>=1;sec--) pos += this.ColNames[sec].length;
361             U.C = this.AddCol(U.Col,U.C.MainSec,pos,U.C,U.Visible,null,null,1); 
362             }
363          this.DeleteColT(U.Col,U.Del?3:2,null,!U.Visible);
364          updhid = 1;
365          MS.Animate; if(AC) AC.push([U.Col,(U.Del?"UndoDeleteCol":"UndoUndeleteCol")+(this.ShowDeleted?"Visible":"")]); ME.Animate;
366          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Col,U.Del,U.C);
367          break;
368       case "ChangeDef" :
369          this.ChangeDef(U.Row,U.OldDef,refresh);
370          if(U.Values){ 
371             for(var c in U.Values) { 
372                U.Row[c+"Changed"] = U.Values[c][1];
373                this.SetValue(U.Row,c,U.Values[c][0],refresh,0,2,1,1,!U.Values[c][1]); 
374                if(U.Row.Changed != U.RowChanged) { U.Row.Changed = U.RowChanged; if(this.ColorState&2) this.ColorRow(U.Row); }
375                }
376             }
377          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Def);
378          break;
379       case "SetLink":
380       case "SetImg":
381       case "SetAttribute" :
382          this.SetAttribute(U.Row,U.Col,U.Attr,U.OldVal,refresh);
383          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.Attr,U.Val);
384          break;
385       case "EditAttrs" :
386          for(var j=0;j<U.Attrs.length;j++) U.Row[U.Col+U.Attrs[j]] = U.OldVals[j];
387          if(refresh) this.RefreshCell(U.Row,U.Col);
388          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.Attrs,U.Vals);
389          break;
390       
391       case "GanttBase" : 
392          MS.Gantt;
393          MS.GanttBackground; 
394          var C = this.Cols[U.Col];
395          C.GanttBase = U.OldBase;
396          this.UpdateGanttBase(U.Col);
397          if(!upd) this.CalculateSpaces(1); 
398          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OldBase,U.Col);
399          ME.GanttBackground; 
400          ME.Gantt;
401          break;
402       case "GanttFinish" :
403          MS.Gantt;
404          MS.GanttBackground; 
405          var C = this.Cols[U.Col];
406          C.GanttFinish = U.OldFinish;
407          this.UpdateGanttFinish(U.Col);
408          this.ShrinkGanttFinish(U.Col);
409          if(!upd) this.CalculateSpaces(1); 
410          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OldFinish,U.Col);
411          ME.GanttBackground; 
412          ME.Gantt;
413          break;
414       case "Custom": 
415          if(U.Undo && typeof(U.Undo)=="function") U.Undo(U.Object);
416          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Object);
417          break;
418       case "Focus":
419          if(auto && U.ORow) while(U.ORow.Removed==2) this.AddAutoPages();
420          var spec = render&&U.ORow&&!U.ORow.r1&&U.ORow.Fixed; 
421          if(spec) { var zl = this.Loading; this.Loading = 1; }
422          this.Focus(U.ORow,U.OCol,U.OPos,U.ORect,16);
423          if(spec) this.Loading = zl;
424          if(Grids.OnUndo) Grids.OnUndo(this,t,U.ORow,U.OCol,U.OPos,U.ORect);
425          break;
426       case "UpdateRowHeight":
427          this.UpdateRowHeight(U.Row,1);
428          break;
429       case "ResizeRow":
430          MS.RowResize;
431          
432          U.Row.Height = U.OHeight;
433          U.Row.OrigHeight = U.OrigHeight;
434          U.Row.Resized = U.Resized;
435          if(U.Row.Space) this.RefreshRow(U.Row);
436          else {
437             if(this.RowIndex) this.RefreshCell(U.Row,this.RowIndex); 
438             this.UpdateRowHeight(U.Row,1,0,1);
439             }
440          MS.Animate; if(A) A.push([U.Row,"UndoResize"]); ME.Animate;
441          if(Grids.OnUndo) Grids.OnUndo(this,t,U.ORow,U.OHeight);
442          ME.RowResize;
443          break;
444       case "ResizeCol":
445          if(U.OWidth==null){ this.Cols[U.Col].RelWidth = 1; this.Update(); }
446          else this.CapResize(U.Col,U.OWidth-this.Cols[U.Col].Width,U.Row,this.Cols[U.Col].Width,1);
447          MS.Animate; if(AC) AC.push([U.Col,"UndoResizeCol"]); ME.Animate;
448          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Col,U.OWidth);
449          break;
450       case "ResizeSec":
451          this.LeftWidth = U.OLeft; this.MidWidth = U.OMid; this.RightWidth = U.ORight;
452          this.Update();
453          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OLeft,U.OMid,U.ORight);
454          break;
455       case "ResizeMain":
456          this.MainTag.style.width = U.OWidth; this.MainTag.style.height = U.OHeight;
457          this.Update();
458          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OWidth,U.OHeight);
459          break;
460       case "Select":
461          if(U.OSel==null) break;
462          if(U.Row&&U.Col) this.SelectCell(U.Row,U.Col,U.OSel,0,0,1,!oi||cnt==1||OU[oi-1].Type!="Select"||OU[oi-1].Row!=U.Row);
463          else if(U.Row) { this.SelectRow(U.Row,U.OSel,0,0,1,1); MS.Animate; if(A) A.push([U.Row,U.OSel?"UndoSelect":"UndoDeselect"]); ME.Animate; }
464          else if(U.Col) { this.SelectCol(U.Col,U.OSel,0,1,0,1); MS.Animate; if(AC) AC.push([U.Col,U.OSel?"UndoSelectCol":"UndoDeselectCol"]); ME.Animate; }
465          else this.SelectAllRows(U.OSel,0,1);
466          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.OSel);
467          break;
468       case "Filter":
469          if(U.OpChange) U.Row[U.Col+"Filter"] = U.OldOp;
470          else U.Row[U.Col] = U.OldVal;
471          if(cnt<=1||!oi||OU[oi-1].Type!="Filter") this.DoFilter();
472          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.OldVal,U.OldOp,U.OpChange);
473          break;
474       case "Sort":
475          this.ChangeSort(U.OSort,0,0,0,1);
476          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OSort);
477          break;
478       case "Search":
479          this.DoSearch(U.OAction?U.OAction:"Clear",0,1);
480          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OAction);
481          break;
482       case "Filtered":
483          this.SetFiltered(U.OFiltered,0,null,1);
484          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OFiltered);
485          break;
486       case "Grouped":
487          if(U.OGrouped) this.DoGroupOn(null,1); else this.DoGroupOff(1);
488          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OGrouped);
489          break;
490       case "Sorted":
491          if(U.OSorted) this.ActionSortOn(null,0,null,1); else this.ActionSortOff(null,0,null,1);
492          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OSorted);
493          break;
494       case "Searched":
495          if(U.OSearched) this.ActionSearchOn(null,0,1); else this.ActionSearchOff(null,0,1);
496          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OSearched);
497          break;
498       case "EFormula":
499          U.Row[U.Col+"EFormula"] = U.OldVal;
500          if(U.NewVal) delete this.EFormulas[U.Row.id+"$"+U.Col+"$"+U.NewVal];
501          if(!U.Auto){
502             U.Row[U.Col+"Changed"] = U.CellChanged;
503             if(U.Row.Changed != U.RowChanged) { U.Row.Changed = U.RowChanged; if(refresh&&this.ColorState&2) this.ColorRow(U.Row); }
504             }
505          recalc = 1;
506          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.NewVal,U.Auto);
507          break;
508       case "Error":
509          U.Row[U.Col+"Error"] = U.OldVal;
510          this.ColorCell(U.Row,U.Col);
511          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Row,U.Col,U.NewVal);
512          break;
513       case "Scroll":
514          this.NoScrollUndoTo = new Date()-0+500;
515          if(U.NV!=null && U.NV!=U.OV) {
516             if(auto) while(U.OV > this.GetBodyScrollHeight()-this.GetBodyHeight()) this.AddAutoPages();
517             this.SetScrollTop(U.OV);
518             }
519          if(U.NH[0]!=null && U.NH[0]!=U.OH[0]) this.SetScrollLeft(U.OH[0],0);
520          if(U.NH[1]!=null && U.NH[1]!=U.OH[1]) {
521             if(auto) while(U.OH[1] > this.GetBodyScrollWidth(1)-this.GetBodyWidth(1)) this.AddAutoColPages();
522             this.SetScrollLeft(U.OH[1],1);
523             }
524          if(U.NH[2]!=null && U.NH[2]!=U.OH[2]) this.SetScrollLeft(U.OH[2],2);
525          if(Grids.OnUndo) Grids.OnUndo(this,t,U.OV,U.OH[0],U.OH[1],U.OH[2]);
526          break;
527       case "Border":
528          
529          break;
530       case "BorderRow":
531          
532          break;
533       case "BorderCol":
534          
535          break;
536       case "Style":
537       case "CanEdit":
538          var row = U.Row, col = U.Col, A = U.Old;
539          if(!row){
540             var C = this.Cols[col], R = this.Rows, Cells = U.Cells;
541             for(var n in A) C[n] = A[n];
542             for(var id in Cells){ var rr = Cells[id], r = R[id]; for(var c in rr) r[c] = rr[c]; }
543             for(var id in R) if(R[id].r1) if(U.Refresh==0) this.ColorCell(R[id],col); else this.RefreshCell(R[id],col);
544             }
545          else {
546             for(var n in A) row[n] = A[n];
547             if(U.Refresh==0){ if(col) this.ColorCell(row,col); else this.ColorRow(row); }
548             else if(col) this.RefreshCell(row,col); else this.RefreshRow(row);
549             MS.Animate; if(anim&&row&&col) this.AnimCell(row,col,"UndoStyle"); ME.Animate;
550             }
551          if(Grids.OnUndo) Grids.OnUndo(this,t,row,col,A,U.Cells);
552          break;
553       case "IndentCol":
554          this.Cols[U.Col].Level = U.OldLevel;
555          var O = U.Rows, R = this.Rows; for(var id in O){ for(var a in O[id]) R[id][a] = O[id][a]; this.RefreshRow(R[id]); }
556          if(U.Show) this.HideRow(R[U.Show]);
557          if(U.Hide) this.ShowRow(R[U.Hide]);
558          if(Grids.OnUndo) Grids.OnUndo(this,t,col,U.OldLevel,U.Rows);
559          break;
560       case "Name":
561          this.ChangeName(U.New,U.Old,0,0); recalc = 1;
562          if(Grids.OnUndo) Grids.OnUndo(this,t,U.New,U.Old);
563          break;
564       case "AddSpan":
565       case "RemoveSpan":
566          var D = U.Data, R = {};
567          for(var i=D.length-4;i>=0;i-=4) {
568             if(!D[i+3]||!this.Rows[D[i]][D[i+1]] && !D.RefreshRow[D[i]]) R[D[i]] = 1;
569             this.Rows[D[i]][D[i+1]] = D[i+3];
570             }
571          for(var id in D.UpdateSpan) this.UpdateSpan(this.Rows[id]);
572          for(var i=0;i<D.RefreshCell.length;i+=2) this.RefreshCell(this.Rows[D.RefreshCell[i]],D.RefreshCell[i+1]);
573          if(t=="RemoveSpan") for(var id in D.UpdateRowSpan) this.UpdateRowSpan(this.Rows[id],1);
574          for(var id in D.RefreshRow) this.RefreshRow(this.Rows[id]);
575          for(var id in R) this.RefreshRow(this.Rows[id]);
576          if(Grids.OnUndo) Grids.OnUndo(this,t,D);
577          break;
c35f05 578       case "CreateRowSpan": break;
25ab64 579       case "Calendars":
F 580          this.ChangeGanttCalendars(U.Old);
581          if(U.OldExclude!=null) { var C = this.Cols[this.GetFirstGantt()]; if(C&&C.GanttExclude!=U.OldExclude) { C.GanttExclude = U.OldExclude; this.CalculateSpaces(1); } }
582          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Old,U.OldExclude);
583          break;
584       case "FixAbove":
585          this.FixAbove(U.First,null,null,1);
586          render = 2;
587          if(Grids.OnUndo) Grids.OnUndo(this,t,U.First);
588          break;
589       case "FixBelow":
590          this.FixAbove(U.Last,null,null,1);
591          render = 2;
592          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Last);
593          break;
594       case "FixPrev":
595          this.FixPrev(U.First,null,null,null,1);
596          render = 1;
597          if(Grids.OnUndo) Grids.OnUndo(this,t,U.First);
598          break;
599       case "FixNext":
600          this.FixAbove(U.Last,null,null,null,1);
601          render = 1;
602          if(Grids.OnUndo) Grids.OnUndo(this,t,U.Last);
603          break;
604
605       default: cnt++;
606       }
607    }
608 while(oi>=0 && OU[oi].Type=="Start") oi--;
609 OU.Pos = oi+1;
610 MS.Gantt; if(slack) this.FillGanttSlack(null,null,null,3); ME.Gantt;
611 if(hidemess) this.HideMessage();
612 if(upd) this.EndUpdate();
613 if(Grids.OnUndo) Grids.OnUndo(this,"End");
614 this.InUndo = 0;
615  
616 this.OUndo = OU;
617 MS.Gantt; if(dep&&this.GanttDependency) this.RefreshGantt(17); ME.Gantt;
618 if(calctree&&this.MainCol) this.CalcTreeWidth(render);
619 if(render==2&&(this.Paging==1||this.Paging==2)) this.CreatePages();
620 if(render) this.Render();
621 else if(updhid) this.UpdateHidden();
622 MS.Animate; this.OUndo = null; if(A) this.AnimRows(A); if(AC) this.AnimCols(AC); this.OUndo = OU; ME.Animate; 
623 if(this.DetailSelected) for(var i=0;i<Grids.length;i++) if(Grids[i] && Grids[i].Undo && Grids[i].MasterGrid==this) Grids[i].CalculateSpaces(1);
624 this.CalculateSpaces(1);
625 return true;
626 }
627 // -----------------------------------------------------------------------------------------------------------
628 TGP.CountRedo = function(cnt,blocks){
629 if(!cnt) cnt = 1e5;
630 var block = 0, items = 0, zal = cnt, L = this.Locked;
631 for(var i=this.OUndo.Pos;i<this.OUndo.length && cnt;i++){
632    var t = this.OUndo[i].Type;
633    if(t=="End") block--;
634    else if(t=="Start") block++;
635    else if(L[CUndoLock[t]]) return 0;
636    else items++;
637    if(!block) cnt--;   
638    }
639 return blocks ? zal-cnt : items;
640 }
641 // -----------------------------------------------------------------------------------------------------------
642 TGP.DoRedo = function(cnta,refresh,recur,hidemess){
643 MS.Master; if(this.MasterGrid) return this.MasterGrid.DoRedo(cnta,refresh); ME.Master;
644 if(this.EditMode&&this.Edit) { this.Edit.Redo(); return true; }
645 var OU = this.OUndo, upd = 0, recalc = 0;
646 if(!OU || !OU.length || this.AutoUpdate&&!(this.Undo&32)) return false;
647 var cnt = this.CountRedo(cnta);
648 if(!cnt) return false;
649 if(!recur && refresh && cnt>=this.SynchroCount) {
650    this.ShowMessage(this.GetText("DoRedo"));
651    var T = this; setTimeout(function(){ T.DoRedo(cnta,1,1,1); },10);
652    return;   
653    }
654 this.OUndo = null; 
655 var A = null, AC = null, anim = 0, slack = 0;
656 MS.Animate; 
657 if(!this.SuppressAnimations&&refresh&&this.AnimateUndo) { 
658    if(this.AnimateRows) { A = []; var T = this, FCnt = 0, F = [], FF = function(){ if(!--FCnt) T.ClearRows(F,1); } }  
659    if(this.AnimateCols) { AC = []; var T = this, FCCnt = 0, FC = [], FFC = function(){ if(!--FCCnt) T.DelColsUndo(FC); } } 
660    if(this.AnimateCells) anim = 1;
661    this.FinishAnimations();
662    }
663 ME.Animate;
664 this.InUndo = 1;
665 var autoupdate = this.AutoUpdate;
666 if(Grids.OnRedo) Grids.OnRedo(this,"Start");
667 if(cnt>3) { this.StartUpdate(); upd = 1; }
668 var auto = this.RemoveAutoPages, render = false, updhid = false, calctree = 0, dep = 0;
669 for(var oi=OU.Pos;oi<OU.length && cnt;oi++,cnt--){
670    var U = OU[oi], t = U.Type;
671    if(auto && U.Row) while(U.Row.Removed==2) this.AddAutoPages();
672    switch(t){
673       case "Accept" :
674          if(OU.Rev) OU.Rev--;
675          
676          break;
677       case "Change" : 
678          MS.Gantt; if(this.Gantt) this.CheckGantt(U.Row,U.Col,U.NewVal,1,1); ME.Gantt;
679          
680          this.SetValue(U.Row,U.Col,U.NewVal,anim?"RedoChange":refresh,null,null,null,null,null,null,U.UpdateHeight);
681          MS.Gantt; if(this.Gantt&&!slack) { if(cnt>20) slack = 1; else this.FillGanttSlack(U.Row,null,null,3); } ME.Gantt;
682          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.OldVal);
683          recalc = 1;
684          break;
685       case "Add" :
686       
687          MS.Add;
688          if(OU.Rev && !U.Row.Removed){
689             var zal = U.Row.CanDelete; U.Row.CanDelete = 1;
690             this.DeleteRow(U.Row,3);
691             U.Row.CanDelete = zal;
692             }
693          else {
694             if(auto && U.Parent) while(U.Parent.Removed==2) this.AddAutoPages();
695             
696             U.Row.DetailRow = null;
697             if(U.Src) { var vis = U.Src.Visible; U.Src.Visible = U.SrcVisible; }
698             this.AddRow(U.Parent,U.Next,refresh,U.Id,U.Def,U.Src,null,null,null,U.Row);
699             if(U.Src) U.Src.Visible = vis;
700             if(U.Copy) {
701                U.Row.State = 0;
702                U.Row.Count = U.Count;
703                U.Row.Copy = U.Copy;
704                this.UpdateIcon(U.Row);
705                }
706             if(U.Expanded!=null) { U.Row.Expanded = U.Expanded; this.UpdateIcon(U.Row); }
707             if(U.Deleted!=null) { U.Row.Deleted = U.Deleted; if(this.ColorState&2) this.ColorRow(U.Row); }
708
709             }
710          if(!upd) this.Recalculate(U.Row,null,refresh);
711          if(OU.Rev && refresh) this.UploadChanges(U.Row);
712          calctree = 1;
713          
714          MS.Animate; if(A) A.push([U.Row,"RedoAdd"]); ME.Animate;
715          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Src);
716          ME.Add;
717          break; 
718       case "Delete" :
719          
720          MS.Delete;
721          if(this.SaveOrder && !Is(U.Row,"NoUpload")) this.SetChange({ Row:U.Row.id,Deleted:1 });
722          this.DeleteRowRedo(U.Row,U.Del,refresh,upd,U.Removed&&!A);
723          if(refresh&&OU.Rev) this.UploadChanges(U.Row);
724          calctree = 1;
725          MS.Animate; 
726          if(A) {
727             A.push([U.Row,(!U.Row.Deleted?"RedoUndelete":"RedoDelete")+(this.ShowDeleted?"Visible":""),-1,U.Removed?FF:null]); 
728             if(U.Removed) { F[F.length] = U.Row; FCnt++; }
729             }
730          ME.Animate;
731          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row);
732          ME.Delete;
733          break;   
734       case "Remove": break;
735       case "Move" :
736          MS.Move; 
737          if(auto && U.Parent) while(U.Parent.Removed==2) this.AddAutoPages();
738          if(refresh) this.MoveRows(U.Row,U.Next?U.Next:U.Parent,U.Next?1:2); 
739          else this.MoveRow(U.Row,U.Parent,U.Next,refresh); 
740          if(OU.Rev && !autoupdate){
741             for(var p=oi+1,rev=OU.Rev,mov=0;p<OU.length;p++){
742                if(OU[p].Type=="Accept" && !--rev) {
743                   if(p<=cnt) mov = U.Row.Moved;
744                   break;
745                   }
746                if(OU[p].Type=="Move" && OU[p].Row==U.Row) {
747                   if(OU[p].Parent==OU[p].OldParent) { if(!mov) mov = 1; }
748                   else { mov = 2; break; }
749                   }
750                }
751             if(U.Row.Moved!=mov) { U.Row.Moved = mov; if(this.ColorState&2) this.ColorRow(U.Row); }
752             }
753          calctree = 1;
754          MS.Animate; if(A) A.push([U.Row,"RedoMove",1]); ME.Animate;
755          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.OldParent,U.OldNext);
756          ME.Move;
757          break;
758       case "DelPage": break;
759       case "Show":
760          this.ShowRow(U.Row); calctree = 1; dep = 1;
761          MS.Animate; if(A) A.push([U.Row,"RedoShow",1]); ME.Animate;
762          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row);
763          break;
764       case "Hide":
765          this.HideRow(U.Row); calctree = 1; dep = 1;
766          MS.Animate; if(A) A.push([U.Row,"RedoHide",1]); ME.Animate;
767          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row);
768          break;         
769       case "Span" :
770          this.SpanRange(U.Row,U.Col,U.Row2,U.Col2,U.Plus);
771          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.Row2,U.Col2);
772          break;
773       case "SplitAuto" :
774          break;
775       case "Split" :
776          this.SplitSpanned(U.Row,U.Col);
777          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.Row2,U.Col2);
778          break;
779       case "ColsVisibility":
780          var zalren = this.Rendering; this.Rendering = 0;
781          this.ChangeColsVisibility(U.Show,U.Hide);
782          MS.Animate; if(AC) { if(U.Show) AC.push([U.Show,"RedoShowCol"+(U.Show.length>1?"s":"")]); if(U.Hide) AC.push([U.Hide,"RedoHideCol"+(U.Hide.length>1?"s":""),null,null,null,null,1]); } ME.Animate;
783          this.Rendering = zalren;
784          
785          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Show,U.Hide);
786          break;
787       case "MoveCol":
788          if(this.MoveCol(U.Col,U.ToCol,U.Right,null,1,null,1)) render = true;
789          
790          MS.Animate; if(AC) AC.push([U.Col,"RedoMoveCol"]); ME.Animate;
791          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Col,U.ToOld,U.RightOld);
792          break;
793       case "AddCol":
794          this.AddCol(U.Col,U.C.MainSec,U.C.Pos,U.C,U.Visible);
795          updhid = 1;
796          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Col,U.C);
797          MS.Animate; if(AC) AC.push([U.Col,"RedoAddCol"]); ME.Animate;
798          break;
799       case "DeleteCol":
800          this.DeleteColT(U.Col,U.Del?2:3,U.Removed,U.Removed&&AC);
801          updhid = 1;
802          MS.Animate; if(AC) { AC.push([U.Col,(U.Del?"RedoDeleteCol":"RedoUndeleteCol")+(this.ShowDeleted?"Visible":""),U.Removed?FFC:null,null,null,null,1]); if(U.Removed){ FC.push(U.Col); FCCnt++; } } ME.Animate;
803          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Col,U.Del,U.C);
804          break;
805       case "ChangeDef" :
806          this.ChangeDef(U.Row,U.Def,refresh);
807          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.OldDef);
808          break;
809       case "SetLink":
810       case "SetImg":
811       case "SetAttribute" :
812          this.SetAttribute(U.Row,U.Col,U.Attr,U.Val,refresh);
813          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.Attr,U.OldVal);
814          break;
815       case "EditAttrs" :
816          for(var j=0;j<U.Attrs.length;j++) U.Row[U.Col+U.Attrs[j]] = U.Vals[j];
817          if(refresh) this.RefreshCell(U.Row,U.Col);
818          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.Attrs,U.OldVals);
819          break;
820       
821       case "GanttBase" : 
822          MS.Gantt;
823          var C = this.Cols[U.Col];
824          C.GanttBase = U.Base;
825          this.UpdateGanttBase(U.Col);
826          if(!upd) this.CalculateSpaces(1); 
827          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Base,U.Col);
828          ME.Gantt;
829          break;
830       case "GanttFinish" :
831          MS.Gantt;
832          var C = this.Cols[U.Col];
833          C.GanttFinish = U.Finish;
834          this.UpdateGanttFinish(U.Col);
835          this.ShrinkGanttFinish(U.Col);
836          if(!upd) this.CalculateSpaces(1); 
837          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Finish,U.Col);
838          ME.Gantt;
839          break;
840       case "Custom": 
841          if(U.Redo && typeof(U.Redo)=="function") U.Redo(U.Object);
842          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Object);
843          break;
844       case "Focus":
845          this.Focus(U.Row,U.Col,U.Pos,U.Rect,16);
846          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.Pos,U.Rect);
847          break;
848       case "ResizeRow":
849          MS.RowResize;
850          this.ResizeRow(U.Row,U.Height,1);
851          MS.Animate; if(A) A.push([U.Row,"RedoResize"]); ME.Animate;
852          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Height);
853          ME.RowResize;
854          break;
855       case "ResizeCol":
856          this.CapResize(U.Col,U.Width-this.Cols[U.Col].Width,U.Row,this.Cols[U.Col].Width,1);
857          MS.Animate; if(AC) AC.push([U.Col,"RedoResizeCol"]); ME.Animate;
858          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Col,U.Width);
859          break;
860       case "ResizeSec":
861          this.LeftWidth = U.Left; this.MidWidth = U.Mid; this.RightWidth = U.Right;
862          this.Update();
863          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Left,U.Mid,U.Right);
864          break;
865       case "ResizeMain":
866          this.MainTag.style.width = U.Width; this.MainTag.style.height = U.Height;
867          this.Update();
868          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Width,U.Height);
869          break;
870       case "Select":
871          if(U.Sel==null) break;
872          if(U.Row&&U.Col) this.SelectCell(U.Row,U.Col,U.Sel,0,0,1,oi==OU.length-1||cnt==1||OU[oi+1].Type!="Select"||OU[oi+1].Row!=U.Row);
873          else if(U.Row) { this.SelectRow(U.Row,U.Sel,0,0,1,1); MS.Animate; if(A) A.push([U.Row,U.Sel?"RedoSelect":"RedoDeselect"]); ME.Animate; }
874          else if(U.Col) { this.SelectCol(U.Col,U.Sel,0,1,0,1); MS.Animate; if(AC) AC.push([U.Col,U.Sel?"RedoSelectCol":"RedoDeselectCol"]); ME.Animate; }
875          else this.SelectAllRows(U.Sel,0,1);
876          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.Sel);
877          break;
878       case "Filter":
879          if(U.OpChange) U.Row[U.Col+"Filter"] = U.NewOp;
880          else U.Row[U.Col] = U.NewVal;
881          if(cnt<=1||oi==OU.length-1||OU[oi+1].Type!="Filter") this.DoFilter();
882          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.NewVal,U.NewOp,U.OpChange);
883          break;
884       case "Sort":
885          this.ChangeSort(U.Sort,0,0,0,1);
886          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Sort);
887          break;
888       case "Search":
889          this.DoSearch(U.Action?U.Action:"Clear",0,1);
890          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Action);
891          break;
892       case "Filtered":
893          this.SetFiltered(U.Filtered,0,null,1);
894          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Filtered);
895          break;
896       case "Grouped":
897          if(U.Grouped) this.DoGroupOn(null,1); else this.DoGroupOff(1);
898          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Grouped);
899          break;
900       case "Sorted":
901          if(U.Sorted) this.ActionSortOn(null,0,null,1); else this.ActionSortOff(null,0,null,1);
902          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Sorted);
903          break;
904       case "Searched":
905          if(U.Searched) this.ActionSearchOn(null,0,1); else this.ActionSearchOff(null,0,1);
906          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Searched);
907          break;
908       case "EFormula":
909          U.Row[U.Col+"EFormula"] = U.NewVal;
910          if(U.OldVal) delete this.EFormulas[U.Row.id+"$"+U.Col+"$"+U.OldVal];
911          if(!U.Auto){
912             var nochg = this.GetAttr(U.Row,U.Col,"NoChanged");
913             if(!nochg){  
914                if(!U.Row[U.Col+"Changed"]) { U.Row[U.Col+"Changed"] = 1; if(U.Row.Changed && refresh) this.ColorCell(U.Row,U.Col); }
915                if(!U.Row.Changed) { U.Row.Changed = 1; if(refresh && this.ColorState&2) this.ColorRow(U.Row); }
916                }
917             }
918          recalc = 1;
919          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.OldVal);
920          break;
921       case "Error":
922          U.Row[U.Col+"Error"] = U.NewVal;
923          this.ColorCell(U.Row,U.Col);
924          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.OldVal);
925          break;
926       case "Scroll":
927          this.NoScrollUndoTo = new Date()-0+500;
928          if(U.NV!=null && U.NV!=U.OV) {
929             if(auto) while(U.NV > this.GetBodyScrollHeight()-this.GetBodyHeight()) this.AddAutoPages();
930             this.SetScrollTop(U.NV);
931             }
932          if(U.NH[0]!=null && U.NH[0]!=U.OH[0]) this.SetScrollLeft(U.NH[0],0);
933          if(U.NH[1]!=null && U.NH[1]!=U.OH[1]) {
934             if(auto) while(U.NH[1] > this.GetBodyScrollWidth(1)-this.GetBodyWidth(1)) this.AddAutoColPages();
935             this.SetScrollLeft(U.NH[1],1);
936             }
937          if(U.NH[2]!=null && U.NH[2]!=U.OH[2]) this.SetScrollLeft(U.NH[2],2);
938          if(Grids.OnRedo) Grids.OnRedo(this,t,U.NV,U.NH[0],U.NH[1],U.NH[2]);
939          break;
940       case "Border":
941          
942          break;
943       case "BorderRow":
944          
945          break;
946       case "BorderCol":
947          
948          break;
949       case "Style":
950          this.SetCellStyle(U.Row,U.Col,U.Val,1);
951          MS.Animate; if(anim&&U.Row&&U.Col) this.AnimCell(U.Row,U.Col,"RedoStyle"); ME.Animate;
952          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.Val);
953          break;
954       case "CanEdit":
955          this.SetCanEdit(U.Row,U.Col,U.Val["CanEdit"]);
956          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row,U.Col,U.Val);
957          break;
958       case "IndentCol":
959          this.IndentCols(U.Col,0,0,U.NewLevel<U.OldLevel?1:0);
960          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Col,U.NewLevel);
961          break;
962       case "Name":
963          this.ChangeName(U.Old,U.New,0,0); recalc = 1;
964          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Old,U.New);
965          break;
966       case "AddSpan":
967       case "RemoveSpan":
968          if(U.Remove) break; 
969          var D = U.Data, R = {};
970          for(var i=0;i<D.length;i+=4) {
971             if(!D[i+2]||!this.Rows[D[i]][D[i+1]] && !D.RefreshRow[D[i]]) R[D[i]] = 1;
972             this.Rows[D[i]][D[i+1]] = D[i+2];
973             }
974          for(var id in D.UpdateSpan) this.UpdateSpan(this.Rows[id]);
975          for(var i=0;i<D.RefreshCell.length;i+=2) this.RefreshCell(this.Rows[D.RefreshCell[i]],D.RefreshCell[i+1]);
976          if(t=="AddSpan") for(var id in D.UpdateRowSpan) this.UpdateRowSpan(this.Rows[id],1);
977          for(var id in D.RefreshRow) this.RefreshRow(this.Rows[id]);
978          for(var id in R) this.RefreshRow(this.Rows[id]);
979          if(Grids.OnRedo) Grids.OnRedo(this,t,D);
980          break;
c35f05 981       case "CreateRowSpan":
F 982          var r = U.Row, chg = 0;
983          for(var col in this.SpanCols) if(this.CreateRowSpan(r,col)) chg++; 
984          if(chg) { 
985             this.ClearChildren(r); r.State = 3; this.RenderPage(r);  
986             }
987          break;
25ab64 988       case "Calendars":
F 989          this.ChangeGanttCalendars(U.New);
990          if(U.NewExclude!=null) { var C = this.Cols[this.GetFirstGantt()]; if(C&&C.GanttExclude!=U.NewExclude) { C.GanttExclude = U.NewExclude; this.CalculateSpaces(1); } }
991          if(Grids.OnRedo) Grids.OnRedo(this,t,U.New,U.NewExclude);
992          break;
993       case "FixAbove":
994          this.FixAbove(U.Row,null,null,1);
995          render = 2;
996          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row);
997          break;
998       case "FixBelow":
999          this.FixBelow(U.Row,null,null,1);
1000          render = 2;
1001          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Row);
1002          break;
1003       case "FixPrev":
1004          this.FixPrev(U.Col,null,null,null,1);
1005          render = 1;
1006          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Col);
1007          break;
1008       case "FixNext":
1009          this.FixNext(U.Col,null,null,null,1);
1010          render = 1;
1011          if(Grids.OnRedo) Grids.OnRedo(this,t,U.Col);
1012          break;
1013       default: cnt++;
1014       }
1015    }
1016 while(oi<OU.length && OU[oi].Type=="End") oi++;
1017
1018 MS.Gantt; if(slack) this.FillGanttSlack(null,null,null,3); ME.Gantt;
1019 OU.Pos = oi;
1020 if(hidemess) this.HideMessage();
1021 if(upd) this.EndUpdate();
1022 if(Grids.OnRedo) Grids.OnRedo(this,"End");
1023 this.InUndo = 0;
1024
1025 this.OUndo = OU;
1026 MS.Gantt; if(dep&&this.GanttDependency) this.RefreshGantt(17); ME.Gantt;
1027 if(calctree&&this.MainCol) this.CalcTreeWidth(render);
1028 if(render==2&&(this.Paging==1||this.Paging==2)) this.CreatePages();
1029 if(render) this.Render();
1030 else if(updhid) this.UpdateHidden();
1031 MS.Animate; this.OUndo = null; if(A) this.AnimRows(A); if(AC) this.AnimCols(AC); this.OUndo = OU; ME.Animate; 
1032 if(this.DetailSelected) for(var i=0;i<Grids.length;i++) if(Grids[i] && Grids[i].Undo && Grids[i].MasterGrid==this) Grids[i].CalculateSpaces(1);
1033 this.CalculateSpaces(1);
1034 return true;
1035 }
1036 // -----------------------------------------------------------------------------------------------------------
1037 TGP.DelColsUndo = function(FC){
1038 var OU = this.OUndo; this.OUndo = null;
1039 this.NoUpdateHeights = new Date()-0;
1040 for(var i=0;i<FC.length;i++) this.DelCol(FC[i]);
1041 this.NoUpdateHeights = null;
1042 this.UpdateHeights();
1043 this.OUndo = OU;
1044 this.CalculateSpaces(1); 
1045 }
1046 // -----------------------------------------------------------------------------------------------------------
1047 MS.Debug;
1048 // -----------------------------------------------------------------------------------------------------------
1049 TGP.DebugUndo = function(){
1050 var OU = this.OUndo, upd = 0, s = "var G=TGGrids['"+this.id+"'];\n";
1051 for(var i=0;i<this.OUndo.Pos;i++){
1052    var U = OU[i];
1053    switch(U.Type){
1054       case "Change" : 
1055          s += "G.SetValue(G.Rows['"+U.Row.id+"'],'"+U.Col+"','"+U.NewVal+"',1);\n";
1056          break;
1057       case "Add" :
1058       case "Copy" :
1059          MS.Add;
1060          var or = U.Row;
1061          if(U.Type=="Add") s += "G.AddRow("+(U.Parent?(U.Parent.Page?"TGGetNode(G.XB,"+this.GetPageNum(U.Parent)+")":"G.Rows['"+U.Parent.id+"']"):"null")+","+(U.Next?"G.Rows['"+U.Next.id+"']":"null")+",1,"+(U.Id?"'"+U.Id+"'":"null")+","+(U.Def?"'"+U.Def+"'":"null")+","+(U.Master?1:0)+");\n";
1062          else s += "var r=G.CopyRow("+(U.Source?"G.Rows['"+U.Source.id+"']":"null")+","+(U.Parent?(U.Parent.Page?"TGGetNode(G.XB,"+this.GetPageNum(U.Parent)+")":"G.Rows['"+U.Parent.id+"']"):"null")+","+(U.Next?"G.Rows['"+U.Next.id+"']":"null")+","+(U.Grid?U.Grid.This:"null")+",0,"+U.Empty+","+(U.Id?"'"+U.Id+"'":"null")+");var p=r.parentNode,e=p.Expanded;"+this.This+".ShowRow(r);if(e!=p.Expanded)"+this.This+".Collapse(p);\n";
1063          ME.Add;
1064          break;   
1065       case "Delete" :
1066          s += "G.DeleteRowT(G.Rows['"+U.Row.id+"'],"+(U.Deleted?3:2)+",0);\n";
1067          break;   
1068       case "Move" :
1069          s += "G.MoveRow(G.Rows['"+U.Row.id+"'],"+(U.Parent?"G.Rows['"+U.Parent.id+"']":"null")+","+(U.Next?"G.Rows['"+U.Next.id+"']":"null")+",1);\n";
1070          break;   
1071       case "Span" :
1072          s += "G.SpanRange(G.Rows['"+U.Row.id+"'],'"+U.Col+"',G.Rows['"+U.Row2.id+"'],'"+U.Col2+"');\n";
1073          break;
1074       case "Split" :
1075          s += "G.SplitSpanned(G.Rows['"+U.Row.id+"'],'"+U.Col+"');\n";
1076          break;
1077       case "MoveCol":
1078          s += "G.MoveCol('"+U.Col+"','"+U.ToCol+"',"+U.Right+");\n";
1079          break;
1080       case "ChangeDef" :
1081          s += "G.ChangeDef(G.Rows['"+U.Row.id+"'],'"+U.Def.Name+",1');\n";
1082          break;
1083       case "SetAttribute" :
1084          s += "G.SetAttribute(G.Rows['"+U.Row.id+"'],'"+U.Col+"','"+U.Attr+"','"+U.Val+"',1);\n";
1085          break;
1086       }
1087    }
1088 return s;
1089 }
1090 // -----------------------------------------------------------------------------------------------------------
1091 TGP.ActionDebugUndo = function(){  
1092 if(!this.DebugFlags["error"]) return;
1093 var s = this.DebugUndo();
1094 this.CloseDialog();
1095 this.Dialog = ShowDialog({
1096    Head:"Debug undo",
1097    Body:"<textarea id='DebugUndo' style='width:"+(this.MainTag.offsetWidth-10)+"px;height:"+(this.MainTag.offsetHeight-50)+"px;'>"+StringToXml(s)+"</textarea>",
1098    Foot:"<button class='"+this.Img.Style+"MenuButton' style='width:60px;' onclick='"+this.This+".CloseDialog();'>OK</button>"
1099       + "<button class='"+this.Img.Style+"MenuButton' style='width:60px;' onclick='"+this.This+".ActionTestUndo()'>Test</button>",
1100    Modal:1
1101    },{Tag:this.MainTag,Align:"center middle"});
1102
1103 }
1104 // -----------------------------------------------------------------------------------------------------------
1105 TGP.ActionTestUndo = function(){  
1106 if(!this.DebugFlags["error"]) return;
1107 var s = this.DebugUndo();
1108 this.CloseDialog();
1109 Grids.OnRenderPageFinishZal = Grids.OnRenderPageFinish;
1110 Grids.OnRenderPageFinish = new Function("G","setTimeout(function(){"+s+";alert('Undo actions finished');},100);TGGrids.OnRenderPageFinish=TGGrids.OnRenderPageFinishZal;if(Grids.OnRenderPageFinish)TGGrids.OnRenderPageFinish(G);");
1111 this.Reload();
1112 }
1113 // -----------------------------------------------------------------------------------------------------------
1114 ME.Debug;
1115 // -----------------------------------------------------------------------------------------------------------
1116 TGP.ActionUndo = function(dummy,T){ return T ? this.CanUndo() : this.DoUndo(1,1); }
1117 TGP.ActionUndoAll = function(dummy,T){ return T ? (this.MasterGrid?this.MasterGrid.CountUndo(null,1):this.CountUndo(null,1)) : this.DoUndo(0,1); }
1118 TGP.ActionRedo = function(dummy,T){ return T ? this.CanRedo() : this.DoRedo(1,1); }
1119 TGP.ActionRedoAll = function(dummy,T){ return T ? (this.MasterGrid?this.MasterGrid.CountRedo(null,1):this.CountRedo(null,1)) : this.DoRedo(0,1); }
1120 TGP.ActionClearUndo = function(dummy,T){ if(T) return this.CanUndo()||this.CanRedo(); this.ClearUndo(); return true; }
1121 // -----------------------------------------------------------------------------------------------------------
1122 ME.Undo;