// VsPkg.cs : Implementation of FastForwardVisualStudio
//
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using Microsoft.Win32;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio;
using FastForward.WinCore.Configuration;
using System.Collections.Generic;
using FastForward.WinCore;
namespace FastForward.VisualStudio
{
///
/// This is the class that implements the package exposed by this assembly.
///
[PackageRegistration(UseManagedResourcesOnly = true)]
[DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")]
[InstalledProductRegistration(true, null, null, null)]
[ProvideLoadKey("Standard", "0.2", "FastForward.NET", "Craig Sutherland", 1)]
[ProvideMenuResource(1000, 1)]
[ProvideToolWindow(typeof(ProjectsToolWindow))]
[Guid(GuidList.guidFastForwardVisualStudioPkgString)]
public sealed class VisualStudioPackage
: Package, IVsInstalledProduct
{
#region Private fields
private VisualStudioConfig configuration;
private ServerList servers = new ServerList();
#endregion
#region Constructors
///
/// Default constructor of the package.
/// Inside this method you can place any initialization code that does not require
/// any Visual Studio service because at this point the package object is created but
/// not sited yet inside Visual Studio environment. The place to do all the other
/// initialization is the Initialize method.
///
public VisualStudioPackage()
{
System.Diagnostics.Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
configuration = VisualStudioConfig.Load();
}
#endregion
#region Public properties
#region Configuration
///
/// Gets the configuration for the plug-in.
///
public VisualStudioConfig Configuration
{
get { return this.configuration; }
}
#endregion
#endregion
#region Public methods
#region IdBmpSplash()
///
/// Gets the id for the splash screen bitmap.
///
///
///
public int IdBmpSplash(out uint pIdBmp)
{
pIdBmp = 500;
return VSConstants.S_OK;
}
#endregion
#region IdIcoLogoForAboutbox()
///
/// Gets the identifier of the icon for the about box.
///
///
///
public int IdIcoLogoForAboutbox(out uint pIdIco)
{
pIdIco = 600;
return VSConstants.S_OK;
}
#endregion
#region OfficialName()
///
/// Gets the official name of the plug-in.
///
///
///
public int OfficialName(out string pbstrName)
{
pbstrName = "FastForward.NET";
return VSConstants.S_OK;
}
#endregion
#region ProductDetails()
///
/// Gets the product details.
///
///
///
public int ProductDetails(out string pbstrProductDetails)
{
pbstrProductDetails = "Provides integration with CruiseControl.NET from within Visual Studio.";
return VSConstants.S_OK;
}
#endregion
#region ProductID()
///
/// Gets the identifier of the product.
///
///
///
public int ProductID(out string pbstrPID)
{
pbstrPID = "FastForward.VisualStudio";
return VSConstants.S_OK;
}
#endregion
#endregion
#region Protected methods
#region Initialize()
///
/// Initialization of the package; this method is called right after the package is sited, so this is the place
/// where you can put all the initilaization code that rely on services provided by VisualStudio.
///
protected override void Initialize()
{
System.Diagnostics.Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
base.Initialize();
// Add our command handlers for menu (commands must exist in the .vsct file)
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (null != mcs)
{
// Create the command for the menu item.
CommandID menuCommandID = new CommandID(GuidList.guidFastForwardVisualStudioCmdSet, (int)PkgCmdIDList.cmdidFfnetSettings);
MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
mcs.AddCommand(menuItem);
// Create the command for the tool window
CommandID toolwndCommandID = new CommandID(GuidList.guidFastForwardVisualStudioCmdSet, (int)PkgCmdIDList.cmdidProjectsToolWindow);
MenuCommand menuToolWin = new MenuCommand(ShowToolWindow, toolwndCommandID);
mcs.AddCommand(menuToolWin);
}
// Initialise the server list
foreach (var server in this.configuration.Servers)
{
this.servers.AddServer(server);
}
// Attach the server list
ToolWindowPane window = this.FindToolWindow(typeof(ProjectsToolWindow), 0, true);
if ((null == window) || (null == window.Frame))
{
throw new NotSupportedException(ToolWindowResources.CanNotCreateWindow);
}
var control = window.Window as ProjectsControl;
control.AttachServerList(this.servers);
}
#endregion
#endregion
#region Private methods
#region ShowToolWindow()
///
/// This function is called when the user clicks the menu item that shows the
/// tool window. See the Initialize method to see how the menu item is associated to
/// this function using the OleMenuCommandService service and the MenuCommand class.
///
private void ShowToolWindow(object sender, EventArgs e)
{
// Get the instance number 0 of this tool window. This window is single instance so this instance
// is actually the only one.
// The last flag is set to true so that if the tool window does not exists it will be created.
ToolWindowPane window = this.FindToolWindow(typeof(ProjectsToolWindow), 0, true);
if ((null == window) || (null == window.Frame))
{
throw new NotSupportedException(ToolWindowResources.CanNotCreateWindow);
}
IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
}
#endregion
#region MenuItemCallback()
///
/// This function is the callback used to execute a command when the a menu item is clicked.
/// See the Initialize method to see how the menu item is associated to this function using
/// the OleMenuCommandService service and the MenuCommand class.
///
private void MenuItemCallback(object sender, EventArgs args)
{
var form = new SettingsForm(this);
form.OkClicked += (o, e) =>
{
UpdateServers(form.Configuration.Servers);
this.configuration.Save();
};
form.ShowDialog();
}
#endregion
#region UpdateServers()
///
/// Update all the servers.
///
private void UpdateServers(IEnumerable servers)
{
var oldServers = (from record in this.configuration.Servers
select record).ToList();
foreach (var server in servers)
{
// Check if the server already exists
var oldServer = (from record in oldServers
where (record.Address == server.Address) && (record.TargetServer == server.TargetServer)
select record).SingleOrDefault();
if (oldServer == null)
{
// Add the server
this.servers.AddServer(server);
this.configuration.Servers.Add(server);
}
else
{
// Update the server
this.servers.UpdateServer(server);
server.Server = oldServer.Server;
server.Server.DisplayName = server.Name;
server.Server.Data.Set(server);
// Don't remove the server
oldServers.Remove(oldServer);
}
}
// Remove any removed servers
foreach (var oldServer in oldServers)
{
this.servers.RemoveServer(oldServer);
this.configuration.Servers.Remove(oldServer);
}
}
#endregion
#endregion
}
}