Advertisement
Guest User

Untitled

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