Script Sample: Check for Updates

Purpose

These macros check whether any other program has modified a file currently being edited in HoTMetaL. If this happens, the user is presented with the option to reload the document.

How To Use

Copy the macros from the file macros.txt into the hotmetal.mcr file found in the Macros folder of your HoTMetaL PRO application folder.

The macros in macro.txt use a number of standard macros such as On_Application_Open so be sure to check that you are not duplicating any of those. If you already have such macros, just add the code into the appropriate macros instead of adding a new macro.

On_Application_Open

In this macro, we define some variables for constants that are used later on. This technique of defining global variables and functions in On_Application_Open is often useful.

<MACRO name="On_Application_Open" lang="JScript"><![CDATA[
  var viewWYSIWYG = 0;
  var viewTagsOn = 1;
  var viewSource = 2;
]]></MACRO>

On_Document_Open_Complete

In this macro, we use Microsoft's FileSystemObject to get the last modified date of the file that was just opened. This is stored in the LastMod custom document property for later comparison with the file on disk.

<MACRO name="On_Document_Open_Complete" lang="JScript"><![CDATA[
  var name = ActiveDocument.LocalFullName;
  if (Application.ReadableFileExists(name)) {  // if document has never been saved, do nothing
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var f = fso.GetFile(name);
    var mod = Date.parse(f.DateLastModified);
    var props = ActiveDocument.CustomDocumentProperties;
    props.Add("LastMod", mod);
  }
]]></MACRO>

On_Document_Activate, On_Application_Activate

Whenever the document becomes active, for example because the user has switched to it after editing another document, or has returned to HoTMetaL from some other application, we check whether the version of the file on disk has a more recent last modified date than the one we stored when the document was opened.

This checking is only done for local files because it is not feasible to check the last modified date of remote files.

If the version on disk is newer, we inform the user that the document has apparently been changed and ask if they want to load the (newer) version that is on disk.

<MACRO name="On_Document_Activate" lang="JScript" id="44" tooltip="Hide_On_Document_Activate" desc="Runs Macro: Hide_On_Document_Activate"><![CDATA[
  // Do this for local documents only
  if (ActiveDocument.FullName == ActiveDocument.LocalFullName) {
    var name = ActiveDocument.LocalFullName;
    if (Application.ReadableFileExists(name)) {  // if document has never been saved, do nothing
      var fso = new ActiveXObject("Scripting.FileSystemObject");
      var f = fso.GetFile(name);
      var newMod = Date.parse(f.DateLastModified);
      var props = ActiveDocument.CustomDocumentProperties;
      if (props.count != 0) {
        oldMod = props.Item("LastMod").value;
        if (oldMod != newMod) {
          var Yes = 6;
          var No = 7;
          var msg = "The disk version of this document has changed from the\n";
          msg += "version in memory.  Do you want to re-open the document?";
          var ret = Application.MessageBox(msg, 36, "Document Changed");
          if (ret == Yes) {
            ActiveDocument.Reload();
          }
          // Reset the timestamp regardless of the user's response
          // This will prevent the dialog from always showing
          Application.Run("On_Document_Open_Complete");
        }
      }
    }
  }
]]></MACRO>
 
<MACRO name="On_Application_Activate" lang="JScript"><![CDATA[
  Application.Run("On_Document_Activate");
]]></MACRO>

On_Document_Save, On_Document_SaveAs

When the user saves the document (or does a Save As), we update the LastMod document property so that it reflects the current time of the document on disk.

<MACRO name="On_Document_Save" lang="JScript"><![CDATA[
  var fso = new ActiveXObject("Scripting.FileSystemObject");
  var f = fso.GetFile(ActiveDocument.LocalFullName);
  var mod = Date.parse(f.DateLastModified);
  var props = ActiveDocument.CustomDocumentProperties;
  if (props.count != 0) {
    props.Add("LastMod", mod);
  }
]]></MACRO> 
 
<MACRO name="On_Document_SaveAs" lang="JScript"><![CDATA[
  Application.Run("On_Document_Save");
]]></MACRO>