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.

This commit is contained in:
gamosoft_cp 2013-06-18 20:52:05 +00:00
parent cbb4618c7e
commit d6526a2d11
4 changed files with 160 additions and 22 deletions

View File

@ -11,15 +11,6 @@ namespace Outlook2013TodoAddIn
/// </summary>
public partial class AppointmentsControl : UserControl
{
#region "Variables"
/// <summary>
/// Used to retrieve the email address of a contact
/// </summary>
private const string PR_SMTP_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E";
#endregion "Variables"
#region "Properties"
/// <summary>
@ -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
}
}
/// <summary>
/// Resolves Outlook recipient email address
/// </summary>
/// <param name="rcpt">Recipient</param>
/// <returns>Email address of the contact</returns>
private string GetEmailAddress(Outlook.Recipient rcpt)
{
Outlook.PropertyAccessor pa = rcpt.PropertyAccessor;
return pa.GetProperty(PR_SMTP_ADDRESS).ToString();
}
/// <summary>
/// Switch to the calendar view when double-clicking a date
/// </summary>

View File

@ -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;
}
/// <summary>
/// To enable/disable drop operations on every day of the calendar
/// </summary>
/// <param name="sender">Sender</param>
/// <param name="e">DragEventArgs</param>
private void lblCtrl_DragEnter(object sender, DragEventArgs e)
{
List<string> outlookRequiredFormats = new List<string>() { "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;
}
}
/// <summary>
/// When the user "drops" one or more email items into the calendar
/// </summary>
/// <param name="sender">Sender</param>
/// <param name="e">DragEventArgs</param>
private void lblCtrl_DragDrop(object sender, DragEventArgs e)
{
Label lblDay = sender as Label;
if (sender != null)
{
Outlook.Explorer mailExpl = Globals.ThisAddIn.Application.ActiveExplorer();
List<string> attendees = new List<string>();
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();
}
}
/// <summary>
/// Changes labels according to the currently displayed month
/// </summary>

View File

@ -201,6 +201,7 @@
<Compile Include="NewMailAlert.Designer.cs">
<DependentUpon>NewMailAlert.cs</DependentUpon>
</Compile>
<Compile Include="OutlookHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>

View File

@ -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"
/// <summary>
/// Used to retrieve the email address of a contact
/// </summary>
private const string PR_SMTP_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E";
#endregion "Variables"
#region "Methods"
/// <summary>
/// Resolves Outlook recipient email address
/// </summary>
/// <param name="rcpt">Recipient</param>
/// <returns>Email address of the contact</returns>
public static string GetEmailAddress(Outlook.Recipient rcpt)
{
Outlook.PropertyAccessor pa = rcpt.PropertyAccessor;
return pa.GetProperty(PR_SMTP_ADDRESS).ToString();
}
/// <summary>
/// Gets a list of recipients email addresses, and when exception is present will not be included
/// </summary>
/// <param name="rcpts">Recipients</param>
/// <param name="exception">Email address exception</param>
/// <returns>List of emails</returns>
public static List<string> GetRecipentsEmailAddresses(Outlook.Recipients rcpts, string exception)
{
List<string> results = new List<string>();
foreach (Outlook.Recipient rcpt in rcpts)
{
string smtpAddress = OutlookHelper.GetEmailAddress(rcpt);
if (smtpAddress != exception && !results.Contains(smtpAddress))
{
results.Add(smtpAddress);
}
}
return results;
}
/// <summary>
/// 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
/// </summary>
/// <param name="dt">DateTime</param>
/// <param name="d">TimeSpan</param>
/// <returns></returns>
public static DateTime RoundUp(DateTime dt, TimeSpan d)
{
return new DateTime(((dt.Ticks + d.Ticks - 1) / d.Ticks) * d.Ticks);
}
#endregion "Methods"
}
}