From 58cd79fdb6a0ecfcc11d181fd237273a16159634 Mon Sep 17 00:00:00 2001
From: Patrick Simpson
Date: Wed, 8 Feb 2017 15:40:48 +0100
Subject: [PATCH] First batch of Com verification update
---
.../AcaciaZPushPlugin.csproj | 2 +
.../Features/DebugSupport/DebugInfo.cs | 6 +-
.../DebugSupport/FeatureDebugSupport.cs | 2 -
.../AcaciaZPushPlugin/Features/Feature.cs | 8 +-
.../Features/FreeBusy/FeatureFreeBusy.cs | 12 +-
.../Features/GAB/FeatureGAB.cs | 13 +-
.../Features/GAB/GABHandler.cs | 26 ++-
.../Features/Notes/FeatureNotes.cs | 5 +-
.../OutOfOffice/FeatureOutOfOffice.cs | 1 -
.../Features/ReplyFlags/FeatureReplyFlags.cs | 1 -
.../FeatureSecondaryContacts.cs | 1 -
.../Features/SendAs/FeatureSendAs.cs | 4 +-
.../AcaciaZPushPlugin/Stubs/IAddIn.cs | 52 +++++
.../AcaciaZPushPlugin/Stubs/IBase.cs | 16 +-
.../Stubs/IDistributionList.cs | 5 +
.../AcaciaZPushPlugin/Stubs/IMailItem.cs | 4 +-
.../AcaciaZPushPlugin/Stubs/ISearch.cs | 2 +-
.../Stubs/OutlookWrappers/AddInWrapper.cs | 188 +++++++++++++++++
.../OutlookWrappers/AddressBookWrapper.cs | 7 +-
.../OutlookWrappers/AppointmentItemWrapper.cs | 113 +++++++---
.../Stubs/OutlookWrappers/ComWrapper.cs | 5 +-
.../OutlookWrappers/ContactItemWrapper.cs | 110 +++++++---
.../DistributionListWrapper.cs | 159 ++++++++------
.../Stubs/OutlookWrappers/FolderWrapper.cs | 156 ++++++++------
.../Stubs/OutlookWrappers/MailItemWrapper.cs | 198 ++++++++++--------
.../Stubs/OutlookWrappers/Mapping.cs | 80 +++----
.../Stubs/OutlookWrappers/NoteItemWrapper.cs | 106 +++++++---
.../OutlookWrappers/OutlookItemWrapper.cs | 16 +-
.../Stubs/OutlookWrappers/OutlookWrapper.cs | 33 +--
.../Stubs/OutlookWrappers/SearchWrapper.cs | 22 +-
.../OutlookWrappers/StorageItemWrapper.cs | 101 ++++++---
.../Stubs/OutlookWrappers/StoreWrapper.cs | 23 +-
.../Stubs/OutlookWrappers/TaskItemWrapper.cs | 103 ++++++---
.../AcaciaZPushPlugin/ThisAddIn.cs | 97 +--------
.../AcaciaZPushPlugin/UI/GABLookupControl.cs | 32 +--
.../UI/Outlook/OutlookImageList.cs | 3 +-
.../AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs | 1 -
.../AcaciaZPushPlugin/UI/SettingsDialog.cs | 12 +-
.../AcaciaZPushPlugin/UI/SettingsPage.cs | 10 +-
.../AcaciaZPushPlugin/Utils/ComRelease.cs | 8 +-
.../AcaciaZPushPlugin/Utils/MailEvents.cs | 92 ++++----
.../Utils/OutlookRegistryUtils.cs | 2 +-
.../AcaciaZPushPlugin/Utils/Util.cs | 37 +++-
.../ZPush/FolderRegistration.cs | 1 -
.../AcaciaZPushPlugin/ZPush/ZPushAccount.cs | 14 +-
.../AcaciaZPushPlugin/ZPush/ZPushAccounts.cs | 50 +++--
.../AcaciaZPushPlugin/ZPush/ZPushChannel.cs | 1 -
.../AcaciaZPushPlugin/ZPush/ZPushChannels.cs | 1 -
.../AcaciaZPushPlugin/ZPush/ZPushFolder.cs | 24 +--
.../ZPush/ZPushLocalStore.cs | 26 +--
.../AcaciaZPushPlugin/ZPush/ZPushSync.cs | 5 +-
.../AcaciaZPushPlugin/ZPush/ZPushWatcher.cs | 47 +++--
52 files changed, 1279 insertions(+), 764 deletions(-)
create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddIn.cs
create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddInWrapper.cs
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
index 64518df..702b8e4 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
@@ -279,7 +279,9 @@
+
+
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugInfo.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugInfo.cs
index 8bbb2c9..cc11799 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugInfo.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugInfo.cs
@@ -101,9 +101,9 @@ namespace Acacia.Features.DebugSupport
}
// Add Add-ins
- foreach (COMAddIn addin in ThisAddIn.Instance.Application.COMAddIns)
+ foreach (KeyValuePair addin in ThisAddIn.Instance.COMAddIns)
{
- PropertyDescriptor p = new CustomPropertyDescriptor(addin.ProgId, DebugCategory.AddIns, addin.Description);
+ PropertyDescriptor p = new CustomPropertyDescriptor(addin.Key, DebugCategory.AddIns, addin.Value);
properties.Add(p);
}
}
@@ -234,7 +234,7 @@ namespace Acacia.Features.DebugSupport
{
get
{
- return ThisAddIn.Instance.Application.Version;
+ return ThisAddIn.Instance.Version;
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/FeatureDebugSupport.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/FeatureDebugSupport.cs
index 8730652..44315c5 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/FeatureDebugSupport.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/FeatureDebugSupport.cs
@@ -13,8 +13,6 @@
/// along with this program.If not, see.
///
/// Consult LICENSE file for details
-
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using Acacia.Features.ReplyFlags;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Feature.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Feature.cs
index 2460dfc..3d0b1b2 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Feature.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Feature.cs
@@ -14,7 +14,6 @@
///
/// Consult LICENSE file for details
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -58,11 +57,6 @@ namespace Acacia.Features
return null;
}
- protected static Microsoft.Office.Interop.Outlook.Application App
- {
- get { return ThisAddIn.Instance.Application; }
- }
-
virtual public void GetCapabilities(ZPushCapabilities caps)
{
caps.Add(Name.ToLower());
@@ -206,7 +200,7 @@ namespace Acacia.Features
get
{
if (_mailEvents == null)
- _mailEvents = new MailEvents(App);
+ _mailEvents = new MailEvents(ThisAddIn.Instance);
return _mailEvents;
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/FreeBusy/FeatureFreeBusy.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/FreeBusy/FeatureFreeBusy.cs
index f9fb908..64ad9fd 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/FreeBusy/FeatureFreeBusy.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/FreeBusy/FeatureFreeBusy.cs
@@ -190,12 +190,14 @@ namespace Acacia.Features.FreeBusy
if (account != null && handler.Contacts != null)
{
// Look for the email address. If found, use the account associated with the GAB
- ISearch search = handler.Contacts.Search();
- search.AddField("urn:schemas:contacts:email1").SetOperation(SearchOperation.Equal, username);
- using (IItem result = search.SearchOne())
+ using (ISearch search = handler.Contacts.Search())
{
- if (result != null)
- return account;
+ search.AddField("urn:schemas:contacts:email1").SetOperation(SearchOperation.Equal, username);
+ using (IItem result = search.SearchOne())
+ {
+ if (result != null)
+ return account;
+ }
}
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
index c932342..d644247 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
@@ -14,7 +14,6 @@
///
/// Consult LICENSE file for details
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -30,6 +29,7 @@ using System.ComponentModel;
using System.Windows.Forms;
using Acacia.UI;
using static Acacia.DebugOptions;
+using Microsoft.Office.Interop.Outlook;
namespace Acacia.Features.GAB
{
@@ -233,7 +233,7 @@ namespace Acacia.Features.GAB
///
private void DoSuppressEvent(IItem item, ref bool cancel)
{
- if (item != null)
+ /*if (item != null)
{
foreach (Inspector inspector in App.Inspectors)
{
@@ -248,7 +248,8 @@ namespace Acacia.Features.GAB
MessageBoxButtons.OK,
MessageBoxIcon.Warning
);
- cancel = true;
+ cancel = true;*/
+ // TODO
}
#endregion
@@ -263,7 +264,7 @@ namespace Acacia.Features.GAB
BeginProcessing();
// Delete any contacts folders in the local store
- using (ZPushLocalStore store = ZPushLocalStore.GetInstance(App))
+ using (ZPushLocalStore store = ZPushLocalStore.GetInstance(ThisAddIn.Instance))
{
if (store != null)
{
@@ -353,7 +354,7 @@ namespace Acacia.Features.GAB
_store.Dispose();
_store = null;
}
- _store = ZPushLocalStore.GetInstance(App);
+ _store = ZPushLocalStore.GetInstance(ThisAddIn.Instance);
if (_store == null)
return null;
@@ -469,7 +470,7 @@ namespace Acacia.Features.GAB
_store.Dispose();
_store = null;
}
- _store = ZPushLocalStore.GetInstance(App);
+ _store = ZPushLocalStore.GetInstance(ThisAddIn.Instance);
if (_store == null)
return;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/GABHandler.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/GABHandler.cs
index 9562b9e..903ea11 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/GABHandler.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/GABHandler.cs
@@ -262,16 +262,18 @@ namespace Acacia.Features.GAB
try
{
// Delete the old contacts from this chunk
- ISearch search = Contacts.Search();
- search.AddField(PROP_SEQUENCE, true).SetOperation(SearchOperation.Equal, index.numberOfChunks);
- search.AddField(PROP_CHUNK, true).SetOperation(SearchOperation.Equal, index.chunk);
- foreach (IItem oldItem in search.Search())
+ using (ISearch search = Contacts.Search())
{
- // TODO: Search should handle this, like folder enumeration
- using (oldItem)
+ search.AddField(PROP_SEQUENCE, true).SetOperation(SearchOperation.Equal, index.numberOfChunks);
+ search.AddField(PROP_CHUNK, true).SetOperation(SearchOperation.Equal, index.chunk);
+ foreach (IItem oldItem in search.Search())
{
- Logger.Instance.Trace(this, "Deleting GAB entry: {0}", oldItem.Subject);
- oldItem.Delete();
+ // TODO: Search should handle this, like folder enumeration
+ using (oldItem)
+ {
+ Logger.Instance.Trace(this, "Deleting GAB entry: {0}", oldItem.Subject);
+ oldItem.Delete();
+ }
}
}
@@ -616,9 +618,11 @@ namespace Acacia.Features.GAB
private IItem FindItemById(string id)
{
- ISearch search = Contacts.Search();
- search.AddField(PROP_GAB_ID, true).SetOperation(SearchOperation.Equal, id);
- return search.SearchOne();
+ using (ISearch search = Contacts.Search())
+ {
+ search.AddField(PROP_GAB_ID, true).SetOperation(SearchOperation.Equal, id);
+ return search.SearchOne();
+ }
}
private void SetItemStandard(IItem item, string id, Dictionary value, ChunkIndex index)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Notes/FeatureNotes.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Notes/FeatureNotes.cs
index a21892b..d481693 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Notes/FeatureNotes.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Notes/FeatureNotes.cs
@@ -18,7 +18,6 @@ using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
using Acacia.Utils;
using Acacia.ZPush;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Drawing;
@@ -122,7 +121,7 @@ namespace Acacia.Features.Notes
Logger.Instance.Trace(this, "PatchFolder: {0}", folderId);
try
{
- using (IFolder folder = Mapping.GetFolderFromID(folderId))
+ using (IFolder folder = ThisAddIn.Instance.GetFolderFromID(folderId))
{
if (folder == null)
return;
@@ -168,7 +167,7 @@ namespace Acacia.Features.Notes
Logger.Instance.Trace(this, "UnpatchFolder: {0}", folderId);
try
{
- using (IFolder folder = Mapping.GetFolderFromID(folderId))
+ using (IFolder folder = ThisAddIn.Instance.GetFolderFromID(folderId))
{
if (folder == null)
return;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/FeatureOutOfOffice.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/FeatureOutOfOffice.cs
index 409df96..e019b6f 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/FeatureOutOfOffice.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/FeatureOutOfOffice.cs
@@ -19,7 +19,6 @@ using Acacia.UI.Outlook;
using Acacia.Utils;
using Acacia.ZPush;
using Acacia.ZPush.Connect;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/ReplyFlags/FeatureReplyFlags.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/ReplyFlags/FeatureReplyFlags.cs
index e9c3df8..2e00658 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/ReplyFlags/FeatureReplyFlags.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/ReplyFlags/FeatureReplyFlags.cs
@@ -22,7 +22,6 @@ using System.Threading.Tasks;
using Acacia.Stubs;
using Acacia.Utils;
using Acacia.ZPush;
-using Microsoft.Office.Interop.Outlook;
using static Acacia.DebugOptions;
namespace Acacia.Features.ReplyFlags
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SecondaryContacts/FeatureSecondaryContacts.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SecondaryContacts/FeatureSecondaryContacts.cs
index 4952c4d..f6d9c8c 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SecondaryContacts/FeatureSecondaryContacts.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SecondaryContacts/FeatureSecondaryContacts.cs
@@ -18,7 +18,6 @@ using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
using Acacia.Utils;
using Acacia.ZPush;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Drawing;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SendAs/FeatureSendAs.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SendAs/FeatureSendAs.cs
index 0dbedcc..0641b13 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SendAs/FeatureSendAs.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SendAs/FeatureSendAs.cs
@@ -22,7 +22,6 @@ using System.Threading.Tasks;
using Acacia.Stubs;
using Acacia.Utils;
using Acacia.ZPush;
-using Microsoft.Office.Interop.Outlook;
using Acacia.Features.SharedFolders;
using Acacia.ZPush.API.SharedFolders;
using static Acacia.DebugOptions;
@@ -86,7 +85,8 @@ namespace Acacia.Features.SendAs
Logger.Instance.Trace(this, "Checking, Shared folder owner: {0}", shared.Store.UserName);
// It's a shared folder, use the owner as the sender if possible
// TODO: make a wrapper for this
- var recip = ThisAddIn.Instance.Application.Session.CreateRecipient(shared.Store.UserName);
+ // TODO: remove RawApp access
+ var recip = ThisAddIn.Instance.RawApp.Session.CreateRecipient(shared.Store.UserName);
Logger.Instance.Trace(this, "Checking, Shared folder owner recipient: {0}", recip.Name);
if (recip != null && recip.Resolve())
{
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddIn.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddIn.cs
new file mode 100644
index 0000000..5489474
--- /dev/null
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddIn.cs
@@ -0,0 +1,52 @@
+using Acacia.Features;
+using Acacia.UI.Outlook;
+using Acacia.ZPush;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
+
+namespace Acacia.Stubs
+{
+ public interface IAddIn
+ {
+ NSOutlook.Application RawApp { get; } // TODO: remove
+
+ ZPushWatcher Watcher { get; }
+ IEnumerable Features { get; }
+ IEnumerable> COMAddIns { get; }
+ string Version { get; }
+
+ IWin32Window Window { get; }
+
+ OutlookUI OutlookUI { get; }
+
+ #region Event handlers
+
+ // TODO: custom event types
+ event NSOutlook.ApplicationEvents_11_ItemLoadEventHandler ItemLoad;
+ event NSOutlook.ApplicationEvents_11_ItemSendEventHandler ItemSend;
+
+ #endregion
+
+ ///
+ /// Sends and receives all accounts.
+ ///
+ void SendReceive();
+
+ ///
+ /// Restarts the application
+ ///
+ void Restart();
+
+ void InvokeUI(Action action);
+
+ IFolder GetFolderFromID(string folderId);
+
+ FeatureType GetFeature()
+ where FeatureType : Feature;
+ }
+}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IBase.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IBase.cs
index e41772f..3e3cb77 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IBase.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IBase.cs
@@ -24,7 +24,7 @@ namespace Acacia.Stubs
{
public interface IBase : IComWrapper
{
- #region MAPI properties
+ #region Properties
bool AttrHidden { get; set; }
@@ -34,21 +34,31 @@ namespace Acacia.Stubs
#endregion
+ #region Ids and hierarchy
+
string EntryId { get; }
IFolder Parent { get; }
string ParentEntryId { get; }
IStore Store { get; }
///
- /// Quick accessor to Store.Id, to prevent allocation a wrapper for it.
+ /// Quick accessor to Store.Id, to prevent allocating a wrapper for it.
///
string StoreId { get; }
+
///
- /// Quick accessor to Store.DisplayName, to prevent allocation a wrapper for it.
+ /// Quick accessor to Store.DisplayName, to prevent allocating a wrapper for it.
///
string StoreDisplayName { get; }
+
+ #endregion
+
+ #region Methods
+
void Delete();
string ToString();
+
+ #endregion
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IDistributionList.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IDistributionList.cs
index 184f5a6..5ce8428 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IDistributionList.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IDistributionList.cs
@@ -27,6 +27,11 @@ namespace Acacia.Stubs
string DLName { get; set; }
string SMTPAddress { get; set; }
+ ///
+ /// Adds a member to the distribution list.
+ ///
+ /// The item. This is not disposed or released.
+ /// If the item is not a contact or distribution list
void AddMember(IItem item);
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IMailItem.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IMailItem.cs
index 355ea10..5fff5dc 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IMailItem.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IMailItem.cs
@@ -19,7 +19,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs
{
@@ -34,6 +33,7 @@ namespace Acacia.Stubs
string SenderEmailAddress { get; }
string SenderName { get; }
- void SetSender(AddressEntry addressEntry);
+ // TODO: make a wrapper for this
+ void SetSender(Microsoft.Office.Interop.Outlook.AddressEntry addressEntry);
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/ISearch.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/ISearch.cs
index 18d5aef..385b676 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/ISearch.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/ISearch.cs
@@ -53,7 +53,7 @@ namespace Acacia.Stubs
ISearchField AddField(string name, bool isUserField = false);
}
- public interface ISearch : ISearchOperator
+ public interface ISearch : ISearchOperator, IDisposable
where ItemType : IItem
{
ISearchOperator AddOperator(SearchOperator oper);
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddInWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddInWrapper.cs
new file mode 100644
index 0000000..9b81921
--- /dev/null
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddInWrapper.cs
@@ -0,0 +1,188 @@
+using Acacia.Features;
+using Acacia.Native;
+using Acacia.UI.Outlook;
+using Acacia.Utils;
+using Acacia.ZPush;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
+
+namespace Acacia.Stubs.OutlookWrappers
+{
+ public class AddInWrapper : IAddIn
+ {
+ private readonly ThisAddIn _thisAddIn;
+ private NSOutlook.Application _app;
+
+ public AddInWrapper(ThisAddIn thisAddIn)
+ {
+ this._thisAddIn = thisAddIn;
+ this._app = thisAddIn.Application;
+ }
+
+ public void SendReceive()
+ {
+ NSOutlook.NameSpace session = _app.Session;
+ try
+ {
+ session.SendAndReceive(false);
+ }
+ finally
+ {
+ ComRelease.Release(session);
+ }
+ }
+
+ public void Restart()
+ {
+ // Can not use the assembly location, as that is in the GAC
+ string codeBase = Assembly.GetExecutingAssembly().CodeBase;
+ UriBuilder uri = new UriBuilder(codeBase);
+ string path = Uri.UnescapeDataString(uri.Path);
+ // Create the path to the restarter
+ path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), "OutlookRestarter.exe");
+
+ // Run that
+ Process process = new Process();
+ process.StartInfo = new ProcessStartInfo(path, Environment.CommandLine);
+ process.Start();
+
+ // And close us
+ _app.Quit();
+ }
+
+ public event NSOutlook.ApplicationEvents_11_ItemLoadEventHandler ItemLoad
+ {
+ add { _app.ItemLoad += value; }
+ remove { _app.ItemLoad -= value; }
+ }
+
+ public event NSOutlook.ApplicationEvents_11_ItemSendEventHandler ItemSend
+ {
+ add { _app.ItemSend += value; }
+ remove { _app.ItemSend -= value; }
+ }
+
+ public NSOutlook.Application RawApp
+ {
+ get
+ {
+ return _app;
+ }
+ }
+
+ public OutlookUI OutlookUI { get { return _thisAddIn.OutlookUI; } }
+
+ public ZPushWatcher Watcher { get { return _thisAddIn.Watcher; } }
+ public IEnumerable Features { get { return _thisAddIn.Features; } }
+ public IEnumerable> COMAddIns
+ {
+ get
+ {
+ Microsoft.Office.Core.COMAddIns addIns = _app.COMAddIns;
+ try
+ {
+ foreach(Microsoft.Office.Core.COMAddIn comAddin in addIns)
+ {
+ try
+ {
+ yield return new KeyValuePair(comAddin.ProgId, comAddin.Description);
+ }
+ finally
+ {
+ ComRelease.Release(comAddin);
+ }
+ }
+ }
+ finally
+ {
+ ComRelease.Release(addIns);
+ }
+ }
+ }
+
+ public string Version
+ {
+ get { return _app.Version; }
+ }
+
+
+ public FeatureType GetFeature()
+ where FeatureType : Feature
+ {
+ foreach (Feature feature in Features)
+ {
+ if (feature is FeatureType)
+ return (FeatureType)feature;
+ }
+ return default(FeatureType);
+ }
+
+
+ public void InvokeUI(Action action)
+ {
+ // [ZP-992] For some reason using the dispatcher causes a deadlock
+ // since switching to UI-chunked tasks. Running directly works.
+ action();
+ }
+
+ public IFolder GetFolderFromID(string folderId)
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.NameSpace nmspace = com.Add(_app.Session);
+ NSOutlook.Folder f = (NSOutlook.Folder)nmspace.GetFolderFromID(folderId);
+ return Mapping.Wrap(f);
+ }
+ }
+
+ #region Window handle
+
+ private class WindowHandle : IWin32Window
+ {
+ private IntPtr hWnd;
+
+ public WindowHandle(IntPtr hWnd)
+ {
+ this.hWnd = hWnd;
+ }
+
+ public IntPtr Handle
+ {
+ get
+ {
+ return hWnd;
+ }
+ }
+ }
+
+ public IWin32Window Window
+ {
+ get
+ {
+ IOleWindow win = _app.ActiveWindow() as IOleWindow;
+ if (win == null)
+ return null;
+ try
+ {
+ IntPtr hWnd;
+ win.GetWindow(out hWnd);
+ return new WindowHandle(hWnd);
+ }
+ finally
+ {
+ ComRelease.Release(win);
+ }
+ }
+ }
+
+ #endregion
+
+ }
+}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressBookWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressBookWrapper.cs
index 47a9f3a..ff6a4ce 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressBookWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressBookWrapper.cs
@@ -15,18 +15,18 @@
/// Consult LICENSE file for details
using Acacia.Utils;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
class AddressBookWrapper : FolderWrapper, IAddressBook
{
- public AddressBookWrapper(Folder folder)
+ public AddressBookWrapper(NSOutlook.MAPIFolder folder)
:
base(folder)
{
@@ -35,10 +35,9 @@ namespace Acacia.Stubs.OutlookWrappers
public void Clear()
{
- foreach(dynamic item in _item.Items)
+ foreach(dynamic item in _item.Items.RawEnum())
{
item.Delete();
- ComRelease.Release(item);
}
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AppointmentItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AppointmentItemWrapper.cs
index 7a3263e..9071f7d 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AppointmentItemWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AppointmentItemWrapper.cs
@@ -19,27 +19,21 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Microsoft.Office.Interop.Outlook;
using Acacia.Utils;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
- class AppointmentItemWrapper : OutlookItemWrapper, IAppointmentItem, IZPushItem
+ class AppointmentItemWrapper : OutlookItemWrapper, IAppointmentItem, IZPushItem
{
- internal AppointmentItemWrapper(AppointmentItem item)
+ internal AppointmentItemWrapper(NSOutlook.AppointmentItem item)
:
base(item)
{
}
- public override string ToString() { return "Appointment: " + Subject; }
- protected override PropertyAccessor GetPropertyAccessor()
- {
- return _item.PropertyAccessor;
- }
-
- #region Properties
+ #region IAppointmentItem implementation
public DateTime Start
{
@@ -58,6 +52,29 @@ namespace Acacia.Stubs.OutlookWrappers
set { _item.Location = value; }
}
+ #endregion
+
+ #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; }
@@ -70,45 +87,75 @@ namespace Acacia.Stubs.OutlookWrappers
set { _item.Subject = value; }
}
- public IStore Store { get { return StoreWrapper.Wrap(_item.Parent?.Store); } }
- // TODO: release needed
- public string StoreId { get { return _item.Parent?.Store?.StoreID; } }
- public string StoreDisplayName { get { return _item.Parent?.Store?.DisplayName; } }
-
- #endregion
-
- #region Methods
-
- protected override UserProperties GetUserProperties()
- {
- return _item.UserProperties;
- }
-
- public void Delete() { _item.Delete(); }
public void Save() { _item.Save(); }
#endregion
+ #region IBase implementation
+
+ public string EntryId { get { return _item.EntryID; } }
+
public IFolder Parent
{
- get { return (IFolder)Mapping.Wrap(_item.Parent as Folder); }
+ get
+ {
+ // The wrapper manages the returned folder
+ return Mapping.Wrap(_item.Parent as NSOutlook.Folder);
+ }
}
+
public string ParentEntryId
{
get
{
- Folder parent = _item.Parent;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folder parent = com.Add(_item.Parent);
return parent?.EntryID;
}
- finally
- {
- ComRelease.Release(parent);
- }
}
}
- public string EntryId { get { return _item.EntryID; } }
+ public IStore Store
+ {
+ get
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ return StoreWrapper.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
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs
index e5b150e..61cf8cb 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs
@@ -43,9 +43,8 @@ namespace Acacia.Stubs.OutlookWrappers
if (!_isDisposed)
{
Logger.Instance.Warning(this, "Undisposed wrapper: {0}", _createdTrace);
- Dispose();
- // Don't count auto disposals
- Interlocked.Decrement(ref Statistics.DisposedWrappers);
+ // Dispose, but don't count auto disposals, so the stats show it.
+ DoRelease();
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ContactItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ContactItemWrapper.cs
index 01db56f..a8617a2 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ContactItemWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ContactItemWrapper.cs
@@ -15,30 +15,23 @@
/// Consult LICENSE file for details
using Acacia.Utils;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
- class ContactItemWrapper : OutlookItemWrapper, IContactItem
+ class ContactItemWrapper : OutlookItemWrapper, IContactItem
{
- internal ContactItemWrapper(ContactItem item)
+ internal ContactItemWrapper(NSOutlook.ContactItem item)
:
base(item)
{
}
- protected override PropertyAccessor GetPropertyAccessor()
- {
- return _item.PropertyAccessor;
- }
-
- public override string ToString() { return "Contact: " + Subject; }
-
#region IContactItem implementation
public string CustomerID
@@ -179,6 +172,30 @@ namespace Acacia.Stubs.OutlookWrappers
set { _item.Language = value; }
}
+ public void SetPicture(string path)
+ {
+ _item.AddPicture(path);
+ }
+
+ #endregion
+
+ #region Wrapper methods
+
+ protected override NSOutlook.UserProperties GetUserProperties()
+ {
+ return _item.UserProperties;
+ }
+
+ protected override NSOutlook.PropertyAccessor GetPropertyAccessor()
+ {
+ return _item.PropertyAccessor;
+ }
+
+ public override string ToString()
+ {
+ return "Contact:" + Subject;
+ }
+
#endregion
#region IItem implementation
@@ -195,49 +212,74 @@ namespace Acacia.Stubs.OutlookWrappers
set { _item.Subject = value; }
}
- public IStore Store { get { return StoreWrapper.Wrap(_item.Parent?.Store); } }
- // TODO: release needed
- public string StoreId { get { return _item.Parent?.Store?.StoreID; } }
- public string StoreDisplayName { get { return _item.Parent?.Store?.DisplayName; } }
-
- protected override UserProperties GetUserProperties()
- {
- return _item.UserProperties;
- }
-
- public void Delete() { _item.Delete(); }
public void Save() { _item.Save(); }
- public void SetPicture(string path)
- {
- _item.AddPicture(path);
- }
-
#endregion
#region IBase implementation
+ public string EntryId { get { return _item.EntryID; } }
+
public IFolder Parent
{
- get { return (IFolder)Mapping.Wrap(_item.Parent as Folder); }
+ get
+ {
+ // The wrapper manages the returned folder
+ return Mapping.Wrap(_item.Parent as NSOutlook.Folder);
+ }
}
+
public string ParentEntryId
{
get
{
- Folder parent = _item.Parent;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folder parent = com.Add(_item.Parent);
return parent?.EntryID;
}
- finally
- {
- ComRelease.Release(parent);
- }
}
}
- public string EntryId { get { return _item.EntryID; } }
+ public IStore Store
+ {
+ get
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ return StoreWrapper.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
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/DistributionListWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/DistributionListWrapper.cs
index 2754c93..7771581 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/DistributionListWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/DistributionListWrapper.cs
@@ -19,47 +19,35 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Microsoft.Office.Interop.Outlook;
using Acacia.Utils;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
- class DistributionListWrapper : OutlookItemWrapper, IDistributionList
+ class DistributionListWrapper : OutlookItemWrapper, IDistributionList
{
- internal DistributionListWrapper(DistListItem item)
+ internal DistributionListWrapper(NSOutlook.DistListItem item)
:
base(item)
{
}
- protected override PropertyAccessor GetPropertyAccessor()
- {
- return _item.PropertyAccessor;
- }
-
- #region Properties
+ #region IDistributionList implementation
public string SMTPAddress
{
get
{
- PropertyAccessor props = _item.PropertyAccessor;
- try
- {
- return (string)props.GetProperty(OutlookConstants.PR_EMAIL1EMAILADDRESS);
- }
- finally
- {
- ComRelease.Release(props);
- }
+ return (string)GetProperty(OutlookConstants.PR_EMAIL1EMAILADDRESS);
}
set
{
- string displayName = DLName + " (" + value + ")";
- byte[] oneOffId = CreateOneOffMemberId(DLName, "SMTP", value);
- PropertyAccessor props = _item.PropertyAccessor;
- try
+ using (ComRelease com = new ComRelease())
{
+ string displayName = DLName + " (" + value + ")";
+ byte[] oneOffId = CreateOneOffMemberId(DLName, "SMTP", value);
+
+ NSOutlook.PropertyAccessor props = com.Add(_item.PropertyAccessor);
props.SetProperties(
new string[]
{
@@ -79,35 +67,20 @@ namespace Acacia.Stubs.OutlookWrappers
}
);
}
- finally
- {
- ComRelease.Release(props);
- }
}
}
- #endregion
-
- #region Methods
-
- protected override UserProperties GetUserProperties()
+ public string DLName
{
- return _item.UserProperties;
+ get { return _item.DLName; }
+ set { _item.DLName = value; }
}
- public void Delete() { _item.Delete(); }
- public void Save() { _item.Save(); }
-
public void AddMember(IItem item)
{
if (item is IContactItem)
{
- string email = ((IContactItem)item).Email1Address;
- Recipient recipient = ThisAddIn.Instance.Application.Session.CreateRecipient(email);
- if (recipient.Resolve())
- _item.AddMember(recipient);
- else
- Logger.Instance.Warning(this, "Unable to resolve recipient: {0}", email);
+ AddContactMember((IContactItem)item);
}
else if (item is IDistributionList)
{
@@ -115,8 +88,19 @@ namespace Acacia.Stubs.OutlookWrappers
}
else
{
- Logger.Instance.Warning(this, "Unknown item type when adding to distlist: {0}", item);
- }
+ throw new NotSupportedException("Unknown item type when adding to distlist: " + item.GetType());
+ }
+ }
+
+ private void AddContactMember(IContactItem member)
+ {
+ string email = member.Email1Address;
+ // TODO: remove RawApp, Recipient wrapper
+ NSOutlook.Recipient recipient = ThisAddIn.Instance.RawApp.Session.CreateRecipient(email);
+ if (recipient.Resolve())
+ _item.AddMember(recipient);
+ else
+ Logger.Instance.Warning(this, "Unable to resolve recipient: {0}", email);
}
private void AddDistributionListMember(IDistributionList member)
@@ -124,9 +108,8 @@ namespace Acacia.Stubs.OutlookWrappers
// Resolving a distribution list can only be done by name. This fails if the name is in multiple
// groups (e.g. 'Germany' and 'Sales Germany' fails to find Germany). Patch the member
// tables explicitly.
- PropertyAccessor props = _item.PropertyAccessor;
- object[] members = props.GetProperty(OutlookConstants.PR_DISTLIST_MEMBERS);
- object[] oneOffMembers = props.GetProperty(OutlookConstants.PR_DISTLIST_ONEOFFMEMBERS);
+ object[] members = (object[])GetProperty(OutlookConstants.PR_DISTLIST_MEMBERS);
+ object[] oneOffMembers = (object[])GetProperty(OutlookConstants.PR_DISTLIST_ONEOFFMEMBERS);
// Create the new member ids
byte[] memberId = CreateMemberId(member);
@@ -163,7 +146,7 @@ namespace Acacia.Stubs.OutlookWrappers
newOneOffMembers[existingIndex] = oneOffMemberId;
// Write back
- props.SetProperties(
+ SetProperties(
new string[] { OutlookConstants.PR_DISTLIST_MEMBERS, OutlookConstants.PR_DISTLIST_ONEOFFMEMBERS },
new object[] { newMembers, newOneOffMembers }
);
@@ -213,14 +196,27 @@ namespace Acacia.Stubs.OutlookWrappers
#endregion
- public override string ToString() { return "DistributionList: " + DLName; }
+ #region Wrapper methods
- public string DLName
+ protected override NSOutlook.UserProperties GetUserProperties()
{
- get { return _item.DLName; }
- set { _item.DLName = value; }
+ return _item.UserProperties;
}
+ protected override NSOutlook.PropertyAccessor GetPropertyAccessor()
+ {
+ return _item.PropertyAccessor;
+ }
+
+ public override string ToString()
+ {
+ return "DistributionList: " + DLName;
+ }
+
+ #endregion
+
+ #region IItem implementation
+
public string Body
{
get { return _item.Body; }
@@ -233,40 +229,75 @@ namespace Acacia.Stubs.OutlookWrappers
set { _item.Subject = value; }
}
- public IFolder Parent { get { return (IFolder)Mapping.Wrap(_item.Parent as Folder); } }
+ 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(_item.Parent as NSOutlook.Folder);
+ }
+ }
+
public string ParentEntryId
{
get
{
- Folder parent = _item.Parent;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folder parent = com.Add(_item.Parent);
return parent?.EntryID;
}
- finally
- {
- ComRelease.Release(parent);
- }
}
}
- public IStore Store { get { return StoreWrapper.Wrap(_item.Parent?.Store); } }
+
+ public IStore Store
+ {
+ get
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ return StoreWrapper.Wrap(parent?.Store);
+ }
+ }
+ }
+
public string StoreId
{
get
{
- // TODO: release needed
- return _item.Parent?.Store?.StoreID;
+ 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
{
- // TODO: release needed
- return _item.Parent?.Store?.DisplayName;
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ NSOutlook.Store store = com.Add(parent?.Store);
+ return store.StoreID;
+ }
}
}
- public string EntryId { get { return _item.EntryID; } }
+ public void Delete() { _item.Delete(); }
+
+ #endregion
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs
index 944d122..2361b09 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs
@@ -14,7 +14,6 @@
///
/// Consult LICENSE file for details
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -23,39 +22,41 @@ using System.Threading.Tasks;
using System.Collections;
using Acacia.Utils;
using Acacia.ZPush;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
- public class FolderWrapper : OutlookWrapper, IFolder
+ public class FolderWrapper : OutlookWrapper, IFolder
{
- public FolderWrapper(Folder folder)
+ public FolderWrapper(NSOutlook.MAPIFolder folder)
:
- base(folder)
+ base((NSOutlook.Folder)folder)
{
}
- protected override PropertyAccessor GetPropertyAccessor()
+ protected override NSOutlook.PropertyAccessor GetPropertyAccessor()
{
return _item.PropertyAccessor;
}
public IFolder Parent
{
- get { return (IFolder)Mapping.Wrap(_item.Parent as Folder); }
+ get
+ {
+ // The wrapper manages the returned folder
+ return Mapping.Wrap(_item.Parent as NSOutlook.Folder);
+ }
}
+
public string ParentEntryId
{
get
{
- Folder parent = _item.Parent;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folder parent = com.Add(_item.Parent);
return parent?.EntryID;
}
- finally
- {
- ComRelease.Release(parent);
- }
}
}
@@ -69,17 +70,20 @@ namespace Acacia.Stubs.OutlookWrappers
using (ComRelease com = new ComRelease())
{
// The parent of the root item is a session, not null. Hence the explicit type checks.
- Folder current = _item;
+ // _item is managed by this wrapper and does not need to be released.
+ NSOutlook.Folder current = _item;
for (int i = 0; i < depth; ++i)
{
- object parent = current.Parent;
- com.Add(parent);
- if (!(parent is Folder))
+ object parent = com.Add(current.Parent);
+
+ current = parent as NSOutlook.Folder;
+ if (current == null)
return false;
- current = (Folder)parent;
}
- return !(com.Add(current.Parent) is Folder);
+ // Check if the remaining parent is a folder
+ object finalParent = com.Add(current.Parent);
+ return !(finalParent is NSOutlook.Folder);
}
}
@@ -118,15 +122,18 @@ namespace Acacia.Stubs.OutlookWrappers
public ItemType ItemType { get { return (ItemType)(int)_item.DefaultItemType; } }
- public class IItemsEnumerator : IEnumerator
+ #region Enumeration
+
+ public class ItemsEnumerator : ComWrapper, IEnumerator
where ItemType : IItem
{
- private Items _items;
+ private NSOutlook.Items _items;
private IEnumerator _enum;
private ItemType _last;
- public IItemsEnumerator(Folder _folder, string field, bool descending)
+ public ItemsEnumerator(NSOutlook.Folder _folder, string field, bool descending)
{
+ // TODO: can _items be released here already?
this._items = _folder.Items;
if (field != null)
{
@@ -135,6 +142,23 @@ namespace Acacia.Stubs.OutlookWrappers
this._enum = _items.GetEnumerator();
}
+ protected override void DoRelease()
+ {
+ CleanLast();
+ if (_enum != null)
+ {
+ if (_enum is IDisposable)
+ ((IDisposable)_enum).Dispose();
+ ComRelease.Release(_enum);
+ _enum = null;
+ }
+ if (_items != null)
+ {
+ ComRelease.Release(_items);
+ _items = null;
+ }
+ }
+
public ItemType Current
{
get
@@ -162,23 +186,6 @@ namespace Acacia.Stubs.OutlookWrappers
}
}
- public void Dispose()
- {
- CleanLast();
- if (_enum != null)
- {
- if (_enum is IDisposable)
- ((IDisposable)_enum).Dispose();
- ComRelease.Release(_enum);
- _enum = null;
- }
- if (_items != null)
- {
- ComRelease.Release(_items);
- _items = null;
- }
- }
-
public bool MoveNext()
{
CleanLast();
@@ -192,14 +199,15 @@ namespace Acacia.Stubs.OutlookWrappers
}
}
- public class IItemsEnumerable : IEnumerable
+ public class ItemsEnumerable : IEnumerable
where ItemType : IItem
{
- private readonly Folder _folder;
+ // Managed by the caller, not released here
+ private readonly NSOutlook.Folder _folder;
private readonly string _field;
private readonly bool _descending;
- public IItemsEnumerable(Folder folder, string field, bool descending)
+ public ItemsEnumerable(NSOutlook.Folder folder, string field, bool descending)
{
this._folder = folder;
this._field = field;
@@ -208,7 +216,7 @@ namespace Acacia.Stubs.OutlookWrappers
public IEnumerator GetEnumerator()
{
- return new IItemsEnumerator(_folder, _field, _descending);
+ return new ItemsEnumerator(_folder, _field, _descending);
}
IEnumerator IEnumerable.GetEnumerator()
@@ -221,15 +229,17 @@ namespace Acacia.Stubs.OutlookWrappers
{
get
{
- return new IItemsEnumerable(_item, null, false);
+ return new ItemsEnumerable(_item, null, false);
}
}
public IEnumerable ItemsSorted(string field, bool descending)
{
- return new IItemsEnumerable(_item, field, descending);
+ return new ItemsEnumerable(_item, field, descending);
}
+ #endregion
+
public IItem GetItemById(string entryId)
{
try
@@ -274,10 +284,13 @@ namespace Acacia.Stubs.OutlookWrappers
return new SearchWrapper(_item.Items);
}
+ #region Subfolders
+
public IEnumerable GetSubFolders()
where FolderType : IFolder
{
- foreach (MAPIFolder folder in _item.Folders)
+ // Don't release the items, the wrapper manages them
+ foreach (NSOutlook.Folder folder in _item.Folders.RawEnum(false))
{
yield return WrapFolder(folder);
};
@@ -287,14 +300,19 @@ namespace Acacia.Stubs.OutlookWrappers
where FolderType : IFolder
{
// Fetching the folder by name throws an exception if not found, loop and find
- // to prevent exceptions in the log
- MAPIFolder sub = null;
- foreach(MAPIFolder folder in _item.Folders)
+ // to prevent exceptions in the log.
+ // Don't release the items in RawEnum, they are release manually or handed to WrapFolders.
+ NSOutlook.Folder sub = null;
+ foreach(NSOutlook.Folder folder in _item.Folders.RawEnum(false))
{
if (folder.Name == name)
{
sub = folder;
- break;
+ break; // TODO: does this prevent the rest of the objects from getting released?
+ }
+ else
+ {
+ ComRelease.Release(folder);
}
}
if (sub == null)
@@ -305,46 +323,47 @@ namespace Acacia.Stubs.OutlookWrappers
public FolderType CreateFolder(string name)
where FolderType : IFolder
{
- Folders folders = _item.Folders;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folders folders = com.Add(_item.Folders);
if (typeof(FolderType) == typeof(IFolder))
{
return WrapFolder(folders.Add(name));
}
else if (typeof(FolderType) == typeof(IAddressBook))
{
- MAPIFolder newFolder = folders.Add(name, OlDefaultFolders.olFolderContacts);
+ NSOutlook.MAPIFolder newFolder = folders.Add(name, NSOutlook.OlDefaultFolders.olFolderContacts);
newFolder.ShowAsOutlookAB = true;
return WrapFolder(newFolder);
}
else
throw new NotSupportedException();
}
- finally
- {
- ComRelease.Release(folders);
- }
}
- private FolderType WrapFolder(MAPIFolder folder)
+ private FolderType WrapFolder(NSOutlook.MAPIFolder folder)
where FolderType : IFolder
{
if (typeof(FolderType) == typeof(IFolder))
{
- return (FolderType)(IFolder)new FolderWrapper((Folder)folder);
+ return (FolderType)(IFolder)new FolderWrapper(folder);
}
else if (typeof(FolderType) == typeof(IAddressBook))
{
- return (FolderType)(IFolder)new AddressBookWrapper((Folder)folder);
+ return (FolderType)(IFolder)new AddressBookWrapper(folder);
}
else
+ {
+ ComRelease.Release(folder);
throw new NotSupportedException();
+ }
}
+ #endregion
+
public IStorageItem GetStorageItem(string name)
{
- StorageItem item = _item.GetStorage(name, OlStorageIdentifierType.olIdentifyBySubject);
+ NSOutlook.StorageItem item = _item.GetStorage(name, NSOutlook.OlStorageIdentifierType.olIdentifyBySubject);
if (item == null)
return null;
return new StorageItemWrapper(item);
@@ -359,16 +378,12 @@ namespace Acacia.Stubs.OutlookWrappers
public ItemType Create()
where ItemType : IItem
{
- Items items = _item.Items;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Items items = com.Add(_item.Items);
object item = items.Add(Mapping.OutlookItemType());
return Mapping.Wrap(item);
}
- finally
- {
- ComRelease.Release(items);
- }
}
#endregion
@@ -415,12 +430,14 @@ namespace Acacia.Stubs.OutlookWrappers
_item.BeforeItemMove -= HandleBeforeItemMove;
}
- private void HandleBeforeItemMove(object item, MAPIFolder target, ref bool cancel)
+ private void HandleBeforeItemMove(object item, NSOutlook.MAPIFolder target, ref bool cancel)
{
try
{
if (_beforeItemMove != null)
{
+ // TODO: there is a tiny potential for a leak here, if there is an exception in the wrap methods. Should
+ // only happen if Outlook sends the wrong type object though
using (IItem itemWrapped = Mapping.Wrap(item))
using (IFolder targetWrapped = Mapping.Wrap(target))
{
@@ -430,6 +447,11 @@ namespace Acacia.Stubs.OutlookWrappers
}
}
}
+ else
+ {
+ // TODO: check this
+ ComRelease.Release(item, target);
+ }
}
catch(System.Exception e)
{
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MailItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MailItemWrapper.cs
index 10edd5e..be57f96 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MailItemWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MailItemWrapper.cs
@@ -19,27 +19,95 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Microsoft.Office.Interop.Outlook;
using Acacia.Utils;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
- class MailItemWrapper : OutlookItemWrapper, IMailItem
+ class MailItemWrapper : OutlookItemWrapper, IMailItem
{
- internal MailItemWrapper(MailItem item)
+ internal MailItemWrapper(NSOutlook.MailItem item)
:
base(item)
{
}
- protected override PropertyAccessor GetPropertyAccessor()
+ #region IMailItem implementation
+
+ public DateTime? AttrLastVerbExecutionTime
+ {
+ get
+ {
+ return GetProperty(OutlookConstants.PR_LAST_VERB_EXECUTION_TIME) as DateTime?;
+ }
+ set
+ {
+ SetProperty(OutlookConstants.PR_LAST_VERB_EXECUTION_TIME, value);
+ }
+ }
+
+ public int AttrLastVerbExecuted
+ {
+ get
+ {
+ return (int)GetProperty(OutlookConstants.PR_LAST_VERB_EXECUTED);
+ }
+ set
+ {
+ SetProperty(OutlookConstants.PR_LAST_VERB_EXECUTED, value);
+ }
+ }
+
+ public string SenderEmailAddress
+ {
+ get
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ return com.Add(_item.Sender)?.Address;
+ }
+ }
+ }
+
+ public string SenderName
+ {
+ get
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ return com.Add(_item.Sender)?.Name;
+ }
+ }
+ }
+
+
+ public void SetSender(NSOutlook.AddressEntry addressEntry)
+ {
+ _item.Sender = addressEntry;
+ }
+
+ #endregion
+
+ #region Wrapper methods
+
+ protected override NSOutlook.UserProperties GetUserProperties()
+ {
+ return _item.UserProperties;
+ }
+
+ protected override NSOutlook.PropertyAccessor GetPropertyAccessor()
{
return _item.PropertyAccessor;
}
- public override string ToString() { return "Mail: " + Subject; }
+ public override string ToString()
+ {
+ return "Mail:" + Subject;
+ }
- #region Properties
+ #endregion
+
+ #region IItem implementation
public string Body
{
@@ -53,19 +121,44 @@ namespace Acacia.Stubs.OutlookWrappers
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(_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 Store
{
get
{
- Folder parent = (Folder)_item.Parent;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folder parent = com.Add(_item.Parent);
return StoreWrapper.Wrap(parent?.Store);
}
- finally
- {
- ComRelease.Release(parent);
- }
}
}
@@ -73,17 +166,11 @@ namespace Acacia.Stubs.OutlookWrappers
{
get
{
- Folder parent = (Folder)_item.Parent;
- Store store = null;
- try
+ using (ComRelease com = new ComRelease())
{
- store = parent?.Store;
- return store?.StoreID;
- }
- finally
- {
- ComRelease.Release(parent);
- ComRelease.Release(store);
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ NSOutlook.Store store = com.Add(parent?.Store);
+ return store.StoreID;
}
}
}
@@ -92,76 +179,17 @@ namespace Acacia.Stubs.OutlookWrappers
{
get
{
- Folder parent = (Folder)_item.Parent;
- Store store = null;
- try
+ using (ComRelease com = new ComRelease())
{
- store = parent?.Store;
- return store?.DisplayName;
- }
- finally
- {
- ComRelease.Release(parent);
- ComRelease.Release(store);
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ NSOutlook.Store store = com.Add(parent?.Store);
+ return store.StoreID;
}
}
}
- public string SenderEmailAddress
- {
- get
- {
- // TODO: should Sender be released?
- return _item.Sender?.Address;
- }
- }
-
- public string SenderName
- {
- get { return _item.Sender?.Name; }
- }
-
-
- public void SetSender(AddressEntry addressEntry)
- {
- _item.Sender = addressEntry;
- }
-
-
- #endregion
-
- #region Methods
-
- protected override UserProperties GetUserProperties()
- {
- return _item.UserProperties;
- }
-
public void Delete() { _item.Delete(); }
- public void Save() { _item.Save(); }
#endregion
-
- public IFolder Parent
- {
- get { return (IFolder)Mapping.Wrap(_item.Parent as Folder); }
- }
- public string ParentEntryId
- {
- get
- {
- Folder parent = _item.Parent;
- try
- {
- return parent?.EntryID;
- }
- finally
- {
- ComRelease.Release(parent);
- }
- }
- }
-
- public string EntryId { get { return _item.EntryID; } }
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/Mapping.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/Mapping.cs
index 93bcf10..f19bac6 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/Mapping.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/Mapping.cs
@@ -15,12 +15,12 @@
/// Consult LICENSE file for details
using Acacia.Utils;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
@@ -32,7 +32,8 @@ namespace Acacia.Stubs.OutlookWrappers
///
/// The Outlook object.
/// The IItem wrapper, or null if the object could not be wrapped
- public static IBase Wrap(object o, bool mustRelease = true)
+ // TODO: made this private to see if it's still used
+ private static IBase Wrap(object o, bool mustRelease = true)
{
if (o == null)
return null;
@@ -47,25 +48,25 @@ namespace Acacia.Stubs.OutlookWrappers
private static IBase CreateWrapper(object o)
{
// TODO: switch on o.Class
- if (o is MailItem)
- return new MailItemWrapper((MailItem)o);
- if (o is AppointmentItem)
- return new AppointmentItemWrapper((AppointmentItem)o);
- if (o is Folder)
- return new FolderWrapper((Folder)o);
- if (o is ContactItem)
- return new ContactItemWrapper((ContactItem)o);
- if (o is DistListItem)
- return new DistributionListWrapper((DistListItem)o);
- if (o is NoteItem)
- return new NoteItemWrapper((NoteItem)o);
- if (o is TaskItem)
- return new TaskItemWrapper((TaskItem)o);
-
- // TODO: support this?
- if (o is ReportItem)
- return null;
+ if (o is NSOutlook.MailItem)
+ return new MailItemWrapper((NSOutlook.MailItem)o);
+ if (o is NSOutlook.AppointmentItem)
+ return new AppointmentItemWrapper((NSOutlook.AppointmentItem)o);
+ if (o is NSOutlook.Folder)
+ return new FolderWrapper((NSOutlook.Folder)o);
+ if (o is NSOutlook.ContactItem)
+ return new ContactItemWrapper((NSOutlook.ContactItem)o);
+ if (o is NSOutlook.DistListItem)
+ return new DistributionListWrapper((NSOutlook.DistListItem)o);
+ if (o is NSOutlook.NoteItem)
+ return new NoteItemWrapper((NSOutlook.NoteItem)o);
+ if (o is NSOutlook.TaskItem)
+ return new TaskItemWrapper((NSOutlook.TaskItem)o);
+ // TODO: support others?
+ // The caller assumes a wrapper will be returned, so any lingering object here will never be released.
+ // TODO: do this only if caller has mustRelease
+ ComRelease.Release(o);
return null;
}
@@ -74,60 +75,45 @@ namespace Acacia.Stubs.OutlookWrappers
{
return (Type)Wrap(o, mustRelease);
}
-
+ // TODO: are these not the same now? Differ only on wrong type?
public static Type WrapOrDefault(object o, bool mustRelease = true)
where Type : IBase
{
IBase wrapped = Wrap(o, mustRelease);
if (wrapped is Type)
return (Type)wrapped;
+
+ // TODO: release if required
if (wrapped != null)
wrapped.Dispose();
return default(Type);
}
- public static OlItemType OutlookItemType()
+ public static NSOutlook.OlItemType OutlookItemType()
where ItemType: IItem
{
Type type = typeof(ItemType);
if (type == typeof(IContactItem))
- return OlItemType.olContactItem;
+ return NSOutlook.OlItemType.olContactItem;
if (type == typeof(IDistributionList))
- return OlItemType.olDistributionListItem;
+ return NSOutlook.OlItemType.olDistributionListItem;
throw new NotImplementedException(); // TODO
}
- public static OlUserPropertyType OutlookPropertyType()
+ public static NSOutlook.OlUserPropertyType OutlookPropertyType()
{
Type type = typeof(PropType);
if (type == typeof(string))
- return OlUserPropertyType.olText;
+ return NSOutlook.OlUserPropertyType.olText;
if (type == typeof(DateTime))
- return OlUserPropertyType.olDateTime;
+ return NSOutlook.OlUserPropertyType.olDateTime;
if (type == typeof(int))
- return OlUserPropertyType.olInteger;
+ return NSOutlook.OlUserPropertyType.olInteger;
if (type.IsEnum)
- return OlUserPropertyType.olInteger;
+ return NSOutlook.OlUserPropertyType.olInteger;
if (type == typeof(string[]))
- return OlUserPropertyType.olKeywords;
+ return NSOutlook.OlUserPropertyType.olKeywords;
throw new NotImplementedException(); // TODO
}
-
-
- // TODO: this needs to go elsewhere
- public static IFolder GetFolderFromID(string folderId)
- {
- NameSpace nmspace = ThisAddIn.Instance.Application.Session;
- try
- {
- Folder f = (Folder)nmspace.GetFolderFromID(folderId);
- return Wrap(f);
- }
- finally
- {
- ComRelease.Release(nmspace);
- }
- }
-
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/NoteItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/NoteItemWrapper.cs
index 0b8a55a..e3ebaa2 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/NoteItemWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/NoteItemWrapper.cs
@@ -14,32 +14,44 @@
///
/// Consult LICENSE file for details
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using Acacia.Utils;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
- public class NoteItemWrapper : OutlookItemWrapper, INoteItem
+ public class NoteItemWrapper : OutlookItemWrapper, INoteItem
{
- internal NoteItemWrapper(NoteItem item)
+ internal NoteItemWrapper(NSOutlook.NoteItem item)
:
base(item)
{
}
- protected override PropertyAccessor GetPropertyAccessor()
+ #region Wrapper methods
+
+ protected override NSOutlook.UserProperties GetUserProperties()
+ {
+ throw new NotSupportedException("NoteItem does not support user properties");
+ }
+
+ protected override NSOutlook.PropertyAccessor GetPropertyAccessor()
{
return _item.PropertyAccessor;
}
- public override string ToString() { return "Note: " + Subject; }
+ public override string ToString()
+ {
+ return "Note:" + Subject;
+ }
- #region Properties
+ #endregion
+
+ #region IItem implementation
public string Body
{
@@ -50,49 +62,81 @@ namespace Acacia.Stubs.OutlookWrappers
public string Subject
{
get { return _item.Subject; }
- set { throw new NotSupportedException(); }
+ set
+ {
+ throw new NotSupportedException("NoteItem does not support setting body");
+ }
}
- public IStore Store { get { return StoreWrapper.Wrap(_item.Parent?.Store); } }
- // TODO: release needed
- public string StoreId { get { return _item.Parent?.Store?.StoreID; } }
- public string StoreDisplayName { get { return _item.Parent?.Store?.DisplayName; } }
-
- #endregion
-
- #region Methods
-
- protected override UserProperties GetUserProperties()
- {
- // Note item doesn't have user properties
- throw new NotSupportedException();
- }
-
- public void Delete() { _item.Delete(); }
public void Save() { _item.Save(); }
#endregion
+ #region IBase implementation
+
+ public string EntryId { get { return _item.EntryID; } }
+
public IFolder Parent
{
- get { return (IFolder)Mapping.Wrap(_item.Parent as Folder); }
+ get
+ {
+ // The wrapper manages the returned folder
+ return Mapping.Wrap(_item.Parent as NSOutlook.Folder);
+ }
}
+
public string ParentEntryId
{
get
{
- Folder parent = _item.Parent;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folder parent = com.Add(_item.Parent);
return parent?.EntryID;
}
- finally
- {
- ComRelease.Release(parent);
- }
}
}
- public string EntryId { get { return _item.EntryID; } }
+ public IStore Store
+ {
+ get
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ return StoreWrapper.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
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs
index 683e28c..0e86002 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs
@@ -1,10 +1,10 @@
using Acacia.Utils;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
@@ -20,8 +20,8 @@ namespace Acacia.Stubs.OutlookWrappers
{
using (ComRelease com = new ComRelease())
{
- UserProperties userProperties = com.Add(GetUserProperties());
- UserProperty prop = com.Add(userProperties.Find(name, true));
+ NSOutlook.UserProperties userProperties = com.Add(GetUserProperties());
+ NSOutlook.UserProperty prop = com.Add(userProperties.Find(name, true));
if (prop == null)
return default(Type);
@@ -35,8 +35,8 @@ namespace Acacia.Stubs.OutlookWrappers
{
using (ComRelease com = new ComRelease())
{
- UserProperties userProperties = com.Add(GetUserProperties());
- UserProperty prop = com.Add(userProperties.Find(name, true));
+ NSOutlook.UserProperties userProperties = com.Add(GetUserProperties());
+ NSOutlook.UserProperty prop = com.Add(userProperties.Find(name, true));
if (prop == null)
prop = userProperties.Add(name, Mapping.OutlookPropertyType());
@@ -52,6 +52,10 @@ namespace Acacia.Stubs.OutlookWrappers
}
}
- abstract protected UserProperties GetUserProperties();
+ ///
+ /// Returns the UserProperties associated with the current item.
+ ///
+ /// An unwrapped UserProperties object. The caller is responsible for releasing this.
+ abstract protected NSOutlook.UserProperties GetUserProperties();
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs
index 86221aa..fe56318 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs
@@ -15,7 +15,6 @@
/// Consult LICENSE file for details
using Acacia.Features.DebugSupport;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -23,6 +22,7 @@ using Acacia.Utils;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
@@ -70,9 +70,10 @@ namespace Acacia.Stubs.OutlookWrappers
#region Properties implementation
- private PropertyAccessor _props;
+ // Assigned in Props, released in DoRelease
+ private NSOutlook.PropertyAccessor _props;
- private PropertyAccessor Props
+ private NSOutlook.PropertyAccessor Props
{
get
{
@@ -88,7 +89,7 @@ namespace Acacia.Stubs.OutlookWrappers
/// Returns the wrapped item's property accessor.
///
/// The property accessor. The caller is responsible for disposing this.
- abstract protected PropertyAccessor GetPropertyAccessor();
+ abstract protected NSOutlook.PropertyAccessor GetPropertyAccessor();
#endregion
@@ -127,30 +128,6 @@ namespace Acacia.Stubs.OutlookWrappers
}
}
- public DateTime? AttrLastVerbExecutionTime
- {
- get
- {
- return Props.GetProperty(OutlookConstants.PR_LAST_VERB_EXECUTION_TIME) as DateTime?;
- }
- set
- {
- Props.SetProperty(OutlookConstants.PR_LAST_VERB_EXECUTION_TIME, value);
- }
- }
-
- public int AttrLastVerbExecuted
- {
- get
- {
- return Props.GetProperty(OutlookConstants.PR_LAST_VERB_EXECUTED);
- }
- set
- {
- Props.SetProperty(OutlookConstants.PR_LAST_VERB_EXECUTED, value);
- }
- }
-
public object GetProperty(string property)
{
try
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs
index 440aa03..1e26dae 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs
@@ -19,12 +19,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Microsoft.Office.Interop.Outlook;
using Acacia.Utils;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
- class SearchWrapper : ISearch
+ class SearchWrapper : ComWrapper, ISearch
where ItemType : IItem
{
private interface SearchTerm
@@ -151,13 +151,23 @@ namespace Acacia.Stubs.OutlookWrappers
}
private readonly List terms = new List();
- private readonly Items _items;
+ private NSOutlook.Items _items;
- public SearchWrapper(Items items)
+ ///
+ /// Constructor.
+ ///
+ /// The items to search. The new object takes ownership
+ public SearchWrapper(NSOutlook.Items items)
{
this._items = items;
}
+ protected override void DoRelease()
+ {
+ ComRelease.Release(_items);
+ _items = null;
+ }
+
public ISearchOperator AddOperator(SearchOperator oper)
{
SearchOperatorImpl so = new SearchOperatorImpl(oper);
@@ -176,11 +186,13 @@ namespace Acacia.Stubs.OutlookWrappers
{
List values = new List();
string filter = MakeFilter();
+
object value = _items.Find(filter);
while(value != null)
{
if (values.Count < maxResults)
{
+ // Wrap and add if it returns an object. If not, WrapOrDefault will release it
ItemType wrapped = Mapping.WrapOrDefault(value);
if (wrapped != null)
{
@@ -189,6 +201,7 @@ namespace Acacia.Stubs.OutlookWrappers
}
else
{
+ // Release if not returned. Keep looping to release any others
ComRelease.Release(value);
}
value = _items.FindNext();
@@ -198,6 +211,7 @@ namespace Acacia.Stubs.OutlookWrappers
public ItemType SearchOne()
{
+ // Wrap manages com object in value
object value = _items.Find(MakeFilter());
if (value == null)
return default(ItemType);
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs
index c148bf1..e0ea714 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs
@@ -15,31 +15,44 @@
/// Consult LICENSE file for details
using Acacia.Utils;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
+
namespace Acacia.Stubs.OutlookWrappers
{
- public class StorageItemWrapper : OutlookItemWrapper, IStorageItem
+ public class StorageItemWrapper : OutlookItemWrapper, IStorageItem
{
- public StorageItemWrapper(StorageItem item)
+ public StorageItemWrapper(NSOutlook.StorageItem item)
:
base(item)
{
}
- protected override PropertyAccessor GetPropertyAccessor()
+ #region Wrapper methods
+
+ protected override NSOutlook.UserProperties GetUserProperties()
+ {
+ return _item.UserProperties;
+ }
+
+ protected override NSOutlook.PropertyAccessor GetPropertyAccessor()
{
return _item.PropertyAccessor;
}
- public override string ToString() { return "StorageItem"; }
+ public override string ToString()
+ {
+ return "StorageItem";
+ }
- #region Properties
+ #endregion
+
+ #region IItem implementation
public string Body
{
@@ -53,45 +66,75 @@ namespace Acacia.Stubs.OutlookWrappers
set { _item.Subject = value; }
}
- public IStore Store { get { return StoreWrapper.Wrap(_item.Parent?.Store); } }
- // TODO: release needed
- public string StoreId { get { return _item.Parent?.Store?.StoreID; } }
- public string StoreDisplayName { get { return _item.Parent?.Store?.DisplayName; } }
-
- #endregion
-
- #region Methods
-
- protected override UserProperties GetUserProperties()
- {
- return _item.UserProperties;
- }
-
- public void Delete() { _item.Delete(); }
public void Save() { _item.Save(); }
#endregion
+ #region IBase implementation
+
+ public string EntryId { get { return _item.EntryID; } }
+
public IFolder Parent
{
- get { return (IFolder)Mapping.Wrap(_item.Parent as Folder); }
+ get
+ {
+ // The wrapper manages the returned folder
+ return Mapping.Wrap(_item.Parent as NSOutlook.Folder);
+ }
}
+
public string ParentEntryId
{
get
{
- Folder parent = _item.Parent;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folder parent = com.Add(_item.Parent);
return parent?.EntryID;
}
- finally
- {
- ComRelease.Release(parent);
- }
}
}
- public string EntryId { get { return _item.EntryID; } }
+ public IStore Store
+ {
+ get
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ return StoreWrapper.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
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs
index e17b4c4..30f1241 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs
@@ -19,21 +19,21 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Microsoft.Office.Interop.Outlook;
using Acacia.Utils;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
public class StoreWrapper : ComWrapper, IStore
{
- public static IStore Wrap(Store store)
+ public static IStore Wrap(NSOutlook.Store store)
{
return store == null ? null : new StoreWrapper(store);
}
- private Store _store;
+ private NSOutlook.Store _store;
- private StoreWrapper(Store store)
+ private StoreWrapper(NSOutlook.Store store)
{
this._store = store;
}
@@ -46,21 +46,20 @@ namespace Acacia.Stubs.OutlookWrappers
public IFolder GetRootFolder()
{
- return new FolderWrapper((Folder)_store.GetRootFolder());
+ // FolderWrapper manages the returned Folder
+ return new FolderWrapper((NSOutlook.Folder)_store.GetRootFolder());
}
public IItem GetItemFromID(string id)
{
- NameSpace nmspace = _store.Session;
- try
- {
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.NameSpace nmspace = com.Add(_store.Session);
+
+ // Get the item; the wrapper manages it
object o = nmspace.GetItemFromID(id);
return Mapping.Wrap(o);
}
- finally
- {
- ComRelease.Release(nmspace);
- }
}
public string DisplayName { get { return _store.DisplayName; } }
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/TaskItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/TaskItemWrapper.cs
index cc05464..833f7a1 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/TaskItemWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/TaskItemWrapper.cs
@@ -15,31 +15,44 @@
/// Consult LICENSE file for details
using Acacia.Utils;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
+
namespace Acacia.Stubs.OutlookWrappers
{
- public class TaskItemWrapper : OutlookItemWrapper, ITaskItem
+ public class TaskItemWrapper : OutlookItemWrapper, ITaskItem
{
- internal TaskItemWrapper(TaskItem item)
+ internal TaskItemWrapper(NSOutlook.TaskItem item)
:
base(item)
{
}
- protected override PropertyAccessor GetPropertyAccessor()
+ #region Wrapper methods
+
+ protected override NSOutlook.UserProperties GetUserProperties()
+ {
+ return _item.UserProperties;
+ }
+
+ protected override NSOutlook.PropertyAccessor GetPropertyAccessor()
{
return _item.PropertyAccessor;
}
- public override string ToString() { return "Task: " + Subject; }
+ public override string ToString()
+ {
+ return "Task:" + Subject;
+ }
- #region Properties
+ #endregion
+
+ #region IItem implementation
public string Body
{
@@ -50,48 +63,78 @@ namespace Acacia.Stubs.OutlookWrappers
public string Subject
{
get { return _item.Subject; }
- set { throw new NotSupportedException(); }
+ set { _item.Subject = value; }
}
- public IStore Store { get { return StoreWrapper.Wrap(_item.Parent?.Store); } }
- // TODO: release needed
- public string StoreId { get { return _item.Parent?.Store?.StoreID; } }
- public string StoreDisplayName { get { return _item.Parent?.Store?.DisplayName; } }
-
- #endregion
-
- #region Methods
-
- protected override UserProperties GetUserProperties()
- {
- return _item.UserProperties;
- }
-
- public void Delete() { _item.Delete(); }
public void Save() { _item.Save(); }
#endregion
+ #region IBase implementation
+
+ public string EntryId { get { return _item.EntryID; } }
+
public IFolder Parent
{
- get { return (IFolder)Mapping.Wrap(_item.Parent as Folder); }
+ get
+ {
+ // The wrapper manages the returned folder
+ return Mapping.Wrap(_item.Parent as NSOutlook.Folder);
+ }
}
+
public string ParentEntryId
{
get
{
- Folder parent = _item.Parent;
- try
+ using (ComRelease com = new ComRelease())
{
+ NSOutlook.Folder parent = com.Add(_item.Parent);
return parent?.EntryID;
}
- finally
- {
- ComRelease.Release(parent);
- }
}
}
- public string EntryId { get { return _item.EntryID; } }
+ public IStore Store
+ {
+ get
+ {
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.Folder parent = com.Add(_item.Parent);
+ return StoreWrapper.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
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs
index 640a8f0..c1fb633 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs
@@ -19,8 +19,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
-using Outlook = Microsoft.Office.Interop.Outlook;
-using Office = Microsoft.Office.Core;
using Acacia.Features;
using System.Threading;
using System.Windows.Forms;
@@ -33,27 +31,22 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;
using Acacia.Native;
+using Acacia.Stubs;
+using Acacia.Stubs.OutlookWrappers;
namespace Acacia
{
public partial class ThisAddIn
{
-
- public static ThisAddIn Instance
+ public static IAddIn Instance
{
get;
private set;
}
+ // TODO: remove?
private Control _dispatcher;
- public void InvokeUI(Action action)
- {
- // [ZP-992] For some reason using the dispatcher causes a deadlock
- // since switching to UI-chunked tasks. Running directly works.
- action();
- }
-
#region Features
///
@@ -73,17 +66,6 @@ namespace Acacia
private set;
}
- public FeatureType GetFeature()
- where FeatureType : Feature
- {
- foreach(Feature feature in Features)
- {
- if (feature is FeatureType)
- return (FeatureType)feature;
- }
- return default(FeatureType);
- }
-
#region Startup / Shutdown
private void ThisAddIn_Startup(object sender, System.EventArgs args)
@@ -104,10 +86,10 @@ namespace Acacia
return;
}
- Instance = this;
+ Instance = new AddInWrapper(this);
// Set the culture info from Outlook's language setting rather than the OS setting
- int lcid = Application.LanguageSettings.get_LanguageID(Office.MsoAppLanguageID.msoLanguageIDUI);
+ int lcid = Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(lcid);
// Create a dispatcher
@@ -122,7 +104,7 @@ namespace Acacia
}
// Create the watcher
- Watcher = new ZPushWatcher(Application);
+ Watcher = new ZPushWatcher(Instance);
OutlookUI.Watcher = Watcher;
// Allow to features to register whatever they need
@@ -176,6 +158,7 @@ namespace Acacia
{
try
{
+ // TODO: is any management of Pages needed here?
Pages.Add(new SettingsPage(Features.ToArray()), Properties.Resources.ThisAddIn_Title);
}
catch(System.Exception e)
@@ -192,35 +175,6 @@ namespace Acacia
#endregion
- #region Misc helpers
-
- public void SendReceive()
- {
- Outlook.NameSpace session = Application.Session;
- session.SendAndReceive(false);
- ComRelease.Release(session);
- }
-
- public void Restart()
- {
- // Can not use the assembly location, as that is in the GAC
- string codeBase = Assembly.GetExecutingAssembly().CodeBase;
- UriBuilder uri = new UriBuilder(codeBase);
- string path = Uri.UnescapeDataString(uri.Path);
- // Create the path to the restarter
- path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), "OutlookRestarter.exe");
-
- // Run that
- Process process = new Process();
- process.StartInfo = new ProcessStartInfo(path, Environment.CommandLine);
- process.Start();
-
- // And close us
- Application.Quit();
- }
-
- #endregion
-
#region Ribbons
private OutlookUI _outlookUI;
@@ -245,41 +199,6 @@ namespace Acacia
}
}
- #region Window handle
-
- private class WindowHandle : IWin32Window
- {
- private IntPtr hWnd;
-
- public WindowHandle(IntPtr hWnd)
- {
- this.hWnd = hWnd;
- }
-
- public IntPtr Handle
- {
- get
- {
- return hWnd;
- }
- }
- }
-
- public IWin32Window Window
- {
- get
- {
- var win = Application.ActiveWindow() as IOleWindow;
- if (win == null)
- return null;
- IntPtr hWnd;
- win.GetWindow(out hWnd);
- return new WindowHandle(hWnd);
- }
- }
-
- #endregion
-
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return OutlookUI;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/GABLookupControl.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/GABLookupControl.cs
index 17dc99a..5088051 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/GABLookupControl.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/GABLookupControl.cs
@@ -224,23 +224,25 @@ namespace Acacia.UI
public List Lookup(string text, int max)
{
// Begin GAB lookup, search on full name or username
- ISearch search = _gab.Contacts.Search();
- ISearchOperator oper = search.AddOperator(SearchOperator.Or);
- oper.AddField("urn:schemas:contacts:cn").SetOperation(SearchOperation.Like, text + "%");
- oper.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Like, text + "%");
-
- // Fetch the results up to the limit.
- // TODO: make limit a property
- List users = new List();
- foreach (IContactItem result in search.Search(max))
+ using (ISearch search = _gab.Contacts.Search())
{
- using (result)
- {
- users.Add(new GABUser(result.FullName, result.CustomerID));
- }
- }
+ ISearchOperator oper = search.AddOperator(SearchOperator.Or);
+ oper.AddField("urn:schemas:contacts:cn").SetOperation(SearchOperation.Like, text + "%");
+ oper.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Like, text + "%");
- return users;
+ // Fetch the results up to the limit.
+ // TODO: make limit a property
+ List users = new List();
+ foreach (IContactItem result in search.Search(max))
+ {
+ using (result)
+ {
+ users.Add(new GABUser(result.FullName, result.CustomerID));
+ }
+ }
+
+ return users;
+ }
}
public GABUser LookupExact(string username)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookImageList.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookImageList.cs
index 2347e02..048d413 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookImageList.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookImageList.cs
@@ -128,7 +128,8 @@ namespace Acacia.UI.Outlook
Images.ColorDepth = ColorDepth.Depth32Bit;
Images.ImageSize = new Size(16, 16);
- CommandBars cmdBars = ThisAddIn.Instance.Application.ActiveWindow().CommandBars;
+ // TODO: memory management
+ CommandBars cmdBars = ThisAddIn.Instance.RawApp.ActiveWindow().CommandBars;
foreach (string id in icons)
{
IPictureDisp pict = cmdBars.GetImageMso(id, Images.ImageSize.Width, Images.ImageSize.Height);
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs
index f889750..1f88a94 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs
@@ -14,7 +14,6 @@
///
/// Consult LICENSE file for details
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Drawing;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/SettingsDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/SettingsDialog.cs
index 0e8d30f..68bc4a9 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/SettingsDialog.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/SettingsDialog.cs
@@ -23,7 +23,6 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
-using Microsoft.Office.Interop.Outlook;
namespace Acacia.UI
{
@@ -48,19 +47,20 @@ namespace Acacia.UI
{
get
{
- return ThisAddIn.Instance.Application;
+ return null;
+ // TODO return ThisAddIn.Instance.Application;
}
}
- public OlObjectClass Class
+ public Microsoft.Office.Interop.Outlook.OlObjectClass Class
{
get
{
- return OlObjectClass.olApplication;
+ return Microsoft.Office.Interop.Outlook.OlObjectClass.olApplication;
}
}
- public NameSpace Session
+ public Microsoft.Office.Interop.Outlook.NameSpace Session
{
get
{
@@ -68,7 +68,7 @@ namespace Acacia.UI
}
}
- dynamic PropertyPageSite.Parent
+ dynamic Microsoft.Office.Interop.Outlook.PropertyPageSite.Parent
{
get
{
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/SettingsPage.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/SettingsPage.cs
index 7a128af..e921a73 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/SettingsPage.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/SettingsPage.cs
@@ -25,11 +25,12 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Acacia.Features;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.UI
{
[ComVisible(true)]
- public partial class SettingsPage : UserControl, Microsoft.Office.Interop.Outlook.PropertyPage
+ public partial class SettingsPage : UserControl, NSOutlook.PropertyPage
{
private readonly Dictionary _featuresDirty = new Dictionary();
@@ -78,8 +79,8 @@ namespace Acacia.UI
Dirty = _featuresDirty.Values.Aggregate((a, b) => a | b);
}
- private Microsoft.Office.Interop.Outlook.PropertyPageSite _propertyPageSite;
- public Microsoft.Office.Interop.Outlook.PropertyPageSite PropertyPageSite
+ private NSOutlook.PropertyPageSite _propertyPageSite;
+ public NSOutlook.PropertyPageSite PropertyPageSite
{
get
{
@@ -96,7 +97,8 @@ namespace Acacia.UI
System.Reflection.MethodInfo methodInfo = oleObjectType.GetMethod("GetClientSite");
Object propertyPageSite = methodInfo.Invoke(this, null);
- _propertyPageSite = (Microsoft.Office.Interop.Outlook.PropertyPageSite)propertyPageSite;
+ // TODO: does this need to be released?
+ _propertyPageSite = (NSOutlook.PropertyPageSite)propertyPageSite;
}
return _propertyPageSite;
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/ComRelease.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/ComRelease.cs
index b20488d..5d089ab 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/ComRelease.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/ComRelease.cs
@@ -55,6 +55,12 @@ namespace Acacia.Utils
}
}
+ public static void Release(params object[] objs)
+ {
+ foreach (object o in objs)
+ Release(o);
+ }
+
public static void Release(object o)
{
if (!Enabled)
@@ -67,7 +73,7 @@ namespace Acacia.Utils
Logger.Instance.TraceExtra(typeof(ComRelease), "Releasing object: {0:X} @ {1}", GetObjAddress(o),
new System.Diagnostics.StackTrace());
}
- Marshal.FinalReleaseComObject(o);
+ Marshal.ReleaseComObject(o);
}
private static long GetObjAddress(object o)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
index 2008541..d2c6d5e 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
@@ -14,7 +14,6 @@
///
/// Consult LICENSE file for details
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -22,6 +21,7 @@ using System.Text;
using System.Threading.Tasks;
using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Utils
{
@@ -47,8 +47,10 @@ namespace Acacia.Utils
public event MailResponseEventHandler Respond;
public event MailResponseEventHandler Reply;
- private void OnReply(MailItem mail, MailItem response)
+ private void OnReply(NSOutlook.MailItem mail, NSOutlook.MailItem response)
{
+ // TODO: check release of first item
+ // TODO: release if not sending event
try
{
if ((Reply != null || Respond != null) && mail != null)
@@ -70,8 +72,10 @@ namespace Acacia.Utils
}
public event MailResponseEventHandler ReplyAll;
- private void OnReplyAll(MailItem mail, MailItem response)
+ private void OnReplyAll(NSOutlook.MailItem mail, NSOutlook.MailItem response)
{
+ // TODO: check release of first item
+ // TODO: release if not sending event
try
{
if ((ReplyAll != null || Respond != null) && mail != null)
@@ -93,8 +97,10 @@ namespace Acacia.Utils
}
public event MailResponseEventHandler Forward;
- private void OnForward(MailItem mail, MailItem response)
+ private void OnForward(NSOutlook.MailItem mail, NSOutlook.MailItem response)
{
+ // TODO: check release of first item
+ // TODO: release if not sending event
try
{
if ((Forward != null || Respond != null) && mail != null)
@@ -116,8 +122,10 @@ namespace Acacia.Utils
}
public event MailEventHandler Read;
- private void OnRead(MailItem mail)
+ private void OnRead(NSOutlook.MailItem mail)
{
+ // TODO: check release of first item
+ // TODO: release if not sending event
try
{
if (Read != null && mail != null)
@@ -180,6 +188,7 @@ namespace Acacia.Utils
{
try
{
+ // TODO: release item if event not sent
if (ItemSend != null && item != null)
{
using (IMailItem wrapped = Mapping.WrapOrDefault(item, false))
@@ -199,93 +208,104 @@ namespace Acacia.Utils
#region Implementation
- public MailEvents(Application app)
+ public MailEvents(IAddIn app)
{
app.ItemLoad += OnItemLoad;
app.ItemSend += OnItemSend;
}
- void OnItemLoad(object item)
+ private void OnItemLoad(object item)
{
- ItemEvents_10_Event hasEvents = item as ItemEvents_10_Event;
+ NSOutlook.ItemEvents_10_Event hasEvents = item as NSOutlook.ItemEvents_10_Event;
if (hasEvents != null)
{
new MailEventHooker(hasEvents, this);
}
}
- private class MailEventHooker
+ private class MailEventHooker : ComWrapper
{
- private readonly ItemEvents_10_Event item;
- private readonly MailEvents events;
+ private NSOutlook.ItemEvents_10_Event _item;
+ private readonly MailEvents _events;
+ private int _id;
+ private static int nextId;
- public MailEventHooker(ItemEvents_10_Event item, MailEvents events)
+ public MailEventHooker(NSOutlook.ItemEvents_10_Event item, MailEvents events)
{
- this.item = item;
- this.events = events;
+ this._id = ++nextId;
+ this._item = item;
+ this._events = events;
HookEvents(true);
}
+ protected override void DoRelease()
+ {
+ Logger.Instance.Debug(this, "DoRelease: {0}", _id);
+ ComRelease.Release(_item);
+ _item = null;
+ }
+
private void HookEvents(bool add)
{
- ItemEvents_10_Event events = this.item;
-
if (add)
{
- events.BeforeDelete += HandleBeforeDelete;
- events.Forward += HandleForward;
- events.Read += HandleRead;
- events.Reply += HandleReply;
- events.ReplyAll += HandleReplyAll;
- events.Unload += HandleUnload;
- events.Write += HandleWrite;
+ _item.BeforeDelete += HandleBeforeDelete;
+ _item.Forward += HandleForward;
+ _item.Read += HandleRead;
+ _item.Reply += HandleReply;
+ _item.ReplyAll += HandleReplyAll;
+ _item.Unload += HandleUnload;
+ _item.Write += HandleWrite;
}
else
{
- events.BeforeDelete -= HandleBeforeDelete;
- events.Forward -= HandleForward;
- events.Read -= HandleRead;
- events.Reply -= HandleReply;
- events.ReplyAll -= HandleReplyAll;
- events.Unload -= HandleUnload;
- events.Write -= HandleWrite;
+ _item.BeforeDelete -= HandleBeforeDelete;
+ _item.Forward -= HandleForward;
+ _item.Read -= HandleRead;
+ _item.Reply -= HandleReply;
+ _item.ReplyAll -= HandleReplyAll;
+ _item.Unload -= HandleUnload;
+ _item.Write -= HandleWrite;
}
}
private void HandleBeforeDelete(object item, ref bool cancel)
{
- events.OnBeforeDelete(item, ref cancel);
+ _events.OnBeforeDelete(item, ref cancel);
}
private void HandleForward(object response, ref bool cancel)
{
- events.OnForward(item as MailItem, response as MailItem);
+ _events.OnForward(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
}
private void HandleRead()
{
- events.OnRead(item as MailItem);
+ _events.OnRead(_item as NSOutlook.MailItem);
}
private void HandleReply(object response, ref bool cancel)
{
- events.OnReply(item as MailItem, response as MailItem);
+ _events.OnReply(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
}
private void HandleReplyAll(object response, ref bool cancel)
{
- events.OnReplyAll(item as MailItem, response as MailItem);
+ _events.OnReplyAll(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
}
private void HandleUnload()
{
+ Logger.Instance.Debug(this, "HandleUnload: {0}", _id);
// All events must be unhooked on unload, otherwise a resource leak is created.
HookEvents(false);
+ Dispose();
}
private void HandleWrite(ref bool cancel)
{
- events.OnWrite(item, ref cancel);
+ Logger.Instance.Debug(this, "HandleWrite: {0}", _id);
+ _events.OnWrite(_item, ref cancel);
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/OutlookRegistryUtils.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/OutlookRegistryUtils.cs
index 4d61861..4a7110a 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/OutlookRegistryUtils.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/OutlookRegistryUtils.cs
@@ -29,7 +29,7 @@ namespace Acacia.Utils
public static RegistryKey OpenOutlookKey(string suffix = null, RegistryKeyPermissionCheck permissions = RegistryKeyPermissionCheck.Default)
{
// Determine the base path
- string[] versionParts = ThisAddIn.Instance.Application.Version.Split('.');
+ string[] versionParts = ThisAddIn.Instance.Version.Split('.');
string versionString = versionParts[0] + "." + versionParts[1];
string baseKeyPath = string.Format(OutlookConstants.REG_KEY_BASE, versionString);
return RegistryUtil.OpenKeyImpl(baseKeyPath, suffix, false, permissions);
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Util.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Util.cs
index e565bda..0803c1a 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Util.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Util.cs
@@ -15,8 +15,8 @@
/// Consult LICENSE file for details
using Acacia.ZPush;
-using Microsoft.Office.Interop.Outlook;
using System;
+using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -44,5 +44,40 @@ namespace Acacia.Utils
return a.Equals(b);
}
+
+ public static IEnumerable RawEnum(this IEnumerable source, bool releaseItems = true)
+ {
+ foreach (T item in source)
+ {
+ try
+ {
+ yield return item;
+ }
+ finally
+ {
+ if (releaseItems)
+ ComRelease.Release(item);
+ }
+ }
+ ComRelease.Release(source);
+ }
+
+ // TODO: check this
+ public static IEnumerable RawEnum(this IEnumerable source, bool releaseItems = true)
+ {
+ foreach (object item in source)
+ {
+ try
+ {
+ yield return item;
+ }
+ finally
+ {
+ if (releaseItems)
+ ComRelease.Release(item);
+ }
+ }
+ ComRelease.Release(source);
+ }
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/FolderRegistration.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/FolderRegistration.cs
index 402b985..d3f6938 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/FolderRegistration.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/FolderRegistration.cs
@@ -16,7 +16,6 @@
using Acacia.Features;
using Acacia.Stubs;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs
index d3c89c9..6f4d531 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs
@@ -17,7 +17,6 @@
using Acacia.Stubs;
using Acacia.Utils;
using Acacia.ZPush.Connect;
-using Microsoft.Office.Interop.Outlook;
using Microsoft.Win32;
using System;
using System.Collections.Concurrent;
@@ -28,6 +27,7 @@ using System.Security;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.ZPush
{
@@ -37,14 +37,16 @@ namespace Acacia.ZPush
#region Miscellaneous
private readonly string _regPath;
- private readonly Store _store;
+
+ // TODO: this should probably be wrapped. Make ZPushAccount ComWrapper?
+ private readonly NSOutlook.Store _store;
///
/// Constructor.
///
/// They registry key containing the account settings.
/// The store this account represents.
- internal ZPushAccount(string regPath, Store store)
+ internal ZPushAccount(string regPath, NSOutlook.Store store)
{
this._regPath = regPath;
this._store = store;
@@ -72,7 +74,8 @@ namespace Acacia.ZPush
///
public void SendReceive()
{
- ThisAddIn.Instance.SendReceive();
+ // TODO: ThisAddIn.Instance.SendReceive();
+ throw new NotImplementedException();
}
#endregion
@@ -80,7 +83,8 @@ namespace Acacia.ZPush
#region Properties
[Browsable(false)]
- public Store Store
+ // TODO: remove this
+ public NSOutlook.Store Store
{
get
{
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccounts.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccounts.cs
index d563775..60a6d7d 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccounts.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccounts.cs
@@ -16,13 +16,13 @@
using Acacia.Stubs;
using Acacia.Utils;
-using Microsoft.Office.Interop.Outlook;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.ZPush
{
@@ -33,9 +33,10 @@ namespace Acacia.ZPush
public class ZPushAccounts
{
private readonly ZPushWatcher _watcher;
- private readonly Application _app;
- private readonly NameSpace _session;
- private readonly Stores _stores;
+ // TODO: wrap these
+ private readonly NSOutlook.Application _app;
+ private readonly NSOutlook.NameSpace _session;
+ private readonly NSOutlook.Stores _stores;
///
/// ZPushAccounts indexed by SMTPAddress. Null values are not allowed.
@@ -48,7 +49,7 @@ namespace Acacia.ZPush
///
private readonly Dictionary _accountsByStoreId = new Dictionary();
- public ZPushAccounts(ZPushWatcher watcher, Application app)
+ public ZPushAccounts(ZPushWatcher watcher, NSOutlook.Application app)
{
this._watcher = watcher;
this._app = app;
@@ -66,7 +67,7 @@ namespace Acacia.ZPush
{
// Process existing accounts
using (ComRelease com = new ComRelease())
- foreach (Account account in com.Add(_session.Accounts))
+ foreach (NSOutlook.Account account in com.Add(_session.Accounts))
{
Tasks.Task(null, "AccountCheck", () =>
{
@@ -113,7 +114,7 @@ namespace Acacia.ZPush
{
// Collect all the store ids
HashSet stores = new HashSet();
- foreach (Store store in _stores)
+ foreach (NSOutlook.Store store in _stores)
{
try
{
@@ -184,22 +185,18 @@ namespace Acacia.ZPush
return null;
}
- public ZPushAccount GetAccount(MAPIFolder folder)
+ public ZPushAccount GetAccount(NSOutlook.MAPIFolder folder)
{
- ZPushAccount zpush = null;
- Store store = folder.Store;
- try
+ using (ComRelease com = new ComRelease())
{
+ ZPushAccount zpush = null;
+ NSOutlook.Store store = com.Add(folder.Store);
string storeId = store?.StoreID;
if (storeId == null)
return null;
_accountsByStoreId.TryGetValue(storeId, out zpush);
return zpush;
}
- finally
- {
- ComRelease.Release(store);
- }
}
public ZPushAccount GetAccount(string smtpAddress)
@@ -214,12 +211,12 @@ namespace Acacia.ZPush
///
/// The account. This function will release the handle
/// The ZPushAccount, or null if not a ZPush account.
- private ZPushAccount GetAccount(Account account)
+ private ZPushAccount GetAccount(NSOutlook.Account account)
{
try
{
// Only EAS accounts can be zpush accounts
- if (account.AccountType != OlAccountType.olEas)
+ if (account.AccountType != NSOutlook.OlAccountType.olEas)
return null;
// Check for a cached value
@@ -239,14 +236,14 @@ namespace Acacia.ZPush
///
/// Event handler for Stores.StoreAdded event.
///
- internal void StoreAdded(Store s)
+ private void StoreAdded(NSOutlook.Store s)
{
try
{
using (ComRelease com = new ComRelease())
{
Logger.Instance.Trace(this, "StoreAdded: {0}", s.StoreID);
- foreach (Store store in com.Add(com.Add(_app.Session).Stores))
+ foreach (NSOutlook.Store store in com.Add(com.Add(_app.Session).Stores))
{
if (!_accountsByStoreId.ContainsKey(store.StoreID))
{
@@ -287,11 +284,12 @@ namespace Acacia.ZPush
///
/// Creates the ZPushAccount for the account, from the registry values.
///
- /// The account.
+ /// The account. The caller is responsible for releasing this.
/// The associated ZPushAccount
/// If the registry key cannot be found
- private ZPushAccount CreateFromRegistry(Account account)
+ private ZPushAccount CreateFromRegistry(NSOutlook.Account account)
{
+ // TODO: check that caller releases account everywhere
using (ComRelease com = new ComRelease())
using (RegistryKey baseKey = FindRegistryKey(account))
{
@@ -302,7 +300,7 @@ namespace Acacia.ZPush
string storeId = ZPushAccount.GetStoreId(baseKey.Name);
// Find the store
- Store store = _app.Session.GetStoreFromID(storeId);
+ NSOutlook.Store store = _app.Session.GetStoreFromID(storeId);
// Done, create and register
ZPushAccount zpush = new ZPushAccount(baseKey.Name, store);
@@ -316,7 +314,7 @@ namespace Acacia.ZPush
///
/// The store
/// The ZPushAccount, or null if no account is associated with the store
- private ZPushAccount TryCreateFromRegistry(Store store)
+ private ZPushAccount TryCreateFromRegistry(NSOutlook.Store store)
{
using (RegistryKey baseKey = FindRegistryKey(store))
{
@@ -330,7 +328,7 @@ namespace Acacia.ZPush
private RegistryKey OpenBaseKey()
{
- NameSpace session = _app.Session;
+ NSOutlook.NameSpace session = _app.Session;
string path = string.Format(OutlookConstants.REG_SUBKEY_ACCOUNTS, session.CurrentProfileName);
ComRelease.Release(session);
return OutlookRegistryUtils.OpenOutlookKey(path);
@@ -340,7 +338,7 @@ namespace Acacia.ZPush
/// Finds the registry key for the account.
///
/// The registry key, or null if it cannot be found
- private RegistryKey FindRegistryKey(Account account)
+ private RegistryKey FindRegistryKey(NSOutlook.Account account)
{
// Find the registry key by email adddress
using (RegistryKey key = OpenBaseKey())
@@ -365,7 +363,7 @@ namespace Acacia.ZPush
/// Finds the registry key for the account associated with the store.
///
/// The registry key, or null if it cannot be found
- private RegistryKey FindRegistryKey(Store store)
+ private RegistryKey FindRegistryKey(NSOutlook.Store store)
{
// Find the registry key by store id
using (RegistryKey key = OpenBaseKey())
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushChannel.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushChannel.cs
index b129e74..f78a25f 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushChannel.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushChannel.cs
@@ -14,7 +14,6 @@
///
/// Consult LICENSE file for details
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushChannels.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushChannels.cs
index 07684b2..0372ec0 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushChannels.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushChannels.cs
@@ -14,7 +14,6 @@
///
/// Consult LICENSE file for details
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs
index fb340f0..23eed64 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs
@@ -16,20 +16,20 @@
using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using Acacia.Utils;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.ZPush
{
public class ZPushFolder : FolderWrapper
{
- private readonly Items _items;
- private readonly Folders _subFolders;
+ private readonly NSOutlook.Items _items;
+ private readonly NSOutlook.Folders _subFolders;
private ZPushFolder _parent;
private readonly ZPushWatcher _watcher;
private List _itemsWatchers = new List();
@@ -39,14 +39,14 @@ namespace Acacia.ZPush
///
protected readonly Dictionary _children = new Dictionary();
- internal ZPushFolder(ZPushWatcher watcher, Folder folder)
+ internal ZPushFolder(ZPushWatcher watcher, NSOutlook.Folder folder)
:
this(watcher, null, folder)
{
Initialise();
}
- private ZPushFolder(ZPushWatcher watcher, ZPushFolder parent, Folder folder)
+ private ZPushFolder(ZPushWatcher watcher, ZPushFolder parent, NSOutlook.Folder folder)
:
base(folder)
{
@@ -66,7 +66,7 @@ namespace Acacia.ZPush
_watcher.OnFolderDiscovered(this);
// Recurse the children
- foreach (Folder subfolder in this._subFolders)
+ foreach (NSOutlook.Folder subfolder in this._subFolders)
{
Tasks.Task(null, "WatchChild", () => WatchChild(subfolder));
}
@@ -140,7 +140,7 @@ namespace Acacia.ZPush
/// Watches the child folder.
///
/// The child folder. Ownership will be taken.
- private void WatchChild(Folder child)
+ private void WatchChild(NSOutlook.Folder child)
{
if (!_children.ContainsKey(child.EntryID))
{
@@ -167,12 +167,12 @@ namespace Acacia.ZPush
#region Event handlers
- private void SubFolders_FolderAdd(MAPIFolder folder)
+ private void SubFolders_FolderAdd(NSOutlook.MAPIFolder folder)
{
try
{
Logger.Instance.Debug(this, "Folder added in {0}: {1}", this._item.Name, folder.Name);
- WatchChild((Folder)folder);
+ WatchChild((NSOutlook.Folder)folder);
}
catch (System.Exception e) { Logger.Instance.Error(this, "Exception in SubFolders_FolderAdd: {0}: {1}", Name, e); }
}
@@ -187,7 +187,7 @@ namespace Acacia.ZPush
// but that doesn't fire if a folder was removed on the server.
// Hence, fetch all the remaining folder ids, and remove any folder that no longer exists.
HashSet remaining = new HashSet();
- foreach (Folder child in _subFolders)
+ foreach (NSOutlook.Folder child in _subFolders)
{
try
{
@@ -219,7 +219,7 @@ namespace Acacia.ZPush
catch (System.Exception e) { Logger.Instance.Error(this, "Exception in SubFolders_FolderRemove: {0}: {1}", Name, e); }
}
- private void SubFolders_FolderChange(MAPIFolder folder)
+ private void SubFolders_FolderChange(NSOutlook.MAPIFolder folder)
{
try
{
@@ -236,7 +236,7 @@ namespace Acacia.ZPush
// Create it now
// This will send a discover notification if required, which is just as good as a change notification
Logger.Instance.Debug(this, "Folder change on unreported folder in {0}: {1}, {2}, {3}", this._item.Name, folder.Name, folder.EntryID, folder.Store.DisplayName);
- WatchChild((Folder)folder);
+ WatchChild((NSOutlook.Folder)folder);
}
}
catch (System.Exception e) { Logger.Instance.Error(this, "Exception in SubFolders_FolderChange: {0}: {1}", Name, e); }
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushLocalStore.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushLocalStore.cs
index 7674a63..faa31f2 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushLocalStore.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushLocalStore.cs
@@ -17,13 +17,13 @@
using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
using Acacia.Utils;
-using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.ZPush
{
@@ -33,7 +33,7 @@ namespace Acacia.ZPush
/// TODO: merge with Store where possible
public class ZPushLocalStore : ComWrapper
{
- private Store _store;
+ private NSOutlook.Store _store;
public IFolder RootFolder
{
@@ -45,7 +45,7 @@ namespace Acacia.ZPush
public string StoreId { get { return _store.StoreID; } }
- private ZPushLocalStore(Store store)
+ private ZPushLocalStore(NSOutlook.Store store)
{
this._store = store;
HideAllFolders();
@@ -69,7 +69,7 @@ namespace Acacia.ZPush
// Hide the folders that are not custom folders
using (ComRelease com = new ComRelease())
{
- foreach (Folder sub in com.Add(com.Add(_store.GetRootFolder()).Folders))
+ foreach (NSOutlook.Folder sub in com.Add(com.Add(_store.GetRootFolder()).Folders))
{
using (IFolder wrapped = Mapping.Wrap(sub))
{
@@ -80,7 +80,7 @@ namespace Acacia.ZPush
}
}
- public static ZPushLocalStore GetInstance(Application App)
+ public static ZPushLocalStore GetInstance(IAddIn addIn)
{
try
{
@@ -94,7 +94,7 @@ namespace Acacia.ZPush
Logger.Instance.Debug(typeof(ZPushLocalStore), "Opening store with prefix {0}", prefix);
// See if a store with this prefix exists
- Store store = FindInstance(App, prefix);
+ NSOutlook.Store store = FindInstance(addIn, prefix);
if (store != null)
return new ZPushLocalStore(store);
@@ -114,8 +114,8 @@ namespace Acacia.ZPush
// Path found, create the store
Logger.Instance.Info(typeof(ZPushLocalStore), "Creating new store: {0}", path);
- App.Session.AddStore(path);
- store = App.Session.Stores[App.Session.Stores.Count];
+ addIn.RawApp.Session.AddStore(path);
+ store = addIn.RawApp.Session.Stores[addIn.RawApp.Session.Stores.Count];
Logger.Instance.Debug(typeof(ZPushLocalStore), "Created new store: {0}", store.FilePath);
// Set the display name
@@ -134,9 +134,9 @@ namespace Acacia.ZPush
}
}
- private static Store FindInstance(Application app, string prefix)
+ private static NSOutlook.Store FindInstance(IAddIn addIn, string prefix)
{
- foreach (Store store in app.Session.Stores)
+ foreach (NSOutlook.Store store in addIn.RawApp.Session.Stores)
{
if (store.IsDataFileStore && store.FilePath.StartsWith(prefix))
{
@@ -151,17 +151,17 @@ namespace Acacia.ZPush
{
using (ComRelease com = new ComRelease())
{
- MAPIFolder f = _store.GetDefaultFolder(OlDefaultFolders.olFolderDeletedItems);
+ NSOutlook.MAPIFolder f = _store.GetDefaultFolder(NSOutlook.OlDefaultFolders.olFolderDeletedItems);
if (f != null)
{
com.Add(f);
// Normal enumeration fails when deleting. Do it like this.
- Folders folders = com.Add(f.Folders);
+ NSOutlook.Folders folders = com.Add(f.Folders);
for (int i = folders.Count; i > 0; --i)
com.Add(folders[i]).Delete();
- Items items = com.Add(f.Items);
+ NSOutlook.Items items = com.Add(f.Items);
for (int i = items.Count; i > 0; --i)
com.Add(items[i]).Delete();
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushSync.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushSync.cs
index 5dabaa0..dadfb89 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushSync.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushSync.cs
@@ -23,6 +23,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.ZPush
{
@@ -76,7 +77,7 @@ namespace Acacia.ZPush
#region Setup
- private readonly Microsoft.Office.Interop.Outlook.SyncObject _syncObject;
+ private readonly NSOutlook.SyncObject _syncObject;
private readonly Timer _timer;
private ZPushWatcher _watcher;
private bool _started;
@@ -85,7 +86,7 @@ namespace Acacia.ZPush
public readonly bool Enabled;
public readonly TimeSpan Period;
- public ZPushSync(ZPushWatcher watcher, Microsoft.Office.Interop.Outlook.Application app)
+ public ZPushSync(ZPushWatcher watcher, NSOutlook.Application app)
{
// Get the settings
Enabled = GlobalOptions.INSTANCE.ZPushSync;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushWatcher.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushWatcher.cs
index dc536c5..c4c6588 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushWatcher.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushWatcher.cs
@@ -19,7 +19,6 @@ using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
using Acacia.Utils;
using Acacia.ZPush.Connect;
-using Microsoft.Office.Interop.Outlook;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
@@ -27,6 +26,7 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.ZPush
{
@@ -37,22 +37,22 @@ namespace Acacia.ZPush
///
public class ZPushWatcher
{
- private readonly Application _app;
+ private readonly NSOutlook.Application _app;
public readonly ZPushAccounts Accounts;
public readonly ZPushSync Sync;
- private Explorer _explorer;
+ private NSOutlook.Explorer _explorer;
#region Setup
- public ZPushWatcher(Application app)
+ public ZPushWatcher(IAddIn addIn)
{
- this._app = app;
- Sync = new ZPushSync(this, app);
- Accounts = new ZPushAccounts(this, app);
+ this._app = addIn.RawApp;
+ Sync = new ZPushSync(this, _app);
+ Accounts = new ZPushAccounts(this, _app);
// Need to keep a link to keep receiving events
- _explorer = app.ActiveExplorer();
+ _explorer = _app.ActiveExplorer();
_explorer.SelectionChange += Explorer_SelectionChange;
}
@@ -164,6 +164,7 @@ namespace Acacia.ZPush
}
else
{
+ // TODO
ThisAddIn.Instance.InvokeUI(() =>
{
Logger.Instance.Warning(this, "Password not available for account: {0}", account);
@@ -206,7 +207,7 @@ namespace Acacia.ZPush
{
if (ActiveFolderChange != null)
{
- MAPIFolder active = _explorer.CurrentFolder;
+ NSOutlook.MAPIFolder active = _explorer.CurrentFolder;
if (active != null)
{
using (IFolder folder = Mapping.Wrap(active))
@@ -237,7 +238,7 @@ namespace Acacia.ZPush
if (_explorer.CurrentFolder == null)
return null;
- MAPIFolder folder = _explorer.CurrentFolder;
+ NSOutlook.MAPIFolder folder = _explorer.CurrentFolder;
try
{
return Accounts.GetAccount(folder);
@@ -276,7 +277,7 @@ namespace Acacia.ZPush
private void HandleFolderWatchers(ZPushAccount account)
{
// We need to keep the object alive to keep receiving events
- _rootFolder = new ZPushFolder(this, (Folder)account.Store.GetRootFolder());
+ _rootFolder = new ZPushFolder(this, (NSOutlook.Folder)account.Store.GetRootFolder());
}
public void WatchFolder(FolderRegistration folder, FolderEventHandler handler, FolderEventHandler changedHandler = null)
@@ -341,12 +342,12 @@ namespace Acacia.ZPush
watcher.OnChanged(folder);
}
- internal bool ShouldFolderBeWatched(ZPushFolder parent, Folder child)
+ internal bool ShouldFolderBeWatched(ZPushFolder parent, NSOutlook.Folder child)
{
if (parent.IsAtDepth(0))
{
// Special mail folders cause issues, they are disallowed
- if (child.DefaultItemType != OlItemType.olMailItem)
+ if (child.DefaultItemType != NSOutlook.OlItemType.olMailItem)
return true;
return !IsBlackListedMailFolder(child);
@@ -354,23 +355,23 @@ namespace Acacia.ZPush
return true;
}
- private static readonly OlDefaultFolders[] BLACKLISTED_MAIL_FOLDERS =
+ private static readonly NSOutlook.OlDefaultFolders[] BLACKLISTED_MAIL_FOLDERS =
{
- OlDefaultFolders.olFolderOutbox,
- OlDefaultFolders.olFolderDrafts,
- OlDefaultFolders.olFolderConflicts,
- OlDefaultFolders.olFolderSyncIssues,
- OlDefaultFolders.olFolderRssFeeds,
- OlDefaultFolders.olFolderManagedEmail
+ NSOutlook.OlDefaultFolders.olFolderOutbox,
+ NSOutlook.OlDefaultFolders.olFolderDrafts,
+ NSOutlook.OlDefaultFolders.olFolderConflicts,
+ NSOutlook.OlDefaultFolders.olFolderSyncIssues,
+ NSOutlook.OlDefaultFolders.olFolderRssFeeds,
+ NSOutlook.OlDefaultFolders.olFolderManagedEmail
};
- private static bool IsBlackListedMailFolder(Folder folder)
+ private static bool IsBlackListedMailFolder(NSOutlook.Folder folder)
{
string entryId = folder.EntryID;
using (ComRelease com = new ComRelease())
{
- Store store = com.Add(folder.Store);
- foreach(OlDefaultFolders defaultFolder in BLACKLISTED_MAIL_FOLDERS)
+ NSOutlook.Store store = com.Add(folder.Store);
+ foreach(NSOutlook.OlDefaultFolders defaultFolder in BLACKLISTED_MAIL_FOLDERS)
{
try
{