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 { /// /// Helper class used to display advanced Message Boxes and other forms of user interaction. /// /// /// 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. /// public static class MessageService { #region Inner Types /// /// Delegate that represents a method that shows a given error. /// /// Thrown Exception /// An optional message internal delegate void ShowErrorDelegate(Exception ex, string message); /// /// 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. /// /// Candidate to test. /// Null if the validation passes, an error string to display otherwise. 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; } } /// /// 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). /// 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 /// /// Shows a message box. /// /// /// Returns which button was clicked public static void ShowMessage(string message) { ShowMessage(message, DefaultMessageCaption); } /// /// /// /// /// /// Returns which button was clicked public static void ShowMessage(string message, string caption) { LogService.LogService.LogMessage(message); Instance.Show(LogCategory.Message, message, caption); } #endregion #region ShowWarning /// /// /// /// public static void ShowWarning(string message) { ShowWarning(message, DefaultWarningCaption); } /// /// Shows a warning to the user /// /// /// public static void ShowWarning(string message, string caption) { LogService.LogService.LogWarning(message); Instance.Show(LogCategory.Warning, message, caption); } #endregion #region ShowError /// /// Shows an error to the user. /// /// /// public static void ShowError(Exception ex, string message) { ShowError(ex, message, false); } /// /// Shows an error message to the user with a custom caption. /// /// /// /// public static void ShowError(Exception ex, string message, string caption) { ShowError(ex, message, caption, false); } /// /// /// /// public static void ShowError(Exception ex) { ShowError(ex, null); } public static void ShowError(string message, LoggingContext context) { ShowLoggingErrorImpl(message, context.Errors); } /// /// /// /// public static void ShowError(string message) { ShowError((Exception)null, message); } public static void ShowError(string message, string caption) { ShowError(null, message, caption); } /// /// /// /// /// public static void ShowErrorFormatted(string format, params object[] formatItems) { ShowError((Exception)null, Format(format, formatItems)); } /// /// /// /// /// /// public static void ShowError(Exception ex, string message, bool forceSilent /* = false */) { ShowErrorImpl(ex, message, DefaultErrorCaption, forceSilent, false); } /// /// /// /// /// /// /// public static void ShowError(Exception ex, string message, string caption, bool forceSilent /* = false */) { ShowErrorImpl(ex, message, caption, forceSilent, false); } /// /// Shows an error to the user. /// /// /// /// /// /// 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 errors) { ShowErrorFormatted("{0}\n{1}", message, errors.Join("\n", error => error.Message)); } #endregion #region AskQuestion /// /// Asks a Yes/No question to the user. /// /// /// /// public static bool AskQuestion(string question, string caption) { return AskQuestion(question, caption, MessageBoxImage.Question); } /// /// Asks a Yes/No question to the user. /// /// /// /// /// public static bool AskQuestion(string question, string caption, MessageBoxImage icon) { return AskQuestion(question, caption, icon, true); } /// /// Asks a Yes/No question to the user. /// /// /// /// /// /// 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; } /// /// Asks a Yes/No/Cancel question to the user. /// public static MessageBoxResult AskQuestionYesNoCancel(string question, string caption, MessageBoxImage icon) { return AskQuestion(question, caption, icon, MessageBoxButton.YesNoCancel); } /// /// Asks a Yes/No/Cancel question to the user. /// public static MessageBoxResult AskQuestion(string question, string caption, MessageBoxImage icon, MessageBoxButton buttons) { return Instance.AskQuestion(question, caption, icon, buttons, MessageBoxResult.Cancel); } /// /// /// /// /// /// public static bool AskQuestionFormatted(string format, params object[] formatItems) { return AskQuestion(Format(format, formatItems)); } /// /// /// /// /// public static bool AskQuestion(string question) { return AskQuestion(question, "Question"); } #endregion #region ShowCustomDialog #endregion #region ShowBalloon /// /// Shows a balloon in tray icon closing after the timeout expired. /// /// The duration before the balloon closes and hides. /// The bold title in the header. /// The content of the balloon. /// Type of balloon. public static IBalloon ShowBalloon(TimeSpan timeout, string title, string text, ToolTipIcon icon) { return Instance.ShowBalloon(timeout, title, text, icon, null); } /// /// Shows a balloon in tray icon closing after the timeout expired. /// /// The duration before the balloon closes and hides. /// The bold title in the header. /// The content of the balloon. /// Type of balloon. /// An action to execute when clicking the balloon. 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 /// /// /// /// /// /// public static string ShowInputBox(string question, string caption) { return ShowInputBox(question, caption, string.Empty, null); } /// /// /// /// /// /// /// public static string ShowInputBox(string question, string caption, string defaultValue) { return ShowInputBox(question, caption, defaultValue, null); } /// /// Show a input box. /// /// Question asked. /// Title of the input box. /// Default value in the input box. /// Predicate used to validate the user input. /// Value enter by user. 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 } }