flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bigosma...@apache.org
Subject svn commit: r1364558 - in /incubator/flex/utilities/InstallApacheFlex: ./ src/ src/com/ src/com/riaspace/ src/com/riaspace/nativeApplicationUpdater/ src/com/riaspace/nativeApplicationUpdater/utils/ src/org/apache/flex/packageflexsdk/util/ src/org/apach...
Date Mon, 23 Jul 2012 09:53:41 GMT
Author: bigosmallm
Date: Mon Jul 23 09:53:41 2012
New Revision: 1364558

URL: http://svn.apache.org/viewvc?rev=1364558&view=rev
Log:
Added auto-update functionality.  
Untested on Mac.  

Added:
    incubator/flex/utilities/InstallApacheFlex/src/com/
    incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/
    incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/
    incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/NativeApplicationUpdater.as
    incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/UpdaterErrorCodes.as
    incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/utils/
    incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/utils/HdiutilHelper.as
    incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/util/
    incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/util/DownloadUtil.as
    incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/view/UpdaterDialog.mxml
Modified:
    incubator/flex/utilities/InstallApacheFlex/build.number
    incubator/flex/utilities/InstallApacheFlex/build.properties
    incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex-app.xml
    incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex.mxml

Modified: incubator/flex/utilities/InstallApacheFlex/build.number
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/build.number?rev=1364558&r1=1364557&r2=1364558&view=diff
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/build.number (original)
+++ incubator/flex/utilities/InstallApacheFlex/build.number Mon Jul 23 09:53:41 2012
@@ -1,3 +1,3 @@
-#Build Number for ANT. Do not edit!
-#Fri Jul 20 13:51:42 EDT 2012
-build.number=2
+#Build Number for ANT. Do not edit!
+#Mon Jul 23 02:10:34 PDT 2012
+build.number=8

Modified: incubator/flex/utilities/InstallApacheFlex/build.properties
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/build.properties?rev=1364558&r1=1364557&r2=1364558&view=diff
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/build.properties (original)
+++ incubator/flex/utilities/InstallApacheFlex/build.properties Mon Jul 23 09:53:41 2012
@@ -22,8 +22,8 @@
 release.version=0.7
 
 #The URLs for the IDE Installer Apps
-installer.url.win=TBD_WIN
-installer.url.mac=TBD_MAC
+installer.url.win=http://people.apache.org/~bigosmallm/installapacheflex/InstallApacheFlex.exe
+installer.url.mac=http://people.apache.org/~bigosmallm/installapacheflex/InstallApacheFlex.dmg
 
 #Flex Locations
 //FLEX_HOME=../ApacheFlex

Modified: incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex-app.xml
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex-app.xml?rev=1364558&r1=1364557&r2=1364558&view=diff
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex-app.xml (original)
+++ incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex-app.xml Mon Jul 23 09:53:41
2012
@@ -45,7 +45,7 @@
 	<!-- A string value of the format <0-999>.<0-999>.<0-999> that represents
application version which can be used to check for application upgrade. 
 	Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
 	An updated version of application must have a versionNumber value higher than the previous
version. Required for namespace >= 2.5 . -->
-	<versionNumber>0.7.1</versionNumber>
+	<versionNumber>0.7.8</versionNumber>
 		         
 	<!-- A string value (such as "v1", "2.5", or "Alpha 1") that represents the version of
the application, as it should be shown to users. Optional. -->
 	<!-- <versionLabel></versionLabel> -->

Modified: incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex.mxml?rev=1364558&r1=1364557&r2=1364558&view=diff
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex.mxml (original)
+++ incubator/flex/utilities/InstallApacheFlex/src/InstallApacheFlex.mxml Mon Jul 23 09:53:41
2012
@@ -20,7 +20,7 @@ limitations under the License.
 
 
 <!--
-This script should be used to create an Apache Flex SDK that has the
+This app should be used to create an Apache Flex SDK that has the
 directory structure that an IDE expects.
 
 The Adobe AIR SDK and the Adobe Flash Player playerglobal.swc are integrated
@@ -36,7 +36,11 @@ variables are not required because the l
 					   width="800" height="600" maxWidth="800" maxHeight="550" minWidth="800" minHeight="550"
 					   backgroundColor="0xDDDDDD" title="Package Apache Flex SDK for use in an IDE"
 					   applicationComplete="handleApplicationComplete(event)" showStatusBar="false"
-					   skinClass="ws.tink.spark.skins.controls.InstallApacheFlexSkin" xmlns:controls="ws.tink.spark.controls.*"
xmlns:controls1="org.apache.flex.packageflexsdk.view.controls.*" xmlns:components="org.apache.flex.packageflexsdk.view.components.*">
+					   skinClass="ws.tink.spark.skins.controls.InstallApacheFlexSkin" 
+					   xmlns:controls="ws.tink.spark.controls.*" 
+					   xmlns:controls1="org.apache.flex.packageflexsdk.view.controls.*" 
+					   xmlns:components="org.apache.flex.packageflexsdk.view.components.*" 
+					   >
 	
 	<fx:Style source="assets/styles/styles.css" />
 	
@@ -46,12 +50,16 @@ variables are not required because the l
 			import flash.globalization.StringTools;
 			
 			import mx.collections.ArrayCollection;
+			import mx.core.IFlexDisplayObject;
 			import mx.events.FlexEvent;
+			import mx.managers.PopUpManager;
+			import mx.rpc.events.ResultEvent;
 			import mx.utils.StringUtil;
 			
 			import org.apache.flex.packageflexsdk.model.OptionalComponentVO;
 			import org.apache.flex.packageflexsdk.resource.RuntimeLocale;
 			import org.apache.flex.packageflexsdk.resource.ViewResourceConstants;
+			import org.apache.flex.packageflexsdk.view.UpdaterDialog;
 			import org.apache.flex.packageflexsdk.view.components.AdobeLicense;
 			import org.apache.flex.packageflexsdk.view.components.ConsoleWindow;
 			import org.apache.flex.packageflexsdk.view.components.MPLLicense;
@@ -65,6 +73,11 @@ variables are not required because the l
 			import ws.tink.spark.controls.StepItem;
 			
 			/**
+			 * The url that stores the current version number of the InstallApacheFlex.{exe|dmg} 

+			 */
+			private var VERSION_URL:String;
+			
+			/**
 			 * Apache Flex binary distribution
 			 * 
 			 * Values stored in ApacheFlexConfig.xml edit file to change
@@ -224,6 +237,8 @@ variables are not required because the l
 				var files:XMLList = data.files.file;
 				var keepGoing:Boolean = true;
 				
+				VERSION_URL = data.versionurl.toString();
+				
 				APACHE_FLEX_BIN_DISTRO_FILE = files.(@name == 'ApacheFlexSDK').@file.toString();
 				APACHE_FLEX_BIN_DISTRO_URL = files.(@name == 'ApacheFlexSDK').@path.toString();
 				if (!APACHE_FLEX_BIN_DISTRO_FILE || !APACHE_FLEX_BIN_DISTRO_URL)
@@ -304,10 +319,51 @@ variables are not required because the l
 			
 			protected function main():void
 			{
+				checkVersion();
 				initiateInstallStepsActivity();
 				initializeOptionInstallsDataProvider();
 			}
 			
+			protected function checkVersion():void
+			{
+				copyOrDownload(VERSION_URL,handleVersionResult,null,handleVersionError);
+			}
+			
+			protected function handleVersionResult(e:Event):void
+			{
+				//Version available
+				var versionXML:XML = XML(e.target.data);
+				var newVersion:String = versionXML.version.toString();
+				
+				//Current version
+				var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
+				var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
+				var currentVersion:String = applicationDescriptor.xmlns::versionNumber.toString();
+				
+				if(newVersion > currentVersion)
+				{
+					showUpdateDialog(versionXML);
+				}
+			}
+			
+			protected function showUpdateDialog(versionXML:XML):void
+			{
+				var updaterDialog:UpdaterDialog = UpdaterDialog(PopUpManager.createPopUp(this,UpdaterDialog,true));
+				updaterDialog.versionXML = versionXML;
+				PopUpManager.centerPopUp(updaterDialog);
+				updaterDialog.addEventListener("close",handleUpdaterDialogClose);
+			}
+			
+			protected function handleUpdaterDialogClose(event:Event):void
+			{
+				PopUpManager.removePopUp(IFlexDisplayObject(event.target));
+			}
+			
+			protected function handleVersionError(e:Event):void
+			{
+				trace();
+			}
+			
 			protected function handleInstallBtnClick(event:MouseEvent):void
 			{
 				if (flexSDKTxtInput.text == "")
@@ -1039,34 +1095,6 @@ variables are not required because the l
 				file.copyTo(copyToFile,true);
 			}
 			
-			/* 			protected function downloadAdobeFlexSDK(callAfterDownloadFunction:Function):void
-			{
-			try
-			{
-			_adobeFlexSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_FLEX_4_6_FILE);
-			var errorHandler:Function = getErrorHandlerFromStep(_currentOptionalStep);
-			copyOrDownload(ADOBE_FLEX_4_6_URL + ADOBE_FLEX_4_6_FILE, callAfterDownloadFunction, _adobeFlexSDKZipFile,
errorHandler);
-			}
-			catch (e:Error)
-			{
-			updateActivityStep(_currentOptionalStep.label, StepItem.ERROR);
-			installNextOptionalComponent();
-			}
-			} */
-			
-			/* 			protected function getErrorHandlerFromStep(step:StepItem):Function
-			{
-			if(step.label == _constants.STEP_OPTIONAL_INSTALL_BLAZEDS)
-			{
-			return handleBlazeDSInstallError;
-			}
-			else if (step.label == _constants.STEP_OPTIONAL_INSTALL_FONTSWF)
-			{
-			return handleFontSWFInstallError;
-			}
-			return null;
-			} */
-			
 			protected function handleBlazeDSInstallError(event:*=null):void{
 				updateActivityStep(_constants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
 				updateOptionalComponentInstallStatusAborted(_constants.STEP_OPTIONAL_INSTALL_BLAZEDS,true);
@@ -1290,7 +1318,7 @@ variables are not required because the l
 				return dir;
 			}
 			
-			private function copyOrDownload(url:String, handlerFunction:Function, dest:File, errorFunction:Function=null):void
+			private function copyOrDownload(url:String, handlerFunction:Function, dest:File=null,
errorFunction:Function=null):void
 			{
 				if (url.search("http") == 0)
 				{

Added: incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/NativeApplicationUpdater.as
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/NativeApplicationUpdater.as?rev=1364558&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/NativeApplicationUpdater.as
(added)
+++ incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/NativeApplicationUpdater.as
Mon Jul 23 09:53:41 2012
@@ -0,0 +1,562 @@
+package com.riaspace.nativeApplicationUpdater
+{
+	import air.update.events.DownloadErrorEvent;
+	import air.update.events.StatusUpdateErrorEvent;
+	import air.update.events.StatusUpdateEvent;
+	import air.update.events.UpdateEvent;
+	
+	import com.riaspace.nativeApplicationUpdater.utils.HdiutilHelper;
+	
+	import flash.desktop.NativeApplication;
+	import flash.desktop.NativeProcess;
+	import flash.desktop.NativeProcessStartupInfo;
+	import flash.events.ErrorEvent;
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.IOErrorEvent;
+	import flash.events.ProgressEvent;
+	import flash.filesystem.File;
+	import flash.filesystem.FileMode;
+	import flash.filesystem.FileStream;
+	import flash.net.URLLoader;
+	import flash.net.URLRequest;
+	import flash.net.URLStream;
+	import flash.system.Capabilities;
+	import flash.utils.ByteArray;
+	import flash.utils.setTimeout;
+
+	[Event(name="initialized", type="air.update.events.UpdateEvent")]
+	[Event(name="checkForUpdate", type="air.update.events.UpdateEvent")]
+	[Event(name="updateStatus",type="air.update.events.StatusUpdateEvent")]
+	[Event(name="updateError",type="air.update.events.StatusUpdateErrorEvent")]
+	[Event(name="downloadStart",type="air.update.events.UpdateEvent")]
+	[Event(name="downloadError",type="air.update.events.DownloadErrorEvent")]
+	[Event(name="downloadComplete",type="air.update.events.UpdateEvent")]
+	[Event(name="progress",type="flash.events.ProgressEvent")]
+	[Event(name="error",type="flash.events.ErrorEvent")]
+	
+	public class NativeApplicationUpdater extends EventDispatcher
+	{
+		
+		namespace UPDATE_XMLNS_1_0 = "http://ns.riaspace.com/air/framework/update/description/1.0";
+		
+		namespace UPDATE_XMLNS_1_1 = "http://ns.riaspace.com/air/framework/update/description/1.1";
+		
+		/**
+		 * The updater has not been initialized.
+		 **/
+		public static const UNINITIALIZED:String = "UNINITIALIZED";
+		
+		/**
+		 * The updater is initializing.
+		 **/
+		public static const INITIALIZING:String = "INITIALIZING";
+		
+		/**
+		 * The updater has been initialized.
+		 **/
+		public static const READY:String = "READY";
+		
+		/**
+		 * The updater has not yet checked for the update descriptor file.
+		 **/
+		public static const BEFORE_CHECKING:String = "BEFORE_CHECKING";
+		
+		/**
+		 * The updater is checking for an update descriptor file.
+		 **/
+		public static const CHECKING:String = "CHECKING";
+		
+		/**
+		 * The update descriptor file is available.
+		 **/
+		public static const AVAILABLE:String = "AVAILABLE";
+
+		/**
+		 * The updater is downloading the AIR file.
+		 **/
+		public static const DOWNLOADING:String = "DOWNLOADING";
+		
+		/**
+		 * The updater has downloaded the AIR file.
+		 **/
+		public static const DOWNLOADED:String = "DOWNLOADED";
+		
+		/**
+		 * The updater is installing the AIR file.
+		 **/
+		public static const INSTALLING:String = "INSTALLING";
+		
+		[Bindable]		
+		public var updateURL:String;
+		
+		protected var _isNewerVersionFunction:Function;
+		
+		protected var _updateDescriptor:XML;
+		
+		protected var _updateVersion:String;
+		
+		protected var _updatePackageURL:String;
+		
+		protected var _updateDescription:String;
+
+		protected var _currentVersion:String;
+		
+		protected var _downloadedFile:File;
+		
+		protected var _installerType:String;
+		
+		protected var _currentState:String = UNINITIALIZED;
+		
+		protected var updateDescriptorLoader:URLLoader;
+		
+		protected var os:String = Capabilities.os.toLowerCase();
+		
+		protected var urlStream:URLStream;
+		
+		protected var fileStream:FileStream;
+		
+		public function NativeApplicationUpdater()
+		{
+		}
+		
+		public function initialize():void
+		{
+			if (currentState == UNINITIALIZED)
+			{
+				currentState = INITIALIZING;
+				
+				var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
+				var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
+				
+				if (xmlns.uri == "http://ns.adobe.com/air/application/2.0")
+					currentVersion = applicationDescriptor.xmlns::version;
+				else
+					currentVersion = applicationDescriptor.xmlns::versionNumber;
+
+				if (os.indexOf("win") > -1)
+				{
+					installerType = "exe";
+				}
+				else if (os.indexOf("mac") > -1)
+				{
+					installerType = "dmg";
+				}
+				else if (os.indexOf("linux") > -1)
+				{
+					if ((new File("/usr/bin/dpkg")).exists)
+						installerType = "deb";
+					else
+						installerType = "rpm";
+				}
+				else
+				{
+					dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, "Not supported os type!",
UpdaterErrorCodes.ERROR_9000));
+				}
+				
+				currentState = READY;
+				dispatchEvent(new UpdateEvent(UpdateEvent.INITIALIZED));
+			}
+		}
+		
+		public function checkNow():void
+		{
+			if (currentState == READY)
+			{
+				currentState = BEFORE_CHECKING;
+				
+				var checkForUpdateEvent:UpdateEvent = new UpdateEvent(UpdateEvent.CHECK_FOR_UPDATE, false,
true);
+				dispatchEvent(checkForUpdateEvent);
+
+				if (!checkForUpdateEvent.isDefaultPrevented())
+				{
+					addEventListener(StatusUpdateEvent.UPDATE_STATUS,
+						function(event:StatusUpdateEvent):void
+						{
+							if (event.available && !event.isDefaultPrevented())
+								downloadUpdate();
+						});
+					addEventListener(UpdateEvent.DOWNLOAD_COMPLETE,
+						function(event:UpdateEvent):void
+						{
+							if (!event.isDefaultPrevented())
+								installUpdate();
+						});
+					
+					checkForUpdate();
+				}
+			}
+		}
+		
+		/**
+		 * ------------------------------------ CHECK FOR UPDATE SECTION -------------------------------------
+		 */
+
+		/**
+		 * Checks for update, this can be runned only in situation when UpdateEvent.CHECK_FOR_UPDATE
was cancelled.
+		 */ 
+		public function checkForUpdate():void
+		{
+			if (currentState == BEFORE_CHECKING)
+			{
+				currentState = CHECKING;
+				
+				updateDescriptorLoader =  new URLLoader();
+				updateDescriptorLoader.addEventListener(Event.COMPLETE,  updateDescriptorLoader_completeHandler);
+				updateDescriptorLoader.addEventListener(IOErrorEvent.IO_ERROR, updateDescriptorLoader_ioErrorHandler);
+				try
+				{
+					updateDescriptorLoader.load(new URLRequest(updateURL));
+				}
+				catch(error:Error)
+				{
+					dispatchEvent(new StatusUpdateErrorEvent(StatusUpdateErrorEvent.UPDATE_ERROR, false,
false, 
+						"Error downloading update descriptor file: " + error.message, 
+						UpdaterErrorCodes.ERROR_9002, error.errorID));
+				}
+			}
+		}
+
+		protected function updateDescriptorLoader_completeHandler(event:Event):void
+		{
+			updateDescriptorLoader.removeEventListener(Event.COMPLETE, updateDescriptorLoader_completeHandler);
+			updateDescriptorLoader.removeEventListener(IOErrorEvent.IO_ERROR, updateDescriptorLoader_ioErrorHandler);
+			updateDescriptorLoader.close();
+			
+			updateDescriptor = new XML(updateDescriptorLoader.data);
+			
+			if (updateDescriptor.namespace() == UPDATE_XMLNS_1_0)
+			{
+				updateVersion = updateDescriptor.UPDATE_XMLNS_1_0::version;
+				updateDescription = updateDescriptor.UPDATE_XMLNS_1_0::description;
+				updatePackageURL = updateDescriptor.UPDATE_XMLNS_1_0::urls.UPDATE_XMLNS_1_1::[installerType];
+			}
+			else
+			{
+				var typeXml:XMLList = updateDescriptor.UPDATE_XMLNS_1_1::[installerType];
+				if (typeXml.length() > 0)
+				{
+					updateVersion = typeXml.UPDATE_XMLNS_1_1::version;
+					updateDescription = typeXml.UPDATE_XMLNS_1_1::description;
+					updatePackageURL = typeXml.UPDATE_XMLNS_1_1::url;
+				}
+			}
+
+			if (!updateVersion || !updatePackageURL)
+			{
+				dispatchEvent(new StatusUpdateErrorEvent(StatusUpdateErrorEvent.UPDATE_ERROR, false,
false, 
+					"Update package is not defined for current installerType: " + installerType, UpdaterErrorCodes.ERROR_9001));
+				return;
+			}
+
+			currentState = AVAILABLE;			
+			dispatchEvent(new StatusUpdateEvent(
+				StatusUpdateEvent.UPDATE_STATUS, false, true, 
+				isNewerVersionFunction.call(this, currentVersion, updateVersion), updateVersion)); //
TODO: handle last event param with details (description)
+		}
+		
+		protected function updateDescriptorLoader_ioErrorHandler(event:IOErrorEvent):void
+		{
+			updateDescriptorLoader.removeEventListener(Event.COMPLETE, updateDescriptorLoader_completeHandler);
+			updateDescriptorLoader.removeEventListener(IOErrorEvent.IO_ERROR, updateDescriptorLoader_ioErrorHandler);
+			updateDescriptorLoader.close();
+			
+			dispatchEvent(new StatusUpdateErrorEvent(StatusUpdateErrorEvent.UPDATE_ERROR, false, false,

+				"IO Error downloading update descriptor file: " + event.text,
+				UpdaterErrorCodes.ERROR_9003, event.errorID));
+		}
+
+		/**
+		 * ------------------------------------ DOWNLOAD UPDATE SECTION -------------------------------------
+		 */
+
+		/**
+		 * Starts downloading update.
+		 */
+		public function downloadUpdate():void
+		{
+			if (currentState == AVAILABLE)
+			{
+				var fileName:String = updatePackageURL.substr(updatePackageURL.lastIndexOf("/") + 1);
+				downloadedFile = File.createTempDirectory().resolvePath(fileName);
+				
+				fileStream = new FileStream();
+				fileStream.addEventListener(IOErrorEvent.IO_ERROR, urlStream_ioErrorHandler);
+				fileStream.addEventListener(Event.CLOSE, fileStream_closeHandler);
+				fileStream.openAsync(downloadedFile, FileMode.WRITE);
+				
+				urlStream = new URLStream();
+				urlStream.addEventListener(Event.OPEN, urlStream_openHandler);
+				urlStream.addEventListener(ProgressEvent.PROGRESS, urlStream_progressHandler);
+				urlStream.addEventListener(Event.COMPLETE, urlStream_completeHandler);
+				urlStream.addEventListener(IOErrorEvent.IO_ERROR, urlStream_ioErrorHandler);
+
+				try
+				{
+					urlStream.load(new URLRequest(updatePackageURL));
+				}
+				catch(error:Error)
+				{
+					dispatchEvent(new DownloadErrorEvent(DownloadErrorEvent.DOWNLOAD_ERROR, false, false,

+						"Error downloading update file: " + error.message, UpdaterErrorCodes.ERROR_9004, error.message));
+				}
+			}
+		}
+
+		protected function urlStream_openHandler(event:Event):void
+		{
+			currentState = NativeApplicationUpdater.DOWNLOADING;
+			dispatchEvent(new UpdateEvent(UpdateEvent.DOWNLOAD_START));
+		}
+		
+		protected function fileStream_closeHandler(event:Event):void
+		{
+			fileStream.removeEventListener(Event.CLOSE, fileStream_closeHandler);
+			fileStream.removeEventListener(IOErrorEvent.IO_ERROR, urlStream_ioErrorHandler);
+			
+			currentState = NativeApplicationUpdater.DOWNLOADED;
+			dispatchEvent(new UpdateEvent(UpdateEvent.DOWNLOAD_COMPLETE, false, true));
+		}
+		
+		protected function urlStream_progressHandler(event:ProgressEvent):void
+		{
+			var bytes:ByteArray = new ByteArray();
+			urlStream.readBytes(bytes);
+			fileStream.writeBytes(bytes);
+			dispatchEvent(event);
+		}
+		
+		protected function urlStream_completeHandler(event:Event):void
+		{
+			urlStream.removeEventListener(Event.OPEN, urlStream_openHandler);
+			urlStream.removeEventListener(ProgressEvent.PROGRESS, urlStream_progressHandler);
+			urlStream.removeEventListener(Event.COMPLETE, urlStream_completeHandler);
+			urlStream.removeEventListener(IOErrorEvent.IO_ERROR, urlStream_ioErrorHandler);
+			urlStream.close();
+
+			fileStream.close();
+		}
+
+		protected function urlStream_ioErrorHandler(event:IOErrorEvent):void
+		{
+			fileStream.removeEventListener(Event.CLOSE, fileStream_closeHandler);
+			fileStream.removeEventListener(IOErrorEvent.IO_ERROR, urlStream_ioErrorHandler);
+			fileStream.close();
+
+			urlStream.removeEventListener(Event.OPEN, urlStream_openHandler);
+			urlStream.removeEventListener(ProgressEvent.PROGRESS, urlStream_progressHandler);
+			urlStream.removeEventListener(Event.COMPLETE, urlStream_completeHandler);
+			urlStream.removeEventListener(IOErrorEvent.IO_ERROR, urlStream_ioErrorHandler);
+			urlStream.close();
+			
+			dispatchEvent(new DownloadErrorEvent(DownloadErrorEvent.DOWNLOAD_ERROR, false, false,

+				"Error downloading update file: " + event.text, UpdaterErrorCodes.ERROR_9005, event.errorID));
+		}
+		
+		/**
+		 * ------------------------------------ INSTALL UPDATE SECTION -------------------------------------
+		 */
+		
+		/**
+		 * Installs downloaded update
+		 */ 
+		public function installUpdate():void
+		{
+			if (currentState == DOWNLOADED)
+			{
+				if (os.indexOf("win") > -1)
+				{
+					installFromFile(downloadedFile);
+				}
+				else if (os.indexOf("mac") > -1)
+				{
+					var hdiutilHelper:HdiutilHelper = new HdiutilHelper(downloadedFile);
+					hdiutilHelper.addEventListener(Event.COMPLETE, hdiutilHelper_completeHandler);
+					hdiutilHelper.addEventListener(ErrorEvent.ERROR, hdiutilHelper_errorHandler);
+					hdiutilHelper.attach();
+				}
+				else if (os.indexOf("linux") > -1)
+				{
+					installFromFile(downloadedFile);
+				}
+			}
+		}
+
+		private function hdiutilHelper_errorHandler(event:ErrorEvent):void
+		{
+			var hdiutilHelper:HdiutilHelper = event.target as HdiutilHelper;
+			hdiutilHelper.removeEventListener(Event.COMPLETE, hdiutilHelper_completeHandler);
+			hdiutilHelper.removeEventListener(ErrorEvent.ERROR, hdiutilHelper_errorHandler);
+			
+			dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, 
+				"Error attaching dmg file!", UpdaterErrorCodes.ERROR_9008));
+		}
+
+		private function hdiutilHelper_completeHandler(event:Event):void
+		{
+			var hdiutilHelper:HdiutilHelper = event.target as HdiutilHelper;
+			hdiutilHelper.removeEventListener(Event.COMPLETE, hdiutilHelper_completeHandler);
+			hdiutilHelper.removeEventListener(ErrorEvent.ERROR, hdiutilHelper_errorHandler);
+			
+			var attachedDmg:File = new File(hdiutilHelper.mountPoint);
+			var files:Array = attachedDmg.getDirectoryListing();
+			
+			if (files.length == 1)
+			{
+				var installFileFolder:File = File(files[0]).resolvePath("Contents/MacOS");
+				var installFiles:Array = installFileFolder.getDirectoryListing();
+
+				if (installFiles.length == 1)
+					installFromFile(installFiles[0]);
+				else
+					dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, 
+						"Contents/MacOS folder should contain only 1 install file!", UpdaterErrorCodes.ERROR_9006));
+			}
+			else
+			{
+				dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, 
+					"Mounted volume should contain only 1 install file!", UpdaterErrorCodes.ERROR_9007));
+			}
+		}
+		
+		protected function installFromFile(updateFile:File):void
+		{
+			var beforeInstallEvent:UpdateEvent = new UpdateEvent(UpdateEvent.BEFORE_INSTALL, false,
true);
+			dispatchEvent(beforeInstallEvent);
+			
+			if (!beforeInstallEvent.isDefaultPrevented())
+			{
+				currentState = INSTALLING;
+				
+				if (os.indexOf("linux") > -1)
+				{
+					updateFile.openWithDefaultApplication();
+				}
+				else
+				{
+					var info:NativeProcessStartupInfo = new NativeProcessStartupInfo();
+					var cmdExe:File = (os.indexOf("win") > -1) ? new File("C:\\Windows\\System32\\cmd.exe")
: null;
+					if (cmdExe && cmdExe.exists)
+					{
+						var args:Vector.<String> = new Vector.<String>();
+						args.push("/c", updateFile.nativePath);
+
+						info.executable = cmdExe;
+						info.arguments = args;
+					}
+					else
+					{
+						info.executable = updateFile;
+					}
+					
+					var installProcess:NativeProcess = new NativeProcess();
+					installProcess.start(info);
+				}
+				
+				setTimeout(NativeApplication.nativeApplication.exit, 200);
+			}
+		}
+		
+		[Bindable]
+		public function get currentVersion():String
+		{
+			return _currentVersion;
+		}
+
+		protected function set currentVersion(value:String):void
+		{
+			_currentVersion = value;
+		}
+
+		[Bindable]
+		public function get updateVersion():String
+		{
+			return _updateVersion;
+		}
+
+		protected function set updateVersion(value:String):void
+		{
+			_updateVersion = value;
+		}
+
+		[Bindable]
+		public function get updateDescriptor():XML
+		{
+			return _updateDescriptor;
+		}
+
+		protected function set updateDescriptor(value:XML):void
+		{
+			_updateDescriptor = value;
+		}
+
+		[Bindable]
+		public function get currentState():String
+		{
+			return _currentState;
+		}
+
+		protected function set currentState(value:String):void
+		{
+			_currentState = value;
+		}
+
+		[Bindable]
+		public function get downloadedFile():File
+		{
+			return _downloadedFile;
+		}
+
+		protected function set downloadedFile(value:File):void
+		{
+			_downloadedFile = value;
+		}
+
+		[Bindable]
+		public function get isNewerVersionFunction():Function
+		{
+			if (_isNewerVersionFunction != null)
+				return _isNewerVersionFunction;
+			else
+				return function(currentVersion:String, updateVersion:String):Boolean { return currentVersion
!= updateVersion};
+		}
+
+		public function set isNewerVersionFunction(value:Function):void
+		{
+			_isNewerVersionFunction = value;
+		}
+
+		[Bindable]
+		public function get installerType():String
+		{
+			return _installerType;
+		}
+
+		protected function set installerType(value:String):void
+		{
+			_installerType = value;
+		}
+
+		[Bindable]
+		public function get updatePackageURL():String
+		{
+			return _updatePackageURL;
+		}
+		
+		protected function set updatePackageURL(value:String):void
+		{
+			_updatePackageURL = value;
+		}
+		
+		[Bindable]
+		public function get updateDescription():String
+		{
+			return _updateDescription;
+		}
+		
+		protected function set updateDescription(value:String):void
+		{
+			_updateDescription = value;
+		}
+	}
+}

Added: incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/UpdaterErrorCodes.as
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/UpdaterErrorCodes.as?rev=1364558&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/UpdaterErrorCodes.as
(added)
+++ incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/UpdaterErrorCodes.as
Mon Jul 23 09:53:41 2012
@@ -0,0 +1,51 @@
+package com.riaspace.nativeApplicationUpdater
+{
+	public class UpdaterErrorCodes
+	{
+		/**
+		 * Not supported os type.
+		 */
+		public static const ERROR_9000:uint = 9000;
+		
+		/**
+		 * Update package is not defined for current installerType.
+		 */
+		public static const ERROR_9001:uint = 9001;
+		
+		/**
+		 * Error downloading update descriptor file.
+		 */
+		public static const ERROR_9002:uint = 9002;
+
+		/**
+		 * IO Error downloading update descriptor file.
+		 */
+		public static const ERROR_9003:uint = 9003;
+
+		/**
+		 * Error downloading update file.
+		 */
+		public static const ERROR_9004:uint = 9004;
+
+		/**
+		 * Error downloading update file.
+		 */
+		public static const ERROR_9005:uint = 9005;
+
+		/**
+		 * Contents/MacOS folder should contain only 1 install file.
+		 */
+		public static const ERROR_9006:uint = 9006;
+
+		/**
+		 * Mounted volume should contain only 1 install file.
+		 */
+		public static const ERROR_9007:uint = 9007;
+
+		/**
+		 * Error attaching dmg file.
+		 */
+		public static const ERROR_9008:uint = 9008;
+
+	}
+}
\ No newline at end of file

Added: incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/utils/HdiutilHelper.as
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/utils/HdiutilHelper.as?rev=1364558&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/utils/HdiutilHelper.as
(added)
+++ incubator/flex/utilities/InstallApacheFlex/src/com/riaspace/nativeApplicationUpdater/utils/HdiutilHelper.as
Mon Jul 23 09:53:41 2012
@@ -0,0 +1,98 @@
+package com.riaspace.nativeApplicationUpdater.utils
+{
+	import flash.desktop.NativeProcess;
+	import flash.desktop.NativeProcessStartupInfo;
+	import flash.events.ErrorEvent;
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.IOErrorEvent;
+	import flash.events.ProgressEvent;
+	import flash.filesystem.File;
+
+	[Event(name="complete",type="flash.events.Event")]
+	[Event(name="error",type="flash.events.ErrorEvent")]
+	
+	public class HdiutilHelper extends EventDispatcher
+	{
+		private var dmg:File;
+		
+		private var result:Function;
+		
+		private var error:Function;
+		
+		private var hdiutilProcess:NativeProcess;
+		
+		public var mountPoint:String;
+		
+		public function HdiutilHelper(dmg:File)
+		{
+			this.dmg = dmg;
+			this.result = result;
+			this.error = error;
+		}
+		
+		public function attach():void
+		{
+			var info:NativeProcessStartupInfo = new NativeProcessStartupInfo();
+			info.executable = new File("/usr/bin/hdiutil");
+			
+			var args:Vector.<String> = new Vector.<String>();
+			args.push("attach", "-plist", dmg.nativePath);
+			info.arguments = args;
+			
+			hdiutilProcess = new NativeProcess();
+			hdiutilProcess.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, hdiutilProcess_errorHandler);
+			hdiutilProcess.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, hdiutilProcess_errorHandler);
+			hdiutilProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, hdiutilProcess_outputHandler);
+			hdiutilProcess.start(info);
+		}
+
+		private function hdiutilProcess_outputHandler(event:ProgressEvent):void
+		{
+			hdiutilProcess.removeEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, hdiutilProcess_errorHandler);
+			hdiutilProcess.removeEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, hdiutilProcess_errorHandler);
+			hdiutilProcess.removeEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, hdiutilProcess_outputHandler);
+			hdiutilProcess.exit();
+			
+			// Storing current XML settings
+			var xmlSettings:Object = XML.settings();
+			// Setting required custom XML settings
+			XML.setSettings(
+				{
+					ignoreWhitespace : true,
+					ignoreProcessingInstructions : true,
+					ignoreComments : true,
+					prettyPrinting : false
+				});
+				
+			var plist:XML = new XML(hdiutilProcess.standardOutput.readUTFBytes(event.bytesLoaded));
+			var dicts:XMLList = plist.dict.array.dict;
+
+			// INFO: for some reason E4X didn't work
+			for each(var dict:XML in dicts)
+			{
+				for each(var element:XML in dict.elements())
+				{
+					if (element.name() == "key" && element.text() == "mount-point")
+					{
+						mountPoint = dict.child(element.childIndex() + 1);
+						break;
+					}
+				}
+			}
+
+			// Reverting back original XML settings
+			XML.setSettings(xmlSettings);
+			
+			if (mountPoint)
+				dispatchEvent(new Event(Event.COMPLETE));
+			else
+				dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, "Couldn't find mount point!"));
+		}
+
+		private function hdiutilProcess_errorHandler(event:IOErrorEvent):void
+		{
+			dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, event.text, event.errorID));
+		}
+	}
+}
\ No newline at end of file

Added: incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/util/DownloadUtil.as
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/util/DownloadUtil.as?rev=1364558&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/util/DownloadUtil.as
(added)
+++ incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/util/DownloadUtil.as
Mon Jul 23 09:53:41 2012
@@ -0,0 +1,75 @@
+package org.apache.flex.packageflexsdk.util
+{
+	import flash.desktop.NativeProcess;
+	import flash.desktop.NativeProcessStartupInfo;
+	import flash.events.ErrorEvent;
+	import flash.events.Event;
+	import flash.events.IOErrorEvent;
+	import flash.events.NativeProcessExitEvent;
+	import flash.events.ProgressEvent;
+	import flash.filesystem.File;
+	import flash.net.URLLoader;
+	import flash.net.URLLoaderDataFormat;
+	import flash.net.URLRequest;
+	import flash.system.Capabilities;
+
+	public class DownloadUtil
+	{
+		public static function download(url:String, completeFunction:Function, errorFunction:Function=null,
progressFunction:Function=null):void
+		{
+			var loader:URLLoader = new URLLoader();
+			var req:URLRequest = new URLRequest(url);
+			req.idleTimeout = 60000;
+			
+			loader.dataFormat = URLLoaderDataFormat.BINARY; 
+			loader.addEventListener(Event.COMPLETE, completeFunction,false,0,true);
+			
+			if (errorFunction != null)
+			{
+				loader.addEventListener(ErrorEvent.ERROR,errorFunction,false,0,true);
+				loader.addEventListener(IOErrorEvent.IO_ERROR,errorFunction,false,0,true);
+			}
+			if(progressFunction != null)
+			{
+				loader.addEventListener(ProgressEvent.PROGRESS, progressFunction,false,0,true);
+			}
+			
+			loader.load(req);
+		}
+		
+		public static function invokeNativeProcess(args:Vector.<String>):void
+		{
+			var os:String = Capabilities.os.toLowerCase();
+			var info:NativeProcessStartupInfo = new NativeProcessStartupInfo();
+			var cmdExe:File = (os.indexOf("win") > -1) ? new File("C:\\Windows\\System32\\cmd.exe")
: null;
+			if (cmdExe && cmdExe.exists)
+			{
+				info.executable = cmdExe;
+				info.arguments = args;
+			}
+			var installProcess:NativeProcess = new NativeProcess();
+			installProcess.start(info);
+		}
+		
+		public static function executeFile(file:File,completeFunction:Function=null):void
+		{
+			var os:String = Capabilities.os.toLowerCase();
+			var info:NativeProcessStartupInfo = new NativeProcessStartupInfo();
+			info.executable = file;
+			var process:NativeProcess = new NativeProcess();
+			if(completeFunction != null)
+			{
+				process.addEventListener(NativeProcessExitEvent.EXIT, completeFunction,false,0,true);
+			}
+			process.addEventListener(NativeProcessExitEvent.EXIT, handleNativeProcessComplete,false,0,true);
+			process.start(info);
+		}
+		
+		protected static function handleNativeProcessComplete(event:NativeProcessExitEvent):void
+		{
+			var process:NativeProcess = NativeProcess(event.target);
+			process.closeInput();
+			process.exit(true);
+		}
+	}
+}
\ No newline at end of file

Added: incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/view/UpdaterDialog.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/view/UpdaterDialog.mxml?rev=1364558&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/view/UpdaterDialog.mxml
(added)
+++ incubator/flex/utilities/InstallApacheFlex/src/org/apache/flex/packageflexsdk/view/UpdaterDialog.mxml
Mon Jul 23 09:53:41 2012
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8"?>
+<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" 
+			   xmlns:s="library://ns.adobe.com/flex/spark" 
+			   xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" xmlns:controls="ws.tink.spark.controls.*">
+	<fx:Script>
+		<![CDATA[
+			import air.update.events.DownloadErrorEvent;
+			import air.update.events.StatusUpdateEvent;
+			import air.update.events.UpdateEvent;
+			
+			import com.riaspace.nativeApplicationUpdater.utils.HdiutilHelper;
+			
+			import mx.controls.Alert;
+			import mx.events.CloseEvent;
+			import mx.utils.DisplayUtil;
+			
+			import org.apache.flex.packageflexsdk.util.DownloadUtil;
+			
+			[Bindable] private var _newVersion:String;
+			private var _urlWindows:String;
+			private var _fileWindows:File;
+			private var _urlMac:String;
+			private var _fileMac:File;
+			
+			protected function handleYesBtnClick(event:MouseEvent):void
+			{
+				downloadUpdater();
+			}
+			
+			protected function downloadUpdater():void
+			{
+				var os:String = Capabilities.os.toLowerCase();
+				if (os.indexOf("win") > -1)
+				{
+					DownloadUtil.download(_urlWindows,handleWindowsInstallerDownloadComplete,handleDownloadError,
handleDownloadProgress);
+				}
+				else if (os.indexOf("mac") > -1)
+				{
+					DownloadUtil.download(_urlMac,handleMacInstallerDownloadComplete,handleDownloadError,
handleDownloadProgress);
+				}
+			}
+			
+			protected function handleWindowsInstallerDownloadComplete(event:Event):void
+			{
+				_fileWindows = File.createTempFile();
+				writeFileToDirectory(_fileWindows,event.target.data);
+				installFromFile(_fileWindows);
+			}
+			
+			protected function installFromFile(file:File):void
+			{
+				DownloadUtil.executeFile(file);
+				setTimeout(NativeApplication.nativeApplication.exit, 200);
+			}
+			
+			protected function handleMacInstallerDownloadComplete(event:Event):void
+			{
+				_fileMac = File.createTempFile();
+				writeFileToDirectory(_fileMac,event.target.data);
+				var hdiutilHelper:HdiutilHelper = new HdiutilHelper(_fileMac);
+				hdiutilHelper.addEventListener(Event.COMPLETE, handleHdiutilHelperComplete);
+				hdiutilHelper.addEventListener(ErrorEvent.ERROR, handleHdiutilHelperError);
+				hdiutilHelper.attach();
+			}
+			
+			private function handleHdiutilHelperComplete(event:Event):void
+			{
+				var hdiutilHelper:HdiutilHelper = event.target as HdiutilHelper;
+				hdiutilHelper.removeEventListener(Event.COMPLETE, handleHdiutilHelperComplete);
+				hdiutilHelper.removeEventListener(ErrorEvent.ERROR, handleHdiutilHelperError);
+				
+				var attachedDmg:File = new File(hdiutilHelper.mountPoint);
+				var files:Array = attachedDmg.getDirectoryListing();
+				
+				if (files.length == 1)
+				{
+					var installFileFolder:File = File(files[0]).resolvePath("Contents/MacOS");
+					var installFiles:Array = installFileFolder.getDirectoryListing();
+					
+					if (installFiles.length == 1)
+					{
+						installFromFile(installFiles[0]);
+					}
+					else
+						dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, 
+							"Contents/MacOS folder should contain only 1 install file!"));
+				}
+				else
+				{
+					dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, 
+						"Mounted volume should contain only 1 install file!"));
+				}
+			}
+			
+			private function handleHdiutilHelperError(event:ErrorEvent):void
+			{
+				var hdiutilHelper:HdiutilHelper = event.target as HdiutilHelper;
+				hdiutilHelper.removeEventListener(Event.COMPLETE, handleHdiutilHelperComplete);
+				hdiutilHelper.removeEventListener(ErrorEvent.ERROR, handleHdiutilHelperError);
+				
+				dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, 
+					"Error attaching dmg file!"));
+			}
+			
+			protected function handleDownloadProgress(event:ProgressEvent):void
+			{
+				var bytesTotal:int = event.bytesTotal;
+				var bytesLoaded:int = event.bytesLoaded;
+				var percentLoaded:int = Math.round(bytesLoaded*100/bytesTotal);
+				progressBar.percent = percentLoaded;
+			}
+			
+			
+			private function handleDownloadError(event:Event):void
+			{
+				Alert.show("Error downloading update file, try again later.");
+			}
+			
+			public function set versionXML(versionXML:XML):void
+			{
+				_urlWindows = versionXML.urlWindows.toString();
+				_urlMac = versionXML.urlMac.toString();
+				_newVersion = versionXML.version.toString();
+			}
+			
+			private function writeFileToDirectory(file:File,data:ByteArray):void
+			{
+				var fs:FileStream = new FileStream();
+				fs.open(file, FileMode.WRITE);
+				fs.writeBytes(data); 
+				fs.close();
+			}
+			
+			protected function handleNoBtnClick(event:MouseEvent):void
+			{
+				dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
+			}
+		]]>
+	</fx:Script>
+	
+	<s:HGroup verticalCenter="0" horizontalCenter="0" verticalAlign="top">
+		<s:VGroup width="100%" horizontalAlign="center">
+			<s:Label text="New version ({_newVersion}) is available." />
+			<s:Label text="Do you want to download it and install?" />
+			<controls:ProgressBar id="progressBar" 
+								  width="60%" 
+								  height="21" />
+			<s:HGroup>
+				<s:Button id="btnYes" label="Yes" click="handleYesBtnClick(event)" />
+				<s:Button id="btnNo" label="No" click="handleNoBtnClick(event)" />
+			</s:HGroup>
+		</s:VGroup>
+	</s:HGroup>
+</s:TitleWindow>
\ No newline at end of file



Mime
View raw message