This commit is contained in:
2018-06-29 19:47:36 +00:00
commit be7f501333
3769 changed files with 1425961 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F04AF6D0-FCEE-4709-ADC6-7274749C06E6}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AyaNova.Plugin.OutlookSchedule</RootNamespace>
<AssemblyName>AyaNova.Plugin.OutlookSchedule</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\..\keys\AyaNova.snk</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\WinFormApp\bin\debug\plugins\OutlookSchedule\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Office.Interop.Outlook, Version=10.0.4504.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\3rdprtylibs\OfficeXPPIA\Microsoft.Office.Interop.Outlook.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CopyableMessageBox.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="OutlookSchedule.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resource.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resource.resx</DependentUpon>
</Compile>
<Compile Include="Timestamp.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\AyaNova.PlugIn\AyaNova.PlugIn.csproj">
<Project>{674BC3C9-4F74-4304-91ED-2EAFFFEB09A7}</Project>
<Name>AyaNova.PlugIn</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\bizobjects\AyaLib\GZTW.AyaNova.BLL.csproj">
<Project>{50B807B6-FC35-4CC3-B54D-91C78426A943}</Project>
<Name>GZTW.AyaNova.BLL</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\csla10\CSLA.Core.Bindablebase\CSLA.Core.Bindablebase.csproj">
<Project>{C2392355-12A9-4197-A1D3-603C390B1E62}</Project>
<Name>CSLA.Core.Bindablebase</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\csla10\CSLA.Server.DataPortal\CSLA.Server.DataPortal.vbproj">
<Project>{80828E2C-E9FB-4E73-A27C-7F9CDB96FCDE}</Project>
<Name>CSLA.Server.DataPortal</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\csla10\CSLA\CSLA.vbproj">
<Project>{1B9A38BB-461A-47A4-AD72-099C694138A0}</Project>
<Name>CSLA</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\Data\Data\GZTW.Data.csproj">
<Project>{701893AA-C042-4FB2-8643-E139372C1117}</Project>
<Name>GZTW.Data</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\Profile\GZTW.Profile\GZTW.Profile.csproj">
<Project>{EDE897E2-E2E6-441D-9F83-0B973AE09670}</Project>
<Name>GZTW.Profile</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="CopyableMessageBox.resx">
<DependentUpon>CopyableMessageBox.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Resource.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="Resources\OutlookSchedule.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\OutlookSchedule32.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\OutlookSchedule16.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>"C:\data\AyaNova\utils\TimeStamp\bin\Release\TimeStamp.exe" "$(ProjectDir)Timestamp.cs" "/N:AyaNova.PlugIn.OutlookSchedule"</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,90 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace AyaNova.Plugin.OutlookSchedule
{
/// <summary>
/// Summary description for CopyableMessageBox.
/// </summary>
public class CopyableMessageBox : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox edOut;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private string mDisplay="";
public CopyableMessageBox(string Display)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
mDisplay=Display;
//
//
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(CopyableMessageBox));
this.edOut = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// edOut
//
this.edOut.Dock = System.Windows.Forms.DockStyle.Fill;
this.edOut.Location = new System.Drawing.Point(0, 0);
this.edOut.Multiline = true;
this.edOut.Name = "edOut";
this.edOut.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.edOut.Size = new System.Drawing.Size(488, 357);
this.edOut.TabIndex = 0;
this.edOut.Text = "";
//
// CopyableMessageBox
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(488, 357);
this.Controls.Add(this.edOut);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "CopyableMessageBox";
this.ShowInTaskbar = false;
this.Load += new System.EventHandler(this.CopyableMessageBox_Load);
this.ResumeLayout(false);
}
#endregion
private void CopyableMessageBox_Load(object sender, System.EventArgs e)
{
edOut.Text=mDisplay;
}
}
}

View File

@@ -0,0 +1,215 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used forserialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="edOut.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="edOut.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="edOut.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>(Default)</value>
</data>
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Name">
<value>CopyableMessageBox</value>
</data>
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>80</value>
</data>
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABn
vzAAZ79QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGe/MABn
v48ggM/gX6jf/1+n3/8Pb8CfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ78/AGe/jx94
z+BQp9//oNjw/9D3///A7///oNjw/6DX8P8Qd8C/AGe/DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ79PAHDA7x+Q
0P9PuOD/f9fw/5/g8P+/6P//wO///7/o//+f2PD/v+j//5DQ8P8feM/QAGe/HwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABn
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
EP/vhz//749A/++IP//gdy//32Af/9BPAP/QRwDA0EcAcNBHAC8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA0EcAn99QD//fUA//0EcA79BHAJ/QRwBQ0EcAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA0EcAX9BHADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA//////////////+f///8D///4AP//4AB//+AAP//gAD//4AA//+AAP/8
AAD8EAAD4AA4HwAA/f8AA///AAH//wAB//8AAf//gAB/v8AADB/gHgAH8P8AA///AAH//wAB//8AAf//
AAH//4AB///AA///8B////n///////////8=
</value>
</data>
</root>

View File

@@ -0,0 +1,913 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AyaNova.PlugIn;
using GZTW.AyaNova.BLL;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;
using System.Data;
using ofc=Microsoft.Office.Interop;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
namespace AyaNova.Plugin.OutlookSchedule
{
class OutlookSchedule : IAyaNovaPlugin
{
//Keep all the object types we want to deal with in a collection
//so that we can quickly check it when asked
private static List<RootObjectTypes> ObjectsWeCanDealWith = null;
private static bool bLicensed = false;
//Holds the image resources from AyaNova
//so we can display the correct icons in our plugin
System.Resources.ResourceManager resman = null;
//Holds the current logged in user's localized text
//lookup object
LocalizedTextTable LocaleText = null;
#region IAyaNovaPlugin Members
#region interface properties
public string PluginName
{
get { return "OutlookSchedule"; }
}
public string PluginVersion
{
get { return "7.5"; }
}
public string About
{
get
{
return "AyaNova OutlookSchedule plugin\r\n" +
"Built " + AyaNova.PlugIn.OutlookSchedule.Timestamp.BuildAt.ToString() + "\r\n" +
"Copyright 2009-2018 Ground Zero Tech-Works Inc.";
}
}
public Guid PluginID
{
get { return new Guid("{6891D5FD-10B3-44ac-B138-D9DB4111F3DE}"); }
}
public System.Drawing.Image PluginSmallIcon
{
get { return Resource.OutlookSchedule16; }
}
public System.Drawing.Image PluginLargeIcon
{
get { return Resource.OutlookSchedule32; }
}
public System.Resources.ResourceManager AyaNovaResourceManager
{
set { resman = value; }
get { return resman; }
}
#endregion interface properties
#region Initialization and Close
public bool Initialize(Version AyaNovaVersion, LocalizedTextTable localizedText)
{
//bLicensed = (!string.IsNullOrEmpty(AyaBizUtils.PluginLicensedVersion("OutlookSchedule")));
//case 2094
bLicensed = AyaBizUtils.PluginAllowed("OutlookSchedule", AyaNova.PlugIn.OutlookSchedule.Timestamp.BuildAt);
if (!bLicensed && AyaBizUtils.PluginTooNew("OutlookSchedule", AyaNova.PlugIn.OutlookSchedule.Timestamp.BuildAt))
{
MessageBox.Show(
"NOT LICENSED!\r\n\r\nThis OutlookSchedule plugin was built " +
AyaNova.PlugIn.OutlookSchedule.Timestamp.BuildAt.ToString() + "\r\n" +
"but your license subscription for it ended " +
AyaBizUtils.PluginSubscriptionDate("OutlookSchedule").ToString() + "\r\n" +
"\r\nDowngrade back to your previous version or purchase a subscription to use this plugin.");
return false;
}
if (AyaNovaVersion.Major < 7)
{
MessageBox.Show("This OutlookSchedule plugin requires AyaNova 7 or newer");
return false;
}
LocaleText = localizedText;
ObjectsWeCanDealWith = new List<RootObjectTypes>();
ObjectsWeCanDealWith.Add(RootObjectTypes.Nothing);
return true;
}
public void Close()
{
;
}
#endregion Initialization and close
#region ShowMenu?
public bool SingleObjectMenuShow(RootObjectTypes objectType)
{
return (ObjectsWeCanDealWith.Contains(objectType));
}
public bool MultipleObjectsMenuShow(RootObjectTypes objectType)
{
return false;
}
#endregion show menu?
#region Menu options
public List<AyaNovaPluginMenuItem> SingleObjectMenuOptions(RootObjectTypes objectType, object ayaNovaObject)
{
if (!ObjectsWeCanDealWith.Contains(objectType)) return null;
List<AyaNovaPluginMenuItem> list = new List<AyaNovaPluginMenuItem>();
list.Add(new AyaNovaPluginMenuItem("OutlookSchedule", "Outlook schedule export", null, null));
//list.Add(new AyaNovaPluginMenuItem("OutlookScheduleDiagnostic", "Outlook schedule export (DIAGNOSTIC MODE)", null, null));
return list;
}
public List<AyaNovaPluginMenuItem> MultipleObjectsMenuOptions(RootObjectTypes objectType)
{
return null;
}
#endregion
#region Menu Commands
private void ShowWarning(string swarn, string scaption)
{
MessageBox.Show(swarn, scaption, MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
#region LIST OBJECT COMMAND
/// <summary>
/// LIST OBJECT
/// </summary>
/// <param name="commandKey"></param>
/// <param name="objectType"></param>
/// <param name="objectIDList"></param>
/// <param name="listObject"></param>
/// <returns></returns>
public bool CommandSelectedForList(string commandKey, RootObjectTypes objectType, List<Guid> objectIDList, object listObject)
{
return false;
}
#endregion list object command
#region SINGLE OBJECT COMMAND
/// <summary>
/// SINGLE OBJECT
/// </summary>
/// <param name="commandKey"></param>
/// <param name="objectType"></param>
/// <param name="ayaNovaObject"></param>
public void CommandSelectedForSingleObject(string commandKey, RootObjectTypes objectType, object ayaNovaObject)
{
if (!bLicensed)
{
ShowWarning("An AyaNova OutlookSchedule license is required to use this plugin.", "Not licensed");
return;
}
switch (commandKey)
{
case "OutlookSchedule":
{
Export(false);
}
break;
case "OutlookScheduleDiagnostic":
{
Export(true);
}
break;
}
}
#endregion single object command
#endregion menu commands
#endregion
#region Outlook api globals and util methods
#region Outlook application object
ofc.Outlook.Application moutApp = null;
public ofc.Outlook.Application outApp
{
get
{
if (moutApp == null)
{
if (bdiag) d("Obtaining link to Outlook...");
//todo: need to login here or something if outlook not already running
moutApp = new ofc.Outlook.Application();
if (bdiag) d("..link obtained to Outlook.");
}
return moutApp;
}
}
#endregion outlook app object
#region AyaNova calendar folder
ofc.Outlook.MAPIFolder mAyaCalendar = null;
/// <summary>
/// Get the AyaNova calendar
/// create it if required
/// </summary>
public ofc.Outlook.MAPIFolder AyaCalendar
{
get
{
if (mAyaCalendar == null)
{
if (bdiag) d("Check for existing AyaNovaSchedule calendar...");
//see if there is one already, if not create it
mAyaCalendar = GetFolder(ofc.Outlook.OlDefaultFolders.olFolderCalendar, "AyaNovaSchedule");
if (mAyaCalendar == null)
{
if (bdiag) d("Calendar AyaNovaSchedule not found in Outlook. Creating it...");
//get required objects to do the op
ofc.Outlook.NameSpace ns = outApp.GetNamespace("MAPI");
ofc.Outlook.MAPIFolder fldDefault=ns.GetDefaultFolder(ofc.Outlook.OlDefaultFolders.olFolderCalendar);
ofc.Outlook.Folders fldDefaultFolders = fldDefault.Folders;
//create it
mAyaCalendar = fldDefaultFolders.Add("AyaNovaSchedule", ofc.Outlook.OlDefaultFolders.olFolderCalendar);
mAyaCalendar.Description = "AyaNova OutlookSchedule plugin exported items";
//release required objects
Marshal.ReleaseComObject(fldDefaultFolders);
fldDefaultFolders = null;
Marshal.ReleaseComObject(fldDefault);
fldDefault = null;
Marshal.ReleaseComObject(ns);
ns = null;
}
}
return mAyaCalendar;
}
}
#endregion ayanova calendar folder
#region Remove AyaNova generated appointment from Outlook
public void RemoveOutlookAppointment(TypeAndID tid)
{
// d("Remove outlook appointment top...");
ofc.Outlook.AppointmentItem oaiToDelete = null;
ofc.Outlook.Items ayCalItems = AyaCalendar.Items;
bool bFoundIt = false;
for (int x = 0; x < ayCalItems.Count; x++)
{
//d("fetching outlook appointment for comparison...");
ofc.Outlook.AppointmentItem oai = (ofc.Outlook.AppointmentItem)ayCalItems[x+1];
//d("examining outlook appointment user properties...");
ofc.Outlook.UserProperties props=null;
if(oai.UserProperties!=null)
props = oai.UserProperties;
if (props != null && props.Count > 0)
{
ofc.Outlook.UserProperty prop = props["AyaNovaTypeAndID"];
if (prop != null)
{
//d("prop.value to string:" + prop.Value.ToString());
//d("Tid to string:" + tid.ToString());//bugbug tid is null here
if (prop.Value.ToString() == tid.ToString())
{
//d("Have a match!");
oaiToDelete = oai;
bFoundIt = true;
}
Marshal.ReleaseComObject(prop); prop = null;
}
Marshal.ReleaseComObject(props); props = null;
}
//d("Found? - " + bFoundIt.ToString());
if (bFoundIt)
break;
else
Marshal.ReleaseComObject(oai); oai = null;
}
Marshal.ReleaseComObject(ayCalItems); ayCalItems = null;
//d("Finished in loop");
//Remove from Outlook
if (oaiToDelete != null)
{
//d("Deleteing outlook appointment " + oaiToDelete.Subject + " ...");
oaiToDelete.Delete();
if (oaiToDelete != null)
{
Marshal.ReleaseComObject(oaiToDelete); oaiToDelete = null;
}
}
else
throw new System.ApplicationException("Outlook schedule plugin: Error RemoveOutlookAppointment: appointment matching [" + tid.ToString() + "] not found in Outlook");
//d("Remove outlook appointment bottom.");
}
#endregion
#region Insert Shadow appointment into Outlook
public void InsertShadowAppointment(ShadowAppointment sa)
{
ofc.Outlook.Items ayCalItems = AyaCalendar.Items;
ofc.Outlook.AppointmentItem oa = (ofc.Outlook.AppointmentItem)ayCalItems.Add(ofc.Outlook.OlItemType.olAppointmentItem);
ofc.Outlook.UserProperties props= oa.UserProperties;
ofc.Outlook.UserProperty prop = props.Add("AyaNovaTypeAndID", Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText, false, null);
prop.Value = sa.AyaNovaTypeAndID.ToString();
oa.Subject = sa.Subject;
oa.Location = sa.Location;
oa.Start = sa.Start;
oa.End = sa.End;
oa.Body = sa.BodyText;
if (sa.ShowTimeAsBusy)
oa.BusyStatus = Microsoft.Office.Interop.Outlook.OlBusyStatus.olBusy;
else
oa.BusyStatus = Microsoft.Office.Interop.Outlook.OlBusyStatus.olTentative;
oa.ReminderSet = false;
oa.Save();
Marshal.ReleaseComObject(prop);prop = null;
Marshal.ReleaseComObject(props);props = null;
Marshal.ReleaseComObject(oa);oa = null;
Marshal.ReleaseComObject(ayCalItems); ayCalItems = null;
}
#endregion insert shadow appt.
#region Localized text stuff
string mSchedUserLocalizedText = null;
string mSchedMarkerLocalizedText = null;
public string SchedMarkerLocalizedText
{
get
{
if (mSchedMarkerLocalizedText == null)
mSchedMarkerLocalizedText = LocaleText.GetLocalizedText("O.ScheduleMarker");
return mSchedMarkerLocalizedText;
}
}
public string SchedUserLocalizedText
{
get
{
if (mSchedUserLocalizedText == null)
mSchedUserLocalizedText = LocaleText.GetLocalizedText("O.WorkorderItemScheduledUser");
return mSchedUserLocalizedText;
}
}
#endregion LocalizedTextstuff
#region Client contact cache
Dictionary<Guid, string> clientInfoCache = null;
/// <summary>
/// Get client info
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public string GetClientInfoDisplay(Guid id)
{
//check in cache first
if(clientInfoCache==null)
clientInfoCache = new Dictionary<Guid, string>();
if (!clientInfoCache.ContainsKey(id))
{
//retrieve the client record
Client c = Client.GetItemNoMRU(id);
StringBuilder b = new StringBuilder();
b.Append(c.Name);
b.Append("\r\n");
b.Append(c.GoToAddress.FullAddress);
b.Append("\r\n");
b.Append(c.GetPrimaryContactDefaultContactInfo());
//if (c.TechNotes != "")
//{
// b.Append(LocaleText.GetLocalizedText("Client.Label.TechNotes"));
// b.Append(":\r\n");
// b.Append(c.TechNotes);
//}
clientInfoCache.Add(id, b.ToString());
}
return clientInfoCache[id];
}
#endregion client contact cache
#region utils
#region ShadowAppointmentStuff
/// <summary>
///
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public ShadowAppointment GetShadowAppointment(AppointmentList.AppointmentListInfo i)
{
ShadowAppointment a = new ShadowAppointment();
if (i.SourceObjectType == RootObjectTypes.ScheduleMarker)
{
ScheduleMarker sm=ScheduleMarker.GetItem(i.SourceObjectID);
a.Subject = sm.Name;
a.Location = SchedMarkerLocalizedText;
a.Start = i.StartDateTime;
a.End = i.EndDateTime;
a.ShowTimeAsBusy = false;
string sFollowUpText = "";
if (sm.FollowID != Guid.Empty)
sFollowUpText = NameFetcher.GetItem(new TypeAndID(sm.FollowType, sm.FollowID)).RecordName + "\r\n";
a.BodyText = sFollowUpText + sm.Notes;
a.AyaNovaTypeAndID = new TypeAndID(RootObjectTypes.ScheduleMarker, i.SourceObjectID);
}
else//workorderitemscheduleuser
{
WorkorderServiceList.WorkorderServiceListInfo woinfo= WorkorderServiceList.GetListForSingleItem(i.WorkorderID)[0];
a.Subject = i.ServiceNumber.ToString() + " " + woinfo.LT_O_Client.Display;
a.Location = SchedUserLocalizedText;
a.Start = i.StartDateTime;
a.End = i.EndDateTime;
a.ShowTimeAsBusy = true;
a.BodyText = i.Subject + "\r\n------------------------------------\r\n" + GetClientInfoDisplay(woinfo.LT_O_Client.Value);
a.AyaNovaTypeAndID = new TypeAndID(i.SourceObjectType, i.SourceObjectID);
}
System.Text.StringBuilder sb = new StringBuilder();
sb.Append(a.Subject);
sb.Append(a.Location);
sb.Append(a.Start.ToString("yyyyMMddHHmm"));
sb.Append(a.End.ToString("yyyyMMddHHmm"));
sb.Append(a.BodyText);
a.CheckSum = GetHash(sb.ToString());
//if (i.SourceObjectType == RootObjectTypes.ScheduleMarker)
// d("Shadow appt. checksum:" + a.CheckSum + "\r\nData was:\r\n" + sb.ToString());
return a;
}
#endregion shadowappointmentstuff
#region Outlook folder stuff
/// <summary>
/// Iterates all folders of type specified and returns the one with the name specified
/// Caller MUST release folder returned
/// </summary>
/// <param name="sNameContains"></param>
/// <returns></returns>
public ofc.Outlook.MAPIFolder GetFolder(ofc.Outlook.OlDefaultFolders folderType, string sNameContains)
{
//d("Top of GetFolder...");
//get required objects to do the op
ofc.Outlook.NameSpace ns = outApp.GetNamespace("MAPI");
ofc.Outlook.MAPIFolder f= GetCalendar(ns.GetDefaultFolder(folderType), sNameContains);
// d("Got folder, releasing objects...");
if (ns != null)
{
Marshal.ReleaseComObject(ns);
ns = null;
}
return f;
}
/// <summary>
/// Recursive method to iterate folders and return one that contains the name specified
/// </summary>
/// <param name="mf"></param>
/// <param name="sNameContains"></param>
/// <returns></returns>
public ofc.Outlook.MAPIFolder GetCalendar(ofc.Outlook.MAPIFolder mf, string sNameContains)
{
//d("Top of GetCalendar " + mf.FolderPath + ", " + sNameContains);
if (mf.FolderPath.Contains(sNameContains))
{
//d("GetCalendar: Found it, returning.");
return mf;
}
ofc.Outlook.Folders fldrs = mf.Folders;
for (int x = 0; x < fldrs.Count; x++)
{
//d("GetCalendar: Checking calendar " + x.ToString() + " of " + mf.Folders.Count.ToString());
ofc.Outlook.MAPIFolder f = mf.Folders[x+1];
if (GetCalendar(f, sNameContains) != null)
{
Marshal.ReleaseComObject(fldrs); fldrs = null;
return f;
}
else
{
Marshal.ReleaseComObject(f); f = null;
}
}
//d("GetCalendar: Not here, returning.");
Marshal.ReleaseComObject(fldrs); fldrs = null;
return null;
}
#endregion Outlook folder stuff
#region Checksum stuff
private aptOut GetOutlookAppointmentChecksum(ofc.Outlook.AppointmentItem oai)
{
//d("top of GetOutlookAppointmentChecksum(" + oai.Subject + ")");
aptOut a;
a.CheckSum="";
a.AyaNovaTypeAndID = new TypeAndID(RootObjectTypes.Nothing, Guid.Empty);
if (oai == null) return a;
if (string.IsNullOrEmpty(oai.EntryID)) return a;
ofc.Outlook.UserProperties props = oai.UserProperties;
ofc.Outlook.UserProperty prop = props["AyaNovaTypeAndID"];
a.AyaNovaTypeAndID = TypeAndID.Parse(prop.Value.ToString());
Marshal.ReleaseComObject(prop); prop = null;
Marshal.ReleaseComObject(props); props = null;
System.Text.StringBuilder sb = new StringBuilder();
sb.Append(oai.Subject);
sb.Append(oai.Location);
sb.Append(oai.Start.ToString("yyyyMMddHHmm"));
sb.Append(oai.End.ToString("yyyyMMddHHmm"));
sb.Append(oai.Body);
a.CheckSum = GetHash(sb.ToString());
//if(a.CheckSum.StartsWith("92C"))
// d("Outlook appt. checksum:"+a.CheckSum+"\r\nData was:\r\n" + sb.ToString());
return a;
}
/// <summary>
/// Get a reliable hash value
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private string GetHash(string s)
{
//TODO: FIPS
SHA256 shaM = new SHA256Managed();
UTF8Encoding enc = new UTF8Encoding();
return BitConverter.ToString(shaM.ComputeHash(enc.GetBytes(s))).Replace("-", "");
}
#endregion checksum stuff
#endregion utils
#endregion outlook api globals and util methods
#region Diagnostic messages
/// <summary>
/// Diagnostics messages
/// </summary>
/// <param name="s"></param>
private void d(string s)
{
if (bdiag)
MessageBox.Show(s);
}
private bool bdiag = false;
#endregion diags
/// <summary>
/// Do the export
/// </summary>
private void Export(bool DiagnosticMode)
{
UserTypes currentUserType = User.CurrentUserType;
if (currentUserType != UserTypes.Schedulable)
{
MessageBox.Show("This plugin can only be used by scheduleable users.\r\n" +
"The current logged in user is an " + currentUserType.ToString() + " type of user.");
return;
}
bdiag = DiagnosticMode;
DateTime dtStarted = DateTime.Now.AddMinutes(-1);
if(bdiag) d("Starting export of items between " + dtStarted.ToString() + " and "+ dtStarted.AddYears(1) + "...");
List<aptOut> lsaptOut = new List<aptOut>();
List<ShadowAppointment> lsShadowApt = new List<ShadowAppointment>();
AppointmentList apl = null;
try
{
#region Build checksum list of appointments in Outlook
if (bdiag) d("Inspecting existing AyaNovaSchedule items in Outlook ...");
ofc.Outlook.Items ayCalItems = AyaCalendar.Items;
// d("Raw AyaCalendar.Items.Count=" + ayCalItems.Count);
for (int x = 0; x < ayCalItems.Count; x++)
{
//d("Fetching existing item " + x.ToString()+" ...");
ofc.Outlook.AppointmentItem oai = (ofc.Outlook.AppointmentItem)ayCalItems[x + 1];
if (oai.Start > dtStarted || oai.End > dtStarted)//appointments that start after now or end after now
{
ofc.Outlook.UserProperties props = oai.UserProperties;
if (props != null && props.Count > 0)
{
ofc.Outlook.UserProperty prop = props["AyaNovaTypeAndID"];
if (prop != null)
{
lsaptOut.Add(GetOutlookAppointmentChecksum(oai));
Marshal.ReleaseComObject(prop); prop = null;
}
Marshal.ReleaseComObject(props); props = null;
}
}
Marshal.ReleaseComObject(oai); oai = null;
}
Marshal.ReleaseComObject(ayCalItems); ayCalItems = null;
if (bdiag) d(lsaptOut.Count.ToString() + " existing relevant AyaNovaSchedule Outlook calendar items found in Outlook.");
#endregion build checksum list
#region Build shadow appointment list
if (bdiag) d("Fetching any existing open AyaNova schedule items in the next year for current logged in user...");
apl = AppointmentList.GetList(dtStarted, dtStarted.AddYears(1), User.CurrentThreadUserID);
UserListScheduleable uls = UserListScheduleable.GetList();
foreach (AppointmentList.AppointmentListInfo i in apl)
{
switch (i.SourceObjectType)
{
case RootObjectTypes.WorkorderItemScheduledUser:
{
lsShadowApt.Add(GetShadowAppointment(i));
}
break;
case RootObjectTypes.ScheduleMarker:
{
#region schedmarkers
////Could be a bunch by region , global , dispatchzone, schedusergroup
////or could be a single by one user ID
switch (i.AppliesToObjectType)
{
case RootObjectTypes.User:
if (i.AppliesToObjectID == User.CurrentThreadUserID)
lsShadowApt.Add(GetShadowAppointment(i));
break;
case RootObjectTypes.Region:
{
//Loop through all active scheduleable users
//if the region ID matches the marker region ID then
//add a marker on the calendar for it
foreach (UserListScheduleable.UserListScheduleableInfo ui in uls)
{
if (ui.ID == User.CurrentThreadUserID)
{
//case 58
if (i.AppliesToObjectID == GZTW.AyaNova.BLL.Region.DefaultRegionID)//SM is for default region? Then applies to everyone
lsShadowApt.Add(GetShadowAppointment(i));
else if (ui.RegionID == GZTW.AyaNova.BLL.Region.DefaultRegionID)//User is in default region? Then applies to them
lsShadowApt.Add(GetShadowAppointment(i));
else if (ui.RegionID == i.AppliesToObjectID)//SM and User in same non default region
lsShadowApt.Add(GetShadowAppointment(i));
break;
}
}
}
break;
case RootObjectTypes.DispatchZone:
{
//Loop through all active scheduleable users
//if the Dispatch zone ID matches the marker zone ID then
//add a marker on the calendar for it
foreach (UserListScheduleable.UserListScheduleableInfo ui in uls)
if (ui.ID == User.CurrentThreadUserID)
{
if (ui.DispatchZoneID == i.AppliesToObjectID)
lsShadowApt.Add(GetShadowAppointment(i));
break;
}
}
break;
case RootObjectTypes.ScheduleableUserGroup:
{
ScheduleableUserGroupUsersList ScheduleMarkerGroup = ScheduleableUserGroupUsersList.GetList(i.AppliesToObjectID);
//Loop through all active scheduleable users
//if they are in the ScheduleableUserGroup then
//add a marker on the calendar for it
foreach (UserListScheduleable.UserListScheduleableInfo ui in uls)
if (ui.ID == User.CurrentThreadUserID)
{
if (ScheduleMarkerGroup.Contains(ui.ID))
lsShadowApt.Add(GetShadowAppointment(i));
break;
}
}
break;
case RootObjectTypes.Global:
{
lsShadowApt.Add(GetShadowAppointment(i));
}
break;
}
#endregion schedmarkers
}
break;
}
}
if (bdiag) d(lsShadowApt.Count.ToString() + " existing AyaNova schedule items found in AyaNova.");
#endregion build shadow appointment list
//Do Export:
#region step 1 remove stale outlook appointments
if (bdiag) d("Removing existing AyaNovaSchedule Outlook calendar items that are changed since last export ...");
//iterate outlook appointments list, for each AyaNova generated one
//that has no matching checksum in shadow, delete it from outlook then from outlist
int nlsaptOutCount = lsaptOut.Count;
int nTotalStaleCount = 0;
#region mismatch Diagnostics stuff
if (bdiag)
{
System.Text.StringBuilder sbdiag = new StringBuilder();
sbdiag.Append("Shadowlist:\r\n");
foreach (ShadowAppointment sa in lsShadowApt)
{
sbdiag.Append(sa.Subject);
sbdiag.Append(" ck:");
sbdiag.Append(sa.CheckSum);
sbdiag.Append("\r\n");
}
d(sbdiag.ToString());
sbdiag.Length = 0;
sbdiag.Append("Outlist:\r\n");
foreach (aptOut sa in lsaptOut)
{
sbdiag.Append(sa.AyaNovaTypeAndID.ToString());
sbdiag.Append(" ck:");
sbdiag.Append(sa.CheckSum);
sbdiag.Append("\r\n");
}
d(sbdiag.ToString());
}
#endregion mismatch diags
//iterate the outlook appointments list
for (int x = 0; x < nlsaptOutCount; x++)
{
//d("x=" + x.ToString() + ", nlsaptOutCount=" + nlsaptOutCount.ToString() + ", lsaptOut.Count=" + lsaptOut.Count.ToString() + ", lsShadowApt.count=" + lsShadowApt.Count.ToString());
bool bExists = false;
//if outlook appointment checksum not in shadow list delete it
aptOut ThisapOut = lsaptOut[x];
foreach (ShadowAppointment sa in lsShadowApt)
{
//System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(sa.CheckSum));
//d("Comparing outlook checksum:\r\n " + ThisapOut.CheckSum + "\r\nTo shadow checksum:\r\n" + sa.CheckSum);
if (sa.CheckSum == ThisapOut.CheckSum)
{
//d("Identical match: " + sa.CheckSum);
bExists = true;
break;
}
}
if (!bExists)
{
//d("Unmatched outlook checksum:\r\n " + ThisapOut.CheckSum );
//remove from outlook
RemoveOutlookAppointment(ThisapOut.AyaNovaTypeAndID);
//remove from the working list
lsaptOut.RemoveAt(x);
x--;
nlsaptOutCount--;
nTotalStaleCount++;
}
}
if (bdiag) d(nTotalStaleCount.ToString() + " stale items removed from Outlook.");
#endregion step 1
#region Step 2 Remove unchanged appointments from shadow appointment list
if (bdiag) d("Identifying AyaNova items that already exist identically in Outlook and do not need to be exported...");
//Iterate through shadow appointments, for each one that has matching checksum in outlook apts remove it from shadow list
int nShadowListCount = lsShadowApt.Count;
int nTotalUnchangedShadowItems = 0;
for (int x = 0; x < nShadowListCount; x++)
{
bool bExists = false;
ShadowAppointment sa = lsShadowApt[x];
foreach (aptOut ao in lsaptOut)
{
if (ao.CheckSum == sa.CheckSum)
{
bExists = true;
break;
}
}
if (bExists)
{
//remove from shadowlist
lsShadowApt.RemoveAt(x);
x--;
nShadowListCount--;
nTotalUnchangedShadowItems++;
}
}
if (bdiag) d(nTotalUnchangedShadowItems.ToString() + " items in AyaNova already exist unchanged in Outlook and won't be exported.");
#endregion Step 2
#region Step 3 Insert remaining shadow appointments in Outlook
if (bdiag)
{
if (lsShadowApt.Count > 0)
d("Exporting " + lsShadowApt.Count.ToString() + " new / updated AyaNova schedule items to Outlook...");
else
d("No items found to export to Outlook.");
}
foreach (ShadowAppointment sa in lsShadowApt)
{
InsertShadowAppointment(sa);
}
#endregion step 3
}
catch (Exception ex)
{
MessageBox.Show("OutlookSchedule plugin error:\r\n"+ex.ToString());
throw (ex);
}
finally
{
#region Step 4 release objects
if (bdiag) d("Releasing calendar object...");
if (mAyaCalendar != null)
{
Marshal.ReleaseComObject(mAyaCalendar); mAyaCalendar = null;
}
if (bdiag) d("Releasing app object...");
if (moutApp != null)
{
Marshal.ReleaseComObject(moutApp); moutApp = null;
}
//clear the client cache
if (clientInfoCache != null)
{
if (bdiag) d("Clearing client cache...");
clientInfoCache.Clear();
clientInfoCache = null;
}
if (bdiag) d("Done!");
#endregion step 4
}
}
}//end of class
#region Appointment and comparison structs
public struct aptOut
{
public TypeAndID AyaNovaTypeAndID;
public string CheckSum;
}
/// <summary>
/// contains all the data that will go into an Outlook appointment
/// </summary>
public struct ShadowAppointment
{
public string Subject;
public string Location;
public DateTime Start;
public DateTime End;
public bool ShowTimeAsBusy;
public string BodyText;
public TypeAndID AyaNovaTypeAndID;
public string CheckSum;
}
#endregion appt comparison structs
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("AyaNova.Plugin.OutlookSchedule")]
[assembly: AssemblyDescription("OutlookSchedule plugin for AyaNova")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Ground Zero Tech-Works Inc.")]
[assembly: AssemblyProduct("AyaNova.Plugin.OutlookSchedule")]
[assembly: AssemblyCopyright("Copyright © 2009-2018 Ground Zero Tech-Works Inc.")]
[assembly: AssemblyTrademark("AyaNova is a registered trademark of Ground Zero Tech-Works Inc.")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6891D5FD-10B3-44ac-B138-D9DB4111F3DE")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("7.5.0.0")]
[assembly: AssemblyFileVersion("7.5.0.0")]

View File

@@ -0,0 +1,84 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AyaNova.Plugin.OutlookSchedule {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resource {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resource() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AyaNova.Plugin.OutlookSchedule.Resource", typeof(Resource).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
internal static System.Drawing.Icon OutlookSchedule {
get {
object obj = ResourceManager.GetObject("OutlookSchedule", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
internal static System.Drawing.Bitmap OutlookSchedule16 {
get {
object obj = ResourceManager.GetObject("OutlookSchedule16", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap OutlookSchedule32 {
get {
object obj = ResourceManager.GetObject("OutlookSchedule32", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="OutlookSchedule" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\OutlookSchedule.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="OutlookSchedule16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\OutlookSchedule16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="OutlookSchedule32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\OutlookSchedule32.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B