JD2022-TU1/main/tools/framework/JD.MessageService/MessageService.cs

498 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Forms;
using JD.Collections.Extensions;
using JD.Kernel.Classes;
using JD.Kernel.StaticHelpers;
using JD.LogService;
namespace JD.MessageService
{
/// <summary>
/// Helper class used to display advanced Message Boxes and other forms of user interaction.
/// </summary>
/// <remarks>
/// Do NOT use this class in command line mode. Although some methods will simply not do anything in command-line mode (ShowMessage, ShowWarning, ShowError),
/// others will throw in command-line mode.
/// </remarks>
public static class MessageService
{
#region Inner Types
/// <summary>
/// Delegate that represents a method that shows a given error.
/// </summary>
/// <param name="ex">Thrown Exception</param>
/// <param name="message">An optional message</param>
internal delegate void ShowErrorDelegate(Exception ex, string message);
/// <summary>
/// Delegates that acts like a predicate for a string. Instead of returning true or false,
/// it has to return null if the validation passes or an error message if it fails.
/// </summary>
/// <param name="candidate">Candidate to test.</param>
/// <returns>Null if the validation passes, an error string to display otherwise.</returns>
public delegate string ValidationPredicate(string candidate);
#endregion
#region Variables
private const string DefaultMessageCaption = "Message";
private const string DefaultWarningCaption = "Warning";
private const string DefaultErrorCaption = "Error";
private static ShowErrorDelegate m_customErrorReporter;
private static IMessageService ms_instance;
private static bool _isCommandLine;
#endregion
#region Properties
public static bool IsCommandLine
{
get { return _isCommandLine; }
set
{
_isCommandLine = value;
ms_instance = null;
}
}
public static IMessageService Instance
{
get
{
if (ms_instance == null)
{
if (IsCommandLine)
{
ms_instance = new CommandlineMessageService();
}
else
{
ms_instance = new GuiMessageService();
}
}
return ms_instance;
}
}
/// <summary>
/// Gets/Sets the custom error reporter. If this property is null, the default
/// messagebox is used (except for debug builds, where the
/// message is only logged to the LogService).
/// </summary>
internal static ShowErrorDelegate CustomErrorReporter
{
get
{
return m_customErrorReporter;
}
set
{
m_customErrorReporter = value;
}
}
#endregion
#region Methods
#region Lifetime
public static void Initialize()
{
Instance.Initialize();
}
public static void Close()
{
DisposableHelper.SafeDispose(ms_instance as IDisposable);
}
#endregion
#region Mock
public static IDisposable Use(IMessageService messageService)
{
Throw.IfNull(messageService, "messageService");
IMessageService old = ms_instance;
ms_instance = messageService;
return new DisposableHelper(delegate
{
ms_instance = old;
});
}
#endregion
#region ShowMessage
/// <summary>
/// Shows a message box.
/// </summary>
/// <param name="message"></param>
/// <returns>Returns which button was clicked</returns>
public static void ShowMessage(string message)
{
ShowMessage(message, DefaultMessageCaption);
}
/// <summary>
/// <see cref="MessageService.ShowMessage(string)"/>
/// </summary>
/// <param name="message"></param>
/// <param name="caption"></param>
/// <returns>Returns which button was clicked</returns>
public static void ShowMessage(string message, string caption)
{
LogService.LogService.LogMessage(message);
Instance.Show(LogCategory.Message, message, caption);
}
#endregion
#region ShowWarning
/// <summary>
/// <see cref="MessageService.ShowWarning(string, string)"/>
/// </summary>
/// <param name="message"></param>
public static void ShowWarning(string message)
{
ShowWarning(message, DefaultWarningCaption);
}
/// <summary>
/// Shows a warning to the user
/// </summary>
/// <param name="message"></param>
/// <param name="caption"></param>
public static void ShowWarning(string message, string caption)
{
LogService.LogService.LogWarning(message);
Instance.Show(LogCategory.Warning, message, caption);
}
#endregion
#region ShowError
/// <summary>
/// Shows an error to the user.
/// </summary>
/// <param name="ex"></param>
/// <param name="message"></param>
public static void ShowError(Exception ex, string message)
{
ShowError(ex, message, false);
}
/// <summary>
/// Shows an error message to the user with a custom caption.
/// </summary>
/// <param name="ex"></param>
/// <param name="message"></param>
/// <param name="caption"></param>
public static void ShowError(Exception ex, string message, string caption)
{
ShowError(ex, message, caption, false);
}
/// <summary>
/// <see cref="MessageService.ShowError(Exception, string)"/>
/// </summary>
/// <param name="ex"></param>
public static void ShowError(Exception ex)
{
ShowError(ex, null);
}
public static void ShowError(string message, LoggingContext context)
{
ShowLoggingErrorImpl(message, context.Errors);
}
/// <summary>
/// <see cref="MessageService.ShowError(Exception, string)"/>
/// </summary>
/// <param name="message"></param>
public static void ShowError(string message)
{
ShowError((Exception)null, message);
}
public static void ShowError(string message, string caption)
{
ShowError(null, message, caption);
}
/// <summary>
/// <see cref="MessageService.ShowError(Exception, string)"/>
/// </summary>
/// <param name="format"></param>
/// <param name="formatItems"></param>
public static void ShowErrorFormatted(string format, params object[] formatItems)
{
ShowError((Exception)null, Format(format, formatItems));
}
/// <summary>
/// <see cref="MessageService.ShowError(Exception, string)"/>
/// </summary>
/// <param name="ex"></param>
/// <param name="message"></param>
/// <param name="forceSilent"></param>
public static void ShowError(Exception ex, string message, bool forceSilent /* = false */)
{
ShowErrorImpl(ex, message, DefaultErrorCaption, forceSilent, false);
}
/// <summary>
/// <see cref="MessageService.ShowError(Exception, string)"/>
/// </summary>
/// <param name="ex"></param>
/// <param name="message"></param>
/// <param name="caption"></param>
/// <param name="forceSilent"></param>
public static void ShowError(Exception ex, string message, string caption, bool forceSilent /* = false */)
{
ShowErrorImpl(ex, message, caption, forceSilent, false);
}
/// <summary>
/// Shows an error to the user.
/// </summary>
/// <param name="ex"></param>
/// <param name="message"></param>
/// <param name="caption"></param>
/// <param name="forceSilent"></param>
/// <param name="isUnhandled"></param>
private static void ShowErrorImpl(Exception ex, string message, string caption, bool forceSilent /* = false */, bool isUnhandled)
{
if (ex != null)
{
LogService.LogService.LogError(message + ": " + ex);
if (CustomErrorReporter != null && isUnhandled)
{
CustomErrorReporter(ex, message);
return;
}
}
else
{
LogService.LogService.LogError(message);
}
if (forceSilent)
{
return;
}
string msg = string.Empty;
if (message != null)
{
msg += message;
}
if (message != null && ex != null)
{
msg += "\n\n";
}
if (ex != null)
{
msg += "Exception occurred: " + ex;
}
Instance.Show(LogCategory.Error, msg, caption);
}
private static void ShowLoggingErrorImpl(string message, IEnumerable<Error> errors)
{
ShowErrorFormatted("{0}\n{1}", message, errors.Join("\n", error => error.Message));
}
#endregion
#region AskQuestion
/// <summary>
/// Asks a Yes/No question to the user.
/// </summary>
/// <param name="question"></param>
/// <param name="caption"></param>
/// <returns></returns>
public static bool AskQuestion(string question, string caption)
{
return AskQuestion(question, caption, MessageBoxImage.Question);
}
/// <summary>
/// Asks a Yes/No question to the user.
/// </summary>
/// <param name="question"></param>
/// <param name="caption"></param>
/// <param name="icon"></param>
/// <returns></returns>
public static bool AskQuestion(string question, string caption, MessageBoxImage icon)
{
return AskQuestion(question, caption, icon, true);
}
/// <summary>
/// Asks a Yes/No question to the user.
/// </summary>
/// <param name="question"></param>
/// <param name="caption"></param>
/// <param name="icon"></param>
/// <param name="defaultAnswer"></param>
/// <returns></returns>
public static bool AskQuestion(string question, string caption, MessageBoxImage icon, bool defaultAnswer)
{
return Instance.AskQuestion(question, caption, icon, MessageBoxButton.YesNo, defaultAnswer ? MessageBoxResult.Yes : MessageBoxResult.No) == MessageBoxResult.Yes;
}
/// <summary>
/// Asks a Yes/No/Cancel question to the user.
/// </summary>
public static MessageBoxResult AskQuestionYesNoCancel(string question, string caption, MessageBoxImage icon)
{
return AskQuestion(question, caption, icon, MessageBoxButton.YesNoCancel);
}
/// <summary>
/// Asks a Yes/No/Cancel question to the user.
/// </summary>
public static MessageBoxResult AskQuestion(string question, string caption, MessageBoxImage icon, MessageBoxButton buttons)
{
return Instance.AskQuestion(question, caption, icon, buttons, MessageBoxResult.Cancel);
}
/// <summary>
/// <see cref="MessageService.AskQuestion(string, string)"/>
/// </summary>
/// <param name="format"></param>
/// <param name="formatItems"></param>
/// <returns></returns>
public static bool AskQuestionFormatted(string format, params object[] formatItems)
{
return AskQuestion(Format(format, formatItems));
}
/// <summary>
/// <see cref="MessageService.AskQuestion(string, string)"/>
/// </summary>
/// <param name="question"></param>
/// <returns></returns>
public static bool AskQuestion(string question)
{
return AskQuestion(question, "Question");
}
#endregion
#region ShowCustomDialog
#endregion
#region ShowBalloon
/// <summary>
/// Shows a balloon in tray icon closing after the timeout expired.
/// </summary>
/// <param name="timeout">The duration before the balloon closes and hides.</param>
/// <param name="title">The bold title in the header.</param>
/// <param name="text">The content of the balloon.</param>
/// <param name="icon">Type of balloon.</param>
public static IBalloon ShowBalloon(TimeSpan timeout, string title, string text, ToolTipIcon icon)
{
return Instance.ShowBalloon(timeout, title, text, icon, null);
}
/// <summary>
/// Shows a balloon in tray icon closing after the timeout expired.
/// </summary>
/// <param name="timeout">The duration before the balloon closes and hides.</param>
/// <param name="title">The bold title in the header.</param>
/// <param name="text">The content of the balloon.</param>
/// <param name="icon">Type of balloon.</param>
/// <param name="clickHandler">An action to execute when clicking the balloon.</param>
public static IBalloon ShowBalloon(TimeSpan timeout, string title, string text, ToolTipIcon icon, Action clickHandler)
{
return Instance.ShowBalloon(timeout, title, text, icon, clickHandler);
}
#endregion
#region ShowInput
/// <summary>
/// <see cref="MessageService.ShowInputBox(string, string, string, ValidationPredicate)"/>
/// </summary>
/// <param name="question"></param>
/// <param name="caption"></param>
/// <returns></returns>
public static string ShowInputBox(string question, string caption)
{
return ShowInputBox(question, caption, string.Empty, null);
}
/// <summary>
/// <see cref="MessageService.ShowInputBox(string, string, string, ValidationPredicate)"/>
/// </summary>
/// <param name="question"></param>
/// <param name="caption"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static string ShowInputBox(string question, string caption, string defaultValue)
{
return ShowInputBox(question, caption, defaultValue, null);
}
/// <summary>
/// Show a input box.
/// </summary>
/// <param name="question">Question asked.</param>
/// <param name="caption">Title of the input box.</param>
/// <param name="defaultValue">Default value in the input box.</param>
/// <param name="validationPredicate">Predicate used to validate the user input.</param>
/// <returns>Value enter by user.</returns>
public static string ShowInputBox(string question, string caption, string defaultValue, ValidationPredicate validationPredicate)
{
ThrowIfCommandLineMode();
return Instance.ShowInputBox(question, caption, defaultValue, validationPredicate);
}
#endregion
#region Helper Methods
private static string Format(string formatString, object[] formatItems)
{
return string.Format(CultureInfo.CurrentCulture, formatString, formatItems);
}
private static void ThrowIfCommandLineMode()
{
Throw.InvalidOperationIf(IsCommandLine, "Cannot use this method in command-line mode.");
}
#endregion
#endregion
}
}