2016-01-06 03:31:37 +00:00
namespace VitaliiGanzha.VsDingExtension
2014-03-13 22:21:47 +00:00
{
2015-06-05 21:48:04 +00:00
using System ;
using System.Diagnostics ;
2015-06-12 21:09:04 +00:00
using System.Drawing ;
2015-06-05 21:48:04 +00:00
using System.Globalization ;
using System.Runtime.InteropServices ;
2015-06-12 21:09:04 +00:00
using System.Windows.Forms ;
2015-06-05 21:48:04 +00:00
using EnvDTE ;
using EnvDTE80 ;
using Microsoft.VisualStudio.ComponentModelHost ;
using Microsoft.VisualStudio.Shell ;
2015-12-16 15:04:33 +00:00
using Microsoft.VisualStudio.TestWindow.Controller ;
2016-01-06 03:31:37 +00:00
using Microsoft.VisualStudio.TestWindow.Extensibility ;
using Task = System . Threading . Tasks . Task ;
2015-06-05 21:48:04 +00:00
2014-03-13 22:21:47 +00:00
[PackageRegistration(UseManagedResourcesOnly = true)]
2015-06-05 22:02:21 +00:00
[InstalledProductRegistration("#110", "#112", "1.1", IconResourceID = 400)]
2014-03-13 22:21:47 +00:00
[Guid(GuidList.guidVsDingExtensionProjectPkgString)]
2014-03-20 23:28:02 +00:00
[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
2015-12-31 07:36:25 +00:00
[ProvideOptionPage(typeof(OptionsDialog), "Ding", "General settings", 0, 0, true)]
2016-01-06 07:13:14 +00:00
[ProvideOptionPage(typeof(SoundsSelectOptionsPage), "Ding", "Overrride sounds", 0, 0, true)]
2015-06-08 19:05:20 +00:00
public sealed class VsDingExtensionProjectPackage : Package , IDisposable
2014-03-13 22:21:47 +00:00
{
private DTE2 applicationObject ;
2014-03-22 00:03:52 +00:00
private BuildEvents buildEvents ;
private DebuggerEvents debugEvents ;
2015-06-05 21:48:04 +00:00
private OptionsDialog _options = null ;
2016-01-06 03:31:37 +00:00
private SoundsSelectOptionsPage soundOverridesSettings = null ;
private Players players = null ;
2015-06-01 01:02:52 +00:00
2014-03-13 22:21:47 +00:00
public VsDingExtensionProjectPackage ( )
{
2015-06-01 01:02:52 +00:00
Debug . WriteLine ( string . Format ( CultureInfo . CurrentCulture , "Entering constructor for: {0}" , ToString ( ) ) ) ;
2014-03-13 22:21:47 +00:00
}
#region Package Members
protected override void Initialize ( )
{
2015-06-01 01:02:52 +00:00
Debug . WriteLine ( string . Format ( CultureInfo . CurrentCulture , "Entering Initialize() of: {0}" , ToString ( ) ) ) ;
2014-03-13 22:21:47 +00:00
base . Initialize ( ) ;
2014-03-25 05:40:05 +00:00
applicationObject = ( DTE2 ) GetService ( typeof ( DTE ) ) ;
2015-06-01 01:02:52 +00:00
buildEvents = applicationObject . Events . BuildEvents ;
debugEvents = applicationObject . Events . DebuggerEvents ;
2014-03-13 22:21:47 +00:00
2016-01-06 03:31:37 +00:00
players = new Players ( this . SoundSettingsOverrides ) ;
this . soundOverridesSettings . OnApplyHandler + = ( ) = > this . players . SoundSettingsChanged ( ) ;
2015-12-29 03:52:44 +00:00
SetupEventHandlers ( ) ;
}
private void SetupEventHandlers ( )
{
2015-06-01 01:02:52 +00:00
buildEvents . OnBuildDone + = ( scope , action ) = >
{
2015-06-12 21:09:04 +00:00
if ( Options . IsBeepOnBuildComplete )
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( EventType . BuildCompleted , "Build has been completed." ) ;
2015-06-12 21:09:04 +00:00
}
2015-06-01 01:02:52 +00:00
} ;
2015-06-12 21:09:04 +00:00
2015-12-29 03:52:44 +00:00
debugEvents . OnEnterBreakMode + = delegate ( dbgEventReason reason , ref dbgExecutionAction action )
2014-03-25 05:40:05 +00:00
{
2015-06-12 21:09:04 +00:00
if ( reason ! = dbgEventReason . dbgEventReasonStep & & Options . IsBeepOnBreakpointHit )
2014-03-25 05:40:05 +00:00
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( EventType . BreakpointHit , "Breakpoint was hit." ) ;
2014-03-25 05:40:05 +00:00
}
} ;
2014-03-13 22:21:47 +00:00
2014-03-20 23:28:02 +00:00
var componentModel =
2015-06-01 01:02:52 +00:00
GetGlobalService ( typeof ( SComponentModel ) ) as IComponentModel ;
2014-03-13 22:21:47 +00:00
2014-03-20 23:28:02 +00:00
if ( componentModel = = null )
{
2014-03-22 00:03:52 +00:00
Debug . WriteLine ( "componentModel is null" ) ;
return ;
2014-03-20 23:28:02 +00:00
}
var operationState = componentModel . GetService < IOperationState > ( ) ;
operationState . StateChanged + = OperationStateOnStateChanged ;
2014-03-13 22:21:47 +00:00
}
2014-03-20 23:28:02 +00:00
2015-06-05 21:48:04 +00:00
private OptionsDialog Options
{
get
{
if ( _options = = null )
{
_options = ( OptionsDialog ) GetDialogPage ( typeof ( OptionsDialog ) ) ;
}
return _options ;
}
}
2016-01-06 03:31:37 +00:00
private SoundsSelectOptionsPage SoundSettingsOverrides
2015-12-16 16:18:16 +00:00
{
2016-01-06 03:31:37 +00:00
get
{
if ( this . soundOverridesSettings = = null )
{
this . soundOverridesSettings = ( SoundsSelectOptionsPage ) GetDialogPage ( typeof ( SoundsSelectOptionsPage ) ) ;
}
return this . soundOverridesSettings ;
}
2015-12-16 16:18:16 +00:00
}
2016-01-06 03:31:37 +00:00
private void HandleEventSafe ( EventType eventType , string messageText , ToolTipIcon icon = ToolTipIcon . Info )
2015-06-12 21:09:04 +00:00
{
2015-06-12 21:33:43 +00:00
if ( ! ShouldPerformNotificationAction ( ) )
{
return ;
}
2015-12-29 03:52:44 +00:00
players . PlaySoundSafe ( eventType ) ;
2015-12-16 16:18:16 +00:00
ShowNotifyMessage ( messageText , icon ) ;
2015-06-12 21:09:04 +00:00
}
2016-01-06 03:31:37 +00:00
private void ShowNotifyMessage ( string messageText , ToolTipIcon icon = ToolTipIcon . Info )
2015-06-12 21:09:04 +00:00
{
if ( ! _options . ShowTrayNotifications )
{
return ;
}
2015-12-16 16:18:16 +00:00
if ( Options . ShowTrayDisableMessage )
{
2016-01-06 03:31:37 +00:00
string autoAppendMessage = Environment . NewLine + "You can disable this notification in:" + Environment . NewLine + "Tools->Options->Ding->Show tray notifications" ;
2015-12-16 16:18:16 +00:00
messageText = string . Format ( "{0}{1}" , messageText , autoAppendMessage ) ;
}
2015-06-12 21:09:04 +00:00
2016-01-06 03:31:37 +00:00
Task . Run ( async ( ) = >
2015-06-12 21:09:04 +00:00
{
var tray = new NotifyIcon
{
Icon = SystemIcons . Application ,
2015-12-16 16:18:16 +00:00
BalloonTipIcon = icon ,
2015-06-12 21:09:04 +00:00
BalloonTipText = messageText ,
BalloonTipTitle = "Visual Studio Ding extension" ,
Visible = true
} ;
tray . ShowBalloonTip ( 5000 ) ;
2016-01-06 03:31:37 +00:00
await Task . Delay ( 5000 ) ;
2015-06-12 21:09:04 +00:00
tray . Icon = ( Icon ) null ;
tray . Visible = false ;
tray . Dispose ( ) ;
} ) ;
}
2015-06-12 21:33:43 +00:00
private bool ShouldPerformNotificationAction ( )
2014-03-20 23:28:02 +00:00
{
2015-06-12 21:09:04 +00:00
if ( ! Options . IsBeepOnlyWhenVisualStudioIsInBackground )
2014-03-20 23:28:02 +00:00
{
2015-06-05 21:48:04 +00:00
return true ;
2014-03-20 23:28:02 +00:00
}
2015-12-29 03:52:44 +00:00
return Options . IsBeepOnlyWhenVisualStudioIsInBackground & & ! WinApiHelper . ApplicationIsActivated ( ) ;
2014-03-20 23:28:02 +00:00
}
2014-03-13 22:21:47 +00:00
2015-06-05 21:48:04 +00:00
private void OperationStateOnStateChanged ( object sender , OperationStateChangedEventArgs operationStateChangedEventArgs )
2015-06-01 01:02:52 +00:00
{
2015-12-16 15:04:33 +00:00
if ( Options . IsBeepOnTestComplete & & operationStateChangedEventArgs . State . HasFlag ( TestOperationStates . TestExecutionFinished ) )
2015-06-05 21:48:04 +00:00
{
2015-12-29 03:52:44 +00:00
var testOperation = ( ( TestRunRequest ) operationStateChangedEventArgs . Operation ) ;
var isTestsFailed = testOperation . DominantTestState = = TestState . Failed ;
var eventType = isTestsFailed ? EventType . TestsCompletedFailure : EventType . TestsCompletedSuccess ;
if ( Options . IsBeepOnTestFailed & & isTestsFailed )
2015-12-16 15:04:33 +00:00
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( eventType , "Test execution failed!" , ToolTipIcon . Error ) ;
2015-12-16 15:04:33 +00:00
}
else
{
2015-12-29 03:52:44 +00:00
HandleEventSafe ( eventType , "Test execution has been completed." ) ;
2015-12-16 15:04:33 +00:00
}
2015-06-05 21:48:04 +00:00
}
2015-06-01 01:02:52 +00:00
}
2015-06-05 21:48:04 +00:00
#endregion
2015-06-04 18:42:54 +00:00
2015-06-08 19:05:20 +00:00
public void Dispose ( )
{
2015-12-29 03:52:44 +00:00
players . Dispose ( ) ;
2015-06-08 19:05:20 +00:00
}
2014-03-13 22:21:47 +00:00
}
}