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;
|
2017-02-08 15:40:48 +01:00
|
|
|
|
using NSOutlook = Microsoft.Office.Interop.Outlook;
|
2016-12-21 12:53:16 +01:00
|
|
|
|
|
|
|
|
|
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-08 15:40:48 +01:00
|
|
|
|
private void OnReply(NSOutlook.MailItem mail, NSOutlook.MailItem 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
|
|
|
|
|
{
|
|
|
|
|
if ((Reply != null || Respond != null) && mail != null)
|
|
|
|
|
{
|
|
|
|
|
using (IMailItem mailWrapped = Mapping.Wrap<IMailItem>(mail, false),
|
|
|
|
|
responseWrapped = Mapping.Wrap<IMailItem>(response))
|
|
|
|
|
{
|
|
|
|
|
if (Reply != null)
|
|
|
|
|
Reply(mailWrapped, responseWrapped);
|
|
|
|
|
if (Respond != null)
|
|
|
|
|
Respond(mailWrapped, responseWrapped);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Error(this, "OnReply: {0}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public event MailResponseEventHandler ReplyAll;
|
2017-02-08 15:40:48 +01:00
|
|
|
|
private void OnReplyAll(NSOutlook.MailItem mail, NSOutlook.MailItem 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
|
|
|
|
|
{
|
|
|
|
|
if ((ReplyAll != null || Respond != null) && mail != null)
|
|
|
|
|
{
|
|
|
|
|
using (IMailItem mailWrapped = Mapping.Wrap<IMailItem>(mail, false),
|
|
|
|
|
responseWrapped = Mapping.Wrap<IMailItem>(response))
|
|
|
|
|
{
|
|
|
|
|
if (ReplyAll != null)
|
|
|
|
|
ReplyAll(mailWrapped, responseWrapped);
|
|
|
|
|
if (Respond != null)
|
|
|
|
|
Respond(mailWrapped, responseWrapped);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Error(this, "OnReplyAll: {0}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public event MailResponseEventHandler Forward;
|
2017-02-08 15:40:48 +01:00
|
|
|
|
private void OnForward(NSOutlook.MailItem mail, NSOutlook.MailItem 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
|
|
|
|
|
{
|
|
|
|
|
if ((Forward != null || Respond != null) && mail != null)
|
|
|
|
|
{
|
|
|
|
|
using (IMailItem mailWrapped = Mapping.Wrap<IMailItem>(mail, false),
|
|
|
|
|
responseWrapped = Mapping.Wrap<IMailItem>(response))
|
|
|
|
|
{
|
|
|
|
|
if (Forward != null)
|
|
|
|
|
Forward(mailWrapped, responseWrapped);
|
|
|
|
|
if (Respond != null)
|
|
|
|
|
Respond(mailWrapped, responseWrapped);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Error(this, "OnForward: {0}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public event MailEventHandler Read;
|
2017-02-08 15:40:48 +01:00
|
|
|
|
private void OnRead(NSOutlook.MailItem mail)
|
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
|
|
|
|
|
{
|
|
|
|
|
if (Read != null && mail != null)
|
|
|
|
|
{
|
|
|
|
|
using (IMailItem wrapped = Mapping.Wrap<IMailItem>(mail, false))
|
|
|
|
|
{
|
|
|
|
|
Read(wrapped);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Error(this, "OnRead: {0}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public event CancellableItemEventHandler BeforeDelete;
|
|
|
|
|
private void OnBeforeDelete(object item, ref bool cancel)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (BeforeDelete != null && item != null)
|
|
|
|
|
{
|
|
|
|
|
using (IItem wrapped = Mapping.Wrap<IItem>(item, false))
|
|
|
|
|
{
|
|
|
|
|
if (wrapped != null)
|
|
|
|
|
BeforeDelete(wrapped, ref cancel);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(System.Exception e)
|
|
|
|
|
{
|
|
|
|
|
Logger.Instance.Error(this, "OnBeforeDelete: {0}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: should this be CancellableMailItemEventHandler?
|
|
|
|
|
public event CancellableItemEventHandler Write;
|
|
|
|
|
private void OnWrite(object item, ref bool cancel)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (Write != null && item != null)
|
|
|
|
|
{
|
|
|
|
|
using (IItem wrapped = Mapping.Wrap<IItem>(item, false))
|
|
|
|
|
{
|
|
|
|
|
if (wrapped != null)
|
|
|
|
|
Write(wrapped, ref cancel);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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 13:03:37 +01:00
|
|
|
|
using (IItem wrapped = Wrappers.Wrap<IItem>(item))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2017-02-08 15:40:48 +01:00
|
|
|
|
NSOutlook.ItemEvents_10_Event hasEvents = item as NSOutlook.ItemEvents_10_Event;
|
2016-12-21 12:53:16 +01:00
|
|
|
|
if (hasEvents != null)
|
|
|
|
|
{
|
2017-02-09 12:20:06 +01:00
|
|
|
|
new MailEventHooker(hasEvents, this);
|
2017-02-13 13:03:37 +01:00
|
|
|
|
}*/
|
2016-12-21 12:53:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-10 11:15:58 +01:00
|
|
|
|
private class MailEventHooker : ComWrapper<NSOutlook.ItemEvents_10_Event>
|
2016-12-21 12:53:16 +01:00
|
|
|
|
{
|
2017-02-08 15:40:48 +01:00
|
|
|
|
private readonly MailEvents _events;
|
2017-02-08 16:03:43 +01:00
|
|
|
|
// 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-10 11:15:58 +01:00
|
|
|
|
public MailEventHooker(NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events) : base(itemEvents)
|
2016-12-21 12:53:16 +01:00
|
|
|
|
{
|
2017-02-09 12:20:06 +01:00
|
|
|
|
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 13:03:37 +01:00
|
|
|
|
~MailEventHooker()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
2017-02-09 12:20:06 +01:00
|
|
|
|
// 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-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-10 11:15:58 +01:00
|
|
|
|
_item.BeforeDelete += HandleBeforeDelete;
|
|
|
|
|
_item.Forward += HandleForward;
|
|
|
|
|
_item.Read += HandleRead;
|
|
|
|
|
_item.Reply += HandleReply;
|
|
|
|
|
_item.ReplyAll += HandleReplyAll;
|
|
|
|
|
_item.Unload += HandleUnload;
|
|
|
|
|
_item.Write += HandleWrite;
|
2016-12-21 12:53:16 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2017-02-10 11:15:58 +01:00
|
|
|
|
_item.BeforeDelete -= HandleBeforeDelete;
|
|
|
|
|
_item.Forward -= HandleForward;
|
|
|
|
|
_item.Read -= HandleRead;
|
|
|
|
|
_item.Reply -= HandleReply;
|
|
|
|
|
_item.ReplyAll -= HandleReplyAll;
|
|
|
|
|
_item.Unload -= HandleUnload;
|
|
|
|
|
_item.Write -= HandleWrite;
|
2016-12-21 12:53:16 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleBeforeDelete(object item, ref bool cancel)
|
|
|
|
|
{
|
2017-02-08 16:03:43 +01:00
|
|
|
|
Logger.Instance.Debug(this, "HandleBeforeDelete: {0}", _id);
|
2017-02-08 15:40:48 +01:00
|
|
|
|
_events.OnBeforeDelete(item, ref cancel);
|
2016-12-21 12:53:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleForward(object response, ref bool cancel)
|
|
|
|
|
{
|
2017-02-08 16:03:43 +01:00
|
|
|
|
Logger.Instance.Debug(this, "HandleForward: {0}", _id);
|
2017-02-10 11:15:58 +01:00
|
|
|
|
_events.OnForward(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
2016-12-21 12:53:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleRead()
|
|
|
|
|
{
|
2017-02-08 16:03:43 +01:00
|
|
|
|
Logger.Instance.Debug(this, "HandleRead: {0}", _id);
|
2017-02-10 11:15:58 +01:00
|
|
|
|
_events.OnRead(_item as NSOutlook.MailItem);
|
2016-12-21 12:53:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleReply(object response, ref bool cancel)
|
|
|
|
|
{
|
2017-02-08 16:03:43 +01:00
|
|
|
|
Logger.Instance.Debug(this, "HandleReply: {0}", _id);
|
2017-02-10 11:15:58 +01:00
|
|
|
|
_events.OnReply(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
2016-12-21 12:53:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleReplyAll(object response, ref bool cancel)
|
|
|
|
|
{
|
2017-02-08 16:03:43 +01:00
|
|
|
|
Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id);
|
2017-02-10 11:15:58 +01:00
|
|
|
|
_events.OnReplyAll(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
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 13:03: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);
|
2017-02-10 11:15:58 +01:00
|
|
|
|
_events.OnWrite(_item, ref cancel);
|
2016-12-21 12:53:16 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|