From d6526a2d11b1a71ec72b005654a502308a3c547f Mon Sep 17 00:00:00 2001 From: gamosoft_cp Date: Tue, 18 Jun 2013 20:52:05 +0000 Subject: [PATCH] Added new functionality to create appointments when dragging & dropping emails into the calendar. By default will create them on the designated day, using current's day time rounded up within the following 15 minutes. --- Outlook2013TodoAddIn/AppointmentsControl.cs | 24 +---- Outlook2013TodoAddIn/CustomCalendar.cs | 90 +++++++++++++++++++ .../Outlook2013TodoAddIn.csproj | 1 + Outlook2013TodoAddIn/OutlookHelper.cs | 67 ++++++++++++++ 4 files changed, 160 insertions(+), 22 deletions(-) create mode 100644 Outlook2013TodoAddIn/OutlookHelper.cs diff --git a/Outlook2013TodoAddIn/AppointmentsControl.cs b/Outlook2013TodoAddIn/AppointmentsControl.cs index 172b77a..58d42a3 100644 --- a/Outlook2013TodoAddIn/AppointmentsControl.cs +++ b/Outlook2013TodoAddIn/AppointmentsControl.cs @@ -11,15 +11,6 @@ namespace Outlook2013TodoAddIn /// public partial class AppointmentsControl : UserControl { - #region "Variables" - - /// - /// Used to retrieve the email address of a contact - /// - private const string PR_SMTP_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"; - - #endregion "Variables" - #region "Properties" /// @@ -283,10 +274,10 @@ namespace Outlook2013TodoAddIn if (appt != null) { Outlook.MailItem mail = Globals.ThisAddIn.Application.CreateItem(Outlook.OlItemType.olMailItem) as Outlook.MailItem; - string curUserAddress = GetEmailAddress(Globals.ThisAddIn.Application.Session.CurrentUser); + string curUserAddress = OutlookHelper.GetEmailAddress(Globals.ThisAddIn.Application.Session.CurrentUser); foreach (Outlook.Recipient rcpt in appt.Recipients) { - string smtpAddress = GetEmailAddress(rcpt); + string smtpAddress = OutlookHelper.GetEmailAddress(rcpt); if (curUserAddress != smtpAddress) { mail.Recipients.Add(smtpAddress); @@ -299,17 +290,6 @@ namespace Outlook2013TodoAddIn } } - /// - /// Resolves Outlook recipient email address - /// - /// Recipient - /// Email address of the contact - private string GetEmailAddress(Outlook.Recipient rcpt) - { - Outlook.PropertyAccessor pa = rcpt.PropertyAccessor; - return pa.GetProperty(PR_SMTP_ADDRESS).ToString(); - } - /// /// Switch to the calendar view when double-clicking a date /// diff --git a/Outlook2013TodoAddIn/CustomCalendar.cs b/Outlook2013TodoAddIn/CustomCalendar.cs index 4c6fc42..ed4d7dc 100644 --- a/Outlook2013TodoAddIn/CustomCalendar.cs +++ b/Outlook2013TodoAddIn/CustomCalendar.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using Outlook = Microsoft.Office.Interop.Outlook; namespace Outlook2013TodoAddIn { @@ -156,6 +157,9 @@ namespace Outlook2013TodoAddIn lblCtrl.MouseLeave += lblCtrl_MouseLeave; lblCtrl.Click += lblCtrl_Click; // TODO: If we disable this, then we can't select a date... lblCtrl.DoubleClick += lblCtrl_DoubleClick; + lblCtrl.AllowDrop = true; + lblCtrl.DragEnter += lblCtrl_DragEnter; + lblCtrl.DragDrop += lblCtrl_DragDrop; } this.tableLayoutPanel1.Controls.Add(lblCtrl); this.tableLayoutPanel1.SetCellPosition(lblCtrl, new TableLayoutPanelCellPosition(col, row)); @@ -166,6 +170,92 @@ namespace Outlook2013TodoAddIn this.btnNext.FlatAppearance.MouseOverBackColor = this.HoverBackColor; } + /// + /// To enable/disable drop operations on every day of the calendar + /// + /// Sender + /// DragEventArgs + private void lblCtrl_DragEnter(object sender, DragEventArgs e) + { + List outlookRequiredFormats = new List() { "RenPrivateSourceFolder", "RenPrivateMessages", "RenPrivateItem", "FileGroupDescriptor", "FileGroupDescriptorW", "FileContents", "Object Descriptor" }; + if (outlookRequiredFormats.All(r => e.Data.GetDataPresent(r))) + { + e.Effect = DragDropEffects.Copy; + } + else + { + e.Effect = DragDropEffects.None; + } + } + + /// + /// When the user "drops" one or more email items into the calendar + /// + /// Sender + /// DragEventArgs + private void lblCtrl_DragDrop(object sender, DragEventArgs e) + { + Label lblDay = sender as Label; + if (sender != null) + { + Outlook.Explorer mailExpl = Globals.ThisAddIn.Application.ActiveExplorer(); + List attendees = new List(); + string curUserAddress = OutlookHelper.GetEmailAddress(Globals.ThisAddIn.Application.Session.CurrentUser); + string body = String.Empty; + string subject = String.Empty; + foreach (object obj in mailExpl.Selection) + { + Outlook.MailItem mail = obj as Outlook.MailItem; + if (mail != null) + { + subject = mail.Subject; + body = mail.Body; + if (mail.SenderEmailAddress != curUserAddress && !attendees.Contains(mail.SenderEmailAddress)) + { + attendees.Add(mail.SenderEmailAddress); + } + attendees.AddRange(OutlookHelper.GetRecipentsEmailAddresses(mail.Recipients, curUserAddress)); + } + else // It's not an email, let's see if it's a meeting instead + { + Outlook.MeetingItem meeting = obj as Outlook.MeetingItem; + if (meeting != null) + { + subject = meeting.Subject; + body = meeting.Body; + if (meeting.SenderEmailAddress != curUserAddress && !attendees.Contains(meeting.SenderEmailAddress)) + { + attendees.Add(meeting.SenderEmailAddress); + } + attendees.AddRange(OutlookHelper.GetRecipentsEmailAddresses(meeting.Recipients, curUserAddress)); + } + else // It wasn't a meeting either, let's try with an appointment + { + Outlook.AppointmentItem appointment = obj as Outlook.AppointmentItem; + if (appointment != null) + { + subject = appointment.Subject; + body = appointment.Body; + if (appointment.Organizer != curUserAddress && !attendees.Contains(appointment.Organizer)) + { + attendees.Add(appointment.Organizer); + } + attendees.AddRange(OutlookHelper.GetRecipentsEmailAddresses(appointment.Recipients, curUserAddress)); + } + } + } + } + Outlook.AppointmentItem appt = Globals.ThisAddIn.Application.CreateItem(Outlook.OlItemType.olAppointmentItem) as Outlook.AppointmentItem; + attendees.ForEach(a => appt.Recipients.Add(a)); + appt.Body = Environment.NewLine + Environment.NewLine + body; + appt.Subject = subject; + DateTime day = (DateTime)lblDay.Tag; + DateTime now = DateTime.Now; + appt.Start = OutlookHelper.RoundUp(new DateTime(day.Year, day.Month, day.Day, now.Hour, now.Minute, now.Second), TimeSpan.FromMinutes(15)); + appt.Display(); + } + } + /// /// Changes labels according to the currently displayed month /// diff --git a/Outlook2013TodoAddIn/Outlook2013TodoAddIn.csproj b/Outlook2013TodoAddIn/Outlook2013TodoAddIn.csproj index b90b25c..78f66aa 100644 --- a/Outlook2013TodoAddIn/Outlook2013TodoAddIn.csproj +++ b/Outlook2013TodoAddIn/Outlook2013TodoAddIn.csproj @@ -201,6 +201,7 @@ NewMailAlert.cs + Code diff --git a/Outlook2013TodoAddIn/OutlookHelper.cs b/Outlook2013TodoAddIn/OutlookHelper.cs new file mode 100644 index 0000000..d26d35a --- /dev/null +++ b/Outlook2013TodoAddIn/OutlookHelper.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Outlook = Microsoft.Office.Interop.Outlook; + +namespace Outlook2013TodoAddIn +{ + public class OutlookHelper + { + #region "Variables" + + /// + /// Used to retrieve the email address of a contact + /// + private const string PR_SMTP_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"; + + #endregion "Variables" + + #region "Methods" + + /// + /// Resolves Outlook recipient email address + /// + /// Recipient + /// Email address of the contact + public static string GetEmailAddress(Outlook.Recipient rcpt) + { + Outlook.PropertyAccessor pa = rcpt.PropertyAccessor; + return pa.GetProperty(PR_SMTP_ADDRESS).ToString(); + } + + /// + /// Gets a list of recipients email addresses, and when exception is present will not be included + /// + /// Recipients + /// Email address exception + /// List of emails + public static List GetRecipentsEmailAddresses(Outlook.Recipients rcpts, string exception) + { + List results = new List(); + foreach (Outlook.Recipient rcpt in rcpts) + { + string smtpAddress = OutlookHelper.GetEmailAddress(rcpt); + if (smtpAddress != exception && !results.Contains(smtpAddress)) + { + results.Add(smtpAddress); + } + } + return results; + } + + /// + /// Rounds up a datetime to the nearest X interval + /// e.g.: RoundUp(new DateTime(2013, 6, 18, 13, 43, 10), TimeSpan.FromMinutes(15)); -> 6/18/2013 1:45:00 PM + /// + /// DateTime + /// TimeSpan + /// + public static DateTime RoundUp(DateTime dt, TimeSpan d) + { + return new DateTime(((dt.Ticks + d.Ticks - 1) / d.Ticks) * d.Ticks); + } + + #endregion "Methods" + } +} \ No newline at end of file