www.pudn.com > OracleServiceManager.zip > SystemTrayObserver.cs


using System; 
using System.Collections; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Drawing; 
using System.IO; 
using System.Net; 
using System.Reflection; 
using System.Resources; 
using System.ServiceProcess; 
using System.Threading; 
using System.Windows.Forms; 
using kae.ServiceStatePublisher; 
 
namespace kae.OracleServiceManager 
{ 
	///  
	/// SystemTrayObserver is a concrete observer listening to the current subject for changes. 
	/// SystemTrayObserver manages the tray icon interface for OSM. 
	///  
	public class SystemTrayObserver : Container 
	{ 
		protected delegate void UpdateFunction( ServiceSubject subject); 
 
		private const int INDEX_SERVICESMENU = 1; 
 
		private readonly string START; 
		private readonly string CONTINUE; 
		private readonly string PAUSE; 
		private readonly string STOP; 
 
		private OsmResources _resources; 
		private NotifyIcon _trayIcon; 
		private MenuItem _availableServicesMenu; 
		private MenuItem _startServiceMenuItem; 
		private MenuItem _stopServiceMenuItem; 
		private MenuItem _pauseServiceMenuItem; 
		private MenuItem _currentServiceMenuItem; 
		private bool _updating; 
		private EventHandler onMenuItemClick; 
		private UpdateFunction serverChanged; 
		private UpdateFunction serviceChanged; 
		private UpdateFunction serviceStateChanged; 
 
		public SystemTrayObserver( ServiceSubject subject) 
		{ 
			if (subject != null) 
			{ 
				subject.ServerChanged += new EventHandler( this.OnServerChanged); 
				subject.ServiceChanged += new EventHandler( this.OnServiceChanged); 
				subject.StateChanged += new EventHandler( this.OnStateChanged); 
			} 
 
			serverChanged = new UpdateFunction( this.ServerChanged); 
			serviceChanged = new UpdateFunction( this.ServiceChanged); 
			serviceStateChanged = new UpdateFunction( this.ServiceStateChanged); 
			onMenuItemClick = new EventHandler( this.ServiceItemClick); 
 
			_resources = OracleServiceManager.Instance.Resources; 
			START = GetAppString( "Start"); 
			CONTINUE = GetAppString( "Continue"); 
			PAUSE = GetAppString( "Pause"); 
			STOP = GetAppString( "Stop"); 
 
			InitializeComponent(); 
		} 
 
		protected override void Dispose( bool disposing) 
		{ 
			if (disposing) 
			{ 
				_availableServicesMenu.Dispose(); 
				_availableServicesMenu = null; 
				_startServiceMenuItem.Dispose(); 
				_startServiceMenuItem = null; 
				_stopServiceMenuItem.Dispose(); 
				_stopServiceMenuItem = null; 
				_pauseServiceMenuItem.Dispose(); 
				_pauseServiceMenuItem = null; 
				_currentServiceMenuItem = null; 
 
				if (_trayIcon != null) 
				{ 
					_trayIcon.Icon = null; 
					_trayIcon.Text = null; 
					_trayIcon.ContextMenu = null; 
					_trayIcon.Dispose(); 
				} 
			} 
			base.Dispose( disposing); 
		} 
 
		protected bool Updating 
		{ 
			get { return _updating; } 
			set { _updating = value; } 
		} 
 
		#region Manually generated initialization code 
		private void InitializeComponent() 
		{ 
			_trayIcon = new System.Windows.Forms.NotifyIcon( this); 
			_trayIcon.Icon = _resources.GetApplicationImage(); 
			_trayIcon.Visible = true; 
			SetDefaultTrayIconText(); 
			_trayIcon.ContextMenu = new ContextMenu(); 
			_trayIcon.DoubleClick += new EventHandler( this.NotifyIconDoubleClick); 
 
			string menuLabel = GetStringFromResources( "About"); 
			MenuItem aboutMenuItem = new MenuItem( menuLabel, new EventHandler( this.AboutClick)); 
			menuLabel = GetStringFromResources( "Options"); 
			MenuItem optionsMenuItem = new MenuItem( menuLabel, new EventHandler( this.OptionsClick)); 
			menuLabel = GetStringFromResources( "Exit"); 
			MenuItem exitMenuItem = new MenuItem( menuLabel, new EventHandler( this.ExitClick)); 
			_stopServiceMenuItem = new MenuItem( STOP, new EventHandler( this.StopClick)); 
			_stopServiceMenuItem.Enabled = false; 
			_pauseServiceMenuItem = new MenuItem( PAUSE, new EventHandler( this.PauseClick)); 
			_pauseServiceMenuItem.Enabled = false; 
			_startServiceMenuItem = new MenuItem( START, new EventHandler( this.StartClick)); 
			_startServiceMenuItem.Enabled = false; 
			_availableServicesMenu = new MenuItem(); 
			DisableAvailableServicesMenu(); 
			menuLabel = GetStringFromResources( "OpenDialog"); 
			MenuItem osmMenuItem = new MenuItem( menuLabel, new EventHandler( this.OpenServiceManagerClick)); 
			osmMenuItem.DefaultItem = true; 
 
			_trayIcon.ContextMenu.MenuItems.Add( 0, aboutMenuItem); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, optionsMenuItem); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, exitMenuItem); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, new MenuItem( "-")); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, _stopServiceMenuItem); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, _pauseServiceMenuItem); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, _startServiceMenuItem); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, new MenuItem( "-")); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, _availableServicesMenu); 
			_trayIcon.ContextMenu.MenuItems.Add( 0, osmMenuItem); 
		} 
		#endregion 
		 
		#region Implementation of Listener/Observer 
		protected void OnServerChanged( object sender, System.EventArgs e) 
		{ 
			ServiceSubject subject = (ServiceSubject) sender; 
			Update( serverChanged, subject); 
		} 
 
		protected void OnServiceChanged( object sender, System.EventArgs e) 
		{ 
			ServiceSubject subject = (ServiceSubject) sender; 
			Update( serviceChanged, subject); 
		} 
 
		protected void OnStateChanged( object sender, System.EventArgs e) 
		{ 
			ServiceSubject subject = (ServiceSubject) sender; 
			Update( serviceStateChanged, subject); 
		} 
 
		private void Update( UpdateFunction function, ServiceSubject subject) 
		{ 
			if (!Updating) 
			{ 
				Updating = true; 
 
				function( subject); 
 
				Updating = false; 
			} 
		} 
 
		private void ServerChanged( ServiceSubject subject) 
		{ 
			ClearCurrentServiceItem(); 
			SetDefaultActionMenuState(); 
			RemoveAvailableServicesItems(); 
 
			if (subject.ServerName != null) 
			{ 
				string connected = GetStringFromResources( "Connected"); 
				RemoveAvailableServicesMenu(); 
				_availableServicesMenu = CreateAvailableServicesMenu( subject.ServerName); 
				SetAvailableServicesMenu( subject.ServerName); 
				SetTrayIconText( connected, subject.ServerName); 
				SetDefaultTrayIconImage(); 
			} 
			else 
			{ 
				DisableAvailableServicesMenu(); 
				SetDefaultTrayIconText(); 
				SetDefaultTrayIconImage(); 
			} 
		} 
 
		private void ServiceChanged( ServiceSubject subject) 
		{ 
			ClearCurrentServiceItem(); 
 
			if (subject.Controller != null) 
			{ 
				string serviceName = subject.Controller.DisplayName; 
				SetCurrentServiceItem( serviceName); 
				SetActionMenuState( subject, serviceName); 
				SetTrayIconText( subject.State.Status, subject.ServerName, serviceName); 
				SetTrayIconImage( subject.State); 
			} 
			else 
			{ 
				SetDefaultActionMenuState(); 
				SetDefaultTrayIconImage(); 
			} 
		} 
 
		private void ServiceStateChanged( ServiceSubject subject) 
		{ 
			string serverName = subject.ServerName; 
			string serviceName; 
			 
			if (subject.State != ServiceStateUnknown.Instance) 
			{ 
				serviceName = subject.Controller.DisplayName; 
				SetActionMenuState( subject, serviceName); 
				SetTrayIconText( subject.State.Status, serverName, serviceName); 
				SetTrayIconImage( subject.State); 
			} 
			else 
			{ 
				SetDefaultActionMenuState(); 
				SetDefaultTrayIconImage(); 
			} 
		} 
		#endregion 
 
		#region NotifyIcon support functions 
		private void RemoveAvailableServicesMenu() 
		{ 
			_trayIcon.ContextMenu.MenuItems.RemoveAt( INDEX_SERVICESMENU); 
		} 
 
		private MenuItem CreateAvailableServicesMenu( string serverName) 
		{ 
			string format = GetStringFromResources( "CurrentService"); 
			MenuItem item = new MenuItem( String.Format( format, serverName)); 
			_trayIcon.ContextMenu.MenuItems.Add( INDEX_SERVICESMENU, item); 
			return item; 
		} 
 
		private void DisableAvailableServicesMenu() 
		{ 
			_availableServicesMenu.Text = GetStringFromResources( "NoServer"); 
			_availableServicesMenu.Enabled = false; 
		} 
 
		private void RemoveAvailableServicesItems() 
		{ 
			_availableServicesMenu.MenuItems.Clear(); 
		} 
 
		private void SetAvailableServicesMenu( string serverName) 
		{ 
			AddOracleServicesToMenu( serverName); 
			if (_availableServicesMenu.MenuItems.Count == 0) 
			{ 
				string noServices = GetStringFromResources( "NoServices"); 
				MenuItem item = _availableServicesMenu.MenuItems.Add( noServices); 
				item.Enabled = false; 
			} 
		} 
 
		private void AddOracleServicesToMenu( string serverName) 
		{ 
			ServiceController[] services = ServiceController.GetServices( serverName); 
 
			if (services.Length > 0) 
			{ 
				foreach (ServiceController service in services) 
				{ 
					// HACK: Modify to monitor different databases 
					if (service.ServiceName.StartsWith( "Oracle")) 
						_availableServicesMenu.MenuItems.Add( service.ServiceName, onMenuItemClick); 
				} 
			} 
		} 
 
		private void ClearCurrentServiceItem() 
		{ 
			if (_currentServiceMenuItem != null) 
			{ 
				_currentServiceMenuItem.Checked = false; 
				_currentServiceMenuItem = null; 
			} 
		} 
 
		private void SetCurrentServiceItem( string serviceName) 
		{ 
			foreach (MenuItem item in _availableServicesMenu.MenuItems) 
			{ 
				if (item.Text.Equals( serviceName)) 
				{ 
					item.Checked = true; 
					_currentServiceMenuItem = item; 
					break; 
				} 
			} 
		} 
 
		private void SetDefaultTrayIconText() 
		{ 
			_trayIcon.Text = _resources.ApplicationName; 
		} 
 
		private void SetTrayIconText( string status) 
		{ 
			_trayIcon.Text = status; 
		} 
 
		private void SetTrayIconText( string status, string serverName) 
		{ 
			_trayIcon.Text = String.Format( @"{0} - \\{1}", status, serverName); 
		} 
 
		private void SetTrayIconText( string status, string serverName, string serviceName) 
		{ 
			_trayIcon.Text = String.Format( @"{0} - \\{1} - {2}", status, serverName, serviceName); 
		} 
 
		private void SetDefaultTrayIconImage() 
		{ 
			SetTrayIconImage( ServiceStateUnknown.Instance); 
		} 
 
		private void SetTrayIconImage( ServiceState state) 
		{ 
			_trayIcon.Icon = _resources.GetSmallStateImage( state); 
		} 
 
		private void SetDefaultActionMenuState() 
		{ 
			SetActionItemInfo( START, _startServiceMenuItem, null, false); 
			SetActionItemInfo( PAUSE, _pauseServiceMenuItem, null, false); 
			SetActionItemInfo( STOP, _stopServiceMenuItem, null, false); 
		} 
 
		private void SetActionMenuState( ServiceSubject subject, string serviceName) 
		{ 
			Debug.Assert( subject != null, "[SetActionMenuState] Subject cannot be null"); 
 
			string startOrContinue = (subject.State == ServiceStopped.Instance) ? START : CONTINUE; 
			SetActionItemInfo( startOrContinue, _startServiceMenuItem, serviceName, subject.CanStart); 
			SetActionItemInfo( PAUSE, _pauseServiceMenuItem, serviceName, subject.CanPause); 
			SetActionItemInfo( STOP, _stopServiceMenuItem, serviceName, subject.CanStop); 
		} 
 
		private void SetActionItemInfo( string actionName, MenuItem menuItem, string serviceName, bool isEnabled) 
		{ 
			menuItem.Enabled = isEnabled; 
 
			if (serviceName != null) 
				menuItem.Text = String.Format( @"{0} - {1}", actionName, serviceName); 
			else 
				menuItem.Text = actionName; 
		} 
 
		private bool VerifyUserAction( string action) 
		{ 
			string serviceName = OracleServiceManager.Instance.Subject.Controller.DisplayName; 
			string serverName = OracleServiceManager.Instance.Subject.ServerName; 
 
			return OracleServiceManager.Instance.VerifyUserAction( action, serviceName, serverName); 
		} 
 
		private string GetStringFromResources( string name) 
		{ 
			return _resources.GetString( typeof(SystemTrayObserver), name); 
		} 
 
		private string GetAppString( string name) 
		{ 
			return _resources.GetAppString( name); 
		} 
		#endregion 
 
		#region User action implementation 
		private void NotifyIconDoubleClick( object sender, EventArgs e) 
		{ 
			OpenServiceManagerClick( sender, e); 
		} 
 
		private void OptionsClick( object sender, EventArgs e) 
		{ 
			OracleServiceManager.Instance.ConfigureOptions(); 
		} 
 
		private void AboutClick( object sender, EventArgs e) 
		{ 
			OracleServiceManager.Instance.ShowAboutDialog(); 
		} 
 
		private void ExitClick( object sender, EventArgs e) 
		{ 
			_trayIcon.Visible = false; 
			OracleServiceManager.Instance.ExitThread(); 
		} 
 
		private void StartClick( object sender, EventArgs e) 
		{ 
			if (VerifyUserAction( START)) 
				OracleServiceManager.Instance.Subject.Start(); 
		} 
 
		private void PauseClick( object sender, EventArgs e) 
		{ 
			if (VerifyUserAction( PAUSE)) 
				OracleServiceManager.Instance.Subject.Pause(); 
		} 
 
		private void StopClick( object sender, EventArgs e) 
		{ 
			if (VerifyUserAction( PAUSE)) 
				OracleServiceManager.Instance.Subject.Stop(); 
		} 
 
		private void ServiceItemClick( object sender, EventArgs e) 
		{ 
			MenuItem menuItem = (MenuItem) sender; 
			ServiceSubject subject = OracleServiceManager.Instance.Subject; 
 
			subject.Controller = new ServiceController( menuItem.Text, subject.ServerName); 
		} 
 
		private void OpenServiceManagerClick( object sender, EventArgs e) 
		{ 
			OracleServiceManager.Instance.OpenServiceManagerDialog(); 
		} 
		#endregion 
	} 
}