mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-25 14:27:26 +01:00
7c0bc50b4a
Inc. Signed-off-by: Gabor Apati-Nagy<gabor.apati-nagy@citrix.com>
209 lines
9.0 KiB
C#
209 lines
9.0 KiB
C#
/* 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;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using XenAdmin.Dialogs;
|
|
using XenAPI;
|
|
using XenAdmin.Commands;
|
|
|
|
namespace XenAdmin.Dialogs
|
|
{
|
|
/// <summary>
|
|
/// A confirmation dialog for Commands. Primarily used for displaying the subset of items from the multiple-selection
|
|
/// which are not going to be actioned by the Command.
|
|
/// </summary>
|
|
internal partial class CommandErrorDialog : XenDialogBase
|
|
{
|
|
public enum DialogMode { Close, OKCancel };
|
|
|
|
public DialogMode Mode { get; private set; }
|
|
|
|
private ListSortDirection m_direction;
|
|
private DataGridViewColumn m_oldSortedColumn;
|
|
|
|
|
|
/// <summary>
|
|
/// Gets a new <see cref="CommandErrorDialog"/> using the specified parameters.
|
|
/// </summary>
|
|
/// <typeparam name="TXenObject">The type of the xen object.</typeparam>
|
|
/// <param name="title">The title for the confirmation dialog.</param>
|
|
/// <param name="text">The text for the confirmation dialog.</param>
|
|
/// <param name="cantExecuteReasons">A dictionary of names of the objects which will be ignored with assoicated reasons.</param>
|
|
public static CommandErrorDialog Create<TXenObject>(string title, string text, IDictionary<TXenObject, string> cantExecuteReasons) where TXenObject : IXenObject
|
|
{
|
|
Dictionary<SelectedItem, string> d = new Dictionary<SelectedItem, string>();
|
|
foreach (TXenObject x in cantExecuteReasons.Keys)
|
|
{
|
|
d[new SelectedItem(x)] = cantExecuteReasons[x];
|
|
}
|
|
return new CommandErrorDialog(title, text, d);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="CommandErrorDialog"/> class.
|
|
/// </summary>
|
|
/// <param name="title">The title for the confirmation dialog.</param>
|
|
/// <param name="text">The text for the confirmation dialog.</param>
|
|
/// <param name="cantExecuteReasons">A dictionary of names of the objects which will be ignored with assoicated reasons.</param>
|
|
public CommandErrorDialog(string title, string text, IDictionary<SelectedItem, string> cantExecuteReasons)
|
|
: this(title, text, cantExecuteReasons, DialogMode.Close)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="CommandErrorDialog"/> class.
|
|
/// </summary>
|
|
/// <param name="title">The title for the confirmation dialog.</param>
|
|
/// <param name="text">The text for the confirmation dialog.</param>
|
|
/// <param name="cantExecuteReasons">A dictionary of names of the objects which will be ignored with assoicated reasons.</param>
|
|
/// <param name="mode">Whether the dialog should show a Close button, or OK and Cancel buttons.</param>
|
|
public CommandErrorDialog(string title, string text, IDictionary<SelectedItem, string> cantExecuteReasons, DialogMode mode)
|
|
{
|
|
Util.ThrowIfParameterNull(cantExecuteReasons, "cantExecuteReasons");
|
|
Util.ThrowIfParameterNull(title, "title");
|
|
Util.ThrowIfParameterNull(text, "text");
|
|
|
|
InitializeComponent();
|
|
pbQuestion.Image = SystemIcons.Error.ToBitmap();
|
|
|
|
Text = title;
|
|
lblText.Text = text;
|
|
Mode = mode;
|
|
|
|
btnCancel.Visible = mode == DialogMode.OKCancel;
|
|
btnOK.Visible = mode == DialogMode.OKCancel;
|
|
btnClose.Visible = mode == DialogMode.Close;
|
|
|
|
foreach (SelectedItem selectedItem in cantExecuteReasons.Keys)
|
|
{
|
|
DataGridViewRow row = new DataGridViewRow {Tag = selectedItem.XenObject};
|
|
row.Cells.AddRange(new DataGridViewCell[]
|
|
{
|
|
new DataGridViewImageCell {Value = Images.GetImage16For(selectedItem.XenObject)},
|
|
new DataGridViewTextBoxCell {Value = selectedItem.XenObject.ToString()},
|
|
new DataGridViewTextBoxCell {Value = cantExecuteReasons[selectedItem]}
|
|
});
|
|
m_dataGridView.Rows.Add(row);
|
|
}
|
|
|
|
m_direction = ListSortDirection.Ascending;
|
|
m_oldSortedColumn = colName;
|
|
m_dataGridView.Sort(new RowComparer(colName.Index, m_direction));
|
|
}
|
|
|
|
private void btnOK_Click(object sender, EventArgs e)
|
|
{
|
|
DialogResult = DialogResult.OK;
|
|
Close();
|
|
}
|
|
|
|
private void btnCancel_Click(object sender, EventArgs e)
|
|
{
|
|
DialogResult = DialogResult.Cancel;
|
|
Close();
|
|
}
|
|
|
|
private void m_dataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
|
|
{
|
|
if (e.ColumnIndex < colName.Index || e.ColumnIndex > colReason.Index)
|
|
return;
|
|
|
|
var newColumn = m_dataGridView.Columns[e.ColumnIndex];
|
|
|
|
if (m_oldSortedColumn == null)
|
|
{
|
|
// the DataGridView is not currently sorted
|
|
m_direction = ListSortDirection.Ascending;
|
|
m_oldSortedColumn = newColumn;
|
|
}
|
|
else
|
|
{
|
|
if (m_oldSortedColumn == newColumn)
|
|
{
|
|
// Sort the same column again, reversing the SortOrder.
|
|
m_direction = (m_direction == ListSortDirection.Ascending)
|
|
? ListSortDirection.Descending
|
|
: ListSortDirection.Ascending;
|
|
}
|
|
else
|
|
{
|
|
// Sort a new column and remove the SortGlyph from the old column
|
|
m_direction = ListSortDirection.Ascending;
|
|
m_oldSortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
|
|
m_oldSortedColumn = newColumn;
|
|
}
|
|
}
|
|
|
|
m_dataGridView.Sort(new RowComparer(newColumn.Index, m_direction));
|
|
newColumn.HeaderCell.SortGlyphDirection = m_direction == ListSortDirection.Ascending
|
|
? SortOrder.Ascending
|
|
: SortOrder.Descending;
|
|
}
|
|
|
|
private class RowComparer : IComparer
|
|
{
|
|
private readonly int m_columnIndex;
|
|
private readonly ListSortDirection m_direction;
|
|
private const int COL_NAME = 1;
|
|
private const int COL_REASON = 2;
|
|
|
|
public RowComparer(int columnIndex, ListSortDirection direction)
|
|
{
|
|
m_columnIndex = columnIndex;
|
|
m_direction = direction;
|
|
}
|
|
|
|
public int Compare(object x, object y)
|
|
{
|
|
var row1 = (DataGridViewRow)x;
|
|
var row2 = (DataGridViewRow)y;
|
|
|
|
int result = 0;
|
|
|
|
if (m_columnIndex == COL_NAME)
|
|
result = ((IXenObject)row1.Tag).CompareTo(row2.Tag);
|
|
else if (m_columnIndex == COL_REASON)
|
|
result = string.Compare(row1.Cells[COL_REASON].Value.ToString(), row2.Cells[COL_REASON].Value.ToString());
|
|
|
|
if (m_direction == ListSortDirection.Descending)
|
|
return -1 * result;
|
|
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
} |