/* 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
{
///
/// 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.
///
internal partial class CommandErrorDialog : XenDialogBase
{
public enum DialogMode { Close, OKCancel };
public DialogMode Mode { get; private set; }
private ListSortDirection m_direction;
private DataGridViewColumn m_oldSortedColumn;
///
/// Gets a new using the specified parameters.
///
/// The type of the xen object.
/// The title for the confirmation dialog.
/// The text for the confirmation dialog.
/// A dictionary of names of the objects which will be ignored with assoicated reasons.
public static CommandErrorDialog Create(string title, string text, IDictionary cantExecuteReasons) where TXenObject : IXenObject
{
Dictionary d = new Dictionary();
foreach (TXenObject x in cantExecuteReasons.Keys)
{
d[new SelectedItem(x)] = cantExecuteReasons[x];
}
return new CommandErrorDialog(title, text, d);
}
///
/// Initializes a new instance of the class.
///
/// The title for the confirmation dialog.
/// The text for the confirmation dialog.
/// A dictionary of names of the objects which will be ignored with assoicated reasons.
public CommandErrorDialog(string title, string text, IDictionary cantExecuteReasons)
: this(title, text, cantExecuteReasons, DialogMode.Close)
{
}
///
/// Initializes a new instance of the class.
///
/// The title for the confirmation dialog.
/// The text for the confirmation dialog.
/// A dictionary of names of the objects which will be ignored with assoicated reasons.
/// Whether the dialog should show a Close button, or OK and Cancel buttons.
public CommandErrorDialog(string title, string text, IDictionary 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;
}
}
}
}