/* * Copyright (c) 2009 Craig Sutherland * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using FastForward.WinCore.Configuration; using ThoughtWorks.CruiseControl.Remote.Monitor; namespace FastForward.WinCore { /// /// Display the selected projects. /// public partial class ProjectListView : UserControl, IProjectSelector { #region Private fields private int listSort = 0; private Dictionary configurations = new Dictionary(); private Dictionary projects = new Dictionary(); #endregion #region Constructors /// /// Initialise a new . /// public ProjectListView() { InitializeComponent(); } #endregion #region Public properties #region ContextMenuStrip /// /// The context menu to use. /// public override ContextMenuStrip ContextMenuStrip { get { return allProjectsList.ContextMenuStrip; } set { allProjectsList.ContextMenuStrip = value; } } #endregion #region ImageList /// /// The associated image list. /// public ImageList ImageList { get { return allProjectsList.SmallImageList; } set { allProjectsList.SmallImageList = value; allProjectsList.LargeImageList = value; } } #endregion #region ShowGroups /// /// Should the groups be displayed or not. /// public bool ShowGroups { get { return allProjectsList.ShowGroups; } set { allProjectsList.ShowGroups = value; } } #endregion #endregion #region Public methods #region SaveToConfig() /// /// Save the current settings to the configuration. /// /// public void SaveToConfig(List config) { ListViewHelper.SaveListView(allProjectsList, listSort, config); } #endregion #region LoadFromConfig() /// /// Load the settings from the configuration. /// /// public void LoadFromConfig(List config) { listSort = ListViewHelper.LoadListView(allProjectsList, config); } #endregion #region GetSelectedProjects() /// /// Get the selected projects. /// /// public IEnumerable GetSelectedProjects() { var list = new List(); foreach (var item in allProjectsList.SelectedItems) { var projectItem = item as ProjectListViewItem; if (projectItem != null) list.Add(projectItem.Project); } return list; } #endregion #region AddServer() /// /// Add a new server. /// /// /// public void AddServer(Server server, ServerConfig config) { // Store the configuration server.DisplayName = config.Name; configurations.Add(server, config); // Add the groups var serverName = server.GetDisplayName(true); allProjectsList.Groups.Add(server.TargetAddress, serverName); // Add the projects server.ProjectAdded += server_ProjectAdded; server.ProjectRemoved += server_ProjectRemoved; foreach (var project in server.Projects) { AddProject(project, config); } } #endregion #region RemoveServer() /// /// Remove an existing server. /// /// public void RemoveServer(Server server) { // Remove the projects server.ProjectAdded -= server_ProjectAdded; server.ProjectRemoved -= server_ProjectRemoved; foreach (var project in server.Projects) { RemoveProject(project); } configurations.Remove(server); allProjectsList.Groups.Remove(allProjectsList.Groups[server.TargetAddress]); } #endregion #region AddProject() /// /// Add a new project. /// /// /// private void AddProject(Project value, ServerConfig serverConfig) { var addProject = true; if (serverConfig != null) { var projectConfig = serverConfig.FindProject(value.Name); if (projectConfig == null) { addProject = (serverConfig.NewProjectMode == ServerNewProjectMode.AlwaysShow); } else { addProject = !projectConfig.IsHidden; } } if (addProject) { var item = new ProjectListViewItem(value); allProjectsList.Items.Add(item); projects.Add(value, item); item.Group = allProjectsList.Groups[value.Server.TargetAddress]; } } #endregion #region RemoveProject() /// /// Remove an existing project. /// /// private void RemoveProject(Project value) { if (projects.ContainsKey(value)) { projects[value].Remove(); projects.Remove(value); } } #endregion #region Clear() /// /// Clear all the projects and servers. /// public void Clear() { var keys = configurations.Keys.ToArray(); foreach (var server in keys) { RemoveServer(server); } } #endregion #endregion #region Protected methods #region Dispose() /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #endregion #endregion #region Private methods #region DrawDetails() /// /// Draw the details for a project item. /// /// /// private void DrawDetails(DrawListViewSubItemEventArgs e, Project project) { e.DrawBackground(); double width = 100; var font = allProjectsList.Font; var backgroundColour = Color.YellowGreen; if (project.Activity.IsCheckingModifications()) { backgroundColour = Color.LightGoldenrodYellow; } else if (project.Activity.IsPending()) { backgroundColour = Color.Yellow; font = new Font(font, FontStyle.Italic); } else if (project.Activity.IsBuilding()) { font = new Font(font, FontStyle.Bold); width = (e.Item as ProjectListViewItem).ProgressCompleted; using (var newBrush = new SolidBrush(Color.LightGoldenrodYellow)) { e.Graphics.FillRectangle(newBrush, e.Bounds); } } var bounds = new Rectangle(e.Bounds.X, e.Bounds.Y, Convert.ToInt32(e.Bounds.Width * width / 100), e.Bounds.Height); using (var newBrush = new SolidBrush(backgroundColour)) { e.Graphics.FillRectangle(newBrush, bounds); } bounds = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height); using (var newPen = new Pen(SystemColors.ControlDark)) { e.Graphics.DrawRectangle(newPen, bounds); } var format = new StringFormat(StringFormatFlags.NoWrap); format.Alignment = StringAlignment.Near; format.LineAlignment = StringAlignment.Center; format.Trimming = StringTrimming.EllipsisCharacter; using (var newBrush = new SolidBrush(allProjectsList.ForeColor)) { e.Graphics.DrawString(e.SubItem.Text, font, newBrush, e.Bounds, format); } } #endregion #endregion #region Event handlers #region allProjectsList_ColumnClick() /// /// The user has clicked on a column header. /// /// /// private void allProjectsList_ColumnClick(object sender, ColumnClickEventArgs e) { listSort = ListViewHelper.SortListView(allProjectsList, e.Column, listSort); } #endregion #region server_ProjectAdded() /// /// A new project has been added on a server. /// /// /// private void server_ProjectAdded(object sender, ProjectChangedArgs e) { this.SafeInvoke(() => { var serverConfig = configurations[e.Project.Server]; AddProject(e.Project, serverConfig); }); } #endregion #region server_ProjectRemoved() /// /// An existing project has been removed from a server. /// /// /// private void server_ProjectRemoved(object sender, ProjectChangedArgs e) { this.SafeInvoke(() => { RemoveProject(e.Project); }); } #endregion #region allProjectsList_DrawSubItem() /// /// An item. /// /// /// private void allProjectsList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) { if (e.ColumnIndex == 4) { var project = (e.Item as ProjectListViewItem).Project; if ((e.Item.Selected && !project.Activity.IsBuilding()) || project.Activity.IsSleeping()) { e.DrawDefault = true; } else { DrawDetails(e, project); } } else { e.DrawDefault = true; } } #endregion #region allProjectsList_DrawColumnHeader() /// /// Draw the column header. /// /// /// private void allProjectsList_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e) { e.DrawDefault = true; } #endregion #region allProjectsList_DoubleClick() /// /// The user has double-clicked on the grid. /// /// The list view that was double-clicked on. /// The arguments for the handler. private void allProjectsList_DoubleClick(object sender, EventArgs e) { if (DoubleClick != null) { DoubleClick(this, EventArgs.Empty); } } #endregion #endregion #region Public events #region DoubleClick /// /// The list has been double-clicked. /// public event EventHandler DoubleClick; #endregion #endregion } }