diff --git a/Source/TeamBuildMonitorGadget.sln b/Source/TeamBuildMonitorGadget.sln
new file mode 100644
index 0000000..c3ddaaf
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget.sln
@@ -0,0 +1,24 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TeamBuildMonitorGadget", "TeamBuildMonitorGadget\TeamBuildMonitorGadget.csproj", "{BA7022CF-10AD-4F4A-9C01-86E739B92318}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BA7022CF-10AD-4F4A-9C01-86E739B92318}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BA7022CF-10AD-4F4A-9C01-86E739B92318}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BA7022CF-10AD-4F4A-9C01-86E739B92318}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BA7022CF-10AD-4F4A-9C01-86E739B92318}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source/TeamBuildMonitorGadget/App.xaml b/Source/TeamBuildMonitorGadget/App.xaml
new file mode 100644
index 0000000..5a6a59e
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/App.xaml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/TeamBuildMonitorGadget/App.xaml.cs b/Source/TeamBuildMonitorGadget/App.xaml.cs
new file mode 100644
index 0000000..9a92511
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/App.xaml.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Windows;
+using System.Windows.Navigation;
+using System.Data;
+using System.Xml;
+using System.Configuration;
+
+namespace TeamBuildMonitorGadget {
+ ///
+ /// Interaction logic for App.xaml
+ ///
+
+ public partial class App : System.Windows.Application {
+
+ }
+}
\ No newline at end of file
diff --git a/Source/TeamBuildMonitorGadget/BuildStoreDriver.cs b/Source/TeamBuildMonitorGadget/BuildStoreDriver.cs
new file mode 100644
index 0000000..033e0d4
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/BuildStoreDriver.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows;
+using Microsoft.TeamFoundation.Build.Proxy;
+using System.ComponentModel;
+using System.Windows.Documents;
+using System.Collections.ObjectModel;
+using Microsoft.TeamFoundation.Client;
+using System.Net;
+using Microsoft.TeamFoundation.Build.Common;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ public class BuildStoreDriver : DependencyObject {
+ private BuildStoreWorker _backgroundWorker;
+
+ public BuildStoreDriver() {
+
+ }
+
+ public static readonly DependencyProperty TeamFoundationServerUriProperty = DependencyProperty.Register("TeamFoundationServerUri", typeof(string), typeof(BuildStoreDriver), new UIPropertyMetadata(null, RecreateBackgroundWorker));
+ public static readonly DependencyProperty TeamProjectNameProperty = DependencyProperty.Register("TeamProjectName", typeof(string), typeof(BuildStoreDriver), new UIPropertyMetadata(null, RecreateBackgroundWorker));
+ public static readonly DependencyProperty TeamBuildTypeNameProperty = DependencyProperty.Register("TeamBuildTypeName", typeof(string), typeof(BuildStoreDriver), new UIPropertyMetadata(null, RecreateBackgroundWorker));
+ public static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.Register("IsUpdating", typeof(bool), typeof(BuildStoreDriver), new UIPropertyMetadata(false));
+ public static readonly DependencyProperty LastExceptionProperty = DependencyProperty.Register("LastException", typeof(Exception), typeof(BuildStoreDriver), new UIPropertyMetadata(null));
+ private static readonly DependencyPropertyKey PreviousBuildsPropertyKey = DependencyProperty.RegisterReadOnly("PreviousBuilds", typeof(ObservableCollection), typeof(BuildStoreDriver), new UIPropertyMetadata(null));
+ public static readonly DependencyProperty PreviousBuildsProperty = PreviousBuildsPropertyKey.DependencyProperty;
+
+ public ObservableCollection PreviousBuilds {
+ get { return (ObservableCollection)GetValue(PreviousBuildsProperty); }
+ private set { SetValue(PreviousBuildsPropertyKey, value); }
+ }
+
+ public string TeamFoundationServerUri {
+ get { return (string)GetValue(TeamFoundationServerUriProperty); }
+ set { SetValue(TeamFoundationServerUriProperty, value); }
+ }
+
+ public string TeamProjectName {
+ get { return (string)GetValue(TeamProjectNameProperty); }
+ set { SetValue(TeamProjectNameProperty, value); }
+ }
+
+ public string TeamBuildTypeName {
+ get { return (string)GetValue(TeamBuildTypeNameProperty); }
+ set { SetValue(TeamBuildTypeNameProperty, value); }
+ }
+
+ public Exception LastException {
+ get { return (Exception)GetValue(LastExceptionProperty); }
+ set { SetValue(LastExceptionProperty, value); }
+ }
+
+ private static void RecreateBackgroundWorker(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) {
+ BuildStoreDriver driver = dependencyObject as BuildStoreDriver;
+ if (driver != null) {
+ driver.PreviousBuilds = new ObservableCollection();
+ if (driver._backgroundWorker != null) {
+ driver._backgroundWorker.CancelAsync();
+ }
+ driver._backgroundWorker = new BuildStoreWorker(driver.TeamFoundationServerUri, driver.TeamProjectName, driver.TeamBuildTypeName, driver.PreviousBuilds);
+ driver._backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
+ delegate(object sender, RunWorkerCompletedEventArgs workedCompletedEventArgs) {
+ if (workedCompletedEventArgs.Error != null) {
+ driver.LastException = workedCompletedEventArgs.Error;
+ }
+ });
+ }
+ }
+
+ public void Monitor() {
+ VerifyAccess();
+
+ if (!_backgroundWorker.IsBusy) {
+ this.LastException = null;
+ _backgroundWorker.RunWorkerAsync();
+ }
+ }
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/BuildStoreWorker.cs b/Source/TeamBuildMonitorGadget/BuildStoreWorker.cs
new file mode 100644
index 0000000..b5750c8
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/BuildStoreWorker.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+using Microsoft.TeamFoundation.Client;
+using Microsoft.TeamFoundation.Build.Proxy;
+using System.Collections.ObjectModel;
+using System.Net;
+using System.Threading;
+using System.Windows;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ public class BuildStoreWorker : BackgroundWorker {
+ private string _teamFoundationServerUri;
+ private string _teamProjectName;
+ private string _teamBuildTypeName;
+ private BuildSummaryFactory _summaryFactory;
+ private ObservableCollection _buildSummaries;
+
+ public BuildStoreWorker(string teamFoundationServerUri, string teamProjectName, string teamBuildTypeName, ObservableCollection buildSummaries) {
+ _teamFoundationServerUri = teamFoundationServerUri;
+ _teamProjectName = teamProjectName;
+ _teamBuildTypeName = teamBuildTypeName;
+ _buildSummaries = buildSummaries;
+ _summaryFactory = new BuildSummaryFactory();
+
+ this.WorkerSupportsCancellation = true;
+ this.WorkerReportsProgress = true;
+ this.DoWork += new DoWorkEventHandler(BuildStoreWorker_DoWork);
+ this.ProgressChanged += new ProgressChangedEventHandler(BuildStoreWorker_ProgressChanged);
+ }
+
+ private void BuildStoreWorker_DoWork(object sender, DoWorkEventArgs e) {
+
+ TeamFoundationServer server = new TeamFoundationServer(_teamFoundationServerUri, CredentialCache.DefaultCredentials);
+ server.EnsureAuthenticated();
+
+ while (!this.CancellationPending) {
+ BuildStore store = (BuildStore)server.GetService(typeof(BuildStore));
+ BuildData[] builds = store.GetListOfBuilds(_teamProjectName, _teamBuildTypeName);
+ this.ReportProgress(0, builds);
+ Thread.Sleep(30000);
+ }
+ }
+
+ private void BuildStoreWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
+ BuildData[] results = (BuildData[])e.UserState;
+
+ List summaries = new List();
+ foreach (BuildData buildData in results) {
+ BuildSummary summary = _summaryFactory.GetBuildSummary(buildData);
+ summaries.Add(summary);
+ }
+ summaries.Sort();
+
+ _buildSummaries.Clear();
+ for (int i = 0; i < summaries.Count && i < 4; i++) {
+ _buildSummaries.Add(summaries[i]);
+ }
+
+ }
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/BuildSummary.cs b/Source/TeamBuildMonitorGadget/BuildSummary.cs
new file mode 100644
index 0000000..a232d0c
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/BuildSummary.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ public class BuildSummary : INotifyPropertyChanged, IComparable {
+ private string _buildNumber;
+ private DateTime _buildDate;
+ private string _buildStatus;
+ private string _buildUri;
+ private string _dropLocation;
+
+ public static readonly PropertyChangedEventArgs BuildNumberPropertyChangedEventArgs = new PropertyChangedEventArgs("BuildNumber");
+ public static readonly PropertyChangedEventArgs BuildDatePropertyChangedEventArgs = new PropertyChangedEventArgs("BuildDate");
+ public static readonly PropertyChangedEventArgs BuildStatusPropertyChangedEventArgs = new PropertyChangedEventArgs("BuildStatus");
+ public static readonly PropertyChangedEventArgs DropLocationPropertyChangedEventArgs = new PropertyChangedEventArgs("DropLocation");
+
+ public string BuildUri {
+ get { return _buildUri; }
+ internal set { _buildUri = value; }
+ }
+
+ public string BuildNumber {
+ get { return _buildNumber; }
+ set {
+ _buildNumber = value;
+ OnPropertyChanged(BuildNumberPropertyChangedEventArgs);
+ }
+ }
+
+ public DateTime BuildDate {
+ get { return _buildDate; }
+ set {
+ _buildDate = value;
+ OnPropertyChanged(BuildDatePropertyChangedEventArgs);
+ }
+ }
+
+ public string BuildStatus {
+ get { return _buildStatus; }
+ set {
+ _buildStatus = value;
+ OnPropertyChanged(BuildStatusPropertyChangedEventArgs);
+ }
+ }
+
+ public string DropLocation {
+ get { return _dropLocation; }
+ set {
+ _dropLocation = value;
+ OnPropertyChanged(DropLocationPropertyChangedEventArgs);
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
+ if (this.PropertyChanged != null) {
+ this.PropertyChanged(this, e);
+ }
+ }
+
+ #region IComparable Members
+
+ public int CompareTo(BuildSummary other) {
+ return other.BuildDate.CompareTo(this.BuildDate);
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/BuildSummaryFactory.cs b/Source/TeamBuildMonitorGadget/BuildSummaryFactory.cs
new file mode 100644
index 0000000..9131ba0
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/BuildSummaryFactory.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.TeamFoundation.Build.Proxy;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ public class BuildSummaryFactory {
+ private List _summaries = new List();
+
+ public BuildSummary GetBuildSummary(BuildData buildData) {
+ BuildSummary result = null;
+
+ foreach (BuildSummary summary in _summaries) {
+ if (summary.BuildUri == buildData.BuildUri) {
+ result = summary;
+ break;
+ }
+ }
+
+ if (result == null) {
+ result = new BuildSummary();
+ _summaries.Add(result);
+ }
+
+ result.BuildDate = buildData.StartTime;
+ result.BuildNumber = buildData.BuildNumber;
+ result.BuildStatus = buildData.BuildStatus;
+ result.BuildUri = buildData.BuildUri;
+ result.DropLocation = buildData.DropLocation;
+
+ return result;
+ }
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/DateConverter.cs b/Source/TeamBuildMonitorGadget/DateConverter.cs
new file mode 100644
index 0000000..6a692c6
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/DateConverter.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Data;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ public class DateConverter : IValueConverter {
+
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
+ string result = string.Empty;
+
+ if (value != null) {
+ DateTime dt = (DateTime)value;
+ if (parameter != null) {
+ if (parameter.ToString() == "today") {
+ if (dt.Date == DateTime.Today) {
+ result = "Today";
+ } else if (dt.Date == DateTime.Today.AddDays(-1)) {
+ result = "Yesterday";
+ } else {
+ result = dt.ToString("dd-MMM");
+ }
+ } else {
+ result = dt.ToString(parameter.ToString());
+ }
+ } else {
+ result = dt.ToString("dd-MMM");
+ }
+ }
+
+ return result;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/Gadget.html b/Source/TeamBuildMonitorGadget/Gadget.html
new file mode 100644
index 0000000..cf46751
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Gadget.html
@@ -0,0 +1,24 @@
+
+
+ Team Build Monitor Gadget
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/TeamBuildMonitorGadget/Gadget.xml b/Source/TeamBuildMonitorGadget/Gadget.xml
new file mode 100644
index 0000000..ce38cd5
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Gadget.xml
@@ -0,0 +1,21 @@
+
+
+ Team Build Monitor
+ PaulStovell.TeamBuildMonitorGadget
+ 1.0.0.0
+
+
+
+ 2007
+ Team Build Monitor
+
+
+
+
+
+
+ full
+
+
+
+
diff --git a/Source/TeamBuildMonitorGadget/GadgetBackground.png b/Source/TeamBuildMonitorGadget/GadgetBackground.png
new file mode 100644
index 0000000..c5e0fc2
Binary files /dev/null and b/Source/TeamBuildMonitorGadget/GadgetBackground.png differ
diff --git a/Source/TeamBuildMonitorGadget/GadgetIcon.gif b/Source/TeamBuildMonitorGadget/GadgetIcon.gif
new file mode 100644
index 0000000..a35c345
Binary files /dev/null and b/Source/TeamBuildMonitorGadget/GadgetIcon.gif differ
diff --git a/Source/TeamBuildMonitorGadget/IsNullVisibilityConverter.cs b/Source/TeamBuildMonitorGadget/IsNullVisibilityConverter.cs
new file mode 100644
index 0000000..35eb078
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/IsNullVisibilityConverter.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Data;
+using System.Windows;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ public class IsNullVisibilityConverter : IValueConverter {
+
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
+ Visibility result = Visibility.Visible;
+
+ if (parameter == null) {
+ result = (value == null) ? Visibility.Visible : Visibility.Collapsed;
+ } else if (parameter.ToString().ToLower().Contains("not")) {
+ result = (value == null) ? Visibility.Collapsed : Visibility.Visible;
+ }
+
+ return result;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/MainPage.xaml b/Source/TeamBuildMonitorGadget/MainPage.xaml
new file mode 100644
index 0000000..cd9535d
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/MainPage.xaml
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Settings
+
+
+
+
+
+
+
+
+
+
+ There was an error communicating with the server.
+ View details
+ |
+ Try again
+
+
+
+
+
diff --git a/Source/TeamBuildMonitorGadget/MainPage.xaml.cs b/Source/TeamBuildMonitorGadget/MainPage.xaml.cs
new file mode 100644
index 0000000..2af120f
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/MainPage.xaml.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Timers;
+using System.Diagnostics;
+using Microsoft.TeamFoundation.VersionControl.Client;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ ///
+ /// Interaction logic for MainPage.xaml
+ ///
+ public partial class MainPage : System.Windows.Controls.Page {
+ ///
+ /// Constructor.
+ ///
+ public MainPage() {
+ InitializeComponent();
+
+ LoadSettings();
+ }
+
+ public static readonly DependencyProperty BuildStoreDriverProperty = DependencyProperty.Register("BuildStoreDriver", typeof(BuildStoreDriver), typeof(MainPage), new UIPropertyMetadata(null));
+ public static readonly DependencyProperty FriendlyNameProperty = DependencyProperty.Register("FriendlyName", typeof(string), typeof(MainPage), new UIPropertyMetadata(null));
+
+ public BuildStoreDriver BuildStoreDriver {
+ get { return (BuildStoreDriver)GetValue(BuildStoreDriverProperty); }
+ set { SetValue(BuildStoreDriverProperty, value); }
+ }
+
+ public string FriendlyName {
+ get { return (string)GetValue(FriendlyNameProperty); }
+ set { SetValue(FriendlyNameProperty, value); }
+ }
+
+ private void BuildItem_Clicked(object sender, RoutedEventArgs e) {
+ FrameworkElement element = sender as FrameworkElement;
+ if (element != null) {
+ BuildSummary summary = element.Tag as BuildSummary;
+ if (summary != null && summary.DropLocation != null && summary.DropLocation.Length > 0) {
+ Process.Start(summary.DropLocation);
+ }
+ }
+ }
+
+ private void ExceptionDetailsLink_Clicked(object sender, RoutedEventArgs e) {
+ if (BuildStoreDriver.LastException != null) {
+ MessageBox.Show(BuildStoreDriver.LastException.ToString());
+ }
+ }
+
+ private void TryAgainLink_Clicked(object sender, RoutedEventArgs e) {
+ this.BuildStoreDriver.Monitor();
+ }
+
+ private void SettingsLink_Clicked(object sender, RoutedEventArgs e) {
+ SettingsWindow window = new SettingsWindow();
+ window.ShowDialog();
+ LoadSettings();
+ }
+
+ private void LoadSettings() {
+ Settings settings = Settings.GetSettings();
+ this.FriendlyName = settings.FriendlyName;
+
+ BuildStoreDriver driver = new BuildStoreDriver();
+ driver.TeamFoundationServerUri = settings.TeamFoundationServerUri;
+ driver.TeamProjectName = settings.TeamProjectName;
+ driver.TeamBuildTypeName = settings.TeamBuildTypeName;
+ driver.Monitor();
+
+ this.BuildStoreDriver = driver;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/TeamBuildMonitorGadget/Properties/AssemblyInfo.cs b/Source/TeamBuildMonitorGadget/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4e4715c
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Properties/AssemblyInfo.cs
@@ -0,0 +1,62 @@
+#region Using directives
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Resources;
+using System.Globalization;
+using System.Windows;
+using System.Runtime.InteropServices;
+
+#endregion
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TeamBuildMonitorGadget")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TeamBuildMonitorGadget")]
+[assembly: AssemblyCopyright("Copyright @ 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+// Specifies the location in which theme dictionaries are stored for types in an assembly.
+[assembly: ThemeInfo(
+ // Specifies the location of system theme-specific resource dictionaries for this project.
+ // The default setting in this project is "None" since this default project does not
+ // include these user-defined theme files:
+ // Themes\Aero.NormalColor.xaml
+ // Themes\Classic.xaml
+ // Themes\Luna.Homestead.xaml
+ // Themes\Luna.Metallic.xaml
+ // Themes\Luna.NormalColor.xaml
+ // Themes\Royale.NormalColor.xaml
+ ResourceDictionaryLocation.None,
+
+ // Specifies the location of the system non-theme specific resource dictionary:
+ // Themes\generic.xaml
+ ResourceDictionaryLocation.SourceAssembly)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.*")]
diff --git a/Source/TeamBuildMonitorGadget/Properties/Resources.Designer.cs b/Source/TeamBuildMonitorGadget/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..d1935bf
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.312
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace PaulStovell.TeamBuildMonitorGadget.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PaulStovell.TeamBuildMonitorGadget.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/Properties/Resources.resx b/Source/TeamBuildMonitorGadget/Properties/Resources.resx
new file mode 100644
index 0000000..e2cc0e0
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Source/TeamBuildMonitorGadget/Properties/Settings.Designer.cs b/Source/TeamBuildMonitorGadget/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..03fe953
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.312
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace PaulStovell.TeamBuildMonitorGadget.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/Properties/Settings.settings b/Source/TeamBuildMonitorGadget/Properties/Settings.settings
new file mode 100644
index 0000000..4024694
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/TeamBuildMonitorGadget/Properties/app.manifest b/Source/TeamBuildMonitorGadget/Properties/app.manifest
new file mode 100644
index 0000000..a40d110
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Properties/app.manifest
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/TeamBuildMonitorGadget/Settings.cs b/Source/TeamBuildMonitorGadget/Settings.cs
new file mode 100644
index 0000000..24471cb
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/Settings.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Deployment.Application;
+using System.Xml.Serialization;
+using System.Collections;
+using System.Web;
+using System.Reflection;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ public class Settings {
+ private string _settingsFileName;
+ private Dictionary _innerSettings;
+
+ private Settings(string fileName) {
+ _settingsFileName = fileName;
+
+ _innerSettings = new Dictionary();
+ if (File.Exists(_settingsFileName)) {
+ string[] lines = File.ReadAllLines(_settingsFileName);
+ foreach (string line in lines) {
+ string[] keyValuePair = line.Split('=');
+ string key = HttpUtility.UrlDecode(keyValuePair[0]);
+ string value = HttpUtility.UrlDecode(keyValuePair[1]);
+ _innerSettings[key] = value;
+ }
+ }
+ }
+
+ public string TeamFoundationServerUri {
+ get { return GetSetting("TeamFoundationServerUri", "http://myserver:8080"); }
+ set { SetSetting("TeamFoundationServerUri", value); }
+ }
+
+ public string TeamProjectName {
+ get { return GetSetting("TeamProjectName", "MyProjectName"); }
+ set { SetSetting("TeamProjectName", value); }
+ }
+
+ public string TeamBuildTypeName {
+ get { return GetSetting("TeamBuildTypeName", "MyBuildName"); }
+ set { SetSetting("TeamBuildTypeName", value); }
+ }
+
+ public string FriendlyName {
+ get { return GetSetting("FriendlyName", "My project\r\nMy favourite build"); }
+ set { SetSetting("FriendlyName", value); }
+ }
+
+ public string SettingsFileName {
+ get { return _settingsFileName; }
+ }
+
+ private string GetSetting(string settingName, string defaultValue) {
+ string result = defaultValue;
+ if (_innerSettings.ContainsKey(settingName)) {
+ result = _innerSettings[settingName];
+ }
+ return result;
+ }
+
+ private void SetSetting(string settingName, string value) {
+ _innerSettings[settingName] = value;
+ }
+
+ public void Save() {
+ List lines = new List();
+ foreach (KeyValuePair kvp in _innerSettings) {
+ lines.Add(HttpUtility.UrlEncode(kvp.Key) + "=" + HttpUtility.UrlEncode(kvp.Value));
+ }
+ File.WriteAllLines(_settingsFileName, lines.ToArray());
+ }
+
+ public static Settings GetSettings() {
+ string startDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.Replace("file:///", ""));
+ string filename = Path.Combine(startDirectory, "PaulStovell.NET\\TeamBuildMonitor");
+ if (!Directory.Exists(filename)) {
+ Directory.CreateDirectory(filename);
+ }
+ filename = Path.Combine(filename, "Settings.xml");
+ return new Settings(filename);
+ }
+ }
+}
diff --git a/Source/TeamBuildMonitorGadget/SettingsWindow.xaml b/Source/TeamBuildMonitorGadget/SettingsWindow.xaml
new file mode 100644
index 0000000..fa6247b
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/SettingsWindow.xaml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/TeamBuildMonitorGadget/SettingsWindow.xaml.cs b/Source/TeamBuildMonitorGadget/SettingsWindow.xaml.cs
new file mode 100644
index 0000000..9e1c3ca
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/SettingsWindow.xaml.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace PaulStovell.TeamBuildMonitorGadget {
+ ///
+ /// Interaction logic for SettingsWindow.xaml
+ ///
+ public partial class SettingsWindow : System.Windows.Window {
+ public SettingsWindow() {
+ InitializeComponent();
+
+ this.Settings = Settings.GetSettings();
+ }
+
+ ///
+ /// DependencyProperty for the Settings property.
+ ///
+ public static readonly DependencyProperty SettingsProperty = DependencyProperty.Register("Settings", typeof(Settings), typeof(SettingsWindow), new UIPropertyMetadata(null));
+
+ ///
+ /// Gets or sets the settings shown on the dialog.
+ ///
+ public Settings Settings {
+ get { return (Settings)GetValue(SettingsProperty); }
+ set { SetValue(SettingsProperty, value); }
+ }
+
+ ///
+ /// Called when the Save button is clicked.
+ ///
+ public void SaveButton_Clicked(object sender, RoutedEventArgs e) {
+ this.Settings.Save();
+ this.Close();
+ }
+
+ ///
+ /// Called when the Cancel button is clicked.
+ ///
+ public void CancelButton_Clicked(object sender, RoutedEventArgs e) {
+ this.Close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/TeamBuildMonitorGadget/TeamBuildMonitorGadget.csproj b/Source/TeamBuildMonitorGadget/TeamBuildMonitorGadget.csproj
new file mode 100644
index 0000000..6b649e6
--- /dev/null
+++ b/Source/TeamBuildMonitorGadget/TeamBuildMonitorGadget.csproj
@@ -0,0 +1,186 @@
+
+
+ Debug
+ AnyCPU
+ {BA7022CF-10AD-4F4A-9C01-86E739B92318}
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ PaulStovell.TeamBuildMonitorGadget
+ TeamBuildMonitorGadget
+ 4
+ winexe
+ false
+ Custom
+ Program
+ $(WINDIR)\System32\PresentationHost.exe
+ -debug "$(MSBuildProjectDirectory)\bin\$(Configuration)\$(AssemblyName)$(ApplicationExtension)"
+ True
+ 3.0
+ true
+ false
+ TeamBuildMonitorGadget_TemporaryKey.pfx
+ F77084D76CC675AC29126AB31829820F50E2E98C
+ true
+
+
+ Publish\
+ false
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ false
+ http://www.paulstovell.net/
+ Team Build Monitor Gadget
+ Paul Stovell
+ false
+ true
+ 1.0.0.%2a
+ .xbap
+ true
+
+
+ true
+ full
+ false
+ .\bin\Debug\
+ DEBUG;TRACE
+
+
+ false
+ true
+ .\bin\Release\
+ TRACE
+
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.Build.Client.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.Build.Common.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.Client.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.Common.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.VersionControl.Client.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.VersionControl.Common.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.VersionControl.Common.Integration.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.VersionControl.Controls.dll
+
+
+ False
+ C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.TeamFoundation.VersionControl.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ App.xaml
+ Code
+
+
+
+
+
+ Component
+
+
+
+
+
+
+ MainPage.xaml
+
+
+
+ ResXFileCodeGenerator
+ Designer
+ Resources.Designer.cs
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ True
+ Settings.settings
+
+
+
+ Code
+ SettingsWindow.xaml
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
+ False
+ .NET Framework 2.0
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/TeamBuildMonitorGadget/TeamBuildMonitorGadget_TemporaryKey.pfx b/Source/TeamBuildMonitorGadget/TeamBuildMonitorGadget_TemporaryKey.pfx
new file mode 100644
index 0000000..e5ba1a0
Binary files /dev/null and b/Source/TeamBuildMonitorGadget/TeamBuildMonitorGadget_TemporaryKey.pfx differ