Advertisement
Guest User

Untitled

a guest
Aug 5th, 2012
22
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.87 KB | None | 0 0
  1. BeginPackage["Undo`"]
  2. SetUpUndo::usage="";
  3.  
  4. Begin["`Private`"]
  5.  
  6. getCellID[]:="CellID"/.Developer`CellInformation[EvaluationNotebook[]]
  7.  
  8. ClearAll[appendEvents];
  9. appendEvents[evList_,(Rule|RuleDelayed)[lhs_,rhs_]]/;MemberQ[evList, (Rule|RuleDelayed)[lhs,_]]:=evList/.(Rule|RuleDelayed)[lhs,sth_]:>(lhs:>(sth;rhs));
  10. appendEvents[evList_, ev_]:=Append[evList, ev]
  11.  
  12. checkCreateUndoNotebook[]:=Refresh[
  13. With[{nb:=CurrentValue[EvaluationNotebook[], {TaggingRules,"undoNotebook"}]},
  14. If[(* if the undo notebook is not created or open *)!TrueQ@NotebookTools`NotebookOpenQ@nb,
  15. nb=CreateDocument[{}, CellGrouping->Manual,Visible->False,ShowSelection->False,
  16. WindowTitle->FileBaseName[WindowTitle/.AbsoluteOptions[EvaluationNotebook[], WindowTitle]]<>"_undoData"];
  17. ]], None]
  18.  
  19. nbdeRules={Dynamic[rhs_]:>Dynamic[rhs; Needs["Undo`"];Undo`Private`checkCreateUndoNotebook[]], Null:>Dynamic[Needs["Undo`"];Undo`Private`checkCreateUndoNotebook[]],rhs_:>Dynamic[rhs;Needs["Undo`"];Undo`Private`checkCreateUndoNotebook[]]};
  20.  
  21. parseNBEOptions[nb_]:=ReleaseHold@Replace[Hold[NotebookDynamicExpression]/.Options[nb, NotebookDynamicExpression], nbdeRules, {1}]
  22.  
  23. appendNDE[nb_NotebookObject]:=SetOptions[nb, parseNBEOptions[nb]/.newNDE_:>NotebookDynamicExpression:>newNDE]
  24.  
  25. appendNEA[nb_NotebookObject]:=(* appends the notebook event action WindowClose *)
  26. appendEvents[Replace[NotebookEventActions/.Options[nb, NotebookEventActions], None:>{}], "WindowClose":>NotebookClose@CurrentValue[EvaluationNotebook[], {TaggingRules,"undoNotebook"}]]/.newOpts_:>SetOptions[nb, NotebookEventActions:>newOpts]
  27.  
  28. SetUpUndo[nb_NotebookObject,styles_List]:=SetOptions[initializeNotebook[nb];nb, StyleDefinitions->Fold[
  29. #1/.{s_String:>Notebook[{Cell[StyleData[StyleDefinitions->s]],Cell[StyleData[#2],cellEventActions
  30. ]}],
  31. Notebook[{bef___,Cell[StyleData[#2],cellRest___],aft___}, rest___]:>Notebook[{bef,Cell[StyleData[#2], cellRest, cellEventActions],aft}, rest],
  32. Notebook[{all___}, rest___]:>Notebook[{all, Cell[StyleData[#2], cellEventActions]},rest]
  33. }&,
  34. FullOptions[nb, StyleDefinitions],styles]];
  35.  
  36. SetUpUndo[nb_,styles_]:=SetUpUndo[nb, {styles}];
  37.  
  38. $defaultFrequency=15;
  39.  
  40. initializeNotebook[nb_NotebookObject]:=Through@{appendNDE, appendNEA,
  41. SetOptions[#, CreateCellID->True]&,
  42. (CurrentValue[#, {TaggingRules, "undoSettings", "frequency"}]=$defaultFrequency)&}[
  43. nb];
  44.  
  45. cellEventActions=CellEventActions:>{PassEventsDown -> True, "KeyDown" :> If[CurrentValue["EventKey"]=!=None,undoSave[CurrentValue[CellID]]],"MouseClicked":>If[CurrentValue["AltKey"], undoLoad@CurrentValue@CellID]};
  46.  
  47. ClearAll[undoSave];
  48. undoSave[id_Integer]:=
  49. If[Mod[ ++ idCounter[id],
  50. CurrentValue[EvaluationNotebook[], {TaggingRules, "undoSettings", "frequency"}]] === 0,
  51. undoSave[ToString@id, CurrentValue[EvaluationNotebook[], {TaggingRules,"undoNotebook"}]]];
  52.  
  53. undoSave[id_, undoNb_]:=(If[
  54. NotebookFind[undoNb, ToString@id<>"End", All, CellTags]===$Failed,
  55. createCellIDZone[id][undoNb],
  56. SelectionMove[undoNb, Before, Cell]];
  57. copyCell[EvaluationNotebook[], undoNb]);
  58.  
  59. createCellIDZone[id_][nb_NotebookObject]:=(ToString@id/.idStr_:>{idStr<>"Start", idStr<>"End"}/.{stag_, etag_}:>FrontEndExecute[{
  60. FrontEnd`SelectionMove[nb,After,CellGroup],
  61. FrontEnd`NotebookWrite[nb,Cell@CellGroupData[{Cell["Start", CellTags->stag],Cell["End", CellTags->etag]}]],
  62. FrontEnd`SelectionMove[undoNb, Previous, Cell],
  63. FrontEnd`SelectionMove[undoNb, Before, Cell]}];
  64. nb)
  65.  
  66. undoNb:=CurrentValue[EvaluationNotebook[], {TaggingRules, "undoNotebook"}];
  67.  
  68. idCounter[_]=0;
  69.  
  70. ClearAll[doSthWithWholeCellSelected];
  71. doSthWithWholeCellSelected[sth_,what_:Cell][nb_]:=With[{val=CurrentValue[nb, ShowSelection],
  72. cursor=("CursorPosition"/.Developer`CellInformation[nb])[[1,1]]},
  73. FrontEndExecute[{
  74. FrontEnd`SetOptions[nb, ShowSelection->False],
  75. FrontEnd`SelectionMove[nb, All, what,AutoScroll->False]}];
  76. With[{cell=sth[nb]},
  77. {FrontEnd`SelectionMove[nb, Before, CellContents, AutoScroll->False],
  78. FrontEnd`SelectionMove[nb, Next, Character, cursor, AutoScroll->False],
  79. FrontEnd`SetOptions[nb, ShowSelection->val]}/.l:{a_, b_, c_}:>If[cursor>0,FrontEndExecute@l,FrontEndExecute[{a,c}]];
  80. cell
  81. ]
  82. ]
  83.  
  84. getCurrentCell[nb_NotebookObject]:=doSthWithWholeCellSelected[NotebookRead][nb];
  85.  
  86. copyCell[nbFrom_, nbTo_]:=NotebookWrite[nbTo, getCurrentCell[nbFrom]]
  87.  
  88. replaceCurrentCellContents[nb_NotebookObject, newCell_]:=doSthWithWholeCellSelected[NotebookWrite[#, newCell]&, CellContents][nb];
  89.  
  90. undoLoad[id_Integer]:=undoLoad[ToString@id,CurrentValue[EvaluationNotebook[], {TaggingRules, "undoNotebook"}]];
  91.  
  92. undoLoad[id_, nb_]:=If[(* if it is found *)
  93. NotebookFind[undoNb, ToString@id<>"End", All, CellTags]=!=$Failed,
  94. SelectionMove[undoNb, Previous, Cell];
  95. replaceCurrentCellContents[EvaluationNotebook[],If[CurrentValue[NotebookSelection@undoNb, CellTags]=!=ToString@id<>"Start",(NotebookDelete[undoNb];#)&@NotebookRead[undoNb],SelectionMove[undoNb, After, Cell];""]]]
  96.  
  97. End[];
  98. EndPackage[];
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement