Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

783 lines
24 KiB
C#

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (c) 2004-2006 Novell, Inc.
//
// Authors:
// Jordi Mas i Hernandez (jordi@ximian.com)
// Benjamin Dasnois (benjamin.dasnois@gmail.com)
// Robert Thompson (rmt@corporatism.org)
// Peter Bartok (pbartok@novell.com)
//
// TODO:
// - Add support for MessageBoxOptions and MessageBoxDefaultButton.
//
// NOT COMPLETE
using System;
using System.Drawing;
using System.Globalization;
using System.Resources;
namespace System.Windows.Forms
{
public class MessageBox
{
#region Private MessageBoxForm class
internal class MessageBoxForm : Form
{
#region MessageBoxFrom Local Variables
const int space_border = 10;
const int button_width = 86;
const int button_height = 23;
const int button_space = 5;
const int space_image_text= 10;
string msgbox_text;
bool size_known = false;
Icon icon_image;
RectangleF text_rect;
MessageBoxButtons msgbox_buttons;
MessageBoxDefaultButton msgbox_default;
bool buttons_placed = false;
int button_left;
Button[] buttons = new Button[4];
bool show_help;
string help_file_path;
string help_keyword;
HelpNavigator help_navigator;
object help_param;
AlertType alert_type;
#endregion // MessageBoxFrom Local Variables
#region MessageBoxForm Constructors
public MessageBoxForm (IWin32Window owner, string text, string caption,
MessageBoxButtons buttons, MessageBoxIcon icon,
bool displayHelpButton)
{
show_help = displayHelpButton;
switch (icon) {
case MessageBoxIcon.None: {
icon_image = null;
alert_type = AlertType.Default;
break;
}
case MessageBoxIcon.Error: { // Same as MessageBoxIcon.Hand and MessageBoxIcon.Stop
icon_image = SystemIcons.Error;
alert_type = AlertType.Error;
break;
}
case MessageBoxIcon.Question: {
icon_image = SystemIcons.Question;
alert_type = AlertType.Question;
break;
}
case MessageBoxIcon.Asterisk: { // Same as MessageBoxIcon.Information
icon_image = SystemIcons.Information;
alert_type = AlertType.Information;
break;
}
case MessageBoxIcon.Warning: { // Same as MessageBoxIcon.Exclamation:
icon_image = SystemIcons.Warning;
alert_type = AlertType.Warning;
break;
}
}
msgbox_text = text;
msgbox_buttons = buttons;
msgbox_default = MessageBoxDefaultButton.Button1;
if (owner != null) {
Owner = Control.FromHandle(owner.Handle).FindForm();
} else {
if (Application.MWFThread.Current.Context != null) {
Owner = Application.MWFThread.Current.Context.MainForm;
}
}
this.Text = caption;
this.ControlBox = true;
this.MinimizeBox = false;
this.MaximizeBox = false;
this.ShowInTaskbar = (Owner == null);
this.FormBorderStyle = FormBorderStyle.FixedDialog;
}
public MessageBoxForm (IWin32Window owner, string text, string caption,
MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options, bool displayHelpButton)
: this (owner, text, caption, buttons, icon, displayHelpButton)
{
msgbox_default = defaultButton;
}
public MessageBoxForm (IWin32Window owner, string text, string caption,
MessageBoxButtons buttons, MessageBoxIcon icon)
: this (owner, text, caption, buttons, icon, false)
{
}
#endregion // MessageBoxForm Constructors
#region Protected Instance Properties
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;;
cp.Style |= (int)(WindowStyles.WS_DLGFRAME | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CAPTION);
if (!is_enabled)
cp.Style |= (int)(WindowStyles.WS_DISABLED);
return cp;
}
}
#endregion // Protected Instance Properties
#region MessageBoxForm Methods
public void SetHelpData (string file_path, string keyword, HelpNavigator navigator, object param)
{
help_file_path = file_path;
help_keyword = keyword;
help_navigator = navigator;
help_param = param;
}
internal string HelpFilePath {
get { return help_file_path; }
}
internal string HelpKeyword {
get { return help_keyword; }
}
internal HelpNavigator HelpNavigator {
get { return help_navigator; }
}
internal object HelpParam {
get { return help_param; }
}
public DialogResult RunDialog ()
{
this.StartPosition = FormStartPosition.CenterScreen;
if (size_known == false) {
InitFormsSize ();
}
if (Owner != null)
TopMost = Owner.TopMost;
XplatUI.AudibleAlert (alert_type);
this.ShowDialog ();
return this.DialogResult;
}
internal override void OnPaintInternal (PaintEventArgs e)
{
e.Graphics.DrawString (msgbox_text, this.Font, ThemeEngine.Current.ResPool.GetSolidBrush (Color.Black), text_rect);
if (icon_image != null) {
e.Graphics.DrawIcon(icon_image, space_border, space_border);
}
}
private void InitFormsSize ()
{
int tb_width = 0;
// Max width of messagebox must be 60% of screen width
int max_width = (int) (Screen.GetWorkingArea (this).Width * 0.6);
if (max_width > 500) {
float dx;
using (Graphics g = this.CreateGraphics ()) {
dx = g.DpiX;
}
int new_max_width = (int) (dx * 5.0); // aim for text no wider than 5.0 inches
if (new_max_width < max_width)
max_width = new_max_width;
}
// First we have to know the size of text + image
int iconImageWidth = 0;
if (icon_image != null)
iconImageWidth = icon_image.Width + 10;
Drawing.SizeF tsize = TextRenderer.MeasureText (msgbox_text, this.Font, new Size (max_width - iconImageWidth, int.MaxValue), TextFormatFlags.WordBreak);
text_rect = new RectangleF ();
text_rect.Height = tsize.Height;
if (icon_image != null) {
tsize.Width += iconImageWidth;
if(icon_image.Height > tsize.Height) {
// Place text middle-right
text_rect.Location = new Point (icon_image.Width + space_image_text + space_border, (int)((icon_image.Height/2)-(tsize.Height/2)) + space_border);
} else {
text_rect.Location = new Point (icon_image.Width + space_image_text + space_border, 2 + space_border);
}
if (tsize.Height < icon_image.Height)
tsize.Height = icon_image.Height;
} else {
text_rect.Location = new Point (space_border + button_space, space_border);
}
tsize.Height += space_border * 2;
text_rect.Height += space_border;
// Now we want to know the amount of buttons
int buttoncount;
switch (msgbox_buttons) {
case MessageBoxButtons.OK:
buttoncount = 1;
break;
case MessageBoxButtons.OKCancel:
buttoncount = 2;
break;
case MessageBoxButtons.AbortRetryIgnore:
buttoncount = 3;
break;
case MessageBoxButtons.YesNoCancel:
buttoncount = 3;
break;
case MessageBoxButtons.YesNo:
buttoncount = 2;
break;
case MessageBoxButtons.RetryCancel:
buttoncount = 2;
break;
default:
buttoncount = 0;
break;
}
if (show_help)
buttoncount ++;
// Calculate the width based on amount of buttons
tb_width = (button_width + button_space) * buttoncount;
// The form caption can also make us bigger
SizeF caption = TextRenderer.MeasureString (Text, new Font (DefaultFont, FontStyle.Bold));
// Use the bigger of the caption size (plus some arbitrary borders/close button)
// or the text size, up to 60% of the screen (max_size)
Size new_size = new SizeF (Math.Min (Math.Max (caption.Width + 40, tsize.Width), max_width), tsize.Height).ToSize ();
// Now we choose the good size for the form
if (new_size.Width > tb_width)
this.ClientSize = new Size (new_size.Width + (space_border * 2), Height = new_size.Height + (space_border * 4));
else
this.ClientSize = new Size (tb_width + (space_border * 2), Height = new_size.Height + (space_border * 4));
text_rect.Width = new_size.Width - iconImageWidth;
// Now we set the left of the buttons
button_left = (this.ClientSize.Width / 2) - (tb_width / 2) + 5;
AddButtons ();
size_known = true;
// Still needs to implement defaultButton and options
switch(msgbox_default) {
case MessageBoxDefaultButton.Button2: {
if (this.buttons[1] != null) {
ActiveControl = this.buttons[1];
}
break;
}
case MessageBoxDefaultButton.Button3: {
if (this.buttons[2] != null) {
ActiveControl = this.buttons[2];
}
break;
}
}
}
protected override bool ProcessDialogKey(Keys keyData) {
if (keyData == Keys.Escape) {
this.CancelClick(this, null);
return true;
}
if (((keyData & Keys.Modifiers) == Keys.Control) &&
(((keyData & Keys.KeyCode) == Keys.C) ||
((keyData & Keys.KeyCode) == Keys.Insert))) {
Copy();
}
return base.ProcessDialogKey (keyData);
}
protected override bool ProcessDialogChar (char charCode)
{
// Shortcut keys, kinda like mnemonics, except you don't have to press Alt
if ((charCode == 'N' || charCode == 'n') && (CancelButton != null && (CancelButton as Button).Text == "No"))
CancelButton.PerformClick ();
else if ((charCode == 'Y' || charCode == 'y') && (AcceptButton as Button).Text == "Yes")
AcceptButton.PerformClick ();
else if ((charCode == 'A' || charCode == 'a') && (CancelButton != null && (CancelButton as Button).Text == "Abort"))
CancelButton.PerformClick ();
else if ((charCode == 'R' || charCode == 'r') && (AcceptButton as Button).Text == "Retry")
AcceptButton.PerformClick ();
else if ((charCode == 'I' || charCode == 'i') && buttons.Length >= 3 && buttons[2].Text == "Ignore")
buttons[2].PerformClick ();
return base.ProcessDialogChar (charCode);
}
private void Copy ()
{
string separator = "---------------------------" + Environment.NewLine;
System.Text.StringBuilder contents = new System.Text.StringBuilder ();
contents.Append (separator);
contents.Append (this.Text).Append (Environment.NewLine);
contents.Append (separator);
contents.Append (msgbox_text).Append (Environment.NewLine);
contents.Append (separator);
foreach (Button btn in buttons) {
if (btn == null)
break;
contents.Append (btn.Text).Append (" ");;
}
contents.Append (Environment.NewLine);
contents.Append (separator);
DataObject obj = new DataObject(DataFormats.Text, contents.ToString());
Clipboard.SetDataObject (obj);
}
#endregion // MessageBoxForm Methods
#region Functions for Adding buttons
private void AddButtons()
{
if (!buttons_placed) {
switch (msgbox_buttons) {
case MessageBoxButtons.OK: {
buttons[0] = AddOkButton (0);
break;
}
case MessageBoxButtons.OKCancel: {
buttons[0] = AddOkButton (0);
buttons[1] = AddCancelButton (1);
break;
}
case MessageBoxButtons.AbortRetryIgnore: {
buttons[0] = AddAbortButton (0);
buttons[1] = AddRetryButton (1);
buttons[2] = AddIgnoreButton (2);
break;
}
case MessageBoxButtons.YesNoCancel: {
buttons[0] = AddYesButton (0);
buttons[1] = AddNoButton (1);
buttons[2] = AddCancelButton (2);
break;
}
case MessageBoxButtons.YesNo: {
buttons[0] = AddYesButton (0);
buttons[1] = AddNoButton (1);
break;
}
case MessageBoxButtons.RetryCancel: {
buttons[0] = AddRetryButton (0);
buttons[1] = AddCancelButton (1);
break;
}
}
if (show_help) {
for (int i = 0; i <= 3; i++) {
if (buttons [i] == null) {
AddHelpButton (i);
break;
}
}
}
buttons_placed = true;
}
}
private Button AddButton (string text, int left, EventHandler click_event)
{
Button button = new Button ();
button.Text = Locale.GetText(text);
button.Width = button_width;
button.Height = button_height;
button.Top = this.ClientSize.Height - button.Height - space_border;
button.Left = ((button_width + button_space) * left) + button_left;
if (click_event != null)
button.Click += click_event;
if ((text == "OK") || (text == "Retry") || (text == "Yes"))
AcceptButton = button;
else if ((text == "Cancel") || (text == "Abort") || (text == "No"))
CancelButton = button;
this.Controls.Add (button);
return button;
}
private Button AddOkButton (int left)
{
return AddButton ("OK", left, new EventHandler (OkClick));
}
private Button AddCancelButton (int left)
{
return AddButton ("Cancel", left, new EventHandler (CancelClick));
}
private Button AddAbortButton (int left)
{
return AddButton ("Abort", left, new EventHandler (AbortClick));
}
private Button AddRetryButton(int left)
{
return AddButton ("Retry", left, new EventHandler (RetryClick));
}
private Button AddIgnoreButton (int left)
{
return AddButton ("Ignore", left, new EventHandler (IgnoreClick));
}
private Button AddYesButton (int left)
{
return AddButton ("Yes", left, new EventHandler (YesClick));
}
private Button AddNoButton (int left)
{
return AddButton ("No", left, new EventHandler (NoClick));
}
private Button AddHelpButton (int left)
{
Button button = AddButton ("Help", left, null);
button.Click += delegate { Owner.RaiseHelpRequested (new HelpEventArgs (Owner.Location)); };
return button;
}
#endregion
#region Button click handlers
private void OkClick (object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close ();
}
private void CancelClick (object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close ();
}
private void AbortClick (object sender, EventArgs e)
{
this.DialogResult = DialogResult.Abort;
this.Close ();
}
private void RetryClick (object sender, EventArgs e)
{
this.DialogResult = DialogResult.Retry;
this.Close ();
}
private void IgnoreClick (object sender, EventArgs e)
{
this.DialogResult = DialogResult.Ignore;
this.Close ();
}
private void YesClick (object sender, EventArgs e)
{
this.DialogResult = DialogResult.Yes;
this.Close ();
}
private void NoClick (object sender, EventArgs e)
{
this.DialogResult = DialogResult.No;
this.Close ();
}
#endregion
#region UIA Framework: Methods, Properties and Events
internal string UIAMessage {
get { return msgbox_text; }
}
internal Rectangle UIAMessageRectangle {
get {
return new Rectangle ((int) text_rect.X,
(int) text_rect.Y,
(int) text_rect.Width,
(int) text_rect.Height);
}
}
internal Rectangle UIAIconRectangle {
get {
return new Rectangle (space_border,
space_border,
icon_image == null ? -1 : icon_image.Width,
icon_image == null ? -1 : icon_image.Height);
}
}
#endregion
}
#endregion // Private MessageBoxForm class
#region Constructors
private MessageBox ()
{
}
#endregion // Constructors
#region Public Static Methods
public static DialogResult Show (string text)
{
MessageBoxForm form = new MessageBoxForm (null, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None);
return form.RunDialog ();
}
public static DialogResult Show (IWin32Window owner, string text)
{
MessageBoxForm form = new MessageBoxForm (owner, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None);
return form.RunDialog ();
}
public static DialogResult Show (string text, string caption)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None);
return form.RunDialog ();
}
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons, MessageBoxIcon.None);
return form.RunDialog ();
}
public static DialogResult Show (IWin32Window owner, string text, string caption,
MessageBoxButtons buttons)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons, MessageBoxIcon.None);
return form.RunDialog ();
}
public static DialogResult Show (IWin32Window owner, string text, string caption,
MessageBoxButtons buttons, MessageBoxIcon icon)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons, icon);
return form.RunDialog ();
}
public static DialogResult Show (IWin32Window owner, string text, string caption)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None);
return form.RunDialog ();
}
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons,
MessageBoxIcon icon)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons, icon);
return form.RunDialog ();
}
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons,
MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
icon, defaultButton, MessageBoxOptions.DefaultDesktopOnly, false);
return form.RunDialog ();
}
public static DialogResult Show (IWin32Window owner, string text, string caption,
MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
icon, defaultButton, MessageBoxOptions.DefaultDesktopOnly, false);
return form.RunDialog ();
}
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
icon, defaultButton, options, false);
return form.RunDialog ();
}
public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
icon, defaultButton, options, false);
return form.RunDialog ();
}
#endregion // Public Static Methods
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
bool displayHelpButton)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
icon, defaultButton, options, displayHelpButton);
return form.RunDialog ();
}
[MonoTODO ("Help is not implemented")]
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
string helpFilePath)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
icon, defaultButton, options, true);
form.SetHelpData (helpFilePath, null, HelpNavigator.TableOfContents, null);
return form.RunDialog ();
}
[MonoTODO ("Help is not implemented")]
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
string helpFilePath, string keyword)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
icon, defaultButton, options, true);
form.SetHelpData (helpFilePath, keyword, HelpNavigator.TableOfContents, null);
return form.RunDialog ();
}
[MonoTODO ("Help is not implemented")]
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
string helpFilePath, HelpNavigator navigator)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
icon, defaultButton, options, true);
form.SetHelpData (helpFilePath, null, navigator, null);
return form.RunDialog ();
}
[MonoTODO ("Help is not implemented")]
public static DialogResult Show (string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
string helpFilePath, HelpNavigator navigator, object param)
{
MessageBoxForm form = new MessageBoxForm (null, text, caption, buttons,
icon, defaultButton, options, true);
form.SetHelpData (helpFilePath, null, navigator, param);
return form.RunDialog ();
}
[MonoTODO ("Help is not implemented")]
public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
string helpFilePath)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
icon, defaultButton, options, true);
form.SetHelpData (helpFilePath, null, HelpNavigator.TableOfContents, null);
return form.RunDialog ();
}
[MonoTODO ("Help is not implemented")]
public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
string helpFilePath, string keyword)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
icon, defaultButton, options, true);
form.SetHelpData (helpFilePath, keyword, HelpNavigator.TableOfContents, null);
return form.RunDialog ();
}
[MonoTODO ("Help is not implemented")]
public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
string helpFilePath, HelpNavigator navigator)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
icon, defaultButton, options, true);
form.SetHelpData (helpFilePath, null, navigator, null);
return form.RunDialog ();
}
[MonoTODO ("Help is not implemented")]
public static DialogResult Show (IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options,
string helpFilePath, HelpNavigator navigator, object param)
{
MessageBoxForm form = new MessageBoxForm (owner, text, caption, buttons,
icon, defaultButton, options, true);
form.SetHelpData (helpFilePath, null, navigator, param);
return form.RunDialog ();
}
}
}