using System; using System.Collections.Generic; using System.Text; using Extensibility; using System.Runtime.InteropServices; using Outlook = Microsoft.Office.Interop.Outlook; using Office = Microsoft.Office.Core; //using Word = Microsoft.Office.Interop.Word; using System.Windows.Forms; //AyaNova stuff using GZTW.AyaNova.BLL; using CSLA.Security; using System.Threading; using Infragistics.Win; using Infragistics.Win.UltraWinEditors; using System.Globalization; using Infragistics.Win.UltraWinGrid; using System.Data; using System.Collections.Specialized; using System.Reflection; namespace AyaNovaOL { #region WrapperClass /// /// Delegate signature to inform the application about closed objects. /// /// The unique ID of the closed object. public delegate void WrapperClosedDelegate(Guid id); /// /// The Wrapperclass itself has a unique ID and a closed event. /// internal abstract class WrapperClass { /// /// The event ocures when the monitored item has been closed. /// public event WrapperClosedDelegate Closed; /// /// The unique ID of the wrapped object. /// public Guid Id { get; private set; } protected void OnClosed() { if (Closed != null) Closed(Id); } /// /// The constructor creates a new unique ID. /// public WrapperClass() { Id = Guid.NewGuid(); } } // ---------- end of WrapperClass.cs ----------------------------- #endregion #region ExplorerWrapper // ----------- ExplorerWrapper.cs ------------------------------- internal class ExplorerWrapper : WrapperClass { public Outlook.Explorer Explorer { get; private set; } //beforefolderswitch isn't fired when outlook initially opened to the first explorer //so need to force it first time only bool bFirstCall = true; public ExplorerWrapper(Outlook.Explorer explorer) : base() { Explorer = explorer; ConnectEvents(); if (bFirstCall) { bFirstCall = false; AddExplorerMenu(Explorer.CurrentFolder); } } #region Events void ConnectEvents() { //((Outlook.ExplorerEvents_10_Event)Explorer).Activate += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_ActivateEventHandler(ExplorerWrapper_Activate); ((Outlook.ExplorerEvents_10_Event)Explorer).BeforeFolderSwitch += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeFolderSwitchEventHandler(ExplorerWrapper_BeforeFolderSwitch); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeItemCopy += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeItemCopyEventHandler(ExplorerWrapper_BeforeItemCopy); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeItemCut += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeItemCutEventHandler(ExplorerWrapper_BeforeItemCut); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeItemPaste += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeItemPasteEventHandler(ExplorerWrapper_BeforeItemPaste); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeMaximize += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeMaximizeEventHandler(ExplorerWrapper_BeforeMaximize); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeMinimize += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeMinimizeEventHandler(ExplorerWrapper_BeforeMinimize); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeMove += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeMoveEventHandler(ExplorerWrapper_BeforeMove); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeSize += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeSizeEventHandler(ExplorerWrapper_BeforeSize); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeViewSwitch += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeViewSwitchEventHandler(ExplorerWrapper_BeforeViewSwitch); ((Outlook.ExplorerEvents_10_Event)Explorer).Close += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_CloseEventHandler(ExplorerWrapper_Close); //((Outlook.ExplorerEvents_10_Event)Explorer).Deactivate += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_DeactivateEventHandler(ExplorerWrapper_Deactivate); //((Outlook.ExplorerEvents_10_Event)Explorer).FolderSwitch += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_FolderSwitchEventHandler(ExplorerWrapper_FolderSwitch); //((Outlook.ExplorerEvents_10_Event)Explorer).SelectionChange += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_SelectionChangeEventHandler(ExplorerWrapper_SelectionChange); //((Outlook.ExplorerEvents_10_Event)Explorer).ViewSwitch += new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_ViewSwitchEventHandler(ExplorerWrapper_ViewSwitch); } void DisconnectEvents() { //((Outlook.ExplorerEvents_10_Event)Explorer).Activate -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_ActivateEventHandler(ExplorerWrapper_Activate); ((Outlook.ExplorerEvents_10_Event)Explorer).BeforeFolderSwitch -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeFolderSwitchEventHandler(ExplorerWrapper_BeforeFolderSwitch); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeItemCopy -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeItemCopyEventHandler(ExplorerWrapper_BeforeItemCopy); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeItemCut -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeItemCutEventHandler(ExplorerWrapper_BeforeItemCut); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeItemPaste -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeItemPasteEventHandler(ExplorerWrapper_BeforeItemPaste); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeMaximize -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeMaximizeEventHandler(ExplorerWrapper_BeforeMaximize); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeMinimize -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeMinimizeEventHandler(ExplorerWrapper_BeforeMinimize); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeMove -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeMoveEventHandler(ExplorerWrapper_BeforeMove); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeSize -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeSizeEventHandler(ExplorerWrapper_BeforeSize); //((Outlook.ExplorerEvents_10_Event)Explorer).BeforeViewSwitch -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_BeforeViewSwitchEventHandler(ExplorerWrapper_BeforeViewSwitch); ((Outlook.ExplorerEvents_10_Event)Explorer).Close -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_CloseEventHandler(ExplorerWrapper_Close); //((Outlook.ExplorerEvents_10_Event)Explorer).Deactivate -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_DeactivateEventHandler(ExplorerWrapper_Deactivate); //((Outlook.ExplorerEvents_10_Event)Explorer).FolderSwitch -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_FolderSwitchEventHandler(ExplorerWrapper_FolderSwitch); //((Outlook.ExplorerEvents_10_Event)Explorer).SelectionChange -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_SelectionChangeEventHandler(ExplorerWrapper_SelectionChange); //((Outlook.ExplorerEvents_10_Event)Explorer).ViewSwitch -= new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_ViewSwitchEventHandler(ExplorerWrapper_ViewSwitch); } #endregion events void ExplorerWrapper_Close() { DisconnectEvents(); btnOLSelectedToAyaNova = null; btnOLSelectedFromAyaNova = null; btnOLAllToAyaNova = null; btnOLAllFromAyaNova = null; btnOLConfig = null; popOL = null; popOLSubAll = null; popOLSubSelected = null; btnOLAbout = null; Explorer = null; GC.Collect(); GC.WaitForPendingFinalizers(); OnClosed(); } #region Views / Folder / Selection void ExplorerWrapper_ViewSwitch() { } void ExplorerWrapper_BeforeViewSwitch(object NewView, ref bool Cancel) { } void ExplorerWrapper_SelectionChange() { //if (Explorer.Selection.Count > 1) //{ // try // { // if (Explorer.Selection[1] is Outlook.ContactItem) // { // Outlook.ContactItem ci = (Outlook.ContactItem)Explorer.Selection[1]; // Util.d(ci.FirstName); // } // else // Util.d("Not recognized as a contact item"); // } // catch (Exception ex) // { // Util.d(ex.Message); // } //} //Util.d(" Selection count: " + this.Explorer.Selection.Count.ToString() + "\r\nClass: " + // + "\r\nItem type:" + Explorer.Selection[0].GetType().ToString()); } void ExplorerWrapper_FolderSwitch() { } void ExplorerWrapper_BeforeFolderSwitch(object NewFolder, ref bool Cancel) { if (NewFolder == null) return; AddExplorerMenu((Outlook.MAPIFolder)NewFolder); } #endregion #region Activate / Deactivate void ExplorerWrapper_Activate() { } void ExplorerWrapper_Deactivate() { } #endregion #region Resize / Move void ExplorerWrapper_BeforeSize(ref bool Cancel) { } void ExplorerWrapper_BeforeMove(ref bool Cancel) { } void ExplorerWrapper_BeforeMinimize(ref bool Cancel) { } void ExplorerWrapper_BeforeMaximize(ref bool Cancel) { } #endregion #region Cut / Copy / Paste void ExplorerWrapper_BeforeItemPaste(ref object ClipboardContent, Microsoft.Office.Interop.Outlook.MAPIFolder Target, ref bool Cancel) { } void ExplorerWrapper_BeforeItemCut(ref bool Cancel) { } void ExplorerWrapper_BeforeItemCopy(ref bool Cancel) { } #endregion #region Add explorer menu //defined here to prevent being GC'd and losing functionality public Office.CommandBarButton btnOLSelectedToAyaNova = null; public Office.CommandBarButton btnOLSelectedFromAyaNova = null; public Office.CommandBarButton btnOLAllToAyaNova = null; public Office.CommandBarButton btnOLAllFromAyaNova = null; public Office.CommandBarButton btnOLConfig = null; public Office.CommandBarPopup popOL = null; public Office.CommandBarPopup popOLSubAll = null; public Office.CommandBarPopup popOLSubSelected = null; public Office.CommandBarButton btnOLAbout = null; /// /// Add explorer menu /// based on info in fldr /// /// mapfolder menu will be displayed with void AddExplorerMenu(Outlook.MAPIFolder fldr) { //Debug testing System.Text.StringBuilder sbLog = new StringBuilder(); sbLog.AppendLine("Log: Start of AddExplorerMenu(MAPIFOLDER=\"" + fldr.Name + "\")"); int nHelpIndex = 0; object missing = Type.Missing; try { if (true) { sbLog.AppendLine("Log: Get reference to Explorer.CommandBars.ActiveMenuBar"); //d("is mailitem"); Office.CommandBar sbar = Explorer.CommandBars.ActiveMenuBar; //Find and remove our menu if it exists sbLog.AppendLine("Log: Remove OLI menu item if it was inserted before.."); foreach (Office.CommandBarControl c in sbar.Controls) { if (c.Tag == "AyaNovaPopup") { sbLog.AppendLine("Log: OLI menu item found from before, getting reference"); popOL = (Office.CommandBarPopup)c; break; } } if (popOL != null) { sbLog.AppendLine("Log: Removing stale OLI menu item"); popOL.Visible = false; popOL.Delete(false); popOL = null; } //nullify buttons btnOLSelectedToAyaNova = null; btnOLSelectedFromAyaNova = null; btnOLAllToAyaNova = null; btnOLAllFromAyaNova = null; btnOLConfig = null; popOLSubAll = null; popOLSubSelected = null; btnOLAbout = null; //Should it display? sbLog.AppendLine("Log: Should it display? (DefaultItemType=\""+fldr.DefaultItemType.ToString() + "\")"); switch (fldr.DefaultItemType) { //Items we currently handle: case Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem: case Microsoft.Office.Interop.Outlook.OlItemType.olContactItem: case Microsoft.Office.Interop.Outlook.OlItemType.olMailItem: break; default: return; } //d("popOL is null?:"+(popOL==null).ToString()); if (popOL == null) { // Locate the Help menu try { nHelpIndex = sbar.Controls["Help"].Index; } catch { nHelpIndex = sbar.Controls.Count; if (nHelpIndex == 0) nHelpIndex = 1; sbLog.AppendLine("Log: Help menu not located, using index " + nHelpIndex + " instead"); } //add it sbLog.AppendLine("Log: Adding menu item now..."); popOL = (Office.CommandBarPopup)sbar.Controls.Add(Office.MsoControlType.msoControlPopup, missing, "AyaNovaPopup", nHelpIndex, true); popOL.Caption = "AyaNova"; popOL.Visible = true; popOL.Tag = "AyaNovaPopup"; sbLog.AppendLine("Log: Menu item added, now adding buttons for types we can handle in this case..."); switch (fldr.DefaultItemType) { //Items we currently handle: case Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem: { sbLog.AppendLine("Log: About to add appointment item buttons..."); btnOLAllFromAyaNova = (Office.CommandBarButton)popOL.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLAllFromAyaNova", missing, true); btnOLAllFromAyaNova.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLAllFromAyaNova.Caption = "Import AyaNova schedule items"; btnOLConfig = (Office.CommandBarButton)popOL.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLConfig", missing, true); btnOLConfig.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLConfig.Caption = "Options"; btnOLConfig.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLConfig_Click); btnOLAllFromAyaNova.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLAllFromAyaNova_Click); btnOLAbout = (Office.CommandBarButton)popOL.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLAbout", missing, true); btnOLAbout.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLAbout.Caption = "&About"; btnOLAbout.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLAbout_Click); sbLog.AppendLine("Log: Added appointmentitem buttons"); } break; case Microsoft.Office.Interop.Outlook.OlItemType.olContactItem: { sbLog.AppendLine("Log: About to add contactitem buttons..."); popOLSubSelected = (Office.CommandBarPopup)popOL.Controls.Add(Office.MsoControlType.msoControlPopup, missing, "popOLSubSelected", missing, true); popOLSubSelected.Caption = "Selected items..."; popOLSubSelected.Visible = true; popOLSubSelected.Tag = "popOLSubSelected"; btnOLSelectedFromAyaNova = (Office.CommandBarButton)popOLSubSelected.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLSelectedFromAyaNova", missing, true); btnOLSelectedFromAyaNova.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLSelectedFromAyaNova.Caption = "Import AyaNova contacts"; btnOLSelectedToAyaNova = (Office.CommandBarButton)popOLSubSelected.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLSelectedToAyaNova", missing, true); btnOLSelectedToAyaNova.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLSelectedToAyaNova.Caption = "Export Outlook contacts"; popOLSubAll = (Office.CommandBarPopup)popOL.Controls.Add(Office.MsoControlType.msoControlPopup, missing, "popOLSubAll", missing, true); popOLSubAll.Caption = "All items..."; popOLSubAll.Visible = true; popOLSubAll.Tag = "popOLSubAll"; btnOLAllFromAyaNova = (Office.CommandBarButton)popOLSubAll.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLAllFromAyaNova", missing, true); btnOLAllFromAyaNova.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLAllFromAyaNova.Caption = "Import AyaNova contacts"; btnOLAllToAyaNova = (Office.CommandBarButton)popOLSubAll.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLAllToAyaNova", missing, true); btnOLAllToAyaNova.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLAllToAyaNova.Caption = "Export Outlook contacts"; btnOLAllFromAyaNova.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLAllFromAyaNova_Click); btnOLAllToAyaNova.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLAllToAyaNova_Click); btnOLSelectedFromAyaNova.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLSelectedFromAyaNova_Click); btnOLSelectedToAyaNova.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLSelectedToAyaNova_Click); btnOLConfig = (Office.CommandBarButton)popOL.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLConfig", missing, true); btnOLConfig.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLConfig.Caption = "Options"; btnOLConfig.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLConfig_Click); btnOLAbout = (Office.CommandBarButton)popOL.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLAbout", missing, true); btnOLAbout.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLAbout.Caption = "&About"; btnOLAbout.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLAbout_Click); sbLog.AppendLine("Log: Added appointmentitem buttons."); } break; case Microsoft.Office.Interop.Outlook.OlItemType.olMailItem: { sbLog.AppendLine("Log: About to add mail item buttons..."); btnOLConfig = (Office.CommandBarButton)popOL.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLConfig", missing, true); btnOLConfig.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLConfig.Caption = "Options"; btnOLConfig.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLConfig_Click); btnOLAbout = (Office.CommandBarButton)popOL.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLAbout", missing, true); btnOLAbout.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLAbout.Caption = "&About"; btnOLAbout.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLAbout_Click); sbLog.AppendLine("Log: Added mail item buttons"); } break; } } } } catch (Exception ex) { MessageBox.Show("ExplorerWrapper->AddMenu exception:\r\n" + ex.ToString() + "\r\n=========== DEBUG LOG ===========\r\n" + sbLog.ToString() ); } } #endregion add explorer menu #region AyaNova Explorer commands /// /// About - Version and copyright /// /// /// private void btnOLAbout_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { About d = new About(); d.ShowDialog(); d.Dispose(); return; } /// /// Config - user preferences /// /// /// private void btnOLConfig_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { //Util.d("Stub:Config - UPDATE Properties..."); //AyaNovaOL.Properties.Settings.Default.Upgrade(); //AyaNovaOL.Properties.Settings.Default.Save(); //Util.d("Stub:Config - Properties updated"); Util.db("Options selected, checking if AyaNOva initialized..."); if (!Util.Login()) return; Util.db("AyaNova initialized and logged in, calling options dialog..."); Options d = new Options(); d.ShowDialog(); d.Dispose(); } /// /// Export / Sync Selected items to AyaNova /// /// /// private void btnOLSelectedToAyaNova_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { if (!Util.Login()) return; switch (Explorer.CurrentFolder.DefaultItemType) { //Items we currently handle: case Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem: { MessageBox.Show("STUB:SelectedToAyaNova->olAppointmentItem"); } break; case Microsoft.Office.Interop.Outlook.OlItemType.olContactItem: { #region Export selected contact items to AyaNova ContactExportOptions d = new ContactExportOptions(); if (d.ShowDialog() != DialogResult.OK) { d.Dispose(); return; } d.Dispose(); //do the export ExportContactsToAyaNova exp = new ExportContactsToAyaNova(); try { Cursor.Current = Cursors.WaitCursor; exp.DoExport(true, Explorer); Util.d("All done!"); } catch (Exception ex) { MessageBox.Show(ex.Message); } #endregion export selected contact items to AyaNova } break; case Microsoft.Office.Interop.Outlook.OlItemType.olMailItem: { MessageBox.Show("STUB:SelectedToAyaNova->olMailItem"); } break; default: return; } } /// /// Sync selected items from AyaNova /// /// /// private void btnOLSelectedFromAyaNova_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { if (!Util.Login()) return; switch (Explorer.CurrentFolder.DefaultItemType) { //Items we currently handle: case Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem: { MessageBox.Show("STUB:SelectedFromAyaNova->olAppointmentItem"); } break; case Microsoft.Office.Interop.Outlook.OlItemType.olContactItem: { #region Import selected contact items from AyaNova ChooseAyaContactType d = new ChooseAyaContactType(); d.ShowDialog(); if (d.SelectedObjectType == RootObjectTypes.Nothing) { d.Dispose(); return; } SelectAyaNovaContacts s = new SelectAyaNovaContacts(d.SelectedObjectType,d.SelectedVendorType); s.ShowDialog(); if (s.SelectedIDList == null || s.SelectedIDList.Count == 0) { s.Dispose(); d.Dispose(); return; } ImportContactsFromAyaNova im = new ImportContactsFromAyaNova(); try { Cursor.Current = Cursors.WaitCursor; im.DoImport(true, Explorer.CurrentFolder, d.SelectedObjectType, d.SelectedVendorType, s.SelectedIDList); } catch (Exception ex) { MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); } s.Dispose(); d.Dispose(); Util.d("All done!"); #endregion import selected contact items from AyaNova } break; case Microsoft.Office.Interop.Outlook.OlItemType.olMailItem: { MessageBox.Show("STUB:SelectedFromAyaNova->olMailItem"); } break; default: return; } } /// /// Export / Sync All items to AyaNova /// /// /// private void btnOLAllToAyaNova_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { if (!Util.Login()) return; switch (Explorer.CurrentFolder.DefaultItemType) { //Items we currently handle: case Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem: { MessageBox.Show("STUB:AllToAyaNova->olAppointmentItem"); } break; case Microsoft.Office.Interop.Outlook.OlItemType.olContactItem: { #region Export all contact items to AyaNova ContactExportOptions d = new ContactExportOptions(); if (d.ShowDialog() != DialogResult.OK) { d.Dispose(); return; } d.Dispose(); //do the export ExportContactsToAyaNova exp = new ExportContactsToAyaNova(); try { Cursor.Current = Cursors.WaitCursor; exp.DoExport(false, Explorer); Util.d("All done!"); } catch (Exception ex) { MessageBox.Show(ex.Message); } #endregion export all contact items to AyaNova } break; case Microsoft.Office.Interop.Outlook.OlItemType.olMailItem: { MessageBox.Show("STUB:AllToAyaNova->olMailItem"); } break; default: return; } } /// /// Import / Sync all items from AyaNova /// /// /// private void btnOLAllFromAyaNova_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { if (!Util.Login()) return; switch (Explorer.CurrentFolder.DefaultItemType) { //Items we currently handle: case Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem: { #region Import schedule from AyaNova UserTypes currentUserType = User.CurrentUserType; if (currentUserType != UserTypes.Schedulable) { MessageBox.Show("This feature can only be used by scheduleable users.\r\n" + "The current AyaNova logged in user is an " + currentUserType.ToString() + " type of user."); return; } ImportSchedule Imp = new ImportSchedule(Explorer.Application, Util.LocaleText); try { Cursor.Current = Cursors.WaitCursor; Imp.Import(false); Cursor.Current = Cursors.Default; Util.d("All done!"); } catch (Exception ex) { MessageBox.Show("Import failed with the following error:\r\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } #endregion } break; case Microsoft.Office.Interop.Outlook.OlItemType.olContactItem: { #region Import contact item ChooseAyaContactType d = new ChooseAyaContactType(); d.ShowDialog(); if (d.SelectedObjectType == RootObjectTypes.Nothing) { d.Dispose(); return; } ImportContactsFromAyaNova im = new ImportContactsFromAyaNova(); try { Cursor.Current = Cursors.WaitCursor; im.DoImport(false, Explorer.CurrentFolder, d.SelectedObjectType, d.SelectedVendorType, null); } catch (Exception ex) { MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); } d.Dispose(); Util.d("All done!"); #endregion import contact item } break; case Microsoft.Office.Interop.Outlook.OlItemType.olMailItem: { MessageBox.Show("STUB:AllFromAyaNova->olMailItem"); } break; default: return; } } #endregion explorer commands }// ----------- end of ExplorerWrapper.cs ----------------------- #endregion ExplorerWrapper #region InspectorWrapper // ----------- InspectorWrapper.cs ----------------------------- internal class InspectorWrapper : WrapperClass { #region Setup public Outlook.Inspector Inspector { get; private set; } public int CurrentItemID { get; private set; } public Outlook.MailItem CurrentMailItem { get; private set; } public InspectorWrapper(Outlook.Inspector inspector) { CurrentItemID = 0; Inspector = inspector; if (inspector.CurrentItem is Outlook.MailItem) { CurrentMailItem = (Outlook.MailItem)inspector.CurrentItem; CurrentItemID = CurrentMailItem.GetHashCode(); } AddMenu(); ConnectEvents(); } void ConnectEvents() { //case 1520 //((Outlook.InspectorEvents_10_Event)Inspector).Activate += new Microsoft.Office.Interop.Outlook.InspectorEvents_10_ActivateEventHandler(InspectorWrapper_Activate); // ((Outlook.InspectorEvents_10_Event)Inspector).BeforeMaximize += new Microsoft.Office.Interop.Outlook.InspectorEvents_10_BeforeMaximizeEventHandler(InspectorWrapper_BeforeMaximize); //((Outlook.InspectorEvents_10_Event)Inspector).BeforeMinimize += new Microsoft.Office.Interop.Outlook.InspectorEvents_10_BeforeMinimizeEventHandler(InspectorWrapper_BeforeMinimize); // ((Outlook.InspectorEvents_10_Event)Inspector).BeforeMove += new Microsoft.Office.Interop.Outlook.InspectorEvents_10_BeforeMoveEventHandler(InspectorWrapper_BeforeMove); // ((Outlook.InspectorEvents_10_Event)Inspector).BeforeSize += new Microsoft.Office.Interop.Outlook.InspectorEvents_10_BeforeSizeEventHandler(InspectorWrapper_BeforeSize); ((Outlook.InspectorEvents_10_Event)Inspector).Close += new Microsoft.Office.Interop.Outlook.InspectorEvents_10_CloseEventHandler(InspectorWrapper_Close); //((Outlook.InspectorEvents_10_Event)Inspector).Deactivate += new Microsoft.Office.Interop.Outlook.InspectorEvents_10_DeactivateEventHandler(InspectorWrapper_Deactivate); } void DisconnectEvents() { //case 1520 //((Outlook.InspectorEvents_10_Event)Inspector).Activate -= new Microsoft.Office.Interop.Outlook.InspectorEvents_10_ActivateEventHandler(InspectorWrapper_Activate); //((Outlook.InspectorEvents_10_Event)Inspector).BeforeMaximize -= new Microsoft.Office.Interop.Outlook.InspectorEvents_10_BeforeMaximizeEventHandler(InspectorWrapper_BeforeMaximize); // ((Outlook.InspectorEvents_10_Event)Inspector).BeforeMinimize -= new Microsoft.Office.Interop.Outlook.InspectorEvents_10_BeforeMinimizeEventHandler(InspectorWrapper_BeforeMinimize); // ((Outlook.InspectorEvents_10_Event)Inspector).BeforeMove -= new Microsoft.Office.Interop.Outlook.InspectorEvents_10_BeforeMoveEventHandler(InspectorWrapper_BeforeMove); // ((Outlook.InspectorEvents_10_Event)Inspector).BeforeSize -= new Microsoft.Office.Interop.Outlook.InspectorEvents_10_BeforeSizeEventHandler(InspectorWrapper_BeforeSize); ((Outlook.InspectorEvents_10_Event)Inspector).Close -= new Microsoft.Office.Interop.Outlook.InspectorEvents_10_CloseEventHandler(InspectorWrapper_Close); // ((Outlook.InspectorEvents_10_Event)Inspector).Deactivate -= new Microsoft.Office.Interop.Outlook.InspectorEvents_10_DeactivateEventHandler(InspectorWrapper_Deactivate); } //defined here to avoid being gc'd and losing functionality public Office.CommandBarButton btnAyaNovaNewWO = null; public Office.CommandBarButton btnAyaNovaNewSchedMarker = null; public Office.CommandBarPopup popAyaNova = null; public Office.CommandBarButton btnOLConfig = null; public Office.CommandBarButton btnOLAbout = null; void AddMenu() { object missing = Type.Missing; try { if (Inspector.CurrentItem is Outlook.MailItem && !IsWordEditor/*case 1520*/) { //d("is mailitem"); Office.CommandBar sbar = Inspector.CommandBars.ActiveMenuBar;//["Standard"]; int nHelpIndex = 0; foreach (Office.CommandBarControl c in sbar.Controls) { if (c.Tag == "AyaNovaPopup") { popAyaNova = (Office.CommandBarPopup)c; break; } } if (popAyaNova != null) { popAyaNova.Delete(false); popAyaNova = null; } //d("popAyaNova is null?:"+(popAyaNova==null).ToString()); if (popAyaNova == null) { // Locate the Help menu try { nHelpIndex = sbar.Controls["Help"].Index; } catch { nHelpIndex = sbar.Controls.Count; //case 1911 if (nHelpIndex == 0) nHelpIndex = 1; } //add it popAyaNova = (Office.CommandBarPopup)sbar.Controls.Add(Office.MsoControlType.msoControlPopup, missing, "AyaNovaPopup", nHelpIndex, true); popAyaNova.Caption = "AyaNova"; popAyaNova.Visible = true; popAyaNova.Tag = "AyaNovaPopup"; btnAyaNovaNewWO = (Office.CommandBarButton)popAyaNova.Controls.Add(Office.MsoControlType.msoControlButton, missing, "AyaNovaMailItem", missing, true); btnAyaNovaNewWO.Style = Office.MsoButtonStyle.msoButtonCaption; btnAyaNovaNewWO.Caption = "Schedule workorder item"; btnAyaNovaNewSchedMarker = (Office.CommandBarButton)popAyaNova.Controls.Add(Office.MsoControlType.msoControlButton, missing, "AyaNovaMailItem", missing, true); btnAyaNovaNewSchedMarker.Style = Office.MsoButtonStyle.msoButtonCaption; btnAyaNovaNewSchedMarker.Caption = "New Schedule Marker"; btnOLConfig = (Office.CommandBarButton)popAyaNova.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLConfig", missing, true); btnOLConfig.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLConfig.Caption = "Options"; btnOLConfig.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLConfig_Click); btnOLAbout = (Office.CommandBarButton)popAyaNova.Controls.Add(Office.MsoControlType.msoControlButton, missing, "OLAbout", missing, true); btnOLAbout.Style = Office.MsoButtonStyle.msoButtonCaption; btnOLAbout.Caption = "&About"; btnOLAbout.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnOLAbout_Click); //d("set events and tags"); btnAyaNovaNewWO.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnAyaNova_Click); // d("2"); btnAyaNovaNewWO.Tag = "AyaNovaNewWO" + CurrentItemID.ToString(); // d("3"); btnAyaNovaNewSchedMarker.Click += new Office._CommandBarButtonEvents_ClickEventHandler(btnAyaNova_Click); // d("4"); btnAyaNovaNewSchedMarker.Tag = "AyaNovaNewSchedMarker" + CurrentItemID.ToString(); //d("Done"); } } } catch (Exception ex) { MessageBox.Show("InspectorWrapper->AddMenu exception:\r\n" + ex.ToString()); } } void d(string s) { MessageBox.Show(s); } void InspectorWrapper_Close() { DisconnectEvents(); btnAyaNovaNewWO = null; btnAyaNovaNewSchedMarker = null; popAyaNova = null; btnOLConfig = null; btnOLAbout = null; if (CurrentMailItem != null) Marshal.ReleaseComObject(CurrentMailItem); if (Inspector != null) Marshal.ReleaseComObject(Inspector); // Inspector = null; // GC.Collect(); //GC.WaitForPendingFinalizers(); OnClosed(); } /// /// Case 1520 /// /// bool IsWordEditor { get { if (Inspector!=null && Inspector.IsWordMail() && Inspector.EditorType == Microsoft.Office.Interop.Outlook.OlEditorType.olEditorWord && Inspector.WordEditor != null) return true; return false; } } #endregion #region Resize / Move void InspectorWrapper_BeforeSize(ref bool Cancel) { } void InspectorWrapper_BeforeMove(ref bool Cancel) { } void InspectorWrapper_BeforeMinimize(ref bool Cancel) { } void InspectorWrapper_BeforeMaximize(ref bool Cancel) { } #endregion #region Activate / Deactivate void InspectorWrapper_Activate() { //case 1520 if (Inspector != null) { } } void InspectorWrapper_Deactivate() { } #endregion #region AyaNova specific /// /// About - Version and copyright /// /// /// private void btnOLAbout_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { About d = new About(); d.ShowDialog(); d.Dispose(); } /// /// Config - user preferences /// /// /// private void btnOLConfig_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { Util.db("Options selected, checking if AyaNOva initialized..."); if (!Util.Login()) return; Util.db("AyaNova initialized and logged in, calling options dialog..."); Options d = new Options(); d.ShowDialog(); d.Dispose(); } private void btnAyaNova_Click(Office.CommandBarButton ctrl, ref bool CancelDefault) { if (!Util.Login()) return; if (ctrl.Tag.StartsWith("AyaNovaNewWO")) { //Try to Match client based on sender address Guid gClientID = MatchClientToSenderAddress(); WorkorderSelector d = new WorkorderSelector(); d.SuggestedClient = gClientID; d.EmailText = CurrentMailItemToString(); if (d.ShowDialog() == DialogResult.Cancel) { d.Dispose(); return; } d.Dispose(); return; } if (ctrl.Tag.StartsWith("AyaNovaNewSchedMarker")) { ScheduleMarker sm = ScheduleMarker.NewItem(); sm.Notes = CurrentMailItemToString(); //Start new sched markers on the next hour and add one hour. DateTime n=DateTime.Now; DateTime dtStart=new System.DateTime(n.Year, n.Month, n.Day, n.Hour, 0, 0).AddHours(1); sm.StartDate = dtStart; sm.StopDate = dtStart.AddHours(1); ScheduleMarkerForm smf = new ScheduleMarkerForm(); smf.ScheduleMarkerToEdit = sm; if (smf.ShowDialog() == DialogResult.Cancel) { smf.Dispose(); return; } smf.Dispose(); } } private Guid MatchClientToSenderAddress() { Guid clientID = Guid.Empty; string SenderEmail = ""; try { SenderEmail = X4UMapi.GetMessageSenderAddress(CurrentMailItem.MAPIOBJECT); } catch { } if (!string.IsNullOrEmpty(SenderEmail)) { GenericNVList gnv = GenericNVList.GetList("CLIENT", "ID", "EMAIL", true, true, true); foreach (System.Collections.DictionaryEntry de in gnv.BindableList) { if (SenderEmail.Equals(de.Value.ToString(), StringComparison.InvariantCultureIgnoreCase)) { return new Guid(de.Key.ToString()); } } } return Guid.Empty; } private string CurrentMailItemToString() { StringBuilder sb = new StringBuilder(); //sent //from //to //subject //body sb.Append("Sent: "); sb.Append(CurrentMailItem.SentOn.ToString()); sb.Append("\r\n"); sb.Append("From: "); sb.Append(X4UMapi.GetMessageSenderAddress(CurrentMailItem.MAPIOBJECT)); sb.Append("\r\n"); sb.Append("To: "); sb.Append(CurrentMailItem.To); sb.Append("\r\n"); sb.Append("Subject: "); sb.Append(CurrentMailItem.Subject); sb.Append("\r\n"); sb.Append("\r\n"); sb.Append(X4UMapi.GetMessageBody(CurrentMailItem.MAPIOBJECT)); if (AyaNovaOL.Properties.Settings.Default.IncludeEmailHeader) { string sHeader = X4UMapi.GetMessageHeaders(CurrentMailItem.MAPIOBJECT); if (!string.IsNullOrEmpty(sHeader)) { sb.Append("\r\n\r\n---------< message header >--------------\r\n"); sb.Append(sHeader); } } return sb.ToString(); } #endregion } // ----------- end of InspectorWrapper.cs ---------------------------- #endregion #region Mapi assistance public class X4UMapi { #region Public Functions /// /// The GetMessageBody function is used to retrieve a messagebody of a email without hitting the Outlook Security Guard. /// /// /// The messagebody as string /// /// object missing = Missing.Value; /// /// get the Outlook Application Object /// Outlook.Application outlookApplication = new Outlook.Application(); /// /// get the namespace object /// Outlook.NameSpace nameSpace = outlookApplication.GetNamespace("MAPI"); /// /// Logon to Session, here we use an already opened Outlook /// nameSpace.Logon(missing, missing, false, false); /// /// get the InboxFolder /// Outlook.MAPIFolder inboxFolder = nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); /// /// get the first email /// Outlook.MailItem mailItem = ( Outlook.MailItem ) inboxFolder.Items[1]; /// /// get mailbody /// string body = X4UMapi.GetMessageBody(mailItem.MAPIOBJECT); /// /// release used resources /// Marshal.ReleaseComObject(mailItem); /// Marshal.ReleaseComObject(inboxFolder); /// /// logof from namespace /// nameSpace.Logoff(); /// /// release resources /// Marshal.ReleaseComObject( nameSpace ); /// Marshal.ReleaseComObject(outlookApplication.Application); /// public static string GetMessageBody(object mapiObject) { // try to get the message body string body = GetMessageProperty(mapiObject, PR_BODY); // if body is empty, get HTML_BODY Property if (body == "") GetMessageProperty(mapiObject, PR_BODY_HTML); // if body still empty, get HTML Property if (body == "") GetMessageProperty(mapiObject, PR_HTML); return body; } /// /// The GetMessageSenderAddress function is used to retrieve a messagebody of a email without hitting the Outlook Security Guard. /// /// The Outlook Item MAPIOBJECT property /// The sender EmailAddress as string /// /// object missing = Missing.Value; /// /// get the Outlook Application Object /// Outlook.Application outlookApplication = new Outlook.Application(); /// /// get the namespace object /// Outlook.NameSpace nameSpace = outlookApplication.GetNamespace("MAPI"); /// /// Logon to Session, here we use an already opened Outlook /// nameSpace.Logon(missing, missing, false, false); /// /// get the InboxFolder /// Outlook.MAPIFolder inboxFolder = nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); /// /// get the first email /// Outlook.MailItem mailItem = ( Outlook.MailItem ) inboxFolder.Items[1]; /// /// get mailbody /// string body = X4UMapi.GetMessageBody(mailItem.MAPIOBJECT); /// /// release used resources /// Marshal.ReleaseComObject(mailItem); /// Marshal.ReleaseComObject(inboxFolder); /// /// logof from namespace /// nameSpace.Logoff(); /// /// release resources /// Marshal.ReleaseComObject( nameSpace ); /// Marshal.ReleaseComObject(outlookApplication.Application); /// public static string GetMessageSenderAddress(object mapiObject) { // try to get the message body return GetMessageProperty(mapiObject, PR_SENDER_EMAIL_ADDRESS); } public static string GetMessageHeaders(object mapiObject) { return GetMessageProperty(mapiObject, PR_TRANSPORT_MESSAGE_HEADERS); } #endregion #region Internal Functions /// /// Returns the Propertyvalue as string from the given Property Tag /// /// [in] The Outlook Item MAPIOBJECT Property /// [in] The Property Tag to retrieve /// The Item Body as string. private static string GetMessageProperty(object mapiObject, uint propertyTag) { string body = ""; // Pointer to IUnknown Interface IntPtr IUnknown = NULL; // Pointer to IMessage Interface IntPtr IMessage = NULL; // Pointer to IMAPIProp Interface IntPtr IMAPIProp = NULL; // Structure that will hold the Property Value SPropValue propValue; // A pointer that points to the SPropValue structure IntPtr ptrPropValue = NULL; // if we have no MAPIObject everything is senseless... if (mapiObject == null) return ""; try { // We can pass NULL here as parameter, so we do it. MAPIInitialize(NULL); // retrive the IUnknon Interface from our MAPIObject comming from Outlook. IUnknown = Marshal.GetIUnknownForObject(mapiObject); // since HrGetOneProp needs a IMessage Interface, we must query our IUnknown interface for the IMessage interface. // create a Guid that we pass to retreive the IMessage Interface. Guid guidIMessage = new Guid(IID_IMessage); // try to retrieve the IMessage interface, if we don't get it, everything else is sensless. if (Marshal.QueryInterface(IUnknown, ref guidIMessage, out IMessage) != S_OK) return ""; // create a Guid that we pass to retreive the IMAPIProp Interface. Guid guidIMAPIProp = new Guid(IID_IMAPIProp); // try to retrieve the IMAPIProp interface from IMessage Interface, everything else is sensless. if (Marshal.QueryInterface(IMessage, ref guidIMAPIProp, out IMAPIProp) != S_OK) return ""; // double check, if we wave no pointer, exit... if (IMAPIProp == NULL) return ""; // try to get the Property ( Property Tags can be found with Outlook Spy from Dmitry Streblechenko ) // we pass the IMAPIProp Interface, the PropertyTag and the pointer to the SPropValue to the function. HrGetOneProp(IMAPIProp, propertyTag, out ptrPropValue); // if that also fails we have no such property if (ptrPropValue == NULL) return ""; // connect the pointer to our structure holding the value propValue = (SPropValue)Marshal.PtrToStructure(ptrPropValue, typeof(SPropValue)); // now get the property // mark, that the result could also be a pointer to a stream if the messagebody is > 64K // the property value could also of another type body = Marshal.PtrToStringAnsi(new IntPtr(propValue.Value)); return body; } catch (System.Exception ex) { return ""; } finally { // Free used Memory structures if (ptrPropValue != NULL) MAPIFreeBuffer(ptrPropValue); // cleanup all references to COM Objects if (IMAPIProp != NULL) Marshal.Release(IMAPIProp); if (IMessage != NULL) Marshal.Release(IMessage); if (IUnknown != NULL) Marshal.Release(IUnknown); MAPIUninitialize(); } } #endregion #region Private Properties /// /// A Variable used as C-Style NULL Pointer; /// private static readonly IntPtr NULL = IntPtr.Zero; /// /// Used for checking returncodes. /// private const int S_OK = 0; #endregion #region Initialization / Cleanup /// /// The construction Code. /// public X4UMapi() { } #endregion #region MAPI Interface ID'S // The Interface ID's are used to retrieve the specific MAPI Interfaces from the IUnknown Object public const string IID_IMAPISession = "00020300-0000-0000-C000-000000000046"; public const string IID_IMAPIProp = "00020303-0000-0000-C000-000000000046"; public const string IID_IMAPITable = "00020301-0000-0000-C000-000000000046"; public const string IID_IMAPIMsgStore = "00020306-0000-0000-C000-000000000046"; public const string IID_IMAPIFolder = "0002030C-0000-0000-C000-000000000046"; public const string IID_IMAPISpoolerService = "0002031E-0000-0000-C000-000000000046"; public const string IID_IMAPIStatus = "0002031E-0000-0000-C000-000000000046"; public const string IID_IMessage = "00020307-0000-0000-C000-000000000046"; public const string IID_IAddrBook = "00020309-0000-0000-C000-000000000046"; public const string IID_IProfSect = "00020304-0000-0000-C000-000000000046"; public const string IID_IMAPIContainer = "0002030B-0000-0000-C000-000000000046"; public const string IID_IABContainer = "0002030D-0000-0000-C000-000000000046"; public const string IID_IMsgServiceAdmin = "0002031D-0000-0000-C000-000000000046"; public const string IID_IProfAdmin = "0002031C-0000-0000-C000-000000000046"; public const string IID_IMailUser = "0002030A-0000-0000-C000-000000000046"; public const string IID_IDistList = "0002030E-0000-0000-C000-000000000046"; public const string IID_IAttachment = "00020308-0000-0000-C000-000000000046"; public const string IID_IMAPIControl = "0002031B-0000-0000-C000-000000000046"; public const string IID_IMAPILogonRemote = "00020346-0000-0000-C000-000000000046"; public const string IID_IMAPIForm = "00020327-0000-0000-C000-000000000046"; #endregion #region Property Tags /// /// Used to get the Emailheaders /// public const uint PR_TRANSPORT_MESSAGE_HEADERS = 0x007D001E; /// /// Used to read the Body of an Email /// public const uint PR_BODY = 0x1000001E; /// /// Used to read the HTML Body of the Email /// public const uint PR_BODY_HTML = 0x1013001E; /// /// Used to read the HTML Body of the Email /// public const uint PR_HTML = 0x10130102; /// /// Used to read the smtp / exchange sender address of an Email /// public const uint PR_SENDER_EMAIL_ADDRESS = 0x0C1F001E; #endregion #region MAPI Structures /// /// The SPropValue structure describes a MAPI property. /// public struct SPropValue { /// /// Property tag for the property. Property tags are 32-bit unsigned integers consisting of the property's unique identifier in the high-order 16 bits and the property's type in the low-order 16 bits. /// public uint ulPropTag; /// /// Reserved for MAPI; do not use. /// public uint dwAlignPad; /// /// Union of data values, the specific value dictated by the property type. /// public long Value; } #endregion #region MAPI DLL Imports /// /// The MAPIInitialize function increments the MAPI subsystem reference count and initializes global data for the MAPI DLL. /// /// [in] Pointer to a MAPIINIT_0 structure. The lpMapiInit parameter can be set to NULL. /// /// S_OK /// The MAPI subsystem was initialized successfully. /// [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)] private static extern int MAPIInitialize(IntPtr lpMapiInit); /// /// The MAPIUninitialize function decrements the reference count, cleans up, and deletes per-instance global data for the MAPI DLL. /// [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)] private static extern void MAPIUninitialize(); /// /// The HrGetOneProp function retrieves the value of a single property from a property interface, that is, an interface derived from IMAPIProp. /// /// [in] Pointer to the IMAPIProp interface from which the property value is to be retrieved. /// [in] Property tag of the property to be retrieved. /// [out] Pointer to a pointer to the returned SPropValue structure defining the retrieved property value. /// /// Unlike the IMAPIProp::GetProps method, the HrGetOneProp function never returns any warning. /// Because it retrieves only one property, it simply either succeeds or fails. For retrieving multiple properties, /// GetProps is faster. /// /// You can set or change a single property with the HrSetOneProp function. /// [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "HrGetOneProp@12")] private static extern void HrGetOneProp(IntPtr pmp, uint ulPropTag, out IntPtr ppprop); /// /// The HrSetOneProp function sets or changes the value of a single property on a property interface, that is, an interface derived from IMAPIProp. /// /// [in] Pointer to an IMAPIProp interface on which the property value is to be set or changed. /// [in] Pointer to the SPropValue structure defining the property to be set or changed. /// /// Unlike the IMAPIProp::SetProps method, the HrSetOneProp function never returns any warning. /// Because it sets only one property, it simply either succeeds or fails. /// For setting or changing multiple properties, SetProps is faster. /// /// You can retrieve a single property with the HrGetOneProp function. /// [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "HrGetOneProp@8")] private static extern void HrSetOneProp(IntPtr pmp, IntPtr pprop); /// /// The MAPIFreeBuffer function frees a memory buffer allocated with a call to the MAPIAllocateBuffer function or the MAPIAllocateMore function. /// /// [in] Pointer to a previously allocated memory buffer. If NULL is passed in the lpBuffer parameter, MAPIFreeBuffer does nothing. [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "MAPIFreeBuffer@4")] private static extern void MAPIFreeBuffer(IntPtr lpBuffer); #endregion } #endregion MapiAssistance #region AyaNova Util stuff /// /// Used within sub forms to indicate what to do /// with the current record /// public enum RecordActionType : int { SaveOnly = 1, SaveAndExit = 2, SaveAndNew = 3, PromptToSave = 4, DeleteAndExit = 5 } public class Util { internal static LocalizedTextTable LocaleText = null; public static Global GlobalSettings = null; public static GZTW.AyaNova.BLL.Region RegionalSettings = null; public static bool bLoggedIn = false; #region case 1421 dataportal issues public static void SerializationWorkaround() { AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.AssemblyResolve += new ResolveEventHandler (currentDomain_AssemblyResolve); } public static Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { db("currentDomain_AssemblyResolve, resolving: " + args.Name); Assembly[] list = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly asm in list) if (asm.FullName == args.Name) return asm; //case 1421 resolves potential infinite loop stack overflow return null; // return Assembly.Load(args.Name); } //Assembly currDomain_AssemblyResolve(object sender, ResolveEventArgs args) //{ // // get a list of all the assemblies loaded in our appdomain // Assembly[] list = AppDomain.CurrentDomain.GetAssemblies(); // // search the list to find the assembly that was not found automatically // // and return the assembly from the list // foreach (Assembly asm in list) // if (asm.FullName == args.Name) // return asm; // // if the assembly wasn't already in the appdomain, then try to load it. // //return Assembly.Load(args.Name); <-- stack overflow from an XML serialization assembly // return null; <--- my modification //} #endregion #region Login/Logout public static bool Login() { db("TopOfLogin(), checking if already logged in, if not then initializing and login will be next.."); if (bLoggedIn) return true; //case 1421 if (AyaBizUtils.AyaNovaConnectionSetting.UsingDataPortal) { db("Calling serialization workaround..."); SerializationWorkaround(); } try { db("Calling AyaBizUtils.Initialize()..."); GZTW.AyaNova.BLL.AyaBizUtils.Initialize(); db("Initialize OK, no exception"); } catch (Exception ex) { db("Exception when calling initialize, details to follow..."); //"crack" the exception to get to the innermost exception while (ex.InnerException != null) ex = ex.InnerException; MessageBox.Show("AyaNova initialization failed. Error: \r\n" + ex.Message + "\r\nStackTrace:\r\n" + ex.StackTrace); return false; } //************************ if (Thread.CurrentPrincipal.Identity.IsAuthenticated != false) { db("Authenticated is true, calling logout"); DoLogout(); } bool bDoLogin = true; string sLogin = "user"; string sPass = "user"; if (!AyaBizUtils.Lite) { Login dlg = null; #if(XDEBUG) dlg = new Login("manager", "letmein"); #else if(AyaBizUtils.Trial) dlg = new Login("manager","letmein"); else dlg = new Login("",""); #endif db("Login dialog instantiated, displaying it next..."); dlg.ShowDialog(); db("Login dialog closed, processing login..."); bDoLogin = dlg.LoggingIn; sLogin = dlg.Username; sPass = dlg.Password; dlg.Dispose(); } if (bDoLogin) { db("User chose OK from login dialog, processing login..."); AyaBizUtils.Login(sLogin, sPass); if (Thread.CurrentPrincipal.Identity.IsAuthenticated) { db("Authenticated, checking license..."); //check the license // bool bLicensed = (!string.IsNullOrEmpty(AyaBizUtils.PluginLicensedVersion("AyaNovaOLI"))); bool bLicensed = AyaBizUtils.PluginAllowed("AyaNovaOLI", AyaNova.PlugIn.AyaNovaOL.Timestamp.BuildAt); if (!bLicensed) { MessageBox.Show("An AyaNova OLI license is required to use this add-on.","AyaNova OLI License not found"); DoLogout(); return false; } db("License ok, retrieving settings and continuing processing, should be good from here."); //Get the settings User uLoggingIn = User.GetItem((((BusinessPrincipal)Thread.CurrentPrincipal).ID)); //change: 9-Nov-2006 check for client account login and prevent it if (uLoggingIn.IsClientOrHeadOfficeAccount) { MessageBox.Show("Sorry, client account logins are restricted to AyaNova WBI only."); return false; } //Load the localized text data Util.LocaleText = LocalizedTextTable.Load(uLoggingIn.DefaultLanguage); AyaBizUtils.GlobalSettings = null; Util.GlobalSettings = AyaBizUtils.GlobalSettings; Util.RegionalSettings = GZTW.AyaNova.BLL.Region.GetItem(uLoggingIn.RegionID); GZTW.AyaNova.BLL.AyaBizUtils.RegionalSettings = Util.RegionalSettings; //Get users form setting preferences collection //Util.gFormSettings = UIUserFormSettings.GetItems(User.CurrentThreadUserID); //Changed: 15-March-2005 added so that admins settings can be copied if any //missing for current user // Util.gAdminFormSettings = UIUserFormSettings.GetItems(User.AdministratorID); //Added: 22-May-2006 added for new grid layout objects Util.gGridLastViews = UIUserGridLastViews.GetItems(User.CurrentThreadUserID); //Localize all of the infragistics //components internal messages that user might see //this only needs to be called this one time for //the entire session //Util.LocalizeInfragistics(); bLoggedIn = true; return true; } else { MessageBox.Show("Login failed!"); DoLogout(); return false; } //************************** } else { db("User chose to cancel login"); return false; } } private static void DoLogout() { bLoggedIn = false; if (Thread.CurrentPrincipal == null || Thread.CurrentPrincipal.Identity.IsAuthenticated == false) return; Thread.CurrentPrincipal = null; } #endregion login/logout #region Localized DateTime mask for input /// /// Returns input mask to use in date and time editor for this locale /// /// static public string LocaleDateTimeMask() { CultureInfo ciCurrent = System.Globalization.CultureInfo.CurrentCulture; //Use date and time editor to calculate input mask DateTimeEditor editor = new DateTimeEditor(); string dateMask = editor.CalcDefaultDateMask(ciCurrent); string timeMask = editor.CalcDefaultTimeMask(ciCurrent); //Case 137 //.net doesn't set the short time format in the current culture object based on the //regional settings, but instead sets the long time pattern instead since the regional //settings only has one box to set a custom format in. Infragistics uses the incorrect //pattern (short) so it doesn't pick up the customized setting in calcdefaulttimemask //reported to infragistics and if they fix it I can revert this code back, but it probably internally //just does the same thing anyway. if (ciCurrent.DateTimeFormat.ShortTimePattern != ciCurrent.DateTimeFormat.LongTimePattern) { //timeMask = ciCurrent.DateTimeFormat.LongTimePattern; timeMask = "{longtime}"; } return dateMask + " " + timeMask; //------------------------------------------- } #endregion #region Localise Form or any control that can host controls //static Infragistics.Win.UltraWinExplorerBar.UltraExplorerBarViewStyle defaultExplorerBarViewStyle = Infragistics.Win.UltraWinExplorerBar.UltraExplorerBarViewStyle.XP; static UIElementButtonStyle defaultButtonStyle = UIElementButtonStyle.WindowsXPCommandButton; static DefaultableBoolean defaultUseOsThemes = DefaultableBoolean.False; static EmbeddableElementDisplayStyle defaultEmbeddableElementDisplayStyle = EmbeddableElementDisplayStyle.OfficeXP; //static Infragistics.Win.UltraWinToolbars.ToolbarStyle defaultToolBarStyle = ToolbarStyle.OfficeXP; #region Grid /// /// Modify ui elements to display localized values /// specific to a grid control because it's quirky when /// on a tab control (invisible) /// /// static public void LocalizeGrid(Infragistics.Win.UltraWinGrid.UltraGrid Grid) { //case 1039 //log.Debug("LocalizeGrid(" + Grid.Name +"."+ Grid.Parent.Name + ")"); //replace UltraGrid header text with localized version //this is a special case because the column headers are based on the read only collection //business object's public properties, which means the system of using LT: and periods to //denote and separate parts of locale text strings won't work //so in this case only the text we're looking for is in the format of: //LT_Object_Label_Item (underscores instead of colons and periods) Grid.DisplayLayout.ScrollBarLook.ViewStyle = Infragistics.Win.UltraWinScrollBar.ScrollBarViewStyle.Office2007; //Loop through the columns in the grid's band(0) column collection foreach (Infragistics.Win.UltraWinGrid.UltraGridBand band in Grid.DisplayLayout.Bands) { ////case 1039 //log.Debug("Processing " + band.Columns.Count.ToString() +" columns in band(" + band.Index.ToString() +")"); foreach (Infragistics.Win.UltraWinGrid.UltraGridColumn cm in band.Columns) { //check the header to see if it needs localizing... if (cm.Header.Caption.StartsWith("LT_")) { //yes it does, so replace the LT_ with nothing to get rid of it string s = cm.Header.Caption.Replace("LT_", ""); cm.Header.Caption = LocaleText.GetLocalizedText(s.Replace("_", ".")); } } } } /// /// If a grid is bound to an editable collection /// it's field names initially are our internal property names /// this function converts the column captions back to localized text keys /// so that the localize function later will set them correctly /// /// Name of business object band represents /// band to be pre-localized public static void GridPreLocalize(string ObjectName, Infragistics.Win.UltraWinGrid.UltraGridBand Band) { List PrivateColumns = new List(); PrivateColumns.Add("IsDirty"); PrivateColumns.Add("IsNew"); PrivateColumns.Add("IsSavable"); PrivateColumns.Add("Modifier"); PrivateColumns.Add("Created"); PrivateColumns.Add("Modified"); PrivateColumns.Add("Creator"); PrivateColumns.Add("IsDeleted"); PrivateColumns.Add("IsValid"); PrivateColumns.Add("BrokenRulesText"); PrivateColumns.Add("CurrentUserID"); PrivateColumns.Add("RootObjectID"); PrivateColumns.Add("RootObjectType"); PrivateColumns.Add("ID"); PrivateColumns.Add("ContactID");//<--TODO: HACK will need to be done repeatedly? Might need alternative? PrivateColumns.Add("HeadOfficeID");//<--TODO: HACK will need to be done repeatedly? Might need alternative? //case 1039 //log.Debug("GridPreLocalize(" + ObjectName + ", " + Band.Key+ ")"); foreach (Infragistics.Win.UltraWinGrid.UltraGridColumn c in Band.Columns) { if (!PrivateColumns.Contains(c.Header.Caption)) { c.Header.Caption = "LT_" + ObjectName + "_Label_" + c.Header.Caption; } } } #endregion /// /// Modify ui elements to display localized values /// static public void Localize(Control c) { if (c is Infragistics.Win.UltraWinEditors.UltraDateTimeEditor) { ((Infragistics.Win.UltraWinEditors.UltraDateTimeEditor)c).DisplayStyle = defaultEmbeddableElementDisplayStyle; ((Infragistics.Win.UltraWinEditors.UltraDateTimeEditor)c).ButtonStyle = defaultButtonStyle; ((Infragistics.Win.UltraWinEditors.UltraDateTimeEditor)c).UseOsThemes = defaultUseOsThemes; ((Infragistics.Win.UltraWinEditors.UltraDateTimeEditor)c).MaskInput = LocaleDateTimeMask(); } if (c is Infragistics.Win.UltraWinEditors.UltraCheckEditor) { // ((Infragistics.Win.UltraWinEditors.UltraCheckEditor)c).GlyphStyle = defaultGlyphStyle; ((Infragistics.Win.UltraWinEditors.UltraCheckEditor)c).GlyphInfo = Infragistics.Win.UIElementDrawParams.Office2007CheckBoxGlyphInfo; ((Infragistics.Win.UltraWinEditors.UltraCheckEditor)c).UseOsThemes = defaultUseOsThemes; } if (c is Infragistics.Win.UltraWinEditors.UltraTextEditor) { ((Infragistics.Win.UltraWinEditors.UltraTextEditor)c).DisplayStyle = defaultEmbeddableElementDisplayStyle; ((Infragistics.Win.UltraWinEditors.UltraTextEditor)c).UseOsThemes = defaultUseOsThemes; } //Localize the top level object itself if applicable if (c.Text.StartsWith("LT:")) c.Text = LocaleText.GetLocalizedText(c.Text.Replace("LT:", "")); if (c is Infragistics.Win.UltraWinEditors.UltraOptionSet) { Infragistics.Win.UltraWinEditors.UltraOptionSet uos = (Infragistics.Win.UltraWinEditors.UltraOptionSet)c; uos.GlyphInfo = Infragistics.Win.UIElementDrawParams.Office2007RadioButtonGlyphInfo; //uos.GlyphStyle = defaultGlyphStyle; uos.UseOsThemes = defaultUseOsThemes; foreach (Infragistics.Win.ValueListItem vi in uos.Items) { if (vi.DisplayText.StartsWith("LT:")) vi.DisplayText = LocaleText.GetLocalizedText(vi.DisplayText.Replace("LT:", "")); } //An ultraoptionset doesn't contain any child controls so bump up a level now return; } if (c is ToolStrip) { foreach (ToolStripItem i in ((ToolStrip)c).Items) { if (i.Text != null && i.Text.StartsWith("LT:")) i.Text = LocaleText.GetLocalizedText(i.Text.Replace("LT:", "")); if (i.ToolTipText != null && i.ToolTipText.StartsWith("LT:")) i.ToolTipText = LocaleText.GetLocalizedText(i.ToolTipText.Replace("LT:", "")); if (i is ToolStripDropDownButton) { ToolStripDropDownButton b = (ToolStripDropDownButton)i; foreach (ToolStripItem di in b.DropDownItems) { if (di.Text != null && di.Text.StartsWith("LT:")) di.Text = LocaleText.GetLocalizedText(di.Text.Replace("LT:", "")); if (di.ToolTipText != null && di.ToolTipText.StartsWith("LT:")) di.ToolTipText = LocaleText.GetLocalizedText(di.ToolTipText.Replace("LT:", "")); } } } } //Loop through the controls foreach (Control c2 in c.Controls) { Localize(c2); } } #endregion #region Business object data binding and broken rule feedback /// /// Take care of binding form controls to business object properties /// /// /// /// /// public static void BindField(Control control, string propertyName, object dataSource, string dataMember) { //if (log.IsDebugEnabled) // //case 1039 //log.Debug("BindField(" + control.Name + ", " + propertyName + ", " + dataSource.ToString() + ", " + dataMember + ")"); Binding bd; int index; index = control.DataBindings.Count - 1; while (index >= 0) { bd = control.DataBindings[index]; if (bd.PropertyName == propertyName) control.DataBindings.Remove(bd); index--; } control.DataBindings.Add(propertyName, dataSource, dataMember); } /// /// Display errorProvider icons beside any fields that have broken rules /// on the form /// /// Form containing business object /// Business object instance variable /// instance variable of ErrorProvider object on form public static void BrokenRuleFeedback(Control ctl, CSLA.BusinessBase Obj, ErrorProvider EP) { // //case 1039 //if(log.IsDebugEnabled) // //case 1039 //log.Debug("BrokenRuleFeedback("+ctl.Name+", " + Obj.ToString()+ ")"); //Loop through all databindings for control (if any) foreach (Binding b in ctl.DataBindings) { string sErr = BrokenRuleLocalizer(Obj.GetBrokenRulesCollection().get_RuleForProperty(b.BindingMemberInfo.BindingField).Description); //MessageBox.Show("ctrl:" + ctl.Name + " bindingField: " +b.BindingMemberInfo.BindingField + " error:"+ sErr); EP.SetError(ctl, sErr); } //recurse through all controls inside passed in control foreach (Control c in ctl.Controls) { BrokenRuleFeedback(c, Obj, EP); } } /// /// Takes a broken rule text and xforms it into the localized version /// applying all formatting as required /// /// /// private static string BrokenRuleLocalizer(string BrokenRuleString) { if (BrokenRuleString == null) return null; if (BrokenRuleString == "") return ""; //Localize and format the string //this string comes to us as a set of comma delimited localized text key strings //i.e. "Error.Object.RequiredFieldEmpty,Client.Label.Name" //the first key translates often to a string with format characters in it such as //"{0} is not a valid value for the {1} field //The second and following keys are the values to be inserted in those format positions //This code makes an object array of all the second and following localized text strings //and then passes that to the string.format function along with the first string string[] sarray = BrokenRuleString.Split(','); object[] sitems = new object[sarray.GetLength(0) - 1]; for (int x = 1; x < sarray.GetLength(0); x++) { sitems[x - 1] = LocaleText.GetLocalizedText(sarray[x]); } return string.Format(LocaleText.GetLocalizedText(sarray[0]), sitems); } /// /// cracks a broken rule collection into separate errors /// then processes them /// /// A brokenrulestext property of a biz object contains one or more /// broken rules as in the brokenrulelocalizer method above, but /// separated by pipe characters | /// /// /// public static string BrokenRuleCollectionLocalizer(string BrokenRuleCollection) { StringBuilder sb = new StringBuilder(); string[] sarray = BrokenRuleCollection.Split('|'); foreach (string s in sarray) { sb.Append(BrokenRuleLocalizer(s)); sb.Append("\r\n"); } return sb.ToString(); } #endregion #region Grid broken rules display /// /// If the current row's underlying list object /// has broken rules, then show a broken rule error icon in the row selector /// /// static public void GridShowBrokenRulesErrorIcons(Infragistics.Win.UltraWinGrid.InitializeRowEventArgs e) { //removed item below, too wordy in log ////case 1039 //log.Debug("GridShowBrokenRulesErrorIcons"); if (e.Row.ListObject != null) { //If it's not valid (has broken rules) then //put an error icon in the row selector //otherwise clear any previous one that might be there if (!((CSLA.BusinessBase)e.Row.ListObject).IsValid) e.Row.RowSelectorAppearance.Image = new System.Windows.Forms.ErrorProvider().Icon.ToBitmap(); else e.Row.RowSelectorAppearance.Image = null; } } /// /// Show tool tip containing all broken rules if mouse over a /// broken rule icon in the row selector /// /// /// static public void GridShowBrokenRulesToolTip(Infragistics.Win.UIElementEventArgs e, System.Windows.Forms.ToolTip tipError) { //too wordy to include this ////case 1039 //log.Debug("GridShowBrokenRulesToolTip"); tipError.RemoveAll(); if (e.Element is RowSelectorUIElement) { RowSelectorUIElement UIElement = (RowSelectorUIElement)e.Element; if (UIElement.Row.ListObject != null) { //If it's not valid (has broken rules) then //put an error icon in the row selector //otherwise clear any previous one that might be there if (!((CSLA.BusinessBase)UIElement.Row.ListObject).IsValid) { tipError.InitialDelay = 0; StringBuilder sbLocalizedBrokenRules = new StringBuilder(); // //Because there could be more than one broken rule in the collection //we need to first split them out as they come with the pipe character separating each //broken rule which in turn is a comma delimited array suitable for the //BrokenRuleLocalizer method to work with string[] rulesarray = ((CSLA.BusinessBase)UIElement.Row.ListObject).BrokenRulesText.Split('|'); foreach (string PreLocalizedSingleBrokenRule in rulesarray) { sbLocalizedBrokenRules.Append(BrokenRuleLocalizer(PreLocalizedSingleBrokenRule)); } tipError.SetToolTip(UIElement.Control, sbLocalizedBrokenRules.ToString()); //Originally... //tipError.SetToolTip(UIElement.Control,((CSLA.BusinessBase)UIElement.Row.ListObject).BrokenRulesText); } } } } #endregion #region GridPreparation /// /// Prepares grid to settings compatible with our own filtering / sorting etc /// called once by any form containing a grid when it's first loaded /// to set the grid up properly /// /// This seems to be only called from read only grids so any settings /// affecting data entry are not useful here /// /// static public void PrepareGrid(Infragistics.Win.UltraWinGrid.UltraGrid Grid) { //case 1039 //log.Debug("PrepareGrid"); //Turn off internal sorting but //still use the sort arrows Grid.DisplayLayout.Override.HeaderClickAction = HeaderClickAction.ExternalSortSingle; //Set the caption to be on the left side of the grid Grid.DisplayLayout.CaptionAppearance.TextHAlign = HAlign.Left; } /// /// setup string bound columns in editable grids to allow user /// to enter nothing in them by wiping out all text. This then /// causes the data bound object to have an empty string value stored. /// /// Without this an error is thrown whenver a user attempts to clear a previously /// entered text field in a grid /// /// static public void SetTextColumnsNullable(Infragistics.Win.UltraWinGrid.UltraGrid Grid) { //case 1039 //log.Debug("SetTextColumnsNullable"); foreach (UltraGridBand b in Grid.DisplayLayout.Bands) { foreach (Infragistics.Win.UltraWinGrid.UltraGridColumn c in b.Columns) { if (c.DataType == typeof(string)) c.Nullable = Infragistics.Win.UltraWinGrid.Nullable.EmptyString; } } } #endregion #region Load / save grid layout internal static UIUserGridLastViews gGridLastViews; ///// ///// Save layout of grid ///// //static public void SaveGridLayout(string GridKey, string GridSubKey, string Description, Infragistics.Win.UltraWinGrid.UltraGrid Grid) //{ // //case 1039 //if(log.IsDebugEnabled) // //case 1039 //log.Debug("SaveGridLayout(" + GridKey + ", " + GridSubKey + ", " + Description + ", " + Grid.Name + "." + Grid.Parent.Name+ ")"); // bool bFiltered = false; // Util.gGridLastViews[GridKey].ViewXML = Util.GetGridSortAndFilterXML(Grid.DisplayLayout.Bands[0], false, ref bFiltered); //} /// /// Fetch and set the grid layout /// public static void FetchGridLayout(string GridKey, string GridSubKey, Infragistics.Win.UltraWinGrid.UltraGrid Grid) { //if (log.IsDebugEnabled) //case 1039 //log.Debug("FetchGridLayout(" + GridKey + ", " + GridSubKey + ", " + Grid.Name + "." + Grid.Parent.Name + ")"); if (gGridLastViews.Contains(GridKey)) { #region Use new UI agnostic method to load settings int nPosition = 0; Infragistics.Win.UltraWinGrid.UltraGridBand band = Grid.DisplayLayout.Bands[0]; foreach (UltraGridColumn cm in band.Columns) cm.Hidden = true; //show the columns that are in the order collection //And set their properties such as width, pinned, sort order etc foreach (DataRow TabRow in Util.gGridLastViews[GridKey].ViewOrder.Rows) { string columnName = TabRow["UI"].ToString(); UltraGridColumn c; if (band.Columns.Exists(columnName)) c = band.Columns[columnName]; else { //it's a non-bound column that was added dynamically in the form //so add it here to mimic original column layout saving and loading behaviour //This works on the assumption that the forms will resetup the datatype and //caption and any other customizations for a column that is added this way //which is how they should be coded c = band.Columns.Add(columnName); } c.Hidden = false; //Set sort indicator for first visible column only if (nPosition == 0) { if (GridKey != "WorkorderItemTasks")//Case 46 - added { if (TabRow["SORT"].ToString() == "DESC") c.SortIndicator = SortIndicator.Descending; else c.SortIndicator = SortIndicator.Ascending; } } c.Header.VisiblePosition = nPosition++; c.Width = System.Convert.ToInt32(TabRow["WIDTH"]); c.Header.Fixed = (TabRow["PIN"].ToString() == "1") ? true : false; } //Turn back on the events for the grid //Grid.EventManager.SetEnabled(Infragistics.Win.UltraWinGrid.EventGroups.AllEvents, true); #endregion new method } else { #region Use old method to load saved grid layout //which will later be saved as new method when they close the form that loaded it try { Grid.EventManager.SetEnabled(GridEventIds.BeforeSortChange, false); /* * * NOTE: the tag copying thing below should be redundant, no grid should be localized before it loads * it's saved state and it should use the key for localizing in any case, not the caption or tag right? * * * */ //Changed: 15-March-2005 //Will now use users setting if found, if none, will try to use manager's setting //if none then will do as normal UIGridLayout ugl = UIGridLayout.GetItem(GridKey, GridSubKey, User.CurrentThreadUserID); //check to see if it exists yet... if (ugl.GridKey == "") { if (User.IsAdmin) return; //case 1039 //log.Debug("No previously saved grid layout for this grid and user, trying manager account's setting..."); ugl = UIGridLayout.GetItem(GridKey, GridSubKey, User.AdministratorID); //check to see if it exists yet... if (ugl.GridKey == "") { //case 1039 //log.Debug("No previously saved grid layout for manager either no default will be used."); return; } } //case 1039 //log.Debug("Grid layout exists, loading from previously saved layout..."); //Copy all the grid column headings to thier tag property so we have them for localizing //this is because the load layout is going to fetch the headings as they //were last displayed (localized) in addition to the other settings and //we don't want that to happen. foreach (UltraGridBand b in Grid.DisplayLayout.Bands) { ////case 1039 //log.Debug("Copying to tags band " + b.Index.ToString() + " columns: " + b.Columns.Count.ToString()); foreach (Infragistics.Win.UltraWinGrid.UltraGridColumn c in b.Columns) { //case 1039 //log.Debug("Processing Column: " + c.Key); c.Header.Tag = c.Header.Caption; } } System.IO.MemoryStream ms = new System.IO.MemoryStream(ugl.GetLayoutContent()); ////case 1039 //log.Debug("Layout content size: " + ugl.LayoutSize.ToString()); Grid.DisplayLayout.Load(ms, PropertyCategories.Bands | PropertyCategories.SortedColumns | PropertyCategories.ColumnFilters); // //Copy them back again foreach (UltraGridBand b in Grid.DisplayLayout.Bands) { ////case 1039 //log.Debug("Copying from tags band " + b.Index.ToString() + " columns: " + b.Columns.Count.ToString()); foreach (Infragistics.Win.UltraWinGrid.UltraGridColumn c in b.Columns) { //in the case of unbound columns that were present //when the grid was saved they will not really be there // so this will avoid an error if (c.Header.Tag != null) { ////case 1039 //log.Debug("Processing Column: " + c.Key); c.Header.Caption = c.Header.Tag.ToString(); } } } ////case 1039 //log.Debug("Done processing load layout"); Grid.EventManager.SetEnabled(GridEventIds.BeforeSortChange, true); } catch (Exception ex) { //log.Error("FetchGridLayout", ex); MessageBox.Show("FetchGridLayout Error: \r\n" + ex.Message); } #endregion old method } //Case 240 //catches most of the editable grids inside edit forms GridStyler(Grid); } #region Band 1 ////Added: 02-August-2006 new methods to save and load layout for band 1 ////i.e. contact phones ///// ///// Save layout of grid ///// //static public void SaveGridLayoutBAND1(string GridKey, string GridSubKey, string Description, Infragistics.Win.UltraWinGrid.UltraGrid Grid) //{ // //if (log.IsDebugEnabled) // //case 1039 //log.Debug("SaveGridLayoutBAND1(" + GridKey + ", " + GridSubKey + ", " + Description + ", " + Grid.Name + "." + Grid.Parent.Name + ")"); // bool bFiltered = false; // Util.gGridLastViews[GridKey].ViewXML = Util.GetGridSortAndFilterXML(Grid.DisplayLayout.Bands[1], false, ref bFiltered); //} /// /// Fetch and set the grid layout /// public static void FetchGridLayoutBAND1(string GridKey, string GridSubKey, Infragistics.Win.UltraWinGrid.UltraGrid Grid) { //if (log.IsDebugEnabled) //case 1039 //log.Debug("FetchGridLayoutBAND1(" + GridKey + ", " + GridSubKey + ", " + Grid.Name + "." + Grid.Parent.Name + ")"); if (gGridLastViews.Contains(GridKey)) { #region Use new UI agnostic method to load settings int nPosition = 0; Infragistics.Win.UltraWinGrid.UltraGridBand band = Grid.DisplayLayout.Bands[1]; foreach (UltraGridColumn cm in band.Columns) cm.Hidden = true; //show the columns that are in the order collection //And set their properties such as width, pinned, sort order etc foreach (DataRow TabRow in Util.gGridLastViews[GridKey].ViewOrder.Rows) { string columnName = TabRow["UI"].ToString(); UltraGridColumn c; if (band.Columns.Exists(columnName)) c = band.Columns[columnName]; else { //it's a non-bound column that was added dynamically in the form //so add it here to mimic original column layout saving and loading behaviour //This works on the assumption that the forms will resetup the datatype and //caption and any other customizations for a column that is added this way //which is how they should be coded c = band.Columns.Add(columnName); } c.Hidden = false; //Set sort indicator for first visible column only if (nPosition == 0) { if (TabRow["SORT"].ToString() == "DESC") c.SortIndicator = SortIndicator.Descending; else c.SortIndicator = SortIndicator.Ascending; } c.Header.VisiblePosition = nPosition++; c.Width = System.Convert.ToInt32(TabRow["WIDTH"]); // c.Header.Fixed = (TabRow["PIN"].ToString() == "1") ? true : false; } #endregion new method } } #endregion band1 #endregion #region All grids common styling /// /// Added in response to Case 240 /// though highly overdue /// /// One centralized location to style all grids in the application /// /// public static void GridStyler(Infragistics.Win.UltraWinGrid.UltraGrid Grid) { //Case 240 //Grid.DisplayLayout.Override.RowAlternateAppearance.BackColor = Color.Honeydew; // Grid.DisplayLayout.Override.RowAlternateAppearance.BackColor = Color.AliceBlue; Grid.DisplayLayout.Override.RowAlternateAppearance.BackColor = System.Drawing.Color.WhiteSmoke; } #endregion #region Grid delete buttons case 1105 static public void GridAddDeleteButton(Infragistics.Win.UltraWinGrid.UltraGrid Grid) { //remove and replace because other columns might have been shown //and forced it from the rightmost position e.g. case 1252 if (Grid.DisplayLayout.Bands[0].Columns.Exists("REMOVE")) Grid.DisplayLayout.Bands[0].Columns.Remove("REMOVE"); Grid.DisplayLayout.Bands[0].Columns.Add("REMOVE", ""); Grid.DisplayLayout.Bands[0].Columns["REMOVE"].Hidden = false; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].Header.Caption = ""; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].Style = Infragistics.Win.UltraWinGrid.ColumnStyle.Button; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].CellButtonAppearance.Image = Resource1.Delete16; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].CellButtonAppearance.ImageHAlign = HAlign.Center; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].CellButtonAppearance.ImageVAlign = VAlign.Middle; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].Header.Appearance.Image = Resource1.Delete16; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].Header.Appearance.ImageHAlign = HAlign.Center; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].Width = 24; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].MinWidth = 24; Grid.DisplayLayout.Bands[0].Columns["REMOVE"].MaxWidth = 24; } static public void GridRemoveDeleteButton(Infragistics.Win.UltraWinGrid.UltraGrid Grid) { if (Grid.DisplayLayout.Bands[0].Columns.Exists("REMOVE")) Grid.DisplayLayout.Bands[0].Columns.Remove("REMOVE"); } #endregion #region No selection string /// /// replacement for the current space character used to indicate no selection /// has been made in grids /// public static string NoSelectionString { get { return "-"; } } #endregion #region Common Prompting messageboxes localized // public static DialogResult PromptForSave() { DialogResult dr = MessageBox.Show(LocaleText.GetLocalizedText("UI.Label.SavePrompt"), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button3); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptForSave (user selected " + dr.ToString()+")"); return dr; } public static DialogResult PromptForBrokenRulesCancelSave() { DialogResult dr = MessageBox.Show(LocaleText.GetLocalizedText("UI.Label.UnsaveableDueToBrokenRulesPrompt"), "", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptForBrokenRulesCancelSave (proceed without saving?) (user selected " + dr.ToString()+")"); return dr; } public static DialogResult PromptForDelete() { DialogResult dr = MessageBox.Show(LocaleText.GetLocalizedText("UI.Label.DeletePrompt"), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button3); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptForDelete (user selected " + dr.ToString()+")"); return dr; } public static DialogResult PromptForDeleteWorkorder() { DialogResult dr = MessageBox.Show(LocaleText.GetLocalizedText("UI.Label.DeleteWorkorderPrompt"), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button3); //if (log.IsDebugEnabled) //case 1039 //log.Debug("PromptForDeleteWORKORDER (user selected " + dr.ToString() + ")"); return dr; } public static DialogResult PromptYesNoCancelFromLocaleKey(string LocaleKey) { DialogResult dr = MessageBox.Show(LocaleText.GetLocalizedText(LocaleKey), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button3); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptYesNoCancelFromLocaleKey("+LocaleKey+" (user selected " + dr.ToString()+")"); return dr; } public static DialogResult PromptYesNoFromLocaleKey(string LocaleKey) { DialogResult dr = MessageBox.Show(LocaleText.GetLocalizedText(LocaleKey), "", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptYesNoFromLocaleKey("+LocaleKey+" (user selected " + dr.ToString()+")"); return dr; } public static void PromptWithIconOKOnlyFromLocaleKey(string LocaleKey, MessageBoxIcon ic) { MessageBox.Show(LocaleText.GetLocalizedText(LocaleKey), "", MessageBoxButtons.OK, ic); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptWithIconOKOnlyFromLocaleKey("+LocaleKey+")"); return; } public static void PromptWithIconOKOnlyFromLocaleKey(string LocaleKey, string sExtraInfo, MessageBoxIcon ic) { MessageBox.Show(string.Format(LocaleText.GetLocalizedText(LocaleKey), sExtraInfo), "", MessageBoxButtons.OK, ic); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptWithIconOKOnlyFromLocaleKey("+LocaleKey+")"); return; } //show a standard administrator only function message box with an OK key public static void PromptAdministratorOnly() { MessageBox.Show(LocaleText.GetLocalizedText("Error.Security.AdministratorOnlyMessage"), "", MessageBoxButtons.OK, MessageBoxIcon.Hand); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptAdministratorOnly()"); return; } public static void PromptRestricted() { MessageBox.Show(LocaleText.GetLocalizedText("Error.Trial.Restricted"), "", MessageBoxButtons.OK, MessageBoxIcon.Information); //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("PromptRestricted()"); return; } #endregion #region ComboBox helpers #region combo performance enhancement when loading //These methods added 19-July-2006 and changed //combos on forms to call these before and after update //the alphasort was causing terrible performance when loading large //sets of data into combo //Customized version... static public void ComboBeginUpdate(GZTW.WinForm.Controls.GZUltraComboEditor cb) { //Added: 19-July-2006 Huge performance increase with large lists cb.BeginUpdate(); cb.SortStyle = ValueListSortStyle.None; } static public void ComboEndUpdate(GZTW.WinForm.Controls.GZUltraComboEditor cb) { //Added: 19-July-2006 see above cb.SortStyle = ValueListSortStyle.Ascending; cb.EndUpdate(); } //Stock versions... static public void ComboBeginUpdate(UltraComboEditor cb) { //Added: 19-July-2006 Huge performance increase with large lists cb.BeginUpdate(); cb.SortStyle = ValueListSortStyle.None; } static public void ComboEndUpdate(UltraComboEditor cb) { //Added: 19-July-2006 see above cb.SortStyle = ValueListSortStyle.Ascending; cb.EndUpdate(); } #endregion /// /// Select the value list item in the combo that /// matches the ID passed in with it /// /// /// /// /// static public void ComboSelectGuid(UltraComboEditor cb, Guid SelectRecord) { //case 1039 //log.Debug("ComboSelectGuid"); foreach (ValueListItem vi in cb.Items) { if ((Guid)vi.DataValue == SelectRecord) { cb.SelectedItem = vi; break; } } } /// /// Check if guid present in combo /// /// /// /// /// static public bool ComboContainsGuid(UltraComboEditor cb, Guid SelectRecord) { //case 1168 foreach (ValueListItem vi in cb.Items) { if ((Guid)vi.DataValue == SelectRecord) { return true; } } return false; } /// /// Remove from the value list the item in the combo that /// matches the ID passed in with it /// /// /// /// /// static public void ComboRemoveFromListGuid(UltraComboEditor cb, Guid SelectRecord) { ////case 1039 //log.Debug("ComboRemoveFromListGuid"); ValueListItem viRemove = null; foreach (ValueListItem vi in cb.Items) { if ((Guid)vi.DataValue == SelectRecord) { viRemove = vi; break; } } if (viRemove != null) cb.Items.Remove(viRemove); } /// /// /// /// /// /// /// static public void FillGZComboBoxWithNameIDList(string ObjectName, GZTW.WinForm.Controls.GZUltraComboEditor cb, bool SelectMode, Guid SelectRecord, bool Regional)//case 58 { //case 1039 //if(log.IsDebugEnabled) //case 1039 //log.Debug("FillGZComboBoxWithNameIDList("+ObjectName+", " + cb.Name + ", " +SelectMode.ToString() + ", " + SelectRecord.ToString() + ")" ); //Save the current combo box selection if any //in case we need to manually put it back in the //case of an inactive item being pre-selected Guid gCurrentlySelectedID = Guid.Empty; if (cb.Value != null && cb.Value.ToString() != Util.NoSelectionString)//case 1261 { try { gCurrentlySelectedID = (Guid)cb.Value; } catch (System.InvalidCastException ex) { //log.Error("FillGZComboBoxWithNameIDList: error casting value of selected combo box item to a guid, Guid.Empty will be used instead", ex); gCurrentlySelectedID = Guid.Empty; } } cb.BeginUpdate(); //wipe any previous list ////case 1039 //log.Debug("Before clear list item count:" + cb.Items.Count.ToString()); cb.ClearList(); ////case 1039 //log.Debug("After clear list item count:" + cb.Items.Count.ToString()); ValueListItem viSelected = cb.EmptyValueListItem; if (SelectMode) { //Fetch selected record and add to list so it's displayed if (SelectRecord != Guid.Empty) { NameFetcher nf = null; try { nf = NameFetcher.GetItem(ObjectName, "Name", SelectRecord); } catch (Exception ex) { //log.Error("FillGZComboBoxWithNameIDList: error fetching name of selected item (Object=" + ObjectName + " ID=" + SelectRecord.ToString() + ") Name will not be fetched.", ex); } cb.Items.Add(SelectRecord, nf.RecordName); } } else { //NVCHANGED GenericNVList l = GenericNVList.GetList("a" + ObjectName, "aID", "aName", true, true, Regional); //ensure that non-active record //still appears in list bool bSelectedRecordIsInList = false; //Added: 19-July-2006 for performance improvement cb.SortStyle = ValueListSortStyle.None; foreach (System.Collections.DictionaryEntry d in l.BindableList) { Guid gValue = new Guid(d.Key.ToString()); if (gValue == gCurrentlySelectedID) { bSelectedRecordIsInList = true; viSelected = cb.Items.Add(gValue, d.Value.ToString()); } else { cb.Items.Add(gValue, d.Value.ToString()); } } //Added: 19-July-2006 for performance improvement cb.SortStyle = ValueListSortStyle.Ascending; //manually add non-active item? if (gCurrentlySelectedID != Guid.Empty && !bSelectedRecordIsInList) { //retrieve manually non-active item try { NameFetcher nf = NameFetcher.GetItem(ObjectName, "Name", gCurrentlySelectedID); viSelected = cb.Items.Add(gCurrentlySelectedID, nf.RecordName); viSelected.Appearance.ForeColor = System.Drawing.SystemColors.GrayText; } catch (Exception ex) { } } cb.SelectedItem = viSelected; } cb.EndUpdate(); } #endregion #region First run map fields static public void MapFields() { if (!AyaNovaOL.Properties.Settings.Default.FieldsMapped) { MapPhoneAddress d = new MapPhoneAddress(); d.ShowDialog(); d.Dispose(); } } #endregion public static void d(string s) { MessageBox.Show(s); } public static void db(string s) { #if(DEBUG) MessageBox.Show(s); #endif } }//end of util class #endregion ayanova util stuff #region Tab order manager class TabOrderManager { /// /// Case 152 tab order on forms /// Compare two controls in the selected tab scheme. /// private class TabSchemeComparer : System.Collections.IComparer { private TabScheme comparisonScheme; #region IComparer Members public int Compare(object x, object y) { Control control1 = x as Control; Control control2 = y as Control; if (control1 == control2) return 0; if (control1 == null || control2 == null) { System.Diagnostics.Debug.Assert(false, "Attempting to compare a non-control"); return 0; } if (comparisonScheme == TabScheme.None) { // Nothing to do. return 0; } if (comparisonScheme == TabScheme.AcrossFirst) { // The primary direction to sort is the y direction (using the Top property). // If two controls have the same y coordination, then we sort them by their x's. if (control1.Top < control2.Top) { return -1; } else if (control1.Top > control2.Top) { return 1; } else { return (control1.Left.CompareTo(control2.Left)); } } else // comparisonScheme = TabScheme.DownFirst { // The primary direction to sort is the x direction (using the Left property). // If two controls have the same x coordination, then we sort them by their y's. if (control1.Left < control2.Left) { return -1; } else if (control1.Left > control2.Left) { return 1; } else { return (control1.Top.CompareTo(control2.Top)); } } } #endregion /// /// Create a tab scheme comparer that compares using the given scheme. /// /// public TabSchemeComparer(TabScheme scheme) { comparisonScheme = scheme; } } /// /// The container whose tab order we manage. /// private Control container; /// /// Hash of controls to schemes so that individual containers can have different ordering /// strategies than their parents. /// private System.Collections.Hashtable schemeOverrides; /// /// The tab index we start numbering from when the tab order is applied. /// private int curTabIndex = 0; /// /// The general tab-ordering strategy (i.e. whether we tab across rows first, or down columns). /// public enum TabScheme { None, AcrossFirst, DownFirst } /// /// Constructor /// /// The container whose tab order we manage. public TabOrderManager(Control container) { this.container = container; this.curTabIndex = 0; this.schemeOverrides = new System.Collections.Hashtable(); } /// /// Construct a tab order manager that starts numbering at the given tab index. /// /// The container whose tab order we manage. /// Where to start numbering. /// List of controls with explicitly defined schemes. private TabOrderManager(Control container, int curTabIndex, System.Collections.Hashtable schemeOverrides) { this.container = container; this.curTabIndex = curTabIndex; this.schemeOverrides = schemeOverrides; } /// /// Explicitly set a tab order scheme for a given (presumably container) control. /// /// The control to set the scheme for. /// The requested scheme. public void SetSchemeForControl(Control c, TabScheme scheme) { schemeOverrides[c] = scheme; } /// /// Recursively set the tab order on this container and all of its children. /// /// The tab ordering strategy to apply. /// The next tab index to be used. public int SetTabOrder(TabScheme scheme) { // Tab order isn't important enough to ever cause a crash, so replace any exceptions // with assertions. try { System.Collections.ArrayList controlArraySorted = new System.Collections.ArrayList(); controlArraySorted.AddRange(container.Controls); controlArraySorted.Sort(new TabSchemeComparer(scheme)); foreach (Control c in controlArraySorted) { // Debug.WriteLine("TabOrderManager: Changing tab index for " + c.Name); c.TabIndex = curTabIndex++; if (c.Controls.Count > 0) { // Control has children -- recurse. TabScheme childScheme = scheme; if (schemeOverrides.Contains(c)) { childScheme = (TabScheme)schemeOverrides[c]; } curTabIndex = (new TabOrderManager(c, curTabIndex, schemeOverrides)).SetTabOrder(childScheme); } } return curTabIndex; } catch (Exception e) { System.Diagnostics.Debug.Assert(false, "Exception in TabOrderManager.SetTabOrder: " + e.Message); return 0; } } } #endregion #region Outlook Enums and structs public enum AYOLPhoneNumberType : int { Unused = 0, AssistantTelephoneNumber = 1, Business2TelephoneNumber = 2, BusinessFaxNumber = 3, BusinessTelephoneNumber = 4, CallbackTelephoneNumber = 5, CarTelephoneNumber = 6, CompanyMainTelephoneNumber = 7, Home2TelephoneNumber = 8, HomeFaxNumber = 9, HomeTelephoneNumber = 10, MobileTelephoneNumber = 11, OtherFaxNumber = 12, OtherTelephoneNumber = 13, PagerNumber = 14, PrimaryTelephoneNumber = 15, RadioTelephoneNumber = 16, TelexNumber = 17, TTYTDDTelephoneNumber = 18, ISDNNumber = 19 } public enum AYOLAddressType : int { Unused=0, Business=1, Home=2, Other=3 } /// /// contains user preferences for mapping contacts between AyaNova and Outlook /// public struct OLContactOptions { public int AyaObjectType;//nopersist public int VendorType; public Guid Region; public Guid Zone; public Guid Contract; public string PhysicalAddressEquals; public string PostalAddressEquals; public AYOLPhoneNumberType ClientPhone1; public AYOLPhoneNumberType ClientPhone2; public AYOLPhoneNumberType ClientPhone3; public AYOLPhoneNumberType ClientPhone4; public AYOLPhoneNumberType ClientPhone5; public AYOLPhoneNumberType HeadOfficePhone1; public AYOLPhoneNumberType HeadOfficePhone2; public AYOLPhoneNumberType HeadOfficePhone3; public AYOLPhoneNumberType HeadOfficePhone4; public AYOLPhoneNumberType HeadOfficePhone5; public AYOLPhoneNumberType VendorPhone1; public AYOLPhoneNumberType VendorPhone2; public AYOLPhoneNumberType VendorPhone3; public AYOLPhoneNumberType VendorPhone4; public AYOLPhoneNumberType VendorPhone5; public override string ToString() { return "OLContactOptions:\r\nAyaObjectType:" + AyaObjectType.ToString() + " VendorType:" + VendorType.ToString() + "REgion:" + Region.ToString() + "Zone:" + Zone.ToString() + "Contract:" + Contract.ToString() + "PhysicalAddressEquals:" + PhysicalAddressEquals + "PostalAddressEquals:" + PostalAddressEquals + "\r\n"; } } #endregion }