/* Copyright (c) Citrix Systems Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using XenAdmin.Controls.DataGridViewEx; using XenAdmin.Core; using XenAdmin.Properties; using XenAPI; namespace XenAdmin.Controls.GPU { public partial class GpuRow : UserControl { public GpuRow() { InitializeComponent(); } public GpuRow(IXenObject xenObject, List pGpuList) : this() { this.xenObject = xenObject; pGpuLabel.Text = pGpuList[0].Name; RepopulateAllowedTypes(pGpuList[0]); vGpuCapability = !Helpers.FeatureForbidden(xenObject, Host.RestrictVgpu) && pGpuList[0].HasVGpu; Rebuild(pGpuList); SetupPage(); } private readonly IXenObject xenObject; private Dictionary pGpus = new Dictionary(); private readonly bool vGpuCapability; private void Rebuild(List pGpuList) { Program.AssertOnEventThread(); if (!Visible) return; shinyBarsContainerPanel.SuspendLayout(); // Store a list of the current controls. We remove them at the end because it makes less flicker that way. var oldControls = new List(shinyBarsContainerPanel.Controls.Count); oldControls.AddRange(shinyBarsContainerPanel.Controls.Cast()); bool showingHostLabel = (xenObject is Pool) && xenObject.Connection.Cache.Hosts.Length > 1; int index = 1; XenRef hostRef = null; foreach (PGPU pgpu in pGpuList) { var host = xenObject.Connection.Resolve(pgpu.host); // add host label if needed if (showingHostLabel && (hostRef == null || pgpu.host.opaque_ref != hostRef.opaque_ref)) { AddHostLabel(new Label { Text = String.Format(Messages.GPU_ON_HOST_LABEL, host.Name)}, ref index); hostRef = pgpu.host; } // add pGPU shiny bar var gpuShinyBar = new GpuShinyBar(); var checkBox = (pGpuList.Count > 1 && vGpuCapability) ? new CheckBox() : null; AddShinyBar(gpuShinyBar, checkBox, ref index); gpuShinyBar.Initialize(pgpu); pGpus.Add(pgpu, checkBox); } // Remove old controls foreach (Control c in oldControls) { shinyBarsContainerPanel.Controls.Remove(c); c.Dispose(); } shinyBarsContainerPanel.ResumeLayout(); ReLayout(); } private void AddShinyBar(UserControl shinyBar, CheckBox checkBox, ref int index) { if (checkBox != null) { shinyBarsContainerPanel.Controls.Add(checkBox, 0, index); checkBox.Dock = DockStyle.Fill; checkBox.Margin = new Padding(3, 14, 0, 0); checkBox.CheckedChanged += CheckedChanged; checkBox.Checked = true; } shinyBarsContainerPanel.Controls.Add(shinyBar, 1, index); shinyBar.Dock = DockStyle.Fill; index++; } private void AddHostLabel(Label label, ref int index) { shinyBarsContainerPanel.Controls.Add(label, 0, index); shinyBarsContainerPanel.SetColumnSpan(label, 2); label.Dock = DockStyle.Fill; index++; } private void ReLayout() { Program.AssertOnEventThread(); Height = tableLayoutPanel1.Height + 2; } private void SetupPage() { multipleSelectionPanel.Visible = (pGpus.Count > 1) && vGpuCapability; editButton.Text = (pGpus.Count > 1) ? Messages.GPU_EDIT_ALLOWED_TYPES_MULTIPLE : Messages.GPU_EDIT_ALLOWED_TYPES_SINGLE; editButton.Visible = vGpuCapability; } private GpuShinyBar FindGpuShinyBar(PGPU pGpu) { return pGpu != null ? shinyBarsContainerPanel.Controls.OfType().FirstOrDefault( shinyBar => shinyBar.PGPU == pGpu) : null; } public void RefreshGpu(PGPU pGpu) { Program.AssertOnEventThread(); if (!Visible) return; GpuShinyBar gpuShinyBar = FindGpuShinyBar(pGpu); if (gpuShinyBar != null) { gpuShinyBar.Initialize(pGpu); gpuShinyBar.Refresh(); } } public IEnumerable PGPUs { get { return pGpus.Keys; } } public List SelectedPGPUs { get { if (pGpus.Count == 0) return null; return pGpus.Count > 1 ? (from kvp in pGpus where kvp.Value != null && kvp.Value.Checked select kvp.Key).ToList() : new List {pGpus.Keys.ElementAt(0)}; } } private void selectAllButton_Click(object sender, EventArgs e) { foreach (var checkBox in pGpus.Values.Where(checkBox => checkBox != null)) { checkBox.Checked = true; } } private void clearAllButton_Click(object sender, EventArgs e) { foreach (var checkBox in pGpus.Values.Where(checkBox => checkBox != null)) { checkBox.Checked = false; } } private void editButton_Click(object sender, EventArgs e) { new GpuConfiguration(SelectedPGPUs).ShowDialog(Program.MainWindow); } private void CheckedChanged(object sender, EventArgs e) { editButton.Enabled = clearAllButton.Enabled = (pGpus.Values.Where(checkBox => checkBox != null).Any(checkBox => checkBox.Checked)); selectAllButton.Enabled = (pGpus.Values.Where(checkBox => checkBox != null).Any(checkBox => !checkBox.Checked)); } #region Allowed vGpu types private void RepopulateAllowedTypes(PGPU pGpu) { allowedTypesGrid.SuspendLayout(); allowedTypesGrid.Rows.Clear(); allowedTypesGrid.Cursor = Cursors.WaitCursor; try { allowedTypesGrid.Rows.Clear(); if (pGpu.supported_VGPU_types != null && pGpu.supported_VGPU_types.Count > 0) { allowedTypesGrid.Rows.AddRange((from vGpuTypeRef in pGpu.supported_VGPU_types let vGpuType = pGpu.Connection.Resolve(vGpuTypeRef) let enabledType = pGpu.enabled_VGPU_types.Contains(vGpuTypeRef) orderby vGpuType.Capacity ascending select new VGpuTypeRow(vGpuType, enabledType)).ToArray()); } allowedTypesGrid.Height = allowedTypesGrid.Rows[0].Height * (allowedTypesGrid.RowCount); } finally { allowedTypesGrid.ResumeLayout(); allowedTypesGrid.Cursor = Cursors.Default; } } #endregion } class VGpuTypeRow : DataGridViewExRow { public VGPU_type VGpuType; public bool EnabledType; private readonly DataGridViewExImageCell ImageCell = new DataGridViewExImageCell(); private readonly DataGridViewTextBoxCell NameCell = new DataGridViewTextBoxCell(); public VGpuTypeRow(VGPU_type vGpuType, bool enabledType) { VGpuType = vGpuType; EnabledType = enabledType; Cells.AddRange(ImageCell, NameCell); UpdateDetails(); } public void UpdateDetails() { ImageCell.Value = EnabledType ? Resources._000_Tick_h32bit_16 : Resources._000_Abort_h32bit_16; NameCell.Value = VGpuType.Name; } } }