xenadmin/XenAdmin/Dialogs/ThreeButtonDialog.cs
Konstantina Chremmou 2e6b2d8995 CA-145890: added new Page to the options dialog where the user can configure how
confirmations are displayed. Added checkboxes to the dialogs requesting confirmation
of dismissal of notifications so the user can opt to skip this step.

Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
2016-11-17 13:35:31 +00:00

419 lines
15 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.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>
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.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;
}
}
public bool ShowCheckbox
{
get { return checkBoxOption.Visible; }
set { checkBoxOption.Visible = value; }
}
public string CheckboxCaption
{
get { return checkBoxOption.Text; }
set { checkBoxOption.Text = value; }
}
public bool IsCheckBoxChecked
{
get { return checkBoxOption.Checked; }
set { checkBoxOption.Checked = value; }
}
/// <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;
public string MainMessage = "";
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;
}
}
/// <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
}
}
}