Added double-click enabled calendar control and comments
This commit is contained in:
parent
837924b0bf
commit
4501a61b08
@ -31,7 +31,7 @@
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.numRangeDays = new System.Windows.Forms.NumericUpDown();
|
||||
this.lblRangeDays = new System.Windows.Forms.Label();
|
||||
this.apptCalendar = new System.Windows.Forms.MonthCalendar();
|
||||
this.apptCalendar = new Outlook2013TodoAddIn.DoubleClickMonthCalendar();
|
||||
this.ctxMenuAppointments = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.mnuItemReplyAllEmail = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.hdrDate = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
@ -86,6 +86,7 @@
|
||||
this.apptCalendar.MaxSelectionCount = 1;
|
||||
this.apptCalendar.Name = "apptCalendar";
|
||||
this.apptCalendar.TabIndex = 4;
|
||||
this.apptCalendar.DoubleClickEx += new System.EventHandler(this.apptCalendar_DoubleClickEx);
|
||||
this.apptCalendar.DateChanged += new System.Windows.Forms.DateRangeEventHandler(this.monthCalendar1_DateChanged);
|
||||
//
|
||||
// ctxMenuAppointments
|
||||
@ -186,7 +187,7 @@
|
||||
|
||||
private System.Windows.Forms.NumericUpDown numRangeDays;
|
||||
private System.Windows.Forms.Label lblRangeDays;
|
||||
private System.Windows.Forms.MonthCalendar apptCalendar;
|
||||
private DoubleClickMonthCalendar apptCalendar;
|
||||
private System.Windows.Forms.ContextMenuStrip ctxMenuAppointments;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuItemReplyAllEmail;
|
||||
private System.Windows.Forms.ColumnHeader hdrDate;
|
||||
|
@ -7,22 +7,38 @@ using Outlook = Microsoft.Office.Interop.Outlook;
|
||||
|
||||
namespace Outlook2013TodoAddIn
|
||||
{
|
||||
/// User control to hold the calendar, etc...
|
||||
/// </summary>
|
||||
public partial class AppointmentsControl : UserControl
|
||||
{
|
||||
#region "Variables"
|
||||
/// <summary>
|
||||
|
||||
/// <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>
|
||||
/// Number of days (including today) to retrieve appointments from in the future
|
||||
/// </summary>
|
||||
public decimal NumDays
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.numRangeDays.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.numRangeDays.Value = value;
|
||||
}
|
||||
get { return this.numRangeDays.Value; }
|
||||
set { this.numRangeDays.Value = value; }
|
||||
}
|
||||
|
||||
#endregion "Properties"
|
||||
|
||||
#region "Methods"
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public AppointmentsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -43,22 +59,40 @@ namespace Outlook2013TodoAddIn
|
||||
// MessageBox.Show("Test");
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Respond to calendar changes
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">DateRangeEventArgs</param>
|
||||
private void monthCalendar1_DateChanged(object sender, DateRangeEventArgs e)
|
||||
{
|
||||
this.RetrieveAppointments();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change days to retrieve appointments in the future
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void numRangeDays_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default.NumDays = this.numRangeDays.Value;
|
||||
this.RetrieveAppointments();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manual refresh
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void btnRefresh_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.RetrieveAppointments();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve all appointments for the current configurations
|
||||
/// </summary>
|
||||
public void RetrieveAppointments()
|
||||
{
|
||||
// Get the Outlook folder for the calendar to retrieve the appointments
|
||||
@ -123,20 +157,15 @@ namespace Outlook2013TodoAddIn
|
||||
case Outlook.OlBusyStatus.olBusy:
|
||||
current.ForeColor = Color.Purple;
|
||||
break;
|
||||
|
||||
case Outlook.OlBusyStatus.olFree:
|
||||
break;
|
||||
|
||||
case Outlook.OlBusyStatus.olOutOfOffice:
|
||||
current.ForeColor = Color.Brown;
|
||||
break;
|
||||
|
||||
case Outlook.OlBusyStatus.olTentative:
|
||||
break;
|
||||
|
||||
case Outlook.OlBusyStatus.olWorkingElsewhere:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -159,11 +188,11 @@ namespace Outlook2013TodoAddIn
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get recurring appointments in date range.
|
||||
/// Get recurring appointments in a date range.
|
||||
/// </summary>
|
||||
/// <param name="folder"></param>
|
||||
/// <param name="startTime"></param>
|
||||
/// <param name="endTime"></param>
|
||||
/// <param name="folder">Outlook folder</param>
|
||||
/// <param name="startTime">Start time</param>
|
||||
/// <param name="endTime">End time</param>
|
||||
/// <returns>Outlook.Items</returns>
|
||||
private Outlook.Items GetAppointmentsInRange(Outlook.Folder folder, DateTime startTime, DateTime endTime)
|
||||
{
|
||||
@ -190,6 +219,11 @@ namespace Outlook2013TodoAddIn
|
||||
catch { return null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the appointment, having in mind it might be a recurring event
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void listView1_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if (this.listView1.SelectedIndices.Count != 0)
|
||||
@ -222,13 +256,17 @@ namespace Outlook2013TodoAddIn
|
||||
// Open up the appointment in a new window
|
||||
appt.Display(true); // Modal yes/no
|
||||
}
|
||||
|
||||
// At the end, synchronously "refresh" items in case they have changed
|
||||
this.RetrieveAppointments();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new mail item to reply all recipients of an appointment (except the current user)
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void mnuItemReplyAllEmail_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (this.listView1.SelectedIndices.Count != 0)
|
||||
@ -237,7 +275,6 @@ 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);
|
||||
foreach (Outlook.Recipient rcpt in appt.Recipients)
|
||||
{
|
||||
@ -245,8 +282,6 @@ namespace Outlook2013TodoAddIn
|
||||
if (curUserAddress != smtpAddress)
|
||||
{
|
||||
mail.Recipients.Add(smtpAddress);
|
||||
|
||||
//mail.Recipients.Add(rcpt.AddressEntry.Name);
|
||||
}
|
||||
}
|
||||
mail.Body = Environment.NewLine + Environment.NewLine + appt.Body;
|
||||
@ -256,10 +291,44 @@ 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>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void apptCalendar_DoubleClickEx(object sender, EventArgs e)
|
||||
{
|
||||
// TODO: Clicking in days outside of the current month will cause the calendar to refresh to that day, reposition all days and
|
||||
// select the wrong one
|
||||
//MessageBox.Show(this.apptCalendar.SelectionStart.ToShortDateString());
|
||||
|
||||
// Get the Outlook folder for the calendar to retrieve the appointments
|
||||
Outlook.Folder calFolder =
|
||||
Globals.ThisAddIn.Application.Session.GetDefaultFolder(
|
||||
Outlook.OlDefaultFolders.olFolderCalendar)
|
||||
as Outlook.Folder;
|
||||
|
||||
//Outlook.View view = Globals.ThisAddIn.Application.ActiveExplorer().CurrentView;
|
||||
|
||||
foreach (Outlook.View view in Globals.ThisAddIn.Application.ActiveExplorer().CurrentFolder.Views)
|
||||
{
|
||||
MessageBox.Show("New view: {0}", view.Name);
|
||||
}
|
||||
|
||||
//calFolder.Display();
|
||||
}
|
||||
|
||||
#endregion "Methods"
|
||||
}
|
||||
}
|
36
Outlook2013TodoAddIn/DoubleClickMonthCalendar.cs
Normal file
36
Outlook2013TodoAddIn/DoubleClickMonthCalendar.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Outlook2013TodoAddIn
|
||||
{
|
||||
public class DoubleClickMonthCalendar : MonthCalendar
|
||||
{
|
||||
public event EventHandler DoubleClickEx;
|
||||
|
||||
public DoubleClickMonthCalendar()
|
||||
{
|
||||
lastClickTick = Environment.TickCount - SystemInformation.DoubleClickTime;
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
int tick = Environment.TickCount;
|
||||
if (tick - lastClickTick <= SystemInformation.DoubleClickTime)
|
||||
{
|
||||
EventHandler handler = DoubleClickEx;
|
||||
if (handler != null) handler(this, EventArgs.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
lastClickTick = tick;
|
||||
}
|
||||
}
|
||||
|
||||
private int lastClickTick;
|
||||
}
|
||||
}
|
@ -2,21 +2,33 @@
|
||||
|
||||
namespace Outlook2013TodoAddIn
|
||||
{
|
||||
/// <summary>
|
||||
/// Mimic Outlook's popup to open one instance or the whole series
|
||||
/// </summary>
|
||||
public partial class FormRecurringOpen : Form
|
||||
{
|
||||
public DialogResult ButtonPressed { get; set; }
|
||||
#region "Properties"
|
||||
|
||||
/// <summary>
|
||||
/// Whether the user wants to retrieve all instances or not
|
||||
/// </summary>
|
||||
public bool OpenRecurring
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.rbtnAll.Checked;
|
||||
}
|
||||
get { return this.rbtnAll.Checked; }
|
||||
}
|
||||
|
||||
#endregion "Properties"
|
||||
|
||||
#region "Methods"
|
||||
|
||||
/// <summary>
|
||||
/// Open the form
|
||||
/// </summary>
|
||||
public FormRecurringOpen()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
#endregion "Methods"
|
||||
}
|
||||
}
|
@ -178,6 +178,7 @@
|
||||
can be found.
|
||||
-->
|
||||
<ItemGroup>
|
||||
<Compile Include="DoubleClickMonthCalendar.cs" />
|
||||
<Compile Include="FormRecurringOpen.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -5,69 +5,69 @@ using Office = Microsoft.Office.Core;
|
||||
|
||||
namespace Outlook2013TodoAddIn
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for the add-in
|
||||
/// </summary>
|
||||
public partial class ThisAddIn
|
||||
{
|
||||
private AppointmentsControl appControl;
|
||||
#region "Properties"
|
||||
|
||||
/// <summary>
|
||||
/// Control with calendar, etc...
|
||||
/// </summary>
|
||||
public AppointmentsControl AppControl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Custom task pane
|
||||
/// </summary>
|
||||
public Microsoft.Office.Tools.CustomTaskPane ToDoTaskPane { get; set; }
|
||||
|
||||
//private Dictionary<Outlook.Inspector, InspectorWrapper> inspectorWrappersValue = new Dictionary<Outlook.Inspector, InspectorWrapper>();
|
||||
//private Outlook.Inspectors inspectors;
|
||||
#endregion "Properties"
|
||||
|
||||
//void Inspectors_NewInspector(Outlook.Inspector Inspector)
|
||||
//{
|
||||
// if (Inspector.CurrentItem is Outlook.MailItem)
|
||||
// {
|
||||
// inspectorWrappersValue.Add(Inspector, new InspectorWrapper(Inspector));
|
||||
// }
|
||||
//}
|
||||
|
||||
//public Dictionary<Outlook.Inspector, InspectorWrapper> InspectorWrappers
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return inspectorWrappersValue;
|
||||
// }
|
||||
//}
|
||||
#region "Methods"
|
||||
|
||||
/// <summary>
|
||||
/// Initialize settings upon add-in startup
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void ThisAddIn_Startup(object sender, System.EventArgs e)
|
||||
{
|
||||
//inspectors = this.Application.Inspectors;
|
||||
//inspectors.NewInspector +=
|
||||
// new Outlook.InspectorsEvents_NewInspectorEventHandler(
|
||||
// Inspectors_NewInspector);
|
||||
this.AddRegistryNotification();
|
||||
|
||||
//foreach (Outlook.Inspector inspector in inspectors)
|
||||
//{
|
||||
// Inspectors_NewInspector(inspector);
|
||||
//}
|
||||
this.AppControl = new AppointmentsControl();
|
||||
this.AppControl.NumDays = Properties.Settings.Default.NumDays; // Setting the value will load the appointments
|
||||
this.AppControl.RetrieveAppointments();
|
||||
|
||||
appControl = new AppointmentsControl();
|
||||
appControl.NumDays = Properties.Settings.Default.NumDays; // Setting the value will load the appointments
|
||||
|
||||
//Properties.Settings.Default.Properties[]
|
||||
// appControl.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
ToDoTaskPane = this.CustomTaskPanes.Add(appControl, "Appointments");
|
||||
ToDoTaskPane.Visible = Properties.Settings.Default.Visible;
|
||||
|
||||
//ToDoTaskPane.Visible = true;
|
||||
//ToDoTaskPane.Width = 285; // appControl.Width;
|
||||
ToDoTaskPane = this.CustomTaskPanes.Add(this.AppControl, "Appointments");
|
||||
// TODO: Fix this
|
||||
// ToDoTaskPane.Visible = Properties.Settings.Default.Visible;
|
||||
ToDoTaskPane.Visible = true;
|
||||
ToDoTaskPane.Width = Properties.Settings.Default.Width;
|
||||
ToDoTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
|
||||
ToDoTaskPane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoHorizontal;
|
||||
ToDoTaskPane.VisibleChanged += ToDoTaskPane_VisibleChanged;
|
||||
appControl.SizeChanged += appControl_SizeChanged;
|
||||
|
||||
this.AddRegistryNotification();
|
||||
this.AppControl.SizeChanged += appControl_SizeChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Store the new size setting upon resizing
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void appControl_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default.Width = ToDoTaskPane.Width;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggle ribbon button's status
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void ToDoTaskPane_VisibleChanged(object sender, EventArgs e)
|
||||
{
|
||||
// TODO: Save visibility ONLY when not closing the form
|
||||
// Properties.Settings.Default.Visible = ToDoTaskPane.Visible;
|
||||
TodoRibbonAddIn rbn = Globals.Ribbons.FirstOrDefault(r => r is TodoRibbonAddIn) as TodoRibbonAddIn;
|
||||
if (rbn != null)
|
||||
@ -77,45 +77,42 @@ namespace Outlook2013TodoAddIn
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is NEVER executed anymore
|
||||
/// This is not executed by default
|
||||
/// http://msdn.microsoft.com/en-us/library/office/ee720183.aspx#OL2010AdditionalShutdownChanges_AddinShutdownChangesinOL2010Beta
|
||||
/// We MANUALLY add notification to the registry of each user
|
||||
/// We MANUALLY add notification to the registry of each user below
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">EventArgs</param>
|
||||
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
|
||||
{
|
||||
//inspectors.NewInspector -=
|
||||
// new Outlook.InspectorsEvents_NewInspectorEventHandler(
|
||||
// Inspectors_NewInspector);
|
||||
//inspectors = null;
|
||||
//inspectorWrappersValue = null;
|
||||
// Can't call these because the object is already disposed. Settings will be set while the app is running
|
||||
//Properties.Settings.Default.Visible = ToDoTaskPane.Visible;
|
||||
//Properties.Settings.Default.Width = ToDoTaskPane.Width;
|
||||
//Properties.Settings.Default.NumDays = appControl.NumDays;
|
||||
// Can't call property setters such as: Properties.Settings.Default.NumDays = XXX because the pane is already disposed.
|
||||
// Settings will be set while the app is running and saved here.
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implement shutdown notification for this particular add-in
|
||||
/// http://msdn.microsoft.com/en-us/library/office/ee720183.aspx#OL2010AdditionalShutdownChanges_AddinShutdownChangesinOL2010Beta
|
||||
/// HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\Addins\<ProgID>\[RequireShutdownNotification]=dword:0x1
|
||||
/// </summary>
|
||||
private void AddRegistryNotification()
|
||||
{
|
||||
// http://msdn.microsoft.com/en-us/library/office/ee720183.aspx#OL2010AdditionalShutdownChanges_AddinShutdownChangesinOL2010Beta
|
||||
// HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\Addins\<ProgID>\[RequireShutdownNotification]=dword:0x1
|
||||
|
||||
// TODO: Make sure there are no memory leaks (dispose COM obejcts)
|
||||
// TODO: See if this works the first time (if the entry is not there when Outlook loads, it will NOT notify the add-in)
|
||||
string subKey = @"Software\Microsoft\Office\Outlook\Addins\Outlook2013TodoAddIn";
|
||||
RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(subKey, true);
|
||||
|
||||
if (rk == null)
|
||||
{
|
||||
rk = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(subKey);
|
||||
}
|
||||
|
||||
if ((int)rk.GetValue("RequireShutdownNotification", 0) == 0)
|
||||
{
|
||||
rk.SetValue("RequireShutdownNotification", 1, RegistryValueKind.DWord); // "dword:0x1"
|
||||
}
|
||||
}
|
||||
|
||||
#endregion "Methods"
|
||||
|
||||
#region VSTO generated code
|
||||
|
||||
/// <summary>
|
||||
|
1
Outlook2013TodoAddIn/TodoRibbonAddIn.Designer.cs
generated
1
Outlook2013TodoAddIn/TodoRibbonAddIn.Designer.cs
generated
@ -67,7 +67,6 @@
|
||||
this.Name = "TodoRibbonAddIn";
|
||||
this.RibbonType = "Microsoft.Outlook.Explorer";
|
||||
this.Tabs.Add(this.tab1);
|
||||
this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.TodoRibbonAddIn_Load);
|
||||
this.tab1.ResumeLayout(false);
|
||||
this.tab1.PerformLayout();
|
||||
this.group1.ResumeLayout(false);
|
||||
|
@ -2,15 +2,23 @@
|
||||
|
||||
namespace Outlook2013TodoAddIn
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a button to the add-in placeholder in the ribbon
|
||||
/// </summary>
|
||||
public partial class TodoRibbonAddIn
|
||||
{
|
||||
private void TodoRibbonAddIn_Load(object sender, RibbonUIEventArgs e)
|
||||
{
|
||||
}
|
||||
#region "Methods"
|
||||
|
||||
/// <summary>
|
||||
/// Change visibility of the pane
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender</param>
|
||||
/// <param name="e">RibbonControlEventArgs</param>
|
||||
private void toggleButton1_Click(object sender, RibbonControlEventArgs e)
|
||||
{
|
||||
Globals.ThisAddIn.ToDoTaskPane.Visible = this.toggleButton1.Checked;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user