kopano-ol-extension/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs

302 lines
10 KiB
C#
Raw Normal View History

2016-12-21 12:53:16 +01:00
/// Copyright 2016 Kopano b.v.
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License, version 3,
/// as published by the Free Software Foundation.
///
/// 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 Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program.If not, see<http://www.gnu.org/licenses/>.
///
/// Consult LICENSE file for details
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
namespace Acacia.Utils
{
/// <summary>
/// Handles registration for events on mail items. To register for these, each individual MailItem must be registered,
/// which can be done in the Application.ItemLoad event. This class hides that implementation and also ensures the
/// event registrations are removed when the item is unloaded, to prevent resource leaks.
/// </summary>
/// TODO: this name is now wrong
public class MailEvents
{
#region Events
public delegate void MailEventHandler(IMailItem mail);
public delegate void MailResponseEventHandler(IMailItem mail, IMailItem response);
public delegate void ItemEventHandler(IItem item);
public delegate void CancellableItemEventHandler(IItem item, ref bool cancel);
public delegate void CancellableMailItemEventHandler(IMailItem item, ref bool cancel);
/// <summary>
/// Hooks into Reply(All) and Forward events
/// </summary>
public event MailResponseEventHandler Respond;
public event MailResponseEventHandler Reply;
2017-02-13 14:02:37 +01:00
private void OnReply(IMailItem mail, IMailItem response)
2016-12-21 12:53:16 +01:00
{
2017-02-08 15:40:48 +01:00
// TODO: check release of first item
// TODO: release if not sending event
2016-12-21 12:53:16 +01:00
try
{
2017-02-13 14:02:37 +01:00
if ((Reply != null || Respond != null) && mail != null && response != null)
2016-12-21 12:53:16 +01:00
{
2017-02-13 14:02:37 +01:00
if (Reply != null)
Reply(mail, response);
if (Respond != null)
Respond(mail, response);
2016-12-21 12:53:16 +01:00
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "OnReply: {0}", e);
}
}
public event MailResponseEventHandler ReplyAll;
2017-02-13 14:02:37 +01:00
private void OnReplyAll(IMailItem mail, IMailItem response)
2016-12-21 12:53:16 +01:00
{
2017-02-08 15:40:48 +01:00
// TODO: check release of first item
// TODO: release if not sending event
2016-12-21 12:53:16 +01:00
try
{
2017-02-13 14:02:37 +01:00
if ((ReplyAll != null || Respond != null) && mail != null && response != null)
2016-12-21 12:53:16 +01:00
{
2017-02-13 14:02:37 +01:00
if (ReplyAll != null)
ReplyAll(mail, response);
if (Respond != null)
Respond(mail, response);
2016-12-21 12:53:16 +01:00
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "OnReplyAll: {0}", e);
}
}
public event MailResponseEventHandler Forward;
2017-02-13 14:02:37 +01:00
private void OnForward(IMailItem mail, IMailItem response)
2016-12-21 12:53:16 +01:00
{
2017-02-08 15:40:48 +01:00
// TODO: check release of first item
// TODO: release if not sending event
2016-12-21 12:53:16 +01:00
try
{
2017-02-13 14:02:37 +01:00
if ((Forward != null || Respond != null) && mail != null && response != null)
2016-12-21 12:53:16 +01:00
{
2017-02-13 14:02:37 +01:00
if (Forward != null)
Forward(mail, response);
if (Respond != null)
Respond(mail, response);
2016-12-21 12:53:16 +01:00
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "OnForward: {0}", e);
}
}
public event MailEventHandler Read;
2017-02-13 14:02:37 +01:00
private void OnRead(IMailItem mail)
2016-12-21 12:53:16 +01:00
{
try
{
if (Read != null && mail != null)
{
2017-02-13 14:02:37 +01:00
Read(mail);
2016-12-21 12:53:16 +01:00
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "OnRead: {0}", e);
}
}
public event CancellableItemEventHandler BeforeDelete;
2017-02-13 14:02:37 +01:00
private void OnBeforeDelete(IItem item, ref bool cancel)
2016-12-21 12:53:16 +01:00
{
try
{
if (BeforeDelete != null && item != null)
{
2017-02-13 14:02:37 +01:00
BeforeDelete(item, ref cancel);
2016-12-21 12:53:16 +01:00
}
}
catch(System.Exception e)
{
Logger.Instance.Error(this, "OnBeforeDelete: {0}", e);
}
}
// TODO: should this be CancellableMailItemEventHandler?
public event CancellableItemEventHandler Write;
2017-02-13 14:02:37 +01:00
private void OnWrite(IItem item, ref bool cancel)
2016-12-21 12:53:16 +01:00
{
try
{
if (Write != null && item != null)
{
2017-02-13 14:02:37 +01:00
Write(item, ref cancel);
2016-12-21 12:53:16 +01:00
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "OnWrite: {0}", e);
}
}
public event CancellableMailItemEventHandler ItemSend;
private void OnItemSend(object item, ref bool cancel)
{
try
{
2017-02-08 15:40:48 +01:00
// TODO: release item if event not sent
2016-12-21 12:53:16 +01:00
if (ItemSend != null && item != null)
{
using (IMailItem wrapped = Mapping.WrapOrDefault<IMailItem>(item, false))
{
if (wrapped != null)
ItemSend(wrapped, ref cancel);
}
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "OnItemSend: {0}", e);
}
}
#endregion
#region Implementation
2017-02-08 15:40:48 +01:00
public MailEvents(IAddIn app)
2016-12-21 12:53:16 +01:00
{
app.ItemLoad += OnItemLoad;
app.ItemSend += OnItemSend;
}
2017-02-08 15:40:48 +01:00
private void OnItemLoad(object item)
2016-12-21 12:53:16 +01:00
{
2017-02-13 14:02:37 +01:00
IItem wrapped = Wrappers.Wrap<IItem>(item);
// TODO: check type
if (wrapped != null)
2017-02-13 13:03:37 +01:00
{
2017-02-13 14:02:37 +01:00
new MailEventHooker(wrapped, this);
2017-02-13 13:03:37 +01:00
}
2016-12-21 12:53:16 +01:00
}
2017-02-13 14:02:37 +01:00
private class MailEventHooker : DisposableWrapper
2016-12-21 12:53:16 +01:00
{
2017-02-13 14:02:37 +01:00
private IItem _item;
2017-02-08 15:40:48 +01:00
private readonly MailEvents _events;
// TODO: remove id and debug logging
2017-02-08 15:40:48 +01:00
private int _id;
private static int nextId;
2016-12-21 12:53:16 +01:00
2017-02-13 14:02:37 +01:00
public MailEventHooker(IItem item, MailEvents events)
2016-12-21 12:53:16 +01:00
{
2017-02-13 14:02:37 +01:00
this._item = item;
this._id = ++nextId;
2017-02-08 15:40:48 +01:00
this._events = events;
2016-12-21 12:53:16 +01:00
HookEvents(true);
}
2017-02-13 14:02:37 +01:00
/*~MailEventHooker()
2017-02-13 13:03:37 +01:00
{
}
2017-02-13 14:02:37 +01:00
*/
2017-02-13 13:03:37 +01:00
2017-02-08 15:40:48 +01:00
protected override void DoRelease()
2016-12-21 12:53:16 +01:00
{
2017-02-08 15:40:48 +01:00
Logger.Instance.Debug(this, "DoRelease: {0}", _id);
// TODO: It looks like release _itemEvents is not only not needed, but causes exceptions.
// If that is really the case, this doesn't need to be a ComWrapper
2017-02-13 14:02:37 +01:00
_item.Dispose();
2017-02-08 15:40:48 +01:00
}
2016-12-21 12:53:16 +01:00
2017-02-08 15:40:48 +01:00
private void HookEvents(bool add)
{
2016-12-21 12:53:16 +01:00
if (add)
{
2017-02-13 14:02:37 +01:00
_item.Events.BeforeDelete += HandleBeforeDelete;
_item.Events.Forward += HandleForward;
_item.Events.Read += HandleRead;
_item.Events.Reply += HandleReply;
_item.Events.ReplyAll += HandleReplyAll;
_item.Events.Unload += HandleUnload;
_item.Events.Write += HandleWrite;
2016-12-21 12:53:16 +01:00
}
else
{
2017-02-13 14:02:37 +01:00
_item.Events.BeforeDelete -= HandleBeforeDelete;
_item.Events.Forward -= HandleForward;
_item.Events.Read -= HandleRead;
_item.Events.Reply -= HandleReply;
_item.Events.ReplyAll -= HandleReplyAll;
_item.Events.Unload -= HandleUnload;
_item.Events.Write -= HandleWrite;
2016-12-21 12:53:16 +01:00
}
}
private void HandleBeforeDelete(object item, ref bool cancel)
{
Logger.Instance.Debug(this, "HandleBeforeDelete: {0}", _id);
2017-02-13 14:02:37 +01:00
_events.OnBeforeDelete(item.WrapOrDefault<IItem>(), ref cancel);
2016-12-21 12:53:16 +01:00
}
private void HandleForward(object response, ref bool cancel)
{
Logger.Instance.Debug(this, "HandleForward: {0}", _id);
2017-02-13 14:02:37 +01:00
_events.OnForward(_item as IMailItem, response.WrapOrDefault<IMailItem>());
2016-12-21 12:53:16 +01:00
}
private void HandleRead()
{
Logger.Instance.Debug(this, "HandleRead: {0}", _id);
2017-02-13 14:02:37 +01:00
_events.OnRead(_item as IMailItem);
2016-12-21 12:53:16 +01:00
}
private void HandleReply(object response, ref bool cancel)
{
Logger.Instance.Debug(this, "HandleReply: {0}", _id);
2017-02-13 14:02:37 +01:00
_events.OnReply(_item as IMailItem, response.WrapOrDefault<IMailItem>());
2016-12-21 12:53:16 +01:00
}
private void HandleReplyAll(object response, ref bool cancel)
{
Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id);
2017-02-13 14:02:37 +01:00
_events.OnReplyAll(_item as IMailItem, response.WrapOrDefault<IMailItem>());
2016-12-21 12:53:16 +01:00
}
private void HandleUnload()
{
2017-02-08 15:40:48 +01:00
Logger.Instance.Debug(this, "HandleUnload: {0}", _id);
2016-12-21 12:53:16 +01:00
// All events must be unhooked on unload, otherwise a resource leak is created.
2017-02-13 14:02:37 +01:00
HookEvents(false);
Dispose();
2016-12-21 12:53:16 +01:00
}
private void HandleWrite(ref bool cancel)
{
2017-02-08 15:40:48 +01:00
Logger.Instance.Debug(this, "HandleWrite: {0}", _id);
_events.OnWrite(_item, ref cancel);
2016-12-21 12:53:16 +01:00
}
}
#endregion
}
}