JAL-3631 Extensive working of options in install4j for allowing/disabling user defaul...
authorBen Soares <b.soares@dundee.ac.uk>
Wed, 17 Jul 2024 15:31:01 +0000 (16:31 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Wed, 17 Jul 2024 15:31:01 +0000 (16:31 +0100)
utils/install4j/install4j10_template.install4j
utils/install4j/warning.png [new file with mode: 0644]

index 6172279..705a45c 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <install4j version="10.0.8" transformSequenceNumber="10">
-  <directoryPresets config="bin/Jalview" />
+  <directoryPresets config="." />
   <application name="${compiler:JALVIEW_APPLICATION_NAME}" applicationId="${compiler:WINDOWS_APPLICATION_ID}" mediaDir="${compiler:BUILD_DIR}" lzmaCompression="true" shortName="${compiler:INTERNAL_ID}" publisher="University of Dundee" publisherWeb="https://www.jalview.org/" version="${compiler:JALVIEW_VERSION}" allPathsRelative="true" macVolumeId="5aac4968c304f65" javaMinVersion="${compiler:JAVA_MIN_VERSION}" javaMaxVersion="${compiler:JAVA_MAX_VERSION}" allowBetaVM="true" jdkMode="jdk" jdkName="JDK 11.0">
     <searchSequence>
       <directory location="${compiler:JRE_DIR}" />
 # For example, to adjust the maximum memory usage to 512 MB, uncomment the following line:
 # -Xmx512m
 # To include another file, uncomment the following line:
-# -include-options [path to other .vmoption file]
-
-# Uncomment these two lines to disable user-space automatic updates.
-#-Dnouserdefaultappdir=true
-#-Dsilent=noupdate</content>
+# -include-options [path to other .vmoption file]</content>
       </vmOptionsFile>
       <infoPlist>${compiler:file("${compiler:INFO_PLIST_FILE_ASSOCIATIONS_FILE}")}</infoPlist>
       <iconImageFiles>
@@ -396,6 +392,73 @@ return wrapperLink;
                 </serializedBean>
                 <condition>Util.isMacOS() &amp;&amp; !context.getBooleanVariable("isAdmin") // Admin on macOS will add path to /etc/paths.d in Create File action</condition>
               </action>
+              <action name="BOTHSPACE: Set allowUserDefaultAppdirUpdates" id="2976" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.TRUE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">allowUserDefaultAppdirUpdates</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set allowInstallerAppdirUpdates" id="2977" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.FALSE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">allowInstallerAppdirUpdates</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set userDefaultAppdirBase for tooltip explanation" id="2981" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Map&lt;String, String&gt; osAppDataPathMap = new HashMap&lt;&gt;();
+osAppDataPathMap.put("macos", "Library/Application Support/Jalview-Desktop");
+osAppDataPathMap.put("linux", ".local/share/jalview-desktop");
+osAppDataPathMap.put("windows", "AppData\\Local\\Jalview-Desktop");
+osAppDataPathMap.put("other", ".jalview-desktop");
+String appDataPath;
+String append;
+if (Util.isMacOS()) {
+  appDataPath = osAppDataPathMap.get("macos");
+  append = context.getCompilerVariable("JALVIEW_APPLICATION_NAME");
+} else if (Util.isWindows()) {
+  appDataPath = osAppDataPathMap.get("windows");
+  append = context.getCompilerVariable("APPLICATION_FOLDER");
+} else if (Util.isLinux()) {
+  appDataPath = osAppDataPathMap.get("linux");
+  append = context.getCompilerVariable("APPLICATION_FOLDER").toLowerCase(Locale.ROOT);
+} else {
+  appDataPath = osAppDataPathMap.get("other");
+  append = context.getCompilerVariable("APPLICATION_FOLDER").toLowerCase(Locale.ROOT);
+}
+return "~" + File.separator + appDataPath + File.separator + append;</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">userDefaultAppdirBase</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set osName variable for tooltip explanation" id="2982" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">if (Util.isWindows()) {
+    return "Windows";
+} else if (Util.isMacOS()) {
+    return "macOS";
+} else if (Util.isLinux()) {
+    return "Linux";
+}
+return context.getCompilerVariable("sys.platform");</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">osName</property>
+                </serializedBean>
+              </action>
             </actions>
           </screen>
         </startup>
@@ -565,7 +628,7 @@ return console.askOkCancel(message, true);
           </screen>
           <screen name="USERSPACE: Additional checkboxes" id="2893" beanClass="com.install4j.runtime.beans.screens.FormScreen" rollbackBarrierExitCode="0">
             <serializedBean>
-              <property name="subTitle" type="string">User account</property>
+              <property name="subTitle" type="string">Additional tasks for user installation (${installer:sys.userName})</property>
               <property name="title" type="string">${i18n:WizardSelectTasks}</property>
             </serializedBean>
             <condition>!context.getBooleanVariable("isAdmin")</condition>
@@ -614,11 +677,122 @@ return console.askOkCancel(message, true);
         )
     )</visibilityScript>
               </formComponent>
+              <formComponent id="2983" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" />
+              <formComponent name="Enable advanced options" id="3006" customizedId="US_ADVANCED_OPTIONS" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Enable advanced options</property>
+                  <property name="coupledComponentIds">
+                    <add type="string">2980</add>
+                    <add type="string">2975</add>
+                    <add type="string">2989</add>
+                  </property>
+                  <property name="selectionScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("US_ADVANCED_OPTIONS");
+Class&lt;?&gt; cl_advancedOptions = fc_advancedOptions.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_advancedOptions)) {
+    return;
+}
+JCheckBox jcb_advancedOptions = (JCheckBox) fc_advancedOptions.getConfigurationObject();
+boolean advancedOptions = fc_advancedOptions.isEnabled() &amp;&amp; jcb_advancedOptions.isSelected();
+
+FormComponent fc_userUpdates = formEnvironment.getFormComponentById("US_ALLOW_USER_APPDIR_UPDATES");
+Class&lt;?&gt; cl_user = fc_userUpdates.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_user)) {
+    return;
+}
+JCheckBox jcb_user = (JCheckBox) fc_userUpdates.getConfigurationObject();
+boolean userUpdates = fc_userUpdates.isEnabled() &amp;&amp; jcb_user.isSelected();
+
+boolean showWarning = advancedOptions &amp;&amp; (!userUpdates);
+
+formEnvironment.getFormComponentById("US_NO_UPDATES_WARNING").setVisible(showWarning);
+
+FormComponent fc_label = formEnvironment.getFormComponentById("US_LABEL");
+fc_label.setVisible(advancedOptions);
+fc_userUpdates.setVisible(advancedOptions);
+</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">advancedOptions</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent name="Strongly recommended text" id="2980" customizedId="US_LABEL" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetLeft="16">
+                <serializedBean>
+                  <property name="labelHtml" type="string">&lt;html&gt;The following option is strongly recommended to be left as default unless there is a particular reason to change them.&lt;/html&gt;</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("advancedOptions")
+</visibilityScript>
+              </formComponent>
+              <formComponent id="3014" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" insetLeft="16" />
+              <formComponent name="BOTHSPACE: Allow automatic updates in user's home directory" id="2975" customizedId="US_ALLOW_USER_APPDIR_UPDATES" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent" insetLeft="16">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Allow user-space updates for ${compiler:JALVIEW_APPLICATION_NAME} components</property>
+                  <property name="helpText" type="string">&lt;html&gt;This option allows updates to ${compiler:JALVIEW_APPLICATION_NAME}
+&lt;br&gt;
+components to be automatically downloaded
+&lt;br&gt;
+under the user's home space, separately from
+&lt;br&gt;
+the installation location.
+&lt;br&gt;
+&lt;strong&gt;This option is strongly recommended.&lt;/strong&gt;
+&lt;br&gt;
+&lt;br&gt;
+On ${installer:osName}, user updates will be installed under
+&lt;br&gt;
+&lt;pre&gt;${installer:userDefaultAppdirBase}&lt;/pre&gt;
+&lt;/html&gt;</property>
+                  <property name="initiallySelected" type="boolean" value="true" />
+                  <property name="selectionScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("US_ADVANCED_OPTIONS");
+Class&lt;?&gt; cl_advancedOptions = fc_advancedOptions.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_advancedOptions)) {
+    return;
+}
+JCheckBox jcb_advancedOptions = (JCheckBox) fc_advancedOptions.getConfigurationObject();
+boolean advancedOptions = fc_advancedOptions.isEnabled() &amp;&amp; jcb_advancedOptions.isSelected();
+
+FormComponent fc_userUpdates = formEnvironment.getFormComponentById("US_ALLOW_USER_APPDIR_UPDATES");
+Class&lt;?&gt; cl_user = fc_userUpdates.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_user)) {
+    return;
+}
+JCheckBox jcb_user = (JCheckBox) fc_userUpdates.getConfigurationObject();
+boolean userUpdates = fc_userUpdates.isEnabled() &amp;&amp; jcb_user.isSelected();
+
+boolean showWarning = advancedOptions &amp;&amp; (!userUpdates);
+
+formEnvironment.getFormComponentById("US_NO_UPDATES_WARNING").setVisible(showWarning);</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">allowUserDefaultAppdirUpdates</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("advancedOptions")
+</visibilityScript>
+              </formComponent>
+              <formComponent name="BOTHSPACE: No updates warning" id="2989" customizedId="US_NO_UPDATES_WARNING" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent" insetLeft="16">
+                <serializedBean>
+                  <property name="labelIconFile">
+                    <object class="com.install4j.api.beans.ExternalFile">
+                      <string>${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/warning.png</string>
+                    </object>
+                  </property>
+                  <property name="labelText" type="string">No automatic updates will occur when Jalview is launched</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("advancedOptions")
+&amp;&amp;
+!(
+  context.getBooleanVariable("allowUserDefaultAppdirUpdates")
+  || context.getBooleanVariable("allowInstallerAppdirUpdates")
+)</visibilityScript>
+              </formComponent>
             </formComponents>
           </screen>
           <screen name="SYSTEMSPACE: Additional checkboxes" id="2903" beanClass="com.install4j.runtime.beans.screens.FormScreen" rollbackBarrierExitCode="0">
             <serializedBean>
-              <property name="subTitle" type="string">System</property>
+              <property name="subTitle" type="string">Additional tasks for administrator installation</property>
               <property name="title" type="string">${i18n:WizardSelectTasks}</property>
             </serializedBean>
             <condition>context.getBooleanVariable("isAdmin")</condition>
@@ -654,6 +828,200 @@ return console.askOkCancel(message, true);
     )
 </visibilityScript>
               </formComponent>
+              <formComponent id="2984" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" />
+              <formComponent name="Enable advanced options" id="3007" customizedId="SS_ADVANCED_OPTIONS" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Enable advanced options</property>
+                  <property name="coupledComponentIds">
+                    <add type="string">2985</add>
+                  </property>
+                  <property name="selectionScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("SS_ADVANCED_OPTIONS");
+Class&lt;?&gt; cl_advancedOptions = fc_advancedOptions.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_advancedOptions)) {
+    return;
+}
+JCheckBox jcb_advancedOptions = (JCheckBox) fc_advancedOptions.getConfigurationObject();
+boolean advancedOptions = fc_advancedOptions.isEnabled() &amp;&amp; jcb_advancedOptions.isSelected();
+
+FormComponent fc_userUpdates = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_UPDATES");
+Class&lt;?&gt; cl_user = fc_userUpdates.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_user)) {
+    return;
+}
+JCheckBox jcb_user = (JCheckBox) fc_userUpdates.getConfigurationObject();
+boolean userUpdates = fc_userUpdates.isEnabled() &amp;&amp; jcb_user.isSelected();
+
+FormComponent fc_installerUpdates = formEnvironment.getFormComponentById("SS_ALLOW_INSTALLER_APPDIR_UPDATES");
+Class&lt;?&gt; cl_installer = fc_installerUpdates.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_installer)) {
+    return;
+}
+JCheckBox jcb_installer = (JCheckBox) fc_installerUpdates.getConfigurationObject();
+boolean installerUpdates = fc_installerUpdates.isEnabled() &amp;&amp; jcb_installer.isSelected();
+
+boolean showWarning = advancedOptions &amp;&amp; !(userUpdates || installerUpdates);
+
+formEnvironment.getFormComponentById("SS_NO_UPDATES_WARNING").setVisible(showWarning);
+
+fc_installerUpdates.setEnabled(!userUpdates);
+
+FormComponent fc_label = formEnvironment.getFormComponentById("SS_LABEL");
+fc_label.setVisible(advancedOptions);
+fc_userUpdates.setVisible(advancedOptions);
+fc_installerUpdates.setVisible(advancedOptions);
+</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">advancedOptions</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent name="Strongly recommended text" id="2985" customizedId="SS_LABEL" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetLeft="16">
+                <serializedBean>
+                  <property name="labelHtml" type="string">&lt;html&gt;The following options are strongly recommended to be left as default unless there is a particular reason to change them.&lt;/html&gt;</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("advancedOptions")
+</visibilityScript>
+              </formComponent>
+              <formComponent id="3013" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" insetLeft="16" />
+              <formComponent name="BOTHSPACE: Allow automatic updates in user's home directory" id="2986" customizedId="SS_ALLOW_USER_APPDIR_UPDATES" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent" insetLeft="16">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Allow user-space updates for ${compiler:JALVIEW_APPLICATION_NAME} components</property>
+                  <property name="helpText" type="string">&lt;html&gt;This option allows updates to ${compiler:JALVIEW_APPLICATION_NAME}
+&lt;br&gt;
+components to be automatically downloaded
+&lt;br&gt;
+under the user's home space, separately from
+&lt;br&gt;
+the installation location.
+&lt;br&gt;
+&lt;strong&gt;This option is strongly recommended.&lt;/strong&gt;
+&lt;br&gt;
+&lt;br&gt;
+On ${installer:osName}, user updates will be installed under
+&lt;br&gt;
+&lt;pre&gt;${installer:userDefaultAppdirBase}&lt;/pre&gt;
+&lt;/html&gt;</property>
+                  <property name="initiallySelected" type="boolean" value="true" />
+                  <property name="inverseCoupling" type="boolean" value="true" />
+                  <property name="selectionScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("SS_ADVANCED_OPTIONS");
+Class&lt;?&gt; cl_advancedOptions = fc_advancedOptions.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_advancedOptions)) {
+    return;
+}
+JCheckBox jcb_advancedOptions = (JCheckBox) fc_advancedOptions.getConfigurationObject();
+boolean advancedOptions = fc_advancedOptions.isEnabled() &amp;&amp; jcb_advancedOptions.isSelected();
+
+FormComponent fc_userUpdates = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_UPDATES");
+Class&lt;?&gt; cl_user = fc_userUpdates.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_user)) {
+    return;
+}
+JCheckBox jcb_user = (JCheckBox) fc_userUpdates.getConfigurationObject();
+boolean userUpdates = fc_userUpdates.isEnabled() &amp;&amp; jcb_user.isSelected();
+
+FormComponent fc_installerUpdates = formEnvironment.getFormComponentById("SS_ALLOW_INSTALLER_APPDIR_UPDATES");
+Class&lt;?&gt; cl_installer = fc_installerUpdates.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_installer)) {
+    return;
+}
+JCheckBox jcb_installer = (JCheckBox) fc_installerUpdates.getConfigurationObject();
+boolean installerUpdates = fc_installerUpdates.isEnabled() &amp;&amp; jcb_installer.isSelected();
+
+boolean showWarning = advancedOptions &amp;&amp; !(userUpdates || installerUpdates);
+
+formEnvironment.getFormComponentById("SS_NO_UPDATES_WARNING").setVisible(showWarning);
+
+fc_installerUpdates.setEnabled(!userUpdates);
+</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">allowUserDefaultAppdirUpdates</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("advancedOptions")
+</visibilityScript>
+              </formComponent>
+              <formComponent name="SYSTEMSPACE: Allow automatic updates in the installation directory" id="2974" customizedId="SS_ALLOW_INSTALLER_APPDIR_UPDATES" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent" insetLeft="16">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Allow installation updates for ${compiler:JALVIEW_APPLICATION_NAME} components</property>
+                  <property name="helpText" type="string">&lt;html&gt;This option allows updates to ${compiler:JALVIEW_APPLICATION_NAME}
+&lt;br&gt;
+components to be automatically downloaded
+&lt;br&gt;
+into the installation location.
+&lt;br&gt;
+If you are installing into a system location,
+&lt;br&gt;
+a non-administrator user may have problems
+&lt;br&gt;
+launching ${compiler:JALVIEW_APPLICATION_NAME}.
+&lt;br&gt;
+&lt;strong&gt;
+It is strongly recommended to use the
+&lt;br&gt;
+user-space updates option above.
+&lt;/strong&gt;
+&lt;br&gt;
+&lt;br&gt;
+Installation updates will be installed into
+&lt;br&gt;
+&lt;pre&gt;${installer:sys.contentDir}&lt;/pre&gt;
+&lt;/html&gt;</property>
+                  <property name="selectionScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("SS_ADVANCED_OPTIONS");
+Class&lt;?&gt; cl_advancedOptions = fc_advancedOptions.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_advancedOptions)) {
+    return;
+}
+JCheckBox jcb_advancedOptions = (JCheckBox) fc_advancedOptions.getConfigurationObject();
+boolean advancedOptions = fc_advancedOptions.isEnabled() &amp;&amp; jcb_advancedOptions.isSelected();
+
+FormComponent fc_userUpdates = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_UPDATES");
+Class&lt;?&gt; cl_user = fc_userUpdates.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_user)) {
+    return;
+}
+JCheckBox jcb_user = (JCheckBox) fc_userUpdates.getConfigurationObject();
+boolean userUpdates = fc_userUpdates.isEnabled() &amp;&amp; jcb_user.isSelected();
+
+FormComponent fc_installerUpdates = formEnvironment.getFormComponentById("SS_ALLOW_INSTALLER_APPDIR_UPDATES");
+Class&lt;?&gt; cl_installer = fc_installerUpdates.getConfigurationObjectClass();
+if (!JCheckBox.class.equals(cl_installer)) {
+    return;
+}
+JCheckBox jcb_installer = (JCheckBox) fc_installerUpdates.getConfigurationObject();
+boolean installerUpdates = fc_installerUpdates.isEnabled() &amp;&amp; jcb_installer.isSelected();
+
+boolean showWarning = advancedOptions &amp;&amp; !(userUpdates || installerUpdates);
+
+formEnvironment.getFormComponentById("SS_NO_UPDATES_WARNING").setVisible(showWarning);</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">allowInstallerAppdirUpdates</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("advancedOptions")
+</visibilityScript>
+              </formComponent>
+              <formComponent name="BOTHSPACE: No updates warning" id="2988" customizedId="SS_NO_UPDATES_WARNING" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent" insetLeft="16">
+                <serializedBean>
+                  <property name="labelIconFile">
+                    <object class="com.install4j.api.beans.ExternalFile">
+                      <string>${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/warning.png</string>
+                    </object>
+                  </property>
+                  <property name="labelText" type="string">No automatic updates will occur when Jalview is launched</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("advancedOptions")
+&amp;&amp;
+!(
+  context.getBooleanVariable("allowUserDefaultAppdirUpdates")
+  || context.getBooleanVariable("allowInstallerAppdirUpdates")
+)</visibilityScript>
+              </formComponent>
             </formComponents>
           </screen>
           <screen id="15" beanClass="com.install4j.runtime.beans.screens.InstallationScreen" rollbackBarrier="true" rollbackBarrierExitCode="0">
@@ -728,11 +1096,23 @@ return console.askOkCancel(message, true);
                   </action>
                   <action id="2541" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
                     <serializedBean>
-                      <property name="percentValue" type="int" value="100" />
+                      <property name="percentValue" type="int" value="99" />
                     </serializedBean>
                   </action>
                 </beans>
               </group>
+              <action id="3017" beanClass="com.install4j.runtime.beans.actions.control.SetMessageAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="statusMessage" type="string">${i18n:FinishedHeadingLabel(${compiler:JALVIEW_APPLICATION_NAME})}</property>
+                  <property name="useDetail" type="boolean" value="true" />
+                  <property name="useStatus" type="boolean" value="true" />
+                </serializedBean>
+              </action>
+              <action id="3018" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="progressChangeType" type="enum" class="com.install4j.runtime.beans.actions.control.ProgressChangeType" value="SET_INDETERMINATE" />
+                </serializedBean>
+              </action>
               <group name="Register URL Handlers" id="2957" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                 <beans>
                   <action id="2350" beanClass="com.install4j.runtime.beans.actions.desktop.UrlHandlerAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
@@ -965,6 +1345,85 @@ context.getBooleanVariable("addToDockAction")</condition>
                   </action>
                 </beans>
               </group>
+              <group name="BOTHSPACE: VMOPTIONS Getdown update properties" id="3000" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
+                <beans>
+                  <action name="Set disableUserDefaultAppdirUpdates" id="3011" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="script">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string">boolean advanced = context.getBooleanVariable("advancedOptions");
+boolean allowUser = context.getBooleanVariable("allowUserDefaultAppdirUpdates");
+
+return advanced ? !allowUser : false;</property>
+                        </object>
+                      </property>
+                      <property name="variableName" type="string">disableUserDefaultAppdirUpdates</property>
+                    </serializedBean>
+                  </action>
+                  <action name="Set disableUpdates" id="3012" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="script">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string">boolean advanced = context.getBooleanVariable("advancedOptions");
+boolean allowUser = context.getBooleanVariable("allowUserDefaultAppdirUpdates");
+boolean allowInstaller = context.getBooleanVariable("allowInstallerAppdirUpdates");
+
+return advanced ? !( allowUser || allowInstaller ) : false;</property>
+                        </object>
+                      </property>
+                      <property name="variableName" type="string">disableUpdates</property>
+                    </serializedBean>
+                  </action>
+                  <action name="Initial comment" id="3010" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="1">
+                        <element index="0"># Jalview specific options below</element>
+                      </property>
+                    </serializedBean>
+                  </action>
+                  <action name="Allow user-space updates" id="2996" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="2">
+                        <element index="0"># Uncomment the following line to disable user-space updates</element>
+                        <element index="1">#-Dnouserdefaultappdir=true</element>
+                      </property>
+                    </serializedBean>
+                    <condition>!context.getBooleanVariable("disableUserDefaultAppdirUpdates")</condition>
+                  </action>
+                  <action name="Disable user-space updates" id="2997" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="2">
+                        <element index="0"># Comment out the following line to allow user-space updates</element>
+                        <element index="1">-Dnouserdefaultappdir=true</element>
+                      </property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("disableUserDefaultAppdirUpdates")</condition>
+                  </action>
+                  <action name="Allow updates" id="2998" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="2">
+                        <element index="0"># Uncomment the following line to also disable all updates</element>
+                        <element index="1">#-Dsilent=noupdate </element>
+                      </property>
+                    </serializedBean>
+                    <condition>!context.getBooleanVariable("disableUpdates")</condition>
+                  </action>
+                  <action name="Disable updates" id="2999" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="2">
+                        <element index="0"># Comment out the following line to enable updates</element>
+                        <element index="1">-Dsilent=noupdate</element>
+                      </property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("disableUpdates")</condition>
+                  </action>
+                </beans>
+              </group>
               <group name="Java bin symlinks" id="2944" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                 <beans>
                   <action name="macOS/Linux Jalview-&gt;java symlink" id="2942" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
@@ -1059,6 +1518,11 @@ context.getBooleanVariable("addToDockAction")</condition>
                   </action>
                 </beans>
               </group>
+              <action id="3020" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="percentValue" type="int" value="100" />
+                </serializedBean>
+              </action>
             </actions>
             <formComponents>
               <formComponent id="16" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent">
diff --git a/utils/install4j/warning.png b/utils/install4j/warning.png
new file mode 100644 (file)
index 0000000..2063df2
Binary files /dev/null and b/utils/install4j/warning.png differ