3
$\begingroup$

Ive been working on this from morning to midnight (primarily studying the docs that never seem to have useful examples) only to to make very little ground. I am trying to code a dynamic button that performs a recurring NotebookSave[] after a countdown timer[s] completes and then automatically begins cycle again.

The button should do the following...

  1. when inactive label should display AutoSave.

  2. click replaces label with time remaining for next save.

  3. when countdown timer[s] completes this should trigger NotebookSave[].

  4. label should now read SAVED for 10 sec (I think Pause[10] would work).

  5. automatically start cycle over perhaps by recursive function (only closing notebook will stop autosave).

  6. and finally the entire thing nicely packaged in a DynamicModule[] which I should find doing a piece of cake.

From the code below you can see I only completed steps 1 and 2 (step 3 attempted but failed). Any help for steps 3 - 5 would be most appreciated. I also include a small sampling of my many bad attempts so you would take pity on my wretched soul.

timer[s_ : 600] := Dynamic[s - Clock[{0, s, 1}, s, 1]];
s = 10;
Button[Dynamic[x, {(x := #) &, NotebookSave[]}, 
  Initialization :> (x := "AutoSave")], x := timer[s]]

(* may ignore these bad attempts *)
(*
Button[Dynamic[x,{}Initialization:>(x:="AutoSave")],(x:=timer[];\
NotebookSave)];
Button[Dynamic[x,Initialization:>(x:="AutoSave")],Dynamic[x,{x:=timer[\
],NotebookSave[]}]];
Button[Dynamic[x,Initialization:>(x:="AutoSave")],x:=Dynamic[t,{t:=\
timer[s],If[t==0,NotebookSave[]]}]]
Button[Dynamic[x,Initialization:>(x:="AutoSave")],x:=Dynamic[t,{t:=\
timer[s],If[t==0,NotebookSave[]]}]]
*)
$\endgroup$

1 Answer 1

3
$\begingroup$

Button will not work for what you want to do, since it will require to set the Method -> "Queued" and then you cannot do anything in the notebook anymore.

I would use ScheduledTask and write the information when to save in the "WindowStatusArea". The below code should serve as a proof of concept. Just execute in inside your notebook and then you can go on using the notebook for other tasks.

    With[{nb=EvaluationNotebook[], p1:=Pause[1]},
   CurrentValue[nb,"WindowStatusArea"]="preparing repetitive autosave";
    SessionSubmit[
      ScheduledTask[ 
        Module[{sCountDown = 3,s},
          s = sCountDown
          ; Do[
              CurrentValue[nb,"WindowStatusArea"]=("Autosaving Notebook in " <> ToString[s] <> " seconds")
              ; If[s > 0
                  ,
                    s = s - 1
                  , 
                    CurrentValue[nb,"WindowStatusArea"]="Saving Notebook now"
                  ; p1; NotebookSave[nb]; p1; s = sCountDown
                  ; CurrentValue[nb, "WindowStatusArea"] = "SAVED"]
                  ; p1
                  , {10^5}
           ]
        ]
     , {Quantity[5,"Seconds"], 10^7 }]]
];

enter image description here

$\endgroup$
5
  • $\begingroup$ wow i really didn't expect anyone to be so generous as to rewrite a whole application for me. thank so much for all your effort. it will not go to waste. $\endgroup$ Commented Aug 11, 2021 at 10:39
  • $\begingroup$ the dynamic button would have been included in a DockedCell toolbar where all Buttons are set to Method -> "Queued". Could Dynamic options such as SynchronousUpdating have averted notebook freeze? $\endgroup$ Commented Aug 11, 2021 at 10:51
  • $\begingroup$ I don't think so. What you can do is to start and stop the scheduled task by Button, maybe. BTW: There is also a standard NotebookAutoSave notebook option, but it is too limited, I think. $\endgroup$ Commented Aug 11, 2021 at 11:08
  • $\begingroup$ if you dont mind i really like this but works too good (saves every 3 - 5 seconds).. how to stop this unnamed ScheduleTask? i removed cell containing code and close/reopen notebook now WindowStatusArea has frozen message Saving Notebook now. ideally i wish to anchor your solution to a function for starting it. autoSave[s,p] would have two arguments: s for duration of save recurrence and another argument p for length of pause for status messages. and finally how to stop autoSave[s,p] . i am about a year in with Mathematica and have no idea how to manage ScheduledTasks. $\endgroup$ Commented Aug 12, 2021 at 1:00
  • $\begingroup$ to test stopping SheduleTask i first prepended code with task= on new notebook document. then tried TaskRemove[Tasks[]] and TaskRemove[task]. neither worked. i really like this solution but i cant use it until i figure out how to stop it. i think i can figure out the other things. $\endgroup$ Commented Aug 12, 2021 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.