14
$\begingroup$

With Mathematica 10 came the closing dialog notebook, which probably most of you deactivated. (You can bring it back by dechecking "Always exit after closing last window" in Edit->Preferences->Interface.) I just kept it, because my Mathematica installation gets non-responsive (often accompanied by the pop up of the "Progress" window) in several situations including start up.

However, the default closing dialog defaultClosingDialog
isn't very functional.

Therefore I'd like to customize it to get, e.g. something like: customClosingDialog_Explained
Where the "Quit" button is replaced by a "Quit Kernel" button that just quits the kernel, as there is no advantage to use the default "Quit" instead of the close window X. Furthermore I'd like to extend the closing dialog by adding additional buttons, e.g. a "Evaluate Specified Notebook" button that will evaluate a notebook file, whose path is defined in some .txt file.

The only way to read the default MathematicaClosingDialog.nb into Mma I found is

nb = Import[FileNameJoin[{$InstallationDirectory, "SystemFiles", "FrontEnd", 
            "TextResources", "MathematicaClosingDialog.nb"}]]

The output of this import looks like a mess, though.

In summary:

  1. How to replace the "Quit" button with a "Quit Kernel" button?
  2. How to add additional buttons, like a "Evaluate Specified Notebook" button?
  3. Can the directory for the MathematicaClosingDialog.nb be changed?
    (I couldn't find it in the "Option Inspector".)
$\endgroup$
4
  • $\begingroup$ I'm not seeing a closing dialog in V10 on OS X. $\endgroup$
    – m_goldberg
    Aug 10, 2014 at 16:32
  • $\begingroup$ @m_goldberg I don't know if there is one on OS X, but is "Always exit after closing last window" unchecked in Edit->Preferences->Interface? Or is this item nonexisting on OS X? $\endgroup$
    – Karsten7
    Aug 10, 2014 at 17:05
  • 1
    $\begingroup$ I don't see the preference item you mention. $\endgroup$
    – m_goldberg
    Aug 10, 2014 at 17:15
  • 1
    $\begingroup$ @m_goldberg I do not think this dialog exists under OS X, because it depends on the fact that under Windows MMA 10 has a menu bar in each notebook window. So if you close the last nb, you are given the choice -in Preferences- to either quit MMA for good or open the ClosingDialog (with another menu bar). Under OS X I understand that MMA 10 still has a global menu bar, so this issue does not arise. $\endgroup$
    – magma
    Aug 18, 2014 at 22:32

1 Answer 1

12
$\begingroup$

It turned out that the MathematicaClosingDialog.nb is a nice example for a graphical user interface that solely uses the FrontEnd MathKernel. On the downside, one has to deal with low-level code.

First I made a copy of the original MathematicaClosingDialog.nb, renamed it as MathematicaClosingDialog_Default.nb, and then imported it into a notebook:

nb = Import[
      FileNameJoin[{$InstallationDirectory, "SystemFiles", "FrontEnd", 
      "TextResources", "MathematicaClosingDialog_Default.nb"}]];

The result of this Import is a Notebook expression, with a bunch of low-level code. However, it isn't too hard to figure out what the components mean, if one doesn't get intimidated and discouraged by this code, that initially looks like a mess.

"Quit Kernel" Button

The definition of the "Quit" button can be found at

nb[[1, 3, 1, 1, 1, 1, 1, 1, 3]]

and converted into the familiar appearance by

ToExpression@nb[[1, 3, 1, 1, 1, 1, 1, 1, 3]]

QuitButton

It can be utilized to create the new "Quit Kernel" button by

newQuit = nb[[1, 3, 1, 1, 1, 1, 1, 1, 3]] /.    
   {FEPrivate`FrontEndResourceString["quitButtonText"] -> "Quit Kernel", 
    EventHandlerTag[{"MouseClicked" :> DialogReturn[FrontEndTokenExecute["FrontEndQuit"]], 
      PassEventsDown -> Automatic, PassEventsUp -> True}] -> 
     EventHandlerTag[{"MouseClicked" :> FrontEndTokenExecute["EvaluatorQuit", "Local"], 
       PassEventsDown -> Automatic, PassEventsUp -> True}]};

and then visualized with

ToExpression@newQuit

QuitKernelButton

Clicking on this button will quit the kernel "Local". (More precisely it will bring up the "Do you really want to quit the kernel?" dialog.) It is important to explicitly include a kernel name in FrontEndTokenExecute["EvaluatorQuit", "Local"], as the closing dialog will run with the FrontEnd MathKernel and not with the "Local" kernel or whatever kernel you used as "Notebook's Kernel".

"Evaluate Specified Notebook" Button

For the second task a suitable icon is needed. I created one based on the notebook icon:

nbIcon = Import[
  FileNameJoin[{$InstallationDirectory, "SystemFiles", "FrontEnd", 
  "SystemResources", "Bitmaps", "Product", "[email protected]"}]]
nbIcon = ImageResize[ImageCrop[nbIcon, 55], 39]
Export[FileNameJoin[{NotebookDirectory[], "Document.png"}], nbIcon]

Document

and a hover icon:

dcs = DominantColors[nbIcon]
nbIconHover = ColorReplace[nbIcon, (First@dcs) -> ColorData["HTML"]["DodgerBlue"]]
Export[FileNameJoin[{NotebookDirectory[], "Document-Hover.png"}], nbIconHover]

DocumentHover

I then copied these icons into the $InstallationDirectory\SystemFiles\FrontEnd\SystemResources\Bitmaps\Dialog\Closing directory.

The new button will be based on the "New Notebook" button:

evalSNB = nb[[1, 3, 1, 1, 1, 1, 1, 1, 1]] /. 
  {FrontEnd`ToFileName[{"Dialogs", "Closing"}, "File.png"] ->
    FrontEnd`ToFileName[{"Dialogs", "Closing"}, "Document.png"],
   FrontEnd`ToFileName[{"Dialogs", "Closing"}, "File-Hover.png"] -> 
    FrontEnd`ToFileName[{"Dialogs", "Closing"}, "Document-Hover.png"], 
   FEPrivate`FrontEndResource["MathematicaClosingDialog", "NewNotebook"] -> 
    "Evaluate Specified NB", 
   RGBColor[0.9294117647058824, 0.1803921568627451, 0.01568627450980392] -> 
    RGBColor[0.08104575163398693, 0.3058823529411765, 0.6640522875816994],
   EventHandlerTag[{"MouseClicked" :> DialogReturn[FrontEndTokenExecute["New"]], 
     PassEventsDown -> Automatic, PassEventsUp -> True}] -> 
    EventHandlerTag[{"MouseClicked" :> FrontEndTokenExecute[NotebookOpen["D:\\selectedNB.nb", Visible -> False],"EvaluateNotebook", "Local"], 
      PassEventsDown -> Automatic, PassEventsUp -> True}]};

Since one can't import a txt file using the FrontEnd (at least not with Import), a notebook file selectedNB.nb with the following content is used as an intermediate:

FrontEndTokenExecute[NotebookOpen[Import["D:\\specifiedNB.txt"], Visible -> False], 
  "EvaluateNotebook", "Local"]
NotebookClose[]

With the option Visible -> False the notebook won't be displayed. If you prefer to see the notebook while it is evaluated, just remove this option. The txt file contains the directory of the notebook with the interesting code. That notebook ends with SystemOpen functions to display the calculated graphs and finally a NotebookClose[].

Custom Closing Dialog

Now our custom closing dialog is created with:

newClosingDialog = nb;
newClosingDialog[[1, 3, 1, 1, 1, 1, 1, 1, 3]] = newQuit;
newClosingDialog[[1, 3, 1, 1, 1, 1, 1]] = 
  Append[newClosingDialog[[1, 3, 1, 1, 1, 1, 1]], {evalSNB, "", ""}];
newClosingDialog[[1, 3, 1, 1, 1, 1]] = 
  Append[RowSpacings -> 5]@newClosingDialog[[1, 3, 1, 1, 1, 1]];

Where the last command increased the spacing between the first and the new second row. You can use

newClosingDialog[[1, 3]] // CellPrint

to visualize the main part of the new dialog.

Finally it is exported with:

Export[FileNameJoin[{NotebookDirectory[], "MathematicaClosingDialog.nb"}], newClosingDialog]

Unfortunately, I couldn't find a file specification for the closing dialog in the "Option Inspector" and therefore had to copy my custom MathematicaClosingDialog.nb into the folder of the default closing dialog. (!! This will override the original MathematicaClosingDialog.nb !!)


CustomClosingDialog

$\endgroup$
1
  • $\begingroup$ What a professional answer. +1 $\endgroup$
    – Mr.Wizard
    Aug 22, 2014 at 8:41

Your Answer

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

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