You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

402 lines
16 KiB

//
// Appointment.cs
//
// Author: Kees van Spelde <sicos2002@hotmail.com>
//
// Copyright (c) 2013-2018 Magic-Sessions. (www.magic-sessions.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using MsgReader.Localization;
namespace MsgReader.Outlook
{
#region Enum AppointmentRecurrenceType
/// <summary>
/// The recurrence type of an appointment
/// </summary>
public enum AppointmentRecurrenceType
{
/// <summary>
/// There is no reccurence
/// </summary>
None = -1,
/// <summary>
/// The appointment is daily
/// </summary>
Daily = 0,
/// <summary>
/// The appointment is weekly
/// </summary>
Weekly = 1,
/// <summary>
/// The appointment is monthly
/// </summary>
Montly = 2,
/// <summary>
/// The appointment is yearly
/// </summary>
Yearly = 3
}
#endregion
#region Enum AppointmentClientIntent
/// <summary>
/// The intent of an appointment
/// </summary>
public enum AppointmentClientIntent
{
/// <summary>
/// The user is the owner of the Meeting object's
/// </summary>
Manager = 1,
/// <summary>
/// The user is a delegate acting on a Meeting object in a delegator's Calendar folder. If this bit is set, the
/// ciManager bit SHOULD NOT be set
/// </summary>
Delegate = 2,
/// <summary>
/// The user deleted the Meeting object with no response sent to the organizer
/// </summary>
DeletedWithNoResponse = 4,
/// <summary>
/// The user deleted an exception to a recurring series with no response sent to the organizer
/// </summary>
DeletedExceptionWithNoResponse = 8,
/// <summary>
/// Appointment accepted as tentative
/// </summary>
RespondedTentative = 16,
/// <summary>
/// Appointment accepted
/// </summary>
RespondedAccept = 32,
/// <summary>
/// Appointment declined
/// </summary>
RespondedDecline = 64,
/// <summary>
/// The user modified the start time
/// </summary>
ModifiedStartTime = 128,
/// <summary>
/// The user modified the end time
/// </summary>
ModifiedEndTime = 256,
/// <summary>
/// The user changed the location of the meeting
/// </summary>
ModifiedLocation = 512,
/// <summary>
/// The user declined an exception to a recurring series
/// </summary>
RespondedExceptionDecline = 1024,
/// <summary>
/// The user declined an exception to a recurring series
/// </summary>
Canceled = 2048,
/// <summary>
/// The user canceled an exception to a recurring serie
/// </summary>
ExceptionCanceled = 4096
}
#endregion
public partial class Storage
{
/// <summary>
/// Class used to contain all the appointment information of a <see cref="Storage.Message" />.
/// </summary>
public sealed class Appointment : Storage
{
#region Properties
/// <summary>
/// Returns the location for the appointment, null when not available
/// </summary>
public string Location { get; }
/// <summary>
/// Returns the start time for the appointment, null when not available
/// </summary>
public DateTime? Start { get; }
/// <summary>
/// Returns the end time for the appointment, null when not available
/// </summary>
public DateTime? End { get; }
/// <summary>
/// Returns a string with all the attendees (To and CC), if you also want their E-mail addresses then
/// get the <see cref="Storage.Message.Recipients" /> from the message, null when not available
/// </summary>
public string AllAttendees { get; }
/// <summary>
/// Returns a string with all the TO (mandatory) attendees. If you also want their E-mail addresses then
/// get the <see cref="Storage.Message.Recipients" /> from the <see cref="Storage.Message" /> and filter this
/// one on <see cref="RecipientType.To" />. Null when not available
/// </summary>
public string ToAttendees { get; }
/// <summary>
/// Returns a string with all the CC (optional) attendees. If you also want their E-mail addresses then
/// get the <see cref="Storage.Message.Recipients" /> from the <see cref="Storage.Message" /> and filter this
/// one on <see cref="RecipientType.Cc" />. Null when not available
/// </summary>
public string CcAttendees { get; }
/// <summary>
/// Returns A value of <c>true</c> for the PidLidAppointmentNotAllowPropose property ([MS-OXPROPS] section 2.17)
/// indicates that attendees are not allowed to propose a new date and/or time for the meeting. A value of
/// <c>false</c> or the absence of this property indicates that the attendees are allowed to propose a new date
/// and/or time. This property is meaningful only on Meeting objects, Meeting Request objects, and Meeting
/// Update objects. Null when not available
/// </summary>
public bool? NotAllowPropose { get; }
/// <summary>
/// Returns a <see cref="UnsendableRecipients" /> object with all the unsendable attendees. Null when not available
/// </summary>
public UnsendableRecipients UnsendableRecipients { get; }
/// <summary>
/// Returns the reccurence type (daily, weekly, monthly or yearly) for the <see cref="Storage.Appointment" />
/// </summary>
public AppointmentRecurrenceType ReccurrenceType { get; }
/// <summary>
/// Returns the reccurence type (daily, weekly, monthly or yearly) for the <see cref="Storage.Appointment" /> as a
/// string,
/// null when not available
/// </summary>
public string RecurrenceTypeText { get; }
/// <summary>
/// Returns the reccurence patern for the <see cref="Storage.Appointment" />, null when not available
/// </summary>
public string RecurrencePatern { get; }
/// <summary>
/// The clients intention for the the <see cref="Storage.Appointment" /> as a list,
/// null when not available
/// of <see cref="AppointmentClientIntent" />
/// </summary>
public ReadOnlyCollection<AppointmentClientIntent> ClientIntent { get; }
/// <summary>
/// The <see cref="ClientIntent" /> for the the <see cref="Storage.Appointment" /> as text
/// </summary>
public string ClientIntentText { get; }
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="Storage.Task" /> class.
/// </summary>
/// <param name="message"> The message. </param>
internal Appointment(Storage message) : base(message._rootStorage)
{
//GC.SuppressFinalize(message);
_namedProperties = message._namedProperties;
_propHeaderSize = MapiTags.PropertiesStreamHeaderTop;
Location = GetMapiPropertyString(MapiTags.Location);
Start = GetMapiPropertyDateTime(MapiTags.AppointmentStartWhole);
End = GetMapiPropertyDateTime(MapiTags.AppointmentEndWhole);
AllAttendees = GetMapiPropertyString(MapiTags.AppointmentAllAttendees);
ToAttendees = GetMapiPropertyString(MapiTags.AppointmentToAttendees);
CcAttendees = GetMapiPropertyString(MapiTags.AppointmentCCAttendees);
NotAllowPropose = GetMapiPropertyBool(MapiTags.AppointmentNotAllowPropose);
UnsendableRecipients = GetUnsendableRecipients(MapiTags.AppointmentUnsendableRecipients);
#region Recurrence
var recurrenceType = GetMapiPropertyInt32(MapiTags.ReccurrenceType);
if (recurrenceType == null)
{
ReccurrenceType = AppointmentRecurrenceType.None;
RecurrenceTypeText = LanguageConsts.AppointmentReccurenceTypeNoneText;
}
else
{
switch (recurrenceType)
{
case 1:
ReccurrenceType = AppointmentRecurrenceType.Daily;
break;
case 2:
ReccurrenceType = AppointmentRecurrenceType.Weekly;
break;
case 3:
case 4:
ReccurrenceType = AppointmentRecurrenceType.Montly;
break;
case 5:
case 6:
ReccurrenceType = AppointmentRecurrenceType.Yearly;
break;
default:
ReccurrenceType = AppointmentRecurrenceType.None;
break;
}
switch (ReccurrenceType)
{
case AppointmentRecurrenceType.Daily:
RecurrenceTypeText = LanguageConsts.AppointmentReccurenceTypeDailyText;
break;
case AppointmentRecurrenceType.Weekly:
RecurrenceTypeText = LanguageConsts.AppointmentReccurenceTypeWeeklyText;
break;
case AppointmentRecurrenceType.Montly:
RecurrenceTypeText = LanguageConsts.AppointmentReccurenceTypeMonthlyText;
break;
case AppointmentRecurrenceType.Yearly:
RecurrenceTypeText = LanguageConsts.AppointmentReccurenceTypeYearlyText;
break;
}
}
RecurrencePatern = GetMapiPropertyString(MapiTags.ReccurrencePattern);
#endregion
#region ClientIntent
var clientIntentList = new List<AppointmentClientIntent>();
var clientIntent = GetMapiPropertyInt32(MapiTags.PidLidClientIntent);
if (clientIntent == null)
{
ClientIntent = null;
}
else
{
var bitwiseValue = (int) clientIntent;
if ((bitwiseValue & 1) == 1)
{
clientIntentList.Add(AppointmentClientIntent.Manager);
ClientIntentText = LanguageConsts.AppointmentClientIntentManagerText;
}
if ((bitwiseValue & 2) == 2)
{
clientIntentList.Add(AppointmentClientIntent.Delegate);
ClientIntentText = LanguageConsts.AppointmentClientIntentDelegateText;
}
if ((bitwiseValue & 4) == 4)
{
clientIntentList.Add(AppointmentClientIntent.DeletedWithNoResponse);
ClientIntentText = LanguageConsts.AppointmentClientIntentDeletedWithNoResponseText;
}
if ((bitwiseValue & 8) == 8)
{
clientIntentList.Add(AppointmentClientIntent.DeletedExceptionWithNoResponse);
ClientIntentText = LanguageConsts.AppointmentClientIntentDeletedExceptionWithNoResponseText;
}
if ((bitwiseValue & 16) == 16)
{
clientIntentList.Add(AppointmentClientIntent.RespondedTentative);
ClientIntentText = LanguageConsts.AppointmentClientIntentRespondedTentativeText;
}
if ((bitwiseValue & 32) == 32)
{
clientIntentList.Add(AppointmentClientIntent.RespondedAccept);
ClientIntentText = LanguageConsts.AppointmentClientIntentRespondedAcceptText;
}
if ((bitwiseValue & 64) == 64)
{
clientIntentList.Add(AppointmentClientIntent.RespondedDecline);
ClientIntentText = LanguageConsts.AppointmentClientIntentRespondedDeclineText;
}
if ((bitwiseValue & 128) == 128)
{
clientIntentList.Add(AppointmentClientIntent.ModifiedStartTime);
ClientIntentText = LanguageConsts.AppointmentClientIntentModifiedStartTimeText;
}
if ((bitwiseValue & 256) == 256)
{
clientIntentList.Add(AppointmentClientIntent.ModifiedEndTime);
ClientIntentText = LanguageConsts.AppointmentClientIntentModifiedEndTimeText;
}
if ((bitwiseValue & 512) == 512)
{
clientIntentList.Add(AppointmentClientIntent.ModifiedLocation);
ClientIntentText = LanguageConsts.AppointmentClientIntentModifiedLocationText;
}
if ((bitwiseValue & 1024) == 1024)
{
clientIntentList.Add(AppointmentClientIntent.RespondedExceptionDecline);
ClientIntentText = LanguageConsts.AppointmentClientIntentRespondedExceptionDeclineText;
}
if ((bitwiseValue & 2048) == 2048)
{
clientIntentList.Add(AppointmentClientIntent.Canceled);
ClientIntentText = LanguageConsts.AppointmentClientIntentCanceledText;
}
if ((bitwiseValue & 4096) == 4096)
{
clientIntentList.Add(AppointmentClientIntent.ExceptionCanceled);
ClientIntentText = LanguageConsts.AppointmentClientIntentExceptionCanceledText;
}
ClientIntent = clientIntentList.AsReadOnly();
}
#endregion
}
#endregion
}
}
}