mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-25 23:10:16 +01:00
417 lines
16 KiB
C#
417 lines
16 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.Drawing;
|
|||
|
using System.Windows.Forms;
|
|||
|
using System.Threading;
|
|||
|
using System.Collections.Generic;
|
|||
|
|
|||
|
|
|||
|
namespace XenAdmin.Dialogs
|
|||
|
{
|
|||
|
public partial class ThreeButtonDialog : XenDialogBase
|
|||
|
{
|
|||
|
private string helpName = "DefaultHelpTopic";
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gives you a dialog with a single OK button.
|
|||
|
/// </summary>
|
|||
|
/// <param name="properties"></param>
|
|||
|
/// <param name="helpName"></param>
|
|||
|
public ThreeButtonDialog(Details properties, string helpName)
|
|||
|
: this(properties, ButtonOK)
|
|||
|
{
|
|||
|
this.helpName = helpName;
|
|||
|
HelpButton = true;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gives you a dialog with the specified buttons.
|
|||
|
/// </summary>
|
|||
|
/// <param name="properties"></param>
|
|||
|
/// <param name="helpName"></param>
|
|||
|
/// <param name="buttons">Must be between 1 and 3 buttons</param>
|
|||
|
public ThreeButtonDialog(Details properties, string helpName, params TBDButton[] buttons)
|
|||
|
: this(properties, buttons)
|
|||
|
{
|
|||
|
this.helpName = helpName;
|
|||
|
HelpButton = true;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gives you a dialog with a single OK button.
|
|||
|
/// </summary>
|
|||
|
/// <param name="properties"></param>
|
|||
|
/// <param name="helpName"></param>
|
|||
|
public ThreeButtonDialog(Details properties)
|
|||
|
: this(properties, ButtonOK)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gives you a dialog with the specified buttons.
|
|||
|
/// </summary>
|
|||
|
/// <param name="properties"></param>
|
|||
|
/// <param name="buttons">>Must be between 1 and 3 buttons</param>
|
|||
|
public ThreeButtonDialog(Details properties, params TBDButton[] buttons)
|
|||
|
{
|
|||
|
System.Diagnostics.Trace.Assert(buttons.Length > 0 && buttons.Length < 4, "Three button dialog can only have between 1 and 3 buttons.");
|
|||
|
InitializeComponent();
|
|||
|
|
|||
|
if (properties.Icon == null)
|
|||
|
pictureBoxIcon.Visible = false;
|
|||
|
else
|
|||
|
pictureBoxIcon.Image = properties.Icon.ToBitmap();
|
|||
|
|
|||
|
labelMessage.Text = properties.MainMessage;
|
|||
|
if (properties.linkLength > 0)
|
|||
|
labelMessage.Links.Add(new LinkLabel.Link(properties.linkStart, properties.linkLength, properties.linkUrl));
|
|||
|
|
|||
|
if (properties.WindowTitle != null)
|
|||
|
this.Text = properties.WindowTitle;
|
|||
|
|
|||
|
button1.Visible = true;
|
|||
|
button1.Text = buttons[0].label;
|
|||
|
button1.DialogResult = buttons[0].result;
|
|||
|
if (buttons[0].defaultAction == ButtonType.ACCEPT)
|
|||
|
{
|
|||
|
AcceptButton = button1;
|
|||
|
if (buttons.Length == 1)
|
|||
|
CancelButton = button1;
|
|||
|
}
|
|||
|
else if (buttons[0].defaultAction == ButtonType.CANCEL)
|
|||
|
CancelButton = button1;
|
|||
|
|
|||
|
if (buttons[0].selected)
|
|||
|
button1.Select();
|
|||
|
|
|||
|
if (buttons.Length > 1)
|
|||
|
{
|
|||
|
button2.Visible = true;
|
|||
|
button2.Text = buttons[1].label;
|
|||
|
button2.DialogResult = buttons[1].result;
|
|||
|
if (buttons[1].defaultAction == ButtonType.ACCEPT)
|
|||
|
AcceptButton = button2;
|
|||
|
else if (buttons[1].defaultAction == ButtonType.CANCEL)
|
|||
|
CancelButton = button2;
|
|||
|
|
|||
|
if (buttons[1].selected)
|
|||
|
button2.Select();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
button2.Visible = false;
|
|||
|
}
|
|||
|
|
|||
|
if (buttons.Length > 2)
|
|||
|
{
|
|||
|
button3.Visible = true;
|
|||
|
button3.Text = buttons[2].label;
|
|||
|
button3.DialogResult = buttons[2].result;
|
|||
|
if (buttons[2].defaultAction == ButtonType.ACCEPT)
|
|||
|
AcceptButton = button3;
|
|||
|
else if (buttons[2].defaultAction == ButtonType.CANCEL)
|
|||
|
CancelButton = button3;
|
|||
|
|
|||
|
if (buttons[2].selected)
|
|||
|
button3.Select();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
button3.Visible = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The message displayed on the dialog
|
|||
|
/// </summary>
|
|||
|
public String Message
|
|||
|
{
|
|||
|
get { return labelMessage.Text; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// A list of buttons on the page
|
|||
|
/// </summary>
|
|||
|
public List<Button> Buttons
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return new List<Button>()
|
|||
|
{
|
|||
|
button1,
|
|||
|
button2,
|
|||
|
button3
|
|||
|
};
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// A list of buttons on the page that have been set visible
|
|||
|
/// </summary>
|
|||
|
public List<Button> VisibleButtons
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
List<Button> visibleButtonList = new List<Button>();
|
|||
|
Buttons.ForEach(button => AddButtonIfVisible(visibleButtonList, button));
|
|||
|
return visibleButtonList;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void AddButtonIfVisible( List<Button> buttonList, Button button )
|
|||
|
{
|
|||
|
if( button.Visible )
|
|||
|
buttonList.Add( button );
|
|||
|
}
|
|||
|
|
|||
|
internal override string HelpName
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return helpName;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class TBDButton
|
|||
|
{
|
|||
|
public string label;
|
|||
|
public DialogResult result;
|
|||
|
public ButtonType defaultAction = ButtonType.NONE;
|
|||
|
public bool selected = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Describes a button for the three button dialog. This constructor infers the dialogs default button from
|
|||
|
/// the result type you give it.
|
|||
|
///
|
|||
|
/// To override this behaviour use another constructor.
|
|||
|
/// </summary>
|
|||
|
/// <param name="label">The label for the button</param>
|
|||
|
/// <param name="result">The result to return on click. Setting result to be OK or Yes results in the dialog choosing this button as the DefaultAcceptButton,
|
|||
|
/// and No or Cancel sets it as the DefaultCancelButton.</param>
|
|||
|
public TBDButton(string label, DialogResult result)
|
|||
|
{
|
|||
|
this.label = label;
|
|||
|
this.result = result;
|
|||
|
if (result == DialogResult.OK || result == DialogResult.Yes)
|
|||
|
defaultAction = ButtonType.ACCEPT;
|
|||
|
if (result == DialogResult.No || result == DialogResult.Cancel)
|
|||
|
defaultAction = ButtonType.CANCEL;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// This constructor allows you to override how the threebuttondialog interprets the dialogresult of this button.
|
|||
|
/// </summary>
|
|||
|
/// <param name="label">The label for the button</param>
|
|||
|
/// <param name="result">The result to return on click.</param>
|
|||
|
/// <param name="isDefaultButton">The role the button plays in the dialog</param>
|
|||
|
public TBDButton(string label, DialogResult result, ButtonType isDefaultButton)
|
|||
|
: this(label, result)
|
|||
|
{
|
|||
|
defaultAction = isDefaultButton;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// This constructor allows you to override how the threebuttondialog interprets the dialogresult of this button and specify if the button is selected by default.
|
|||
|
/// </summary>
|
|||
|
/// <param name="label">The label for the button</param>
|
|||
|
/// <param name="result">The result to return on click.</param>
|
|||
|
/// <param name="isDefaultButton">The role the button plays in the dialog</param>
|
|||
|
public TBDButton(string label, DialogResult result, ButtonType isDefaultButton, bool select)
|
|||
|
: this(label, result, isDefaultButton)
|
|||
|
{
|
|||
|
selected = select;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Using Accept results in this button becoming the DefaultAcceptButton, and Cancel sets it as the DefaultCancelButton
|
|||
|
/// </summary>
|
|||
|
public enum ButtonType { NONE, ACCEPT, CANCEL };
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Describes the main properties of a dialog
|
|||
|
/// </summary>
|
|||
|
public class Details
|
|||
|
{
|
|||
|
public Icon Icon;
|
|||
|
public string WindowTitle = null;
|
|||
|
public string MainMessage = "";
|
|||
|
public int linkStart = 0;
|
|||
|
public int linkLength = 0;
|
|||
|
public string linkUrl = "";
|
|||
|
|
|||
|
public Details(Icon Icon, string MainMessage)
|
|||
|
{
|
|||
|
this.Icon = Icon;
|
|||
|
this.MainMessage = MainMessage;
|
|||
|
}
|
|||
|
|
|||
|
public Details(Icon Icon, string MainMessage, string WindowTitle)
|
|||
|
: this(Icon, MainMessage)
|
|||
|
{
|
|||
|
this.WindowTitle = WindowTitle;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public Details(Icon Icon, string MainMessage, int linkStart, int linkLength, string linkUrl, string WindowTitle)
|
|||
|
: this(Icon, MainMessage, WindowTitle)
|
|||
|
{
|
|||
|
this.linkStart = linkStart;
|
|||
|
this.linkLength = linkLength;
|
|||
|
this.linkUrl = linkUrl;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Retrieves a button with label Messages.YES_BUTTON_CAPTION and result DialogResult.Yes
|
|||
|
/// </summary>
|
|||
|
public static TBDButton ButtonYes
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return new TBDButton(Messages.YES_BUTTON_CAPTION, DialogResult.Yes);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Retrieves a button with label Messages.NO_BUTTON_CAPTION and result DialogResult.No
|
|||
|
/// </summary>
|
|||
|
public static TBDButton ButtonNo
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return new TBDButton(Messages.NO_BUTTON_CAPTION, DialogResult.No);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Retrieves a button with label Messages.OK and result DialogResult.OK)
|
|||
|
/// </summary>
|
|||
|
public static TBDButton ButtonOK
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return new TBDButton(Messages.OK, DialogResult.OK);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Retrieves a button with label Messages.CANCEL and result DialogResult.Cancel
|
|||
|
/// </summary>
|
|||
|
public static TBDButton ButtonCancel
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return new TBDButton(Messages.CANCEL, DialogResult.Cancel);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void ThreeButtonDialog_FormClosing(object sender, FormClosingEventArgs e)
|
|||
|
{
|
|||
|
if (e.CloseReason == CloseReason.UserClosing)
|
|||
|
{
|
|||
|
if (!closedFromButton)
|
|||
|
{
|
|||
|
// User has closed without pressing a button (e.g. the cross)
|
|||
|
|
|||
|
// In the following scenarios we can predict what they mean:
|
|||
|
|
|||
|
if (CancelButton != null)
|
|||
|
{
|
|||
|
// There's a cancel button, this most closely maps to the desire of someone telling the window to get lost
|
|||
|
DialogResult = CancelButton.DialogResult;
|
|||
|
}
|
|||
|
else if (VisibleButtons.Find(delegate(Button b) { return b.DialogResult == DialogResult.Cancel; }) != null)
|
|||
|
{
|
|||
|
// There's a cancel button, this most closely maps to the desire of someone telling the window to get lost
|
|||
|
DialogResult = DialogResult.Cancel;
|
|||
|
}
|
|||
|
else if (VisibleButtons.Count == 1)
|
|||
|
{
|
|||
|
// Single button, they only had one choice anyway. 99% of the time this an OK prompt
|
|||
|
DialogResult = VisibleButtons[0].DialogResult;
|
|||
|
}
|
|||
|
else if (VisibleButtons.Count == 2 && VisibleButtons[0].DialogResult == DialogResult.Yes && VisibleButtons[1].DialogResult == DialogResult.No)
|
|||
|
{
|
|||
|
// Another common scenario, a yes/no prompt. Slightly more dubious this one, but they most likely mean no.
|
|||
|
// The following issues have been considered:
|
|||
|
// - If we are performing a dangerous/significant/unreversable action then this should be an OK Cancel dialog anyway
|
|||
|
// - You've got the Yes/No buttons the wrong way round
|
|||
|
//
|
|||
|
// ...either way you should go back to UI school :)
|
|||
|
DialogResult = DialogResult.No;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// We can't figure out what they mean, and since people almost always only assume that the dialog only returns the results on
|
|||
|
// the buttons we are going to block the close
|
|||
|
|
|||
|
// Set a CancelButton if you want to stop this happening
|
|||
|
e.Cancel = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private bool closedFromButton = false;
|
|||
|
private void button1_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
closedFromButton = true;
|
|||
|
Close();
|
|||
|
}
|
|||
|
|
|||
|
private void button2_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
closedFromButton = true;
|
|||
|
Close();
|
|||
|
}
|
|||
|
|
|||
|
private void button3_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
closedFromButton = true;
|
|||
|
Close();
|
|||
|
}
|
|||
|
|
|||
|
private void labelMessage_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
System.Diagnostics.Process.Start(e.Link.LinkData.ToString());
|
|||
|
}
|
|||
|
catch { } // Best effort
|
|||
|
}
|
|||
|
}
|
|||
|
}
|