mirror of
				https://github.com/Kopano-dev/kopano-ol-extension.git
				synced 2023-10-10 11:37:40 +00:00 
			
		
		
		
	[KOE-65] Adding meeting UID as X-Push-Meeting-UID header in outgoing request.
This commit is contained in:
		@@ -244,6 +244,7 @@
 | 
				
			|||||||
    <Compile Include="Features\BCC\FeatureBCC.cs" />
 | 
					    <Compile Include="Features\BCC\FeatureBCC.cs" />
 | 
				
			||||||
    <Compile Include="Features\FreeBusy\FreeBusyServlet.cs" />
 | 
					    <Compile Include="Features\FreeBusy\FreeBusyServlet.cs" />
 | 
				
			||||||
    <Compile Include="Features\FreeBusy\Servlet.cs" />
 | 
					    <Compile Include="Features\FreeBusy\Servlet.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Features\MeetingRequest\FeatureMeetingRequest.cs" />
 | 
				
			||||||
    <Compile Include="Features\SecondaryContacts\FeatureSecondaryContacts.cs" />
 | 
					    <Compile Include="Features\SecondaryContacts\FeatureSecondaryContacts.cs" />
 | 
				
			||||||
    <Compile Include="Features\DebugSupport\AboutDialog.cs">
 | 
					    <Compile Include="Features\DebugSupport\AboutDialog.cs">
 | 
				
			||||||
      <SubType>Form</SubType>
 | 
					      <SubType>Form</SubType>
 | 
				
			||||||
@@ -303,6 +304,7 @@
 | 
				
			|||||||
    <Compile Include="Stubs\IAccount.cs" />
 | 
					    <Compile Include="Stubs\IAccount.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\IAddIn.cs" />
 | 
					    <Compile Include="Stubs\IAddIn.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\IAddressEntry.cs" />
 | 
					    <Compile Include="Stubs\IAddressEntry.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Stubs\IMeetingItem.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\ICommandBars.cs" />
 | 
					    <Compile Include="Stubs\ICommandBars.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\IComWrapper.cs" />
 | 
					    <Compile Include="Stubs\IComWrapper.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\IExplorer.cs" />
 | 
					    <Compile Include="Stubs\IExplorer.cs" />
 | 
				
			||||||
@@ -320,6 +322,7 @@
 | 
				
			|||||||
    <Compile Include="Stubs\OutlookWrappers\AccountWrapper.cs" />
 | 
					    <Compile Include="Stubs\OutlookWrappers\AccountWrapper.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\OutlookWrappers\AddInWrapper.cs" />
 | 
					    <Compile Include="Stubs\OutlookWrappers\AddInWrapper.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\OutlookWrappers\AddressEntryWrapper.cs" />
 | 
					    <Compile Include="Stubs\OutlookWrappers\AddressEntryWrapper.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Stubs\OutlookWrappers\MeetingItemWrapper.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\OutlookWrappers\CommandBarsWrapper.cs" />
 | 
					    <Compile Include="Stubs\OutlookWrappers\CommandBarsWrapper.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\OutlookWrappers\ExplorerWrapper.cs" />
 | 
					    <Compile Include="Stubs\OutlookWrappers\ExplorerWrapper.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\OutlookWrappers\FoldersWrapper.cs" />
 | 
					    <Compile Include="Stubs\OutlookWrappers\FoldersWrapper.cs" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,12 @@ namespace Acacia
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Meeting requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public const string ZPUSH_MEETING_UID = OutlookConstants.NS_TRANSPORT_MESSAGE_HEADERS + "X-Push-Meeting-UID";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region GAB
 | 
					        #region GAB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public const string ZPUSH_GAB_INDEX = "$PushIndex";
 | 
					        public const string ZPUSH_GAB_INDEX = "$PushIndex";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@ namespace Acacia.Features
 | 
				
			|||||||
            typeof(SecondaryContacts.FeatureSecondaryContacts),
 | 
					            typeof(SecondaryContacts.FeatureSecondaryContacts),
 | 
				
			||||||
            typeof(SendAs.FeatureSendAs),
 | 
					            typeof(SendAs.FeatureSendAs),
 | 
				
			||||||
            typeof(Signatures.FeatureSignatures),
 | 
					            typeof(Signatures.FeatureSignatures),
 | 
				
			||||||
 | 
					            typeof(MeetingRequest.FeatureMeetingRequest),
 | 
				
			||||||
            typeof(DebugSupport.FeatureDebugSupport)
 | 
					            typeof(DebugSupport.FeatureDebugSupport)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					/// Copyright 2017 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.Utils;
 | 
				
			||||||
 | 
					using Acacia.ZPush;
 | 
				
			||||||
 | 
					using Acacia.Features.SharedFolders;
 | 
				
			||||||
 | 
					using Acacia.ZPush.API.SharedFolders;
 | 
				
			||||||
 | 
					using static Acacia.DebugOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Features.MeetingRequest
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [AcaciaOption("Provides the ability to select different senders for Z-Push accounts.")]
 | 
				
			||||||
 | 
					    public class FeatureMeetingRequest : Feature
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public FeatureMeetingRequest()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override void Startup()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (MailEvents != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                MailEvents.ItemSend.Register<IMeetingItem>(Meeting_ItemSend);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private void Meeting_ItemSend(IMeetingItem item, ref bool cancel)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            byte[] uid = item.GlobalObjectId;
 | 
				
			||||||
 | 
					            item.SetProperty(Constants.ZPUSH_MEETING_UID, uid.BytesToHex());
 | 
				
			||||||
 | 
					            item.Save();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -51,7 +51,7 @@ namespace Acacia.Features.SendAs
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if (MailEvents != null)
 | 
					            if (MailEvents != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                MailEvents.ItemSend += MailEvents_ItemSend;
 | 
					                MailEvents.ItemSend.Register<IMailItem>(MailEvents_ItemSend);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (SendAsOwner)
 | 
					            if (SendAsOwner)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -114,6 +114,13 @@ namespace Acacia
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Meeting requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public const string PSETID_MEETING = GUID + "{6ED8DA90-450B-101B-98DA-00AA003F1305}/";
 | 
				
			||||||
 | 
					        public const string PR_MEETING_UID = PSETID_MEETING + "0003" + PT_BINARY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region EAS / ZPush
 | 
					        #region EAS / ZPush
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public const string PR_ZPUSH_MESSAGE_ID = PROP + "6B20" + PT_STRING8;
 | 
					        public const string PR_ZPUSH_MESSAGE_ID = PROP + "6B20" + PT_STRING8;
 | 
				
			||||||
@@ -229,12 +236,12 @@ namespace Acacia
 | 
				
			|||||||
        #region Notes
 | 
					        #region Notes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public const string PREFIX_NOTES = GUID + "{0006200E-0000-0000-C000-000000000046}/";
 | 
					        public const string PSETID_NOTE = GUID + "{0006200E-0000-0000-C000-000000000046}/";
 | 
				
			||||||
        public const string PR_NOTE_COLOR = PREFIX_NOTES + "8B00" + PT_LONG;
 | 
					        public const string PR_NOTE_COLOR = PSETID_NOTE + "8B00" + PT_LONG;
 | 
				
			||||||
        public const string PR_NOTE_WIDTH = PREFIX_NOTES + "8B02" + PT_LONG;
 | 
					        public const string PR_NOTE_WIDTH = PSETID_NOTE + "8B02" + PT_LONG;
 | 
				
			||||||
        public const string PR_NOTE_HEIGHT = PREFIX_NOTES + "8B03" + PT_LONG;
 | 
					        public const string PR_NOTE_HEIGHT = PSETID_NOTE + "8B03" + PT_LONG;
 | 
				
			||||||
        public const string PR_NOTE_X = PREFIX_NOTES + "8B04" + PT_LONG;
 | 
					        public const string PR_NOTE_X = PSETID_NOTE + "8B04" + PT_LONG;
 | 
				
			||||||
        public const string PR_NOTE_Y = PREFIX_NOTES + "8B05" + PT_LONG;
 | 
					        public const string PR_NOTE_Y = PSETID_NOTE + "8B05" + PT_LONG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,5 +30,6 @@ namespace Acacia.Stubs
 | 
				
			|||||||
        DateTime Start { get; set; }
 | 
					        DateTime Start { get; set; }
 | 
				
			||||||
        DateTime End { get; set; }
 | 
					        DateTime End { get; set; }
 | 
				
			||||||
        string Location { get; set; }
 | 
					        string Location { get; set; }
 | 
				
			||||||
 | 
					        string GlobalAppointmentId { get; }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					/// Copyright 2017 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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Stubs
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Specialisation for meeting requests
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public interface IMeetingItem : IItem
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        IAppointmentItem GetAssociatedAppointment(bool addToCalendar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        byte[] GlobalObjectId
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get;
 | 
				
			||||||
 | 
					            set;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -52,6 +52,11 @@ namespace Acacia.Stubs.OutlookWrappers
 | 
				
			|||||||
            set { _item.Location = value; }
 | 
					            set { _item.Location = value; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string GlobalAppointmentId
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get { return _item.GlobalAppointmentID; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region Wrapper methods
 | 
					        #region Wrapper methods
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,6 +62,8 @@ namespace Acacia.Stubs.OutlookWrappers
 | 
				
			|||||||
                return new NoteItemWrapper((NSOutlook.NoteItem)o);
 | 
					                return new NoteItemWrapper((NSOutlook.NoteItem)o);
 | 
				
			||||||
            if (o is NSOutlook.TaskItem)
 | 
					            if (o is NSOutlook.TaskItem)
 | 
				
			||||||
                return new TaskItemWrapper((NSOutlook.TaskItem)o);
 | 
					                return new TaskItemWrapper((NSOutlook.TaskItem)o);
 | 
				
			||||||
 | 
					            if (o is NSOutlook.MeetingItem)
 | 
				
			||||||
 | 
					                return new MeetingItemWrapper((NSOutlook.MeetingItem)o);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // TODO: support others?
 | 
					            // TODO: support others?
 | 
				
			||||||
            if (mustRelease)
 | 
					            if (mustRelease)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,164 @@
 | 
				
			|||||||
 | 
					/// Copyright 2017 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.Utils;
 | 
				
			||||||
 | 
					using NSOutlook = Microsoft.Office.Interop.Outlook;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Stubs.OutlookWrappers
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class MeetingItemWrapper : OutlookItemWrapper<NSOutlook.MeetingItem>, IMeetingItem
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal MeetingItemWrapper(NSOutlook.MeetingItem item)
 | 
				
			||||||
 | 
					        :
 | 
				
			||||||
 | 
					        base(item)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IAppointmentItem GetAssociatedAppointment(bool addToCalendar)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _item.GetAssociatedAppointment(addToCalendar).Wrap<IAppointmentItem>();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public byte[] GlobalObjectId
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                byte[] uid = (byte[])GetProperty(OutlookConstants.PR_MEETING_UID);
 | 
				
			||||||
 | 
					                if (uid != null)
 | 
				
			||||||
 | 
					                    return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                using (IAppointmentItem appointment = GetAssociatedAppointment(false))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (appointment != null)
 | 
				
			||||||
 | 
					                        return appointment.GlobalAppointmentId.HexToBytes();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            set
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                SetProperty(OutlookConstants.PR_MEETING_UID, value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Wrapper methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override NSOutlook.UserProperties GetUserProperties()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _item.UserProperties;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override NSOutlook.PropertyAccessor GetPropertyAccessor()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _item.PropertyAccessor;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return "Appointment:" + Subject;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region IItem implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Body
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get { return _item.Body; }
 | 
				
			||||||
 | 
					            set { _item.Body = value; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Subject
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get { return _item.Subject; }
 | 
				
			||||||
 | 
					            set { _item.Subject = value; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Save() { _item.Save(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region IBase implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string EntryID { get { return _item.EntryID; } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IFolder Parent
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // The wrapper manages the returned folder
 | 
				
			||||||
 | 
					                return Mapping.Wrap<IFolder>(_item.Parent as NSOutlook.Folder);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string ParentEntryID
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                using (ComRelease com = new ComRelease())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    NSOutlook.Folder parent = com.Add(_item.Parent);
 | 
				
			||||||
 | 
					                    return parent?.EntryID;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IStore GetStore()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            using (ComRelease com = new ComRelease())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                NSOutlook.Folder parent = com.Add(_item.Parent);
 | 
				
			||||||
 | 
					                return Mapping.Wrap(parent?.Store);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string StoreID
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                using (ComRelease com = new ComRelease())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    NSOutlook.Folder parent = com.Add(_item.Parent);
 | 
				
			||||||
 | 
					                    NSOutlook.Store store = com.Add(parent?.Store);
 | 
				
			||||||
 | 
					                    return store.StoreID;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string StoreDisplayName
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                using (ComRelease com = new ComRelease())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    NSOutlook.Folder parent = com.Add(_item.Parent);
 | 
				
			||||||
 | 
					                    NSOutlook.Store store = com.Add(parent?.Store);
 | 
				
			||||||
 | 
					                    return store.StoreID;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Delete() { _item.Delete(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -21,6 +21,7 @@ using System.Text;
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Acacia.Stubs;
 | 
					using Acacia.Stubs;
 | 
				
			||||||
using Acacia.Stubs.OutlookWrappers;
 | 
					using Acacia.Stubs.OutlookWrappers;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Acacia.Utils
 | 
					namespace Acacia.Utils
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -151,26 +152,177 @@ namespace Acacia.Utils
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public event CancellableMailItemEventHandler ItemSend;
 | 
					        #region Send
 | 
				
			||||||
        private void OnItemSend(object item, ref bool cancel)
 | 
					
 | 
				
			||||||
 | 
					        private class Dispatchers
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            try
 | 
					            public class Dispatcher
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (ItemSend != null && item != null)
 | 
					                private readonly Dispatchers _dispatchers;
 | 
				
			||||||
 | 
					                private bool _failed;
 | 
				
			||||||
 | 
					                private List<object> _params = new List<object>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                public Dispatcher(Dispatchers dispatchers)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    using (IMailItem wrapped = Mapping.WrapOrDefault<IMailItem>(item, false))
 | 
					                    this._dispatchers = dispatchers;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                public Dispatcher Item(object item, bool mustRelease = false)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (_failed || !_dispatchers.IsRegistered)
 | 
				
			||||||
 | 
					                        return this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (wrapped != null)
 | 
					                        IItem wrapped = Mapping.WrapOrDefault<IItem>(item, mustRelease);
 | 
				
			||||||
                            ItemSend(wrapped, ref cancel);
 | 
					                        if (wrapped == null)
 | 
				
			||||||
 | 
					                            _failed = true;
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                            _params.Add(wrapped);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch (System.Exception e)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Logger.Instance.Error(this, "Dispatcher.Item: {0}: {1}", _dispatchers._name, e);
 | 
				
			||||||
 | 
					                        _failed = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return this;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                public void Exec()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        ExecInternal(0);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch (System.Exception e)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Logger.Instance.Error(this, "Dispatcher.Exec: {0}: {1}", _dispatchers._name, e);
 | 
				
			||||||
 | 
					                        _failed = true;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                private object[] ExecInternal(int skipTypeCheck)
 | 
				
			||||||
 | 
					                { 
 | 
				
			||||||
 | 
					                    if (_failed || !_dispatchers.IsRegistered)
 | 
				
			||||||
 | 
					                        return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    object[] paramsArray = this._params.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    foreach (Delegate handler in _dispatchers._handlers)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // Check the signature
 | 
				
			||||||
 | 
					                        ParameterInfo[] parameters = handler.Method.GetParameters();
 | 
				
			||||||
 | 
					                        if (parameters.Length != paramsArray.Length)
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        bool invoke = true;
 | 
				
			||||||
 | 
					                        for (int i = 0; i < paramsArray.Length - skipTypeCheck; ++i)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            // TODO: this doesn't handle null correctly
 | 
				
			||||||
 | 
					                            Type formal = parameters[i].ParameterType;
 | 
				
			||||||
 | 
					                            Type actual = paramsArray[i].GetType();
 | 
				
			||||||
 | 
					                            if (!formal.IsAssignableFrom(actual))
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                invoke = false;
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        if (!invoke)
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // Invoke
 | 
				
			||||||
 | 
					                        handler.DynamicInvoke(paramsArray);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Cleanup();
 | 
				
			||||||
 | 
					                    return paramsArray;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                public void Exec(ref bool cancel)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        _params.Add(cancel);
 | 
				
			||||||
 | 
					                        object[] paramsArray = ExecInternal(1);
 | 
				
			||||||
 | 
					                        if (paramsArray == null)
 | 
				
			||||||
 | 
					                            return;
 | 
				
			||||||
 | 
					                        cancel = (bool)paramsArray.Last();
 | 
				
			||||||
 | 
					                        _params.RemoveAt(_params.Count - 1);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch (System.Exception e)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Logger.Instance.Error(this, "Dispatcher.Exec(cancel): {0}: {1}", _dispatchers._name, e);
 | 
				
			||||||
 | 
					                        _failed = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                private void Cleanup()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    foreach (object param in _params)
 | 
				
			||||||
 | 
					                        if (param is IDisposable)
 | 
				
			||||||
 | 
					                            ((IDisposable)param).Dispose();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (System.Exception e)
 | 
					
 | 
				
			||||||
 | 
					            private List<Delegate> _handlers = new List<Delegate>();
 | 
				
			||||||
 | 
					            private readonly string _name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            private bool IsRegistered { get { return _handlers.Count > 0; } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public Dispatchers(string name)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Logger.Instance.Error(this, "OnItemSend: {0}", e);
 | 
					                this._name = name;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public void Add(Delegate o)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _handlers.Add(o);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public void Remove(Delegate o)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _handlers.Remove(o);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public Dispatcher Dispatch()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return new Dispatcher(this);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public class CancellableItemEvent
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public delegate void Handler<ItemType>(ItemType item, ref bool cancel)
 | 
				
			||||||
 | 
					            where ItemType : IItem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            private readonly Dispatchers _handlers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public CancellableItemEvent(string name)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _handlers = new Dispatchers(name);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public void Register<ItemType>(Handler<ItemType> handler)
 | 
				
			||||||
 | 
					            where ItemType : IItem
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _handlers.Add(handler);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public void Unregister<ItemType>(Handler<ItemType> handler)
 | 
				
			||||||
 | 
					            where ItemType : IItem
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _handlers.Remove(handler);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            internal void Dispatch(object item, ref bool cancel)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _handlers.Dispatch().Item(item).Exec(ref cancel);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public readonly CancellableItemEvent ItemSend = new CancellableItemEvent("ItemSend");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region Implementation
 | 
					        #region Implementation
 | 
				
			||||||
@@ -178,7 +330,7 @@ namespace Acacia.Utils
 | 
				
			|||||||
        public MailEvents(IAddIn app)
 | 
					        public MailEvents(IAddIn app)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            app.ItemLoad += OnItemLoad;
 | 
					            app.ItemLoad += OnItemLoad;
 | 
				
			||||||
            app.ItemSend += OnItemSend;
 | 
					            app.ItemSend += ItemSend.Dispatch;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void OnItemLoad(object item)
 | 
					        private void OnItemLoad(object item)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,7 +54,7 @@ namespace Acacia.Utils
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        #region Hex strings
 | 
					        #region Hex strings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static byte[] HexToBytes(string hex)
 | 
					        public static byte[] HexToBytes(this string hex)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int NumberChars = hex.Length;
 | 
					            int NumberChars = hex.Length;
 | 
				
			||||||
            byte[] bytes = new byte[NumberChars / 2];
 | 
					            byte[] bytes = new byte[NumberChars / 2];
 | 
				
			||||||
@@ -63,14 +63,14 @@ namespace Acacia.Utils
 | 
				
			|||||||
            return bytes;
 | 
					            return bytes;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static string BytesToHex(byte[] bytes)
 | 
					        public static string BytesToHex(this byte[] bytes)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (bytes == null)
 | 
					            if (bytes == null)
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
            return BitConverter.ToString(bytes).Replace("-", "");
 | 
					            return BitConverter.ToString(bytes).Replace("-", "");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static string HexToUtf8(string s)
 | 
					        public static string HexToUtf8(this string s)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return Encoding.UTF8.GetString(HexToBytes(s));
 | 
					            return Encoding.UTF8.GetString(HexToBytes(s));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user