keepass2android/src/KeePassLib2Android/Utility/MessageService.cs

456 lines
13 KiB
C#

/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Diagnostics;
using KeePassLib.Resources;
using KeePassLib.Serialization;
namespace KeePassLib.Utility
{
public enum MessageBoxButtons
{
OK, OKCancel, AbortRetryIgnore, YesNoCancel, YesNo, RetryCancel
}
public enum MessageBoxIcon
{
Information, Warning, Error, Question
}
public enum MessageBoxDefaultButton
{
Button1, Button2, Button3
}
public enum DialogResult
{
Yes, No, Cancel, Retry, Abort
}
public sealed class MessageServiceEventArgs : EventArgs
{
private string m_strTitle = string.Empty;
private string m_strText = string.Empty;
//private MessageBoxButtons m_msgButtons = MessageBoxButtons.OK;
//private MessageBoxIcon m_msgIcon = MessageBoxIcon.None;
public string Title { get { return m_strTitle; } }
public string Text { get { return m_strText; } }
//public MessageBoxButtons Buttons { get { return m_msgButtons; } }
//public MessageBoxIcon Icon { get { return m_msgIcon; } }
public MessageServiceEventArgs() { }
public MessageServiceEventArgs(string strTitle, string strText,
MessageBoxButtons msgButtons, MessageBoxIcon msgIcon)
{
m_strTitle = (strTitle ?? string.Empty);
m_strText = (strText ?? string.Empty);
}
}
public static class MessageService
{
private static volatile uint m_uCurrentMessageCount = 0;
#if !KeePassLibSD
private const MessageBoxIcon m_mbiInfo = MessageBoxIcon.Information;
private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Warning;
private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Error;
#else
private const MessageBoxIcon m_mbiInfo = MessageBoxIcon.Asterisk;
private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Exclamation;
private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Hand;
#endif
//private const MessageBoxIcon m_mbiQuestion = MessageBoxIcon.Question;
public static string NewLine
{
#if !KeePassLibSD
get { return Environment.NewLine; }
#else
get { return "\r\n"; }
#endif
}
public static string NewParagraph
{
#if !KeePassLibSD
get { return Environment.NewLine + Environment.NewLine; }
#else
get { return "\r\n\r\n"; }
#endif
}
public static uint CurrentMessageCount
{
get { return m_uCurrentMessageCount; }
}
public static event EventHandler<MessageServiceEventArgs> MessageShowing;
private static string ObjectsToMessage(object[] vLines)
{
return ObjectsToMessage(vLines, false);
}
private static string ObjectsToMessage(object[] vLines, bool bFullExceptions)
{
if(vLines == null) return string.Empty;
string strNewPara = MessageService.NewParagraph;
StringBuilder sbText = new StringBuilder();
bool bSeparator = false;
foreach(object obj in vLines)
{
if(obj == null) continue;
string strAppend = null;
Exception exObj = (obj as Exception);
string strObj = (obj as string);
#if !KeePassLibSD
StringCollection scObj = (obj as StringCollection);
#endif
if(exObj != null)
{
if(bFullExceptions)
strAppend = StrUtil.FormatException(exObj);
else if((exObj.Message != null) && (exObj.Message.Length > 0))
strAppend = exObj.Message;
}
#if !KeePassLibSD
else if(scObj != null)
{
StringBuilder sb = new StringBuilder();
foreach(string strCollLine in scObj)
{
if(sb.Length > 0) sb.AppendLine();
sb.Append(strCollLine.TrimEnd());
}
strAppend = sb.ToString();
}
#endif
else if(strObj != null)
strAppend = strObj;
else
strAppend = obj.ToString();
if(!string.IsNullOrEmpty(strAppend))
{
if(bSeparator) sbText.Append(strNewPara);
else bSeparator = true;
sbText.Append(strAppend);
}
}
return sbText.ToString();
}
#if !KeePassLibSD
/*internal static Form GetTopForm()
{
FormCollection fc = Application.OpenForms;
if((fc == null) || (fc.Count == 0)) return null;
return fc[fc.Count - 1];
}*/
#endif
private static DialogResult SafeShowMessageBox(string strText, string strTitle,
MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb)
{
#if KeePassLibSD
return MessageBox.Show(strText, strTitle, mb, mi, mdb);
#else
if (mb == MessageBoxButtons.OK)
{
//Android.Widget.Toast toast = ..
}
//this might help: http://www.gregshackles.com/2011/04/using-background-threads-in-mono-for-android-applications/
throw new NotImplementedException();
/*IWin32Window wnd = null;
try
{
Form f = GetTopForm();
if((f != null) && f.InvokeRequired)
return (DialogResult)f.Invoke(new SafeShowMessageBoxInternalDelegate(
SafeShowMessageBoxInternal), f, strText, strTitle, mb, mi, mdb);
else wnd = f;
}
catch(Exception) { Debug.Assert(false); }
if(wnd == null)
{
if(StrUtil.RightToLeft)
return MessageBox.Show(strText, strTitle, mb, mi, mdb, m_mboRtl);
return MessageBox.Show(strText, strTitle, mb, mi, mdb);
}
try
{
if(StrUtil.RightToLeft)
return MessageBox.Show(wnd, strText, strTitle, mb, mi, mdb, m_mboRtl);
return MessageBox.Show(wnd, strText, strTitle, mb, mi, mdb);
}
catch(Exception) { Debug.Assert(false); }
if(StrUtil.RightToLeft)
return MessageBox.Show(strText, strTitle, mb, mi, mdb, m_mboRtl);
return MessageBox.Show(strText, strTitle, mb, mi, mdb);
*/
#endif
}
#if !KeePassLibSD
/* internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent,
string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi,
MessageBoxDefaultButton mdb);
internal static DialogResult SafeShowMessageBoxInternal(IWin32Window iParent,
string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi,
MessageBoxDefaultButton mdb)
{
if(StrUtil.RightToLeft)
return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb, m_mboRtl);
return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb);
}*/
#endif
public static void ShowInfo(params object[] vLines)
{
ShowInfoEx(null, vLines);
}
public static void ShowInfoEx(string strTitle, params object[] vLines)
{
++m_uCurrentMessageCount;
strTitle = (strTitle ?? PwDefs.ShortProductName);
string strText = ObjectsToMessage(vLines);
if(MessageService.MessageShowing != null)
MessageService.MessageShowing(null, new MessageServiceEventArgs(
strTitle, strText, MessageBoxButtons.OK, m_mbiInfo));
SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiInfo,
MessageBoxDefaultButton.Button1);
--m_uCurrentMessageCount;
}
public static void ShowWarning(params object[] vLines)
{
ShowWarningPriv(vLines, false);
}
internal static void ShowWarningExcp(params object[] vLines)
{
ShowWarningPriv(vLines, true);
}
private static void ShowWarningPriv(object[] vLines, bool bFullExceptions)
{
++m_uCurrentMessageCount;
string strTitle = PwDefs.ShortProductName;
string strText = ObjectsToMessage(vLines, bFullExceptions);
if(MessageService.MessageShowing != null)
MessageService.MessageShowing(null, new MessageServiceEventArgs(
strTitle, strText, MessageBoxButtons.OK, m_mbiWarning));
SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiWarning,
MessageBoxDefaultButton.Button1);
--m_uCurrentMessageCount;
}
public static void ShowFatal(params object[] vLines)
{
++m_uCurrentMessageCount;
string strTitle = PwDefs.ShortProductName + @" - " + KLRes.FatalError;
string strText = KLRes.FatalErrorText + MessageService.NewParagraph +
KLRes.ErrorInClipboard + MessageService.NewParagraph +
// Please send it to the KeePass developers.
// KLRes.ErrorFeedbackRequest + MessageService.NewParagraph +
ObjectsToMessage(vLines);
try
{
#if !KeePassLibSD
/* nicht benoetigt - hoffentlich :-)
Clipboard.Clear();
Clipboard.SetText(ObjectsToMessage(vLines, true));*/
#else
Clipboard.SetDataObject(ObjectsToMessage(vLines, true));
#endif
}
catch(Exception) { Debug.Assert(false); }
if(MessageService.MessageShowing != null)
MessageService.MessageShowing(null, new MessageServiceEventArgs(
strTitle, strText, MessageBoxButtons.OK, m_mbiFatal));
SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiFatal,
MessageBoxDefaultButton.Button1);
--m_uCurrentMessageCount;
}
public static DialogResult Ask(string strText, string strTitle,
MessageBoxButtons mbb)
{
++m_uCurrentMessageCount;
string strTextEx = (strText ?? string.Empty);
string strTitleEx = (strTitle ?? PwDefs.ShortProductName);
if(MessageService.MessageShowing != null)
MessageService.MessageShowing(null, new MessageServiceEventArgs(
strTitleEx, strTextEx, mbb, MessageBoxIcon.Question));
DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx, mbb,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
--m_uCurrentMessageCount;
return dr;
}
public static bool AskYesNo(string strText, string strTitle, bool bDefaultToYes)
{
++m_uCurrentMessageCount;
string strTextEx = (strText ?? string.Empty);
string strTitleEx = (strTitle ?? PwDefs.ShortProductName);
if(MessageService.MessageShowing != null)
MessageService.MessageShowing(null, new MessageServiceEventArgs(
strTitleEx, strTextEx, MessageBoxButtons.YesNo, MessageBoxIcon.Question));
DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx,
MessageBoxButtons.YesNo, MessageBoxIcon.Question, bDefaultToYes ?
MessageBoxDefaultButton.Button1 : MessageBoxDefaultButton.Button2);
--m_uCurrentMessageCount;
return (dr == DialogResult.Yes);
}
public static bool AskYesNo(string strText, string strTitle)
{
return AskYesNo(strText, strTitle, true);
}
public static bool AskYesNo(string strText)
{
return AskYesNo(strText, null, true);
}
public static void ShowLoadWarning(string strFilePath, Exception ex)
{
ShowLoadWarning(strFilePath, ex, false);
}
public static void ShowLoadWarning(string strFilePath, Exception ex,
bool bFullException)
{
string str = string.Empty;
if((strFilePath != null) && (strFilePath.Length > 0))
str += strFilePath + MessageService.NewParagraph;
str += KLRes.FileLoadFailed;
if((ex != null) && (ex.Message != null) && (ex.Message.Length > 0))
{
str += MessageService.NewParagraph;
if(!bFullException) str += ex.Message;
else str += ObjectsToMessage(new object[] { ex }, true);
}
ShowWarning(str);
}
public static void ShowLoadWarning(IOConnectionInfo ioConnection, Exception ex)
{
if(ioConnection != null)
ShowLoadWarning(ioConnection.GetDisplayName(), ex, false);
else ShowWarning(ex);
}
public static void ShowSaveWarning(string strFilePath, Exception ex,
bool bCorruptionWarning)
{
FileLockException fl = (ex as FileLockException);
if(fl != null)
{
ShowWarning(fl.Message);
return;
}
string str = string.Empty;
if((strFilePath != null) && (strFilePath.Length > 0))
str += strFilePath + MessageService.NewParagraph;
str += KLRes.FileSaveFailed;
if((ex != null) && (ex.Message != null) && (ex.Message.Length > 0))
str += MessageService.NewParagraph + ex.Message;
if(bCorruptionWarning)
str += MessageService.NewParagraph + KLRes.FileSaveCorruptionWarning;
ShowWarning(str);
}
public static void ShowSaveWarning(IOConnectionInfo ioConnection, Exception ex,
bool bCorruptionWarning)
{
if(ioConnection != null)
ShowSaveWarning(ioConnection.GetDisplayName(), ex, bCorruptionWarning);
else ShowWarning(ex);
}
public static void ExternalIncrementMessageCount()
{
++m_uCurrentMessageCount;
}
public static void ExternalDecrementMessageCount()
{
--m_uCurrentMessageCount;
}
}
}