/* Copyright (c) Cloud Software Group, Inc. * * 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.ComponentModel; using System.Drawing; using System.Windows.Forms; using XenAdmin.Actions; using XenAdmin.Controls; using XenAdmin.Core; using XenAdmin.SettingsPanels; using XenAPI; namespace XenAdmin.Wizards.NewVMApplianceWizard { public partial class NewVMApplianceVMOrderAndDelaysPage : XenTabPage, IEditPage { private Pool _pool; public Pool Pool { get { return _pool; } set { _pool = value; } } public NewVMApplianceVMOrderAndDelaysPage() { InitializeComponent(); nudStartDelay.Maximum = long.MaxValue; nudOrder.Maximum = long.MaxValue; dataGridView1.SortCompare += dataGridView1_SortCompare; } public override string Text { get { return Messages.NEWVMAPPLIANCE_VMORDERANDDELAYSPAGE_TEXT; } } public string SubText { get { return ""; } } public override string HelpID { get { return "VMOrderAndDelays"; } } public Image Image => Images.StaticImages._000_RebootVM_h32bit_16; public override string PageTitle { get { return Messages.NEWVMAPPLIANCE_VMORDERANDDELAYSPAGE_TITLE; } } /// /// Whether the user has made any changes to VM properties on the server. /// public bool ChangesMade { get; private set; } private List _selectedVMs = null; private Dictionary _changedSettings = null; public void SetSelectedVMs(List selectedVMs) { _selectedVMs = selectedVMs; _changedSettings = GetChangedSettings(); RefreshTab(); } private void RefreshTab() { dataGridView1.Rows.Clear(); foreach (VM vm in _selectedVMs) { VMStartupOptions settings = _changedSettings != null && _changedSettings.ContainsKey(vm) ? new VMStartupOptions(_changedSettings[vm].Order, _changedSettings[vm].StartDelay) : new VMStartupOptions(vm.order, vm.start_delay); // Create a new row for this VM dataGridView1.Rows.Add(new VMDataGridViewRow(vm, settings)); } dataGridView1.Sort(ColumnName, ListSortDirection.Ascending); } void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e) { // If sorting by name, actually sort by VM. This ensures that we use the // same sort as everywhere else. if (e.Column == ColumnName) { VM vm1 = ((VMDataGridViewRow)dataGridView1.Rows[e.RowIndex1]).Vm; VM vm2 = ((VMDataGridViewRow)dataGridView1.Rows[e.RowIndex2]).Vm; e.SortResult = vm1.CompareTo(vm2); e.Handled = true; return; } e.Handled = false; } private class VMDataGridViewRow : DataGridViewRow { private DataGridViewTextBoxCell _nameCell = new DataGridViewTextBoxCell(); private DataGridViewTextBoxCell _descriptionCell = new DataGridViewTextBoxCell(); private DataGridViewTextBoxCell _orderCell = new DataGridViewTextBoxCell(); private DataGridViewTextBoxCell _startDelayCell = new DataGridViewTextBoxCell(); public readonly VM Vm; public VMStartupOptions Settings; public VMDataGridViewRow(VM vm, VMStartupOptions settings) { Vm = vm; Cells.Add(_nameCell); Cells.Add(_descriptionCell); Cells.Add(_orderCell); Cells.Add(_startDelayCell);; Settings = settings; _nameCell.Value = Vm.Name(); _descriptionCell.Value = Vm.Description(); UpdateRow(); } public void UpdateRow() { _orderCell.Value = Settings.Order; _startDelayCell.Value = Settings.StartDelay; } public bool HasChanged() { return Vm.start_delay != Settings.StartDelay || Vm.order != Settings.Order; } } private void updateTextBoxes() { Program.AssertOnEventThread(); if (dataGridView1.SelectedRows.Count == 0) { nudOrder.Enabled = false; nudOrder.Text = ""; nudStartDelay.Enabled = false; nudStartDelay.Text = ""; return; } nudOrder.Enabled = true; nudStartDelay.Enabled = true; long order = ((VMDataGridViewRow) dataGridView1.SelectedRows[0]).Settings.Order; bool sameOrder = true; long startDelay = ((VMDataGridViewRow)dataGridView1.SelectedRows[0]).Settings.StartDelay; bool sameStartDelay = true; foreach (VMDataGridViewRow row in dataGridView1.SelectedRows) { if (order != row.Settings.Order) { order = row.Settings.Order; sameOrder = false; } if (startDelay != row.Settings.StartDelay) { startDelay = row.Settings.StartDelay; sameStartDelay = false; } } nudOrder.Text = sameOrder ? order.ToString() : ""; nudStartDelay.Text = sameStartDelay ? startDelay.ToString() : ""; } /// /// Gets the changed (uncommitted) VM settings. Must be called on the GUI thread. /// /// public Dictionary GetChangedSettings() { Program.AssertOnEventThread(); if (dataGridView1.RowCount == 0) return null; var result = new Dictionary(); foreach (VMDataGridViewRow row in dataGridView1.Rows) { if (row.HasChanged()) result.Add(row.Vm, row.Settings); } return result; } #region Control event handlers private void numericUpDown1_ValueChanged(object sender, EventArgs e) { long order = (long)nudOrder.Value; bool changesMade = false; foreach (VMDataGridViewRow row in dataGridView1.SelectedRows) { if (row.Settings.Order != order) { changesMade = true; row.Settings.Order = order; row.UpdateRow(); } } if (changesMade) { ChangesMade = true; updateTextBoxes(); } } private void nudStartDelay_ValueChanged(object sender, EventArgs e) { long startDelay = (long)nudStartDelay.Value; bool changesMade = false; foreach (VMDataGridViewRow row in dataGridView1.SelectedRows) { if (row.Settings.StartDelay != startDelay) { changesMade = true; row.Settings.StartDelay = startDelay; row.UpdateRow(); } } if (changesMade) { ChangesMade = true; updateTextBoxes(); } } private void dataGridView1_SelectionChanged(object sender, EventArgs e) { updateTextBoxes(); } #endregion #region IEditPage implementation public AsyncAction SaveSettings() { return new SetVMStartupOptionsAction(Pool.Connection, GetChangedSettings(), true); } private VM_appliance _clone; public void SetXenObjects(IXenObject orig, IXenObject clone) { _clone = (VM_appliance)clone; Pool = Helpers.GetPoolOfOne(_clone.Connection); //RefreshTab(null); } public bool ValidToSave { get { return true; } } public void ShowLocalValidationMessages() { } public void HideLocalValidationMessages() { } public void Cleanup() { dataGridView1.Rows.Clear(); } public bool HasChanged { get { return ChangesMade; } } #endregion } }