DotNet 4.8.1 build of DotNetBar

This commit is contained in:
2025-02-07 10:35:23 -05:00
parent 33439b63a0
commit 6b0a5d60f4
2609 changed files with 989814 additions and 7 deletions

View File

@@ -0,0 +1,495 @@
#if FRAMEWORK20
using System;
using DevComponents.Schedule.Model;
using System.Drawing;
using DevComponents.WinForms.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Schedule
{
public class AppointmentHView : AppointmentView
{
#region Private variables
private eViewEnds _ViewEnds = eViewEnds.Complete;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseView"></param>
/// <param name="appointment"></param>
public AppointmentHView(BaseView baseView, Appointment appointment)
: base(baseView, appointment)
{
}
#region Private properties
/// <summary>
/// Gets whether the appointment is mutable
/// </summary>
private bool IsMutable
{
get
{
return (IsSelected == true &&
Appointment.Locked == false &&
Appointment.IsRecurringInstance == false);
}
}
#endregion
#region Protected properties
protected eViewEnds ViewEnds
{
get { return (_ViewEnds); }
set { _ViewEnds = value; }
}
protected virtual Rectangle ParentBounds
{
get { return (Bounds); }
}
#endregion
#region Start/End TimeChanged event handling
/// <summary>
/// Handles StartTime value changes
/// </summary>
/// <param name="sender">CalendarItem</param>
/// <param name="e">EventArgs</param>
protected override void AppointmentView_StartTimeChanged(object sender, EventArgs e)
{
base.AppointmentView_StartTimeChanged(sender, e);
SetViewEnds();
}
/// <summary>
/// Handles EndTime value changes
/// </summary>
/// <param name="sender">CalendarItem</param>
/// <param name="e">EventArgs</param>
protected override void AppointmentView_EndTimeChanged(object sender, EventArgs e)
{
base.AppointmentView_EndTimeChanged(sender, e);
SetViewEnds();
}
#endregion
#region SetViewEnds
/// <summary>
/// Sets the view display end types
/// </summary>
protected virtual void SetViewEnds()
{
_ViewEnds = eViewEnds.Complete;
}
#endregion
#region Appointment rendering
/// <summary>
/// Paint processing
/// </summary>
/// <param name="e">ItemPaintArgs</param>
public override void Paint(ItemPaintArgs e)
{
SetViewEnds();
AppointmentColor.SetColorTable();
int n = (Bounds.Width < 20) ? 0 : 5;
CornerRadius cornerRadius = new CornerRadius(n);
Rectangle r = GetViewRect(ref cornerRadius);
if (r.Width > 1 && r.Height > 0)
{
if (EffectiveStyle == eDotNetBarStyle.Office2010 || StyleManager.IsMetro(EffectiveStyle))
DrawMetroAppointment(e, r);
else
DrawDefaultAppointment(e, r, n, cornerRadius);
if (IsMutable == true)
DrawGribits(e, r);
}
}
#region DrawMetroAppointment
private void DrawMetroAppointment(ItemPaintArgs e, Rectangle r)
{
Graphics g = e.Graphics;
using (Brush br = BackBrush(r))
e.Graphics.FillRectangle(br, r);
if (BaseView.CalendarView.DoAppointmentViewPreRender(this, g, r, null) == false)
{
DrawContent(e, r);
BaseView.CalendarView.DoAppointmentViewPostRender(this, g, r, null);
}
DrawMetroBorder(e, r);
}
#region DrawMetroBorder
private void DrawMetroBorder(ItemPaintArgs e, Rectangle r)
{
Graphics g = e.Graphics;
if ((_ViewEnds & eViewEnds.PartialLeft) != eViewEnds.PartialLeft)
{
if (r.Width > 10)
DrawTimeMarker(g, r, 0);
}
if (IsSelected == true)
{
if (r.Width > 10)
{
using (Pen pen = new Pen(Color.Black, 2))
g.DrawRectangle(pen, r);
}
else
{
g.DrawRectangle(Pens.Black, r);
}
}
else
{
using (Pen pen = BorderPen)
g.DrawRectangle(pen, r);
}
}
#endregion
#endregion
#region DrawDefaultAppointment
private void DrawDefaultAppointment(ItemPaintArgs e,
Rectangle r, int n, CornerRadius cornerRadius)
{
Graphics g = e.Graphics;
using (GraphicsPath path = GetItemPath(r, n * 2, cornerRadius))
{
using (Brush br = BackBrush(r))
g.FillPath(br, path);
if (BaseView.CalendarView.DoAppointmentViewPreRender(this, g, r, path) == false)
{
DrawContent(e, r);
BaseView.CalendarView.DoAppointmentViewPostRender(this, g, r, path);
}
DrawDefaultBorder(e, r, path, n);
}
}
#region DrawDefaultBorder
private void DrawDefaultBorder(ItemPaintArgs e,
Rectangle r, GraphicsPath path, int n)
{
Graphics g = e.Graphics;
if ((_ViewEnds & eViewEnds.PartialLeft) != eViewEnds.PartialLeft)
{
if (r.Width > 10)
DrawTimeMarker(g, r, n);
}
if (IsSelected == true)
{
if (r.Width > 10)
{
using (Pen pen = SelectedBorderPen)
g.DrawPath(pen, path);
}
else
{
g.DrawPath(Pens.Black, path);
}
}
else
{
using (Pen pen = BorderPen)
g.DrawPath(pen, path);
}
}
#endregion
#endregion
#region DrawContent
private void DrawContent(ItemPaintArgs e, Rectangle r)
{
Image image = Image;
Rectangle rText = r;
rText.X += 4;
rText.Width -= 6;
if (Appointment.TimeMarkedAs != null)
{
rText.X += 4;
rText.Width -= 4;
}
Rectangle rImage = GetItemBounds(rText, ref rText, image);
DrawContentImage(e, r, rImage, image);
DrawContentText(e, rText);
}
#region DrawContentText
/// <summary>
/// DrawContentText
/// </summary>
/// <param name="e"></param>
/// <param name="r"></param>
private void DrawContentText(ItemPaintArgs e, Rectangle r)
{
Graphics g = e.Graphics;
// Format the appointment text
if (DisplayTemplateText(e, r) == false)
{
string s = (Appointment.IsMultiDayOrAllDayEvent)
? Appointment.Subject
: String.Format("{0} {1}", Appointment.StartTime.ToShortTimeString(), Appointment.Subject);
// Output the appointment text and
// appropriately weighted bounding path
Font font = Font ?? e.Font;
const eTextFormat tf = eTextFormat.VerticalCenter |
eTextFormat.EndEllipsis | eTextFormat.NoPadding | eTextFormat.NoPrefix;
if (r.Width > 10)
TextDrawing.DrawString(g, s, font, TextColor, r, tf);
Size size = TextDrawing.MeasureString(g, s, font, r.Width, tf);
IsTextClipped = (r.Width < size.Width || r.Height < size.Height);
}
}
#endregion
#endregion
#region GetViewRect
/// <summary>
/// Gets the view rect for the appointment
/// </summary>
/// <param name="cornerRadius">Corner radius</param>
/// <returns>View rect</returns>
private Rectangle GetViewRect(ref CornerRadius cornerRadius)
{
Rectangle r = DisplayRectangle;
r.Intersect(ParentBounds);
if (r.Left == ParentBounds.Left)
{
r.X++;
r.Width--;
}
if ((_ViewEnds & eViewEnds.PartialLeft) == eViewEnds.PartialLeft)
cornerRadius.TopLeft = cornerRadius.BottomLeft = 0;
if ((_ViewEnds & eViewEnds.PartialRight) == eViewEnds.PartialRight)
cornerRadius.TopRight = cornerRadius.BottomRight = 0;
// If the view is selected, then allow
// for a thicker selection rect
if (IsSelected == true)
r.Height--;
return (r);
}
#endregion
#region GetItemPath
/// <summary>
/// Gets a path defining the item
/// </summary>
/// <param name="viewRect"></param>
/// <param name="radius"></param>
/// <param name="cornerRadius"></param>
/// <returns></returns>
private GraphicsPath GetItemPath(Rectangle viewRect, int radius, CornerRadius cornerRadius)
{
GraphicsPath path = new GraphicsPath();
Rectangle r = viewRect;
Rectangle ar = new
Rectangle(r.Right - radius, r.Bottom - radius, radius, radius);
if (cornerRadius.BottomRight > 0)
path.AddArc(ar, 0, 90);
else
path.AddLine(r.Right, r.Bottom, r.Right, r.Bottom);
ar.X = r.X;
if (cornerRadius.BottomLeft > 0)
path.AddArc(ar, 90, 90);
else
path.AddLine(r.Left, r.Bottom, r.Left, r.Bottom);
ar.Y = r.Y;
if (cornerRadius.TopLeft > 0)
path.AddArc(ar, 180, 90);
else
path.AddLine(r.Left, r.Top, r.Left, r.Top);
ar.X = r.Right - radius;
if (cornerRadius.TopRight > 0)
path.AddArc(ar, 270, 90);
else
path.AddLine(r.Right, r.Top, r.Right, r.Top);
path.CloseAllFigures();
return (path);
}
#endregion
#region DrawGribits
/// <summary>
/// Draws the resize gribits for the view
/// </summary>
/// <param name="e"></param>
/// <param name="r">View rectangle</param>
private void DrawGribits(ItemPaintArgs e, Rectangle r)
{
if (r.Width >= 8)
{
Graphics g = e.Graphics;
Rectangle r2 =
new Rectangle(r.X, r.Y + (r.Height / 2) - 2, 5, 5);
// Left gribit
if ((_ViewEnds & eViewEnds.PartialLeft) == 0)
{
r2.X = r.X - 3;
g.FillRectangle(Brushes.White, r2);
g.DrawRectangle(Pens.Black, r2);
}
// Right gribit
if ((_ViewEnds & eViewEnds.PartialRight) == 0)
{
r2.X = r.Right - 2;
g.FillRectangle(Brushes.White, r2);
g.DrawRectangle(Pens.Black, r2);
}
}
}
#endregion
#endregion
#region Mouse processing
/// <summary>
/// Handles mouseDown processing
/// </summary>
/// <param name="objArg">MouseEventArgs</param>
public override void InternalMouseMove(MouseEventArgs objArg)
{
HitArea = GetHitArea(objArg);
base.InternalMouseMove(objArg);
}
/// <summary>
/// Gets the HitArea from the current
/// mouse position
/// </summary>
/// <param name="objArg"></param>
/// <returns></returns>
private eHitArea GetHitArea(MouseEventArgs objArg)
{
if (IsMutable == true)
{
CornerRadius cornerRadius = new CornerRadius(5);
Rectangle r = GetViewRect(ref cornerRadius);
//if (r.Width > 10)
{
Rectangle r2 =
new Rectangle(r.X, r.Y + (r.Height / 2) - 2, 5, 5);
if ((_ViewEnds & eViewEnds.PartialLeft) == 0)
{
r2.X = r.X - 3;
r2.Inflate(2, 2);
if (r2.Contains(objArg.Location))
return (eHitArea.LeftResize);
}
if ((_ViewEnds & eViewEnds.PartialRight) == 0)
{
r2.X = r.Right - 2;
r2.Inflate(2, 2);
if (r2.Contains(objArg.Location))
return (eHitArea.RightResize);
}
}
// By default we are in the move area
return (eHitArea.Move);
}
return (eHitArea.None);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,81 @@
#if FRAMEWORK20
using System;
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
public class AppointmentMonthView : AppointmentHView
{
#region Constants
private const int DaysInWeek = 7;
#endregion
#region Private variables
private MonthWeek _MonthWeek;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseView"></param>
/// <param name="appointment"></param>
public AppointmentMonthView(BaseView baseView, Appointment appointment)
: base(baseView, appointment)
{
}
#region Public properties
/// <summary>
/// Gets and sets View MonthWeek
/// </summary>
public MonthWeek MonthWeek
{
get { return (_MonthWeek); }
set
{
if (_MonthWeek != value)
{
_MonthWeek = value;
SetViewEnds();
}
}
}
#endregion
#region SetViewEnds
/// <summary>
/// Sets the view display end types
/// </summary>
protected override void SetViewEnds()
{
if (_MonthWeek != null)
{
DateTime start = _MonthWeek.FirstDayOfWeek;
DateTime end = start.AddDays(DaysInWeek);
ViewEnds = eViewEnds.Complete;
// Check to see if we can only display
// a partial representation for the view
if (EndTime >= start && StartTime < end)
{
if (StartTime < start)
ViewEnds |= eViewEnds.PartialLeft;
if (EndTime > end)
ViewEnds |= eViewEnds.PartialRight;
}
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,81 @@
#if FRAMEWORK20
using DevComponents.Schedule.Model;
using System.Drawing;
namespace DevComponents.DotNetBar.Schedule
{
public class AppointmentTimeLineView : AppointmentHView
{
#region Private variables
private TimeLineView _TimeLineView;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseView"></param>
/// <param name="appointment"></param>
public AppointmentTimeLineView(BaseView baseView, Appointment appointment)
: base(baseView, appointment)
{
}
#region Public properties
public TimeLineView TimeLineView
{
get { return (_TimeLineView); }
set
{
if (_TimeLineView != value)
{
_TimeLineView = value;
if (_TimeLineView != null)
SetViewEnds();
}
}
}
#endregion
#region SetViewEnds
/// <summary>
/// Sets the view display end types
/// </summary>
protected override void SetViewEnds()
{
ViewEnds = eViewEnds.Complete;
Rectangle r = DisplayRectangle;
Rectangle p = ParentBounds;
if (r.Left < p.Left)
ViewEnds |= eViewEnds.PartialLeft;
if (r.Right > p.Right)
ViewEnds |= eViewEnds.PartialRight;
}
#endregion
#region Protected properties
protected override Rectangle ParentBounds
{
get
{
if (_TimeLineView != null)
return (_TimeLineView.ClientRect);
return (base.ParentBounds);
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,804 @@
#if FRAMEWORK20
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using DevComponents.DotNetBar.Rendering;
using DevComponents.DotNetBar.TextMarkup;
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
public class AppointmentView : CalendarItem
{
#region enums
[Flags]
public enum eViewEnds // View display ends
{
Complete = 0,
PartialLeft = 1,
PartialRight = 2
}
#endregion
#region Static variables
static private AppointmentColor _appointmentColor = new AppointmentColor();
#endregion
#region Private variables
private Font _Font;
private BaseView _BaseView;
private Appointment _Appointment;
private bool _IsTextClipped;
private int _BorderWidth;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseView"></param>
/// <param name="appointment"></param>
public AppointmentView(BaseView baseView, Appointment appointment)
{
_BaseView = baseView;
_Appointment = appointment;
MouseUpNotification = true;
StartTime = appointment.StartTime;
EndTime = appointment.EndTime;
ModelItem = appointment;
IsRecurring = (appointment.IsRecurringInstance == true ||
appointment.Recurrence != null);
RootItem = (appointment.IsRecurringInstance == true) ?
appointment.RootAppointment : appointment;
StartTimeChanged += AppointmentView_StartTimeChanged;
EndTimeChanged += AppointmentView_EndTimeChanged;
}
#region Public properties
#region Appointment
/// <summary>
/// Gets and sets the view Appointment
/// </summary>
public Appointment Appointment
{
get { return (_Appointment); }
set { _Appointment = value; }
}
#endregion
#region AppointmentColor
/// <summary>
/// Gets and sets the appointment color
/// </summary>
public AppointmentColor AppointmentColor
{
get { return (_appointmentColor); }
set { _appointmentColor = value; }
}
#endregion
#region BorderWidth
public int BorderWidth
{
get { return (_BorderWidth); }
set
{
if (_BorderWidth != value)
{
_BorderWidth = value;
Invalidate(_BaseView.CalendarView);
}
}
}
#endregion
#region Font
/// <summary>
/// Gets and sets the view font
/// </summary>
public Font Font
{
get { return (_Font); }
set { _Font = value; }
}
#endregion
#region IsTextClipped
/// <summary>
/// Gets whether the Appointment display Text is clipped
/// </summary>
public bool IsTextClipped
{
get { return (_IsTextClipped); }
internal set { _IsTextClipped = value; }
}
#endregion
#endregion
#region Internal properties
#region BaseView
/// <summary>
/// BaseView
/// </summary>
internal BaseView BaseView
{
get { return (_BaseView); }
}
#endregion
#region Image
/// <summary>
/// Image
/// </summary>
internal Image Image
{
get
{
if (string.IsNullOrEmpty(Appointment.ImageKey) == true)
return (null);
ImageList images;
switch (_BaseView.CalendarView.ImageSize)
{
case eBarImageSize.Medium:
images = _BaseView.CalendarView.ImagesMedium;
break;
case eBarImageSize.Large:
images = _BaseView.CalendarView.ImagesLarge;
break;
default:
images = _BaseView.CalendarView.Images;
break;
}
return (images != null ?
images.Images[Appointment.ImageKey] : null);
}
}
#endregion
#endregion
#region Start/End TimeChanged event handling
/// <summary>
/// Handles StartTime value changes
/// </summary>
/// <param name="sender">CalendarItem</param>
/// <param name="e">EventArgs</param>
protected virtual void AppointmentView_StartTimeChanged(object sender, EventArgs e)
{
_Appointment.StartTime = StartTime;
}
/// <summary>
/// Handles EndTime value changes
/// </summary>
/// <param name="sender">CalendarItem</param>
/// <param name="e">EventArgs</param>
protected virtual void AppointmentView_EndTimeChanged(object sender, EventArgs e)
{
_Appointment.EndTime = EndTime;
}
#endregion
#region DisplayTemplateText
/// <summary>
/// DisplayTemplateText
/// </summary>
/// <param name="e"></param>
/// <param name="r"></param>
/// <returns>true is displayed</returns>
internal bool DisplayTemplateText(ItemPaintArgs e, Rectangle r)
{
if (_BaseView.CalendarView.EnableMarkup == true)
{
if (string.IsNullOrEmpty(Appointment.DisplayTemplate) == false)
{
Text = GetDisplayTemplateText(r);
}
else
{
string text = Appointment.Subject;
if (IsUsingTextMarkup)
{
if (Appointment.IsMultiDayOrAllDayEvent == false)
text += "<br/>" + Appointment.Description;
}
Text = text;
}
if (IsUsingTextMarkup)
{
Graphics g = e.Graphics;
MarkupDrawContext d =
new MarkupDrawContext(g, Font ?? e.Font, TextColor, true);
Size size = new Size(5000, 5000);
TextMarkupBodyMeasure(size, d);
d.RightToLeft = false;
r.Y += 3;
r.Height -= 3;
TextMarkupBodyArrange(new Rectangle(r.Location, TextMarkupBodyBounds.Size), d);
_IsTextClipped = (TextMarkupBodyBounds.Size.Width > r.Width ||
TextMarkupBodyBounds.Size.Height > r.Height);
Region oldClip = g.Clip;
Rectangle clipRect = r;
g.SetClip(clipRect, CombineMode.Intersect);
TextMarkupBodyRender(d);
g.Clip = oldClip;
return (true);
}
}
return (false);
}
#endregion
#region GetDisplayTemplateText
/// <summary>
/// GetDisplayTemplateText
/// </summary>
/// <param name="r"></param>
/// <returns>Templatized text</returns>
private string GetDisplayTemplateText(Rectangle r)
{
string s = Appointment.DisplayTemplate;
if (String.IsNullOrEmpty(s) == true)
return (s);
Regex reg = new Regex("\\[\\w+\\]");
MatchCollection mc = reg.Matches(s);
int index = 0;
StringBuilder sb = new StringBuilder();
sb.Append("<p width=\"" + r.Width.ToString() + "\">");
for (int i = 0; i < mc.Count; i++)
{
Match ma = mc[i];
if (ma.Index > index)
sb.Append(s.Substring(index, ma.Index - index));
switch (ma.Value)
{
case "[StartTime]":
sb.Append(Appointment.StartTime.ToString("t",
_BaseView.CalendarView.Is24HourFormat ? DateTimeFormatInfo.InvariantInfo : null));
break;
case "[StartDate]":
sb.Append(Appointment.StartTime.ToShortDateString());
break;
case "[EndTime]":
sb.Append(Appointment.EndTime.ToString("t",
_BaseView.CalendarView.Is24HourFormat ? DateTimeFormatInfo.InvariantInfo : null));
break;
case "[EndDate]":
sb.Append(Appointment.EndTime.ToShortDateString());
break;
case "[Subject]":
sb.Append(Appointment.Subject);
break;
case "[Description]":
sb.Append(Appointment.Description);
break;
case "[Id]":
sb.Append(Appointment.Id);
break;
case "[Tag]":
sb.Append(Appointment.Tag.ToString());
break;
default:
sb.Append(_BaseView.CalendarView.DoGetDisplayTemplateText(this, ma.Value, ma.Value));
break;
}
index = ma.Index + ma.Length;
}
if (s.Length > index)
sb.Append(s.Substring(index));
sb.Append("</p>");
return (sb.ToString());
}
#endregion
#region Paint
/// <summary>
/// Paint processing
/// </summary>
/// <param name="e">ItemPaintArgs</param>
public override void Paint(ItemPaintArgs e)
{
}
#region GetItemBounds
/// <summary>
/// Gets the item text and image bounds
/// </summary>
/// <param name="r"></param>
/// <param name="rText"></param>
/// <param name="image"></param>
/// <returns></returns>
protected virtual Rectangle GetItemBounds(Rectangle r, ref Rectangle rText, Image image)
{
Rectangle ri = r;
if (Image != null)
{
const int vpad = 2;
const int hpad = 3;
ri.Inflate(0, -vpad);
switch (Appointment.ImageAlign)
{
case eImageContentAlignment.TopLeft:
rText.X += (image.Size.Width + hpad);
rText.Width -= (image.Size.Width + hpad);
break;
case eImageContentAlignment.TopRight:
ri.X = rText.Right - image.Size.Width;
rText.Width -= image.Size.Width;
break;
case eImageContentAlignment.TopCenter:
ri.X += (ri.Width - image.Size.Width) / 2;
rText.Y += (image.Size.Height + hpad);
rText.Height -= (image.Size.Height + hpad);
break;
case eImageContentAlignment.MiddleLeft:
ri.Y += (ri.Height - image.Size.Height) / 2;
rText.X += (image.Size.Width + hpad);
rText.Width -= (image.Size.Width + hpad);
break;
case eImageContentAlignment.MiddleRight:
ri.X = ri.Right - image.Size.Width;
ri.Y += (ri.Height - image.Size.Height) / 2;
rText.Width -= (image.Size.Width + hpad);
break;
case eImageContentAlignment.MiddleCenter:
ri.X = ri.X + (ri.Width - image.Size.Width) / 2;
ri.Y += (ri.Height - image.Size.Height) / 2;
break;
case eImageContentAlignment.BottomLeft:
ri.Y = ri.Bottom - image.Size.Height;
rText.X += (image.Size.Width + hpad);
rText.Width -= (image.Size.Width + hpad);
break;
case eImageContentAlignment.BottomRight:
ri.X = ri.Right - image.Size.Width;
ri.Y = ri.Bottom - image.Size.Height;
rText.Width -= (image.Size.Width - hpad);
break;
default:
ri.X = ri.X + (ri.Width - image.Size.Width) / 2;
ri.Y = ri.Bottom - image.Size.Height;
break;
}
ri.Size = image.Size;
if (ri.X < r.X)
ri.X = r.X;
if (ri.Y < r.Y + vpad)
ri.Y = r.Y + vpad;
}
return (ri);
}
#endregion
#region DrawContentImage
/// <summary>
/// DrawContentImage
/// </summary>
/// <param name="e"></param>
/// <param name="r"></param>
/// <param name="rImage"></param>
/// <param name="image"></param>
protected virtual void DrawContentImage(
ItemPaintArgs e, Rectangle r, Rectangle rImage, Image image)
{
if (image != null)
{
Graphics g = e.Graphics;
rImage.Intersect(r);
g.DrawImageUnscaledAndClipped(image, rImage);
}
}
#endregion
#region DrawTimeMarker
#region DrawTimeMarker
/// <summary>
/// Initiates the drawing of the appointment Time Marker
/// </summary>
/// <param name="g">Graphics</param>
/// <param name="r">Appointment rectangle</param>
/// <param name="corner">Corner radius</param>
protected virtual void DrawTimeMarker(Graphics g, Rectangle r, int corner)
{
if (Appointment.TimeMarkedAs != null)
{
if (Appointment.TimeMarkedAs.Equals(Appointment.TimerMarkerTentative))
{
using (HatchBrush br =
new HatchBrush(HatchStyle.WideUpwardDiagonal, BorderColor, Color.White))
{
g.RenderingOrigin = new Point(r.X, r.Y);
RenderMarker(g, br, r, corner);
}
}
else
{
using (Brush br = TimeMarkerBrush(r))
{
if (br != null)
RenderMarker(g, br, r, corner);
}
}
}
}
#endregion
#region RenderMarker
/// <summary>
/// RenderMarker
/// </summary>
/// <param name="g"></param>
/// <param name="br">Brush</param>
/// <param name="r">Rectangle</param>
/// <param name="corner">Corner</param>
private void RenderMarker(Graphics g, Brush br, Rectangle r, int corner)
{
using (Pen pen = BorderPen)
{
if (corner > 0)
{
using (GraphicsPath path = GetLeftRoundedRectanglePath(r, corner))
{
g.FillPath(br, path);
g.DrawPath(pen, path);
}
}
else
{
int x = Math.Min(5, r.Height / 2);
x = Math.Min(x, r.Width / 2);
r.Width = x;
g.FillRectangle(br, r);
g.DrawRectangle(pen, r);
}
}
}
#endregion
#region GetLeftRoundedRectanglePath
/// <summary>
/// Creates a left rounded rectangle path to be
/// used for the Time Marker
/// </summary>
/// <param name="r">Appointment rectangle</param>
/// <param name="corner">Corner radius</param>
/// <returns>Graphics path</returns>
private GraphicsPath GetLeftRoundedRectanglePath(Rectangle r, int corner)
{
GraphicsPath path = new GraphicsPath();
ElementStyleDisplay.AddCornerArc(path, r, corner, eCornerArc.TopLeft);
path.AddLine(r.X + corner, r.Y, r.X + corner, r.Bottom);
ElementStyleDisplay.AddCornerArc(path, r, corner, eCornerArc.BottomLeft);
return (path);
}
#endregion
#endregion
#endregion
#region Color support
#region BackBrush
/// <summary>
/// Gets the appointment BackGround brush
/// </summary>
/// <param name="r">Bounding rectangle</param>
/// <returns></returns>
protected Brush BackBrush(Rectangle r)
{
string category = _Appointment.CategoryColor;
if (category != null)
{
// Check to see if we have any user defined
// AppointmentCategoryColors
if (_BaseView.CalendarView.HasCategoryColors == true)
{
AppointmentCategoryColor acc =
_BaseView.CalendarView.CategoryColors[category];
if (acc != null)
return (_appointmentColor.BrushPart(acc.BackColor, r));
}
// Just use the default color set
if (category.StartsWith("#") == true)
return (new SolidBrush(ColorFactory.Empty.GetColor(category.Substring(1))));
if (category.Equals(Appointment.CategoryBlue))
return (_appointmentColor.BrushPart((int)eAppointmentPart.BlueBackground, r));
if (category.Equals(Appointment.CategoryGreen))
return (_appointmentColor.BrushPart((int)eAppointmentPart.GreenBackground, r));
if (category.Equals(Appointment.CategoryOrange))
return (_appointmentColor.BrushPart((int)eAppointmentPart.OrangeBackground, r));
if (category.Equals(Appointment.CategoryPurple))
return (_appointmentColor.BrushPart((int)eAppointmentPart.PurpleBackground, r));
if (category.Equals(Appointment.CategoryRed))
return (_appointmentColor.BrushPart((int)eAppointmentPart.RedBackground, r));
if (category.Equals(Appointment.CategoryYellow))
return (_appointmentColor.BrushPart((int)eAppointmentPart.YellowBackground, r));
}
return (_appointmentColor.BrushPart((int)eAppointmentPart.DefaultBackground, r));
}
#endregion
#region BorderColor
/// <summary>
/// Gets the border color for the Category
/// </summary>
protected Color BorderColor
{
get
{
string category = _Appointment.CategoryColor;
if (category != null)
{
// Check to see if we have any user defined
// AppointmentCategoryColors
if (_BaseView.CalendarView.HasCategoryColors == true)
{
AppointmentCategoryColor acc =
_BaseView.CalendarView.CategoryColors[category];
if (acc != null)
return (acc.BorderColor);
}
// Just use the default color set
if (category.Equals(Appointment.CategoryBlue))
return (_appointmentColor.GetColor((int)eAppointmentPart.BlueBorder));
if (category.Equals(Appointment.CategoryGreen))
return (_appointmentColor.GetColor((int)eAppointmentPart.GreenBorder));
if (category.Equals(Appointment.CategoryOrange))
return (_appointmentColor.GetColor((int)eAppointmentPart.OrangeBorder));
if (category.Equals(Appointment.CategoryPurple))
return (_appointmentColor.GetColor((int)eAppointmentPart.PurpleBorder));
if (category.Equals(Appointment.CategoryRed))
return (_appointmentColor.GetColor((int)eAppointmentPart.RedBorder));
if (category.Equals(Appointment.CategoryYellow))
return (_appointmentColor.GetColor((int)eAppointmentPart.YellowBorder));
}
return (_appointmentColor.GetColor((int)eAppointmentPart.DefaultBorder));
}
}
#endregion
#region BorderPen
/// <summary>
/// Gets the border pen
/// </summary>
protected Pen BorderPen
{
get
{
int n = (_BorderWidth > 0) ?
_BorderWidth : _BaseView.CalendarView.AppointmentBorderWidth;
return (new Pen(BorderColor, n));
}
}
#endregion
#region SelectedBorderPen
/// <summary>
/// Gets the selected border pen
/// </summary>
protected Pen SelectedBorderPen
{
get
{
int n = (_BorderWidth > 0) ?
_BorderWidth : _BaseView.CalendarView.AppointmentBorderWidth;
return (new Pen(Color.Black, n + 1));
}
}
#endregion
#region TextColor
/// <summary>
/// Gets the Text color for the Category
/// </summary>
protected Color TextColor
{
get
{
string category = _Appointment.CategoryColor;
// Check to see if we have any user defined
// AppointmentCategoryColors
if (category != null)
{
if (_BaseView.CalendarView.HasCategoryColors == true)
{
AppointmentCategoryColor acc =
_BaseView.CalendarView.CategoryColors[category];
if (acc != null)
return (acc.TextColor);
}
}
return (Color.Black);
}
}
#endregion
#region TimeMarkerBrush
/// <summary>
/// Gets the appointment TimeMarkerBrush
/// </summary>
/// <param name="r">Bounding rectangle</param>
/// <returns></returns>
protected Brush TimeMarkerBrush(Rectangle r)
{
string timeMarkedAs = _Appointment.TimeMarkedAs;
if (timeMarkedAs != null)
{
if (timeMarkedAs.StartsWith("#") == true)
return (new SolidBrush(ColorFactory.Empty.GetColor(timeMarkedAs.Substring(1))));
if (timeMarkedAs.Equals(Appointment.TimerMarkerFree))
return (_appointmentColor.BrushPart((int)eAppointmentPart.FreeTimeMarker, r));
if (timeMarkedAs.Equals(Appointment.TimerMarkerBusy))
return (_appointmentColor.BrushPart((int)eAppointmentPart.BusyTimeMarker, r));
if (timeMarkedAs.Equals(Appointment.TimerMarkerOutOfOffice))
return (_appointmentColor.BrushPart((int)eAppointmentPart.OutOfOfficeTimeMarker, r));
}
return (null);
}
#endregion
#endregion
}
}
#endif

View File

@@ -0,0 +1,527 @@
#if FRAMEWORK20
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
public class AppointmentWeekDayView : AppointmentView
{
#region Private variables
private DayColumn _DayColumn;
private AllDayPanel _AllDayPanel;
private eViewEnds _ViewEnds = eViewEnds.Complete;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseView"></param>
/// <param name="appointment"></param>
public AppointmentWeekDayView(BaseView baseView, Appointment appointment)
: base(baseView, appointment)
{
SetViewEnds();
}
#region Public properties
/// <summary>
/// Gets and sets View DayColumn
/// </summary>
public DayColumn DayColumn
{
get { return (_DayColumn); }
set { _DayColumn = value; }
}
/// <summary>
/// Gets and sets View AllDayPanel
/// </summary>
public AllDayPanel AllDayPanel
{
get { return (_AllDayPanel); }
set
{
if (_AllDayPanel != value)
{
_AllDayPanel = value;
SetViewEnds();
}
}
}
#endregion
#region Private properties
/// <summary>
/// Gets the default horizontal padding
/// </summary>
private int HorizontalPadding
{
get { return (6); }
}
/// <summary>
/// Gets whether the appointment is mutable
/// </summary>
private bool IsMutable
{
get
{
WeekDayView wv = (WeekDayView)BaseView;
return (IsSelected == true &&
wv.IsAllDayItem(this) == false &&
Appointment.Locked == false &&
Appointment.IsRecurringInstance == false);
}
}
#endregion
#region Start/End TimeChanged event handling
/// <summary>
/// Handles StartTime value changes
/// </summary>
/// <param name="sender">CalendarItem</param>
/// <param name="e">EventArgs</param>
protected override void AppointmentView_StartTimeChanged(object sender, EventArgs e)
{
base.AppointmentView_StartTimeChanged(sender, e);
SetViewEnds();
}
/// <summary>
/// Handles EndTime value changes
/// </summary>
/// <param name="sender">CalendarItem</param>
/// <param name="e">EventArgs</param>
protected override void AppointmentView_EndTimeChanged(object sender, EventArgs e)
{
base.AppointmentView_EndTimeChanged(sender, e);
SetViewEnds();
}
#endregion
#region SetViewEnds
/// <summary>
/// Sets the view display end types
/// </summary>
private void SetViewEnds()
{
if (_AllDayPanel != null)
{
_ViewEnds = eViewEnds.Complete;
int col, n;
DateTime start = GetDateCol(StartTime, out col, out n);
DateTime end = start.AddDays(n);
// Check to see if we can only display
// a partial representation for the view
if (col > 0 || start > StartTime)
_ViewEnds |= eViewEnds.PartialLeft;
TimeSpan ts = new TimeSpan(24, 0, 0);
if (end > EndTime || EndTime - end > ts)
_ViewEnds |= eViewEnds.PartialRight;
}
else
{
_ViewEnds = eViewEnds.PartialLeft | eViewEnds.PartialRight;
}
}
/// <summary>
/// Gets the initial starting DayColumn col and max col
/// for the given date
/// </summary>
/// <param name="selDate">Selection date</param>
/// <param name="col">Column</param>
/// <param name="n">Max col</param>
/// <returns></returns>
private DateTime GetDateCol(DateTime selDate, out int col, out int n)
{
DayColumn[] dayColumns = _AllDayPanel.WeekDayView.DayColumns;
// Loop through each column
col = 0;
n = 0;
for (int i = 0; i < dayColumns.Length; i++)
{
DateTime date = dayColumns[i].Date;
// If we have found our containing column, then
// calculate the absolute slice value and return it
if (date.Year >= selDate.Year ||
date.Month >= selDate.Month || date.Day >= selDate.Day)
{
col = i;
n = dayColumns.Length - col - 1;
return (date);
}
}
return (selDate);
}
#endregion
#region Appointment rendering
/// <summary>
/// Paint processing
/// </summary>
/// <param name="e">ItemPaintArgs</param>
public override void Paint(ItemPaintArgs e)
{
AppointmentColor.SetColorTable();
Rectangle r = GetViewRect();
if (r.Width > 1 && r.Height > 0)
{
if (EffectiveStyle == eDotNetBarStyle.Office2010 || StyleManager.IsMetro(EffectiveStyle))
DrawMetroAppointment(e, r);
else
DrawDefaultAppointment(e, r);
if (IsMutable == true)
DrawResizeHandles(e, r);
}
}
#region DrawDefaultAppointment
private void DrawDefaultAppointment(ItemPaintArgs e, Rectangle r)
{
Graphics g = e.Graphics;
int top = Math.Min(Math.Min(r.Width / 2, r.Height / 2), 5);
int bot = top;
if (DayColumn != null)
{
if (StartTime.Date < DayColumn.Date.Date)
top = 0;
if (EndTime.Date > DayColumn.Date.Date.AddDays(1))
bot = 0;
}
using (GraphicsPath path = DisplayHelp.GetRoundedRectanglePath(r, top, top, bot, bot))
{
using (Brush br = BackBrush(r))
g.FillPath(br, path);
if (BaseView.CalendarView.DoAppointmentViewPreRender(this, g, r, path) == false)
{
DrawContent(e, r);
BaseView.CalendarView.DoAppointmentViewPostRender(this, g, r, path);
}
DrawDefaultBorder(g, top, bot, r, path);
}
}
#region DrawDefaultBorder
private void DrawDefaultBorder(Graphics g,
int top, int bot, Rectangle r, GraphicsPath path)
{
DrawTimeMarker(g, r, top);
if (IsSelected == true)
{
using (Pen pen = SelectedBorderPen)
g.DrawPath(pen, path);
}
else
{
using (Pen pen = BorderPen)
g.DrawPath(pen, path);
}
}
#endregion
#endregion
#region DrawMetroAppointment
private void DrawMetroAppointment(ItemPaintArgs e, Rectangle r)
{
Graphics g = e.Graphics;
using (Brush br = BackBrush(r))
g.FillRectangle(br, r);
if (BaseView.CalendarView.DoAppointmentViewPreRender(this, g, r, null) == false)
{
DrawContent(e, r);
BaseView.CalendarView.DoAppointmentViewPostRender(this, g, r, null);
}
DrawMetroBorder(g, r);
}
#region DrawMetroBorder
private void DrawMetroBorder(Graphics g, Rectangle r)
{
DrawTimeMarker(g, r, 0);
if (IsSelected == true)
{
using (Pen pen = new Pen(Color.Black, 2))
g.DrawRectangle(pen, r);
}
else
{
using (Pen pen = BorderPen)
g.DrawRectangle(pen, r);
}
}
#endregion
#endregion
#region GetViewRect
/// <summary>
/// Gets the view rect for the appointment
/// </summary>
/// <returns>View rect</returns>
private Rectangle GetViewRect()
{
Rectangle r = DisplayRectangle;
if ((_ViewEnds & eViewEnds.PartialLeft) != eViewEnds.PartialLeft)
{
r.X += HorizontalPadding;
r.Width -= HorizontalPadding;
}
if ((_ViewEnds & eViewEnds.PartialRight) != eViewEnds.PartialRight)
r.Width -= HorizontalPadding;
// If the view is selected, then allow
// for a thicker selection rect
if (IsSelected == true && Appointment.IsMultiDayOrAllDayEvent == false)
r.Height -= 1;
return (r);
}
#endregion
#region DrawContent
/// <summary>
/// DrawContent
/// </summary>
/// <param name="e"></param>
/// <param name="r"></param>
private void DrawContent(ItemPaintArgs e, Rectangle r)
{
Image image = Image;
Rectangle rText = r;
rText.X += 4;
rText.Width -= 6;
if (Appointment.TimeMarkedAs != null)
{
rText.X += 4;
rText.Width -= 4;
}
Rectangle rImage = GetItemBounds(rText, ref rText, image);
DrawContentImage(e, r, rImage, image);
DrawContentText(e, rText);
}
#region DrawContentText
/// <summary>
/// Draws the content text
/// </summary>
/// <param name="e"></param>
/// <param name="r"></param>
private void DrawContentText(ItemPaintArgs e, Rectangle r)
{
Graphics g = e.Graphics;
if (DisplayTemplateText(e, r) == false)
{
string s = Appointment.Subject;
eTextFormat tf = eTextFormat.NoPadding | eTextFormat.NoPrefix;
WeekDayView wv = BaseView as WeekDayView;
if (wv != null && wv.IsAllDayItem(Appointment) == false)
{
s += "\n" + Appointment.Description;
r.Y += 3;
r.Height -= 3;
tf |= eTextFormat.WordBreak;
}
else
{
tf |= eTextFormat.VerticalCenter;
}
Font font = Font ?? e.Font;
if (r.Width > 4)
TextDrawing.DrawString(g, s, font, TextColor, r, tf);
Size size = TextDrawing.MeasureString(g, s, font, r.Width, tf);
IsTextClipped = (r.Width < size.Width || r.Height < size.Height);
}
}
#endregion
#endregion
#region DrawResizeHandles
/// <summary>
/// Draws the resize handles for the view
/// </summary>
/// <param name="e"></param>
/// <param name="r">View rectangle</param>
private void DrawResizeHandles(ItemPaintArgs e, Rectangle r)
{
if (r.Width > 6)
{
Graphics g = e.Graphics;
Rectangle r2 =
new Rectangle(r.X + (r.Width / 2) - 2, r.Y - 3, 5, 5);
if (DayColumn != null)
{
// Top handle
if (StartTime >= DayColumn.Date)
{
g.FillRectangle(Brushes.White, r2);
g.DrawRectangle(Pens.Black, r2);
}
// Bottom handle
if (EndTime <= DayColumn.Date.AddDays(1))
{
r2.Y = r.Bottom - 2;
g.FillRectangle(Brushes.White, r2);
g.DrawRectangle(Pens.Black, r2);
}
}
}
}
#endregion
#endregion
#region Mouse processing
#region MouseMove processing
/// <summary>
/// Handles mouseDown processing
/// </summary>
/// <param name="objArg">MouseEventArgs</param>
public override void InternalMouseMove(MouseEventArgs objArg)
{
HitArea = GetHitArea(objArg);
base.InternalMouseMove(objArg);
}
/// <summary>
/// Gets the HitArea from the current
/// mouse position
/// </summary>
/// <param name="objArg"></param>
/// <returns>eHitArea</returns>
private eHitArea GetHitArea(MouseEventArgs objArg)
{
if (IsMutable == true)
{
Rectangle r = GetViewRect();
Rectangle r2 =
new Rectangle(r.X + (r.Width / 2) - 7, r.Y - 7, 14, 14);
if (DayColumn != null)
{
// See if we are in the top resize area
if (StartTime >= DayColumn.Date)
{
if (r2.Contains(objArg.Location))
return (eHitArea.TopResize);
}
// See if we are in the bottom resize area
if (EndTime <= DayColumn.Date.AddDays(1))
{
r2.Y = r.Bottom - 10;
if (r2.Contains(objArg.Location))
return (eHitArea.BottomResize);
}
}
// By default we are in the move area
return (eHitArea.Move);
}
// No valid area to report
return (eHitArea.None);
}
#endregion
#endregion
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,420 @@
#if FRAMEWORK20
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
public class CalendarItem : PopupItem
{
#region enums
public enum eHitArea
{
None,
Move,
LeftResize,
RightResize,
TopResize,
BottomResize
}
#endregion
#region Events
/// <summary>
/// Occurs when CategoryColor has changed
/// </summary>
[Description("Occurs when the CategoryColor property has changed.")]
public event EventHandler<EventArgs> CategoryColorChanged;
/// <summary>
/// Occurs when StartTime has Changed
/// </summary>
public event EventHandler StartTimeChanged;
/// <summary>
/// Occurs when EndTime has Changed
/// </summary>
public event EventHandler EndTimeChanged;
/// <summary>
/// Occurs when IsSelected has Changed
/// </summary>
public event EventHandler IsSelectedChanged;
/// <summary>
/// Occurs when CollateId has Changed
/// </summary>
public event EventHandler CollateIdChanged;
#endregion
#region Private variables
private DateTime _StartTime; // Start time
private DateTime _EndTime; // End time
private string _CategoryColor; // CategoryColor
private int _CollateId = -1;
private object _ModelItem; // Model item
private object _RootItem; // Root model item
private bool _IsRecurring; // Is recurring
private bool _IsSelected; // Is selected
private eHitArea _HitArea = eHitArea.None;
private DateTime _LastMouseDown = DateTime.MinValue;
private uint _RefreshCount;
#endregion
/// <summary>
/// Constructor
/// </summary>
public CalendarItem()
{
// Set our default Model item
_ModelItem = this;
MouseUpNotification = true;
SetIsContainer(true);
}
#region Public properties
#region CollateId
/// <summary>
/// Gets or sets the CollateId used for TimeLine row collation.
/// </summary>
public virtual int CollateId
{
get { return (_CollateId); }
set
{
if (_CollateId != value)
{
_CollateId = value;
OnCollateIdChanged();
}
}
}
protected virtual void OnCollateIdChanged()
{
if (CollateIdChanged != null)
CollateIdChanged(this, new EventArgs());
this.Refresh();
}
#endregion
#region StartTime
/// <summary>
/// Gets or sets the CalendarItem Start time.
/// </summary>
public virtual DateTime StartTime
{
get { return (_StartTime); }
set
{
if (_StartTime != value)
{
_StartTime = value;
OnStartTimeChanged();
}
}
}
protected virtual void OnStartTimeChanged()
{
if (StartTimeChanged != null)
StartTimeChanged(this, new EventArgs());
this.Refresh();
}
#endregion
#region EndTime
/// <summary>
/// Gets or sets the CalendarItem End time.
/// </summary>
public virtual DateTime EndTime
{
get { return (_EndTime); }
set
{
if (_EndTime != value)
{
_EndTime = value;
OnEndTimeChanged();
}
}
}
protected virtual void OnEndTimeChanged()
{
if (EndTimeChanged != null)
EndTimeChanged(this, new EventArgs());
this.Refresh();
}
#endregion
#region CategoryColor
/// <summary>
/// Gets or sets the category color used for TimeLine CondensedView markers.
/// Use static members on Appointment class to assign the category color for example Appointment.CategoryRed.
/// </summary>
public virtual string CategoryColor
{
get { return (_CategoryColor); }
set
{
if (_CategoryColor == null || _CategoryColor.Equals(value) == false)
{
string oldValue = _CategoryColor;
_CategoryColor = value;
OnCategoryColorChanged(oldValue, value);
}
}
}
/// <summary>
/// Sends ChangedEvent for the CategoryColor property
/// </summary>
/// <param name="oldValue">Old CategoryColor</param>
/// <param name="newValue">New CategoryColor</param>
protected virtual void OnCategoryColorChanged(string oldValue, string newValue)
{
if (CategoryColorChanged != null)
CategoryColorChanged(this, new CategoryColorChangedEventArgs(oldValue, newValue));
}
#endregion
#region ModelItem
/// <summary>
/// Gets and sets the Model item
/// </summary>
public object ModelItem
{
get { return (_ModelItem); }
set { _ModelItem = value; }
}
#endregion
#region RootItem
/// <summary>
/// Gets and sets the Root Model item
/// </summary>
public object RootItem
{
get { return (_RootItem); }
set { _RootItem = value; }
}
#endregion
#region IsRecurring
/// <summary>
/// Gets and sets the IsRecurring item status
/// </summary>
public bool IsRecurring
{
get { return (_IsRecurring); }
set { _IsRecurring = value; }
}
#endregion
#region IsSelected
/// <summary>
/// Gets and sets the selection state
/// </summary>
public virtual bool IsSelected
{
get { return (_IsSelected); }
set
{
if (_IsSelected != value)
{
_IsSelected = value;
Control c = this.ContainerControl as Control;
if (c != null)
{
Rectangle r = Bounds;
r.Inflate(4, 4);
c.Invalidate(r);
}
Appointment ap = ModelItem as Appointment;
if (ap != null)
ap.IsSelected = value;
OnIsSelectedChanged();
}
}
}
private void OnIsSelectedChanged()
{
if (IsSelectedChanged != null)
IsSelectedChanged(this, new EventArgs());
}
#endregion
#region HitArea
/// <summary>
/// Gets and sets the last hit area
/// </summary>
public eHitArea HitArea
{
get { return (_HitArea); }
set { _HitArea = value; }
}
#endregion
#endregion
#region Internal properties
internal uint RefreshCount
{
get { return (_RefreshCount); }
set { _RefreshCount = value; }
}
#endregion
#region Mouse support
/// <summary>
/// Handles control MouseDown events
/// </summary>
/// <param name="objArg">MouseEventArgs</param>
public override void InternalMouseDown(MouseEventArgs objArg)
{
base.InternalMouseDown(objArg);
if (objArg.Button == MouseButtons.Left)
{
if (IsSimpleMouseDown())
this.IsSelected = true;
InternalMouseMove(objArg);
_LastMouseDown = DateTime.Now;
}
}
/// <summary>
/// Determines if it is a simple, single-click MouseDown
/// </summary>
/// <returns></returns>
private bool IsSimpleMouseDown()
{
return (_LastMouseDown == DateTime.MinValue ||
_LastMouseDown != DateTime.MinValue &&
DateTime.Now.Subtract(_LastMouseDown).TotalMilliseconds > SystemInformation.DoubleClickTime);
}
#endregion
#region RecalcSize
public override void RecalcSize()
{
}
#endregion
#region Paint
public override void Paint(ItemPaintArgs p)
{
}
#endregion
#region IsMarkupSupported
/// <summary>
/// IsMarkupSupported
/// </summary>
protected override bool IsMarkupSupported
{
get { return (true); }
}
#endregion
#region Copy object
/// <summary>
/// Returns copy of the item.
/// </summary>
public override BaseItem Copy()
{
CalendarItem objCopy = new CalendarItem();
CopyToItem(objCopy);
return (objCopy);
}
/// <summary>
/// Copies the CalendarItem specific properties to new instance of the item.
/// </summary>
/// <param name="copy">New CalendarItem instance</param>
protected override void CopyToItem(BaseItem copy)
{
CalendarItem objCopy = copy as CalendarItem;
if (objCopy != null)
{
base.CopyToItem(objCopy);
objCopy._StartTime = this._StartTime;
objCopy._EndTime = this._EndTime;
}
}
#endregion
}
}
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,112 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
namespace DevComponents.DotNetBar.Schedule
{
public class CalendarViewCollection<T> where T : BaseView
{
#region Private variables
private CalendarView _CalendarView; // Assoc CalendarView
private List<T> _Views = new List<T>(); // BaseView items
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="calendarView">CalendarView</param>
public CalendarViewCollection(CalendarView calendarView)
{
_CalendarView = calendarView;
}
#region Public properties
/// <summary>
/// Gets the count of items in the collection
/// </summary>
public int Count
{
get { return (_Views.Count); }
}
/// <summary>
/// Gets the view at the given index
/// </summary>
/// <param name="index">Index</param>
/// <returns>Requested view</returns>
public T this[int index]
{
get { return (GetView(index)); }
}
/// <summary>
/// Gets the view for the given DisplayedOwner
/// </summary>
/// <param name="key">DisplayedOwner</param>
/// <returns>Requested view</returns>
public T this[string key]
{
get { return (GetView(FindDisplayedOwner(key))); }
}
/// <summary>
/// Locates the view index from the given
/// DisplayedOwner text
/// </summary>
/// <param name="key">DisplayedOwner</param>
/// <returns>View index, or -1 if not found</returns>
private int FindDisplayedOwner(string key)
{
for (int i = 0; i < _CalendarView.DisplayedOwners.Count; i++)
{
if (_CalendarView.DisplayedOwners[i].Equals(key))
return (i);
}
return (-1);
}
/// <summary>
/// Returns the given view at the specified index.
///
/// This routine will initiate the creation
/// of the view if it has not previously been created.
/// </summary>
/// <param name="index">Index</param>
/// <returns>Requested view</returns>
private T GetView(int index)
{
if (index >= 0 && index < _Views.Count)
{
if (_Views[index] == null)
{
Type type = typeof(T);
_Views[index] = (T)_CalendarView.NewView(type, index);
}
return (_Views[index]);
}
return (default(T));
}
#endregion
#region Internal properties
/// <summary>
/// Gets the collection view list
/// </summary>
internal List<T> Views
{
get { return (_Views); }
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,142 @@
#if FRAMEWORK20
using System.Collections.ObjectModel;
namespace DevComponents.DotNetBar.Schedule
{
public class DisplayedOwnerCollection : Collection<string>
{
#region Private variables
private CalendarView _CalendarView; // Assoc CalendarView
private bool _IsRangeSet; // Range set flag
private bool _SuspendUpdate;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="calendarView">CalendarView</param>
public DisplayedOwnerCollection(CalendarView calendarView)
{
_CalendarView = calendarView;
}
#region Internal properties
/// <summary>
/// Gets and sets the SuspendUpdate state
/// </summary>
internal bool SuspendUpdate
{
get { return (_SuspendUpdate); }
set { _SuspendUpdate = value; }
}
#endregion
#region AddRange
/// <summary>
/// Adds a range of Owners to the DisplayedOwner collection
/// </summary>
/// <param name="items">Array of Owners to add</param>
public void AddRange(string[] items)
{
int index = Count;
try
{
_IsRangeSet = true;
for (int i = 0; i < items.Length; i++)
Add(items[i]);
}
finally
{
_IsRangeSet = false;
_CalendarView.DisplayedOwnersAdded(index);
}
}
#endregion
#region RemoveItem
/// <summary>
/// Processes list RemoveItem calls
/// </summary>
/// <param name="index">Index to remove</param>
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
if (_SuspendUpdate == false)
_CalendarView.DisplayedOwnersRemoved(index, index + 1);
}
#endregion
#region InsertItem
/// <summary>
/// Processes list InsertItem calls
/// </summary>
/// <param name="index">Index to add</param>
/// <param name="item">Text to add</param>
protected override void InsertItem(int index, string item)
{
if (string.IsNullOrEmpty(item) == false)
{
base.InsertItem(index, item);
if (_SuspendUpdate == false)
{
if (_IsRangeSet == false)
_CalendarView.DisplayedOwnersAdded(index);
}
}
}
#endregion
#region SetItem
/// <summary>
/// Processes list SetItem calls (e.g. replace)
/// </summary>
/// <param name="index">Index to replace</param>
/// <param name="newItem">Text to replace</param>
protected override void SetItem(int index, string newItem)
{
base.SetItem(index, newItem);
if (_SuspendUpdate == false)
_CalendarView.DisplayedOwnersSet(index);
}
#endregion
#region ClearItems
/// <summary>
/// Processes list Clear calls (e.g. remove all)
/// </summary>
protected override void ClearItems()
{
if (Count > 0)
{
int n = Count;
base.ClearItems();
_CalendarView.DisplayedOwnersRemoved(0, n);
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,916 @@
using System;
using System.Collections.ObjectModel;
using System.Drawing;
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
/// <summary>
/// ViewDisplayCustomizations
/// </summary>
public class ViewDisplayCustomizations
{
#region Events
/// <summary>
/// Occurs when the ViewDisplayCustomizations have changed
/// </summary>
public event EventHandler<EventArgs> CollectionChanged;
#endregion
#region Private variables
private CalendarView _CalendarView;
private DaySlotBackgrounds _DaySlotBackgrounds;
#endregion
/// <summary>
/// ViewDisplayCustomizations
/// </summary>
/// <param name="calendarView"></param>
public ViewDisplayCustomizations(CalendarView calendarView)
{
_CalendarView = calendarView;
}
#region Public properties
/// <summary>
/// DaySlotBackgrounds
/// </summary>
public DaySlotBackgrounds DaySlotBackgrounds
{
get
{
if (_DaySlotBackgrounds == null)
{
_DaySlotBackgrounds = new DaySlotBackgrounds();
_DaySlotBackgrounds.CollectionChanged += _DaySlotBackgrounds_CollectionChanged;
}
return (_DaySlotBackgrounds);
}
set
{
if (_DaySlotBackgrounds != null)
_DaySlotBackgrounds.CollectionChanged -= _DaySlotBackgrounds_CollectionChanged;
_DaySlotBackgrounds = value;
if (_DaySlotBackgrounds != null)
_DaySlotBackgrounds.CollectionChanged += _DaySlotBackgrounds_CollectionChanged;
}
}
#endregion
#region Event handling
/// <summary>
/// Handles DaySlotBackgrounds CollectionChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _DaySlotBackgrounds_CollectionChanged(object sender, EventArgs e)
{
_CalendarView.Refresh();
if (CollectionChanged != null)
CollectionChanged(this, EventArgs.Empty);
}
#endregion
#region GetDaySlotAppearance
/// <summary>
/// Retrieves the DaySlotAppearance from the given criteris
/// </summary>
/// <param name="ownerKey"></param>
/// <param name="dateTime"></param>
/// <param name="wkStart"></param>
/// <param name="wkEnd"></param>
/// <returns></returns>
internal DaySlotAppearance GetDaySlotAppearance(
string ownerKey, DateTime dateTime, WorkTime wkStart, WorkTime wkEnd)
{
foreach (DaySlotBackground dsb in DaySlotBackgrounds)
{
if (IsValidSlot(dsb, dateTime, wkStart, wkEnd) == true)
{
if (IsValidOwner(dsb, ownerKey) == true)
return (dsb.Appearance);
}
}
return (null);
}
#endregion
#region IsValidSlot
/// <summary>
/// Determines if the given slot is a valid
/// day and time slot
/// </summary>
/// <param name="dsb"></param>
/// <param name="dateTime"></param>
/// <param name="wkStart"></param>
/// <param name="wkEnd"></param>
/// <returns></returns>
private bool IsValidSlot(DaySlotBackground dsb,
DateTime dateTime, WorkTime wkStart, WorkTime wkEnd)
{
if (IsValidDaySlot(dsb, dateTime) == true)
return (IsValidTimeSlot(dsb, wkStart, wkEnd));
return (false);
}
#endregion
#region IsValidTimeSlot
/// <summary>
/// Determines if the given slot is a valid time slot
/// </summary>
/// <param name="dsb"></param>
/// <param name="wkStart"></param>
/// <param name="wkEnd"></param>
/// <returns></returns>
private bool IsValidTimeSlot(DaySlotBackground dsb, WorkTime wkStart, WorkTime wkEnd)
{
return (wkStart < dsb.Appearance.EndTime && wkEnd > dsb.Appearance.StartTime);
}
#endregion
#region IsValidDaySlot
/// <summary>
/// Determines if the given slot is a valid time slot
/// </summary>
/// <param name="dsb"></param>
/// <param name="dateTime"></param>
/// <returns></returns>
private bool IsValidDaySlot(DaySlotBackground dsb, DateTime dateTime)
{
if (dsb.DateTime == DateTime.MinValue)
return (dsb.DayOfWeek == dateTime.DayOfWeek);
return (dsb.DateTime.Date == dateTime.Date);
}
#endregion
#region IsValidOwner
/// <summary>
/// Determines if the given owner key is valid for the slot
/// </summary>
/// <param name="dsb"></param>
/// <param name="ownerKey"></param>
/// <returns></returns>
private bool IsValidOwner(DaySlotBackground dsb, string ownerKey)
{
if (dsb.HasOwnerKeys == true)
{
if (dsb.OwnerKeys.Contains("") == true)
return (true);
if (dsb.OwnerKeys.Contains(ownerKey) == false)
return (false);
}
return (true);
}
#endregion
}
/// <summary>
/// DaySlotBackgrounds
/// </summary>
public class DaySlotBackgrounds : Collection<DaySlotBackground>
{
#region Events
/// <summary>
/// Occurs when the DaySlotBackgrounds collection changes
/// </summary>
public event EventHandler<EventArgs> CollectionChanged;
#endregion
#region Private variables
private bool _IsRangeSet;
private bool _SuspendUpdate;
#endregion
#region Internal properties
/// <summary>
/// Gets and sets the SuspendUpdate state
/// </summary>
internal bool SuspendUpdate
{
get { return (_SuspendUpdate); }
set { _SuspendUpdate = value; }
}
#endregion
#region Remove
/// <summary>
/// Removes the DaySlotBackground for the given DateTime
/// </summary>
/// <param name="dateTime"></param>
public void Remove(DateTime dateTime)
{
int n = Items.Count;
try
{
SuspendUpdate = true;
for (int i = Items.Count - 1; i >= 0; i--)
{
DaySlotBackground dsb = Items[i];
if (dsb.DateTime.Equals(dateTime) == true)
RemoveAt(i);
}
}
finally
{
SuspendUpdate = false;
if (Items.Count != n)
OnCollectionChanged();
}
}
/// <summary>
/// Removes the DaySlotBackground for the given DayOfWeek
/// </summary>
/// <param name="dayOfWeek"></param>
public void Remove(DayOfWeek dayOfWeek)
{
int n = Items.Count;
try
{
SuspendUpdate = true;
for (int i = Items.Count - 1; i >= 0; i--)
{
DaySlotBackground dsb = Items[i];
if (dsb.DateTime.Equals(DateTime.MinValue) == true)
{
if (dsb.DayOfWeek == dayOfWeek)
RemoveAt(i);
}
}
}
finally
{
SuspendUpdate = false;
if (Items.Count != n)
OnCollectionChanged();
}
}
#endregion
#region AddRange
/// <summary>
/// Adds a range of DaySlotBackgrounds
/// </summary>
/// <param name="daySlotBackgrounds"></param>
public void AddRange(DaySlotBackgrounds daySlotBackgrounds)
{
try
{
_IsRangeSet = true;
foreach (DaySlotBackground dsb in daySlotBackgrounds)
Add(dsb);
}
finally
{
_IsRangeSet = false;
OnCollectionChanged();
}
}
#endregion
#region RemoveItem
/// <summary>
/// Processes list RemoveItem calls
/// </summary>
/// <param name="index">Index to remove</param>
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
OnCollectionChanged();
}
#endregion
#region InsertItem
/// <summary>
/// Processes list InsertItem calls
/// </summary>
/// <param name="index">Index to add</param>
/// <param name="item">Text to add</param>
protected override void InsertItem(int index, DaySlotBackground item)
{
if (item != null)
{
base.InsertItem(index, item);
item.DaySlotBackgrounds = this;
OnCollectionChanged();
}
}
#endregion
#region SetItem
/// <summary>
/// Processes list SetItem calls (e.g. replace)
/// </summary>
/// <param name="index">Index to replace</param>
/// <param name="newItem">Text to replace</param>
protected override void SetItem(int index, DaySlotBackground newItem)
{
base.SetItem(index, newItem);
newItem.DaySlotBackgrounds = this;
OnCollectionChanged();
}
#endregion
#region ClearItems
/// <summary>
/// Processes list Clear calls (e.g. remove all)
/// </summary>
protected override void ClearItems()
{
if (Count > 0)
{
base.ClearItems();
OnCollectionChanged();
}
}
#endregion
#region OnCollectionChanged
/// <summary>
/// Handles collection change notification
/// </summary>
private void OnCollectionChanged()
{
if (_SuspendUpdate == false && _IsRangeSet == false)
{
if (CollectionChanged != null)
CollectionChanged(this, EventArgs.Empty);
}
}
#endregion
}
/// <summary>
/// DaySlotBackground
/// </summary>
public class DaySlotBackground
{
#region Events
/// <summary>
/// Occurs when the DaySlotBackground collection changes
/// </summary>
public event EventHandler<EventArgs> CollectionChanged;
#endregion
#region Private variables
private DayOfWeek _DayOfWeek;
private DateTime _DateTime = DateTime.MinValue;
private DaySlotAppearance _Appearance;
private DaySlotBackgrounds _DaySlotBackgrounds;
private OwnerKeyCollection _OwnerKeys;
#endregion
#region Constructors
public DaySlotBackground(DateTime dateTime, DaySlotAppearance appearance)
{
_DateTime = dateTime;
_Appearance = appearance;
}
public DaySlotBackground(DayOfWeek dayOfWeek, DaySlotAppearance appearance)
{
_DayOfWeek = dayOfWeek;
_DateTime = DateTime.MinValue;
_Appearance = appearance;
}
#endregion
#region Public properties
#region Appearance
/// <summary>
/// Gets or sets the Appearance
/// </summary>
public DaySlotAppearance Appearance
{
get { return (_Appearance); }
set
{
_Appearance = value;
OnCollectionChanged();
}
}
#endregion
#region DateTime
/// <summary>
/// Gets or sets the DateTime
/// </summary>
public DateTime DateTime
{
get { return (_DateTime); }
set
{
if (_DateTime != value)
{
_DateTime = value;
OnCollectionChanged();
}
}
}
#endregion
#region DayOfWeek
/// <summary>
/// Gets or sets the DayOfWeek
/// </summary>
public DayOfWeek DayOfWeek
{
get { return (_DayOfWeek); }
set
{
if (_DayOfWeek != value)
{
_DayOfWeek = value;
OnCollectionChanged();
}
}
}
#endregion
#region OwnerKeys
/// <summary>
/// Gets or sets the OwnerKeyCollection
/// </summary>
public OwnerKeyCollection OwnerKeys
{
get
{
if (_OwnerKeys == null)
{
_OwnerKeys = new OwnerKeyCollection();
_OwnerKeys.CollectionChanged += OwnerKeys_CollectionChanged;
}
return (_OwnerKeys);
}
set
{
if (_OwnerKeys != null)
_OwnerKeys.CollectionChanged -= OwnerKeys_CollectionChanged;
_OwnerKeys = value;
if (_OwnerKeys != null)
_OwnerKeys.CollectionChanged += OwnerKeys_CollectionChanged;
}
}
#endregion
#endregion
#region Internal properties
#region DaySlotBackgrounds
/// <summary>
/// Gets or sets the DaySlotBackgrounds
/// </summary>
internal DaySlotBackgrounds DaySlotBackgrounds
{
get { return (_DaySlotBackgrounds); }
set
{
_DaySlotBackgrounds = value;
OnCollectionChanged();
}
}
#endregion
#region HasOwnerKeys
/// <summary>
/// HasOwnerKeys
/// </summary>
internal bool HasOwnerKeys
{
get { return (_OwnerKeys != null && _OwnerKeys.Count > 0); }
}
#endregion
#endregion
#region Event processing
/// <summary>
/// Processes OwnerKeys_CollectionChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OwnerKeys_CollectionChanged(object sender, EventArgs e)
{
OnCollectionChanged();
}
#endregion
#region OnCollectionChanged
/// <summary>
/// Handles collection change notification
/// </summary>
private void OnCollectionChanged()
{
if (CollectionChanged != null)
CollectionChanged(this, EventArgs.Empty);
}
#endregion
}
/// <summary>
/// DaySlotAppearance
/// </summary>
public class DaySlotAppearance
{
#region Private variables
private WorkTime _StartTime;
private WorkTime _EndTime;
private Color _BackColor;
private Color _HourBorderColor;
private Color _HalfHourBorderColor;
private string _Text;
private ContentAlignment _TextAlignment;
private Color _TextColor;
private Color _SelectedTextColor;
private Font _Font;
private bool _OnTop;
private bool _ShowTextWhenSelected = true;
#endregion
#region Constructors
public DaySlotAppearance(WorkTime startTime, WorkTime endTime,
Color backColor, Color hourBorderColor, Color halfHourBorderColor)
{
_StartTime = startTime;
_EndTime = endTime;
_BackColor = backColor;
_HourBorderColor = hourBorderColor;
_HalfHourBorderColor = halfHourBorderColor;
}
public DaySlotAppearance(int startHour, int startMinute,
int endHour, int endMinute, Color backColor, Color hourBorderColor, Color halfHourBorderColor)
: this(new WorkTime(startHour, startMinute), new WorkTime(endHour, endMinute), backColor, hourBorderColor, halfHourBorderColor)
{
}
#endregion
#region Public properties
#region BackColor
/// <summary>
/// Gets or sets the BackColor
/// </summary>
public Color BackColor
{
get { return (_BackColor); }
set { _BackColor = value; }
}
#endregion
#region EndTime
/// <summary>
/// Gets or sets the Appearance end time
/// </summary>
public WorkTime EndTime
{
get { return (_EndTime); }
set { _EndTime = value; }
}
#endregion
#region Font
/// <summary>
/// Gets or sets the DaySlot Font
/// </summary>
public Font Font
{
get { return (_Font); }
set { _Font = value; }
}
#endregion
#region HalfHourBorderColor
/// <summary>
/// Gets or sets the HalfHourBorderColor
/// </summary>
public Color HalfHourBorderColor
{
get { return (_HalfHourBorderColor); }
set { _HalfHourBorderColor = value; }
}
#endregion
#region HourBorderColor
/// <summary>
/// Gets or sets the HourBorderColor
/// </summary>
public Color HourBorderColor
{
get { return (_HourBorderColor); }
set { _HourBorderColor = value; }
}
#endregion
#region OnTop
/// <summary>
/// Gets or sets whether the Text is on top of the borders
/// </summary>
public bool OnTop
{
get { return (_OnTop); }
set { _OnTop = value; }
}
#endregion
#region StartTime
/// <summary>
/// Gets or sets the Appearance start time
/// </summary>
public WorkTime StartTime
{
get { return (_StartTime); }
set { _StartTime = value; }
}
#endregion
#region Text
/// <summary>
/// Gets or sets the Text
/// </summary>
public string Text
{
get { return (_Text); }
set { _Text = value; }
}
#endregion
#region TextAlignment
/// <summary>
/// Gets or sets the Text Alignment
/// </summary>
public ContentAlignment TextAlignment
{
get { return (_TextAlignment); }
set { _TextAlignment = value; }
}
#endregion
#region TextColor
/// <summary>
/// Gets or sets the Text Color
/// </summary>
public Color TextColor
{
get { return (_TextColor); }
set { _TextColor = value; }
}
#endregion
#region SelectedTextColor
/// <summary>
/// Gets or sets the Selected Text Color
/// </summary>
public Color SelectedTextColor
{
get { return (_SelectedTextColor); }
set { _SelectedTextColor = value; }
}
#endregion
#region ShowTextWhenSelected
/// <summary>
/// Gets or sets wheter the Text is displayed when cells are selected
/// </summary>
public bool ShowTextWhenSelected
{
get { return (_ShowTextWhenSelected); }
set { _ShowTextWhenSelected = value; }
}
#endregion
#endregion
}
/// <summary>
/// OwnerKeyCollection
/// </summary>
public class OwnerKeyCollection : Collection<string>
{
#region Events
/// <summary>
/// Occurs when the OwnerKeyCollection changes
/// </summary>
public event EventHandler<EventArgs> CollectionChanged;
#endregion
#region RemoveItem
/// <summary>
/// Processes list RemoveItem calls
/// </summary>
/// <param name="index">Index to remove</param>
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
OnCollectionChanged();
}
#endregion
#region InsertItem
/// <summary>
/// Processes list InsertItem calls
/// </summary>
/// <param name="index">Index to add</param>
/// <param name="item">Text to add</param>
protected override void InsertItem(int index, string item)
{
if (item != null)
{
base.InsertItem(index, item);
OnCollectionChanged();
}
}
#endregion
#region SetItem
/// <summary>
/// Processes list SetItem calls (e.g. replace)
/// </summary>
/// <param name="index">Index to replace</param>
/// <param name="newItem">Text to replace</param>
protected override void SetItem(int index, string newItem)
{
base.SetItem(index, newItem);
OnCollectionChanged();
}
#endregion
#region ClearItems
/// <summary>
/// Processes list Clear calls (e.g. remove all)
/// </summary>
protected override void ClearItems()
{
if (Count > 0)
{
base.ClearItems();
OnCollectionChanged();
}
}
#endregion
#region OnCollectionChanged
/// <summary>
/// Handles collection change notification
/// </summary>
private void OnCollectionChanged()
{
if (CollectionChanged != null)
CollectionChanged(this, EventArgs.Empty);
}
#endregion
}
}

View File

@@ -0,0 +1,149 @@
#if FRAMEWORK20
using System;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.DotNetBar.Schedule
{
public class AppointmentCategoryColor
{
#region Events
/// <summary>
/// Occurs when AppointmentCategoryColorCollection has changed
/// </summary>
[Description("Occurs when the AppointmentCategoryColorCollection has changed.")]
public event EventHandler<EventArgs> AppointmentCategoryColorChanged;
#endregion
#region Private variables
private string _ColorName;
private Color _TextColor;
private Color _BorderColor;
private ColorDef _BackColor;
#endregion
/// <summary>
/// AppointmentCategoryColor
/// </summary>
/// <param name="colorName">Color name</param>
/// <param name="textColor">Text Color</param>
/// <param name="borderColor">Border Color</param>
/// <param name="backColor">Background Color</param>
public AppointmentCategoryColor(string colorName,
Color textColor, Color borderColor, ColorDef backColor)
{
_ColorName = colorName;
_TextColor = textColor;
_BorderColor = borderColor;
_BackColor = backColor;
}
/// <summary>
/// AppointmentCategoryColor
/// </summary>
/// <param name="colorName">Color name</param>
public AppointmentCategoryColor(string colorName)
: this(colorName, Color.Black, Color.Black, new ColorDef(Color.White))
{
}
#region Public properties
#region ColorName
/// <summary>
/// Color name
/// </summary>
public string ColorName
{
get { return (_ColorName); }
internal set { _ColorName = value; }
}
#endregion
#region TextColor
/// <summary>
/// Text Color
/// </summary>
public Color TextColor
{
get { return (_TextColor); }
set
{
if (_TextColor != value)
{
_TextColor = value;
OnAppointmentCategoryColorChanged();
}
}
}
#endregion
#region BorderColor
/// <summary>
/// Border Color
/// </summary>
public Color BorderColor
{
get { return (_BorderColor); }
set
{
if (_BorderColor != value)
{
_BorderColor = value;
OnAppointmentCategoryColorChanged();
}
}
}
#endregion
#region BackColor
/// <summary>
/// Background Color
/// </summary>
public ColorDef BackColor
{
get { return (_BackColor); }
set
{
if (_BackColor != value)
{
_BackColor = value;
OnAppointmentCategoryColorChanged();
}
}
}
#endregion
#endregion
#region OnAppointmentCategoryColorChanged
private void OnAppointmentCategoryColorChanged()
{
if (AppointmentCategoryColorChanged != null)
AppointmentCategoryColorChanged(this, EventArgs.Empty);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,178 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace DevComponents.DotNetBar.Schedule
{
public class AppointmentCategoryColorCollection
{
#region Events
/// <summary>
/// Occurs when AppointmentCategoryColorCollection has changed
/// </summary>
[Description("Occurs when the AppointmentCategoryColorCollection has changed.")]
public event EventHandler<EventArgs> AppointmentCategoryColorCollectionChanged;
#endregion
#region Private variables
private Dictionary<string, AppointmentCategoryColor> _List;
#endregion
/// <summary>
/// AppointmentCategoryColorCollection
/// </summary>
public AppointmentCategoryColorCollection()
{
_List = new Dictionary<string, AppointmentCategoryColor>();
}
#region Public properties
/// <summary>
/// Gets the Count of items defined
/// </summary>
public int Count
{
get { return (_List.Count); }
}
#endregion
#region Add
/// <summary>
/// Adds a AppointmentCategoryColor to the collection
/// </summary>
/// <param name="acc"></param>
public void Add(AppointmentCategoryColor acc)
{
_List[acc.ColorName] = acc;
acc.AppointmentCategoryColorChanged += CategoryColorChanged;
OnAppointmentCategoryColorCollectionChanged();
}
#endregion
#region Remove
/// <summary>
/// Removes an entry from the collection, by color name
/// </summary>
/// <param name="colorName">Color name</param>
public void Remove(string colorName)
{
if (_List.ContainsKey(colorName))
{
_List[colorName].AppointmentCategoryColorChanged -= CategoryColorChanged;
_List.Remove(colorName);
OnAppointmentCategoryColorCollectionChanged();
}
}
/// <summary>
/// Removes an entry from the collection, by AppointmentCategoryColor
/// </summary>
/// <param name="categoryColor">AppointmentCategoryColor</param>
public void Remove(AppointmentCategoryColor categoryColor)
{
Remove(categoryColor.ColorName);
}
#endregion
#region Clear
/// <summary>
/// Clears the AppointmentCategoryColor collection
/// </summary>
public void Clear()
{
foreach (AppointmentCategoryColor ac in _List.Values)
ac.AppointmentCategoryColorChanged -= CategoryColorChanged;
_List.Clear();
OnAppointmentCategoryColorCollectionChanged();
}
#endregion
#region Items
/// <summary>
/// Gets the entire list of added AppointmentCategoryColor items
/// </summary>
public AppointmentCategoryColor[] Items
{
get
{
AppointmentCategoryColor[] items = new AppointmentCategoryColor[_List.Count];
_List.Values.CopyTo(items, 0);
return (items);
}
}
#endregion
#region this
/// <summary>
/// Gets the AppointmentCategoryColor from the given
/// color name string index
/// </summary>
/// <param name="colorName"></param>
/// <returns></returns>
public AppointmentCategoryColor this[string colorName]
{
get
{
AppointmentCategoryColor acc;
_List.TryGetValue(colorName, out acc);
return (acc);
}
}
#endregion
#region CategoryColorChanged
/// <summary>
/// CategoryColorChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CategoryColorChanged(object sender, EventArgs e)
{
OnAppointmentCategoryColorCollectionChanged();
}
#endregion
#region OnAppointmentCategoryColorCollectionChanged
/// <summary>
/// OnAppointmentCategoryColorCollectionChanged
/// </summary>
private void OnAppointmentCategoryColorCollectionChanged()
{
if (AppointmentCategoryColorCollectionChanged != null)
AppointmentCategoryColorCollectionChanged(this, EventArgs.Empty);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,121 @@
#if FRAMEWORK20
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.DotNetBar.Schedule
{
#region enum definitions
/// <summary>
/// Appointment parts enum
/// </summary>
public enum eAppointmentPart
{
DefaultBorder,
DefaultBackground,
BlueBorder,
BlueBackground,
GreenBorder,
GreenBackground,
OrangeBorder,
OrangeBackground,
PurpleBorder,
PurpleBackground,
RedBorder,
RedBackground,
YellowBorder,
YellowBackground,
BusyTimeMarker,
FreeTimeMarker,
OutOfOfficeTimeMarker
}
#endregion
public class AppointmentColor : CalendarColor
{
/// <summary>
/// Constructor
/// </summary>
public AppointmentColor()
: base(eCalendarColor.Automatic)
{
}
#region SetColorTable routine
/// <summary>
/// Sets our current color table to either
/// a local or global definition
/// </summary>
public override void SetColorTable()
{
// Use the globally set color table
Office2007Renderer r =
GlobalManager.Renderer as Office2007Renderer;
ColorTable = (r != null)
? r.ColorTable.CalendarView.AppointmentColors
: _LocalColorTable;
}
#endregion
#region Static Color definitions
// Array of predefined colors
static ColorDef[] _LocalColorTable = new ColorDef[]
{
new ColorDef(0x4B71A2), // DefaultBorder
new ColorDef(new int[] {0xFDFEFF, 0xC1D3EA}, // DefaultBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x28518E), // BlueBorder
new ColorDef(new int[] {0xB1C5EC, 0x759DDA}, // BlueBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x2C6524), // GreenBorder
new ColorDef(new int[] {0xC2E8BC, 0x84D17B}, // GreenBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x8B3E0A), // OrangeBorder
new ColorDef(new int[] {0xF9C7A0, 0xF49758}, // OrangeBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x3E2771), // PurpleBorder
new ColorDef(new int[] {0xC5B5E6, 0x957BD2}, // PurpleBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x86171C), // RedBorder
new ColorDef(new int[] {0xF1AAAC, 0xE5676E}, // RedBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x7C7814), // YellowBorder
new ColorDef(new int[] {0xFFFCAA, 0xFFF958}, // YellowBackground
new float[] {0f, 1f}, 90f),
new ColorDef(-1), // BusyTimeMarker
new ColorDef(0xFFFFFF), // FreeTimeMarker
new ColorDef(0x800080), // OutOfOfficeTimeMarker
};
#endregion
}
}
#endif

View File

@@ -0,0 +1,439 @@
#if FRAMEWORK20
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.DotNetBar.Schedule
{
//#region ColorDef
///// <summary>
///// Color definition class
///// </summary>
//[TypeConverter(typeof(ColorDefConvertor))]
//public class ColorDef
//{
// #region Events
// /// <summary>
// /// Event raised when the SuperTabColorStates is changed
// /// </summary>
// [Description("Event raised when the ColorDef is changed")]
// public event EventHandler<EventArgs> ColorDefChanged;
// #endregion
// #region Private variables
// private Color[] _Colors; // Color values
// private float[] _Positions; // Gradient color positions
// private float _Angle; // Gradient angle
// #endregion
// #region Constructors
// public ColorDef()
// {
// }
// /// <summary>
// /// Constructor - solid def
// /// </summary>
// /// <param name="rgb">RGB value</param>
// public ColorDef(int rgb)
// : this(ColorScheme.GetColor(rgb))
// {
// }
// /// <summary>
// /// Constructor - solid def
// /// </summary>
// /// <param name="color">Color</param>
// public ColorDef(Color color)
// {
// _Colors = new Color[1];
// _Colors[0] = color;
// _Positions = null;
// }
// /// <summary>
// /// Constructor - 2 color def
// /// </summary>
// /// <param name="start">Start Color</param>
// /// <param name="end">End Color</param>
// public ColorDef(Color start, Color end)
// : this(start, end, 90f)
// {
// }
// /// <summary>
// /// Constructor - 2 color def
// /// </summary>
// /// <param name="start">Start Color</param>
// /// <param name="end">End Color</param>
// /// <param name="angle">Gradient angle</param>
// public ColorDef(Color start, Color end, float angle)
// {
// _Colors = new Color[] { start, end };
// _Positions = new float[] { 0, 1 };
// _Angle = angle;
// }
// /// <summary>
// /// Constructor - Gradient def
// /// </summary>
// /// <param name="rgbs">Array of RGB values</param>
// /// <param name="cPositions">Gradient positions</param>
// public ColorDef(int[] rgbs, float[] cPositions)
// : this(rgbs, cPositions, 90f)
// {
// }
// /// <summary>
// /// Constructor - Gradient def
// /// </summary>
// /// <param name="colors">Array of Color values</param>
// /// <param name="cPositions">Gradient positions</param>
// public ColorDef(Color[] colors, float[] cPositions)
// : this(colors, cPositions, 90f)
// {
// }
// /// <summary>
// /// Constructor - Gradient def
// /// </summary>
// /// <param name="rgbs">Array of RGB values</param>
// /// <param name="cPositions">Gradient positions</param>
// /// <param name="angle">Gradient angle</param>
// public ColorDef(int[] rgbs, float[] cPositions, float angle)
// {
// _Colors = new Color[rgbs.Length];
// for (int i = 0; i < rgbs.Length; i++)
// _Colors[i] = ColorScheme.GetColor(rgbs[i]);
// _Positions = cPositions;
// _Angle = angle;
// }
// /// <summary>
// /// Constructor - Gradient def
// /// </summary>
// /// <param name="colors">Array of Color values</param>
// /// <param name="cPositions">Gradient positions</param>
// /// <param name="angle">Gradient angle</param>
// public ColorDef(Color[] colors, float[] cPositions, float angle)
// {
// _Colors = colors;
// _Positions = cPositions;
// _Angle = angle;
// }
// #endregion
// #region Public properties
// #region Colors
// /// <summary>
// /// Gets or sets the Color array
// /// </summary>
// [Browsable(true), DefaultValue(null)]
// [NotifyParentProperty(true)]
// [Description("Indicates the Color array")]
// public Color[] Colors
// {
// get { return (_Colors); }
// set { _Colors = value; OnColorDefChanged(); }
// }
// #endregion
// #region Positions
// /// <summary>
// /// Gets or sets the Color Positions
// /// </summary>
// [Browsable(true), DefaultValue(null)]
// [NotifyParentProperty(true)]
// [Description("Indicates the Color Positions.")]
// public float[] Positions
// {
// get { return (_Positions); }
// set { _Positions = value; OnColorDefChanged(); }
// }
// #endregion
// #region Angle
// /// <summary>
// /// Gets or sets the Gradient Angle
// /// </summary>
// [Browsable(true), DefaultValue(0f)]
// [NotifyParentProperty(true)]
// [Description("Indicates the Gradient Angle.")]
// public float Angle
// {
// get { return (_Angle); }
// set { _Angle = value; OnColorDefChanged(); }
// }
// #endregion
// #region IsEmpty
// /// <summary>
// /// IsEmpty
// /// </summary>
// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
// public bool IsEmpty
// {
// get { return (_Colors == null ||
// _Colors.Length == 1 && _Colors[0].IsEmpty); }
// }
// #endregion
// #endregion
// #region OnColorDefChanged
// /// <summary>
// /// OnColorDefChanged
// /// </summary>
// private void OnColorDefChanged()
// {
// if (ColorDefChanged != null)
// ColorDefChanged(this, EventArgs.Empty);
// }
// #endregion
//}
//#region ColorDefConvertor
///// <summary>
///// ColorDefConvertor
///// </summary>
//public class ColorDefConvertor : ExpandableObjectConverter
//{
// public override object ConvertTo(
// ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
// {
// if (destinationType == typeof(string))
// {
// ColorDef cd = value as ColorDef;
// if (cd != null)
// {
// ColorConverter cvt = new ColorConverter();
// if (cd.Colors != null)
// {
// if (cd.Colors[0] != Color.Empty)
// return (cvt.ConvertToString(cd.Colors[0]));
// if (cd.Colors.Length > 1 && cd.Colors[1] != Color.Empty)
// return (cvt.ConvertToString(cd.Colors[1]));
// }
// if (cd.Angle != 0)
// return (cd.Angle.ToString());
// }
// return (String.Empty);
// }
// return (base.ConvertTo(context, culture, value, destinationType));
// }
//}
//#endregion
//#endregion
#region CalendarColor
public class CalendarColor
{
#region Private variables
private eCalendarColor _ColorSch; // Current color scheme enum
private ColorDef[] _ColorTable; // Color scheme definition
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="colorSch">eCalendarColor</param>
public CalendarColor(eCalendarColor colorSch)
{
_ColorSch = colorSch;
SetColorTable();
}
#region Public properties
/// <summary>
/// Gets and sets ColorTable
/// </summary>
public ColorDef[] ColorTable
{
get { return (_ColorTable); }
set { _ColorTable = value; }
}
/// <summary>
/// Gets and sets calendar color scheme
/// </summary>
public eCalendarColor ColorSch
{
get { return (_ColorSch); }
set
{
if (_ColorSch != value)
{
_ColorSch = value;
SetColorTable();
}
}
}
#region SetColorTable
public virtual void SetColorTable()
{
}
#endregion
#endregion
#region Get Color
/// <summary>
/// Gets the Color of the calendar part
/// </summary>
/// <param name="part">Calendar part</param>
/// <returns>Color</returns>
public Color GetColor(int part)
{
return (_ColorTable[part].Colors[0]);
}
#endregion
#region GetColorDef
/// <summary>
/// Gets the ColorDef of the part
/// </summary>
/// <param name="part">Calendar part</param>
/// <returns>Part ColorDef</returns>
public ColorDef GetColorDef(int part)
{
return (_ColorTable[part]);
}
#endregion
#region BrushPart routines
/// <summary>
/// Creates a LinearGradientBrush from the given part
/// </summary>
/// <param name="part">Color part</param>
/// <param name="r">Gradient Rectangle</param>
/// <returns>Created Brush</returns>
public Brush BrushPart(int part, Rectangle r)
{
return (BrushPart(GetColorDef(part), r));
}
/// <summary>
/// Creates a LinearGradientBrush from the given ColorDef
/// </summary>
/// <param name="cDef">ColorDef</param>
/// <param name="r">Gradient Rectangle</param>
/// <returns>Created Brush</returns>
public Brush BrushPart(ColorDef cDef, Rectangle r)
{
return (BrushPart(cDef, r, cDef.Angle));
}
/// <summary>
/// Creates a LinearGradientBrush from the given ColorDef
/// </summary>
/// <param name="cDef">ColorDef</param>
/// <param name="r">Gradient Rectangle</param>
/// <param name="angle">Gradient angle</param>
/// <returns>Created Brush</returns>
public Brush BrushPart(ColorDef cDef, Rectangle r, float angle)
{
if (cDef.Colors.Length == 1)
return (new SolidBrush(cDef.Colors[0]));
LinearGradientBrush lbr =
new LinearGradientBrush(r, Color.White, Color.White, angle);
lbr.InterpolationColors = GetColorBlend(cDef);
return (lbr);
}
/// <summary>
/// Creates a ColorBlend from the given ColorDef
/// </summary>
/// <param name="cDef">ColorDef for blend</param>
/// <returns>ColorBlend</returns>
private ColorBlend GetColorBlend(ColorDef cDef)
{
ColorBlend cb = new ColorBlend(cDef.Colors.Length);
// Set each Color and position from the
// provided color definition
cb.Colors = cDef.Colors;
cb.Positions = GetPositions(cDef);
return (cb);
}
/// <summary>
/// Gets the array of color positions
/// </summary>
/// <param name="cDef"></param>
/// <returns></returns>
private float[] GetPositions(ColorDef cDef)
{
float[] cp = cDef.Positions;
if (cp == null || cp.Length != cDef.Colors.Length)
{
cp = new float[cDef.Colors.Length];
float f = 1f / cDef.Colors.Length;
for (int i = 0; i < cp.Length; i++)
cp[i] = i * f;
cp[cDef.Colors.Length - 1] = 1;
}
return (cp);
}
#endregion
}
#endregion
}
#endif

View File

@@ -0,0 +1,691 @@
#if FRAMEWORK20
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.DotNetBar.Schedule
{
#region enum definitions
/// <summary>
/// Month calendar parts enum
/// </summary>
public enum eCalendarMonthPart
{
DayOfTheWeekHeaderBorder,
DayOfTheWeekHeaderBackground,
DayOfTheWeekHeaderForeground,
SideBarBorder,
SideBarBackground,
SideBarForeground,
DayHeaderBorder,
DayHeaderBackground,
DayHeaderForeground,
DayContentBorder,
DayContentSelectionBackground,
DayContentActiveBackground,
DayContactInactiveBackground,
OwnerTabBorder,
OwnerTabBackground,
OwnerTabForeground,
OwnerTabContentBackground,
OwnerTabSelectedForeground,
OwnerTabSelectedBackground,
NowDayHeaderBorder,
NowDayHeaderForeground,
NowDayHeaderBackground,
ContentLinkForeground,
ContentLinkBackground,
}
#endregion
public class CalendarMonthColor : CalendarColor
{
#region Private variables
private ColorDef[][] _LocalColorTable =
{ _Blue, _Green, _Maroon, _Steel, _Teal, _Purple, _Olive,
_Red, _DarkPeach, _DarkSteel, _DarkGreen, _Yellow};
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="eColor">Default color</param>
public CalendarMonthColor(eCalendarColor eColor)
: base(eColor)
{
}
#region SetColorTable routine
/// <summary>
/// Sets our current color table to either
/// a local or global definition
/// </summary>
public override void SetColorTable()
{
if (ColorSch != eCalendarColor.Automatic)
{
// Use the requested local color table
ColorTable = _LocalColorTable[(int)ColorSch];
}
else
{
// Use the globally set color table
Office2007Renderer r =
GlobalManager.Renderer as Office2007Renderer;
ColorTable = (r != null)
? r.ColorTable.CalendarView.MonthViewColors
: _LocalColorTable[(int)eCalendarColor.Blue];
}
}
#endregion
#region Static Color definitions
// Array of predefined color
#region Blue
static ColorDef[] _Blue = new ColorDef[]
{
new ColorDef(0x8DAED9), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xE4ECF6, 0xD6E2F1, 0xC2D4EB, 0xD0DEEF}, // DayOfWeekHeaderBackground
new float[] {0f, .6f, .6f, 1f}, 90f),
new ColorDef(0x000000), // DayOfWeekHeaderForeground - 0x15428B
new ColorDef(0x5D8CC9), // SideBarBorder
new ColorDef(new int[] {0xE4ECF6, 0xD6E2F1, 0xC2D4EB, 0xD0DEEF}, // SideBarBackground
new float[] {0f, .6f, .6f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground - 0x15428B
new ColorDef(0x5D8CC9), // DayHeaderBorder
new ColorDef(new int[] {0xE4ECF6, 0xD6E2F1, 0xC2D4EB, 0xD0DEEF}, // DayHeaderBackground
new float[] {0f, .6f, .6f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0x8DAED9), // DayContentBorder
new ColorDef(0xE6EDF7), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xA5BFE1), // DayContentInactiveDayBackground
new ColorDef(0x5D8CC9), // OwnerTabBorder
new ColorDef(new int[] {0xBBCFE9, 0x8DAED9}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x8DAED9), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region Green
static ColorDef[] _Green = new ColorDef[]
{
new ColorDef(0x72A45A), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xE7F0E4, 0xDDE8D7, 0xCCDEC2, 0xD8E5D0}, // DayOfWeekHeaderBackground
new float[] {0f, .6f, .6f, 1f}, 90f),
new ColorDef(0x50734D), // DayOfWeekHeaderForeground
new ColorDef(0x72A45A), // SideBarBorder
new ColorDef(new int[] {0xE7F0E4, 0xDEE9D8, 0xCBDDC2, 0xD7E5D0}, // SideBarBackground
new float[] {0f, .6f, .6f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x50733F), // DayHeaderBorder
new ColorDef(new int[] {0xE7F0E4, 0xDDE8D7, 0xCCDEC2, 0xD8E5D0}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0x72A45A), // DayContentBorder
new ColorDef(0xE9F1E6), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xB1CDA4), // DayContentInactiveDayBackground
new ColorDef(0x72A45A), // OwnerTabBorder
new ColorDef(new int[] {0xC3D9B9, 0x9CBF8B}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x9CBF8B), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region Maroon
static ColorDef[] _Maroon = new ColorDef[]
{
new ColorDef(0x85495E), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xF4E6EB, 0xEFDAE2, 0xE6C6D2, 0xEDD4DD}, // DayOfWeekHeaderBackground
new float[] {0f, .6f, .6f, 1f}, 90f),
new ColorDef(0x85496B), // DayOfWeekHeaderForeground
new ColorDef(0xBE6886), // SideBarBorder
new ColorDef(new int[] {0xF4E6EB, 0xF0DBE3, 0xE7C7D3, 0xECD4DD}, // SideBarBackground
new float[] {0f, .6f, .6f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x85495E), // DayHeaderBorder
new ColorDef(new int[] {0xF4E6EB, 0xEFDAE2, 0xE6C6D2, 0xEDD4DD}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0xBE6886), // DayContentBorder
new ColorDef(0xF5E8EC), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xDBACBC), // DayContentInactiveDayBackground
new ColorDef(0xBE6886), // OwnerTabBorder
new ColorDef(new int[] {0xE4BFCB, 0xD195AA}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xD195AA), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region Steel
static ColorDef[] _Steel = new ColorDef[]
{
new ColorDef(0x9199A4), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xDCDFE2, 0xD3D6DA, 0xB4BAC1, 0xCBCED4}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x616A76), // DayOfWeekHeaderForeground
new ColorDef(0x9199A4), // SideBarBorder
new ColorDef(new int[] {0xDCDFE2, 0xD2D5DA, 0xB7BCC3, 0xCACED4}, // SideBarBackground
new float[] {0f, .6f, .6f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x9199A4), // DayHeaderBorder
new ColorDef(new int[] {0xDCDFE2, 0xD3D6DA, 0xB4BAC1, 0xCBCED4}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0x9199A4), // DayContentBorder
new ColorDef(0xE8EAEC), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xC7CBD1), // DayContentInactiveDayBackground
new ColorDef(0x9199A4), // OwnerTabBorder
new ColorDef(new int[] {0xCFD2D8, 0xB0B6BE}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xB0B6BE), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region Teal
static ColorDef[] _Teal = new ColorDef[]
{
new ColorDef(0x3F7373), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xDCDFE2, 0xD7E8E8, 0xC0DDDD, 0xD0E5E5}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x3F7380), // DayOfWeekHeaderForeground
new ColorDef(0x5AA4A4), // SideBarBorder
new ColorDef(new int[] {0xE4F0F0, 0xD6E8E8, 0xC2DDDD, 0xD0E5E5}, // SideBarBackground
new float[] {0f, .6f, .6f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x3F7373), // DayHeaderBorder
new ColorDef(new int[] {0xDCDFE2, 0xD7E8E8, 0xC0DDDD, 0xD0E5E5}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0x5AA4A4), // DayContentBorder
new ColorDef(0xE6F1F1), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xA4CDCD), // DayContentInactiveDayBackground
new ColorDef(0x5AA4A4), // OwnerTabBorder
new ColorDef(new int[] {0xB9D9D9, 0x8CBFC0}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x8CBFC0), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region Purple
static ColorDef[] _Purple = new ColorDef[]
{
new ColorDef(0x7171CD), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xE6E6F6, 0xDCDCF2, 0xC9C9EC, 0xD7D7F0}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x4F4F90), // DayOfWeekHeaderForeground
new ColorDef(0x7171CD), // SideBarBorder
new ColorDef(new int[] {0xE6E6F6, 0xDCDCF2, 0xC9C9EC, 0xD7D7F0}, // SideBarBackground
new float[] {0f, .55f, .58f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x4F4F90), // DayHeaderBorder
new ColorDef(new int[] {0xE6E6F6, 0xDCDCF2, 0xC9C9EC, 0xD7D7F0}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0x7171CD), // DayContentBorder
new ColorDef(0xE9E9F7), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0x9B9BDC), // DayContentInactiveDayBackground
new ColorDef(0x7171CD), // OwnerTabBorder
new ColorDef(new int[] {0xC1C1EA, 0x8C8CD7}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x8C8CD7), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region Olive
static ColorDef[] _Olive = new ColorDef[]
{
new ColorDef(0x9D9D57), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xEFEFE3, 0xE8E8D8, 0xDADABF, 0xE3E3CF}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x6E6E3D), // DayOfWeekHeaderForeground
new ColorDef(0x9D9D57), // SideBarBorder
new ColorDef(new int[] {0xEFEFE3, 0xE8E8D8, 0xDADABF, 0xE3E3CF}, // SideBarBackground
new float[] {0f, .55f, .58f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x6E6E3D), // DayHeaderBorder
new ColorDef(new int[] {0xEFEFE3, 0xE8E8D8, 0xDADABF, 0xE3E3CF}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0x9D9D57), // DayContentBorder
new ColorDef(0xF0F0E5), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xC9C9A2), // DayContentInactiveDayBackground
new ColorDef(0x9D9D57), // OwnerTabBorder
new ColorDef(new int[] {0xD5D5B8, 0xBABA89}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xBABA89), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region Red
static ColorDef[] _Red = new ColorDef[]
{
new ColorDef(0xC16969), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xF5E6E6, 0xEFDADA, 0xE7C6C6, 0xEDD4D4}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x874A4A), // DayOfWeekHeaderForeground
new ColorDef(0xC16969), // SideBarBorder
new ColorDef(new int[] {0xF5E6E6, 0xEFDADA, 0xE7C6C6, 0xEDD4D4}, // SideBarBackground
new float[] {0f, .55f, .58f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x874A4A), // DayHeaderBorder
new ColorDef(new int[] {0xF5E6E6, 0xEFDADA, 0xE7C6C6, 0xEDD4D4}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0xC16969), // DayContentBorder
new ColorDef(0xF6E8E8), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xDDACAC), // DayContentInactiveDayBackground
new ColorDef(0xC16969), // OwnerTabBorder
new ColorDef(new int[] {0xE5BFBF, 0xD39696}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xD39696), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region DarkPeach
static ColorDef[] _DarkPeach = new ColorDef[]
{
new ColorDef(0xA98F5D), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xF1EDE4, 0xE9E4D7, 0xDFD5C1, 0xE6E0D1}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x776441), // DayOfWeekHeaderForeground
new ColorDef(0xA98F5D), // SideBarBorder
new ColorDef(new int[] {0xF1EDE4, 0xDFD5C1, 0xDFD5C1, 0xE6E0D1}, // SideBarBackground
new float[] {0f, .55f, .58f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x776441), // DayHeaderBorder
new ColorDef(new int[] {0xF1EDE4, 0xE9E4D7, 0xDFD5C1, 0xE6E0D1}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0xA98F5D), // DayContentBorder
new ColorDef(0xF2EEE6), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xCFC1A5), // DayContentInactiveDayBackground
new ColorDef(0xA98F5D), // OwnerTabBorder
new ColorDef(new int[] {0xDBCFBA, 0xC3B08D}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xC3B08D), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region DarkSteel
static ColorDef[] _DarkSteel = new ColorDef[]
{
new ColorDef(0x6197B1), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xE5EEF2, 0xD8E5EB, 0xC3D7E1, 0xD2E2E9}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x446A96), // DayOfWeekHeaderForeground
new ColorDef(0x6197B1), // SideBarBorder
new ColorDef(new int[] {0xE5EEF2, 0xD8E5EB, 0xC3D7E1, 0xD2E2E9}, // SideBarBackground
new float[] {0f, .55f, .58f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x446A7C), // DayHeaderBorder
new ColorDef(new int[] {0xE5EEF2, 0xD8E5EB, 0xC3D7E1, 0xD2E2E9}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0x6197B1), // DayContentBorder
new ColorDef(0xE7EFF3), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xA8C5D4), // DayContentInactiveDayBackground
new ColorDef(0x6197B1), // OwnerTabBorder
new ColorDef(new int[] {0xBCD2DE, 0x90B6C8}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x90B6C8), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region DarkGreen
static ColorDef[] _DarkGreen = new ColorDef[]
{
new ColorDef(0x5AA48C), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xE4F0EC, 0xD7E8E3, 0xC0DDD4, 0xD0E5DF}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x3F7362), // DayOfWeekHeaderForeground
new ColorDef(0x5AA48C), // SideBarBorder
new ColorDef(new int[] {0xE4F0EC, 0xD7E8E3, 0xC0DDD4, 0xD0E5DF}, // SideBarBackground
new float[] {0f, .55f, .58f, 1f}, 0f),
new ColorDef(0x000000), // SideBarForeground
new ColorDef(0x3F7362), // DayHeaderBorder
new ColorDef(new int[] {0xE4F0EC, 0xD7E8E3, 0xC0DDD4, 0xD0E5DF}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0x5AA48C), // DayContentBorder
new ColorDef(0xE6F1ED), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xA4CDBF), // DayContentInactiveDayBackground
new ColorDef(0x5AA48C), // OwnerTabBorder
new ColorDef(new int[] {0xB9D9CE, 0x8BBFAE}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x8BBFAE), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#region Yellow
static ColorDef[] _Yellow = new ColorDef[]
{
new ColorDef(0xFFD151), // DayOfWeekHeaderBorder
new ColorDef(new int[] {0xFFF8E2, 0xFFF5D7, 0xFFEDBD, 0xFFF2CE}, // DayOfWeekHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x7F6628), // DayOfWeekHeaderForeground
new ColorDef(0xFFD151), // SideBarBorder
new ColorDef(new int[] {0xFFF8E2, 0xFFF5D7, 0xFFEDBD, 0xFFF2CE}, // SideBarBackground
new float[] {0f, .55f, .58f, 1f}, 0f),
new ColorDef(0x7F6628), // SideBarForeground
new ColorDef(0xD3AC40), // DayHeaderBorder
new ColorDef(new int[] {0xFFF8E2, 0xFFF5D7, 0xFFEDBD, 0xFFF2CE}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x000000), // DayHeaderForeground
new ColorDef(0xFFD151), // DayContentBorder
new ColorDef(0xFFF8E4), // DayContentSelectionBackground
new ColorDef(0xFFFFFF), // DayContentActiveDayBackground
new ColorDef(0xFFE69F), // DayContentInactiveDayBackground
new ColorDef(0xFFD151), // OwnerTabBorder
new ColorDef(new int[] {0xFFEBB6, 0xFFDF86}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xFFDF86), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground
new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground
};
#endregion
#endregion
}
}
#endif

View File

@@ -0,0 +1,73 @@
#if FRAMEWORK20
namespace DevComponents.DotNetBar.Schedule
{
#region enum definitions
#region eCalendarViewPart
/// <summary>
/// View calendar parts enum
/// </summary>
public enum eCalendarViewPart
{
OwnerTabBorder,
OwnerTabBackground,
OwnerTabForeground,
OwnerTabContentBackground
}
#endregion
#region eCalendarColor
/// <summary>
/// Defines available custom calendar color
/// </summary>
public enum eCalendarColor
{
Blue,
Green,
Maroon,
Steel,
Teal,
Purple,
Olive,
Red,
DarkPeach,
DarkSteel,
DarkGreen,
Yellow,
Automatic
}
#endregion
#endregion
public class CalendarViewColor : CalendarColor
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="eColor">Default color</param>
public CalendarViewColor(eCalendarColor eColor)
: base(eColor)
{
}
#region SetColorTable routine
/// <summary>
/// Sets our current color table to either
/// a local or global definition
/// </summary>
public override void SetColorTable()
{
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,667 @@
#if FRAMEWORK20
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.DotNetBar.Schedule
{
#region enum definitions
/// <summary>
/// Week/Day calendar parts enum
/// </summary>
public enum eCalendarWeekDayPart : int
{
DayViewBorder,
DayHeaderForeground,
DayHeaderBackground,
DayHeaderBorder,
DayWorkHoursBackground,
DayAllDayEventBackground,
DayOffWorkHoursBackground,
DayHourBorder,
DayHalfHourBorder,
SelectionBackground,
OwnerTabBorder,
OwnerTabBackground,
OwnerTabForeground,
OwnerTabContentBackground,
OwnerTabSelectedForeground,
OwnerTabSelectedBackground,
CondensedViewBackground,
NowDayHeaderBorder,
NowDayHeaderForeground,
NowDayHeaderBackground,
TimeIndicator,
TimeIndicatorBorder
}
#endregion
public class CalendarWeekDayColor : CalendarColor
{
#region Private variables
private ColorDef[][] _LocalColorTable =
{ _Blue, _Green, _Maroon, _Steel, _Teal, _Purple, _Olive,
_Red, _DarkPeach, _DarkSteel, _DarkGreen, _Yellow};
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="eColor">Default color</param>
public CalendarWeekDayColor(eCalendarColor eColor)
: base(eColor)
{
}
#region SetColorTable routine
/// <summary>
/// Sets our current color table to either
/// a local or global definition
/// </summary>
public override void SetColorTable()
{
if (ColorSch != eCalendarColor.Automatic)
{
// Use the requested local color table
ColorTable = _LocalColorTable[(int)ColorSch];
}
else
{
// Use the globally set color table
Office2007Renderer r =
GlobalManager.Renderer as Office2007Renderer;
ColorTable = (r != null)
? r.ColorTable.CalendarView.WeekDayViewColors
: _LocalColorTable[(int)eCalendarColor.Blue];
}
}
#endregion
#region Static Color definitions
// Array of predefined color
#region Blue
static ColorDef[] _Blue = new ColorDef[]
{
new ColorDef(0x5D8CC9), // DayViewBorder
new ColorDef(0x000000), // DayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xE4ECF6, 0xD6E2F1, 0xC2D4EB, 0xD0DEEF}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x8DAED9), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0x8DAED9), // DayAllDayEventBackground
new ColorDef(0xE6EDF7), // DayOffWorkHoursBackground
new ColorDef(0xA5BFE1), // DayHourBorder
new ColorDef(0xD5E1F1), // DayHalfHourBorder
new ColorDef(0x294C7A), // SelectionBackground
new ColorDef(0x5D8CC9), // OwnerTabBorder
new ColorDef(new int[] {0xBBCFE9, 0x8DAED9}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x8DAED9), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region Green
static ColorDef[] _Green = new ColorDef[]
{
new ColorDef(0x72A45A), // DayViewBorder
new ColorDef(0x50734D), // DayHeaderForeground
new ColorDef(new int[] {0xE7F0E4, 0xDDE8D7, 0xCADDC0, 0xD8E5D0}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x72A45A), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xB1CDA4), // DayAllDayEventBackground
new ColorDef(0xE9F1E6), // DayOffWorkHoursBackground
new ColorDef(0xB1CDA4), // DayHourBorder
new ColorDef(0xD6DDD2), // DayHalfHourBorder
new ColorDef(0x3F5B32), // SelectionBackground
new ColorDef(0x72A45A), // OwnerTabBorder
new ColorDef(new int[] {0xC3D9B9, 0x9CBF8B}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x9CBF8B), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region Maroon
static ColorDef[] _Maroon = new ColorDef[]
{
new ColorDef(0xBE6886), // DayViewBorder
new ColorDef(0x85496B), // DayHeaderForeground
new ColorDef(new int[] {0xF4E6EB, 0xEFDAE2, 0xE7C8D3, 0xEDD4DD}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0xBE6886), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xDBACBC), // DayAllDayEventBackground
new ColorDef(0xF5E8EC), // DayOffWorkHoursBackground
new ColorDef(0xDBACBC), // DayHourBorder
new ColorDef(0xE5D3D9), // DayHalfHourBorder
new ColorDef(0x693A4A), // SelectionBackground
new ColorDef(0xBE6886), // OwnerTabBorder
new ColorDef(new int[] {0xE4BFCB, 0xD195AA}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xD195AA), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region Steel
static ColorDef[] _Steel = new ColorDef[]
{
new ColorDef(0x616A76), // DayViewBorder
new ColorDef(0x616A76), // DayHeaderForeground
new ColorDef(new int[] {0xDCDFE2, 0xD3D6DA, 0xB4BAC1, 0xCBCED4}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x9199A4), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xC7CBD1), // DayAllDayEventBackground
new ColorDef(0xE8EAEC), // DayOffWorkHoursBackground
new ColorDef(0xC7CBD1), // DayHourBorder
new ColorDef(0xDDDDDD), // DayHalfHourBorder
new ColorDef(0x4C535C), // SelectionBackground
new ColorDef(0x9199A4), // OwnerTabBorder
new ColorDef(new int[] {0xCFD2D8, 0xB0B6BE}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xB0B6BE), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region Teal
static ColorDef[] _Teal = new ColorDef[]
{
new ColorDef(0x5AA4A4), // DayViewBorder
new ColorDef(0x3F7380), // DayHeaderForeground
new ColorDef(new int[] {0xE4F0F0, 0xD7E8E8, 0xC0DDDD, 0xD0E5E5}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x8CBFC0), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xA4CDCD), // DayAllDayEventBackground
new ColorDef(0xE6F1F1), // DayOffWorkHoursBackground
new ColorDef(0xA4CDCD), // DayHourBorder
new ColorDef(0xD2DDDD), // DayHalfHourBorder
new ColorDef(0x325B5B), // SelectionBackground
new ColorDef(0x5AA4A4), // OwnerTabBorder
new ColorDef(new int[] {0xB9D9D9, 0x8CBFC0}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x8CBFC0), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region Purple
static ColorDef[] _Purple = new ColorDef[]
{
new ColorDef(0x7171CD), // DayViewBorder
new ColorDef(0x4F4F90), // DayHeaderForeground
new ColorDef(new int[] {0xE7E7F6, 0xDCDCF2, 0xC9C9EC, 0xD7D7F0}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x8C8CD7), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0x9B9BDC), // DayAllDayEventBackground
new ColorDef(0xE9E9F7), // DayOffWorkHoursBackground
new ColorDef(0x9B9BDC), // DayHourBorder
new ColorDef(0xD5D5E8), // DayHalfHourBorder
new ColorDef(0x3E3E71), // SelectionBackground
new ColorDef(0x7171CD), // OwnerTabBorder
new ColorDef(new int[] {0xC1C1EA, 0x8C8CD7}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x8C8CD7), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region Olive
static ColorDef[] _Olive = new ColorDef[]
{
new ColorDef(0x9D9D57), // DayViewBorder
new ColorDef(0x6E6E3D), // DayHeaderForeground
new ColorDef(new int[] {0xEFEFE3, 0xE8E8D8, 0xDADABF, 0xE3E3CF}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0xBABA89), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xC9C9A2), // DayAllDayEventBackground
new ColorDef(0xF0F0E5), // DayOffWorkHoursBackground
new ColorDef(0xC9C9A2), // DayHourBorder
new ColorDef(0xDBDBD0), // DayHalfHourBorder
new ColorDef(0x575730), // SelectionBackground
new ColorDef(0x9D9D57), // OwnerTabBorder
new ColorDef(new int[] {0xD5D5B8, 0xBABA89}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xBABA89), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region Red
static ColorDef[] _Red = new ColorDef[]
{
new ColorDef(0xC16969), // DayViewBorder
new ColorDef(0x874A4A), // DayHeaderForeground
new ColorDef(new int[] {0xF5E6E6, 0xEFDADA, 0xE7C6C6, 0xEDD4D4}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0xD39696), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xDDACAC), // DayAllDayEventBackground
new ColorDef(0xF6E8E8), // DayOffWorkHoursBackground
new ColorDef(0xDDACAC), // DayHourBorder
new ColorDef(0xE8D7D7), // DayHalfHourBorder
new ColorDef(0x6B3A3A), // SelectionBackground
new ColorDef(0xC16969), // OwnerTabBorder
new ColorDef(new int[] {0xE5BFBF, 0xD39696}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xD39696), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region DarkPeach
static ColorDef[] _DarkPeach = new ColorDef[]
{
new ColorDef(0xA98F5D), // DayViewBorder
new ColorDef(0x776441), // DayHeaderForeground
new ColorDef(new int[] {0xF1EDE4, 0xE9E4D7, 0xDFD5C1, 0xE6E0D1}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0xC3B08D), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xCFC1A5), // DayAllDayEventBackground
new ColorDef(0xF2EEE6), // DayOffWorkHoursBackground
new ColorDef(0xCFC1A5), // DayHourBorder
new ColorDef(0xE0D7C5), // DayHalfHourBorder
new ColorDef(0x5D4F33), // SelectionBackground
new ColorDef(0xA98F5D), // OwnerTabBorder
new ColorDef(new int[] {0xDBCFBA, 0xC3B08D}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xC3B08D), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region DarkSteel
static ColorDef[] _DarkSteel = new ColorDef[]
{
new ColorDef(0x6197B1), // DayViewBorder
new ColorDef(0x446A96), // DayHeaderForeground
new ColorDef(new int[] {0xE5EEF2, 0xD8E5EB, 0xC3D7E1, 0xD2E2E9}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x90B6C8), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xA8C5D4), // DayAllDayEventBackground
new ColorDef(0xE7EFF3), // DayOffWorkHoursBackground
new ColorDef(0xA8C5D4), // DayHourBorder
new ColorDef(0xDCE5E3), // DayHalfHourBorder
new ColorDef(0x365362), // SelectionBackground
new ColorDef(0x6197B1), // OwnerTabBorder
new ColorDef(new int[] {0xBCD2DE, 0x90B6C8}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x90B6C8), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region DarkGreen
static ColorDef[] _DarkGreen = new ColorDef[]
{
new ColorDef(0x5AA48C), // DayViewBorder
new ColorDef(0x3F7362), // DayHeaderForeground
new ColorDef(new int[] {0xE4F0EC, 0xD7E8E3, 0xC0DDD4, 0xD0E5DF}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0x8BBFAE), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xA4CDBF), // DayAllDayEventBackground
new ColorDef(0xE6F1ED), // DayOffWorkHoursBackground
new ColorDef(0xA4CDBF), // DayHourBorder
new ColorDef(0xD0DDD9), // DayHalfHourBorder
new ColorDef(0x325B4D), // SelectionBackground
new ColorDef(0x5AA48C), // OwnerTabBorder
new ColorDef(new int[] {0xB9D9CE, 0x8BBFAE}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0x8BBFAE), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#region Yellow
static ColorDef[] _Yellow = new ColorDef[]
{
new ColorDef(0xFFD151), // DayViewBorder
new ColorDef(0x7F6628), // DayHeaderForeground
new ColorDef(new int[] {0xFFF8E2, 0xFFF5D7, 0xFFEDBD, 0xFFF2CE}, // DayHeaderBackground
new float[] {0f, .55f, .58f, 1f}, 90f),
new ColorDef(0xFFDF86), // DayHeaderBorder
new ColorDef(0xFFFFFF), // DayWorkHoursBackground
new ColorDef(0xFFE69F), // DayAllDayEventBackground
new ColorDef(0xFFF8E4), // DayOffWorkHoursBackground
new ColorDef(0xFFE69F), // DayHourBorder
new ColorDef(0xFFE69F), // DayHalfHourBorder
new ColorDef(0xB39540), // SelectionBackground
new ColorDef(0xFFD151), // OwnerTabBorder
new ColorDef(new int[] {0xFFEBB6, 0xFFDF86}, // OwnerTabBackground
new float[] {0f, 1f}, 90f),
new ColorDef(0x000000), // OwnerTabForeground
new ColorDef(0xFFDF86), // OwnerTabContentBackground
new ColorDef(0x000000), // OwnerTabSelectedForeground
new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground
new ColorDef(0xF5F5F5), // CondensedViewBackground
new ColorDef(0xEB8900), // NowDayViewBorder
new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground
new float[] {0f, .55f, .058f, 1f}, 90f),
new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator
new float[] {0f, .55f ,58f, 1f}, 90f),
new ColorDef(0xEB8900), // TimeIndicatorBorder
};
#endregion
#endregion
}
}
#endif

View File

@@ -0,0 +1,54 @@
#if FRAMEWORK20
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.DotNetBar.Schedule
{
#region enum definitions
/// <summary>
/// Week/Day calendar parts enum
/// </summary>
public enum eTimeRulerPart : int
{
TimeRulerBackground,
TimeRulerForeground,
TimeRulerBorder,
TimeRulerTickBorder,
TimeRulerIndicator,
TimeRulerIndicatorBorder
}
#endregion
public class TimeRulerColor : CalendarColor
{
/// <summary>
/// Constructor
/// </summary>
public TimeRulerColor()
: base(eCalendarColor.Automatic)
{
}
#region SetColorTable routine
/// <summary>
/// Sets our current color table to either
/// a local or global definition
/// </summary>
public override void SetColorTable()
{
// Use the globally set color table
Office2007Renderer r =
GlobalManager.Renderer as Office2007Renderer;
if (r != null)
ColorTable = r.ColorTable.CalendarView.TimeRulerColors;
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,480 @@
#if FRAMEWORK20
using System;
using System.Windows.Forms;
using DevComponents.Schedule.Model;
using System.ComponentModel;
namespace DevComponents.DotNetBar.Schedule
{
public class CustomCalendarItem : CalendarItem
{
#region Events
/// <summary>
/// Occurs when the OwnerKey has changed
/// </summary>
[Description("Occurs when the OwnerKey has changed.")]
public event EventHandler<EventArgs> OwnerKeyChanged;
/// <summary>
/// Occurs when Locked has changed
/// </summary>
[Description("Occurs when the Locked property has changed.")]
public event EventHandler<EventArgs> LockedChanged;
#endregion
#region Private variables
private string _OwnerKey = ""; // OwnerKey
private bool _Locked; // Locked state
private CustomCalendarItem _BaseCalendarItem; // Base CalendarItem
private CalendarView _CalendarView;
#endregion
#region Public properties
#region CollateId
/// <summary>
/// Gets or sets the CollateId used for TimeLine row collation.
/// </summary>
public override int CollateId
{
get
{
if (_BaseCalendarItem != null)
return (_BaseCalendarItem.CollateId);
return (base.CollateId);
}
set
{
if (_BaseCalendarItem != null)
_BaseCalendarItem.CollateId = value;
base.CollateId = value;
}
}
#endregion
#region OwnerKey
/// <summary>
/// Gets and sets the item OwnerKey
/// </summary>
public string OwnerKey
{
get
{
if (_BaseCalendarItem != null)
return (_BaseCalendarItem.OwnerKey);
return (_OwnerKey);
}
set
{
if (_BaseCalendarItem != null)
{
_BaseCalendarItem.OwnerKey = value;
}
else
{
if (value == null)
value = "";
if (_OwnerKey.Equals(value) == false)
{
string oldValue = _OwnerKey;
_OwnerKey = value;
OnOwnerKeyChanged(oldValue, value);
}
}
}
}
/// <summary>
/// Sends ChangedEvent for the OwnerKey property
/// </summary>
/// <param name="oldValue">Old OwnerKey</param>
/// <param name="newValue">New OwnerKey</param>
protected virtual void OnOwnerKeyChanged(string oldValue, string newValue)
{
if (OwnerKeyChanged != null)
OwnerKeyChanged(this, new OwnerKeyChangedEventArgs(oldValue, newValue));
}
#endregion
#region Locked
/// <summary>
/// Gets and set whether modification is enabled
/// through the user interface"
/// </summary>
public bool Locked
{
get
{
if (_BaseCalendarItem != null)
return (_BaseCalendarItem.Locked);
return (_Locked);
}
set
{
if (_BaseCalendarItem != null)
{
_BaseCalendarItem.Locked = value;
}
else
{
if (_Locked != value)
{
bool oldValue = _Locked;
_Locked = value;
OnLockedChanged(oldValue, value);
}
}
}
}
/// <summary>
/// Sends ChangedEvent for the Locked property
/// </summary>
/// <param name="oldValue">Old OwnerKey</param>
/// <param name="newValue">New OwnerKey</param>
protected virtual void OnLockedChanged(bool oldValue, bool newValue)
{
if (LockedChanged != null)
LockedChanged(this, new LockedChangedEventArgs(oldValue, newValue));
}
#endregion
#region StartTime
public override DateTime StartTime
{
get
{
if (_BaseCalendarItem != null)
return (_BaseCalendarItem.StartTime);
return (base.StartTime);
}
set
{
if (_BaseCalendarItem != null)
_BaseCalendarItem.StartTime = value;
base.StartTime = value;
}
}
#endregion
#region EndTime
public override DateTime EndTime
{
get
{
if (_BaseCalendarItem != null)
return (_BaseCalendarItem.EndTime);
return (base.EndTime);
}
set
{
if (_BaseCalendarItem != null)
_BaseCalendarItem.EndTime = value;
base.EndTime = value;
}
}
#endregion
#region BaseCalendarItem
/// <summary>
/// Base CalendarItem
///
/// This property holds the base CalendarItem from which
/// each displayed CustomItem (of this type) is based.
///
/// In order to keep all displayed items "in-sync", it is necessary
/// to propagate data to and from the base CalendarItem. This is
/// accomplished via hooking those members you are interested in, at
/// both the item (HookEvents) and BaseCalendarItem (HookBaseEvents)
/// level.
///
/// </summary>
public virtual CustomCalendarItem BaseCalendarItem
{
get { return (_BaseCalendarItem); }
set { _BaseCalendarItem = value; }
}
#endregion
#region IsMultiDayOrAllDayEvent
public bool IsMultiDayOrAllDayEvent
{
get
{
return (StartTime < EndTime &&
(EndTime.Subtract(StartTime).TotalDays >= 1 ||
DateTimeHelper.IsSameDay(StartTime, EndTime) == false));
}
}
#endregion
#region CategoryColor
/// <summary>
/// Gets or sets the category color used for TimeLine CondensedView markers.
/// Use static members on Appointment class to assign the category color for example Appointment.CategoryRed.
/// </summary>
public override string CategoryColor
{
get
{
if (_BaseCalendarItem != null)
return (_BaseCalendarItem.CategoryColor);
return (base.CategoryColor);
}
set
{
if (_BaseCalendarItem != null)
_BaseCalendarItem.CategoryColor = value;
base.CategoryColor = value;
}
}
#endregion
#region IsSelected
/// <summary>
/// Gets or sets whether the item is selected.
/// </summary>
public override bool IsSelected
{
get
{
if (_BaseCalendarItem != null)
return (_BaseCalendarItem.IsSelected);
return (base.IsSelected);
}
set
{
if (_BaseCalendarItem != null)
_BaseCalendarItem.IsSelected = value;
base.IsSelected = value;
}
}
#endregion
#region Visible
/// <summary>
/// Gets and sets the item Visibility
/// </summary>
public override bool Visible
{
get
{
if (_BaseCalendarItem != null)
return (_BaseCalendarItem.Visible);
return (base.Visible);
}
set
{
if (_BaseCalendarItem != null)
{
_BaseCalendarItem.Visible = value;
}
else
{
if (_BaseCalendarItem != null)
_BaseCalendarItem.Visible = value;
base.Visible = value;
}
}
}
#endregion
#endregion
#region Internal properties
#region CalendarView
internal CalendarView CalendarView
{
get { return (_CalendarView); }
set { _CalendarView = value; }
}
#endregion
#endregion
#region Refresh
public override void Refresh()
{
if (_CalendarView != null)
{
Control c = (Control)_CalendarView.GetContainerControl();
if (c != null)
{
foreach (BaseItem item in _CalendarView.CalendarPanel.SubItems)
{
BaseView view = item as BaseView;
if (view != null)
RefreshItems(c, view.SubItems);
}
}
}
}
private void RefreshItems(Control c, SubItemsCollection subItems)
{
foreach (BaseItem item in subItems)
{
CustomCalendarItem ci = item as CustomCalendarItem;
if (ci != null)
{
if (ci == this || ci.BaseCalendarItem == this)
ci.Invalidate(c);
}
else if (item is AllDayPanel)
{
RefreshItems(c, item.SubItems);
}
}
}
#endregion
#region Paint
public override void Paint(ItemPaintArgs e)
{
}
#endregion
#region Copy
/// <summary>
/// Returns copy of the item.
/// </summary>
public override BaseItem Copy()
{
CustomCalendarItem objCopy = new CustomCalendarItem();
CopyToItem(objCopy);
return (objCopy);
}
/// <summary>
/// Copies the CustomCalendarItem specific properties to new instance of the item.
/// </summary>
/// <param name="copy">New CustomCalendarItem instance</param>
protected override void CopyToItem(BaseItem copy)
{
CustomCalendarItem objCopy = copy as CustomCalendarItem;
if (objCopy != null)
{
base.CopyToItem(objCopy);
objCopy._OwnerKey = this._OwnerKey;
objCopy._Locked = this.Locked;
objCopy._CalendarView = this.CalendarView;
}
}
#endregion
}
#region OwnerKeyChangedEventArgs
/// <summary>
/// OwnerKeyChangedEventArgs
/// </summary>
///
public class OwnerKeyChangedEventArgs : ValueChangedEventArgs<string, string>
{
public OwnerKeyChangedEventArgs(string oldValue, string newValue)
: base(oldValue, newValue)
{
}
}
#endregion
#region LockedChangedEventArgs
/// <summary>
/// LockedChangedEventArgs
/// </summary>
///
public class LockedChangedEventArgs : ValueChangedEventArgs<bool, bool>
{
public LockedChangedEventArgs(bool oldValue, bool newValue)
: base(oldValue, newValue)
{
}
}
#endregion
#region CategoryColorChangedEventArgs
/// <summary>
/// CategoryColorChangedEventArgs
/// </summary>
///
public class CategoryColorChangedEventArgs : ValueChangedEventArgs<string, string>
{
public CategoryColorChangedEventArgs(string oldValue, string newValue)
: base(oldValue, newValue)
{
}
}
#endregion
}
#endif

View File

@@ -0,0 +1,288 @@
#if FRAMEWORK20
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace DevComponents.DotNetBar.Schedule
{
public class CustomCalendarItemCollection : Collection<CustomCalendarItem>, IDisposable
{
#region Events
/// <summary>
/// Occurs when the collection has changed
/// </summary>
[Description("Occurs when the collection has changed.")]
public event EventHandler<EventArgs> CollectionChanged;
#endregion
#region Private variables
private int _UpdateCount;
#endregion
#region AddRange
/// <summary>
/// Adds a range of CustomCalendarItems to the collection
/// </summary>
/// <param name="items">Array of items to add</param>
public void AddRange(CustomCalendarItem[] items)
{
for (int i = 0; i < items.Length; i++)
Add(items[i]);
OnCollectionChanged();
}
#endregion
#region Remove
/// <summary>
/// Removes a CustomCalendarItem from
/// the collection.
/// </summary>
/// <param name="item">Item to remove</param>
public new void Remove(CustomCalendarItem item)
{
if (item.BaseCalendarItem != null)
item = item.BaseCalendarItem;
base.Remove(item);
}
#endregion
#region RemoveItem
/// <summary>
/// Processes list RemoveItem calls
/// </summary>
/// <param name="index">Index to remove</param>
protected override void RemoveItem(int index)
{
HookItem(Items[index], false);
base.RemoveItem(index);
OnCollectionChanged();
}
#endregion
#region InsertItem
/// <summary>
/// Processes list InsertItem calls
/// </summary>
/// <param name="index">Index to add</param>
/// <param name="item">CustomCalendarItem to add</param>
protected override void InsertItem(int index, CustomCalendarItem item)
{
if (item != null)
{
HookItem(item, true);
base.InsertItem(index, item);
OnCollectionChanged();
}
}
#endregion
#region SetItem
/// <summary>
/// Processes list SetItem calls (e.g. replace)
/// </summary>
/// <param name="index">Index to replace</param>
/// <param name="newItem">CustomCalendarItem to replace</param>
protected override void SetItem(int index, CustomCalendarItem newItem)
{
if (newItem != null)
{
HookItem(Items[index], false);
HookItem(newItem, true);
base.SetItem(index, newItem);
OnCollectionChanged();
}
}
#endregion
#region ClearItems
/// <summary>
/// Processes list Clear calls (e.g. remove all)
/// </summary>
protected override void ClearItems()
{
for (int i = 0; i < Count; i++)
HookItem(Items[i], false);
base.ClearItems();
OnCollectionChanged();
}
#endregion
#region HookItem
/// <summary>
/// Hooks needed system events
/// </summary>
/// <param name="item"></param>
/// <param name="hook"></param>
private void HookItem(CustomCalendarItem item, bool hook)
{
if (hook == true)
{
item.StartTimeChanged += ItemStartTimeChanged;
item.EndTimeChanged += ItemEndTimeChanged;
item.OwnerKeyChanged += ItemOwnerKeyChanged;
item.CategoryColorChanged += ItemCategoryColorChanged;
item.VisibleChanged += ItemVisibleChanged;
item.CollateIdChanged += ItemCollateIdChanged;
}
else
{
item.StartTimeChanged -= ItemStartTimeChanged;
item.EndTimeChanged -= ItemEndTimeChanged;
item.OwnerKeyChanged -= ItemOwnerKeyChanged;
item.CategoryColorChanged -= ItemCategoryColorChanged;
item.VisibleChanged -= ItemVisibleChanged;
item.CollateIdChanged -= ItemCollateIdChanged;
}
}
#endregion
#region Event processing
/// <summary>
/// Processes OwnerKeyChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ItemOwnerKeyChanged(object sender, EventArgs e)
{
OnCollectionChanged();
}
/// <summary>
/// Processes StartTimeChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ItemStartTimeChanged(object sender, EventArgs e)
{
OnCollectionChanged();
}
/// <summary>
/// Processes EndTimeChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ItemEndTimeChanged(object sender, EventArgs e)
{
OnCollectionChanged();
}
/// <summary>
/// Processes ItemCategoryColorChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ItemCategoryColorChanged(object sender, EventArgs e)
{
OnCollectionChanged();
}
/// <summary>
/// Processes ItemVisibleChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ItemVisibleChanged(object sender, EventArgs e)
{
OnCollectionChanged();
}
/// <summary>
/// Processes ItemCollateIdChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ItemCollateIdChanged(object sender, EventArgs e)
{
OnCollectionChanged();
}
#endregion
#region OnCollectionChanged
/// <summary>
/// Propagates CollectionChanged events
/// </summary>
protected virtual void OnCollectionChanged()
{
if (_UpdateCount == 0)
{
if (CollectionChanged != null)
CollectionChanged(this, EventArgs.Empty);
}
}
#endregion
#region Begin/EndUpdate
/// <summary>
/// Begins Update block
/// </summary>
public void BeginUpdate()
{
_UpdateCount++;
}
/// <summary>
/// Ends update block
/// </summary>
public void EndUpdate()
{
if (_UpdateCount == 0)
{
throw new InvalidOperationException(
"EndUpdate must be called After BeginUpdate");
}
_UpdateCount--;
if (_UpdateCount == 0)
OnCollectionChanged();
}
#endregion
#region IDisposable
public void Dispose()
{
for (int i = 0; i < Count; i++)
HookItem(Items[i], false);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,154 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Globalization;
namespace DevComponents.DotNetBar.Schedule
{
internal static class DateHelper
{
#region Date/Time Helpers
/// <summary>
/// Returns the date that is 30 minutes before or after input date if input date minute is 0 or 30. Otherwise it returns next increment to 0 or 30.
/// </summary>
/// <param name="date">Date and time.</param>
/// <param name="forward">Indicates whether to add or subtract minutes.</param>
/// <returns>New date time.</returns>
public static DateTime GetNext30Minute(DateTime date, bool forward)
{
if (date.Minute == 0 || date.Minute == 30)
return (date.AddMinutes(forward ? 30 : -30));
return (date.AddMinutes((forward ? 1 : -1) * Math.Abs(30 - date.Minute)));
}
/// <summary>
/// Returns date that starts with the day. If passed date is not on the requested date function returns first date with day that is before passed date.
/// </summary>
/// <param name="date">Date to inspect.</param>
/// <param name="dayOfWeek">Day of week</param>
/// <returns>Date that starts on given day of week.</returns>
public static DateTime GetDateForDayOfWeek(DateTime date, DayOfWeek dayOfWeek)
{
if (date.DayOfWeek != dayOfWeek)
{
// Go back to the first day of week
while (date.DayOfWeek != dayOfWeek)
{
date = date.AddDays(-1);
}
}
return (date);
}
public static DateTime GetEndOfWeek(DateTime date, DayOfWeek lastDayOfWeek)
{
while (date.DayOfWeek != lastDayOfWeek)
date = date.AddDays(1);
return (date);
}
internal static DayOfWeek GetFirstDayOfWeek()
{
return (ScheduleSettings.GetActiveCulture().DateTimeFormat.FirstDayOfWeek);
}
internal static DayOfWeek GetLastDayOfWeek()
{
DayOfWeek firstDay = GetFirstDayOfWeek();
int lastDay = (int)firstDay + 6;
if (lastDay > 6)
lastDay = lastDay - 7;
return (DayOfWeek)lastDay;
}
/// <summary>
/// Returns whether two days fall on same month and year.
/// </summary>
/// <param name="date1">First date</param>
/// <param name="date2">Second date</param>
/// <returns>true if dates are on same month and year</returns>
public static bool IsSameMonth(DateTime date1, DateTime date2)
{
return (date1.Year == date2.Year && date1.Month == date2.Month);
}
public static DayOfWeek GetNextDay(DayOfWeek currentDay)
{
if ((int)currentDay == 6)
return (DayOfWeek)0;
return (DayOfWeek)(currentDay + 1);
}
/// <summary>
/// Returns true if time periods overlap.
/// </summary>
/// <param name="startTime1">Start of first period.</param>
/// <param name="endTime1">End of first period.</param>
/// <param name="startTime2">Start of second period.</param>
/// <param name="endTime2">End of second period.</param>
/// <returns>true if periods overlap</returns>
public static bool TimePeriodsOverlap(DateTime startTime1, DateTime endTime1, DateTime startTime2, DateTime endTime2)
{
return (startTime1 <= startTime2 && endTime1 > startTime2 ||
startTime1 >= startTime2 && startTime1 < endTime2);
}
public static int GetNumberOfWeeks(DateTime startDate, DateTime endDate)
{
if (startDate == DateTime.MinValue && endDate == DateTime.MinValue)
{
startDate = DateTime.Today.Date;
endDate = startDate.AddMonths(1);
}
if (startDate == DateTime.MinValue || endDate == DateTime.MinValue || endDate < startDate)
{
return (0);
}
endDate = GetEndOfWeek(endDate, DateHelper.GetLastDayOfWeek());
startDate = GetDateForDayOfWeek(startDate, DateHelper.GetFirstDayOfWeek());
return ((int)Math.Max(Math.Ceiling(endDate.Subtract(startDate).TotalDays / 7), 1));
}
/// <summary>
/// Gets the abbreviated month name for
/// the given date
/// </summary>
/// <param name="date">Date</param>
/// <returns>Abbreviated name</returns>
public static string GetThreeLetterMonth(DateTime date)
{
CultureInfo ci = ScheduleSettings.GetActiveCulture();
return (ci.DateTimeFormat.GetAbbreviatedMonthName(date.Month));
}
/// <summary>
/// Gets the abbreviated day name for
/// the given date
/// </summary>
/// <param name="dayOfWeek">Day of week</param>
/// <returns>Abbreviated name</returns>
public static string GetThreeLetterDayOfWeek(DayOfWeek dayOfWeek)
{
CultureInfo ci = ScheduleSettings.GetActiveCulture();
return (ci.DateTimeFormat.GetAbbreviatedDayName(dayOfWeek));
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,94 @@
#if FRAMEWORK20
namespace DevComponents.DotNetBar.Schedule
{
partial class DateNavigator
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
CalendarView = null;
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.CurrentDateLabel = new LabelX();
this.NavigateForward = new DevComponents.DotNetBar.ButtonX();
this.NavigateBack = new DevComponents.DotNetBar.ButtonX();
this.SuspendLayout();
//
// CurrentDateLabel
//
this.CurrentDateLabel.AutoSize = true;
this.CurrentDateLabel.AutoSize = true;
this.CurrentDateLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.CurrentDateLabel.Location = new System.Drawing.Point(54, 4);
this.CurrentDateLabel.Name = "CurrentDateLabel";
this.CurrentDateLabel.Size = new System.Drawing.Size(132, 20);
this.CurrentDateLabel.TabIndex = 1;
this.CurrentDateLabel.Text = "October 20, 2009";
//
// NavigateForward
//
this.NavigateForward.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
this.NavigateForward.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
this.NavigateForward.Location = new System.Drawing.Point(31, 4);
this.NavigateForward.Name = "NavigateForward";
this.NavigateForward.Shape = new DevComponents.DotNetBar.EllipticalShapeDescriptor();
this.NavigateForward.Size = new System.Drawing.Size(20, 20);
this.NavigateForward.TabIndex = 0;
this.NavigateForward.Click += new System.EventHandler(this.NavigateForwardClick);
this.NavigateForward.FocusCuesEnabled = false;
//
// NavigateBack
//
this.NavigateBack.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
this.NavigateBack.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
this.NavigateBack.Location = new System.Drawing.Point(5, 4);
this.NavigateBack.Name = "NavigateBack";
this.NavigateBack.Shape = new DevComponents.DotNetBar.EllipticalShapeDescriptor();
this.NavigateBack.Size = new System.Drawing.Size(20, 20);
this.NavigateBack.TabIndex = 0;
this.NavigateBack.Click += new System.EventHandler(this.NavigateBackClick);
this.NavigateBack.FocusCuesEnabled = false;
//
// DateNavigator
//
this.Controls.Add(this.CurrentDateLabel);
this.Controls.Add(this.NavigateForward);
this.Controls.Add(this.NavigateBack);
this.Name = "DateNavigator";
this.Size = new System.Drawing.Size(223, 30);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ButtonX NavigateBack;
private ButtonX NavigateForward;
private LabelX CurrentDateLabel;
}
}
#endif

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,158 @@
#if FRAMEWORK20
using System;
using System.Drawing;
namespace DevComponents.DotNetBar.Schedule
{
public class DaysOfTheWeek
{
#region enums
public enum eDayType
{
Long, // Long text
Short, // Short text
Single,
None
}
#endregion
#region Private variables
private int _DayCount; // Count of days
private string[][] _DayText; // Days of the week text
private Size[][] _DaySize; // Days of the week measure
private bool _NeedsMeasured; // Text measure flag
#endregion
/// <summary>
/// Constructor
/// </summary>
public DaysOfTheWeek()
: this(DateHelper.GetFirstDayOfWeek(), 7)
{
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="day">Day of the week</param>
/// <param name="count">Count of days</param>
public DaysOfTheWeek(DayOfWeek day, int count)
{
LoadDays(day, count);
}
#region Public properties
/// <summary>
/// Gets the DayText string arrays
/// </summary>
public string[][] DayText
{
get { return (_DayText); }
}
/// <summary>
/// Gets the DaySize Size arrays
/// </summary>
public Size[][] DaySize
{
get {return (_DaySize); }
}
/// <summary>
/// Day text NeedsMeasured flag
/// </summary>
public bool NeedsMeasured
{
get { return (_NeedsMeasured); }
set { _NeedsMeasured = value; }
}
#endregion
#region LoadDays
/// <summary>
/// Loads the DayText arrays
/// </summary>
/// <param name="day">Starting day of week</param>
/// <param name="count">Count of days</param>
public void LoadDays(DayOfWeek day, int count)
{
_DayCount = count;
// Allocate our Day text and Size arrays
_DayText = new string[3][];
_DaySize = new Size[3][];
for (int i = 0; i < 3; i++)
{
_DayText[i] = new string[count];
_DaySize[i] = new Size[count];
}
// Loop through each day of the week, getting
// the long and short text strings for the day
for (int i = 0; i < _DayCount; i++)
{
_DayText[0][i] =
ScheduleSettings.GetActiveCulture().DateTimeFormat.GetDayName(day);
_DayText[1][i] =
DateHelper.GetThreeLetterDayOfWeek(day);
_DayText[2][i] = _DayText[1][i].Substring(0, 1);
day = DateHelper.GetNextDay(day);
}
// Flag that the text will need to be measured
_NeedsMeasured = true;
}
#endregion
#region MeasureText
/// <summary>
/// Measures the day text
/// </summary>
/// <param name="g">Graphics</param>
/// <param name="font">Text font</param>
public void MeasureText(Graphics g, Font font)
{
// Calculate our header text threshold, if
// we haven't done so already
if (_NeedsMeasured == true)
{
for (int i = 0; i < _DayCount; i++)
{
_DaySize[0][i] =
TextDrawing.MeasureString(g, _DayText[0][i], font);
_DaySize[1][i] =
TextDrawing.MeasureString(g, _DayText[1][i], font);
_DaySize[2][i] =
TextDrawing.MeasureString(g, _DayText[2][i], font);
}
_NeedsMeasured = false;
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,268 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C25DFA40-9897-47FA-A525-7528C5BE7724}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DevComponents.DotNetBar.Schedule</RootNamespace>
<AssemblyName>DevComponents.DotNetBar.Schedule</AssemblyName>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>dotnetbar.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<UpgradeBackupLocation />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;FRAMEWORK20</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;FRAMEWORK20</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\DevComponents.DotNetBar.Schedule.XML</DocumentationFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseTrialSchedule|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>FRAMEWORK20;TRIAL</DefineConstants>
<DocumentationFile>bin\Release\DevComponents.DotNetBar.Schedule.XML</DocumentationFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AppointmentView\AppointmentHView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="AppointmentView\AppointmentMonthView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="AppointmentView\AppointmentTimeLineView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="AppointmentView\AppointmentView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="AppointmentView\AppointmentWeekDayView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="BaseView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CalendarItem.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CalendarView\CalendarPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CalendarView\CalendarView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CalendarView\CalendarViewCollection.cs" />
<Compile Include="CalendarView\DisplayedOwnerCollection.cs" />
<Compile Include="CalendarView\ViewDisplayCustomizations.cs" />
<Compile Include="Color\AppointmentCategoryColor.cs" />
<Compile Include="Color\AppointmentCategoryColorCollection.cs" />
<Compile Include="Color\AppointmentColor.cs" />
<Compile Include="Color\CalendarColor.cs" />
<Compile Include="Color\CalendarMonthColor.cs" />
<Compile Include="Color\CalendarViewColor.cs" />
<Compile Include="Color\CalendarWeekDayColor.cs" />
<Compile Include="Color\TimeRulerColor.cs" />
<Compile Include="CustomCalendarItem.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CustomCalendarItemCollection.cs" />
<Compile Include="DateHelper.cs" />
<Compile Include="DateNavigator.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="DateNavigator.Designer.cs">
<DependentUpon>DateNavigator.cs</DependentUpon>
</Compile>
<Compile Include="DaysOfTheWeek.cs" />
<Compile Include="ItemRect.cs" />
<Compile Include="ModelViewConnector.cs" />
<Compile Include="Model\Appointment.cs" />
<Compile Include="Model\AppointmentCollection.cs" />
<Compile Include="Model\AppointmentRecurrence.cs" />
<Compile Include="Model\AppointmentSubsetCollection.cs" />
<Compile Include="Model\BaseWorkDay.cs" />
<Compile Include="Model\CalendarModel.cs" />
<Compile Include="Model\CalendarWorkDay.cs" />
<Compile Include="Model\CalendarWorkDayCollection.cs" />
<Compile Include="Model\DailyRecurrenceSettings.cs" />
<Compile Include="Model\DateTimeHelper.cs" />
<Compile Include="Model\Day.cs" />
<Compile Include="Model\Enums.cs" />
<Compile Include="Model\HolidaysCollection.cs" />
<Compile Include="Model\ImportExport\CalendarEntry.cs" />
<Compile Include="Model\ImportExport\ICS\IcsExporter.cs" />
<Compile Include="Model\ImportExport\ICS\IcsImporter.cs" />
<Compile Include="Model\INotifySubPropertyChanged.cs" />
<Compile Include="Model\Month.cs" />
<Compile Include="Model\MonthlyRecurrenceSettings.cs" />
<Compile Include="Model\NotificationRequest.cs" />
<Compile Include="Model\NotificationServer.cs" />
<Compile Include="Model\NotificationServerEventArgs.cs" />
<Compile Include="Model\Owner.cs" />
<Compile Include="Model\OwnerCollection.cs" />
<Compile Include="Model\Primitives\CustomCollectionBase.cs" />
<Compile Include="Model\RecurrenceGenerator.cs" />
<Compile Include="Model\Reminder.cs" />
<Compile Include="Model\ReminderCollection.cs" />
<Compile Include="Model\WeeklyRecurrenceSettings.cs" />
<Compile Include="Model\WorkDay.cs" />
<Compile Include="Model\WorkDayCollection.cs" />
<Compile Include="Model\WorkTime.cs" />
<Compile Include="Model\Year.cs" />
<Compile Include="Model\YearlyRecurrenceSettings.cs" />
<Compile Include="MonthView\ModelMonthViewConnector.cs" />
<Compile Include="MonthView\MonthView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="MonthView\MonthWeek.cs" />
<Compile Include="NativeFunctions.cs" />
<Compile Include="PosWin.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="PosWin.Designer.cs">
<DependentUpon>PosWin.cs</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScheduleSettings.cs" />
<Compile Include="TimeIndicator\TimeIndicator.cs" />
<Compile Include="TimeIndicator\TimeIndicatorCollection.cs" />
<Compile Include="TimeLineView\DayInfo.cs" />
<Compile Include="TimeLineView\ModelTimeLineViewConnector.cs" />
<Compile Include="TimeLineView\TimeLineHeaderPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="TimeLineView\TimeLineHScrollPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="TimeLineView\TimeLineView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="TimeLineView\TimeLineVScrollPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="VScrollPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="WeekView\AllDayPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="WeekView\ColumnList.cs" />
<Compile Include="WeekView\DayColumn.cs" />
<Compile Include="WeekView\DayView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="WeekView\ModelWeekDayViewConnector.cs" />
<Compile Include="WeekView\TimeRulerPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="WeekView\WeekDayView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="WeekView\WeekDayVScrollPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="WeekView\WeekView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="WinApi.cs" />
<Compile Include="YearView\ModelYearViewConnector.cs" />
<Compile Include="YearView\YearMonth.cs" />
<Compile Include="YearView\YearView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="YearView\YearViewVScrollPanel.cs">
<SubType>Component</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="CalendarView.ico" />
<EmbeddedResource Include="DateNavigator.resx">
<DependentUpon>DateNavigator.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="DateNavigator.ico" />
<EmbeddedResource Include="PosWin.resx">
<DependentUpon>PosWin.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="dotnetbar.snk" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DotNetBar.csproj">
<Project>{36546CE3-335C-4AB6-A2F3-40F8C818BC66}</Project>
<Name>DotNetBar</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,128 @@
#if FRAMEWORK20
using System.Drawing;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Schedule
{
/// <summary>
/// DayRect array management class
/// </summary>
public class ItemRects
{
#region Private variables
private ItemRect[] _ItemRects;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseItem"></param>
/// <param name="length">Rectangle array length</param>
public ItemRects(BaseItem baseItem, int length)
{
_ItemRects = new ItemRect[length];
for (int i = 0; i < length; i++)
_ItemRects[i] = new ItemRect(baseItem);
}
#region Public properties
/// <summary>
/// Gets the Rectangle array
/// </summary>
public ItemRect[] Rects
{
get { return (_ItemRects); }
}
/// <summary>
/// Gets and sets a specific array Rectangle
/// </summary>
/// <param name="index">Rectangle index to get</param>
/// <returns>Rectangle</returns>
public ItemRect this[int index]
{
get { return (_ItemRects[index]); }
set { _ItemRects[index] = value; }
}
#endregion
}
/// <summary>
/// Simple DayRect class
/// </summary>
public class ItemRect
{
#region Private variables
private BaseItem _BaseItem; // BaseItem
private Rectangle _Bounds; // Bounds
private bool _IsSelected; // Rect selection
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseItem">BaseItem</param>
public ItemRect(BaseItem baseItem)
{
_BaseItem = baseItem;
}
#region Public properties
/// <summary>
/// Gets and sets the bounding rect
/// </summary>
public Rectangle Bounds
{
get { return (_Bounds); }
set { _Bounds = value; }
}
/// <summary>
/// Gets and sets the rect selection status
/// </summary>
public bool IsSelected
{
get { return (_IsSelected); }
set
{
if (_IsSelected != value)
{
_IsSelected = value;
Invalidate();
}
}
}
#endregion
#region Public methods
/// <summary>
/// Invalidates the given rectangle
/// </summary>
public void Invalidate()
{
if (_BaseItem != null)
{
Control c = (Control)_BaseItem.GetContainerControl(true);
if (c != null)
c.Invalidate(_Bounds);
}
}
#endregion
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,105 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace DevComponents.Schedule.Model
{
public class AppointmentCollection : Collection<Appointment>
{
#region Constructor
/// <summary>
/// Initializes a new instance of the AppointmentCollection class.
/// </summary>
/// <param name="calendar"></param>
public AppointmentCollection(CalendarModel calendar)
{
_Calendar = calendar;
}
#endregion
#region Internal Implementation
private CalendarModel _Calendar = null;
/// <summary>
/// Gets the calendar collection is associated with.
/// </summary>
public CalendarModel Calendar
{
get { return _Calendar; }
internal set { _Calendar = value; }
}
protected override void InsertItem(int index, Appointment item)
{
OnBeforeInsert(index, item);
base.InsertItem(index, item);
OnAfterInsert(index, item);
}
private void OnAfterInsert(int index, Appointment item)
{
_Calendar.InternalAppointmentAdded(item);
}
private void OnBeforeInsert(int index, Appointment item)
{
item.Calendar = _Calendar;
}
protected override void SetItem(int index, Appointment item)
{
Appointment app = this[index];
OnBeforeSetItem(index, app, item);
base.SetItem(index, item);
OnAfterSetItem(index, app, item);
}
private void OnAfterSetItem(int index, Appointment oldItem, Appointment newItem)
{
_Calendar.InternalAppointmentRemoved(oldItem, false);
_Calendar.InternalAppointmentAdded(newItem);
}
private void OnBeforeSetItem(int index, Appointment oldItem, Appointment newItem)
{
oldItem.Calendar = null;
newItem.Calendar = _Calendar;
}
protected override void RemoveItem(int index)
{
Appointment app = this[index];
OnBeforeRemove(index);
base.RemoveItem(index);
OnAfterRemove(index, app);
}
private void OnAfterRemove(int index, Appointment app)
{
_Calendar.InternalAppointmentRemoved(app, false);
}
private void OnBeforeRemove(int index)
{
this[index].Calendar = null;
}
protected override void ClearItems()
{
foreach (Appointment item in this)
{
item.Calendar = null;
_Calendar.InternalAppointmentRemoved(item, true);
}
base.ClearItems();
_Calendar.InternalAppointmentsCleared();
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,378 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using DevComponents.Schedule.Model.Primitives;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents appointment recurrence definition.
/// </summary>
public class AppointmentRecurrence : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Internal Implementation
public AppointmentRecurrence()
{
_SkippedRecurrences = new CustomCollection<DateTime>();
_SkippedRecurrences.CollectionChanged += new NotifyCollectionChangedEventHandler(SkippedRecurrencesCollectionChanged);
}
private eRecurrenceRangeLimitType _RangeType = eRecurrenceRangeLimitType.NoEndDate;
/// <summary>
/// Gets or sets the range type for the recurrence. Default value is no end date for recurrence.
/// </summary>
[DefaultValue(eRecurrenceRangeLimitType.NoEndDate)]
public eRecurrenceRangeLimitType RangeLimitType
{
get { return _RangeType; }
set
{
if (_RangeType != value)
{
eRecurrenceRangeLimitType oldValue = _RangeType;
_RangeType = value;
OnRangeTypeChanged(oldValue, _RangeType);
}
}
}
private void OnRangeTypeChanged(eRecurrenceRangeLimitType oldValue, eRecurrenceRangeLimitType newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RangeLimitType"));
}
private DateTime _RangeEndDate = DateTime.MinValue;
/// <summary>
/// Gets or sets the recurrence end date. To specify the end date for recurrence set this property and RangeLimitType property to RangeEndDate.
/// </summary>
public DateTime RangeEndDate
{
get { return _RangeEndDate; }
set
{
if (_RangeEndDate != value)
{
DateTime oldValue = _RangeEndDate;
_RangeEndDate = value;
OnRangeEndDateChanged(oldValue, _RangeEndDate);
}
}
}
private void OnRangeEndDateChanged(DateTime oldValue, DateTime newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RangeEndDate"));
}
private int _RangeNumberOfOccurrences = 0;
/// <summary>
/// Gets or sets number of occurrences after which recurrence ends. To specify limited number of recurrences
/// set this property and set RangeLimitType to RangeNumberOfOccurrences.
/// </summary>
[DefaultValue(0)]
public int RangeNumberOfOccurrences
{
get { return _RangeNumberOfOccurrences; }
set
{
if (_RangeNumberOfOccurrences != value)
{
if (value < 0) throw new ArgumentException("Negative values not allows for range limit.");
int oldValue = _RangeNumberOfOccurrences;
_RangeNumberOfOccurrences = value;
OnRangeNumberOfOccurrencesChanged(oldValue, _RangeNumberOfOccurrences);
}
}
}
private void OnRangeNumberOfOccurrencesChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RangeNumberOfOccurrences"));
}
private object _Tag = null;
/// <summary>
/// Gets or sets additional data associated with the object.
/// </summary>
[DefaultValue(null)]
public object Tag
{
get { return _Tag; }
set
{
if (value != _Tag)
{
object oldValue = _Tag;
_Tag = value;
OnTagChanged(oldValue, value);
}
}
}
private void OnTagChanged(object oldValue, object newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Tag"));
}
private eRecurrencePatternType _RecurrenceType = eRecurrencePatternType.Daily;
/// <summary>
/// Gets or sets the recurring frequency for appointment i.e. daily, weekly, monthly or yearly.
/// Default value is Daily.
/// </summary>
[DefaultValue(eRecurrencePatternType.Daily)]
public eRecurrencePatternType RecurrenceType
{
get { return _RecurrenceType; }
set
{
if (value != _RecurrenceType)
{
eRecurrencePatternType oldValue = _RecurrenceType;
_RecurrenceType = value;
OnRecurrenceTypeChanged(oldValue, value);
}
}
}
private void OnRecurrenceTypeChanged(eRecurrencePatternType oldValue, eRecurrencePatternType newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RecurrenceType"));
}
internal void GenerateSubset(AppointmentSubsetCollection subsetCollection, DateTime startDate, DateTime endDate)
{
IRecurrenceGenerator generator = GetRecurrenceGenerator();
if (_RecurrenceType == eRecurrencePatternType.Daily)
{
generator.GenerateDailyRecurrence(subsetCollection, this, startDate, endDate);
}
else if (_RecurrenceType == eRecurrencePatternType.Weekly)
{
generator.GenerateWeeklyRecurrence(subsetCollection, this, startDate, endDate);
}
else if (_RecurrenceType == eRecurrencePatternType.Monthly)
{
generator.GenerateMonthlyRecurrence(subsetCollection, this, startDate, endDate);
}
else if (_RecurrenceType == eRecurrencePatternType.Yearly)
{
generator.GenerateYearlyRecurrence(subsetCollection, this, startDate, endDate);
}
}
private IRecurrenceGenerator _Generator = null;
private IRecurrenceGenerator GetRecurrenceGenerator()
{
if (_Generator == null) _Generator = new RecurrenceGenerator();
return _Generator;
}
private Appointment _Appointment;
/// <summary>
/// Gets reference to appointment recurrence is assigned to.
/// </summary>
[Browsable(false)]
public Appointment Appointment
{
get { return _Appointment; }
internal set { _Appointment = value; }
}
private DailyRecurrenceSettings _Daily;
/// <summary>
/// Gets the settings for Daily recurrence type.
/// </summary>
[Browsable(false)]
public DailyRecurrenceSettings Daily
{
get
{
if (_Daily == null)
{
_Daily = new DailyRecurrenceSettings(this);
_Daily.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
}
return _Daily;
}
}
private WeeklyRecurrenceSettings _Weekly;
/// <summary>
/// Gets the settings for Weekly recurrence type.
/// </summary>
public WeeklyRecurrenceSettings Weekly
{
get
{
if (_Weekly == null)
{
_Weekly = new WeeklyRecurrenceSettings(this);
_Weekly.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
}
return _Weekly;
}
}
private MonthlyRecurrenceSettings _Monthly;
/// <summary>
/// Gets the settings for monthly recurrence type.
/// </summary>
[Browsable(false)]
public MonthlyRecurrenceSettings Monthly
{
get
{
if (_Monthly == null)
{
_Monthly = new MonthlyRecurrenceSettings(this);
_Monthly.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
}
return _Monthly;
}
}
private YearlyRecurrenceSettings _Yearly = null;
/// <summary>
/// Gets the settings for yearly recurrence type.
/// </summary>
public YearlyRecurrenceSettings Yearly
{
get
{
if (_Yearly == null)
{
_Yearly = new YearlyRecurrenceSettings(this);
_Yearly.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
}
return _Yearly;
}
}
private DateTime _RecurrenceStartDate = DateTime.MinValue;
/// <summary>
/// Gets or sets the recurrence start date. Default value is DateTime.MinValue which indicates that recurrence starts after
/// the appointment ends.
/// </summary>
public DateTime RecurrenceStartDate
{
get { return _RecurrenceStartDate; }
set
{
if (value != _RecurrenceStartDate)
{
DateTime oldValue = _RecurrenceStartDate;
_RecurrenceStartDate = value;
OnRecurrenceStartDateChanged(oldValue, value);
}
}
}
private void OnRecurrenceStartDateChanged(DateTime oldValue, DateTime newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RecurrenceStartDate"));
}
private SubPropertyChangedEventHandler _ChildPropertyChangedEventHandler = null;
private SubPropertyChangedEventHandler ChildPropertyChangedEventHandler
{
get
{
if (_ChildPropertyChangedEventHandler == null) _ChildPropertyChangedEventHandler = new SubPropertyChangedEventHandler(ChildPropertyChanged);
return _ChildPropertyChangedEventHandler;
}
}
private void ChildPropertyChanged(object sender, SubPropertyChangedEventArgs e)
{
OnSubPropertyChanged(e);
}
private CustomCollection<DateTime> _SkippedRecurrences = null;
/// <summary>
/// Gets or set the list of dates on which the recurrences are skipped.
/// </summary>
public CustomCollection<DateTime> SkippedRecurrences
{
get
{
return _SkippedRecurrences;
}
}
private void SkippedRecurrencesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(new PropertyChangedEventArgs("SkippedRecurrences"));
}
private bool _IndependentVisibility = false;
/// <summary>
/// Gets or sets whether generated recurring appointments have independent Visible property setting from root Appointment.
/// When set to true recurring appointment instances will not by default have Visible property set to the Visible property of root appointment.
/// Default value is false which means recurring instances by default have Visible property set to the root appointment Visible property.
/// </summary>
public bool IndependentVisibility
{
get { return _IndependentVisibility; }
set
{
if (value != _IndependentVisibility)
{
bool oldValue = _IndependentVisibility;
_IndependentVisibility = value;
OnIndependentVisibilityChanged(oldValue, value);
}
}
}
/// <summary>
/// Called when IndependentVisibility property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnIndependentVisibilityChanged(bool oldValue, bool newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("IndependentVisibility"));
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null) eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,232 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using DevComponents.Schedule.Model.Primitives;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents subset of appointments collection.
/// </summary>
public class AppointmentSubsetCollection : CustomCollection<Appointment>
{
#region Private Variables
private DateTime _StartDate = DateTime.MinValue;
private DateTime _EndDate = DateTime.MinValue;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the AppointmentSubsetCollection class with appointments between given start and end date.
/// </summary>
/// <param name="calendar"></param>
/// <param name="start"></param>
/// <param name="end"></param>
public AppointmentSubsetCollection(CalendarModel calendar, DateTime start, DateTime end)
{
_Calendar = calendar;
_StartDate = start;
_EndDate = end;
PopulateCollection();
}
#endregion
#region Internal Implementation
private CalendarModel _Calendar = null;
/// <summary>
/// Gets the calendar collection is associated with this collection.
/// </summary>
public CalendarModel Calendar
{
get { return _Calendar; }
internal set { _Calendar = value; }
}
protected override void InsertItem(int index, Appointment item)
{
OnBeforeInsert(index, item);
base.InsertItem(index, item);
}
private void OnBeforeInsert(int index, Appointment item)
{
item.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
item.Calendar = _Calendar;
if (item.IsRecurringInstance && _Calendar != null)
_Calendar.InternalAppointmentAdded(item);
}
protected override void SetItem(int index, Appointment item)
{
OnBeforeSetItem(index, item);
base.SetItem(index, item);
}
private void OnBeforeSetItem(int index, Appointment item)
{
Appointment app = this[index];
app.SubPropertyChanged -= this.ChildPropertyChangedEventHandler;
app.Calendar = null;
item.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
app.Calendar = _Calendar;
}
protected override void RemoveItem(int index)
{
OnBeforeRemove(index);
base.RemoveItem(index);
}
private void OnBeforeRemove(int index)
{
Appointment item = this[index];
OnAppointmentRemoved(item);
}
private void OnAppointmentRemoved(Appointment item)
{
item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler;
if (item.IsRecurringInstance && _Calendar != null)
_Calendar.InternalAppointmentRemoved(item, false);
if (item.IsRecurringInstance)
item.Calendar = null;
}
protected override void ClearItems()
{
foreach (Appointment item in this.GetItemsDirect())
{
OnAppointmentRemoved(item);
}
base.ClearItems();
}
private void PopulateCollection()
{
this.Clear();
foreach (Appointment app in _Calendar.Appointments)
{
if (app.LocalStartTime >= _StartDate && app.LocalStartTime <= _EndDate || app.LocalEndTime > _StartDate && (app.LocalEndTime <= _EndDate || app.LocalStartTime < _StartDate))
{
this.Add(app);
}
if (app.Recurrence != null && IsRecurrenceInRange(app, _StartDate, _EndDate))
{
int count = this.GetItemsDirect().Count;
app.Recurrence.GenerateSubset(this, _StartDate, _EndDate);
if (count == this.GetItemsDirect().Count && TotalDaysDuration(app.StartTime, app.EndTime) >= 1 &&
app.LocalEndTime < _StartDate)
{
// Nothing generated lets wind back and look to see is there an recurrence that needs to be captured in this view
int daysLookBack = TotalDaysDuration(app.StartTime, app.EndTime);
DateTime start = _StartDate;
for (int i = 0; i < daysLookBack; i++)
{
start = start.AddDays(-1);
AppointmentSubsetCollection dayCollection = _Calendar.GetDay(start).Appointments;
foreach (Appointment subAppointment in dayCollection)
{
if (subAppointment.IsRecurringInstance && subAppointment.RootAppointment == app &&
(subAppointment.LocalStartTime >= _StartDate && subAppointment.LocalStartTime <= _EndDate ||
subAppointment.LocalEndTime > _StartDate && (subAppointment.LocalEndTime <= _EndDate ||
subAppointment.LocalStartTime < _StartDate)))
{
this.Add(subAppointment);
daysLookBack = -1;
break;
}
}
}
}
}
}
_IsCollectionUpToDate = true;
}
private int TotalDaysDuration(DateTime startTime, DateTime endTime)
{
if (endTime.Hour == 0 && endTime.Minute == 0 && endTime.Second == 0)
endTime = endTime.AddMinutes(-1);
return (int)Math.Max(0, Math.Ceiling(endTime.Date.Subtract(startTime.Date).TotalDays));
}
private bool IsRecurrenceInRange(Appointment app, DateTime startDate, DateTime endDate)
{
if (app.Recurrence.RecurrenceType == eRecurrencePatternType.Yearly)
{
// Simple range check on number of occurrences
if (app.Recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && app.LocalEndTime.Subtract(endDate).TotalDays / 365 > app.Recurrence.RangeNumberOfOccurrences)
return false;
// Date check based on next expected recurrence date
if (app.Recurrence.Yearly.RepeatInterval > 1)
{
DateTime nextRecurrence = DateTimeHelper.MaxDate(app.Recurrence.RecurrenceStartDate, app.EndTime.AddDays(1).Date);
while (nextRecurrence < startDate)
nextRecurrence = RecurrenceGenerator.GetNextYearlyRecurrence(app.Recurrence, nextRecurrence);
if (nextRecurrence > endDate || nextRecurrence.Add(endDate.Subtract(startDate)) < startDate)
return false;
}
else
{
DateTime nextRecurrence = RecurrenceGenerator.GetNextYearlyRecurrence(app.Recurrence, startDate.Date.AddDays(-startDate.DayOfYear));
if (nextRecurrence > endDate || nextRecurrence.Add(endDate.Subtract(startDate)) < startDate)
return false;
}
}
if (app.Recurrence.RangeEndDate == DateTime.MinValue || app.Recurrence.RangeEndDate >= _EndDate || app.Recurrence.RangeEndDate < _EndDate && app.Recurrence.RangeEndDate > _StartDate)
return true;
return false;
}
private SubPropertyChangedEventHandler _ChildPropertyChangedEventHandler = null;
private SubPropertyChangedEventHandler ChildPropertyChangedEventHandler
{
get
{
if (_ChildPropertyChangedEventHandler == null) _ChildPropertyChangedEventHandler = new SubPropertyChangedEventHandler(ChildPropertyChanged);
return _ChildPropertyChangedEventHandler;
}
}
private void ChildPropertyChanged(object sender, SubPropertyChangedEventArgs e)
{
InvalidateCollection();
}
/// <summary>
/// Invalidates collection content due to the change to appointments or some other condition. Invalidating collection
/// content causes the collection elements to be re-generated on next collection read access.
/// </summary>
public virtual void InvalidateCollection()
{
_IsCollectionUpToDate = false;
}
protected override void OnCollectionReadAccess()
{
if (!_IsCollectionUpToDate) PopulateCollection();
base.OnCollectionReadAccess();
}
private bool _IsCollectionUpToDate = false;
internal bool IsCollectionUpToDate
{
get { return _IsCollectionUpToDate; }
set
{
_IsCollectionUpToDate = value;
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Defines a working day.
/// </summary>
public abstract class BaseWorkDay : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Internal Implementation
protected WorkTime _WorkStartTime = new WorkTime(8, 0);
/// <summary>
/// Gets or sets the work start time.
/// </summary>
public WorkTime WorkStartTime
{
get { return _WorkStartTime; }
set
{
WorkTime oldValue = _WorkStartTime;
_WorkStartTime = value;
OnWorkStartTimeChanged(oldValue, value);
}
}
/// <summary>
/// Called when WorkStartTime has changed.
/// </summary>
/// <param name="oldValue">Old property value.</param>
/// <param name="newValue">New property value.</param>
protected virtual void OnWorkStartTimeChanged(WorkTime oldValue, WorkTime newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("WorkStartTime"));
}
protected WorkTime _WorkEndTime = new WorkTime(17, 0);
/// <summary>
/// Gets or sets the work end time.
/// </summary>
public WorkTime WorkEndTime
{
get { return _WorkEndTime; }
set
{
WorkTime oldValue = _WorkEndTime;
_WorkEndTime = value;
OnWorkEndTimeChanged(oldValue, value);
}
}
/// <summary>
/// Called when WorkEndTime has changed.
/// </summary>
/// <param name="oldValue">Old property value.</param>
/// <param name="newValue">New property value.</param>
protected virtual void OnWorkEndTimeChanged(WorkTime oldValue, WorkTime newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("WorkEndTime"));
}
private CalendarModel _Calendar = null;
/// <summary>
/// Gets the calendar work day is associated with.
/// </summary>
[Browsable(false)]
public CalendarModel Calendar
{
get { return _Calendar; }
internal set
{
if (_Calendar != value)
{
_Calendar = value;
}
}
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null) eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
}
}

View File

@@ -0,0 +1,595 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Globalization;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents the calendar model control.
/// </summary>
public class CalendarModel : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Events
/// <summary>
/// Occurs when an appointment has been added to the model.
/// </summary>
public event AppointmentEventHandler AppointmentAdded;
/// <summary>
/// Occurs when an appointment has been removed from the model.
/// </summary>
public event AppointmentEventHandler AppointmentRemoved;
/// <summary>
/// Occurs when AppointmentStartTime has been reached. This event can be used to trigger appointment reminders. Note that event handler will be called on the thread of System.Timer which is different
/// than UI thread. You should use BeginInvoke calls to marshal the calls to your UI thread.
/// </summary>
public event AppointmentEventHandler AppointmentStartTimeReached;
/// <summary>
/// Occurs when Reminder's ReminderTime has been reached. Note that event handler will be called on the thread of System.Timer which is different
/// than UI thread. You should use BeginInvoke calls to marshal the calls to your UI thread.
/// </summary>
[Description("Occurs when Reminder's ReminderTime has been reached.")]
public event ReminderEventHandler ReminderNotification;
/// <summary>
/// Occurs when Appointments collection has been cleared.
/// </summary>
public event EventHandler AppointmentsCleared;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the CalendarModel class.
/// </summary>
public CalendarModel()
{
_Appointments = new AppointmentCollection(this);
_Owners = new OwnerCollection(this);
_WorkDays = new WorkDayCollection(this);
_CalendarWorkDays = new CalendarWorkDayCollection(this);
// Initialize default work-days
_WorkDays.Add(new WorkDay(DayOfWeek.Monday));
_WorkDays.Add(new WorkDay(DayOfWeek.Tuesday));
_WorkDays.Add(new WorkDay(DayOfWeek.Wednesday));
_WorkDays.Add(new WorkDay(DayOfWeek.Thursday));
_WorkDays.Add(new WorkDay(DayOfWeek.Friday));
}
#endregion
#region Internal Implementation
private AppointmentCollection _Appointments;
/// <summary>
/// Gets appointments associated with this calendar.
/// </summary>
public AppointmentCollection Appointments
{
get { return _Appointments; }
}
private OwnerCollection _Owners;
/// <summary>
/// Gets owners of appointments associated with this calendar.
/// </summary>
public OwnerCollection Owners
{
get { return _Owners; }
}
private WorkDayCollection _WorkDays;
/// <summary>
/// Gets working days associated with this calendar.
/// </summary>
public WorkDayCollection WorkDays
{
get { return _WorkDays; }
}
private CalendarWorkDayCollection _CalendarWorkDays = null;
/// <summary>
/// Gets the calendar/date based working days collection. This collection allows you to specify working time for specific dates. Values specified here take precedence over working hours set through WorkDays collection.
/// </summary>
public CalendarWorkDayCollection CalendarWorkDays
{
get { return _CalendarWorkDays; }
}
/// <summary>
/// Gets reference to the Day object which represents day in calendar.
/// </summary>
/// <param name="date">Date to retrieve day for.</param>
/// <returns>Returns reference to Day object.</returns>
public Day GetDay(DateTime date)
{
Year year = null;
if(!_Years.TryGetValue(date.Year, out year))
year = CreateYear(date.Year);
return year.Months[date.Month - 1].Days[date.Day - 1];
//return new Day(date, this);
}
private Year CreateYear(int y)
{
Year year = new Year(y, this);
_Years.Add(y, year);
return year;
}
/// <summary>
/// Returns true if appointment overlapps with one or more of the appointments in the model.
/// </summary>
/// <param name="app">Appointment to check overlap for.</param>
/// <returns>true if there are appointments overlapping appointment otherwise false.</returns>
public bool ContainsOverlappingAppointments(Appointment app)
{
int duration = (int)Math.Max(1, app.EndTime.Subtract(app.StartTime).TotalDays);
for (int i = 0; i < duration; i++)
{
DateTime date = app.StartTime.Date.AddDays(i);
Day day = GetDay(date);
foreach (Appointment item in day.Appointments)
{
if (item != app && DateTimeHelper.TimePeriodsOverlap(item.StartTime, item.EndTime, app.StartTime, app.EndTime))
return true;
}
}
return false;
}
/// <summary>
/// Finds appointments that overlap with the parameter appointment.
/// </summary>
/// <param name="app">Appointment to use to find overlapps</param>
/// <returns>Array of appointments that overlap parameter.</returns>
public Appointment[] FindOverlappingAppointments(Appointment app)
{
List<Appointment> overlaps = new List<Appointment>();
int duration = (int)Math.Max(1, app.EndTime.Subtract(app.StartTime).TotalDays);
for (int i = 0; i < duration; i++)
{
DateTime date = app.StartTime.Date.AddDays(i);
Day day = GetDay(date);
foreach (Appointment item in day.Appointments)
{
if (item != app && DateTimeHelper.TimePeriodsOverlap(item.StartTime, item.EndTime, app.StartTime, app.EndTime))
overlaps.Add(item);
}
}
return overlaps.ToArray();
}
//public Month GetMonth(int year, int month)
//{
// return null;
//}
//private HolidaysCollection _Holidays;
///// <summary>
///// Gets the collection of holidays associated with calendar.
///// </summary>
//public HolidaysCollection Holidays
//{
// get { return _Holidays; }
//}
/// <summary>
/// Returns the calendar date time which has seconds part set to 0.
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DateTime GetCalendarDateTime(DateTime dt)
{
if (_PreciseDateTimeValues)
return dt;
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
}
private static bool _PreciseDateTimeValues = false;
/// <summary>
/// Gets or sets whether Appointment StartTime and EndTime values retain seconds and milliseconds. When
/// set to false seconds and milliseconds are discarded. When set to true the DateTime set to appointment
/// StartTime and EndTime is used as is including seconds and milliseconds. Default value is false.
/// </summary>
public static bool PreciseDateTimeValues
{
get
{
return _PreciseDateTimeValues;
}
set
{
_PreciseDateTimeValues = value;
}
}
public static DateTime CurrentDateTime
{
get
{
DateTime dt = DateTime.Now;
return dt;
}
}
internal System.Globalization.Calendar GetCalendar()
{
return CultureInfo.CurrentCulture.Calendar;
}
private Dictionary<int, Year> _Years = new Dictionary<int, Year>();
internal void InternalAppointmentRemoved(Appointment item, bool isClearing)
{
item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler;
if (!item.IsRecurringInstance && !isClearing)
InvalidateAppointmentCache(item);
if (!isClearing)
OnAppointmentRemoved(new AppointmentEventArgs(item));
}
internal void InternalAppointmentsCleared()
{
InvalidateAppointmentCache();
OnAppointmentsCleared(EventArgs.Empty);
}
protected virtual void OnAppointmentsCleared(EventArgs e)
{
EventHandler handler = AppointmentsCleared;
if (handler != null) handler(this, e);
}
/// <summary>
/// Raises the AppointmentRemoved event.
/// </summary>
/// <param name="appointmentEventArgs">Event arguments</param>
protected virtual void OnAppointmentRemoved(AppointmentEventArgs appointmentEventArgs)
{
AppointmentEventHandler handler = AppointmentRemoved;
if (handler != null) handler(this, appointmentEventArgs);
}
internal void InternalAppointmentAdded(Appointment item)
{
item.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
if (!item.IsRecurringInstance)
InvalidateAppointmentCache(item);
OnAppointmentAdded(new AppointmentEventArgs(item));
}
/// <summary>
/// Raises the AppointmentAdded event.
/// </summary>
/// <param name="appointmentEventArgs">Event arguments</param>
protected virtual void OnAppointmentAdded(AppointmentEventArgs appointmentEventArgs)
{
AppointmentEventHandler handler = AppointmentAdded;
if (handler != null) handler(this, appointmentEventArgs);
}
internal void OwnerRemoved(Owner item)
{
item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler;
OnPropertyChanged(new PropertyChangedEventArgs("Owners"));
}
internal void OwnerAdded(Owner item)
{
item.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
OnPropertyChanged(new PropertyChangedEventArgs("Owners"));
}
internal void WorkDayRemoved(WorkDay item)
{
item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler;
OnPropertyChanged(new PropertyChangedEventArgs("WorkDays"));
}
internal void WorkDayAdded(WorkDay item)
{
item.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
OnPropertyChanged(new PropertyChangedEventArgs("WorkDays"));
}
internal void CalendarWorkDateRemoved(CalendarWorkDay item)
{
item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler;
OnPropertyChanged(new PropertyChangedEventArgs("CalendarWorkDays"));
}
internal void CalendarWorkDateAdded(CalendarWorkDay item)
{
item.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
OnPropertyChanged(new PropertyChangedEventArgs("CalendarWorkDays"));
}
private SubPropertyChangedEventHandler _ChildPropertyChangedEventHandler = null;
private SubPropertyChangedEventHandler ChildPropertyChangedEventHandler
{
get
{
if (_ChildPropertyChangedEventHandler == null) _ChildPropertyChangedEventHandler = new SubPropertyChangedEventHandler(ChildPropertyChanged);
return _ChildPropertyChangedEventHandler;
}
}
private void ChildPropertyChanged(object sender, SubPropertyChangedEventArgs e)
{
Appointment app = sender as Appointment;
OnSubPropertyChanged(e);
if (app != null)
{
if (IsNonTimeProperty(e.PropertyChangedArgs.PropertyName)) return;
if (app.InMoveTo && e.PropertyChangedArgs.PropertyName != "EndTime") return;
if (IsRecurranceProperty(e.PropertyChangedArgs.PropertyName) ||
e.Source is DailyRecurrenceSettings ||
e.Source is WeeklyRecurrenceSettings ||
e.Source is YearlyRecurrenceSettings ||
e.Source is MonthlyRecurrenceSettings)
InvalidateAppointmentCache();
else
InvalidateAppointmentCache(app);
}
}
private bool IsRecurranceProperty(string propertyName)
{
return propertyName == Appointment.RecurrencePropertyName;
}
private void InvalidateAppointmentCache(Appointment app)
{
if (IsUpdateSuspended) return;
if (app.Recurrence != null)
{
// Invalidate all
InvalidateAppointmentCache();
}
else if (_Years.ContainsKey(app.LocalStartTime.Year))
{
DateTime d = DateTimeHelper.BeginningOfDay(app.LocalStartTime);
DateTime end = app.LocalEndTime;
int year = d.Year;
while (d < end)
{
_Years[d.Year].InvalidateAppointments(d.Month, d.Day);
d = d.AddDays(1);
if (d.Year != year && !_Years.ContainsKey(d.Year))
break;
}
}
AccessToday();
OnPropertyChanged(new PropertyChangedEventArgs(AppointmentsPropertyName));
}
/// <summary>
/// Invalidates appointments cache store and causes recurrences to be regenerated when requested.
/// </summary>
public void InvalidateAppointmentCache()
{
if (IsUpdateSuspended) return;
// Invalidate all
foreach (Year year in _Years.Values)
{
year.InvalidateAppointments();
}
AccessToday();
OnPropertyChanged(new PropertyChangedEventArgs(AppointmentsPropertyName));
}
private void AccessToday()
{
DateTime today = DateTime.Today;
Day day = this.GetDay(today);
int appCount = day.Appointments.Count;
}
private bool IsNonTimeProperty(string propertyName)
{
if (propertyName == "Description" || propertyName == "IsRecurringInstance" || propertyName == "Tag"
|| propertyName == "OwnerKey" || propertyName == "IsSelected" || propertyName == "Locked" || propertyName=="LocalStartTime" || propertyName=="LocalEndTime")
return true;
return false;
}
private int _UpdatesCount = 0;
/// <summary>
/// Suspends internal control updates to the cache structures etc. When making changes on multiple appointments
/// time related properties or when adding multiple appointments before doing so call BeginUpdate and after
/// updates are done call EndUpdate method to optimize performance.
/// <remarks>Calls to BeginUpdate method can be nested and only last outer most EndUpdate call will resume internal control updates.</remarks>
/// </summary>
public void BeginUpdate()
{
_UpdatesCount++;
}
/// <summary>
/// Resumes internal control updates that were suspended using BeginUpdate call and invalidates internal cache.
/// </summary>
public void EndUpdate()
{
if (_UpdatesCount == 0)
throw new InvalidOperationException("EndUpdate must be called AFTER BeginUpdate");
_UpdatesCount--;
if (_UpdatesCount == 0)
InvalidateAppointmentCache();
}
/// <summary>
/// Gets whether internal control update is suspended due to the call to BeginUpdate method.
/// </summary>
[Browsable(false)]
public bool IsUpdateSuspended
{
get
{
return _UpdatesCount > 0;
}
}
internal static string AppointmentsPropertyName
{
get { return "Appointments"; }
}
internal static string WorkDaysPropertyName
{
get { return "WorkDays"; }
}
internal static string CalendarWorkDaysPropertyName
{
get { return "CalendarWorkDays"; }
}
private TimeZoneInfo _DisplayTimeZone = null;
/// <summary>
/// Gets or sets the default display time zone used for the appointments. Default value is null which indicates that system time-zone is used.
/// Display Time zone can also be set for each Owner on Owner object. Value set here is used if specific display time-zone is not set on user.
/// </summary>
[DefaultValue(null)]
public TimeZoneInfo DisplayTimeZone
{
get { return _DisplayTimeZone; }
set
{
if (value != _DisplayTimeZone)
{
TimeZoneInfo oldValue = _DisplayTimeZone;
_DisplayTimeZone = value;
InvalidateAppointmentTimes();
InvalidateAppointmentCache();
OnDisplayTimeZoneChanged(oldValue, value);
}
}
}
private void InvalidateAppointmentTimes()
{
foreach (Appointment item in _Appointments)
{
item.InvokeLocalTimePropertyChange();
}
}
private void OnDisplayTimeZoneChanged(TimeZoneInfo oldValue, TimeZoneInfo newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("DisplayTimeZone"));
}
internal void InvokeAppointmentStartTimeReached(Appointment appointment)
{
OnAppointmentStartTimeReached(new AppointmentEventArgs(appointment));
}
/// <summary>
/// Raises AppointmentStartTimeReached event.
/// </summary>
/// <param name="appointmentEventArgs">Event arguments</param>
protected virtual void OnAppointmentStartTimeReached(AppointmentEventArgs appointmentEventArgs)
{
AppointmentEventHandler handler = AppointmentStartTimeReached;
if (handler != null)
handler(this, appointmentEventArgs);
}
internal void InvokeReminderNotification(Reminder reminder)
{
OnReminderNotification(new ReminderEventArgs(reminder));
}
/// <summary>
/// Raises ReminderNotification event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnReminderNotification(ReminderEventArgs e)
{
ReminderEventHandler h = ReminderNotification;
if (h != null)
h(this, e);
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null)
eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
#region CustomReminders
private ReminderCollection _CustomReminders = null;
/// <summary>
/// Gets the collection of custom reminders that are not associated with appointments.
/// </summary>
public ReminderCollection CustomReminders
{
get
{
if (_CustomReminders == null) _CustomReminders = new ReminderCollection(this);
return _CustomReminders;
}
}
#endregion
}
#region Events Support
public delegate void AppointmentEventHandler(object sender, AppointmentEventArgs e);
/// <summary>
/// Defines arguments for appointment related events.
/// </summary>
public class AppointmentEventArgs : EventArgs
{
/// <summary>
/// Gets the appointment referenced by this event.
/// </summary>
public Appointment Appointment;
/// <summary>
/// Initializes a new instance of the AppointmentEventArgs class.
/// </summary>
/// <param name="appointment"></param>
public AppointmentEventArgs(Appointment appointment)
{
Appointment = appointment;
}
}
#endregion
}
#endif

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents specific date based work day.
/// </summary>
public class CalendarWorkDay : BaseWorkDay
{
#region Internal Implementation
/// <summary>
/// Initializes a new instance of the WorkDay class.
/// </summary>
public CalendarWorkDay()
{
}
/// <summary>
/// Initializes a new instance of the WorkDay class.
/// </summary>
/// <param name="date">Date this work-day represents</param>
public CalendarWorkDay(DateTime date)
{
_Date = date;
}
private DateTime _Date = DateTime.MinValue;
/// <summary>
/// Gets or sets the date this day represents.
/// </summary>
public DateTime Date
{
get { return _Date; }
set
{
value = value.Date;
if (value != _Date)
{
DateTime oldValue = _Date;
_Date = value;
OnDateChanged(oldValue, value);
}
}
}
/// <summary>
/// Called when Date property has changed.
/// </summary>
/// <param name="oldValue">Old property value.</param>
/// <param name="newValue">New property value.</param>
protected virtual void OnDateChanged(DateTime oldValue, DateTime newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Date"));
}
#endregion
}
}

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents collection of calendar work days.
/// </summary>
public class CalendarWorkDayCollection : Collection<CalendarWorkDay>
{
#region Constructor
/// <summary>
/// Initializes a new instance of the AppointmentCollection class.
/// </summary>
/// <param name="calendar"></param>
public CalendarWorkDayCollection(CalendarModel calendar)
{
_Calendar = calendar;
}
/// <summary>
/// Initializes a new instance of the CalendarWorkDayCollection class.
/// </summary>
/// <param name="owner"></param>
public CalendarWorkDayCollection(Owner owner)
{
_Owner = owner;
}
#endregion
#region Internal Implementation
private Dictionary<DateTime, CalendarWorkDay> _ItemsDictionary = new Dictionary<DateTime, CalendarWorkDay>();
private Owner _Owner = null;
/// <summary>
/// Gets the Owner of work-day collection.
/// </summary>
public Owner Owner
{
get { return _Owner; }
internal set { _Owner = value; }
}
private CalendarModel _Calendar = null;
/// <summary>
/// Gets the calendar collection is associated with.
/// </summary>
public CalendarModel Calendar
{
get { return _Calendar; }
internal set
{
_Calendar = value;
UpdateItemsCalendarModel();
}
}
internal void UpdateItemsCalendarModel()
{
CalendarModel model = GetCalendarModel();
foreach (CalendarWorkDay item in this.Items)
{
item.Calendar = model;
}
}
protected override void RemoveItem(int index)
{
CalendarWorkDay day = this[index];
OnBeforeRemove(index, day);
base.RemoveItem(index);
OnAfterRemove(index, day);
}
private void OnAfterRemove(int index, CalendarWorkDay day)
{
_ItemsDictionary.Remove(day.Date);
CalendarModel model = GetCalendarModel();
if (model != null)
model.CalendarWorkDateRemoved(day);
}
private void OnBeforeRemove(int index, CalendarWorkDay day)
{
day.Calendar = null;
}
protected override void InsertItem(int index, CalendarWorkDay item)
{
OnBeforeInsert(index, item);
base.InsertItem(index, item);
OnAfterInsert(index, item);
}
private void OnAfterInsert(int index, CalendarWorkDay item)
{
CalendarModel model = GetCalendarModel();
if (model != null)
model.CalendarWorkDateAdded(item);
_ItemsDictionary.Add(item.Date, item);
}
private void OnBeforeInsert(int index, CalendarWorkDay item)
{
if (this[item.Date] != null)
throw new InvalidOperationException("Date '" + item.Date.ToString() + "' already in collection.");
item.Calendar = GetCalendarModel();
}
private CalendarModel GetCalendarModel()
{
if (_Calendar != null) return _Calendar;
if (_Owner != null) return _Owner.Calendar;
return null;
}
protected override void SetItem(int index, CalendarWorkDay newItem)
{
CalendarWorkDay oldItem = this[index];
OnBeforeSetItem(index, oldItem, newItem);
base.SetItem(index, newItem);
OnAfterSetItem(index, oldItem, newItem);
}
private void OnAfterSetItem(int index, CalendarWorkDay oldItem, CalendarWorkDay newItem)
{
CalendarModel model = GetCalendarModel();
if (model != null)
{
model.CalendarWorkDateRemoved(oldItem);
model.CalendarWorkDateAdded(newItem);
}
}
private void OnBeforeSetItem(int index, CalendarWorkDay oldItem, CalendarWorkDay newItem)
{
if (this[newItem.Date] != null)
throw new InvalidOperationException("Date '" + newItem.Date.ToString() + "' already in collection.");
oldItem.Calendar = null;
newItem.Calendar = GetCalendarModel();
}
protected override void ClearItems()
{
CalendarModel model = GetCalendarModel();
foreach (CalendarWorkDay item in this)
{
item.Calendar = null;
if (model != null)
model.CalendarWorkDateRemoved(item);
}
base.ClearItems();
}
/// <summary>
/// Gets the item based on the Key assigned to the item
/// </summary>
/// <param name="date">Date to retrieve data for.</param>
/// <returns>Reference to CalendarWorkDay or null if no day in collection.</returns>
public CalendarWorkDay this[DateTime date]
{
get
{
CalendarWorkDay item = null;
if (_ItemsDictionary.TryGetValue(date.Date, out item))
return item;
return null;
}
}
#endregion
}
}

View File

@@ -0,0 +1,142 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Defines the daily recurrence settings.
/// </summary>
public class DailyRecurrenceSettings : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Internal Implementation
private AppointmentRecurrence _Recurrence = null;
/// <summary>
/// Initializes a new instance of the DailyRecurrenceSettings class.
/// </summary>
/// <param name="recurrence"></param>
public DailyRecurrenceSettings(AppointmentRecurrence recurrence)
{
_Recurrence = recurrence;
}
private eDailyRecurrenceRepeat _RepeatOnDaysOfWeek = eDailyRecurrenceRepeat.All;
/// <summary>
/// Gets or sets the days of week on which appointment is repeated.
/// </summary>
[DefaultValue(eDailyRecurrenceRepeat.All)]
public eDailyRecurrenceRepeat RepeatOnDaysOfWeek
{
get { return _RepeatOnDaysOfWeek; }
set
{
if (value != _RepeatOnDaysOfWeek)
{
eDailyRecurrenceRepeat oldValue = _RepeatOnDaysOfWeek;
_RepeatOnDaysOfWeek = value;
OnRepeatOnDaysOfWeekChanged(oldValue, value);
}
}
}
private void OnRepeatOnDaysOfWeekChanged(eDailyRecurrenceRepeat oldValue, eDailyRecurrenceRepeat newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnDaysOfWeek"));
}
private int _RepeatInterval = 1;
/// <summary>
/// Gets or sets the interval between recurring appointments. Default value is 1. Setting this value to for example 3 means that
/// recurrence is repeated every 3 days.
/// </summary>
[DefaultValue(1)]
public int RepeatInterval
{
get { return _RepeatInterval; }
set
{
if (value != _RepeatInterval)
{
int oldValue = _RepeatInterval;
_RepeatInterval = value;
OnRepeatIntervalChanged(oldValue, value);
}
}
}
private void OnRepeatIntervalChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatInterval"));
}
private bool _ExplicitDailyRecurrence = false;
/// <summary>
/// Indicates whether appointment is explicitly repeated every day regardless of its end time. By default end time of appointment + 1 day is considered as next
/// starting point for appointment. When this property is set to true appointment start time + 1 day is used as next starting point of recurrence.
/// </summary>
[DefaultValue(false), Description("Indicates whether appointment is explicitly repeated every day regardless of its end time. By default end time of appointment + 1 day is considered as next starting point for appointment. When this property is set to true appointment start time + 1 day is used as next starting point of recurrence.")]
public bool ExplicitDailyRecurrence
{
get { return _ExplicitDailyRecurrence; }
set
{
if (value != _ExplicitDailyRecurrence)
{
bool oldValue = _ExplicitDailyRecurrence;
_ExplicitDailyRecurrence = value;
OnExplicitDailyRecurrenceChanged(oldValue, value);
}
}
}
/// <summary>
/// Called when ExplicitDailyRecurrence property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnExplicitDailyRecurrenceChanged(bool oldValue, bool newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("ExplicitDailyRecurrence"));
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null) eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,206 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
namespace DevComponents.Schedule.Model
{
public static class DateTimeHelper
{
/// <summary>
/// Returns number of weekdays (Monday-Friday) between two dates.
/// </summary>
/// <param name="startDateTime">Start date</param>
/// <param name="endDateTime">End date</param>
/// <returns>Total number of weekdays between two dates</returns>
public static int TotalWeekDays(DateTime startDateTime, DateTime endDateTime)
{
int totalDays = 0;
startDateTime = new DateTime(startDateTime.Year, startDateTime.Month, startDateTime.Day);
endDateTime = new DateTime(endDateTime.Year, endDateTime.Month, endDateTime.Day, 23, 59, 0);
// Start date to monday
if (startDateTime.DayOfWeek == DayOfWeek.Saturday)
startDateTime = startDateTime.AddDays(2);
else if (startDateTime.DayOfWeek == DayOfWeek.Sunday)
startDateTime = startDateTime.AddDays(1);
else
{
DateTime newStartDateTime = startDateTime.AddDays(8 - (int)startDateTime.DayOfWeek);
if (newStartDateTime > endDateTime)
{
if (endDateTime.DayOfWeek == DayOfWeek.Saturday)
endDateTime = endDateTime.AddDays(-1);
else if (endDateTime.DayOfWeek == DayOfWeek.Sunday)
endDateTime = endDateTime.AddDays(-2);
return (int)Math.Ceiling(Math.Max(0, endDateTime.Subtract(startDateTime).TotalDays));
}
totalDays = 6 - (int)startDateTime.DayOfWeek;
startDateTime = newStartDateTime;
}
// End date to Sunday
if (endDateTime.DayOfWeek == DayOfWeek.Saturday)
endDateTime = endDateTime.AddDays(1);
else if (endDateTime.DayOfWeek != DayOfWeek.Sunday)
{
int d = (int)endDateTime.DayOfWeek;
DateTime newEndDateTime = endDateTime.AddDays(-(int)endDateTime.DayOfWeek);
totalDays += d;
endDateTime=newEndDateTime;
}
int t = (int)Math.Max(0, Math.Ceiling(endDateTime.Subtract(startDateTime).TotalDays));
if (t > 0)
totalDays += (t / 7) * 5;
return totalDays;
}
/// <summary>
/// Return total number of days specified by day parameter between two dates.
/// </summary>
/// <param name="startDate">Start date.</param>
/// <param name="endDate">End date.</param>
/// <param name="day">Day of week</param>
/// <returns>Number of days between two dates</returns>
public static int TotalDays(DateTime startDate, DateTime endDate, DayOfWeek day)
{
if (endDate < startDate) return 0;
if (startDate.DayOfWeek > day)
startDate = startDate.AddDays(7 - ((int)startDate.DayOfWeek - (int)day));
else
startDate = startDate.AddDays(day - startDate.DayOfWeek);
if (endDate < startDate) return 0;
if (endDate.DayOfWeek < day)
endDate = endDate.AddDays(-(7 - ((int)day - (int)endDate.DayOfWeek)));
else
endDate = endDate.AddDays(day - endDate.DayOfWeek);
if (endDate.Subtract(startDate).TotalDays <= 1) return 1;
int t = (int)Math.Ceiling(endDate.Subtract(startDate).TotalDays);
int totalDays = (int)Math.Floor(Math.Max(1, (double)t / 7)) + 1; // +1 since endDate is always on the day
//if (endDate.RelativeDayOfWeek == day) totalDays++;
return totalDays;
}
public static int TotalNumberOfDays(DateTime startDate, DateTime endDate, eDayOfWeekRecurrence daysOfWeek)
{
int totalDays=0;
if (daysOfWeek == eDayOfWeekRecurrence.All)
return (int)Math.Ceiling(endDate.Subtract(startDate).TotalDays);
if ((daysOfWeek & eDayOfWeekRecurrence.Friday) != 0)
totalDays += TotalDays(startDate, endDate, DayOfWeek.Friday);
if ((daysOfWeek & eDayOfWeekRecurrence.Monday) != 0)
totalDays += TotalDays(startDate, endDate, DayOfWeek.Monday);
if ((daysOfWeek & eDayOfWeekRecurrence.Saturday) != 0)
totalDays += TotalDays(startDate, endDate, DayOfWeek.Saturday);
if ((daysOfWeek & eDayOfWeekRecurrence.Sunday) != 0)
totalDays += TotalDays(startDate, endDate, DayOfWeek.Sunday);
if ((daysOfWeek & eDayOfWeekRecurrence.Thursday) != 0)
totalDays += TotalDays(startDate, endDate, DayOfWeek.Thursday);
if ((daysOfWeek & eDayOfWeekRecurrence.Tuesday) != 0)
totalDays += TotalDays(startDate, endDate, DayOfWeek.Tuesday);
if ((daysOfWeek & eDayOfWeekRecurrence.Wednesday) != 0)
totalDays += TotalDays(startDate, endDate, DayOfWeek.Wednesday);
return totalDays;
}
/// <summary>
/// Returns the date/time that represents end of the day value.
/// </summary>
/// <param name="_DayDate"></param>
/// <returns></returns>
public static DateTime EndOfDay(DateTime day)
{
return new DateTime(day.Year, day.Month, day.Day, 23, 59, 59);
}
/// <summary>
/// Returns the date/time that represents beginning of the day value.
/// </summary>
/// <param name="_DayDate"></param>
/// <returns></returns>
public static DateTime BeginningOfDay(DateTime day)
{
return new DateTime(day.Year, day.Month, day.Day, 0, 0, 0);
}
/// <summary>
/// Returns true if date falls at begging of the day 12:00 AM
/// </summary>
/// <param name="_DayDate"></param>
/// <returns></returns>
public static bool IsBeginningOfDay(DateTime day)
{
return day.Equals(BeginningOfDay(day));
}
internal static bool HasDay(DayOfWeek dayOfWeek, eDayOfWeekRecurrence days)
{
if (dayOfWeek == DayOfWeek.Monday && (days & eDayOfWeekRecurrence.Monday) != 0) return true;
if (dayOfWeek == DayOfWeek.Tuesday && (days & eDayOfWeekRecurrence.Tuesday) != 0) return true;
if (dayOfWeek == DayOfWeek.Wednesday && (days & eDayOfWeekRecurrence.Wednesday) != 0) return true;
if (dayOfWeek == DayOfWeek.Thursday && (days & eDayOfWeekRecurrence.Thursday) != 0) return true;
if (dayOfWeek == DayOfWeek.Friday && (days & eDayOfWeekRecurrence.Friday) != 0) return true;
if (dayOfWeek == DayOfWeek.Saturday && (days & eDayOfWeekRecurrence.Saturday) != 0) return true;
if (dayOfWeek == DayOfWeek.Sunday && (days & eDayOfWeekRecurrence.Sunday) != 0) return true;
return false;
}
public static bool IsWeekendDay(DateTime currentDay)
{
return currentDay.DayOfWeek == DayOfWeek.Sunday || currentDay.DayOfWeek == DayOfWeek.Saturday;
}
/// <summary>
/// Gets greater date between two dates.
/// </summary>
/// <param name="date1">Date 1</param>
/// <param name="date2">Date 2</param>
/// <returns>Greater date.</returns>
public static DateTime MaxDate(DateTime date1, DateTime date2)
{
return date1 > date2 ? date1 : date2;
}
/// <summary>
/// Returns true if both dates are on same day and year.
/// </summary>
/// <param name="date1">First date</param>
/// <param name="date2">Second date</param>
/// <returns>true if dates are on same day and year</returns>
public static bool IsSameDay(DateTime date1, DateTime date2)
{
return (date1.Year == date2.Year && date1.Month == date2.Month &&
date1.Day == date2.Day) || date1.Date.AddDays(1) == date2;
//return date1.Year == date2.Year && date1.Month == date2.Month && date1.Day == date2.Day;
}
/// <summary>
/// Returns true if time periods overlap.
/// </summary>
/// <param name="startTime1">Start of first period.</param>
/// <param name="endTime1">End of first period.</param>
/// <param name="startTime2">Start of second period.</param>
/// <param name="endTime2">End of second period.</param>
/// <returns>true if periods overlap</returns>
public static bool TimePeriodsOverlap(DateTime startTime1, DateTime endTime1, DateTime startTime2, DateTime endTime2)
{
if (startTime1 <= startTime2 && endTime1 > startTime2 || startTime1 >= startTime2 && startTime1 < endTime2)
return true;
return false;
}
}
}
#endif

View File

@@ -0,0 +1,77 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents the calendar day.
/// </summary>
public class Day
{
#region Constructor
/// <summary>
/// Initializes a new instance of the Day class.
/// </summary>
/// <param name="dayDate"></param>
/// <param name="calendar"></param>
public Day(DateTime dayDate, CalendarModel calendar)
{
_DayDate = dayDate;
_Calendar = calendar;
}
#endregion
#region Internal Implementation
private AppointmentSubsetCollection _Appointments;
/// <summary>
/// Gets appointments that start on this day.
/// </summary>
public AppointmentSubsetCollection Appointments
{
get
{
if (_Appointments == null)
_Appointments = new AppointmentSubsetCollection(_Calendar, _DayDate, DateTimeHelper.EndOfDay(_DayDate));
return _Appointments;
}
}
/// <summary>
/// Invalidate the day appointments
/// </summary>
internal void InvalidateAppointments()
{
if (_Appointments != null)
_Appointments.InvalidateCollection();
}
private DateTime _DayDate = DateTime.MinValue;
/// <summary>
/// Gets the date this day represents.
/// </summary>
[Browsable(false)]
public DateTime DayDate
{
get { return _DayDate; }
internal set { _DayDate = value; }
}
private CalendarModel _Calendar;
/// <summary>
/// Gets the Calendar this day is part of.
/// </summary>
[Browsable(false)]
public CalendarModel Calendar
{
get { return _Calendar; }
internal set { _Calendar = value; }
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,191 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Specifies notification type when appointment start time has been reached.
/// </summary>
[Flags()]
public enum eStartTimeAction
{
/// <summary>
/// No action is taken.
/// </summary>
None = 0,
/// <summary>
/// StartTimeReached event is fired.
/// </summary>
StartTimeReachedEvent = 1,
/// <summary>
/// StartTimeCommand is executed.
/// </summary>
Command = 2,
/// <summary>
/// Both event and command are performed.
/// </summary>
StartTimeReachedEventAndCommand = StartTimeReachedEvent | Command
}
/// <summary>
/// Specifies notification type when reminder time has been reached.
/// </summary>
[Flags()]
public enum eReminderAction
{
/// <summary>
/// No action is taken.
/// </summary>
None = 0,
/// <summary>
/// Reminder event is fired.
/// </summary>
Event = 1,
/// <summary>
/// Reminder Command is executed.
/// </summary>
Command = 2,
/// <summary>
/// Both event and command are performed.
/// </summary>
EventAndCommand = Event | Command
}
/// <summary>
/// Specifies the recurrence range type.
/// </summary>
public enum eRecurrenceRangeLimitType
{
/// <summary>
/// Recurrence range has no end date specified.
/// </summary>
NoEndDate,
/// <summary>
/// Recurrence ends on date specified by RangeEndDate property.
/// </summary>
RangeEndDate,
/// <summary>
/// Recurrence ends after specified number of repeats by RangeNumberOfOccurrences property.
/// </summary>
RangeNumberOfOccurrences
}
/// <summary>
/// Specifies the pattern type for appointment recurrence.
/// </summary>
public enum eRecurrencePatternType
{
/// <summary>
/// Appointment recurs daily.
/// </summary>
Daily,
/// <summary>
/// Appointment recurs weekly.
/// </summary>
Weekly,
/// <summary>
/// Appointment recurs monthly.
/// </summary>
Monthly,
/// <summary>
/// Appointment recurs yearly.
/// </summary>
Yearly
}
/// <summary>
/// Specifies the relative day in month for recurrence.
/// </summary>
public enum eRelativeDayInMonth
{
/// <summary>
/// No value specified.
/// </summary>
None,
/// <summary>
/// The first occurrence of the specified day in its month.
/// </summary>
First,
/// <summary>
/// The second occurrence of the specified day in its month.
/// </summary>
Second,
/// <summary>
/// The third occurrence of the specified day in its month.
/// </summary>
Third,
/// <summary>
/// The fourth occurrence of the specified day in its month.
/// </summary>
Fourth,
/// <summary>
/// The last occurrence of the specified day in its month.
/// </summary>
Last
}
/// <summary>
/// Specifies on which day the appointment is repeated.
/// </summary>
[Flags()]
public enum eDayOfWeekRecurrence
{
None = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64,
WeekendDays = Saturday | Sunday,
WeekDays = Monday | Tuesday | Wednesday | Thursday | Friday,
All = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
}
/// <summary>
/// Specifies on which days daily recurrence is repeated.
/// </summary>
public enum eDailyRecurrenceRepeat
{
/// <summary>
/// Appointment is repeated on all days.
/// </summary>
All = eDayOfWeekRecurrence.Monday | eDayOfWeekRecurrence.Tuesday | eDayOfWeekRecurrence.Wednesday | eDayOfWeekRecurrence.Thursday | eDayOfWeekRecurrence.Friday | eDayOfWeekRecurrence.Saturday | eDayOfWeekRecurrence.Sunday,
/// <summary>
/// Appointment is repeated on week-days only, Monday-Friday.
/// </summary>
WeekDays = eDayOfWeekRecurrence.Monday | eDayOfWeekRecurrence.Tuesday | eDayOfWeekRecurrence.Wednesday | eDayOfWeekRecurrence.Thursday | eDayOfWeekRecurrence.Friday,
/// <summary>
/// Appointment is repeated on weekend-days only, Saturday-Sunday.
/// </summary>
WeekendDays = eDayOfWeekRecurrence.WeekendDays
}
/// <summary>
/// Specifies on which month monthly appointment recurrence is repeated.
/// </summary>
[Flags()]
public enum eMonthRecurrence
{
January = 1,
February = 2,
March = 4,
April = 8,
May = 16,
June = 32,
July = 64,
August = 128,
September = 256,
October = 512,
November = 1024,
December = 2048,
All = January | February | March | April | May | June | July | August | September | October | November | December
}
}
#endif

View File

@@ -0,0 +1,16 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents collection of holidays.
/// </summary>
public class HolidaysCollection
{
}
}
#endif

View File

@@ -0,0 +1,48 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Defines an interface for property notification change.
/// </summary>
public interface INotifySubPropertyChanged
{
/// <summary>
/// Occurs when property on object or its sub-objects has changed.
/// </summary>
event SubPropertyChangedEventHandler SubPropertyChanged;
}
public delegate void SubPropertyChangedEventHandler(object sender, SubPropertyChangedEventArgs e);
/// <summary>
/// Defines event arguments for SubPropertyChanged event.
/// </summary>
public class SubPropertyChangedEventArgs : EventArgs
{
/// <summary>
/// Reference to PropertyChangedArgs of changed property.
/// </summary>
public PropertyChangedEventArgs PropertyChangedArgs = null;
/// <summary>
/// Reference to the source object of the event.
/// </summary>
public object Source = null;
/// <summary>
/// Initializes a new instance of the SubPropertyChangedEventArgs class.
/// </summary>
/// <param name="propertyChangedArgs"></param>
/// <param name="source"></param>
public SubPropertyChangedEventArgs(object source, PropertyChangedEventArgs propertyChangedArgs)
{
PropertyChangedArgs = propertyChangedArgs;
Source = source;
}
}
}
#endif

View File

@@ -0,0 +1,156 @@
using System.Collections.Generic;
namespace DevComponents.Schedule.Model.Serialization
{
public class CalendarEntry
{
#region Private variables
private string _Id = "";
private string _Value = "";
private List<AttributeData> _Attributes;
private int _LineStart;
private int _LineEnd;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="lineStart">Text line start</param>
/// <param name="lineEnd">Text line end</param>
public CalendarEntry(int lineStart, int lineEnd)
{
_LineStart = lineStart;
_LineEnd = lineEnd;
_Attributes = new List<AttributeData>();
}
#region Public properties
#region Attributes
/// <summary>
/// Attributes
/// </summary>
public List<AttributeData> Attributes
{
get { return (_Attributes); }
set { _Attributes = value; }
}
#endregion
#region Id
/// <summary>
/// Id
/// </summary>
public string Id
{
get { return (_Id); }
set { _Id = value; }
}
#endregion
#region LineEnd
/// <summary>
/// LineEnd
/// </summary>
public int LineEnd
{
get { return (_LineEnd); }
set { _LineEnd = value; }
}
#endregion
#region LineStart
/// <summary>
/// LineStart
/// </summary>
public int LineStart
{
get { return (_LineStart); }
set { _LineStart = value; }
}
#endregion
#region Value
/// <summary>
/// Value
/// </summary>
public string Value
{
get { return (_Value); }
set { _Value = value; }
}
#endregion
#endregion
}
#region AttributeData
public class AttributeData
{
#region Private variables
private string _Id;
private string _Value;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="id">Id</param>
/// <param name="value">Value</param>
public AttributeData(string id, string value)
{
_Id = id;
_Value = value;
}
#region Public properties
#region Id
/// <summary>
/// Gets or sets the attribute Id
/// </summary>
public string Id
{
get { return (_Id); }
set { _Id = value; }
}
#endregion
#region Value
/// <summary>
/// Gets or sets the attribute value
/// </summary>
public string Value
{
get { return (_Value); }
set { _Value = value; }
}
#endregion
#endregion
}
#endregion
}

View File

@@ -0,0 +1,989 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace DevComponents.Schedule.Model.Serialization
{
/// <summary>
/// Export DNB internal Model/Appointment data layout into
/// ICS (Internet Calendaring and Scheduling - RFC5545) format file.
/// </summary>
public class IcsExporter
{
#region Private constants
private const int FoldCount = 74;
#endregion
#region Private variables
private DateTime _DtStamp = DateTime.Now;
private string _ProdId = "PRODID:-//DotNetBar\\, Inc//iCal 1.0//EN";
private CalendarModel _Model;
private string[] _CalNames;
private string[] _OwnerKeys;
private string _ExportFile;
private StreamWriter _StreamWriter;
#endregion
#region Constructors
/// <summary>
/// IcsExporter
/// </summary>
public IcsExporter()
{
}
/// <summary>
/// IcsExporter
/// </summary>
/// <param name="model"></param>
public IcsExporter(CalendarModel model)
{
Model = model;
}
#endregion
#region Public properties
#region ProdId
/// <summary>
/// Gets or sets the Calendar Product Id.
/// </summary>
public string ProdId
{
get { return (_ProdId); }
set { _ProdId = value; }
}
#endregion
#region Model
/// <summary>
/// CalendarModel
/// </summary>
public CalendarModel Model
{
get { return (_Model); }
set { _Model = value; }
}
#endregion
#endregion
#region Export
/// <summary>
/// Exports Appointment data in the iCalendar format
/// </summary>
/// <param name="ownerKeys">Array of OwnerKeys</param>
/// <param name="calNames">Array of CalendarNames</param>
/// <param name="streamWriter">Export StreamWriter</param>
public void Export(string[] ownerKeys, string[] calNames, StreamWriter streamWriter)
{
if (_Model == null)
throw new Exception("Model can not be null.");
_CalNames = calNames;
_OwnerKeys = ownerKeys;
if (streamWriter == null)
throw new Exception("Invalid StreamWriter.");
_StreamWriter = streamWriter;
if (String.IsNullOrEmpty(_ExportFile) == true)
_ExportFile = streamWriter.BaseStream.ToString();
ExportOwnerData();
streamWriter.Flush();
}
#region Export variations
/// <summary>
/// Exports all appointments to the given export file.
/// </summary>
/// <param name="exportFile">Output file path</param>
public void Export(string exportFile)
{
Export((string[])null, null, exportFile);
}
/// <summary>
/// Exports all appointments to the given export stream.
/// </summary>
/// <param name="streamWriter">Output StreamWriter</param>
public void Export(StreamWriter streamWriter)
{
Export((string[])null, null, streamWriter);
}
/// <summary>
/// Exports all appointments for the specified OwnerKey to
/// the given export file.
/// </summary>
/// <param name="ownerKey">Appointment OwnerKey</param>
/// <param name="exportFile">Output file path</param>
public void Export(string ownerKey, string exportFile)
{
Export(ownerKey, ownerKey, exportFile);
}
/// <summary>
/// Exports all appointments for the specified OwnerKey to
/// the given export stream.
/// </summary>
/// <param name="ownerKey">Appointment OwnerKey</param>
/// <param name="streamWriter">Output StreamWriter</param>
public void Export(string ownerKey, StreamWriter streamWriter)
{
Export(ownerKey, ownerKey, streamWriter);
}
/// <summary>
/// Exports all appointments for the specified OwnerKey to
/// the given export file, using the specified calendar name.
/// </summary>
/// <param name="ownerKey">Appointment OwnerKey</param>
/// <param name="calName">Associated Calendar Name</param>
/// <param name="exportFile">Output file path</param>
public void Export(string ownerKey, string calName, string exportFile)
{
string[] ownerKeys = new string[] { ownerKey };
string[] calNames = new string[] { calName };
Export(ownerKeys, calNames, exportFile);
}
/// <summary>
/// Exports all appointments for the specified OwnerKey to
/// the given export stream, using the specified calendar name.
/// </summary>
/// <param name="ownerKey">Appointment OwnerKey</param>
/// <param name="calName">Associated Calendar Name</param>
/// <param name="streamWriter">Output StreamWriter</param>
public void Export(string ownerKey, string calName, StreamWriter streamWriter)
{
string[] ownerKeys = new string[] { ownerKey };
string[] calNames = new string[] { calName };
Export(ownerKeys, calNames, streamWriter);
}
/// <summary>
/// Exports all appointments for the specified OwnerKey array to
/// the given export file, using the specified associated calendar name array.
/// </summary>
/// <param name="ownerKeys">Array of OwnerKeys</param>
/// <param name="calNames">Array of 1:1 associated Calendar Names</param>
/// <param name="exportFile">Output file path</param>
public virtual void Export(string[] ownerKeys, string[] calNames, string exportFile)
{
using (StreamWriter streamWriter = new StreamWriter(exportFile))
Export(ownerKeys, calNames, streamWriter);
}
#endregion
#endregion
#region ExportOwnerData
/// <summary>
/// Exports model data for each requested OwnerKey
/// </summary>
private void ExportOwnerData()
{
if (_OwnerKeys == null)
_OwnerKeys = GetDefaultOwnerKeys();
if (_CalNames == null)
_CalNames = _OwnerKeys;
string lastCalName = null;
for (int i = 0; i < _OwnerKeys.Length; i++)
{
string ownerKey = _OwnerKeys[i] ?? "";
string calName = ((i < _CalNames.Length)
? _CalNames[i]
: _CalNames[_CalNames.Length - 1]) ?? ownerKey;
if (calName.Equals(lastCalName) == false)
{
if (lastCalName != null)
ExportCalEnd();
ExportCalBegin(calName);
lastCalName = calName;
}
foreach (Appointment app in Model.Appointments)
{
if (IsAppointmentVisible(app, ownerKey) == true)
ExportVEvent(app);
}
}
if (lastCalName != null)
ExportCalEnd();
}
#endregion
#region ExportCalBegin
/// <summary>
/// Exports the beginning calendar sequence
/// </summary>
/// <param name="calName"></param>
private void ExportCalBegin(string calName)
{
ExportLine("BEGIN:VCALENDAR");
ExportLine("CALSCALE:GREGORIAN");
if (_ProdId != null)
ExportLine(_ProdId);
ExportLine("X-WR-CALNAME;VALUE=TEXT:" + calName);
ExportLine("VERSION:2.0");
}
#endregion
#region ExportCalEnd
/// <summary>
/// Exports the ending calendar sequence
/// </summary>
private void ExportCalEnd()
{
ExportLine("END:VCALENDAR\n");
}
#endregion
#region ExportVEvent
#region ExportVEvent
/// <summary>
/// Exports a calendar event (appointment)
/// </summary>
/// <param name="app"></param>
private void ExportVEvent(Appointment app)
{
ExportLine("\nBEGIN:VEVENT");
if (String.IsNullOrEmpty(app.Subject) == false)
ExportLine("SUMMARY:" + AddMetaData(app.Subject));
if (String.IsNullOrEmpty(app.Description) == false)
ExportLine("DESCRIPTION:" + AddMetaData(app.Description));
ExportLine("UID:" + Guid.NewGuid().ToString());
ExportLine("DTSTAMP:" + GetUniversalTime(_DtStamp));
if (String.IsNullOrEmpty(app.CategoryColor) == false)
ExportLine("X-DNB-CATEGORYCOLOR:" + app.CategoryColor);
if (String.IsNullOrEmpty(app.DisplayTemplate) == false)
ExportLine("X-DNB-DISPLAYTEMPLATE:" + AddMetaData(app.DisplayTemplate));
if (app.ImageAlign != eImageContentAlignment.TopLeft)
ExportLine("X-DNB-IMAGEALIGN:" + Enum.GetName(typeof(eImageContentAlignment), app.ImageAlign));
if (String.IsNullOrEmpty(app.ImageKey) == false)
ExportLine("X-DNB-IMAGEKEY:" + app.ImageKey);
if (app.Locked == true)
ExportLine("X-DNB-LOCKED:true");
if (app.StartTimeAction != eStartTimeAction.None)
ExportLine("X-DNB-STARTTIMEACTION:" + Enum.GetName(typeof(eStartTimeAction), app.StartTimeAction));
if (String.IsNullOrEmpty(app.TimeMarkedAs) == false)
ExportLine("X-DNB-TIMEMARKEDAS:" + app.TimeMarkedAs);
if (String.IsNullOrEmpty(app.Tooltip) == false)
ExportLine("X-DNB-TOOLTIP:" + AddMetaData(app.Tooltip));
if ((app.StartTime.Hour == 0 && app.StartTime.Minute == 0) &&
(app.EndTime.Hour == 0 && app.EndTime.Minute == 0))
{
ExportLine("DTSTART;VALUE=DATE:" + app.StartTime.ToString("yyyyMMdd"));
if ((app.EndTime - app.StartTime).TotalMinutes != 60 * 24)
ExportLine("DTEND;VALUE=DATE:" + app.EndTime.ToString("yyyyMMdd"));
}
else
{
ExportLine("DTSTART:" + GetUniversalTime(app.StartTime));
ExportLine("DTEND:" + GetUniversalTime(app.EndTime));
}
if (app.Private == true)
ExportLine("CLASS:PRIVATE");
ExportRRule(app);
ExportAlarms(app);
ExportLine("END:VEVENT");
}
#region ExportRRule
#region ExportRRule
/// <summary>
/// Exports the appointment Recurrence Rule
/// </summary>
/// <param name="app"></param>
private void ExportRRule(Appointment app)
{
if (app.Recurrence != null)
{
switch (app.Recurrence.RecurrenceType)
{
case eRecurrencePatternType.Daily:
ExportDailyRRule(app.Recurrence);
break;
case eRecurrencePatternType.Weekly:
ExportWeeklyRRule(app.Recurrence);
break;
case eRecurrencePatternType.Monthly:
ExportMonthlyRRule(app.Recurrence);
break;
default:
ExportYearlyRRule(app);
break;
}
ExportExDate(app.Recurrence);
}
}
#endregion
#region ExportDailyRRule
/// <summary>
/// ExportDailyRRule
/// </summary>
/// <param name="recur"></param>
private void ExportDailyRRule(AppointmentRecurrence recur)
{
StringBuilder sb = new StringBuilder();
sb.Append("RRULE:FREQ=DAILY");
AddRRuleInterval(sb, recur.Daily.RepeatInterval);
AddRRuleByDay(sb, recur);
AddRRuleRangeInfo(sb, recur);
ExportLine(sb.ToString());
}
#endregion
#region ExportWeeklyRRule
/// <summary>
/// ExportWeeklyRRule
/// </summary>
/// <param name="recur"></param>
private void ExportWeeklyRRule(AppointmentRecurrence recur)
{
StringBuilder sb = new StringBuilder();
sb.Append("RRULE:FREQ=WEEKLY");
AddRRuleInterval(sb, recur.Weekly.RepeatInterval);
if (recur.Weekly.RepeatOnDaysOfWeek != eDayOfWeekRecurrence.None)
AddRRuleByDay(sb, recur.Weekly.RepeatOnDaysOfWeek);
AddRRuleRangeInfo(sb, recur);
ExportLine(sb.ToString());
}
#endregion
#region ExportMonthlyRRule
/// <summary>
/// ExportMonthlyRRule
/// </summary>
/// <param name="recur"></param>
private void ExportMonthlyRRule(AppointmentRecurrence recur)
{
StringBuilder sb = new StringBuilder();
sb.Append("RRULE:FREQ=MONTHLY");
AddRRuleInterval(sb, recur.Monthly.RepeatInterval);
if (recur.Monthly.RepeatOnRelativeDayInMonth == eRelativeDayInMonth.None)
sb.AppendFormat("{0}{1:D}", ";BYMONTHDAY=", recur.Monthly.RepeatOnDayOfMonth);
else
AddRRuleByDay(sb, recur.Monthly.RepeatOnRelativeDayInMonth, recur.Monthly.RelativeDayOfWeek);
AddRRuleRangeInfo(sb, recur);
ExportLine(sb.ToString());
}
#endregion
#region ExportYearlyRRule
/// <summary>
/// ExportYearlyRRule
/// </summary>
/// <param name="app"></param>
private void ExportYearlyRRule(Appointment app)
{
AppointmentRecurrence recur = app.Recurrence;
StringBuilder sb = new StringBuilder();
sb.Append("RRULE:FREQ=YEARLY");
sb.AppendFormat("{0}{1:D}", ";BYMONTH=", recur.Yearly.RepeatOnMonth);
if (recur.Yearly.RepeatOnRelativeDayInMonth == eRelativeDayInMonth.None)
{
if (recur.Yearly.RepeatOnDayOfMonth != app.StartTime.Day)
sb.AppendFormat("{0}{1:D}", ";BYMONTHDAY=", recur.Yearly.RepeatOnDayOfMonth);
}
else
{
AddRRuleByDay(sb, recur.Yearly.RepeatOnRelativeDayInMonth, recur.Yearly.RelativeDayOfWeek);
}
AddRRuleRangeInfo(sb, recur);
ExportLine(sb.ToString());
}
#endregion
#region AddRRuleByDay
/// <summary>
/// AddRRuleByDay
/// </summary>
/// <param name="sb"></param>
/// <param name="repeat"></param>
private void AddRRuleByDay(StringBuilder sb, eDayOfWeekRecurrence repeat)
{
sb.Append(";BYDAY=");
if ((repeat & eDayOfWeekRecurrence.Sunday) != 0)
sb.Append("SU,");
if ((repeat & eDayOfWeekRecurrence.Monday) != 0)
sb.Append("MO,");
if ((repeat & eDayOfWeekRecurrence.Tuesday) != 0)
sb.Append("TU,");
if ((repeat & eDayOfWeekRecurrence.Wednesday) != 0)
sb.Append("WE,");
if ((repeat & eDayOfWeekRecurrence.Thursday) != 0)
sb.Append("TH,");
if ((repeat & eDayOfWeekRecurrence.Friday) != 0)
sb.Append("FR,");
if ((repeat & eDayOfWeekRecurrence.Saturday) != 0)
sb.Append("SA,");
sb.Length--;
}
#endregion
#region AddRRuleByDay
/// <summary>
/// AddRRuleByDay
/// </summary>
/// <param name="sb"></param>
/// <param name="repeat"></param>
private void AddRRuleByDay(StringBuilder sb, AppointmentRecurrence recur)
{
if (recur.Daily.RepeatInterval > 1)
{
sb.Append(";BYDAY=");
}
else
{
switch (recur.Daily.RepeatOnDaysOfWeek)
{
case eDailyRecurrenceRepeat.All:
sb.Append(";BYDAY=SU,MO,TU,WE,TH,FR,SA");
break;
case eDailyRecurrenceRepeat.WeekDays:
sb.Append(";BYDAY=MO,TU,WE,TH,FR");
break;
default:
sb.Append(";BYDAY=SA,SU");
break;
}
}
}
#endregion
#region AddRRuleByDay
/// <summary>
/// AddRRuleByDay
/// </summary>
/// <param name="sb"></param>
/// <param name="rday"></param>
/// <param name="dow"></param>
private void AddRRuleByDay(StringBuilder sb, eRelativeDayInMonth rday, DayOfWeek dow)
{
sb.Append(";BYDAY=");
switch (dow)
{
case DayOfWeek.Sunday:
sb.Append("SU");
break;
case DayOfWeek.Monday:
sb.Append("MO");
break;
case DayOfWeek.Tuesday:
sb.Append("TU");
break;
case DayOfWeek.Wednesday:
sb.Append("WE");
break;
case DayOfWeek.Thursday:
sb.Append("TH");
break;
case DayOfWeek.Friday:
sb.Append("FR");
break;
default:
sb.Append("SA");
break;
}
switch (rday)
{
case eRelativeDayInMonth.First:
sb.Append(";BYSETPOS=1");
break;
case eRelativeDayInMonth.Second:
sb.Append(";BYSETPOS=2");
break;
case eRelativeDayInMonth.Third:
sb.Append(";BYSETPOS=3");
break;
case eRelativeDayInMonth.Fourth:
sb.Append(";BYSETPOS=4");
break;
case eRelativeDayInMonth.Last:
sb.Append(";BYSETPOS=-1");
break;
}
}
#endregion
#region AddRRuleInterval
/// <summary>
/// AddRRuleInterval
/// </summary>
/// <param name="sb"></param>
/// <param name="interval"></param>
private void AddRRuleInterval(StringBuilder sb, int interval)
{
if (interval > 1)
sb.Append(";INTERVAL=" + interval.ToString());
}
#endregion
#region AddRRuleRangeInfo
/// <summary>
/// AddRRuleRangeInfo
/// </summary>
/// <param name="sb"></param>
/// <param name="recur"></param>
private void AddRRuleRangeInfo(StringBuilder sb, AppointmentRecurrence recur)
{
switch (recur.RangeLimitType)
{
case eRecurrenceRangeLimitType.RangeNumberOfOccurrences:
if (recur.RangeNumberOfOccurrences > 0)
sb.Append(";COUNT=" + (recur.RangeNumberOfOccurrences + 1).ToString());
break;
case eRecurrenceRangeLimitType.RangeEndDate:
sb.Append(";UNTIL=" + GetUtcDate(recur.RangeEndDate));
break;
}
if (recur.RecurrenceStartDate != DateTime.MinValue && recur.RecurrenceStartDate != recur.Appointment.StartTime)
ExportLine("X-DNB-RECSTARTDATE=" + GetUtcDate(recur.RecurrenceStartDate));
}
#endregion
#endregion
#region ExportExDate
/// <summary>
/// ExportExDate
/// </summary>
/// <param name="recur"></param>
private void ExportExDate(AppointmentRecurrence recur)
{
if (recur.SkippedRecurrences != null)
{
foreach (DateTime date in recur.SkippedRecurrences)
ExportLine("EXDATE:" + GetUtcDate(date));
}
}
#endregion
#region ExportAlarms
/// <summary>
/// ExportAlarms
/// </summary>
/// <param name="app"></param>
private void ExportAlarms(Appointment app)
{
if (app.Reminders != null)
{
foreach (Reminder rem in app.Reminders)
{
ExportLine("\nBEGIN:VALARM");
if (string.IsNullOrEmpty(rem.Description) == false)
ExportLine("DESCRIPTION:" + rem.Description);
ExportLine("TRIGGER;VALUE=DURATION:" + GetDuration(rem.ReminderTime - app.StartTime));
ExportLine("ACTION:DISPLAY");
ExportLine("END:VALARM");
}
}
if (app.StartTimeAction != eStartTimeAction.None)
{
ExportLine("\nBEGIN:VALARM");
ExportLine("TRIGGER;VALUE=DURATION:PT0M");
ExportLine("ACTION:DISPLAY");
ExportLine("END:VALARM\n");
}
}
#endregion
#region GetDuration
/// <summary>
/// GetDuration
/// </summary>
/// <param name="ts"></param>
/// <returns></returns>
private string GetDuration(TimeSpan ts)
{
StringBuilder sb = new StringBuilder();
if (ts.TotalMinutes < 0)
sb.Append("-");
sb.Append("P");
int totalMinutes = (int)Math.Abs(ts.TotalMinutes);
int days = totalMinutes / (24 * 60);
if (days > 0)
{
sb.Append(days + "D");
totalMinutes %= (24 * 60);
}
if (totalMinutes > 0)
{
sb.Append("T");
int hours = totalMinutes / 60;
if (hours > 0)
{
sb.Append(hours + "H");
totalMinutes %= 60;
}
if (totalMinutes > 0)
sb.Append(totalMinutes + "M");
}
return (sb.ToString());
}
#endregion
#region GetUtcDate
/// <summary>
/// GetUtcDate
/// </summary>
/// <param name="dateTime"></param>
/// <returns></returns>
private string GetUtcDate(DateTime dateTime)
{
DateTime date = dateTime.ToUniversalTime();
return (date.ToString("yyyyMMdd\\tHHmms\\z"));
}
#endregion
#endregion
#region AddMetaData
/// <summary>
/// Adds escape chars to text meta data
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private string AddMetaData(string s)
{
Regex p = new Regex("[,;\\n]");
MatchCollection mc = p.Matches(s);
if (mc.Count > 0)
{
StringBuilder sb = new StringBuilder();
int index = 0;
foreach (Match ma in mc)
{
if (index < ma.Index)
sb.Append(s.Substring(index, ma.Index - index));
index = ma.Index + ma.Length;
char c = ma.Value[0];
if (c == '\n')
c = 'n';
sb.Append('\\');
sb.Append(c);
}
if (index < s.Length)
sb.Append(s.Substring(index, s.Length - index));
return (sb.ToString());
}
return (s);
}
#endregion
#endregion
#region ExportLine
/// <summary>
/// Exports a line
/// </summary>
/// <param name="text"></param>
private void ExportLine(string text)
{
_StreamWriter.WriteLine(WrapLine(text, FoldCount));
}
#region WrapLine
/// <summary>
/// Performs line wrapping (aka folding)
/// </summary>
/// <param name="text">Text to wrap</param>
/// <param name="wrapLength">Wrapping length</param>
/// <returns></returns>
private string WrapLine(string text, int wrapLength)
{
if (text.Length <= wrapLength)
return (text);
StringBuilder sb = new StringBuilder();
int len;
for (int i = 0; i < text.Length; i += len)
{
len = text.Length - i;
if (len > wrapLength)
len = BreakLine(text, i, wrapLength);
if (i > 0)
sb.Append("\n ");
sb.Append(text, i, len);
}
return (sb.ToString());
}
#endregion
#region BreakLine
/// <summary>
/// Determines where to break a line of text
/// </summary>
/// <param name="text">Text</param>
/// <param name="pos">Current text pos</param>
/// <param name="max">Max line length</param>
/// <returns></returns>
private int BreakLine(string text, int pos, int max)
{
int i = max - 1;
while (i > 0 && IsBreakChar(text[pos + i]) == false)
i--;
if (i <= 0)
return (max);
while (i >= 0 && Char.IsWhiteSpace(text[pos + i]) == true)
i--;
return (i + 1);
}
#endregion
#region IsBreakChar
/// <summary>
/// Determines if a char is a break char
/// </summary>
/// <param name="c"></param>
/// <returns>true if break char</returns>
private bool IsBreakChar(char c)
{
return (Char.IsWhiteSpace(c) || c == ',' || c == ';');
}
#endregion
#endregion
#region GetDefaultOwnerKeys
/// <summary>
/// GetDefaultOwnerKeys
/// </summary>
/// <returns>A list of all defined model OwnerKeys</returns>
private string[] GetDefaultOwnerKeys()
{
List<string> list = new List<string>();
foreach (Appointment app in Model.Appointments)
{
string key = app.OwnerKey ?? "";
if (list.Contains(app.OwnerKey) == false)
list.Add(key);
}
list.Sort();
string[] ownerKeys = new string[list.Count];
list.CopyTo(ownerKeys);
return (ownerKeys);
}
#endregion
#region GetUniversalTime
/// <summary>
/// GetUniversalTime
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
private string GetUniversalTime(DateTime date)
{
return (date.ToUniversalTime().ToString("yyyyMMdd\\tHHmms\\z"));
}
#endregion
#region IsAppointmentVisible
/// <summary>
/// Determines if an appointment is visible
/// with respect to the given ownerKey
/// </summary>
/// <param name="app"></param>
/// <param name="ownerKey"></param>
/// <returns></returns>
protected virtual bool IsAppointmentVisible(Appointment app, string ownerKey)
{
if (string.IsNullOrEmpty(ownerKey))
return (true);
return (app.OwnerKey == ownerKey);
}
#endregion
}
}

View File

@@ -0,0 +1,114 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents the calendar month.
/// </summary>
public class Month
{
#region Private Variables
private int _Year = 0, _Month = 0;
private ReadOnlyCollection<Day> _ReadOnlyDays = null;
private List<Day> _Days = null;
private CalendarModel _CalendarModel = null;
#endregion
#region Internal Implementation
/// <summary>
/// Initializes a new instance of the Month class.
/// </summary>
/// <param name="year"></param>
/// <param name="month"></param>
public Month(CalendarModel calendar, int year, int month)
{
_CalendarModel = calendar;
_Year = year;
_Month = month;
}
/// <summary>
/// Gets collection of days in this month.
/// </summary>
public ReadOnlyCollection<Day> Days
{
get
{
if (_ReadOnlyDays == null)
CreateDayCollection();
return _ReadOnlyDays;
}
}
private void CreateDayCollection()
{
Calendar cal = _CalendarModel.GetCalendar();
int daysCount = cal.GetDaysInMonth(_Year, _Month);
_Days = new List<Day>(daysCount);
for (int i = 0; i < daysCount; i++)
{
Day day = new Day(new DateTime(_Year, _Month, i + 1), _CalendarModel);
_Days.Add(day);
}
_ReadOnlyDays = new ReadOnlyCollection<Day>(_Days);
}
/// <summary>
/// Gets the month year.
/// </summary>
[Browsable(false)]
public int Year
{
get { return _Year; }
}
/// <summary>
/// Gets the month.
/// </summary>
[Browsable(false)]
public int MonthOfYear
{
get { return _Month; }
}
/// <summary>
/// Gets the Calendar this day is part of.
/// </summary>
[Browsable(false)]
public CalendarModel CalendarModel
{
get { return _CalendarModel; }
internal set { _CalendarModel = value; }
}
internal void InvalidateAppointments()
{
if (_Days == null) return;
foreach (Day day in _Days)
{
day.InvalidateAppointments();
}
}
internal void InvalidateAppointments(int day)
{
if (_Days == null) return;
_Days[day - 1].InvalidateAppointments();
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,195 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Defines monthly recurrence settings.
/// </summary>
public class MonthlyRecurrenceSettings : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Internal Implementation
private AppointmentRecurrence _Recurrence = null;
/// <summary>
/// Initializes a new instance of the MonthlyRecurrenceSettings class.
/// </summary>
/// <param name="recurrence"></param>
public MonthlyRecurrenceSettings(AppointmentRecurrence recurrence)
{
_Recurrence = recurrence;
}
private int _RepeatOnDayOfMonth = 1;
/// <summary>
/// Gets or sets the day of month on which appointment is repeated.
/// When RepeatOnRelativeDayInMonth property is set to value other than None value of this property is not used.
/// </summary>
[DefaultValue(1)]
public int RepeatOnDayOfMonth
{
get { return _RepeatOnDayOfMonth; }
set
{
if (value != _RepeatOnDayOfMonth)
{
int oldValue = _RepeatOnDayOfMonth;
_RepeatOnDayOfMonth = value;
OnRepeatOnDayOfMonthChanged(oldValue, value);
}
}
}
private void OnRepeatOnDayOfMonthChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnDayOfMonth"));
}
private eRelativeDayInMonth _RepeatOnRelativeDayInMonth = eRelativeDayInMonth.None;
/// <summary>
/// Gets or sets whether appointment should repeat on first, second, third, fourth or last day in month as specified
/// by RepeatOnDayOfMonth property. Property applies only for RecurrenceType Monthly or Yearly.
/// </summary>
[DefaultValue(eRelativeDayInMonth.None)]
public eRelativeDayInMonth RepeatOnRelativeDayInMonth
{
get { return _RepeatOnRelativeDayInMonth; }
set
{
if (value != _RepeatOnRelativeDayInMonth)
{
eRelativeDayInMonth oldValue = _RepeatOnRelativeDayInMonth;
_RepeatOnRelativeDayInMonth = value;
OnRepeatOnRelativeDayInMonthChanged(oldValue, value);
}
}
}
private void OnRepeatOnRelativeDayInMonthChanged(eRelativeDayInMonth oldValue, eRelativeDayInMonth newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnRelativeDayInMonth"));
}
private int _RepeatInterval = 1;
/// <summary>
/// Gets or sets the interval between recurring appointments. Default value is 1.
/// <remarks>
/// For example, setting RepeatInterval to 2 means that appointment will recur every 2 months.
/// </remarks>
/// </summary>
[DefaultValue(1)]
public int RepeatInterval
{
get { return _RepeatInterval; }
set
{
if (value != _RepeatInterval)
{
int oldValue = _RepeatInterval;
_RepeatInterval = value;
OnRepeatIntervalChanged(oldValue, value);
}
}
}
private void OnRepeatIntervalChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatInterval"));
}
private DayOfWeek _RelativeDayOfWeek = DayOfWeek.Monday;
/// <summary>
/// Gets or sets the day of week on which relative repeat as specified by RepeatOnRelativeDayInMonth is effective.
/// For example setting RepeatOnRelativeDayInMonth to First and RelativeDayOfWeek to Monday will repeat the appointment on first
/// Monday in a month.
/// </summary>
[DefaultValue(DayOfWeek.Monday)]
public DayOfWeek RelativeDayOfWeek
{
get { return _RelativeDayOfWeek; }
set
{
if (value != _RelativeDayOfWeek)
{
DayOfWeek oldValue = _RelativeDayOfWeek;
_RelativeDayOfWeek = value;
OnRelativeDayOfWeekChanged(oldValue, value);
}
}
}
private void OnRelativeDayOfWeekChanged(DayOfWeek oldValue, DayOfWeek newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RelativeDayOfWeek"));
}
private eMonthRecurrence _RepeatOnMonths = eMonthRecurrence.All;
/// <summary>
/// Gets or sets the months on which appointment is repeated. This property is represented by bit-flag enum
/// which means that you can combine the values from eMonthRecurrence enum using OR operator to specify multiple values.
/// Default value is All.
/// <remarks>
/// <para>For example you could set this property to eMonthRecurrence.January | eMonthRecurrence.July to repeat appointments on January and July only.</para>
/// </remarks>
/// </summary>
[DefaultValue(eMonthRecurrence.All)]
public eMonthRecurrence RepeatOnMonths
{
get { return _RepeatOnMonths; }
set
{
if (value != _RepeatOnMonths)
{
eMonthRecurrence oldValue = _RepeatOnMonths;
_RepeatOnMonths = value;
OnRepeatOnMonthsChanged(oldValue, value);
}
}
}
private void OnRepeatOnMonthsChanged(eMonthRecurrence oldValue, eMonthRecurrence newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnMonths"));
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null) eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,58 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
namespace DevComponents.Schedule.Model
{
internal class NotificationRequest
{
#region Internal Implementation
/// <summary>
/// Initializes a new instance of the NotificationRequest class.
/// </summary>
/// <param name="notificationTime"></param>
/// <param name="notificationHandler"></param>
public NotificationRequest(DateTime notificationTime, NotificationServerEventHandler notificationHandler)
{
_NotificationTime = notificationTime;
_NotificationHandler = notificationHandler;
_ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
}
private int _ThreadId;
public int ThreadId
{
get { return _ThreadId; }
}
private DateTime _NotificationTime = DateTime.MinValue;
/// <summary>
/// Gets or sets requested notification time.
/// </summary>
public DateTime NotificationTime
{
get { return _NotificationTime; }
set
{
_NotificationTime = value;
}
}
private NotificationServerEventHandler _NotificationHandler = null;
/// <summary>
/// Gets the callback handler for notification when notification time is reached.
/// </summary>
public NotificationServerEventHandler NotificationHandler
{
get { return _NotificationHandler; }
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,173 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Timers;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Provides notification support for appointments.
/// </summary>
internal static class NotificationServer
{
#region Private Variables
private static Timer _Timer = null;
internal static event NotificationServerEventHandler NotifySubscribers;
private static DateTime _NextEventTime;
private static List<NotificationRequest> _RequestList = new List<NotificationRequest>();
#endregion
#region Constructor
static NotificationServer()
{
_Timer = new Timer();
_Timer.Elapsed += new ElapsedEventHandler(NotificationEventTimerTick);
SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged);
_NextEventTime = DateTime.MinValue;
}
static void SystemEvents_TimeChanged(object sender, EventArgs e)
{
if (_NextEventTime > DateTime.MinValue && UtcNow.Subtract(_NextEventTime).TotalSeconds <= 0)
NotifySubscribersOnTimeEvent();
}
static void NotificationEventTimerTick(object sender, ElapsedEventArgs e)
{
NotifySubscribersOnTimeEvent();
}
private static bool _Notifying = false;
private static void NotifySubscribersOnTimeEvent()
{
try
{
_Notifying = true;
_Timer.Stop();
#if DEBUG
Console.WriteLine("{0} NotificationServer notifying subscribers count: {1}", DateTime.Now, _RequestList.Count);
#endif
// Reset next notification time...
_NextEventTime = DateTime.MinValue;
if (_RequestList.Count == 0)
{
return;
}
DateTime now = CalendarModel.GetCalendarDateTime(UtcNow);
NotificationRequest[] requestList = new NotificationRequest[_RequestList.Count];
_RequestList.CopyTo(requestList);
DateTime nextNotification = DateTime.MinValue;
foreach (NotificationRequest item in requestList)
{
if (item.NotificationTime <= now)
{
if (item.NotificationHandler != null)
{
//if (System.Threading.Thread.CurrentThread.ManagedThreadId != item.ThreadId)
//{
// //System.Threading.SendOrPostCallback callback = new System.Threading.SendOrPostCallback(SendNotification);
// //System.Windows.Threading.DispatcherSynchronizationContext.Current.Post(callback, item);
//}
//else
item.NotificationHandler(item, new NotificationServerEventArgs(now));
}
_RequestList.Remove(item);
}
else if (item.NotificationTime < nextNotification || nextNotification == DateTime.MinValue)
nextNotification = item.NotificationTime;
}
if (nextNotification > DateTime.MinValue)
{
SetNextEventTime(nextNotification);
}
//else
// Console.WriteLine("Not setting next notification time...");
}
finally
{
_Notifying = false;
}
}
private static void SendNotification(object e)
{
NotificationRequest item = (NotificationRequest)e;
if (item.NotificationHandler != null)
{
if (System.Threading.Thread.CurrentThread.ManagedThreadId != item.ThreadId)
{
Console.WriteLine("Different THREAD");
}
else
{
DateTime now = CalendarModel.GetCalendarDateTime(UtcNow);
item.NotificationHandler(item, new NotificationServerEventArgs(now));
}
}
}
private static void SetNextEventTime(DateTime dateTime)
{
DateTime now = CalendarModel.GetCalendarDateTime(UtcNow);
if (dateTime.Subtract(now).TotalSeconds <= 0)
{
if (!_Notifying)
NotifySubscribersOnTimeEvent();
else
_NextEventTime = DateTime.MinValue;
}
else if (dateTime.Subtract(now).TotalSeconds > 0 && (_NextEventTime == DateTime.MinValue || dateTime < _NextEventTime))
{
double nextEvent = dateTime.Subtract(UtcNow).TotalSeconds + 1;
if (nextEvent > int.MaxValue / 1000)
nextEvent = (int.MaxValue - 1) / 1000;
_Timer.Interval = (int)Math.Max(5, nextEvent * 1000);
#if DEBUG
Console.WriteLine("{0} NotificationServer scheduling next event on: {1}, previous scheduled event on: {2}", DateTime.Now, dateTime, _NextEventTime);
#endif
_Timer.Start();
_NextEventTime = dateTime;
}
//else
// _NextEventTime = DateTime.MinValue;
}
private static DateTime UtcNow
{
get
{
return TimeZoneInfo.ConvertTimeToUtc(CalendarModel.CurrentDateTime);
}
}
public static void UpdateNotification(NotificationRequest request)
{
SetNextEventTime(request.NotificationTime);
}
#endregion
#region Internal Implementation
public static void Register(NotificationRequest request)
{
_RequestList.Add(request);
SetNextEventTime(request.NotificationTime);
}
public static void Unregister(NotificationRequest request)
{
_RequestList.Remove(request);
}
#endregion
}
internal delegate void NotificationServerEventHandler(NotificationRequest sender, NotificationServerEventArgs e);
}
#endif

View File

@@ -0,0 +1,49 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
namespace DevComponents.Schedule.Model
{
internal class NotificationServerEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the NotificationServerEventArgs class.
/// </summary>
/// <param name="notificationTime"></param>
public NotificationServerEventArgs(DateTime notificationTime)
{
_NotificationTime = notificationTime;
}
private DateTime _NotificationTime;
/// <summary>
/// Gets the time notification is sent on.
/// </summary>
public DateTime NotificationTime
{
get { return _NotificationTime; }
}
private DateTime _NextRequestedNotificationTime = DateTime.MinValue;
/// <summary>
/// Gets or sets the next requested notification time by the handler of the event.
/// Handler of event must set this to the desired next notification time in order to be notified.
/// The value recorded will be the lowest value set by all handlers.
/// </summary>
public DateTime NextRequestedNotificationTime
{
get { return _NextRequestedNotificationTime; }
set
{
value = CalendarModel.GetCalendarDateTime(value);
if (value > NotificationTime && (value < _NextRequestedNotificationTime || _NextRequestedNotificationTime == DateTime.MinValue))
{
_NextRequestedNotificationTime = value;
}
}
}
}
}
#endif

View File

@@ -0,0 +1,296 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using DevComponents.DotNetBar.Schedule;
namespace DevComponents.Schedule.Model
{
public class Owner : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Constructors
/// <summary>
/// Initializes a new instance of the Owner class.
/// </summary>
public Owner()
{
_WorkDays = new WorkDayCollection(this);
_CalendarWorkDays = new CalendarWorkDayCollection(this);
}
/// <summary>
/// Initializes a new instance of the Owner class.
/// </summary>
/// <param name="key"></param>
public Owner(string key)
: this()
{
_Key = key;
}
/// <summary>
/// Initializes a new instance of the Owner class.
/// </summary>
/// <param name="key"></param>
/// <param name="displayName"></param>
public Owner(string key, string displayName)
: this()
{
_Key = key;
_DisplayName = displayName;
}
/// <summary>
/// Initializes a new instance of the Owner class.
/// </summary>
/// <param name="key"></param>
/// <param name="displayName"></param>
/// <param name="colorScheme"></param>
public Owner(string key, string displayName, eCalendarColor colorScheme)
: this()
{
_Key = key;
_ColorScheme = colorScheme;
_DisplayName = displayName;
}
/// <summary>
/// Initializes a new instance of the Owner class.
/// </summary>
/// <param name="key"></param>
/// <param name="colorScheme"></param>
public Owner(string key, eCalendarColor colorScheme)
: this()
{
_Key = key;
_ColorScheme = colorScheme;
}
#endregion
#region Internal Implementation
private WorkDayCollection _WorkDays;
/// <summary>
/// Gets working days associated with this owner. If empty WorkDays from CalendarModel are used instead.
/// </summary>
public WorkDayCollection WorkDays
{
get { return _WorkDays; }
}
private CalendarWorkDayCollection _CalendarWorkDays;
/// <summary>
/// Gets date based working days associated with this owner. Date specific working days take precedence over days specified in WorkDays collection. If empty WorkDays on owner or from CalendarModel are used instead.
/// </summary>
public CalendarWorkDayCollection CalendarWorkDays
{
get { return _CalendarWorkDays; }
}
private string _Key = "";
/// <summary>
/// Gets or sets the unique key that identifies the owner.
/// </summary>
[DefaultValue("")]
public string Key
{
get { return _Key; }
set
{
if (value != _Key)
{
string oldValue = _Key;
_Key = value;
OnKeyChanged(oldValue, value);
}
}
}
private void OnKeyChanged(string oldValue, string newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Key"));
}
private string _Description = "";
/// <summary>
/// Gets or sets the owner description. For example if owner represents person, it would be person name or if owner represents resource
/// like room it would be the room name.
/// </summary>
[DefaultValue("")]
public string Description
{
get { return _Description; }
set
{
if (value != _Description)
{
string oldValue = _Description;
_Description = value;
OnDescriptionChanged(oldValue, value);
}
}
}
private void OnDescriptionChanged(string oldValue, string newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Description"));
}
private object _Tag = null;
/// <summary>
/// Gets or sets custom data associated with the object.
/// </summary>
[DefaultValue(null)]
public object Tag
{
get { return _Tag; }
set
{
if (value != _Tag)
{
object oldValue = _Tag;
_Tag = value;
OnTagChanged(oldValue, value);
}
}
}
private void OnTagChanged(object oldValue, object newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Tag"));
}
private CalendarModel _Calendar = null;
/// <summary>
/// Gets the calendar owner is associated with.
/// </summary>
[Browsable(false)]
public CalendarModel Calendar
{
get { return _Calendar; }
internal set
{
if (_Calendar != value)
{
_Calendar = value;
}
}
}
private TimeZoneInfo _DisplayTimeZone = null;
/// <summary>
/// Gets or sets the display time-zone for this owner. Default value is null.
/// </summary>
[DefaultValue(null)]
public TimeZoneInfo DisplayTimeZone
{
get { return _DisplayTimeZone; }
set
{
if (value != _DisplayTimeZone)
{
TimeZoneInfo oldValue = _DisplayTimeZone;
_DisplayTimeZone = value;
OnDisplayTimeZoneChanged(oldValue, value);
}
}
}
private void OnDisplayTimeZoneChanged(TimeZoneInfo oldValue, TimeZoneInfo newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("DisplayTimeZone"));
}
private eCalendarColor _ColorScheme = eCalendarColor.Automatic;
/// <summary>
/// Gets or sets the owner color scheme used to represent owner data in user interface.
/// </summary>
[DefaultValue(eCalendarColor.Automatic)]
public eCalendarColor ColorScheme
{
get { return _ColorScheme; }
set
{
if (value != _ColorScheme)
{
eCalendarColor oldValue = _ColorScheme;
_ColorScheme = value;
OnColorSchemeChanged(oldValue, value);
}
}
}
private void OnColorSchemeChanged(eCalendarColor oldValue, eCalendarColor newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("ColorScheme"));
}
private string _DisplayName = null;
/// <summary>
/// Gets or sets the display name for the owner. Display name is used in User Interface to identify the owner.
/// If not specified the Key is used instead in UI.
/// </summary>
[DefaultValue(null)]
public string DisplayName
{
get { return _DisplayName; }
set
{
if (value != _DisplayName)
{
string oldValue = _DisplayName;
_DisplayName = value;
OnDisplayNameChanged(oldValue, value);
}
}
}
private void OnDisplayNameChanged(string oldValue, string newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
}
internal static string DisplayNamePropertyName = "DisplayName";
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null) eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,123 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace DevComponents.Schedule.Model
{
public class OwnerCollection : Collection<Owner>
{
#region Constructor
/// <summary>
/// Initializes a new instance of the AppointmentCollection class.
/// </summary>
/// <param name="calendar"></param>
public OwnerCollection(CalendarModel calendar)
{
_Calendar = calendar;
}
#endregion
#region Internal Implementation
private CalendarModel _Calendar = null;
/// <summary>
/// Gets the calendar collection is associated with.
/// </summary>
public CalendarModel Calendar
{
get { return _Calendar; }
internal set { _Calendar = value; }
}
protected override void RemoveItem(int index)
{
Owner owner = this[index];
OnBeforeRemove(index, owner);
base.RemoveItem(index);
OnAfterRemove(index, owner);
}
private void OnAfterRemove(int index, Owner owner)
{
_Calendar.OwnerRemoved(owner);
}
private void OnBeforeRemove(int index, Owner owner)
{
owner.Calendar = null;
}
protected override void InsertItem(int index, Owner item)
{
OnBeforeInsert(index, item);
base.InsertItem(index, item);
OnAfterInsert(index, item);
}
private void OnAfterInsert(int index, Owner item)
{
_Calendar.OwnerAdded(item);
}
private void OnBeforeInsert(int index, Owner item)
{
item.Calendar = _Calendar;
}
protected override void SetItem(int index, Owner newItem)
{
Owner oldItem = this[index];
OnBeforeSetItem(index, oldItem, newItem);
base.SetItem(index, newItem);
OnAfterSetItem(index, oldItem, newItem);
}
private void OnAfterSetItem(int index, Owner oldItem, Owner newItem)
{
_Calendar.OwnerRemoved(oldItem);
_Calendar.OwnerAdded(newItem);
}
private void OnBeforeSetItem(int index, Owner oldItem, Owner newItem)
{
oldItem.Calendar = null;
newItem.Calendar = _Calendar;
}
protected override void ClearItems()
{
foreach (Owner item in this)
{
item.Calendar = null;
_Calendar.OwnerRemoved(item);
}
base.ClearItems();
}
/// <summary>
/// Gets the item based on the Key assigned to the item
/// </summary>
/// <param name="ownerKey"></param>
/// <returns></returns>
public Owner this[string ownerKey]
{
get
{
foreach (Owner item in this.Items)
{
if (item.Key == ownerKey) return item;
}
return null;
}
//set
//{
// Owner owner = this[ownerKey];
// this[IndexOf(owner)] = value;
//}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,600 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
namespace DevComponents.Schedule.Model
{
internal class RecurrenceGenerator : IRecurrenceGenerator
{
#region IRecurrenceGenerator Members
/// <summary>
/// Generates Daily recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well.
/// </summary>
/// <param name="subsetCollection">Collection to add generated recurrences to</param>
/// <param name="recurrence">Recurrence description, must be of Daily recurrence type.</param>
/// <param name="startDate">Start date for generation.</param>
/// <param name="endDate">End date for generation.</param>
public void GenerateDailyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate)
{
Appointment app = recurrence.Appointment;
int appointmentDaysDuration = recurrence.Daily.ExplicitDailyRecurrence ? 0 : (int)Math.Max(0, Math.Ceiling(app.EndTime.Date.Subtract(app.StartTime.Date).TotalDays));
DateTime recurrenceStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate,
recurrence.Daily.ExplicitDailyRecurrence ? (app.StartTime.AddDays(1).Date) : (DateTimeHelper.IsBeginningOfDay(app.EndTime) ? app.EndTime : app.EndTime.AddDays(recurrence.Daily.RepeatInterval).Date));
if (recurrenceStartDate > endDate) return;
int repeats = 0;
// Check the range first
if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate)
{
if (startDate > recurrence.RangeEndDate) return;
}
else if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences)
{
DateTime rangeStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate,
recurrence.Daily.ExplicitDailyRecurrence ? (app.LocalStartTime.AddDays(1).Date) : (DateTimeHelper.IsBeginningOfDay(app.LocalEndTime) ? app.LocalEndTime : app.LocalEndTime.AddDays(recurrence.Daily.RepeatInterval).Date));
int totalDays = (int)Math.Ceiling(startDate.Subtract(rangeStartDate).TotalDays);
switch (recurrence.Daily.RepeatOnDaysOfWeek)
{
case eDailyRecurrenceRepeat.All:
repeats = Math.Max(0, totalDays / (recurrence.Daily.RepeatInterval + appointmentDaysDuration));
if (repeats >= recurrence.RangeNumberOfOccurrences)
return;
break;
case eDailyRecurrenceRepeat.WeekDays:
repeats = Math.Max(0, DateTimeHelper.TotalWeekDays(recurrenceStartDate, startDate) / (recurrence.Daily.RepeatInterval + appointmentDaysDuration));
// Assume weekdays repeat
if (repeats > recurrence.RangeNumberOfOccurrences)
return;
break;
default:
repeats = Math.Max(0, DateTimeHelper.TotalWeekDays(recurrenceStartDate, startDate));
repeats = Math.Max(0, totalDays - repeats);
// Assume weekend days repeat
if (repeats > recurrence.RangeNumberOfOccurrences)
return;
break;
}
//repeats = 0;
}
DateTime currentDay = recurrenceStartDate; // DateTimeHelper.MaxDate(startDate, recurrenceStartDate);
while (currentDay <= endDate)
{
if (currentDay >= startDate || currentDay < startDate && IsRecurringOnDay(currentDay, startDate, endDate, app))
{
if (!IsRecurringOnDay(currentDay, startDate, endDate, app)) break;
if (recurrence.Daily.RepeatOnDaysOfWeek == eDailyRecurrenceRepeat.All ||
(recurrence.Daily.RepeatOnDaysOfWeek == eDailyRecurrenceRepeat.WeekDays && !DateTimeHelper.IsWeekendDay(currentDay)) ||
(recurrence.Daily.RepeatOnDaysOfWeek == eDailyRecurrenceRepeat.WeekendDays && DateTimeHelper.IsWeekendDay(currentDay)))
{
if (!IsIgnoredRecurrence(currentDay, recurrence))
{
subsetCollection.Add(CreateRecurringAppointmentInstance(currentDay, app));
repeats++;
}
}
}
switch (recurrence.Daily.RepeatOnDaysOfWeek)
{
case eDailyRecurrenceRepeat.All:
currentDay = currentDay.AddDays(recurrence.Daily.RepeatInterval + appointmentDaysDuration);
break;
case eDailyRecurrenceRepeat.WeekDays:
//currentDay = currentDay.AddDays(currentDay.DayOfWeek == DayOfWeek.Saturday ? 2 : Math.Max(1, recurrence.Daily.RepeatInterval + appointmentDaysDuration));
currentDay = currentDay.AddDays(Math.Max(1, recurrence.Daily.RepeatInterval + appointmentDaysDuration)); // Changed for consistency
break;
case eDailyRecurrenceRepeat.WeekendDays:
while (true)
{
currentDay = currentDay.AddDays(1);
if (DateTimeHelper.IsWeekendDay(currentDay) == true)
break;
}
break;
}
if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDay >= recurrence.RangeEndDate ||
recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && repeats >= recurrence.RangeNumberOfOccurrences)
break;
}
}
private static bool IsIgnoredRecurrence(DateTime currentDay, AppointmentRecurrence recurrence)
{
if (recurrence.SkippedRecurrences.Count == 0) return false;
foreach (DateTime date in recurrence.SkippedRecurrences)
{
if (date.Date == currentDay.Date)
return true;
}
return false;
}
private bool IsRecurringOnDay(DateTime currentDay, DateTime rangeStart, DateTime rangeEnd, Appointment rootAppointment)
{
TimeSpan duration = rootAppointment.EndTime.Subtract(rootAppointment.StartTime);
DateTime startTime = rootAppointment.GetValidDateTime(new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, rootAppointment.StartTime.Hour, rootAppointment.StartTime.Minute, 0));
DateTime endTime = rootAppointment.GetValidDateTime(startTime.Add(duration));
DateTime localStartTime = rootAppointment.GetLocalDateTime(rootAppointment.GetUTCDateTime(startTime));
DateTime localEndTime = rootAppointment.GetLocalDateTime(rootAppointment.GetUTCDateTime(endTime));
// If time-zone is not used return false
//if (startTime == localStartTime) return currentDay >= rangeStart;
return DateTimeHelper.TimePeriodsOverlap(localStartTime, localEndTime, rangeStart, rangeEnd);
}
private DateTime GetAppointmentEndTime(DateTime currentDay, Appointment rootAppointment)
{
TimeSpan duration = rootAppointment.EndTime.Subtract(rootAppointment.StartTime);
DateTime startTime = rootAppointment.GetValidDateTime(new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, rootAppointment.StartTime.Hour, rootAppointment.StartTime.Minute, 0));
DateTime endTime = rootAppointment.GetValidDateTime(startTime.Add(duration));
return endTime;
}
private Appointment CreateRecurringAppointmentInstance(DateTime currentDay, Appointment rootAppointment)
{
Appointment app = rootAppointment.Copy();
TimeSpan duration = rootAppointment.EndTime.Subtract(rootAppointment.StartTime);
DateTime startTime = app.GetValidDateTime(new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, rootAppointment.StartTime.Hour, rootAppointment.StartTime.Minute, 0));
DateTime endTime = app.GetValidDateTime(startTime.Add(duration));
app.StartTime = startTime;
app.EndTime = endTime;
app.IsRecurringInstance = true;
app.RootAppointment = rootAppointment;
app.Tooltip = rootAppointment.Tooltip;
if (rootAppointment.Recurrence == null || !rootAppointment.Recurrence.IndependentVisibility)
app.Visible = rootAppointment.Visible;
foreach (Reminder reminder in app.Reminders)
{
//reminder.ReminderTime = app.StartTime.Add(reminder.ReminderTime.Subtract(rootAppointment.StartTime));
reminder.IsActive = true;
}
return app;
}
/// <summary>
/// Generates Weekly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well.
/// </summary>
/// <param name="subsetCollection">Collection to add generated recurrences to</param>
/// <param name="recurrence">Recurrence description, must be of Weekly recurrence type.</param>
/// <param name="startDate">Start date for generation.</param>
/// <param name="endDate">End date for generation.</param>
public void GenerateWeeklyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate)
{
Appointment app = recurrence.Appointment;
DateTime baseStartDate = app.EndTime.Date;
if (app.EndTime.Date > app.StartTime.Date && app.EndTime.TimeOfDay > app.StartTime.TimeOfDay && baseStartDate != DateTime.MinValue)
baseStartDate = baseStartDate.AddDays(1);
DateTime recurrenceStartDate = baseStartDate;
int repeatInterval = recurrence.Weekly.RepeatInterval;
if (RepeatsOnSingleDayOnly(recurrence.Weekly.RepeatOnDaysOfWeek) && !(app.StartTime.Date == startDate.Date && endDate.Date == startDate.Date))
{
recurrenceStartDate = baseStartDate.AddMilliseconds(-1).AddDays((repeatInterval) * 7 /*+ (recurrence.Weekly.RepeatInterval > 1 ? (8 - (int)baseStartDate.DayOfWeek) : 1)*/).Date;
if (recurrenceStartDate.DayOfWeek != GetDayOfWeek(recurrence.Weekly.RepeatOnDaysOfWeek))
{
DayOfWeek dayOfWeek = GetDayOfWeek(recurrence.Weekly.RepeatOnDaysOfWeek);
while (recurrenceStartDate.DayOfWeek != dayOfWeek)
recurrenceStartDate = recurrenceStartDate.AddDays(1);
}
}
else
{
if (app.EndTime.Date > app.StartTime.Date && app.EndTime.TimeOfDay < app.StartTime.TimeOfDay)
recurrenceStartDate = app.StartTime.Date.AddDays(1);
else
recurrenceStartDate = app.EndTime.Date.AddDays(1);
}
recurrenceStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate, recurrenceStartDate);
if (recurrenceStartDate > endDate) return;
int totalRecurrences = 0;
// Check the range first
if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate)
{
if (startDate > recurrence.RangeEndDate) return;
}
else if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && repeatInterval == 1)
{
int totalDays = (int)Math.Ceiling(endDate.Subtract(recurrenceStartDate).TotalDays);
int occurrencesPerWeek = GetNumberOfDays(recurrence.Weekly.RepeatOnDaysOfWeek);
if (occurrencesPerWeek == 0)
throw new ArgumentException("Weekly recurrence must have at least single day selected using RepeatOnDaysOfWeek property.");
totalRecurrences = DateTimeHelper.TotalNumberOfDays(recurrenceStartDate, endDate, recurrence.Weekly.RepeatOnDaysOfWeek);
if (totalRecurrences > recurrence.RangeNumberOfOccurrences) return;
}
bool countTotalRecurrences = false;
if (repeatInterval > 1 && recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences)
countTotalRecurrences = true;
bool spansDays = app.StartTime.Day != app.EndTime.Day && endDate.Subtract(startDate).TotalDays <= 1;
DateTime currentDay = recurrenceStartDate;// DateTimeHelper.MaxDate(recurrenceStartDate, startDate);
while (currentDay <= endDate)
{
if ((currentDay >= startDate || spansDays && GetAppointmentEndTime(currentDay, app) >= startDate) && DateTimeHelper.HasDay(currentDay.DayOfWeek, recurrence.Weekly.RepeatOnDaysOfWeek) &&
!IsIgnoredRecurrence(currentDay, recurrence))
{
subsetCollection.Add(CreateRecurringAppointmentInstance(currentDay, app));
totalRecurrences++;
}
else if (countTotalRecurrences && currentDay < startDate && DateTimeHelper.HasDay(currentDay.DayOfWeek, recurrence.Weekly.RepeatOnDaysOfWeek)
&& !IsIgnoredRecurrence(currentDay, recurrence))
{
totalRecurrences++;
if (totalRecurrences >= recurrence.RangeNumberOfOccurrences)
return;
}
if (currentDay.DayOfWeek != DayOfWeek.Sunday)
{
while (currentDay.DayOfWeek != DayOfWeek.Sunday)
{
currentDay = currentDay.AddDays(1);
if (currentDay > endDate || recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDay > recurrence.RangeEndDate)
break;
if ((currentDay >= startDate || spansDays && GetAppointmentEndTime(currentDay, app) >= startDate) && DateTimeHelper.HasDay(currentDay.DayOfWeek, recurrence.Weekly.RepeatOnDaysOfWeek)
&& !IsIgnoredRecurrence(currentDay, recurrence))
{
subsetCollection.Add(CreateRecurringAppointmentInstance(currentDay, app));
}
else if (countTotalRecurrences && currentDay < startDate && DateTimeHelper.HasDay(currentDay.DayOfWeek, recurrence.Weekly.RepeatOnDaysOfWeek)
&& !IsIgnoredRecurrence(currentDay, recurrence))
{
totalRecurrences++;
if (totalRecurrences >= recurrence.RangeNumberOfOccurrences)
return;
}
}
}
currentDay = currentDay.AddDays(1 + (repeatInterval - 1) * 7);
if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDay > recurrence.RangeEndDate ||
recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && totalRecurrences > recurrence.RangeNumberOfOccurrences)
break;
}
}
private DayOfWeek GetDayOfWeek(eDayOfWeekRecurrence d)
{
if (d == eDayOfWeekRecurrence.Monday)
return DayOfWeek.Monday;
else if (d == eDayOfWeekRecurrence.Tuesday)
return DayOfWeek.Tuesday;
else if (d == eDayOfWeekRecurrence.Wednesday)
return DayOfWeek.Wednesday;
else if (d == eDayOfWeekRecurrence.Thursday)
return DayOfWeek.Thursday;
else if (d == eDayOfWeekRecurrence.Friday)
return DayOfWeek.Friday;
else if (d == eDayOfWeekRecurrence.Saturday)
return DayOfWeek.Saturday;
else
return DayOfWeek.Sunday;
}
private bool RepeatsOnSingleDayOnly(eDayOfWeekRecurrence dow)
{
return dow == eDayOfWeekRecurrence.Monday || dow == eDayOfWeekRecurrence.Tuesday ||
dow == eDayOfWeekRecurrence.Wednesday || dow == eDayOfWeekRecurrence.Thursday ||
dow == eDayOfWeekRecurrence.Friday || dow == eDayOfWeekRecurrence.Saturday || dow == eDayOfWeekRecurrence.Sunday;
}
private int GetNumberOfDays(eDayOfWeekRecurrence daysOfWeek)
{
int days = 0;
if ((daysOfWeek & eDayOfWeekRecurrence.Friday) != 0)
days++;
if ((daysOfWeek & eDayOfWeekRecurrence.Monday) != 0)
days++;
if ((daysOfWeek & eDayOfWeekRecurrence.Saturday) != 0)
days++;
if ((daysOfWeek & eDayOfWeekRecurrence.Sunday) != 0)
days++;
if ((daysOfWeek & eDayOfWeekRecurrence.Thursday) != 0)
days++;
if ((daysOfWeek & eDayOfWeekRecurrence.Tuesday) != 0)
days++;
if ((daysOfWeek & eDayOfWeekRecurrence.Wednesday) != 0)
days++;
return days;
}
/// <summary>
/// Generates Monthly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well.
/// </summary>
/// <param name="subsetCollection">Collection to add generated recurrences to</param>
/// <param name="recurrence">Recurrence description, must be of Monthly recurrence type.</param>
/// <param name="startDate">Start date for generation.</param>
/// <param name="endDate">End date for generation.</param>
public void GenerateMonthlyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate)
{
Appointment app = recurrence.Appointment;
DateTime recurrenceStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate, app.EndTime/*.AddDays(1).Date*/);
if (recurrenceStartDate > endDate) return;
int totalRecurrences = 0;
// Check the range first
if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate)
{
if (startDate > recurrence.RangeEndDate) return;
}
else if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && recurrence.RangeNumberOfOccurrences > 0)
{
int count = recurrence.RangeNumberOfOccurrences + 1;
DateTime testDate = DateTimeHelper.BeginningOfDay(recurrenceStartDate);
DateTime startDateOnly = DateTimeHelper.BeginningOfDay(startDate);
while (count > 0 && testDate < startDateOnly)
{
int repeatInterval = recurrence.Monthly.RepeatInterval;
while (repeatInterval > 0)
{
testDate = GetNextMonthlyRecurrence(recurrence, testDate);
repeatInterval--;
}
if (testDate < startDate)
totalRecurrences++;
count--;
}
if (count == 0) return;
}
DateTime currentDate = recurrenceStartDate;// DateTimeHelper.MaxDate(recurrenceStartDate, startDate).AddMonths(-1);
do
{
int repeatCount = recurrence.Monthly.RepeatInterval;
do
{
repeatCount--;
currentDate = GetNextMonthlyRecurrence(recurrence, currentDate);
} while (repeatCount > 0);
if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDate > recurrence.RangeEndDate ||
recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && totalRecurrences >= recurrence.RangeNumberOfOccurrences)
break;
if (currentDate >= startDate && currentDate <= endDate && !IsIgnoredRecurrence(currentDate, recurrence))
{
subsetCollection.Add(CreateRecurringAppointmentInstance(currentDate, app));
totalRecurrences++;
}
} while (currentDate <= endDate);
}
private DateTime GetNextMonthlyRecurrence(AppointmentRecurrence recurrence, DateTime startDate)
{
MonthlyRecurrenceSettings monthly = recurrence.Monthly;
return GetNextMonthlyRecurrence(startDate, monthly.RepeatOnRelativeDayInMonth,
monthly.RelativeDayOfWeek, monthly.RepeatOnDayOfMonth, monthly.RepeatOnMonths);
}
private static void AdjustForRepeatOnMonths(ref DateTime dt, eMonthRecurrence repeatOnMonths)
{
while (((int)Math.Pow(2, (dt.Month - 1)) & (int)repeatOnMonths) == 0)
dt = dt.AddMonths(1);
}
private static DateTime GetNextMonthlyRecurrence(DateTime startDate, eRelativeDayInMonth repeatOnRelativeDayInMonth, DayOfWeek relativeDayOfWeek, int repeatOnDayOfMonth, eMonthRecurrence repeatOnMonths)
{
Calendar cal = GetCalendar();
if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.None)
{
DateTime dt = startDate.AddDays(cal.GetDaysInMonth(startDate.Year, startDate.Month) - startDate.Day + 1);
if (repeatOnMonths != eMonthRecurrence.All) AdjustForRepeatOnMonths(ref dt, repeatOnMonths); // Adjust for repeat on Months
return dt.AddDays(Math.Min(cal.GetDaysInMonth(dt.Year, dt.Month), repeatOnDayOfMonth) - 1);
}
else
{
if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.First)
{
DateTime dt = startDate.AddDays(cal.GetDaysInMonth(startDate.Year, startDate.Month) - startDate.Day + 1);
if (repeatOnMonths != eMonthRecurrence.All) AdjustForRepeatOnMonths(ref dt, repeatOnMonths); // Adjust for repeat on Months
while (dt.DayOfWeek != relativeDayOfWeek)
dt = dt.AddDays(1);
return dt;
}
else if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.Last)
{
DateTime dt = startDate.AddDays(cal.GetDaysInMonth(startDate.Year, startDate.Month) - startDate.Day + 1);
if (repeatOnMonths != eMonthRecurrence.All) AdjustForRepeatOnMonths(ref dt, repeatOnMonths); // Adjust for repeat on Months
dt = dt.AddDays(cal.GetDaysInMonth(dt.Year, dt.Month) - 1);
while (dt.DayOfWeek != relativeDayOfWeek)
dt = dt.AddDays(-1);
return dt;
}
else
{
// Second, third and forth
int relCount = 2;
if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.Third)
relCount = 3;
else if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.Fourth)
relCount = 4;
DateTime dt = startDate.AddDays(cal.GetDaysInMonth(startDate.Year, startDate.Month) - startDate.Day);
if (repeatOnMonths != eMonthRecurrence.All) AdjustForRepeatOnMonths(ref dt, repeatOnMonths); // Adjust for repeat on Months
while (relCount > 0)
{
dt = dt.AddDays(1);
if (dt.DayOfWeek == relativeDayOfWeek)
relCount--;
}
return dt;
}
}
throw new InvalidOperationException("Could not find the next relative date for monthly recurrence starting on " + startDate.ToString() + " RelativeDayInMonth=" + repeatOnRelativeDayInMonth.ToString() + " RelativeDayOfWeek=" + relativeDayOfWeek.ToString());
}
private static Calendar GetCalendar()
{
return CultureInfo.CurrentCulture.Calendar;
}
/// <summary>
/// Generates Yearly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well.
/// </summary>
/// <param name="subsetCollection">Collection to add generated recurrences to</param>
/// <param name="recurrence">Recurrence description, must be of Monthly recurrence type.</param>
/// <param name="startDate">Start date for generation.</param>
/// <param name="endDate">End date for generation.</param>
public void GenerateYearlyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate)
{
Appointment app = recurrence.Appointment;
DateTime recurrenceStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate, app.EndTime.AddDays(1).Date);
if (recurrenceStartDate > endDate) return;
if (!(startDate.Month <= recurrence.Yearly.RepeatOnMonth && endDate.Month >= recurrence.Yearly.RepeatOnMonth) && endDate.Subtract(startDate).TotalDays < 28)
return;
int totalRecurrences = 0;
// Check the range first
if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate)
{
if (startDate > recurrence.RangeEndDate) return;
}
else if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && recurrence.RangeNumberOfOccurrences > 0 && recurrenceStartDate < startDate)
{
int count = recurrence.RangeNumberOfOccurrences + 1;
DateTime testDate = DateTimeHelper.BeginningOfDay(recurrenceStartDate.AddDays(-(recurrenceStartDate.Day - 1))).AddMonths(-1);
if (testDate < app.EndTime)
testDate = app.EndTime.Date.AddDays(1);
DateTime startDateOnly = DateTimeHelper.BeginningOfDay(startDate);
while (count > 0 && testDate < startDateOnly)
{
testDate = GetNextYearlyRecurrence(recurrence, testDate);
if (testDate >= startDateOnly) break;
count--;
totalRecurrences++;
}
if (count == 0) return;
}
DateTime currentDate = DateTimeHelper.MaxDate(startDate, recurrenceStartDate).AddDays(-1);
if (recurrence.Yearly.RepeatInterval > 1)
currentDate = recurrenceStartDate;
do
{
currentDate = GetNextYearlyRecurrence(recurrence, currentDate);
if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDate > recurrence.RangeEndDate ||
recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && totalRecurrences >= recurrence.RangeNumberOfOccurrences)
break;
if (currentDate >= startDate && currentDate <= endDate && !IsIgnoredRecurrence(currentDate, recurrence))
{
subsetCollection.Add(CreateRecurringAppointmentInstance(currentDate, app));
totalRecurrences++;
}
} while (currentDate <= endDate);
}
internal static DateTime GetNextYearlyRecurrence(AppointmentRecurrence recurrence, DateTime startDate)
{
YearlyRecurrenceSettings yearly = recurrence.Yearly;
if (yearly.RepeatInterval > 1)
{
DateTime currentDate = startDate;
for (int i = 0; i < yearly.RepeatInterval; i++)
{
currentDate = GetNextSingleYearlyRecurrence(recurrence, currentDate);
}
return currentDate;
}
else
{
return GetNextSingleYearlyRecurrence(recurrence, startDate);
}
}
internal static DateTime GetNextSingleYearlyRecurrence(AppointmentRecurrence recurrence, DateTime startDate)
{
YearlyRecurrenceSettings yearly = recurrence.Yearly;
Calendar cal = GetCalendar();
if (startDate.Month < yearly.RepeatOnMonth)
{
startDate = startDate.AddMonths((yearly.RepeatOnMonth - startDate.Month) - 1);
return GetNextMonthlyRecurrence(startDate, yearly.RepeatOnRelativeDayInMonth, yearly.RelativeDayOfWeek, yearly.RepeatOnDayOfMonth, eMonthRecurrence.All);
}
else if (startDate.Month == yearly.RepeatOnMonth)
{
DateTime refDate = startDate.AddDays(-(startDate.Day));
DateTime ret = GetNextMonthlyRecurrence(refDate, yearly.RepeatOnRelativeDayInMonth, yearly.RelativeDayOfWeek, yearly.RepeatOnDayOfMonth, eMonthRecurrence.All);
if (ret > startDate) return ret;
}
// Forward to next year and right month
startDate = startDate.AddDays(cal.GetDaysInYear(startDate.Year) - startDate.DayOfYear).AddMonths(yearly.RepeatOnMonth - 1);
return GetNextMonthlyRecurrence(startDate, yearly.RepeatOnRelativeDayInMonth, yearly.RelativeDayOfWeek, yearly.RepeatOnDayOfMonth, eMonthRecurrence.All);
}
#endregion
}
internal interface IRecurrenceGenerator
{
/// <summary>
/// Generates Daily recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well.
/// </summary>
/// <param name="subsetCollection">Collection to add generated recurrences to</param>
/// <param name="recurrence">Recurrence description, must be of Daily recurrence type.</param>
/// <param name="startDate">Start date for generation.</param>
/// <param name="endDate">End date for generation.</param>
void GenerateDailyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate);
/// <summary>
/// Generates Weekly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well.
/// </summary>
/// <param name="subsetCollection">Collection to add generated recurrences to</param>
/// <param name="recurrence">Recurrence description, must be of Weekly recurrence type.</param>
/// <param name="startDate">Start date for generation.</param>
/// <param name="endDate">End date for generation.</param>
void GenerateWeeklyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate);
/// <summary>
/// Generates Monthly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well.
/// </summary>
/// <param name="subsetCollection">Collection to add generated recurrences to</param>
/// <param name="recurrence">Recurrence description, must be of Monthly recurrence type.</param>
/// <param name="startDate">Start date for generation.</param>
/// <param name="endDate">End date for generation.</param>
void GenerateMonthlyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate);
/// <
/// summary>
/// Generates Yearly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well.
/// </summary>
/// <param name="subsetCollection">Collection to add generated recurrences to</param>
/// <param name="recurrence">Recurrence description, must be of Monthly recurrence type.</param>
/// <param name="startDate">Start date for generation.</param>
/// <param name="endDate">End date for generation.</param>
void GenerateYearlyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate);
}
}
#endif

View File

@@ -0,0 +1,482 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents an appointment reminder.
/// </summary>
public class Reminder
{
#region Private variables
private bool _NotificationRequestRegistered = false;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the Reminder class.
/// </summary>
public Reminder()
{
}
/// <summary>
/// Initializes a new instance of the Reminder class.
/// </summary>
/// <param name="reminderTime"></param>
public Reminder(DateTime reminderTime)
{
ReminderTime = reminderTime;
}
/// <summary>
/// Initializes a new instance of the Reminder class.
/// </summary>
/// <param name="description"></param>
/// <param name="reminderTime"></param>
public Reminder(string description, DateTime reminderTime)
{
Description = description;
ReminderTime = reminderTime;
}
#endregion
#region Events
/// <summary>
/// Occurs when ReminderTime has been reached. Note that event handler will be called on the thread of System.Timer which is different
/// than UI thread. You should use BeginInvoke calls to marshal the calls to your UI thread.
/// </summary>
[Description("Occurs when ReminderTime has been reached.")]
public event ReminderEventHandler ReminderNotification;
#endregion
#region Internal Implementation
private bool _IsActiveForPastAppointments = true;
/// <summary>
/// Gets or sets whether reminder will be active for appointments that are in the past. Default value is true.
/// This property is useful if you are creating recurring appointments with reminders that start in past but don't want reminders
/// for past instances of appointment to be active.
/// </summary>
public bool IsActiveForPastAppointments
{
get { return _IsActiveForPastAppointments; }
set
{
if (value != _IsActiveForPastAppointments)
{
bool oldValue = _IsActiveForPastAppointments;
_IsActiveForPastAppointments = value;
OnIsActiveForPastAppointmentsChanged(oldValue, value);
}
}
}
private void OnIsActiveForPastAppointmentsChanged(bool oldValue, bool newValue)
{
//OnPropertyChanged(new PropertyChangedEventArgs("IsActiveForPastAppointments"));
ReminderCollection parentCollection = this.ParentCollection;
if (parentCollection != null)
{
Appointment app = this.ParentCollection.Appointment;
if (app != null)
{
UpdateNotifications();
}
}
}
private string _Description = "";
/// <summary>
/// Gets or sets the reminder description.
/// </summary>
public string Description
{
get { return _Description; }
set
{
if (value != _Description)
{
string oldValue = _Description;
_Description = value;
OnDescriptionChanged(oldValue, _Description);
}
}
}
private void OnDescriptionChanged(string oldValue, string newValue)
{
}
private object _Tag = null;
/// <summary>
/// Gets or sets additional data associated with the object.
/// </summary>
[DefaultValue(null)]
public object Tag
{
get { return _Tag; }
set
{
if (value != _Tag)
{
object oldValue = _Tag;
_Tag = value;
OnTagChanged(oldValue, value);
}
}
}
private void OnTagChanged(object oldValue, object newValue)
{
}
/// <summary>
/// Gets or sets the date and time reminder will be executed at.
/// <remarks>
/// Unless you mark reminder as inactive by setting the IsActive=false the reminder will occur next time
/// notifications are updated or when appointment data is loaded.
/// </remarks>
/// </summary>
private DateTime _ReminderTime = DateTime.MinValue;
public DateTime ReminderTime
{
get { return GetTimeZoneDateTime(_ReminderTime); }
set
{
value = GetUTCDateTime(CalendarModel.GetCalendarDateTime(value));
if (_ReminderTime != value)
{
DateTime oldValue = _ReminderTime;
_ReminderTime = value;
OnReminderTimeChanged(oldValue, _ReminderTime);
}
}
}
private DateTime GetUTCDateTime(DateTime date)
{
if (date == DateTime.MinValue || date == DateTime.MaxValue || date.Kind == DateTimeKind.Utc)
return date;
return TimeZoneInfo.ConvertTimeToUtc(date);
}
private DateTime GetTimeZoneDateTime(DateTime date)
{
if (date.Kind != DateTimeKind.Utc) return date;
TimeZoneInfo zone = TimeZoneInfo.Local;
return TimeZoneInfo.ConvertTimeFromUtc(date, zone);
}
private void OnReminderTimeChanged(DateTime oldValue, DateTime newValue)
{
if (NeedsNotification)
UpdateNotifications();
}
private bool NeedsNotification
{
get
{
return _ReminderAction != eReminderAction.None && _IsActive;
}
}
/// <summary>
/// Gets or sets the action performed when reminder time is reached. Default value is Event and Command.
/// </summary>
private eReminderAction _ReminderAction = eReminderAction.EventAndCommand;
[DefaultValue(eReminderAction.EventAndCommand)]
public eReminderAction ReminderAction
{
get { return _ReminderAction; }
set
{
if (_ReminderAction != value)
{
eReminderAction oldValue = _ReminderAction;
_ReminderAction = value;
OnReminderActionChanged(oldValue, _ReminderAction);
}
}
}
private void OnReminderActionChanged(eReminderAction oldValue, eReminderAction newValue)
{
if (oldValue == eReminderAction.None || newValue == eReminderAction.None)
UpdateNotifications();
}
internal void UpdateNotifications()
{
if (_Appointment != null && !_IsActiveForPastAppointments && _Appointment.StartTime.Date < DateTime.Today)
{
UnregisterNotification();
return;
}
if ((_Appointment != null && _Appointment.Calendar != null || _Parent != null && _Parent.ParentModel != null) &&
_IsActive && _ReminderTime > DateTime.MinValue && _ReminderAction != eReminderAction.None)
{
NotificationRequest request = this.NotificationRequest;
RegisterNotification(request);
}
else
{
UnregisterNotification();
}
}
private void RegisterNotification(NotificationRequest request)
{
if (_NotificationRequestRegistered)
NotificationServer.UpdateNotification(request);
else
NotificationServer.Register(request);
_NotificationRequestRegistered = true;
}
private Appointment _Appointment;
/// <summary>
/// Gets the Appointment reminder is attached to.
/// </summary>
[Browsable(false)]
public Appointment Appointment
{
get { return _Appointment; }
internal set
{
if (_Appointment != value)
{
_Appointment = value;
if (NeedsNotification) UpdateNotifications();
}
}
}
private bool _IsActive = true;
/// <summary>
/// Gets or sets whether reminder is active. Active reminders fire events or execute commands when
/// reminder time has been reached. Set this value to false to dismiss the reminder.
/// </summary>
[DefaultValue(true)]
public bool IsActive
{
get { return _IsActive; }
set
{
if (_IsActive != value)
{
bool oldValue = _IsActive;
_IsActive = value;
OnIsActiveChanged(oldValue, _IsActive);
}
}
}
private void OnIsActiveChanged(bool oldValue, bool newValue)
{
UpdateNotifications();
}
private NotificationRequest _NotificationRequest = null;
private NotificationRequest NotificationRequest
{
get
{
if (_NotificationRequest == null)
{
_NotificationRequest = new NotificationRequest(((_IsSnoozeReminder && _SnoozeDateTime != DateTime.MinValue) ? _SnoozeDateTime : _ReminderTime), new NotificationServerEventHandler(OnReminderNotification));
}
else
_NotificationRequest.NotificationTime = ((_IsSnoozeReminder && _SnoozeDateTime != DateTime.MinValue) ? _SnoozeDateTime : _ReminderTime);
return _NotificationRequest;
}
set
{
_NotificationRequest = value;
}
}
private DateTime _SnoozeDateTime = DateTime.MinValue;
/// <summary>
/// Gets or sets the next snooze time for the reminder. Use the Snooze method if you want to snooze the reminder correctly.
/// </summary>
public DateTime SnoozeDateTime
{
get { return _SnoozeDateTime; }
set
{
value = CalendarModel.GetCalendarDateTime(value);
value = value.Kind == DateTimeKind.Utc ? value : GetUTCDateTime(value);
if (value != _SnoozeDateTime)
{
DateTime oldValue = _SnoozeDateTime;
_SnoozeDateTime = value;
if (_SnoozeDateTime == DateTime.MinValue)
{
this.IsSnoozeReminder = false;
UnregisterNotification();
}
OnSnoozeDateTimeChanged(oldValue, value);
}
}
}
private void OnSnoozeDateTimeChanged(DateTime oldValue, DateTime newValue)
{
//OnPropertyChanged(new PropertyChangedEventArgs("SnoozeDateTime"));
}
/// <summary>
/// Snoozes reminder so it occurs at specified notification time. This method should be used instead of the SnoozeDateTime property and it will
/// set the SnoozeDateTime property to the next notification time.
/// </summary>
/// <param name="nextNotificationTime">Next reminder notification time.</param>
public void Snooze(DateTime nextNotificationTime)
{
nextNotificationTime = CalendarModel.GetCalendarDateTime(nextNotificationTime);
DateTime utcTime = nextNotificationTime.Kind == DateTimeKind.Utc ? nextNotificationTime : GetUTCDateTime(nextNotificationTime);
UnregisterNotification();
this.SnoozeDateTime = nextNotificationTime;
this.IsSnoozeReminder = true;
NotificationRequest request = this.NotificationRequest;
request.NotificationTime = utcTime;
RegisterNotification(request);
}
private void UnregisterNotification()
{
if (_NotificationRequestRegistered)
{
NotificationServer.Unregister(this.NotificationRequest);
_NotificationRequestRegistered = false;
this.NotificationRequest = null;
}
}
private void OnReminderNotification(NotificationRequest request, NotificationServerEventArgs e)
{
if (_ReminderAction != eReminderAction.None)
{
this.NotificationRequest = null;
ProcessNotification();
}
}
/// <summary>
/// Runs the ReminderNotification as if the reminder time has been reached.
/// <remarks>This method is automatically called by reminder once ReminderTime has been reached.</remarks>
/// </summary>
public void ProcessNotification()
{
if (_Appointment != null && _Appointment.Calendar != null)
_Appointment.Calendar.InvokeReminderNotification(this);
else if (_Parent != null && _Parent.ParentModel != null)
_Parent.ParentModel.InvokeReminderNotification(this);
if (_ReminderAction == eReminderAction.None) return;
if ((_ReminderAction & eReminderAction.Event) != 0)
{
OnReminderNotification(new ReminderEventArgs(this));
}
if ((_ReminderAction & eReminderAction.Command) != 0)
{
//throw new NotImplementedException();
}
}
/// <summary>
/// Raises the ReminderNotification event.
/// </summary>
/// <param name="eventArgs"></param>
protected virtual void OnReminderNotification(ReminderEventArgs eventArgs)
{
ReminderEventHandler h = ReminderNotification;
if (h != null)
h(this, eventArgs);
}
/// <summary>
/// Creates an copy of the reminder.
/// </summary>
/// <returns>Reminder copy.</returns>
public Reminder Copy()
{
Reminder copy = new Reminder();
copy.Description = _Description;
copy.Tag = _Tag;
copy.IsActive = _IsActive;
copy.ReminderAction = _ReminderAction;
copy.IsActiveForPastAppointments = this.IsActiveForPastAppointments;
if (ReminderNotification != null)
copy.ReminderNotification = (ReminderEventHandler)ReminderNotification.Clone();
copy.ReminderTime = ReminderTime;
copy.IsSnoozeReminder = _IsSnoozeReminder;
return copy;
}
private bool _IsSnoozeReminder = false;
/// <summary>
/// Gets or sets whether this reminder is snooze reminder usually created by Reminder dialog when user hits the Snooze button.
/// Default value is false.
/// </summary>
public bool IsSnoozeReminder
{
get { return _IsSnoozeReminder; }
set
{
_IsSnoozeReminder = value;
}
}
private ReminderCollection _Parent = null;
internal ReminderCollection ParentCollection
{
get { return _Parent; }
set
{
_Parent = value;
if (NeedsNotification)
UpdateNotifications();
}
}
#endregion
}
#region Events Support
public delegate void ReminderEventHandler(object sender, ReminderEventArgs e);
/// <summary>
/// Defines arguments for reminder related events.
/// </summary>
public class ReminderEventArgs : EventArgs
{
/// <summary>
/// Gets the reminder referenced by this event.
/// </summary>
public Reminder Reminder = null;
/// <summary>
/// Initializes a new instance of the ReminderEventArgs class.
/// </summary>
/// <param name="appointment"></param>
public ReminderEventArgs(Reminder reminder)
{
Reminder = reminder;
}
}
#endregion
}
#endif

View File

@@ -0,0 +1,107 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents collection of reminders.
/// </summary>
public class ReminderCollection : Collection<Reminder>
{
#region Constructor
/// <summary>
/// Initializes a new instance of the ReminderCollection class.
/// </summary>
/// <param name="parent"></param>
public ReminderCollection(Appointment parent)
{
_Appointment = parent;
}
CalendarModel _Model = null;
/// <summary>
/// Initializes a new instance of the ReminderCollection class.
/// </summary>
/// <param name="parent"></param>
public ReminderCollection(CalendarModel parentModel)
{
_Model = parentModel;
}
#endregion
#region Internal Implementation
protected override void InsertItem(int index, Reminder item)
{
OnBeforeInsert(index, item);
base.InsertItem(index, item);
}
private void OnBeforeInsert(int index, Reminder item)
{
item.Appointment = _Appointment;
item.ParentCollection = this;
}
protected override void SetItem(int index, Reminder item)
{
OnBeforeSetItem(index, item);
base.SetItem(index, item);
}
private void OnBeforeSetItem(int index, Reminder item)
{
this[index].Appointment = null;
this[index].ParentCollection = null;
item.Appointment = _Appointment;
item.ParentCollection = this;
}
protected override void RemoveItem(int index)
{
OnBeforeRemove(index);
base.RemoveItem(index);
}
private void OnBeforeRemove(int index)
{
this[index].Appointment = null;
this[index].ParentCollection = null;
}
protected override void ClearItems()
{
foreach (Reminder item in this)
{
item.Appointment = null;
}
base.ClearItems();
}
private Appointment _Appointment;
/// <summary>
/// Gets parent appointment.
/// </summary>
public Appointment Appointment
{
get { return _Appointment; }
internal set
{
_Appointment = value;
}
}
/// <summary>
/// Gets parent model if collection is custom reminders collection.
/// </summary>
public CalendarModel ParentModel
{
get { return _Model; }
internal set { _Model = value; }
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,128 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace DevComponents.Schedule
{
internal class NativeMethods
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct TimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string StandardName;
public NativeMethods.SystemTime StandardDate;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string DaylightName;
public NativeMethods.SystemTime DaylightDate;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
public TimeZoneInformation(NativeMethods.DynamicTimeZoneInformation dtzi)
{
this.Bias = dtzi.Bias;
this.StandardName = dtzi.StandardName;
this.StandardDate = dtzi.StandardDate;
this.StandardBias = dtzi.StandardBias;
this.DaylightName = dtzi.DaylightName;
this.DaylightDate = dtzi.DaylightDate;
this.DaylightBias = dtzi.DaylightBias;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct DynamicTimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string StandardName;
public NativeMethods.SystemTime StandardDate;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string DaylightName;
public NativeMethods.SystemTime DaylightDate;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x80)]
public string TimeZoneKeyName;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SystemTime
{
[MarshalAs(UnmanagedType.U2)]
public short Year;
[MarshalAs(UnmanagedType.U2)]
public short Month;
[MarshalAs(UnmanagedType.U2)]
public short DayOfWeek;
[MarshalAs(UnmanagedType.U2)]
public short Day;
[MarshalAs(UnmanagedType.U2)]
public short Hour;
[MarshalAs(UnmanagedType.U2)]
public short Minute;
[MarshalAs(UnmanagedType.U2)]
public short Second;
[MarshalAs(UnmanagedType.U2)]
public short Milliseconds;
}
[StructLayout(LayoutKind.Sequential)]
internal struct RegistryTimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
public NativeMethods.SystemTime StandardDate;
public NativeMethods.SystemTime DaylightDate;
public RegistryTimeZoneInformation(NativeMethods.TimeZoneInformation tzi)
{
this.Bias = tzi.Bias;
this.StandardDate = tzi.StandardDate;
this.StandardBias = tzi.StandardBias;
this.DaylightDate = tzi.DaylightDate;
this.DaylightBias = tzi.DaylightBias;
}
public RegistryTimeZoneInformation(byte[] bytes)
{
if ((bytes == null) || (bytes.Length != 0x2c))
{
throw new ArgumentException("Argument_InvalidREG_TZI_FORMAT", "bytes");
}
this.Bias = BitConverter.ToInt32(bytes, 0);
this.StandardBias = BitConverter.ToInt32(bytes, 4);
this.DaylightBias = BitConverter.ToInt32(bytes, 8);
this.StandardDate.Year = BitConverter.ToInt16(bytes, 12);
this.StandardDate.Month = BitConverter.ToInt16(bytes, 14);
this.StandardDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x10);
this.StandardDate.Day = BitConverter.ToInt16(bytes, 0x12);
this.StandardDate.Hour = BitConverter.ToInt16(bytes, 20);
this.StandardDate.Minute = BitConverter.ToInt16(bytes, 0x16);
this.StandardDate.Second = BitConverter.ToInt16(bytes, 0x18);
this.StandardDate.Milliseconds = BitConverter.ToInt16(bytes, 0x1a);
this.DaylightDate.Year = BitConverter.ToInt16(bytes, 0x1c);
this.DaylightDate.Month = BitConverter.ToInt16(bytes, 30);
this.DaylightDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x20);
this.DaylightDate.Day = BitConverter.ToInt16(bytes, 0x22);
this.DaylightDate.Hour = BitConverter.ToInt16(bytes, 0x24);
this.DaylightDate.Minute = BitConverter.ToInt16(bytes, 0x26);
this.DaylightDate.Second = BitConverter.ToInt16(bytes, 40);
this.DaylightDate.Milliseconds = BitConverter.ToInt16(bytes, 0x2a);
}
}
}
}
#endif

View File

@@ -0,0 +1,36 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
namespace DevComponents.Schedule
{
[SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods
{
[DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)]
internal static extern int GetDynamicTimeZoneInformation(out NativeMethods.DynamicTimeZoneInformation lpDynamicTimeZoneInformation);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
internal static extern int GetTimeZoneInformation(out NativeMethods.TimeZoneInformation lpTimeZoneInformation);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
internal static extern bool GetFileMUIPath(int flags, [MarshalAs(UnmanagedType.LPWStr)] string filePath, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder language, ref int languageLength, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder fileMuiPath, ref int fileMuiPathLength, ref long enumerator);
[SecurityCritical, DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags);
[SecurityCritical, DllImport("user32.dll", EntryPoint = "LoadStringW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
internal static extern int LoadString(SafeLibraryHandle handle, int id, StringBuilder buffer, int bufferLength);
}
}
#endif

View File

@@ -0,0 +1,122 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Defines weekly recurrence settings.
/// </summary>
public class WeeklyRecurrenceSettings : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Internal Implementation
private AppointmentRecurrence _Recurrence = null;
/// <summary>
/// Initializes a new instance of the WeeklyRecurrenceSettings class.
/// </summary>
/// <param name="recurrence"></param>
public WeeklyRecurrenceSettings(AppointmentRecurrence recurrence)
{
_Recurrence = recurrence;
}
private eDayOfWeekRecurrence _RepeatOnDaysOfWeek = eDayOfWeekRecurrence.All;
/// <summary>
/// Gets or sets the days of week on which appointment is repeated. This property is represented by bit-flag enum
/// which means that you can combine the values from eDayOfWeekRecurrence enum using OR operator to specify multiple values.
/// Default value is All.
/// <remarks>
/// <para>This property value cannot be set to eDayOfWeekRecurrence.None.</para>
/// </remarks>
/// </summary>
[DefaultValue(eDayOfWeekRecurrence.All)]
public eDayOfWeekRecurrence RepeatOnDaysOfWeek
{
get { return _RepeatOnDaysOfWeek; }
set
{
if (value == eDayOfWeekRecurrence.None)
throw new ArgumentException("RepeatOnDaysOfWeek cannot be set to eDayOfWeekRecurrence.None");
if (value != _RepeatOnDaysOfWeek)
{
eDayOfWeekRecurrence oldValue = _RepeatOnDaysOfWeek;
_RepeatOnDaysOfWeek = value;
OnRepeatOnDaysOfWeekChanged(oldValue, value);
}
}
}
private void OnRepeatOnDaysOfWeekChanged(eDayOfWeekRecurrence oldValue, eDayOfWeekRecurrence newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnDaysOfWeek"));
}
private int _RepeatInterval = 1;
/// <summary>
/// Gets or sets the interval between recurring appointments. Default value is 1.
/// <remarks>
/// For example, setting RepeatInterval to 2 means that appointment will recur every 2 weeks.
/// </remarks>
/// </summary>
[DefaultValue(1)]
public int RepeatInterval
{
get { return _RepeatInterval; }
set
{
if (value != _RepeatInterval)
{
int oldValue = _RepeatInterval;
_RepeatInterval = value;
OnRepeatIntervalChanged(oldValue, value);
}
}
}
private void OnRepeatIntervalChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatInterval"));
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null) eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,70 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents working day in calendar.
/// </summary>
public class WorkDay : BaseWorkDay
{
#region Internal Implementation
/// <summary>
/// Initializes a new instance of the WorkDay class.
/// </summary>
public WorkDay()
{
}
/// <summary>
/// Initializes a new instance of the WorkDay class.
/// </summary>
/// <param name="dayOfWeek"></param>
public WorkDay(DayOfWeek dayOfWeek)
{
_DayOfWeek = dayOfWeek;
}
/// <summary>
/// Initializes a new instance of the WorkDay class.
/// </summary>
/// <param name="dayOfWeek"></param>
/// <param name="workStartTime"></param>
/// <param name="workEndTime"></param>
public WorkDay(DayOfWeek dayOfWeek, WorkTime workStartTime, WorkTime workEndTime)
{
_DayOfWeek = dayOfWeek;
_WorkStartTime = workStartTime;
_WorkEndTime = workEndTime;
}
private DayOfWeek _DayOfWeek = DayOfWeek.Monday;
/// <summary>
/// Gets or sets the day of week this instance represents.
/// </summary>
public DayOfWeek DayOfWeek
{
get { return _DayOfWeek; }
set
{
if (value != _DayOfWeek)
{
DayOfWeek oldValue = _DayOfWeek;
_DayOfWeek = value;
OnDayOfWeekChanged(oldValue, value);
}
}
}
private void OnDayOfWeekChanged(DayOfWeek oldValue, DayOfWeek newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("DayOfWeek"));
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,171 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents collection of working days.
/// </summary>
public class WorkDayCollection : Collection<WorkDay>
{
#region Constructor
/// <summary>
/// Initializes a new instance of the AppointmentCollection class.
/// </summary>
/// <param name="calendar"></param>
public WorkDayCollection(CalendarModel calendar)
{
_Calendar = calendar;
}
/// <summary>
/// Initializes a new instance of the WorkDayCollection class.
/// </summary>
/// <param name="owner"></param>
public WorkDayCollection(Owner owner)
{
_Owner = owner;
}
#endregion
#region Internal Implementation
private Owner _Owner = null;
/// <summary>
/// Gets the Owner of work-day collection.
/// </summary>
public Owner Owner
{
get { return _Owner; }
internal set { _Owner = value; }
}
private CalendarModel _Calendar = null;
/// <summary>
/// Gets the calendar collection is associated with.
/// </summary>
public CalendarModel Calendar
{
get { return _Calendar; }
internal set
{
_Calendar = value;
UpdateItemsCalendarModel();
}
}
internal void UpdateItemsCalendarModel()
{
CalendarModel model = GetCalendarModel();
foreach (WorkDay item in this.Items)
{
item.Calendar = model;
}
}
protected override void RemoveItem(int index)
{
WorkDay day = this[index];
OnBeforeRemove(index, day);
base.RemoveItem(index);
OnAfterRemove(index, day);
}
private void OnAfterRemove(int index, WorkDay day)
{
CalendarModel model = GetCalendarModel();
if (model != null)
model.WorkDayRemoved(day);
}
private void OnBeforeRemove(int index, WorkDay day)
{
day.Calendar = null;
}
protected override void InsertItem(int index, WorkDay item)
{
OnBeforeInsert(index, item);
base.InsertItem(index, item);
OnAfterInsert(index, item);
}
private void OnAfterInsert(int index, WorkDay item)
{
CalendarModel model = GetCalendarModel();
if (model != null)
model.WorkDayAdded(item);
}
private void OnBeforeInsert(int index, WorkDay item)
{
if (this[item.DayOfWeek] != null)
throw new InvalidOperationException("Day '" + item.DayOfWeek.ToString() + "' already in collection.");
item.Calendar = GetCalendarModel();
}
private CalendarModel GetCalendarModel()
{
if (_Calendar != null) return _Calendar;
if (_Owner != null) return _Owner.Calendar;
return null;
}
protected override void SetItem(int index, WorkDay newItem)
{
WorkDay oldItem = this[index];
OnBeforeSetItem(index, oldItem, newItem);
base.SetItem(index, newItem);
OnAfterSetItem(index, oldItem, newItem);
}
private void OnAfterSetItem(int index, WorkDay oldItem, WorkDay newItem)
{
CalendarModel model = GetCalendarModel();
if (model != null)
{
model.WorkDayRemoved(oldItem);
model.WorkDayAdded(newItem);
}
}
private void OnBeforeSetItem(int index, WorkDay oldItem, WorkDay newItem)
{
oldItem.Calendar = null;
newItem.Calendar = GetCalendarModel();
}
protected override void ClearItems()
{
CalendarModel model = GetCalendarModel();
foreach (WorkDay item in this)
{
item.Calendar = null;
if (model != null)
model.WorkDayRemoved(item);
}
base.ClearItems();
}
/// <summary>
/// Gets the item based on the Key assigned to the item
/// </summary>
/// <param name="day">Day of week to retrive data for.</param>
/// <returns>Reference to WorkDay or null if no day in collection.</returns>
public WorkDay this[DayOfWeek day]
{
get
{
foreach (WorkDay item in this.Items)
{
if (item.DayOfWeek == day) return item;
}
return null;
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,132 @@
#if FRAMEWORK20
using System;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents a work time.
/// </summary>
public struct WorkTime
{
#region Private variables
private int _Hour; // Hour
private int _Minute; // Minute
#endregion
/// <summary>
/// Initializes a new instance of the WorkTime structure.
/// </summary>
/// <param name="hour"></param>
/// <param name="minute"></param>
public WorkTime(int hour, int minute)
{
if (hour < 0 || hour > 23)
throw new ArgumentException("Hour value must be from 0 to 23");
if (minute < 0 || minute > 59)
throw new ArgumentException("Minute value must be from 0 to 59");
_Hour = hour;
_Minute = minute;
}
#region Public properties
/// <summary>
/// Gets or sets the hour from 0 to 23 this time instance represents.
/// </summary>
public int Hour
{
get { return _Hour; }
set
{
if (value < 0 || value > 23)
throw new ArgumentException("Hour value must be from 0 to 23");
_Hour = value;
}
}
/// <summary>
/// Gets or sets the minute from 0 to 59 this time instance represents.
/// </summary>
public int Minute
{
get { return _Minute; }
set
{
if (value < 0 || value > 59)
throw new ArgumentException("Minute value must be from 0 to 59");
_Minute = value;
}
}
/// <summary>
/// Determines if the WorkTime is Empty
/// </summary>
public bool IsEmpty
{
get
{
return (_Hour == 0 && _Minute == 0);
}
}
#endregion
#region Operator overloades
public static bool operator >=(WorkTime op1, WorkTime op2)
{
if ((op1.Hour > op2.Hour) ||
(op1.Hour == op2.Hour && op1.Minute >= op2.Minute))
{
return (true);
}
return (false);
}
public static bool operator <=(WorkTime op1, WorkTime op2)
{
if ((op1.Hour < op2.Hour) ||
(op1.Hour == op2.Hour && op1.Minute <= op2.Minute))
{
return (true);
}
return (false);
}
public static bool operator >(WorkTime op1, WorkTime op2)
{
if ((op1.Hour > op2.Hour) ||
(op1.Hour == op2.Hour && op1.Minute > op2.Minute))
{
return (true);
}
return (false);
}
public static bool operator <(WorkTime op1, WorkTime op2)
{
if ((op1.Hour < op2.Hour) ||
(op1.Hour == op2.Hour && op1.Minute < op2.Minute))
{
return (true);
}
return (false);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,72 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents the calendar year.
/// </summary>
public class Year
{
#region Internal Implementation
private int _Year = 0;
private CalendarModel _CalendarModel = null;
private ReadOnlyCollection<Month> _ReadOnlyMonths = null;
private List<Month> _Months = null;
/// <summary>
/// Initializes a new instance of the Year class.
/// </summary>
/// <param name="year"></param>
/// <param name="calendarModel"></param>
public Year(int year, CalendarModel calendarModel)
{
_Year = year;
_CalendarModel = calendarModel;
}
/// <summary>
/// Returns read-only collection of months in year.
/// </summary>
public ReadOnlyCollection<Month> Months
{
get
{
if (_ReadOnlyMonths == null)
CreateCollection();
return _ReadOnlyMonths;
}
}
private void CreateCollection()
{
_Months = new List<Month>(12);
for (int i = 0; i < 12; i++)
{
_Months.Add(new Month(_CalendarModel, _Year, i + 1));
}
_ReadOnlyMonths = new ReadOnlyCollection<Month>(_Months);
}
internal void InvalidateAppointments()
{
if (_Months == null) return;
foreach (Month month in _Months)
{
month.InvalidateAppointments();
}
}
internal void InvalidateAppointments(int month, int day)
{
if (_Months == null) return;
_Months[month - 1].InvalidateAppointments(day);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,193 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Defines yearly recurrence settings.
/// </summary>
public class YearlyRecurrenceSettings : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Internal Implementation
private AppointmentRecurrence _Recurrence = null;
/// <summary>
/// Initializes a new instance of the YearlyRecurrenceSettings class.
/// </summary>
/// <param name="recurrence"></param>
public YearlyRecurrenceSettings(AppointmentRecurrence recurrence)
{
_Recurrence = recurrence;
}
private int _RepeatInterval = 1;
/// <summary>
/// Gets or sets the interval between recurring appointments. Default value is 1.
/// <remarks>
/// For example, setting RepeatInterval to 2 means that appointment will recur every 2 years.
/// </remarks>
/// </summary>
[DefaultValue(1)]
public int RepeatInterval
{
get { return _RepeatInterval; }
set
{
if (value != _RepeatInterval)
{
int oldValue = _RepeatInterval;
_RepeatInterval = value;
OnRepeatIntervalChanged(oldValue, value);
}
}
}
private void OnRepeatIntervalChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatInterval"));
}
private int _RepeatOnDayOfMonth = 1;
/// <summary>
/// Gets or sets the day of month on which appointment is repeated.
/// When RepeatOnRelativeDayInMonth property is set to value other than None value of this property is not used.
/// </summary>
[DefaultValue(1)]
public int RepeatOnDayOfMonth
{
get { return _RepeatOnDayOfMonth; }
set
{
if (value != _RepeatOnDayOfMonth)
{
int oldValue = _RepeatOnDayOfMonth;
_RepeatOnDayOfMonth = value;
OnRepeatOnDayOfMonthChanged(oldValue, value);
}
}
}
private void OnRepeatOnDayOfMonthChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnDayOfMonth"));
}
private eRelativeDayInMonth _RepeatOnRelativeDayInMonth = eRelativeDayInMonth.None;
/// <summary>
/// Gets or sets whether appointment should repeat on first, second, third, fourth or last day in month as specified
/// by RepeatOnDayOfMonth property. Default value is None.
/// </summary>
[DefaultValue(eRelativeDayInMonth.None)]
public eRelativeDayInMonth RepeatOnRelativeDayInMonth
{
get { return _RepeatOnRelativeDayInMonth; }
set
{
if (value != _RepeatOnRelativeDayInMonth)
{
eRelativeDayInMonth oldValue = _RepeatOnRelativeDayInMonth;
_RepeatOnRelativeDayInMonth = value;
OnRepeatOnRelativeDayInMonthChanged(oldValue, value);
}
}
}
private void OnRepeatOnRelativeDayInMonthChanged(eRelativeDayInMonth oldValue, eRelativeDayInMonth newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnRelativeDayInMonth"));
}
private DayOfWeek _RelativeDayOfWeek = DayOfWeek.Monday;
/// <summary>
/// Gets or sets the day of week on which relative repeat as specified by RepeatOnRelativeDayInMonth is effective.
/// For example setting RepeatOnRelativeDayInMonth to First and RelativeDayOfWeek to Monday will repeat the appointment on first
/// Monday in a month.
/// </summary>
[DefaultValue(DayOfWeek.Monday)]
public DayOfWeek RelativeDayOfWeek
{
get { return _RelativeDayOfWeek; }
set
{
if (value != _RelativeDayOfWeek)
{
DayOfWeek oldValue = _RelativeDayOfWeek;
_RelativeDayOfWeek = value;
OnRelativeDayOfWeekChanged(oldValue, value);
}
}
}
private void OnRelativeDayOfWeekChanged(DayOfWeek oldValue, DayOfWeek newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RelativeDayOfWeek"));
}
private int _RepeatOnMonth = 1;
/// <summary>
/// Gets or sets the month the appointment is repeated on every year.
/// </summary>
[DefaultValue(1)]
public int RepeatOnMonth
{
get { return _RepeatOnMonth; }
set
{
if (value < 1 || value > 12)
throw new ArgumentException("Valid RepeatOnMonth values are between 1-12");
if (value != _RepeatOnMonth)
{
int oldValue = _RepeatOnMonth;
_RepeatOnMonth = value;
OnRepeatOnMonthChanged(oldValue, value);
}
}
}
private void OnRepeatOnMonthChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnMonth"));
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null) eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,113 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
/// <summary>
/// Represents base class for the model to view connectors.
/// </summary>
internal abstract class ModelViewConnector
{
#region Internal Implementation
#region Private variables
private string _DisplayOwnerKey = "";
#endregion
#region Abstract defines
/// <summary>
/// Connects View to a model.
/// </summary>
public abstract void Connect();
/// <summary>
/// Disconnects view from model.
/// </summary>
public abstract void Disconnect();
/// <summary>
/// Gets whether connector has connected model to a view.
/// </summary>
public abstract bool IsConnected { get; }
public abstract eCalendarView GetView();
#endregion
#region Virtual methods
protected virtual bool IsAppointmentVisible(Appointment app)
{
if (app.Visible == false)
return (false);
if (string.IsNullOrEmpty(_DisplayOwnerKey))
return (true);
return (app.OwnerKey == _DisplayOwnerKey);
}
protected virtual bool IsCustomItemVisible(CustomCalendarItem item)
{
if (item.Visible == false)
return (false);
if (string.IsNullOrEmpty(_DisplayOwnerKey))
return (true);
return (item.OwnerKey.Equals(_DisplayOwnerKey));
}
/// <summary>
/// Gets or sets the owner key of the owner of the appointments displayed on the view.
/// </summary>
public virtual string DisplayOwnerKey
{
get { return _DisplayOwnerKey; }
set
{
if (value == null)
value = "";
if (_DisplayOwnerKey != null)
{
_DisplayOwnerKey = value;
}
}
}
public virtual List<Appointment>
GetAppointmentList(CalendarModel model, DateTime startDate, DateTime endDate)
{
List<Appointment> appts = new List<Appointment>();
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
{
Day day = model.GetDay(date);
if (day.Appointments.Count > 0)
{
foreach (Appointment ap in day.Appointments)
{
if (appts.Contains(ap) == false)
appts.Add(ap);
}
}
}
return (appts);
}
#endregion
#endregion
}
}
#endif

View File

@@ -0,0 +1,598 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using DevComponents.Schedule.Model;
using System.ComponentModel;
namespace DevComponents.DotNetBar.Schedule
{
internal class ModelMonthViewConnector : ModelViewConnector
{
#region Constants
private const int DaysInWeek = 7;
#endregion
#region Private variables
private CalendarModel _Model; // The associated CalendarModel
private MonthView _View; // The associated MonthView
private bool _IsConnected; // Connection status
private uint _RefreshCount;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="model">Assoc CalendarModel</param>
/// <param name="monthView">Assoc MonthView</param>
public ModelMonthViewConnector(CalendarModel model, MonthView monthView)
{
_Model = model;
_View = monthView;
}
#region Public properties
/// <summary>
/// Gets the connection status
/// </summary>
public override bool IsConnected
{
get { return _IsConnected; }
}
#endregion
#region Connect
/// <summary>
/// Performs Model connection processing
/// </summary>
public override void Connect()
{
VerifyModel();
// Load the connection data
if (_IsConnected)
Disconnect();
LoadData();
// Get notification on Model property changes
_Model.PropertyChanged += ModelPropertyChanged;
_Model.SubPropertyChanged += ModelSubPropertyChanged;
_View.CalendarView.CustomItems.CollectionChanged += CustomItemsCollectionChanged;
_IsConnected = true;
}
#endregion
#region Disconnect
/// <summary>
/// Severs the Model/MonthView connection
/// </summary>
public override void Disconnect()
{
VerifyModel();
if (_IsConnected)
{
// Loop through each week, clearing each
// associated view connection
for (int i = 0; i < _View.MonthWeeks.Length; i++)
ClearMonthWeek(_View.MonthWeeks[i]);
_View.SubItems.Clear();
// Stop notification on Model property changes
_Model.PropertyChanged -= ModelPropertyChanged;
_Model.SubPropertyChanged -= ModelSubPropertyChanged;
_View.CalendarView.CustomItems.CollectionChanged -= CustomItemsCollectionChanged;
_IsConnected = false;
}
}
/// <summary>
/// Clears individual MonthWeek view connections
/// </summary>
/// <param name="monthWeek">MonthWeek</param>
private void ClearMonthWeek(MonthWeek monthWeek)
{
if (monthWeek.CalendarItems.Count > 0)
{
// Loop through each CalendarItem, resetting
// it's associated connection
for (int i = monthWeek.CalendarItems.Count - 1; i >= 0; i--)
{
AppointmentMonthView view =
monthWeek.CalendarItems[i] as AppointmentMonthView;
if (view != null)
{
view.IsSelectedChanged -= _View.ItemIsSelectedChanged;
view.Appointment = null;
view.IsSelected = false;
view.MonthWeek = null;
}
monthWeek.CalendarItems.RemoveAt(i);
}
}
}
#endregion
#region LoadData
/// <summary>
/// Loads Model/MonthView connection data
/// </summary>
private void LoadData()
{
MonthWeek[] wks = _View.MonthWeeks;
if (wks.Length > 0)
{
_RefreshCount++;
DateTime startDate = wks[0].FirstDayOfWeek;
DateTime endDate = DateTimeHelper.EndOfDay(wks[wks.Length - 1].LastDayOfWeek);
DateTime appStartDate = startDate.AddMonths(-1);
List<Appointment> appts = GetAppointmentList(_Model, appStartDate, endDate);
for (int i = 0; i < wks.Length; i++)
{
MonthWeek monthWeek = wks[i];
startDate = monthWeek.FirstDayOfWeek;
endDate = DateTimeHelper.EndOfDay(monthWeek.LastDayOfWeek);
UpdateWeekView(monthWeek, appts, startDate, endDate);
UpdateCustomItems(monthWeek, startDate, endDate);
}
}
}
#endregion
#region RefreshData
/// <summary>
/// Refreshes the data in a previously established
/// and loaded connection
/// </summary>
public void RefreshData()
{
LoadData();
List<CalendarItem> removedViews = null;
foreach (MonthWeek monthWeek in _View.MonthWeeks)
RemoveOutdatedViews(monthWeek, ref removedViews);
ProcessRemovedData(removedViews);
}
#region RemoveOutdatedViews
private void RemoveOutdatedViews(
MonthWeek monthWeek, ref List<CalendarItem> removedViews)
{
for (int i = monthWeek.CalendarItems.Count - 1; i >= 0; i--)
{
CalendarItem view = monthWeek.CalendarItems[i];
if (view != null)
{
if (view.RefreshCount != _RefreshCount)
{
if (removedViews == null)
removedViews = new List<CalendarItem>();
removedViews.Add(view);
_View.SubItems._Remove(view);
_View.NeedRecalcSize = true;
monthWeek.CalendarItems.RemoveAt(i);
}
}
}
}
#endregion
#region ProcessRemovedData
private void ProcessRemovedData(List<CalendarItem> removedViews)
{
if (removedViews != null && removedViews.Count > 0)
{
for (int i = 0; i < removedViews.Count; i++)
{
CalendarItem item = removedViews[i];
item.IsSelectedChanged -= _View.ItemIsSelectedChanged;
item.Dispose();
}
_View.NeedRecalcLayout = true;
}
}
#endregion
#endregion
#region UpdateWeekView
private void UpdateWeekView(MonthWeek monthWeek,
List<Appointment> apps, DateTime startDate, DateTime endDate)
{
// Loop through each appointment
// updating the assoc view accordingly
foreach (Appointment app in apps)
{
if (app.StartTime < endDate && app.EndTime > startDate)
{
if (IsAppointmentVisible(app))
{
// Get the assoc view
AppointmentMonthView view = GetViewFromWeek(monthWeek, app) ??
GetNewView(app);
// Set the view start and end times to
// match the assoc appointment
view.StartTime = app.StartTime;
view.EndTime = app.EndTime;
view.RefreshCount = _RefreshCount;
// And update the MonthWeek data
if (view.MonthWeek == null)
{
view.MonthWeek = monthWeek;
monthWeek.CalendarItems.Add(view);
_View.SubItems.Add(view);
}
view.IsSelected = app.IsSelected;
}
}
}
}
#endregion
#region UpdateCustomItems
private void UpdateCustomItems(
MonthWeek monthWeek, DateTime startDate, DateTime endDate)
{
CustomCalendarItemCollection items = _View.CalendarView.CustomItems;
if (items != null && items.Count > 0)
{
for (int i = 0; i < items.Count; i++)
{
CustomCalendarItem item = items[i];
if (IsCustomItemVisible(item) == true &&
(item.StartTime < endDate && item.EndTime > startDate))
{
item.CalendarView = _View.CalendarView;
CustomCalendarItem ci = GetItemFromWeek(monthWeek, item);
if (ci == null)
{
ci = GetNewCustomItem(item);
monthWeek.CalendarItems.Add(ci);
_View.SubItems.Insert(0, ci);
}
ci.RefreshCount = _RefreshCount;
if (ci.BaseCalendarItem != item)
{
ci.StartTime = item.StartTime;
ci.EndTime = item.EndTime;
}
}
}
}
}
#endregion
#region GetViewFrom
private List<AppointmentMonthView> GetViewsFromAll(Appointment app)
{
List<AppointmentMonthView> list = new List<AppointmentMonthView>();
for (int i = 0; i < _View.MonthWeeks.Length; i++)
{
AppointmentMonthView view =
GetViewFromWeek(_View.MonthWeeks[i], app);
if (view != null)
list.Add(view);
}
return (list);
}
private AppointmentMonthView GetViewFromWeek(MonthWeek monthWeek, Appointment appointment)
{
foreach (CalendarItem item in monthWeek.CalendarItems)
{
AppointmentMonthView view = item as AppointmentMonthView;
if (view != null && view.Appointment == appointment)
return (view);
}
return (null);
}
#endregion
#region GetItemFromWeek
private CustomCalendarItem GetItemFromWeek(MonthWeek monthWeek, CustomCalendarItem item)
{
foreach (CalendarItem citem in monthWeek.CalendarItems)
{
CustomCalendarItem view = citem as CustomCalendarItem;
if (view != null && (view == item || view.BaseCalendarItem == item))
return (view);
}
return (null);
}
#endregion
#region GetNewView
/// <summary>
/// Gets a new appointment view
/// </summary>
/// <param name="appointment">Appointment</param>
/// <returns>New view</returns>
private AppointmentMonthView GetNewView(Appointment appointment)
{
AppointmentMonthView view = new AppointmentMonthView(_View, appointment);
view.Tooltip = appointment.Tooltip;
// Set the selected state to match any current
// views that are present for this appointment
for (int i = 0; i < _View.MonthWeeks.Length; i++)
{
AppointmentMonthView viewPart =
GetViewFromWeek(_View.MonthWeeks[i], appointment);
if (viewPart != null)
{
view.IsSelected = viewPart.IsSelected;
break;
}
}
view.IsSelectedChanged += _View.ItemIsSelectedChanged;
return (view);
}
#endregion
#region GetNewCustomItem
/// <summary>
/// Gets a new CustomItem
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
private CustomCalendarItem GetNewCustomItem(CustomCalendarItem item)
{
CustomCalendarItem ci = (CustomCalendarItem)item.Copy();
ci.BaseCalendarItem = item;
ci.ModelItem = item;
// Set the selected state to match any current
// views that are present for this appointment
for (int i = 0; i < _View.MonthWeeks.Length; i++)
{
CustomCalendarItem viewPart =
GetItemFromWeek(_View.MonthWeeks[i], item);
if (viewPart != null)
{
ci.IsSelected = viewPart.IsSelected;
break;
}
}
ci.IsSelectedChanged += _View.ItemIsSelectedChanged;
return (ci);
}
#endregion
#region GetView
/// <summary>
/// Returns the Month view
/// </summary>
/// <returns></returns>
public override eCalendarView GetView()
{
return (eCalendarView.Month);
}
/// <summary>
/// Verifies the Model and MonthView are valid
/// </summary>
private void VerifyModel()
{
if (_Model == null)
throw new NullReferenceException("CalendarModel must be set on connector.");
if (_View == null)
throw new NullReferenceException("MonthCalendarView must be set on connector.");
}
#endregion
#region ModelPropertyChanged
/// <summary>
/// Handles Model property change notifications
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == CalendarModel.AppointmentsPropertyName)
{
RefreshData();
_View.NeedRecalcSize = true;
_View.Refresh();
}
}
#endregion
#region ModelSubPropertyChanged
/// <summary>
/// Handles ModelSubProperty change notifications
/// </summary>
/// <param name="sender">object</param>
/// <param name="e">SubPropertyChangedEventArgs</param>
private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e)
{
if (e.Source is Owner)
{
Owner owner = (Owner)e.Source;
if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key))
{
if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName)
_View.DisplayName = owner.DisplayName;
else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme"))
_View.CalendarColor = owner.ColorScheme;
}
}
else if (e.Source is Appointment)
{
Appointment app = e.Source as Appointment;
List<AppointmentMonthView> list;
string name = e.PropertyChangedArgs.PropertyName;
if (name.Equals("Tooltip"))
{
list = GetViewsFromAll(app);
for (int i = 0; i < list.Count; i++)
list[i].Tooltip = app.Tooltip;
}
else if (name.Equals("IsSelected"))
{
list = GetViewsFromAll(app);
for (int i = 0; i < list.Count; i++)
list[i].IsSelected = app.IsSelected;
}
else if (name.Equals("CategoryColor") || name.Equals("TimeMarkedAs"))
{
list = GetViewsFromAll(app);
for (int i = 0; i < list.Count; i++)
list[i].Refresh();
}
else if (name.Equals("OwnerKey"))
{
if (_View.CalendarView.IsMultiCalendar == true)
{
if (_View.OwnerKey == app.OwnerKey)
{
RefreshData();
_View.NeedRecalcSize = true;
_View.Refresh();
}
else
{
list = GetViewsFromAll(app);
if (list.Count > 0)
{
RefreshData();
_View.NeedRecalcSize = true;
_View.Refresh();
}
}
}
}
else if (name.Equals("Visible"))
{
RefreshData();
}
}
}
#endregion
#region CustomItems_CollectionChanged
void CustomItemsCollectionChanged(object sender, EventArgs e)
{
RefreshData();
_View.NeedRecalcSize = true;
_View.Refresh();
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,216 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Drawing;
namespace DevComponents.DotNetBar.Schedule
{
public class MonthWeek
{
#region Private constants
private const int DaysInWeek = 7;
#endregion
#region Private variables
private DateTime _FirstDayOfWeek; // First day of the week
private DateTime _LastDayOfWeek; // Last day of the week
private Rectangle _Bounds; // Week bounding rectangle
private ItemRects _DayRects; // Day bounding Rectangles
private ItemRects _MoreItems;
private List<CalendarItem>
_CalendarItems = new List<CalendarItem>();
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseItem"></param>
public MonthWeek(BaseItem baseItem)
{
// Allocate our DayRects array
_DayRects = new ItemRects(baseItem, DaysInWeek);
_MoreItems = new ItemRects(baseItem, DaysInWeek);
}
#region Public properties
#region CalendarItems
/// <summary>
/// Gets array of CalendarItems
/// </summary>
public List<CalendarItem> CalendarItems
{
get { return (_CalendarItems); }
}
#endregion
#region FirstDayOfWeek
/// <summary>
/// Gets the first day of the week
/// </summary>
public DateTime FirstDayOfWeek
{
get { return (_FirstDayOfWeek); }
internal set
{
_FirstDayOfWeek = value;
_LastDayOfWeek = _FirstDayOfWeek.AddDays(DaysInWeek - 1);
}
}
#endregion
#endregion
#region Internal properties
#region Bounds
/// <summary>
/// Gets and sets the week bounding Rectangle
/// </summary>
internal Rectangle Bounds
{
get { return (_Bounds); }
set
{
if (_Bounds.Equals(value) == false)
{
_Bounds = value;
CalcDayRects();
}
}
}
#endregion
#region DayRects
/// <summary>
/// Gets the day Rectangles
/// </summary>
internal ItemRects DayRects
{
get { return (_DayRects); }
}
#endregion
#region LastDayOfWeek
internal DateTime LastDayOfWeek
{
get { return (_LastDayOfWeek); }
}
#endregion
#region MoreItems
/// <summary>
/// Gets the MoreItems
/// </summary>
internal ItemRects MoreItems
{
get { return (_MoreItems); }
}
#endregion
#region WeekRange
/// <summary>
/// Gets the week day range text
/// </summary>
internal string WeekRange
{
get
{
string s1 = String.Format("{0:MMM} {1:d} - ",
_FirstDayOfWeek, _FirstDayOfWeek.Day);
if (_FirstDayOfWeek.Month.Equals(_LastDayOfWeek.Month) == false)
s1 = s1 + String.Format("{0:MMM} ", _LastDayOfWeek);
s1 = s1 + String.Format("{0:d}", _LastDayOfWeek.Day);
return (s1);
}
}
#endregion
#endregion
#region Private properties
/// <summary>
/// Gets day height
/// </summary>
private int DayHeight
{
get { return (_Bounds.Height); }
}
/// <summary>
/// Gets day width
/// </summary>
private float DayWidth
{
get { return ((float)_Bounds.Width / DaysInWeek); }
}
#endregion
#region DayRect calculation
/// <summary>
/// Calculates the day rectangles for the
/// current bounding rectangle
/// </summary>
private void CalcDayRects()
{
float dx = 0;
int sx = _Bounds.X;
int sy = _Bounds.Y;
int x2 = sx;
// Loop through each day in the week
for (int i = 0; i < DaysInWeek; i++)
{
int x1 = x2;
x2 = sx + (int)(dx + DayWidth);
dx += DayWidth;
if (i + 1 == DaysInWeek)
x2 = _Bounds.X + _Bounds.Width;
_DayRects[i].Bounds =
new Rectangle(x1, sy, x2 - x1, DayHeight);
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace DevComponents.DotNetBar.Schedule
{
internal class NativeFunctions
{
#region Licensing
#if !TRIAL
internal static bool keyValidated = false;
internal static int keyValidated2 = 0;
internal static bool ValidateLicenseKey(string key)
{
bool ret = false;
string[] parts = key.Split('-');
int i = 10;
foreach (string s in parts)
{
if (s == "88405280")
i++;
else if (s == "D06E")
i += 10;
else if (s == "4617")
i += 8;
else if (s == "8810")
i += 12;
else if (s == "64462F60FA93")
i += 3;
}
if (i == 29)
return true;
keyValidated = true;
return ret;
}
internal static bool CheckLicenseKey(string key)
{
// F962CEC7-CD8F-4911-A9E9-CAB39962FC1F, 189, 266
string[] parts = key.Split('-');
int test = 0;
for (int i = parts.Length - 1; i >= 0; i--)
{
if (parts[i] == "A9E9")
test += 11;
else if (parts[i] == "F962CEC7")
test += 12;
else if (parts[i] == "CAB39962FC1F")
test += 2;
else if (parts[i] == "4911")
test += 99;
else if (parts[i] == "CD8F")
test += 65;
}
keyValidated2 = test + 77;
if (test == 23)
return false;
return true;
}
#endif
#endregion
#if TRIAL
private static Color m_ColorExpFlag=Color.Empty;
internal static bool CheckedThrough = false;
internal static bool ColorExpAlt()
{
#if NOTIMELIMIT
return false;
#else
Color clr=SystemColors.Control;
Color clr2;
Color clr3;
clr2=clr;
if(clr2.ToArgb()==clr.ToArgb())
{
clr3=clr2;
}
else
{
clr3=clr;
}
if(!m_ColorExpFlag.IsEmpty)
{
return (m_ColorExpFlag==Color.Black?false:true);
}
try
{
Microsoft.Win32.RegistryKey key=Microsoft.Win32.Registry.ClassesRoot;
try
{
key = key.CreateSubKey("CLSID\\{57FEED69-A5E0-45e7-8E02-5F4131F5EE63}\\InprocServer32");
}
catch (System.UnauthorizedAccessException)
{
key = key.OpenSubKey("CLSID\\{57FEED69-A5E0-45e7-8E02-5F4131F5EE63}\\InprocServer32");
}
try
{
if(key.GetValue("")==null || key.GetValue("").ToString()=="")
{
key.SetValue("",DateTime.Today.ToOADate().ToString());
}
else
{
if(key.GetValue("").ToString()=="windows3.dll")
{
m_ColorExpFlag=Color.White;
key.Close();
key=null;
return true;
}
DateTime date=DateTime.FromOADate(double.Parse(key.GetValue("").ToString()));
if(((TimeSpan)DateTime.Today.Subtract(date)).TotalDays>28)
{
m_ColorExpFlag=Color.White;
key.SetValue("","windows4.dll");
key.Close();
key=null;
return true;
}
if(((TimeSpan)DateTime.Today.Subtract(date)).TotalDays<0)
{
m_ColorExpFlag=Color.White;
key.SetValue("","windows3.dll");
key.Close();
key=null;
return true;
}
}
}
finally
{
if(key!=null)
key.Close();
CheckedThrough = true;
}
}
catch{}
m_ColorExpFlag=Color.Black;
return false;
#endif
}
#endif
}
}

View File

@@ -0,0 +1,59 @@
#if FRAMEWORK20
namespace DevComponents.DotNetBar.Schedule
{
partial class PosWin
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// PosWin
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.CausesValidation = false;
this.ClientSize = new System.Drawing.Size(1, 1);
this.ControlBox = false;
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Location = new System.Drawing.Point(1000, 1000);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "PosWin";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "PosWin";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.PosWin_Paint);
this.ResumeLayout(false);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,219 @@
#if FRAMEWORK20
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Globalization;
namespace DevComponents.DotNetBar.Schedule
{
public partial class PosWin : Form
{
#region Private variables
private BaseView _View; // BaseView
private string _PosText = ""; // Window content
private int _PosHeight; // Calculated window height
#endregion
/// <summary>
/// Constructor
/// </summary>
public PosWin(BaseView view)
{
_View = view;
InitializeComponent();
}
#region CreateParams / show support
// This code permits us to be able to create a
// window with a drop shadow
private const int CsDropshadow = 0x00020000;
protected override CreateParams CreateParams
{
get
{
CreateParams parameters = base.CreateParams;
parameters.ClassStyle =
(parameters.ClassStyle | CsDropshadow);
return (parameters);
}
}
protected override bool ShowWithoutActivation
{
get { return true; }
}
#endregion
#region Public properties
/// <summary>
/// Gets and sets the window content text
/// </summary>
public string PosText
{
get { return (_PosText); }
set
{
if (_PosText != value)
{
_PosText = value;
this.Refresh();
}
}
}
/// <summary>
/// Gets the calculated window height
/// </summary>
public int PosHeight
{
get
{
if (_PosHeight <= 0)
{
using (Graphics g = CreateGraphics())
{
Size sz = TextDrawing.MeasureString(g, "ABC", SystemFonts.CaptionFont, 0,
eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter);
_PosHeight = sz.Height + 4;
}
}
return (_PosHeight);
}
}
#endregion
#region UpdateWin
/// <summary>
/// Updates the posWin
/// </summary>
/// <param name="viewRect">View rectangle</param>
public void UpdateWin(Rectangle viewRect)
{
CalendarItem item = _View.SelectedItem;
if (item != null)
{
// Calculate where the window should be positioned
// and what time should be displayed
Point pt = item.Bounds.Location;
DateTime time = item.StartTime;
pt.X += item.Bounds.Width + 4;
if (pt.X > _View.ClientRect.Right)
pt.X = _View.ClientRect.Right + 4;
if (_View.NClientData.TabOrientation == eTabOrientation.Horizontal)
{
if (_View.SelectedItem.HitArea == CalendarItem.eHitArea.BottomResize)
{
pt.Y += (item.Bounds.Height - PosHeight);
time = item.EndTime;
}
}
else
{
if (_View.SelectedItem.HitArea == CalendarItem.eHitArea.RightResize)
time = item.EndTime;
}
if (pt.Y < viewRect.Y)
pt.Y = viewRect.Y;
// Convert the point to global coordinates
// and set our window position accordingly
Control c = (Control)_View.GetContainerControl(true);
if (c != null)
pt = c.PointToScreen(pt);
Location = pt;
// Set the window text and show the window
string fmt = "t";
if (_View.ECalendarView == eCalendarView.TimeLine)
{
switch (_View.CalendarView.TimeLinePeriod)
{
case eTimeLinePeriod.Years:
fmt = "";
PosText = time.Year.ToString();
break;
case eTimeLinePeriod.Days:
fmt = "g";
break;
}
}
if (fmt != "")
{
PosText = _View.CalendarView.Is24HourFormat == true
? time.ToString(fmt, DateTimeFormatInfo.InvariantInfo)
: time.ToString(fmt, null);
}
Show();
}
}
#endregion
#region Paint processing
/// <summary>
/// Paint processing
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PosWin_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
const eTextFormat tf =
eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter;
Size sz = TextDrawing.MeasureString(g, _PosText, SystemFonts.CaptionFont, 0, tf);
sz.Width += 6;
sz.Height += 4;
this.Size = sz;
int swidth = Screen.FromControl(this).Bounds.Width;
if (Location.X + sz.Width > swidth)
Location = new Point(swidth - sz.Width, Location.Y);
Rectangle r = new Rectangle(0, 0, sz.Width - 1, sz.Height - 1);
g.DrawRectangle(Pens.Black, r);
TextDrawing.DrawString(g, _PosText, SystemFonts.CaptionFont, Color.Black, r, tf);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,41 @@
#if FRAMEWORK20
using System.Globalization;
namespace DevComponents.DotNetBar.Schedule
{
public static class ScheduleSettings
{
public static double TimeSlotSliceHeight = 23d;
public static string TimeRulerHourFormatString = "00";
public static string TimeRulerMinuteFormatString = "00";
private static CultureInfo _currentCulture;
/// <summary>
/// Gets or sets the CultureInfo for the culture used by the DateTime and Numeric Input controls.
/// Default value is null which indicates that controls will use CurrentUICulture.
/// </summary>
public static CultureInfo CurrentCulture
{
get
{
return _currentCulture;
}
set
{
_currentCulture = value;
}
}
/// <summary>
/// Gets the Culture used by the date time input and month calendar controls
/// </summary>
/// <returns>reference to CultureInfo</returns>
public static CultureInfo GetActiveCulture()
{
return (_currentCulture ?? CultureInfo.CurrentCulture);
}
}
}
#endif

View File

@@ -0,0 +1,600 @@
#if FRAMEWORK20
using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
namespace DevComponents.DotNetBar.Schedule
{
[TypeConverter(typeof(TimeIndicatorConvertor))]
public class TimeIndicator : IDisposable
{
#region Events
/// <summary>
/// Occurs when the collection has changed
/// </summary>
[Description("Occurs when the TimeIndicator has changed.")]
public event EventHandler<EventArgs> TimeIndicatorChanged;
/// <summary>
/// Occurs when a TimeIndicator time has changed
/// </summary>
[Description("Occurs when a TimeIndicator time has changed.")]
public event EventHandler<TimeIndicatorTimeChangedEventArgs> TimeIndicatorTimeChanged;
/// <summary>
/// Occurs when a TimeIndicator Color has changed
/// </summary>
[Description("Occurs when a TimeIndicator Color has changed.")]
public event EventHandler<TimeIndicatorColorChangedEventArgs> TimeIndicatorColorChanged;
#endregion
#region Private variables
private DateTime _IndicatorTime;
private TimeSpan _IndicatorTimeOffset;
private eTimeIndicatorArea _IndicatorArea;
private eTimeIndicatorSource _IndicatorSource = eTimeIndicatorSource.SystemTime;
private eTimeIndicatorVisibility _Visibility = eTimeIndicatorVisibility.Hidden;
private eTimeIndicatorLevel _IndicatorLevel = eTimeIndicatorLevel.Bottom;
private Color _BorderColor;
private ColorDef _IndicatorColor = new ColorDef();
private int _Thickness = 4;
private bool _Enabled = true;
private bool _IsProtected;
private bool _IsDesignMode;
private int _UpdateCount;
private object _Tag;
#endregion
/// <summary>
/// Constructor
/// </summary>
public TimeIndicator()
{
_IndicatorTime = DateTime.Now;
_IndicatorColor.ColorDefChanged += IndicatorColor_ColorDefChanged;
}
#region Internal properties
#region IndicatorDisplayTime
/// <summary>
/// Gets the Indicator display time.
///
/// The DisplayTime is the addition of the IndicatorTime
/// and IndicatorTimeOffset.
/// </summary>
internal DateTime IndicatorDisplayTime
{
get
{
if (_IsDesignMode == true)
return (DateTime.Now.Date.AddHours(3));
return (_IndicatorTime.Add(_IndicatorTimeOffset));
}
}
#endregion
#region DesignMode
/// <summary>
/// Gets or sets whether we are in design mode
/// </summary>
internal bool IsDesignMode
{
get { return (_IsDesignMode); }
set { _IsDesignMode = value; }
}
#endregion
#region IsProtected
/// <summary>
/// Gets or sets whether the timer indicator
/// is protected (can't be deleted)
/// </summary>
internal bool IsProtected
{
get { return (_IsProtected); }
set { _IsProtected = value; }
}
#endregion
#endregion
#region Public properties
#region BorderColor
/// <summary>
/// Gets or sets the leading edge border color
/// </summary>
[Browsable(true), DefaultValue(typeof(Color), "Empty")]
[Description("Indicates the leading edge border color.")]
public Color BorderColor
{
get { return (_BorderColor); }
set
{
if (_BorderColor.Equals(value) == false)
{
_BorderColor = value;
OnTimeIndicatorChanged();
}
}
}
#endregion
#region Enabled
/// <summary>
/// Gets or sets whether automatic time updates are enabled.
/// This property, whose default is true, is only utilized when
/// the IndicatorSource is set to eTimeIndicatorSource.SystemTime
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Enabled
{
get { return (_Enabled); }
set
{
if (_Enabled != value)
{
_Enabled = value;
if (_Enabled == true &&
_IndicatorSource == eTimeIndicatorSource.SystemTime)
{
IndicatorTime = DateTime.Now;
}
}
}
}
#endregion
#region IndicatorArea
/// <summary>
/// Gets or sets the Indicator Display Area.
///
/// This property determines where the Indicator is
/// drawn: in the Time Header, View Content, or both.
/// </summary>
[Browsable(true), DefaultValue(eTimeIndicatorArea.Header)]
[Description("Indicates the Indicator display area.")]
public eTimeIndicatorArea IndicatorArea
{
get { return (_IndicatorArea); }
set
{
if (_IndicatorArea != value)
{
_IndicatorArea = value;
OnTimeIndicatorChanged();
}
}
}
#endregion
#region IndicatorColor
/// <summary>
/// Gets or sets the Indicator color
/// </summary>
[Browsable(true)]
[Description("Indicates the Indicator color.")]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]
public ColorDef IndicatorColor
{
get { return (_IndicatorColor); }
set
{
if (_IndicatorColor != null)
_IndicatorColor.ColorDefChanged -= IndicatorColor_ColorDefChanged;
_IndicatorColor = value;
if (_IndicatorColor != null)
_IndicatorColor.ColorDefChanged += IndicatorColor_ColorDefChanged;
OnTimeIndicatorColorChanged();
}
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public void ResetIndicatorColor()
{
IndicatorColor = new ColorDef();
}
#endregion
#region IndicatorLevel
/// <summary>
/// Gets or sets the IndicatorTime display level
/// </summary>
[Browsable(true), DefaultValue(eTimeIndicatorLevel.Bottom)]
[Description("Indicates the Indicator display level.")]
public eTimeIndicatorLevel IndicatorLevel
{
get { return (_IndicatorLevel); }
set
{
if (_IndicatorLevel != value)
{
_IndicatorLevel = value;
OnTimeIndicatorChanged();
}
}
}
#endregion
#region IndicatorTime
/// <summary>
/// Gets or sets the Indicator time
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public DateTime IndicatorTime
{
get { return (_IndicatorTime); }
set
{
if (_IndicatorTime.Equals(value) == false)
{
DateTime oldValue = IndicatorDisplayTime;
_IndicatorTime = value;
OnTimeIndicatorTimeChanged(oldValue, _IndicatorTime.Add(_IndicatorTimeOffset));
}
}
}
#endregion
#region IndicatorTimeOffset
/// <summary>
/// Gets or sets the Indicator time offset.
///
/// This value is added to the current IndicatorTime
/// before displaying the indicator.
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public TimeSpan IndicatorTimeOffset
{
get { return (_IndicatorTimeOffset); }
set
{
if (_IndicatorTimeOffset.Equals(value) == false)
{
_IndicatorTimeOffset = value;
OnTimeIndicatorChanged();
}
}
}
#endregion
#region Visibility
/// <summary>
/// Gets or sets the Indicator visibility
/// </summary>
[Browsable(true)]
[DefaultValue(eTimeIndicatorVisibility.Hidden)]
[Description("Indicates the Indicator visibility.")]
public eTimeIndicatorVisibility Visibility
{
get { return (_Visibility); }
set
{
if (_Visibility != value)
{
_Visibility = value;
OnTimeIndicatorChanged();
}
}
}
#endregion
#region Tag
/// <summary>
/// Gets or sets the User defined data associated with the object
/// </summary>
[Browsable(false)]
public object Tag
{
get { return (_Tag); }
set { _Tag = value; }
}
#endregion
#region Thickness
/// <summary>
/// Gets or sets the thickness of the Indicator
/// </summary>
[Browsable(true), DefaultValue(4)]
[Description("Indicates the thickness of the Indicator.")]
public int Thickness
{
get { return (_Thickness); }
set
{
if (_Thickness != value)
{
_Thickness = value;
OnTimeIndicatorChanged();
}
}
}
#endregion
#region IndicatorSource
/// <summary>
/// Gets or sets the IndicatorTime source
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public eTimeIndicatorSource IndicatorSource
{
get { return (_IndicatorSource); }
set
{
if (_IndicatorSource != value)
{
_IndicatorSource = value;
OnTimeIndicatorChanged();
}
}
}
#endregion
#endregion
#region IsVisible
/// <summary>
/// Gets whether the indicator is visible
/// </summary>
/// <returns></returns>
internal bool IsVisible()
{
return (_Visibility != eTimeIndicatorVisibility.Hidden);
}
/// <summary>
/// Gets whether the indicator is visible
/// in the given view
/// </summary>
/// <param name="calendarView"></param>
/// <param name="view"></param>
/// <returns></returns>
internal bool IsVisible(CalendarView calendarView, BaseView view)
{
if (_Visibility == eTimeIndicatorVisibility.Hidden)
return (false);
if (_Visibility == eTimeIndicatorVisibility.AllResources)
return (true);
return ((calendarView == null || view.DisplayedOwnerKeyIndex == -1 ||
calendarView.SelectedOwnerIndex == view.DisplayedOwnerKeyIndex));
}
#endregion
#region IndicatorColor_ColorDefChanged
/// <summary>
/// Handles ColorDefChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IndicatorColor_ColorDefChanged(object sender, EventArgs e)
{
OnTimeIndicatorChanged();
}
#endregion
#region OnTimeIndicatorChanged
/// <summary>
/// Handles TimeIndicatorChanged propagation
/// </summary>
private void OnTimeIndicatorChanged()
{
if (TimeIndicatorChanged != null)
TimeIndicatorChanged(this, EventArgs.Empty);
}
#endregion
#region OnTimeIndicatorColorChanged
/// <summary>
/// Handles OnTimeIndicatorColorChanged propagation
/// </summary>
private void OnTimeIndicatorColorChanged()
{
if (TimeIndicatorColorChanged != null)
TimeIndicatorColorChanged(this, new TimeIndicatorColorChangedEventArgs(this));
}
#endregion
#region OnTimeIndicatorTimeChanged
/// <summary>
/// Handles TimeIndicatorTimeChanged propagation
/// </summary>
/// <param name="oldValue"></param>
/// <param name="newValue"></param>
private void OnTimeIndicatorTimeChanged(DateTime oldValue, DateTime newValue)
{
if (TimeIndicatorTimeChanged != null)
TimeIndicatorTimeChanged(this, new TimeIndicatorTimeChangedEventArgs(this, oldValue, newValue));
}
#endregion
#region Begin/EndUpdate
/// <summary>
/// Begins Update block
/// </summary>
public void BeginUpdate()
{
_UpdateCount++;
}
/// <summary>
/// Ends update block
/// </summary>
public void EndUpdate()
{
if (_UpdateCount == 0)
{
throw new InvalidOperationException(
"EndUpdate must be called After BeginUpdate");
}
_UpdateCount--;
if (_UpdateCount == 0)
OnTimeIndicatorChanged();
}
#endregion
#region IDisposable
public void Dispose()
{
if (_IndicatorColor != null)
_IndicatorColor.ColorDefChanged -= IndicatorColor_ColorDefChanged;
}
#endregion
}
#region TimeIndicatorConvertor
/// <summary>
/// TimeIndicatorConvertor
/// </summary>
public class TimeIndicatorConvertor : ExpandableObjectConverter
{
public override object ConvertTo(
ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
return (String.Empty);
}
}
#endregion
#region enums
#region eTimeIndicatorSource
/// <summary>
/// Specifies the source for the IndicatorTime
/// </summary>
public enum eTimeIndicatorSource
{
SystemTime,
UserSpecified
}
#endregion
#region eTimeIndicatorVisibility
/// <summary>
/// Specifies the Indicator visibility
/// </summary>
public enum eTimeIndicatorVisibility
{
AllResources,
SelectedResource,
Hidden
}
#endregion
#region eTimeIndicatorArea
/// <summary>
/// Specifies the Indicator display area
/// </summary>
public enum eTimeIndicatorArea
{
Header,
Content,
All
}
#endregion
#region eTimeIndicatorLevel
/// <summary>
/// Specifies the Indicator display level
/// </summary>
public enum eTimeIndicatorLevel
{
Bottom,
Top
}
#endregion
#endregion
}
#endif

View File

@@ -0,0 +1,498 @@
#if FRAMEWORK20
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Schedule
{
public class TimeIndicatorCollection : Collection<TimeIndicator>, IDisposable
{
#region Events
/// <summary>
/// Occurs when the TimeIndicator collection has changed
/// </summary>
[Description("Occurs when the TimeIndicator collection has changed.")]
public event EventHandler<EventArgs> TimeIndicatorCollectionChanged;
/// <summary>
/// Occurs when a TimeIndicator time has changed
/// </summary>
[Description("Occurs when a TimeIndicator time has changed.")]
public event EventHandler<TimeIndicatorTimeChangedEventArgs> TimeIndicatorTimeChanged;
/// <summary>
/// Occurs when a TimeIndicator Color has changed
/// </summary>
[Description("Occurs when a TimeIndicator Color has changed.")]
public event EventHandler<TimeIndicatorColorChangedEventArgs> TimeIndicatorColorChanged;
#endregion
#region Private variables
private int _UpdateCount;
private Timer _Timer;
#endregion
#region AddRange
/// <summary>
/// Adds a range of TimeIndicators to the collection
/// </summary>
/// <param name="items">Array of items to add</param>
public void AddRange(TimeIndicator[] items)
{
try
{
BeginUpdate();
for (int i = 0; i < items.Length; i++)
Add(items[i]);
}
finally
{
EndUpdate();
}
}
#endregion
#region RemoveItem
/// <summary>
/// Processes list RemoveItem calls
/// </summary>
/// <param name="index">Index to remove</param>
protected override void RemoveItem(int index)
{
if (Items[index].IsProtected == false)
{
Items[index].TimeIndicatorChanged -= IndicatorCollectionChanged;
Items[index].TimeIndicatorTimeChanged -= IndicatorTimeChanged;
Items[index].TimeIndicatorColorChanged -= IndicatorColorChanged;
base.RemoveItem(index);
OnCollectionChanged();
}
}
#endregion
#region InsertItem
/// <summary>
/// Processes list InsertItem calls
/// </summary>
/// <param name="index">Index to add</param>
/// <param name="item">TimeIndicator to add</param>
protected override void InsertItem(int index, TimeIndicator item)
{
if (item != null)
{
item.TimeIndicatorChanged += IndicatorCollectionChanged;
item.TimeIndicatorTimeChanged += IndicatorTimeChanged;
item.TimeIndicatorColorChanged += IndicatorColorChanged;
base.InsertItem(index, item);
OnCollectionChanged();
}
}
#endregion
#region SetItem
/// <summary>
/// Processes list SetItem calls (e.g. replace)
/// </summary>
/// <param name="index">Index to replace</param>
/// <param name="newItem">TimeIndicator to replace</param>
protected override void SetItem(int index, TimeIndicator newItem)
{
if (Items[index].IsProtected == false)
{
if (newItem != null)
{
Items[index].TimeIndicatorChanged -= IndicatorCollectionChanged;
Items[index].TimeIndicatorTimeChanged -= IndicatorTimeChanged;
Items[index].TimeIndicatorColorChanged -= IndicatorColorChanged;
newItem.TimeIndicatorChanged += IndicatorCollectionChanged;
newItem.TimeIndicatorTimeChanged += IndicatorTimeChanged;
newItem.TimeIndicatorColorChanged += IndicatorColorChanged;
base.SetItem(index, newItem);
OnCollectionChanged();
}
}
}
#endregion
#region ClearItems
/// <summary>
/// Processes list Clear calls (e.g. remove all)
/// </summary>
protected override void ClearItems()
{
try
{
BeginUpdate();
for (int i = Count - 1; i>=0 ; i--)
{
if (Items[i].IsProtected == false)
{
Items[i].TimeIndicatorChanged -= IndicatorCollectionChanged;
Items[i].TimeIndicatorTimeChanged -= IndicatorTimeChanged;
Items[i].TimeIndicatorColorChanged -= IndicatorColorChanged;
RemoveAt(i);
}
}
}
finally
{
EndUpdate();
}
}
#endregion
#region Events
#region IndicatorCollectionChanged
/// <summary>
/// IndicatorCollectionChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IndicatorCollectionChanged(object sender, EventArgs e)
{
OnCollectionChanged();
}
#endregion
#region IndicatorColorChanged
/// <summary>
/// IndicatorColorChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IndicatorColorChanged(object sender, TimeIndicatorColorChangedEventArgs e)
{
OnTimeIndicatorColorChanged(e);
}
#endregion
#region IndicatorTimeChanged
/// <summary>
/// IndicatorTimeChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IndicatorTimeChanged(object sender, TimeIndicatorTimeChangedEventArgs e)
{
OnTimeIndicatorTimeChanged(e);
}
#endregion
#endregion
#region OnCollectionChanged
/// <summary>
/// Propagates TimeIndicatorCollectionChanged events
/// </summary>
protected virtual void OnCollectionChanged()
{
if (_UpdateCount == 0)
{
UpdateTimerUse();
if (TimeIndicatorCollectionChanged != null)
TimeIndicatorCollectionChanged(this, EventArgs.Empty);
}
}
#endregion
#region OnTimeIndicatorColorChanged
/// <summary>
/// Propagates OnTimeIndicatorColorChanged events
/// </summary>
/// <param name="e"></param>
protected virtual void OnTimeIndicatorColorChanged(TimeIndicatorColorChangedEventArgs e)
{
if (_UpdateCount == 0)
{
if (TimeIndicatorColorChanged != null)
TimeIndicatorColorChanged(this, e);
}
}
#endregion
#region OnTimeIndicatorTimeChanged
/// <summary>
/// Propagates OnTimeIndicatorTimeChanged events
/// </summary>
/// <param name="e"></param>
protected virtual void OnTimeIndicatorTimeChanged(TimeIndicatorTimeChangedEventArgs e)
{
if (_UpdateCount == 0)
{
if (TimeIndicatorTimeChanged != null)
TimeIndicatorTimeChanged(this, e);
}
}
#endregion
#region System Timer support
#region UpdateTimerUse
/// <summary>
/// Updates our system timer use
/// </summary>
private void UpdateTimerUse()
{
// If we need a timer, then allocate it
// and initialize it to fire approx every minute
if (TimerNeeded() == true)
{
if (_Timer == null)
{
_Timer = new Timer();
_Timer.Tick += Timer_Tick;
DateTime now = DateTime.Now;
_Timer.Interval = (60 - now.Second) * 1000 + (1050 - now.Millisecond);
_Timer.Enabled = true;
}
}
else
{
if (_Timer != null)
{
_Timer.Enabled = false;
_Timer.Tick -= Timer_Tick;
_Timer.Dispose();
_Timer = null;
}
}
}
#endregion
#region TimerNeeded
/// <summary>
/// Determines if a system timer is needed
/// </summary>
/// <returns>true if needed</returns>
private bool TimerNeeded()
{
for (int i = 0; i < Items.Count; i++)
{
TimeIndicator ti = Items[i];
if (ti.IsDesignMode == true)
return (false);
if (ti.Enabled == true &&
ti.IndicatorSource == eTimeIndicatorSource.SystemTime)
{
return (true);
}
}
return (false);
}
#endregion
#region Timer_Tick
/// <summary>
/// Handles our timer tick events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Timer_Tick(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
_Timer.Interval = (60 - now.Second) * 1000 + (1050 - now.Millisecond);
for (int i = 0; i < Items.Count; i++)
{
TimeIndicator ti = Items[i];
if (ti.Enabled == true &&
ti.IndicatorSource == eTimeIndicatorSource.SystemTime)
{
ti.IndicatorTime = now;
}
}
}
#endregion
#endregion
#region Begin/EndUpdate
/// <summary>
/// Begins Update block
/// </summary>
public void BeginUpdate()
{
_UpdateCount++;
}
/// <summary>
/// Ends update block
/// </summary>
public void EndUpdate()
{
if (_UpdateCount == 0)
{
throw new InvalidOperationException(
"EndUpdate must be called After BeginUpdate");
}
_UpdateCount--;
if (_UpdateCount == 0)
OnCollectionChanged();
}
#endregion
#region IDisposable
public void Dispose()
{
for (int i = Count - 1; i >= 0; i--)
{
Items[i].TimeIndicatorChanged -= IndicatorCollectionChanged;
Items[i].TimeIndicatorTimeChanged -= IndicatorTimeChanged;
Items[i].TimeIndicatorColorChanged -= IndicatorColorChanged;
}
}
#endregion
}
#region TimeIndicatorTimeChangedEventArgs
/// <summary>
/// TimeIndicatorTimeChangedEventArgs
/// </summary>
public class TimeIndicatorTimeChangedEventArgs : EventArgs
{
#region Private variables
private TimeIndicator _TimeIndicator;
private DateTime _OldTime;
private DateTime _NewTime;
#endregion
public TimeIndicatorTimeChangedEventArgs(
TimeIndicator timeIndicator, DateTime oldTime, DateTime newTime)
{
_TimeIndicator = timeIndicator;
_OldTime = oldTime;
_NewTime = newTime;
}
#region Public properties
/// <summary>
/// Gets the TimeIndicator being affected
/// </summary>
public TimeIndicator TimeIndicator
{
get { return (_TimeIndicator); }
}
/// <summary>
/// Gets the old DateTime
/// </summary>
public DateTime OldTime
{
get { return (_OldTime); }
}
/// <summary>
/// Gets the new DateTime
/// </summary>
public DateTime NewTime
{
get { return (_NewTime); }
}
#endregion
}
#endregion
#region TimeIndicatorColorChangedEventArgs
/// <summary>
/// TimeIndicatorColorChangedEventArgs
/// </summary>
public class TimeIndicatorColorChangedEventArgs : EventArgs
{
#region Private variables
private TimeIndicator _TimeIndicator;
#endregion
public TimeIndicatorColorChangedEventArgs(TimeIndicator timeIndicator)
{
_TimeIndicator = timeIndicator;
}
#region Public properties
/// <summary>
/// Gets the TimeIndicator being affected
/// </summary>
public TimeIndicator TimeIndicator
{
get { return (_TimeIndicator); }
}
#endregion
}
#endregion
}
#endif

View File

@@ -0,0 +1,38 @@
#if FRAMEWORK20
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
public class DayInfo
{
#region Private data
private WorkTime _WorkStartTime;
private WorkTime _WorkEndTime;
#endregion
#region Public properties
/// <summary>
/// Gets and sets work start time
/// </summary>
public WorkTime WorkStartTime
{
get { return (_WorkStartTime); }
set { _WorkStartTime = value; }
}
/// <summary>
/// Gets and sets work end time
/// </summary>
public WorkTime WorkEndTime
{
get { return (_WorkEndTime); }
set { _WorkEndTime = value; }
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,845 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using DevComponents.Schedule.Model;
using System.ComponentModel;
namespace DevComponents.DotNetBar.Schedule
{
internal class ModelTimeLineViewConnector : ModelViewConnector
{
#region Const
private const int DaysInWeek = 7;
#endregion
#region Static data
static private AppointmentSubsetCollection _lineAppts;
static private List<Appointment> _listAppts;
static private DateTime _lineStartTime; // TimeLine start date
static private DateTime _lineEndTime; // TimeLine end date
static private int _lineState; // Refresh state
static private List<Appointment> _periodAppts;
static private DateTime _periodStartTime; // Period start date
static private DateTime _periodEndTime; // Period end date
#endregion
#region Private variables
private CalendarModel _Model; // The associated CalendarModel
private TimeLineView _View; // The associated _TimeLineView
private DateTime _ViewStartTime; // View start time
private DateTime _ViewEndTime; // View end time
private int _ViewState; // View refresh state
private DayInfo[] _DayInfo; // DayInfo array (WorkStartTimes)
private bool _IsConnected; // Connection status
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="model">Assoc CalendarModel</param>
/// <param name="timeLineView">Assoc TimeLineView</param>
public ModelTimeLineViewConnector(CalendarModel model, TimeLineView timeLineView)
{
_Model = model;
_View = timeLineView;
}
#region Public properties
/// <summary>
/// Gets the connection status
/// </summary>
public override bool IsConnected
{
get { return (_IsConnected); }
}
/// <summary>
/// Gets the internal AppointmentSubsetCollection
/// </summary>
public AppointmentSubsetCollection Appts
{
get
{
if (_lineAppts == null)
_lineAppts = new AppointmentSubsetCollection(_Model, _lineStartTime, _lineEndTime);
return (_lineAppts);
}
}
/// <summary>
/// Gets the list of line appointments
/// </summary>
public List<Appointment> ListAppts
{
get { return (_listAppts); }
}
/// <summary>
/// Gets the DayInfo array
/// </summary>
public DayInfo[] DayInfo
{
get { return (_DayInfo); }
}
#endregion
#region Connect processing
/// <summary>
/// Performs Model connection processing
/// </summary>
public override void Connect()
{
VerifyModel();
if (_IsConnected)
Disconnect();
LoadData();
// Get notification on Model property changes
HookEvents(true);
_IsConnected = true;
}
#endregion
#region Hook events
/// <summary>
/// Hooks or unhooks our system events
/// </summary>
/// <param name="hook"></param>
private void HookEvents(bool hook)
{
if (hook == true)
{
_Model.PropertyChanged += ModelPropertyChanged;
_Model.SubPropertyChanged += ModelSubPropertyChanged;
_View.CalendarView.CustomItems.CollectionChanged += CustomItemsCollectionChanged;
}
else
{
_Model.PropertyChanged -= ModelPropertyChanged;
_Model.SubPropertyChanged -= ModelSubPropertyChanged;
_View.CalendarView.CustomItems.CollectionChanged -= CustomItemsCollectionChanged;
}
}
#endregion
#region Event processing
#region Model property change processing
/// <summary>
/// Handles Model property change notifications
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == CalendarModel.AppointmentsPropertyName)
{
_ViewStartTime = new DateTime();
RefreshData(_ViewState == _lineState);
_View.NeedRecalcLayout = true;
_View.NeedRecalcSize = true;
}
else if (e.PropertyName == CalendarModel.WorkDaysPropertyName)
{
UpdateWorkDayDetails();
_View.Refresh();
}
}
#endregion
#region ModelSubPropertyChanged
/// <summary>
/// Handles ModelSubProperty change notifications
/// </summary>
/// <param name="sender">object</param>
/// <param name="e">SubPropertyChangedEventArgs</param>
private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e)
{
if (e.Source is WorkDay)
{
UpdateWorkDayDetails();
}
else if (e.Source is Owner)
{
Owner owner = (Owner)e.Source;
if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key))
{
if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName)
_View.DisplayName = owner.DisplayName;
else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme"))
_View.CalendarColor = owner.ColorScheme;
}
}
else if (e.Source is Appointment)
{
Appointment app = e.Source as Appointment;
AppointmentTimeLineView appView;
string name = e.PropertyChangedArgs.PropertyName;
if (name.Equals("Tooltip"))
{
appView = GetViewFromTimeLine(app);
if (appView != null)
appView.Tooltip = app.Tooltip;
}
else if (name.Equals("IsSelected"))
{
appView = GetViewFromTimeLine(app);
if (appView != null)
appView.IsSelected = app.IsSelected;
}
else if (name.Equals("CategoryColor") || name.Equals("TimeMarkedAs"))
{
appView = GetViewFromTimeLine(app);
if (appView != null)
appView.Refresh();
}
else if (name.Equals("OwnerKey"))
{
if (_View.CalendarView.IsMultiCalendar == true)
{
if (_View.OwnerKey == app.OwnerKey)
{
_ViewStartTime = new DateTime();
RefreshData(false);
_View.NeedRecalcLayout = true;
_View.RecalcSize();
}
else
{
appView = GetViewFromTimeLine(app);
if (appView != null)
{
_ViewStartTime = new DateTime();
RefreshData(false);
_View.NeedRecalcLayout = true;
_View.RecalcSize();
}
}
}
}
else if (name.Equals("Visible"))
{
RefreshData(true);
}
}
}
#endregion
#region CustomItems_CollectionChanged
/// <summary>
/// Handles CustomItemCollection change events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CustomItemsCollectionChanged(object sender, EventArgs e)
{
_ViewStartTime = new DateTime();
RefreshData(_ViewState == _lineState);
_View.NeedRecalcLayout = true;
_View.NeedRecalcSize = true;
}
#endregion
#endregion
#region Disconnect processing
/// <summary>
/// Severs the Model/TimeLineView connection
/// </summary>
public override void Disconnect()
{
VerifyModel();
if (_IsConnected)
{
_IsConnected = false;
_lineState = 0;
// Clear our TimeLine items and
// stop notification on Model property changes
ClearTimeLineItems();
HookEvents(false);
}
}
/// <summary>
/// Clears TimeLine view items
/// </summary>
private void ClearTimeLineItems()
{
if (_View.CalendarItems.Count > 0)
{
// Loop through each CalendarItem, resetting
// it's associated connection
for (int i = _View.CalendarItems.Count - 1; i >= 0; i--)
{
AppointmentTimeLineView view =
_View.CalendarItems[i] as AppointmentTimeLineView;
if (view != null)
{
view.IsSelectedChanged -= _View.ItemIsSelectedChanged;
view.Appointment = null;
view.IsSelected = false;
}
_View.CalendarItems.RemoveAt(i);
}
}
_View.SubItems.Clear();
}
#endregion
#region LoadData processing
/// <summary>
/// Loads Model/TimeLineView connection data
/// </summary>
private void LoadData()
{
LoadViewData(true, false);
UpdateWorkDayDetails();
}
#endregion
#region LoadViewData
/// <summary>
/// Loads the view data
/// </summary>
/// <param name="reload">Forceful reload</param>
/// <param name="validate">Validation needed</param>
private void LoadViewData(bool reload, bool validate)
{
DateTime startTime, endTime;
GetDateRange(out startTime, out endTime);
reload = LoadPeriodData(reload, startTime, endTime);
if (reload == true ||
_ViewStartTime != startTime || _ViewEndTime != endTime)
{
_ViewStartTime = startTime;
_ViewEndTime = endTime;
if (validate == true)
{
RemoveOutdatedViews(_periodAppts);
RemoveOutdatedCustomItems();
}
UpdateTimeLineView(_periodAppts);
UpdateCustomItems();
}
}
#endregion
#region LoadPeriodData
/// <summary>
/// Loads the Period data (visible view range)
/// </summary>
/// <param name="reload">Forceful reload</param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <returns>reload flag</returns>
private bool LoadPeriodData(bool reload, DateTime startTime, DateTime endTime)
{
reload = LoadLineData(reload);
if (reload == true ||
_periodStartTime != startTime || _periodEndTime != endTime)
{
_periodStartTime = startTime;
_periodEndTime = endTime;
_periodAppts = new List<Appointment>();
if (_listAppts != null)
{
for (int i = 0; i < _listAppts.Count; i++)
{
Appointment app = _listAppts[i];
if (app.EndTime > _periodStartTime && app.StartTime < _periodEndTime)
_periodAppts.Add(app);
}
}
reload = true;
}
return (reload);
}
#endregion
#region LoadLineData
/// <summary>
/// Loads the TimeLine appointment data
/// </summary>
/// <param name="reload"></param>
private bool LoadLineData(bool reload)
{
if (reload == true ||
_lineStartTime != _View.StartDate || _lineEndTime != _View.EndDate)
{
_lineStartTime = _View.StartDate;
_lineEndTime = _View.EndDate;
_lineAppts = null; // Legacy...
_listAppts = GetAppointmentList(_Model, _View.StartDate, _View.EndDate.AddDays(1));
_lineState = _lineState ^ 1;
}
if (_ViewState != _lineState)
{
_ViewState = _lineState;
_View.ModelReloaded = true;
reload = true;
}
return (reload);
}
#endregion
#region RefreshData processing
/// <summary>
/// Refreshes the data in a previously established
/// and loaded connection
/// </summary>
public void RefreshData(bool reload)
{
if (_View.Displayed == true)
LoadViewData(reload, true);
}
#endregion
#region GetDateRange
/// <summary>
/// Gets the range of appointment dates
/// </summary>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
private void GetDateRange(out DateTime startDate, out DateTime endDate)
{
int scol = _View.FirstVisibleColumn;
int ncols = _View.ClientRect.Width / _View.ColumnWidth;
startDate = _View.StartDate;
endDate = startDate;
try
{
startDate = startDate.AddMinutes(scol * _View.CalendarView.BaseInterval);
endDate = startDate.AddMinutes(ncols * _View.CalendarView.BaseInterval);
startDate = startDate.AddMinutes(-_View.CalendarView.BaseInterval);
endDate = endDate.AddMinutes(_View.CalendarView.BaseInterval);
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
}
}
#endregion
#region UpdateTimeLineView
/// <summary>
/// Updates the TimeLine view
/// </summary>
/// <param name="appointments"></param>
private void UpdateTimeLineView(List<Appointment> appointments)
{
// Loop through each appointment
// updating the assoc view accordingly
foreach (Appointment appointment in appointments)
{
if (IsAppointmentVisible(appointment))
{
// Get the assoc view
AppointmentTimeLineView view =
GetViewFromTimeLine(appointment) ?? GetNewView(appointment);
// Set the view start and end times to
// match the assoc appointment
view.StartTime = appointment.StartTime;
view.EndTime = appointment.EndTime;
// Update the item data
if (view.TimeLineView == null)
{
view.TimeLineView = _View;
_View.CalendarItems.Add(view);
_View.SubItems.Add(view);
view.IsSelectedChanged += _View.ItemIsSelectedChanged;
}
}
}
}
#endregion
#region UpdateCustomItems
/// <summary>
/// Updates the TimeLine CustomItems
/// </summary>
private void UpdateCustomItems()
{
CustomCalendarItemCollection items = _View.CalendarView.CustomItems;
if (items != null)
{
for (int i = 0; i < items.Count; i++)
{
CustomCalendarItem item = items[i];
if (IsCustomItemVisible(item) == true &&
(item.StartTime < _ViewEndTime && item.EndTime > _ViewStartTime))
{
item.CalendarView = _View.CalendarView;
CustomCalendarItem ci =
GetItemFromTimeLine(item) ?? GetNewCustomItem(item);
if (ci.StartTime != item.StartTime || ci.EndTime != item.EndTime)
{
ci.StartTime = item.StartTime;
ci.EndTime = item.EndTime;
}
}
}
}
}
#endregion
#region UpdateWorkDayDetails
/// <summary>
/// Updates the WorkDay details array
/// </summary>
private void UpdateWorkDayDetails()
{
// Update workDay timings
if (_DayInfo == null)
_DayInfo = new DayInfo[DaysInWeek];
for (int i = 0; i < DaysInWeek; i++)
{
if (_DayInfo[i] == null)
_DayInfo[i] = new DayInfo();
Owner owner = _Model.Owners[_View.OwnerKey];
WorkDay workDay = (owner != null && owner.WorkDays.Count > 0)
? owner.WorkDays[(DayOfWeek)i] : _Model.WorkDays[(DayOfWeek)i];
if (workDay != null)
{
_DayInfo[i].WorkStartTime = workDay.WorkStartTime;
_DayInfo[i].WorkEndTime = workDay.WorkEndTime;
}
else
{
_DayInfo[i].WorkStartTime = new WorkTime();
_DayInfo[i].WorkEndTime = new WorkTime();
}
}
}
#endregion
#region RemoveOutdatedViews
/// <summary>
/// Removes Outdated Views
/// </summary>
/// <param name="appts"></param>
private void RemoveOutdatedViews(List<Appointment> appts)
{
for (int i=_View.CalendarItems.Count - 1; i>=0; i--)
{
AppointmentTimeLineView view =
_View.CalendarItems[i] as AppointmentTimeLineView;
if (view != null)
{
if (ValidViewAppointment(appts, view) == false)
{
view.TimeLineView = null;
_View.NeedRecalcLayout = true;
_View.SubItems._Remove(view);
_View.CalendarItems.RemoveAt(i);
if (view == _View.SelectedItem)
_View.SelectedItem = null;
view.IsSelectedChanged -= _View.ItemIsSelectedChanged;
}
}
}
}
/// <summary>
/// Determines if the provided view is valid, given
/// the current list of Appointments
/// </summary>
/// <param name="appts"></param>
/// <param name="view"></param>
/// <returns></returns>
private bool ValidViewAppointment(
List<Appointment> appts, AppointmentTimeLineView view)
{
if (IsAppointmentVisible(view.Appointment) == false)
return (false);
if (view.IsSelected == true)
{
if (_Model.Appointments.Contains(view.Appointment) == true)
return (true);
}
return (appts.Contains(view.Appointment));
}
#endregion
#region RemoveOutdatedCustomItems
/// <summary>
/// Removes out dated CustomItems
/// </summary>
private void RemoveOutdatedCustomItems()
{
for (int i = _View.CalendarItems.Count - 1; i >= 0; i--)
{
CustomCalendarItem item = _View.CalendarItems[i] as CustomCalendarItem;
if (item != null)
{
if (IsValidItem(item) == false ||
(item.IsSelected == false && (item.EndTime < _ViewStartTime || item.StartTime > _ViewEndTime)))
{
_View.NeedRecalcSize = true;
_View.SubItems._Remove(item);
_View.CalendarItems.RemoveAt(i);
if (item == _View.SelectedItem)
_View.SelectedItem = null;
item.IsSelectedChanged -= _View.ItemIsSelectedChanged;
}
}
}
}
/// <summary>
/// Determines if the given CustomItem is valid
/// for the current view
/// </summary>
/// <param name="view"></param>
/// <returns></returns>
private bool IsValidItem(CustomCalendarItem view)
{
return (IsCustomItemVisible(view) == true &&
_View.CalendarView.CustomItems.Contains(view.BaseCalendarItem) == true);
}
#endregion
#region GetViewFromTimeLine
/// <summary>
/// Gets the AppointmentView from the timeline
/// </summary>
/// <param name="appointment"></param>
/// <returns>AppointmentView or null</returns>
private AppointmentTimeLineView GetViewFromTimeLine(Appointment appointment)
{
foreach (CalendarItem item in _View.CalendarItems)
{
AppointmentTimeLineView view = item as AppointmentTimeLineView;
if (view != null && view.Appointment == appointment)
return (view);
}
return (null);
}
#endregion
#region GetItemFromTimeLine
/// <summary>
/// Gets the CustomCalendarItem from the timeline.
/// </summary>
/// <param name="item"></param>
/// <returns>CustomCalendarItem or null</returns>
private CustomCalendarItem GetItemFromTimeLine(CustomCalendarItem item)
{
foreach (CalendarItem citem in _View.CalendarItems)
{
CustomCalendarItem view = citem as CustomCalendarItem;
if (view != null && (view == item || view.BaseCalendarItem == item))
return (view);
}
return (null);
}
#endregion
#region GetNewView
/// <summary>
/// Gets a new appointment view
/// </summary>
/// <param name="appointment">Appointment</param>
/// <returns>New view</returns>
private AppointmentTimeLineView GetNewView(Appointment appointment)
{
AppointmentTimeLineView view = new AppointmentTimeLineView(_View, appointment);
view.Tooltip = appointment.Tooltip;
return (view);
}
#endregion
#region GetNewCustomItem
/// <summary>
/// Gets a new CustomCalendarItem
/// </summary>
/// <param name="item"></param>
/// <returns>CustomCalendarItem</returns>
private CustomCalendarItem GetNewCustomItem(CustomCalendarItem item)
{
CustomCalendarItem ci = (CustomCalendarItem)item.Copy();
ci.BaseCalendarItem = item;
_View.CalendarItems.Add(ci);
_View.NeedRecalcLayout = true;
_View.SubItems.Add(ci);
ci.IsSelectedChanged += _View.ItemIsSelectedChanged;
return (ci);
}
#endregion
#region View support routines
/// <summary>
/// Returns the view
/// </summary>
/// <returns></returns>
public override eCalendarView GetView()
{
return (eCalendarView.TimeLine);
}
/// <summary>
/// Verifies the Model and MonthView are valid
/// </summary>
private void VerifyModel()
{
if (_Model == null)
throw new NullReferenceException("CalendarModel must be set on connector.");
if (_View == null)
throw new NullReferenceException("AppointmentTimeLineView must be set on connector.");
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,716 @@
#if FRAMEWORK20
using System;
using System.Windows.Forms;
using DevComponents.DotNetBar.ScrollBar;
using System.Drawing;
using DevComponents.DotNetBar.Controls;
namespace DevComponents.DotNetBar.Schedule
{
public class TimeLineHScrollPanel : BaseItem
{
#region Events
public event EventHandler<EventArgs> ScrollPanelChanged;
#endregion
#region Private variables
private CalendarView _CalendarView; // CalendarView
private HScrollBarAdv _ScrollBar; // Scroll bar
private PageNavigator _PageNavigator; // PageNavigator
private int _UpdateCount;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="calendarView">_CalendarView</param>
public TimeLineHScrollPanel(CalendarView calendarView)
{
_CalendarView = calendarView;
Name = "TimeLineHScrollPanel";
SetUpPanel();
Visible = false;
}
#region Public properties
/// <summary>
/// Gets and sets the display bounds
/// </summary>
public override Rectangle Bounds
{
get { return (base.Bounds); }
set
{
if (base.Bounds != value)
{
base.Bounds = value;
UpdatePanel();
}
}
}
/// <summary>
/// Gets and sets the visible status
/// </summary>
public override bool Visible
{
get { return (base.Visible); }
set
{
if (base.Visible != value)
{
base.Visible = value;
_ScrollBar.Visible = value;
if (_PageNavigator != null)
_PageNavigator.Visible = value;
}
}
}
/// <summary>
/// Gets the ScrollBar
/// </summary>
public HScrollBarAdv ScrollBar
{
get { return (_ScrollBar); }
}
#endregion
#region Internal properties
internal PageNavigator PageNavigator
{
get { return (_PageNavigator); }
}
#endregion
#region Private properties
/// <summary>
/// Gets the scrollBar SmallChange value
/// </summary>
private int ScrollPanelSmallChange
{
get { return (1); }
}
/// <summary>
/// Gets the scrollBar LargeChange value
/// </summary>
private int ScrollPanelLargeChange
{
get { return (Math.Min(ScrollPanelMaximum, ScrollBar.Width / _CalendarView.TimeLineColumnWidth)); }
}
/// <summary>
/// Gets the scrollBar Maximum value
/// </summary>
private int ScrollPanelMaximum
{
get { return (_CalendarView.TimeLineColumnCount); }
}
#endregion
#region HookScrollEvents
/// <summary>
/// Hooks our ScrollBar events
/// </summary>
/// <param name="hook"></param>
private void HookScrollEvents(bool hook)
{
if (hook == true)
{
ScrollBar.Scroll += ScrollBarScroll;
ScrollBar.ValueChanged += ScrollBarValueChanged;
}
else
{
ScrollBar.Scroll -= ScrollBarScroll;
ScrollBar.ValueChanged -= ScrollBarValueChanged;
}
}
#endregion
#region HookNavigateEvents
/// <summary>
/// Hooks our PageNavigator events
/// </summary>
/// <param name="hook"></param>
private void HookNavigateEvents(bool hook)
{
if (_PageNavigator != null)
{
if (hook == true)
{
_PageNavigator.NavigateNextPage += NavigateNextPage;
_PageNavigator.NavigatePreviousPage += NavigatePreviousPage;
_PageNavigator.NavigateToday += NavigateToday;
}
else
{
_PageNavigator.NavigateNextPage -= NavigateNextPage;
_PageNavigator.NavigatePreviousPage -= NavigatePreviousPage;
_PageNavigator.NavigateToday -= NavigateToday;
}
}
}
#endregion
#region Event handling
#region ScrollBar_Scroll
/// <summary>
/// ScrollBar Scroll event handler
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ScrollBarScroll(object sender, ScrollEventArgs e)
{
if (e.Type == ScrollEventType.SmallIncrement)
{
// The user has right-arrow scrolled to the very end of
// the scrollbar, so add another time slice to timeline
if (ScrollBar.Value >= ScrollBar.Maximum - ScrollBar.LargeChange)
IncreaseEndDate(1);
}
else if (e.Type == ScrollEventType.SmallDecrement)
{
// The user has left-arrow scrolled to the very beginning of
// the scrollbar, so add another time slice to timeline
if (ScrollBar.Value == 0)
DecreaseStartDate(1);
}
}
#endregion
#region ScrollBar_ValueChanged
/// <summary>
/// Processes ScrollBar ValueChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ScrollBarValueChanged(object sender, EventArgs e)
{
OnScrollPanelUpdate();
}
#endregion
#region NavigatePreviousPage
/// <summary>
/// Navigates to the previous page
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void NavigatePreviousPage(object sender, EventArgs e)
{
DateTime startDate;
int n = ScrollBar.LargeChange;
int value = ScrollBar.Value - n;
if (value < 0)
{
startDate = GetDecreaseStartDate(n);
}
else
{
startDate =
_CalendarView.TimeLineViewStartDate.AddMinutes(
_CalendarView.BaseInterval * -n);
}
if (_CalendarView.DoPageNavigatorClick(_CalendarView.TimeLineView,
_PageNavigator, PageNavigatorButton.PreviousPage, ref startDate) == false)
{
_CalendarView.TimeLineViewStartDate = GetIntervalStartDate(startDate);
}
}
#endregion
#region NavigateToday
/// <summary>
/// Navigates to Today
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void NavigateToday(object sender, EventArgs e)
{
DateTime startDate = DateTime.Today;
if (_CalendarView.DoPageNavigatorClick(_CalendarView.TimeLineView,
_PageNavigator, PageNavigatorButton.Today, ref startDate) == false)
{
if (startDate < _CalendarView.TimeLineViewScrollStartDate ||
startDate > _CalendarView.TimeLineViewScrollEndDate)
{
_CalendarView.TimeLineViewScrollStartDate =
GetIntervalStartDate(startDate);
}
}
}
#endregion
#region NavigateNextPage
/// <summary>
/// Navigates to the Next page
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void NavigateNextPage(object sender, EventArgs e)
{
DateTime startDate;
int n = ScrollBar.LargeChange;
int value = ScrollBar.Value + n;
if (value > ScrollBar.Maximum - n)
{
startDate = GetIncreaseEndDate(n);
}
else
{
startDate =
_CalendarView.TimeLineViewStartDate.AddMinutes(
_CalendarView.BaseInterval * n);
}
if (_CalendarView.DoPageNavigatorClick(_CalendarView.TimeLineView,
_PageNavigator, PageNavigatorButton.NextPage, ref startDate) == false)
{
_CalendarView.TimeLineViewStartDate = GetIntervalStartDate(startDate);
}
}
#endregion
#region IncreaseEndDate
/// <summary>
/// Increases timeline EndDate
/// </summary>
/// <param name="n">Amount to add</param>
private void IncreaseEndDate(int n)
{
if (_CalendarView.TimeLineCanExtendRange == true)
{
_CalendarView.TimeLineViewEndDate = GetIncreaseEndDate(n);
int value = ScrollBar.Value + n;
if (value > ScrollBar.Maximum - ScrollBar.LargeChange)
value = ScrollBar.Maximum - ScrollBar.LargeChange;
if (ScrollBar.Value != value)
ScrollBar.Value = value;
else
OnScrollPanelUpdate();
}
}
#endregion
#region GetIncreaseEndDate
/// <summary>
/// Increases timeline EndDate
/// </summary>
/// <param name="n">Amount to add</param>
private DateTime GetIncreaseEndDate(int n)
{
if (_CalendarView.TimeLineCanExtendRange == true)
{
DateTime end = new DateTime(9900, 1, 1);
try
{
DateTime date =
_CalendarView.TimeLineViewEndDate.AddMinutes(
_CalendarView.BaseInterval * n);
if (date > end)
date = end;
return (date);
}
catch
{
return (end);
}
}
return (_CalendarView.TimeLineViewEndDate);
}
#endregion
#region DecreaseStartDate
/// <summary>
/// Decreases the timeline StartDate
/// </summary>
/// <param name="n">Amount to del</param>
private void DecreaseStartDate(int n)
{
if (_CalendarView.TimeLineCanExtendRange == true)
{
DateTime startDate = GetDecreaseStartDate(n);
_CalendarView.TimeLineViewStartDate = startDate;
UpdatePanel();
}
}
#endregion
#region GetDecreaseStartDate
/// <summary>
/// Decreases the timeline StartDate
/// </summary>
/// <param name="n">Amount to del</param>
private DateTime GetDecreaseStartDate(int n)
{
if (_CalendarView.TimeLineCanExtendRange == true)
{
try
{
return (_CalendarView.TimeLineViewStartDate.AddMinutes(
-_CalendarView.BaseInterval * n));
}
catch
{
return (new DateTime(1, 1, 1));
}
}
return (_CalendarView.TimeLineViewStartDate);
}
#endregion
#region GetIntervalStartDate
private DateTime GetIntervalStartDate(DateTime startDate)
{
TimeSpan ts = new TimeSpan(startDate.Hour, startDate.Minute, 0);
int interval = _CalendarView.TimeLineInterval;
int minutes = ((int)ts.TotalMinutes / interval) * interval;
return (startDate.Date.AddMinutes(minutes));
}
#endregion
#endregion
#region Begin/EndUpdate
/// <summary>
/// Begins Update block
/// </summary>
public void BeginUpdate()
{
_UpdateCount++;
}
/// <summary>
/// Ends update block
/// </summary>
public void EndUpdate()
{
if (_UpdateCount == 0)
{
throw new InvalidOperationException(
"EndUpdate must be called After BeginUpdate");
}
_UpdateCount--;
if (_UpdateCount == 0)
OnScrollPanelUpdate();
}
#endregion
#region SetUpPanel
/// <summary>
/// Performs panel setup
/// </summary>
private void SetUpPanel()
{
Control c = (Control)_CalendarView.CalendarPanel.GetContainerControl(true);
if (c != null)
{
SetupPageNavigator(c);
SetupScrollBar(c);
UpdatePanel();
}
}
#endregion
#region SetupPageNavigator
/// <summary>
/// Sets-up the PageNavigator
/// </summary>
/// <param name="c"></param>
private void SetupPageNavigator(Control c)
{
_PageNavigator = new PageNavigator();
_PageNavigator.Visible = false;
_PageNavigator.FocusCuesEnabled = false;
HookNavigateEvents(true);
c.Controls.Add(_PageNavigator);
_PageNavigator.NextPageTooltip = _CalendarView.TimeLinePageNavigatorNextPageTooltip;
_PageNavigator.PreviousPageTooltip = _CalendarView.TimeLinePageNavigatorPreviousPageTooltip;
_PageNavigator.TodayTooltip = _CalendarView.TimeLinePageNavigatorTodayTooltip;
}
#endregion
#region SetupScrollBar
private void SetupScrollBar(Control c)
{
_ScrollBar = new HScrollBarAdv();
_ScrollBar.Visible = false;
_ScrollBar.Height = SystemInformation.HorizontalScrollBarHeight;
HookScrollEvents(true);
c.Controls.Add(_ScrollBar);
}
#endregion
#region UpdatePanel
/// <summary>
/// Updates the panel
/// </summary>
public void UpdatePanel()
{
if (Bounds.Width > 0)
{
UpdatePageNavigator();
UpdateScrollBar();
OnScrollPanelUpdate();
}
}
#endregion
#region UpdatePageNavigator
/// <summary>
/// Updates the PageNavigator
/// </summary>
private void UpdatePageNavigator()
{
if (_CalendarView.TimeLineShowPageNavigation == true)
{
// We are to show the PageNavigator, so allocate it
// if we haven't done so already
if (_PageNavigator == null)
{
Control c = (Control)_CalendarView.CalendarPanel.GetContainerControl(true);
if (c != null)
{
SetupPageNavigator(c);
if (_PageNavigator != null)
_PageNavigator.Visible = Visible;
}
}
}
else
{
// We are not to show a PageNavigator, so if we have already
// allocated one, see that we release it appropriately
if (_PageNavigator != null)
{
Control c = (Control)_CalendarView.CalendarPanel.GetContainerControl(true);
if (c != null)
{
c.Controls.Remove(_PageNavigator);
HookNavigateEvents(false);
_PageNavigator = null;
}
}
}
}
#endregion
#region UpdateScrollBar
/// <summary>
/// Updates our ScrollBar
/// </summary>
private void UpdateScrollBar()
{
_ScrollBar.Maximum = ScrollPanelMaximum;
_ScrollBar.SmallChange = ScrollPanelSmallChange;
_ScrollBar.LargeChange = ScrollPanelLargeChange;
if (_ScrollBar.Value > _ScrollBar.Maximum - _ScrollBar.LargeChange)
_ScrollBar.Value = _ScrollBar.Maximum - _ScrollBar.LargeChange;
_ScrollBar.Refresh();
}
#endregion
#region OnScrollPanelUpdate
/// <summary>
/// Passes the scroll onto others
/// </summary>
protected void OnScrollPanelUpdate()
{
if (_UpdateCount == 0)
{
if (ScrollPanelChanged != null)
ScrollPanelChanged(this, EventArgs.Empty);
}
}
#endregion
#region RecalcSize
/// <summary>
/// Performs control recalc
/// </summary>
public override void RecalcSize()
{
// Update our PageNavigator
UpdatePageNavigator();
int navWidth = 0;
if (_PageNavigator != null)
{
navWidth = _PageNavigator.Width;
_PageNavigator.Location =
new Point(Bounds.Right - navWidth, Bounds.Y);
}
// Update our ScrollBar
UpdateScrollBar();
if (_ScrollBar != null)
{
_ScrollBar.Location = Bounds.Location;
_ScrollBar.Width = Bounds.Width - navWidth;
}
base.RecalcSize();
}
#endregion
#region Paint
public override void Paint(ItemPaintArgs p)
{
}
#endregion
#region Copy
/// <summary>
/// Returns copy of the item
/// </summary>
public override BaseItem Copy()
{
TimeLineHScrollPanel objCopy = new TimeLineHScrollPanel(_CalendarView);
this.CopyToItem(objCopy);
return (objCopy);
}
/// <summary>
/// Copies the TimeLineHScrollPanel specific properties to
/// new instance of the item
/// </summary>
/// <param name="copy">New PageNavigatorItem instance</param>
protected override void CopyToItem(BaseItem copy)
{
TimeLineHScrollPanel c = copy as TimeLineHScrollPanel;
base.CopyToItem(c);
}
#endregion
#region Dispose
protected override void Dispose(bool disposing)
{
if (disposing == true && IsDisposed == false)
{
HookScrollEvents(false);
HookNavigateEvents(false);
}
base.Dispose(disposing);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,40 @@
#if FRAMEWORK20
namespace DevComponents.DotNetBar.Schedule
{
public class TimeLineVScrollPanel : VScrollPanel
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="calendarView"></param>
public TimeLineVScrollPanel(CalendarView calendarView)
: base(calendarView)
{
}
#region Private properties
/// <summary>
/// Gets the ScrollBar SmallChange value
/// </summary>
protected override int ScrollPanelSmallChange
{
get { return (CalendarView.TimeLineHeight); }
}
/// <summary>
/// Gets the ScrollBar Maximum value
/// </summary>
protected override int ScrollPanelMaximum
{
get
{
return (CalendarView.TimeLineHeight *
CalendarView.DisplayedOwners.Count);
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,237 @@
#if FRAMEWORK20
using System;
using System.Drawing;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Schedule
{
public class VScrollPanel : BaseItem
{
#region Events
public event EventHandler<EventArgs> ScrollBarChanged;
#endregion
#region Variables
protected CalendarView CalendarView; // CalendarView
private VScrollBarAdv _ScrollBar; // Scroll bar
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="calendarView"></param>
public VScrollPanel(CalendarView calendarView)
{
CalendarView = calendarView;
SetUpScrollBar();
}
#region Public properties
/// <summary>
/// Gets and sets the panel Bounds
/// </summary>
public override Rectangle Bounds
{
get { return (base.Bounds); }
set
{
base.Bounds = value;
UpdateScrollBar();
}
}
/// <summary>
/// Gets and sets the control visibility
/// </summary>
public override bool Visible
{
get { return (base.Visible); }
set
{
if (base.Visible != value)
{
base.Visible = value;
ScrollBar.Visible = value;
if (value == true)
ScrollBar.BringToFront();
}
}
}
/// <summary>
/// Gets the scrollBar
/// </summary>
public VScrollBarAdv ScrollBar
{
get { return (_ScrollBar); }
}
#endregion
#region Private properties
/// <summary>
/// Gets the scrollBar SmallChange value
/// </summary>
protected virtual int ScrollPanelSmallChange
{
get { return (1); }
}
/// <summary>
/// Gets the scrollBar Maximum value
/// </summary>
protected virtual int ScrollPanelMaximum
{
get { return (100); }
}
#endregion
#region SetupScrollBar
/// <summary>
/// Performs scrollBar setup
/// </summary>
private void SetUpScrollBar()
{
_ScrollBar = new VScrollBarAdv();
Control c = (Control)CalendarView.CalendarPanel.GetContainerControl(true);
if (c != null)
c.Controls.Add(_ScrollBar);
_ScrollBar.ValueChanged += ValueChanged;
UpdateScrollBar();
}
#endregion
#region UpdateScrollBar
/// <summary>
/// Updates our scrollbar
/// </summary>
internal void UpdateScrollBar()
{
_ScrollBar.Location = Bounds.Location;
_ScrollBar.Height = Bounds.Height;
_ScrollBar.Width = Bounds.Width;
_ScrollBar.LargeChange = Bounds.Height;
_ScrollBar.SmallChange = 1;
_ScrollBar.SmallChange = ScrollPanelSmallChange;
_ScrollBar.Maximum = ScrollPanelMaximum;
int n = _ScrollBar.Maximum - _ScrollBar.LargeChange + 1;
if (n < 0)
{
_ScrollBar.Maximum = Bounds.Height;
_ScrollBar.Value = 0;
_ScrollBar.Enabled = false;
}
else
{
_ScrollBar.Enabled = true;
if (_ScrollBar.Value > n)
_ScrollBar.Value = n;
else
Refresh();
}
OnScrollBarUpdate();
}
#endregion
#region DisableScrollBar
/// <summary>
/// Disables the scrollbar
/// </summary>
internal void DisableScrollBar()
{
_ScrollBar.Location = Bounds.Location;
_ScrollBar.Height = Bounds.Height;
_ScrollBar.LargeChange = Bounds.Height;
_ScrollBar.SmallChange = 1;
_ScrollBar.SmallChange = ScrollPanelSmallChange;
_ScrollBar.Maximum = Bounds.Height;
_ScrollBar.Value = 0;
_ScrollBar.Enabled = false;
OnScrollBarUpdate();
}
#endregion
#region ValueChanged
/// <param name="sender">object</param>
/// <param name="e">EventArgs</param>
void ValueChanged(object sender, EventArgs e)
{
OnScrollBarUpdate();
}
/// <summary>
/// Passes the scroll onto others
/// </summary>
private void OnScrollBarUpdate()
{
if (ScrollBarChanged != null)
ScrollBarChanged(this, EventArgs.Empty);
}
#endregion
#region IDisposable Members
protected override void Dispose(bool disposing)
{
if (_ScrollBar != null)
{
_ScrollBar.ValueChanged -= ValueChanged;
_ScrollBar.Dispose();
}
base.Dispose(disposing);
}
#endregion
#region Paint
public override void Paint(ItemPaintArgs p)
{
}
#endregion
#region Copy
public override BaseItem Copy()
{
return (null);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,613 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Schedule
{
public class AllDayPanel : BaseItem
{
#region Private variables
private WeekDayView _WeekDayView; // Assoc WeekDayView
private List<CalendarItem> // CalendarItems list
_CalendarItems = new List<CalendarItem>();
private VScrollBarAdv _VScrollBar; // Vertical scroll bar
private int _VScrollPos; // Vertical scrollbar pos
private int _PanelHeight; // Panel height (current)
private int _MaximumPanelHeight; // Panel height (max)
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="weekDayView">WeekDayView</param>
public AllDayPanel(WeekDayView weekDayView)
{
// Save the provided weekDayView and
// tell the system we are a container
_WeekDayView = weekDayView;
SetIsContainer(true);
SubItems.AllowParentRemove = false;
}
#region Public properties
/// <summary>
/// Gets and sets the panel bounding rectangle
/// </summary>
public override Rectangle Bounds
{
get { return (base.Bounds); }
set
{
base.Bounds = value;
UpdateVScrollBar();
}
}
/// <summary>
/// Gets the DayPanel Height
/// </summary>
public int PanelHeight
{
get { return (_PanelHeight); }
}
/// <summary>
/// Gets the panel's CalendarItem list
/// </summary>
public List<CalendarItem> CalendarItems
{
get { return (_CalendarItems); }
}
/// <summary>
/// Gets WeekDayView
/// </summary>
public WeekDayView WeekDayView
{
get { return (_WeekDayView); }
}
#endregion
#region Private properties
/// <summary>
/// gets the Fixed AllDayPanel height
/// </summary>
private int FixedAllDayPanelHeight
{
get { return (_WeekDayView.CalendarView.FixedAllDayPanelHeight); }
}
/// <summary>
/// gets the Maximum AllDayPanel height
/// </summary>
private int MaximumAllDayPanelHeight
{
get { return (_WeekDayView.CalendarView.MaximumAllDayPanelHeight); }
}
/// <summary>
/// Gets the Appointment height
/// </summary>
private int AppointmentPadding
{
get { return (6); }
}
/// <summary>
/// Gets the width of a vertical scrollbar
/// </summary>
private int VsWidth
{
get { return (SystemInformation.VerticalScrollBarWidth); }
}
#endregion
#region RecalcSize
/// <summary>
/// Performs panel recalc support
/// </summary>
public override void RecalcSize()
{
// Reset our panel heights
_PanelHeight = 0;
_MaximumPanelHeight = 0;
if (_CalendarItems.Count > 0)
{
// Sort the items
List<CalendarItem> items = SortCalendarItems();
// Go through our CalendarItems on a per column basis
// accumulating extended appointment data
ulong[] acc = new ulong[DaysInWeek];
int maxAcc = -1;
for (int i = 0; i < items.Count; i++)
{
int freeAcc = CalcAppointmentBounds(items[i], acc);
if (freeAcc > maxAcc)
maxAcc = freeAcc;
}
// Determine our current panel height from our processed data
if (_WeekDayView.CalendarView.IsMultiCalendar == false)
{
_MaximumPanelHeight = (maxAcc + 1) * _WeekDayView.AppointmentHeight;
// Set out current and maximum panel heights
_MaximumPanelHeight += AppointmentPadding;
_PanelHeight = _MaximumPanelHeight;
if (_PanelHeight > MaximumAllDayPanelHeight)
_PanelHeight = MaximumAllDayPanelHeight;
}
}
// Take into account the FixedAllDayPanelHeight setting
if (_WeekDayView.CalendarView.IsMultiCalendar == true)
{
_PanelHeight = (FixedAllDayPanelHeight >= 0) ? FixedAllDayPanelHeight : 50;
_MaximumPanelHeight = _PanelHeight;
}
else if (FixedAllDayPanelHeight >= 0)
{
_PanelHeight = FixedAllDayPanelHeight;
}
HeightInternal = _PanelHeight;
base.RecalcSize();
}
#region SortCalendarItems
/// <summary>
/// Sorts the CalendarItems
/// </summary>
private List<CalendarItem> SortCalendarItems()
{
List<CalendarItem> items =
new List<CalendarItem>(_CalendarItems.Count);
items.AddRange(_CalendarItems);
items.Sort(
delegate(CalendarItem c1, CalendarItem c2)
{
if (c1.StartTime > c2.StartTime)
return (1);
if (c1.StartTime < c2.StartTime)
return (-1);
if (c1.EndTime > c2.EndTime)
return (-1);
if (c1.EndTime < c2.EndTime)
return (1);
return (0);
}
);
return (items);
}
#endregion
#region CalcAppointmentBounds
const int DaysInWeek = 7;
/// <summary>
/// Calculates the display bounds for the AppointmentView
/// </summary>
/// <param name="item">CalendarItem</param>
/// <param name="acc">Row accumulator</param>
private int CalcAppointmentBounds(CalendarItem item, ulong[] acc)
{
// Determine the starting day index for
// the given appointment
int ns = GetDayIndex(item);
// Calculate the top and height for the item
Rectangle r = _WeekDayView.DayColumns[ns].Bounds;
r.Width = 0;
r.Y = _WeekDayView.ClientRect.Y + _WeekDayView.DayOfWeekHeaderHeight + _VScrollPos + 2;
r.Height = _WeekDayView.AppointmentHeight;
int maxAcc = -1;
// Determine the ending day index
DateTime st = _WeekDayView.DayColumns[ns].Date;
int ne = ns + (item.EndTime - st).Days;
if (item.EndTime.Hour > 0 || item.EndTime.Minute > 0 || item.EndTime.Second > 0)
ne++;
if (ne > DaysInWeek)
ne = DaysInWeek;
int freeAcc = GetFreeAcc(ns, ne, acc);
if (freeAcc >= 0)
{
ulong u = (1ul << freeAcc);
for (int i = ns; i < ne; i++)
{
if (i < _WeekDayView.NumberOfColumns)
r.Width += _WeekDayView.DayColumns[i].Bounds.Width;
acc[i] |= u;
}
r.Y += (freeAcc * _WeekDayView.AppointmentHeight);
if (freeAcc > maxAcc)
maxAcc = freeAcc;
}
else
{
r.Y = _WeekDayView.DayColumns[0].Bounds.Bottom;
}
DateTime start = _WeekDayView.DayColumns[0].Date;
DateTime end = _WeekDayView.DayColumns[_WeekDayView.DayColumns.Length - 1].Date;
// Check to see if we can only display
// a partial representation for the view
if (item.EndTime >= start && item.StartTime < end)
{
int hpad = 4;
if (item.StartTime >= start)
{
r.X += hpad;
r.Width -= hpad;
}
if (item.EndTime <= end)
r.Width -= hpad;
}
// Now that we have calculated the items height and
// width, invoke a Recalc on the item
item.WidthInternal = r.Width;
item.HeightInternal = r.Height - 1;
item.RecalcSize();
// Set our bounds for the item
r.Width = item.WidthInternal;
r.Height = item.HeightInternal;
item.Bounds = r;
// Set it's display state
item.Displayed = true;
return (maxAcc);
}
#region GetFreeAcc
private int GetFreeAcc(int ns, int ne, ulong[] acc)
{
for (int i = 0; i < sizeof(ulong) * 8; i++)
{
if (CheckFreeAcc(ns, ne, acc, i) == true)
return (i);
}
return (-1);
}
#region CheckFreeAcc
private bool CheckFreeAcc(int ns, int ne, ulong[] acc, int n)
{
for (int i = ns; i < ne; i++)
{
ulong u = acc[i];
if ((u & (1ul << n)) != 0)
return (false);
}
return (true);
}
#endregion
#endregion
#region GetDayIndex
/// <summary>
/// Gets the starting day index for the given appointment
/// </summary>
/// <returns>Day of week index (0-6)</returns>
private int GetDayIndex(CalendarItem item)
{
DateTime date = _WeekDayView.DayColumns[0].Date;
for (int i = 0; i < _WeekDayView.DayColumns.Length; i++)
{
date = date.AddDays(1);
if (date > item.StartTime)
return (i);
}
return (0);
}
#endregion
#endregion
#endregion
#region Scrollbar routines
#region UpdateVScrollBar
/// <summary>
/// Updates our vertical scrollbar
/// </summary>
private void UpdateVScrollBar()
{
if (_PanelHeight > 0 && _PanelHeight < _MaximumPanelHeight)
{
// If we don't have one already, allocate it
if (_VScrollBar == null)
{
_VScrollBar = new VScrollBarAdv();
_VScrollBar.Width = VsWidth;
Control c = (Control)this.GetContainerControl(true);
if (c != null)
c.Controls.Add(_VScrollBar);
_VScrollBar.ValueChanged += _VExtScrollBar_ValueChanged;
}
// Initialize the scrollbar
_VScrollBar.Location = new Point(Bounds.Right + 1, Bounds.Y);
_VScrollBar.Height = _PanelHeight;
_VScrollBar.SmallChange = _PanelHeight / 2;
_VScrollBar.LargeChange = _WeekDayView.AppointmentHeight * 2;
_VScrollBar.Maximum = _MaximumPanelHeight -
_VScrollBar.Height + _VScrollBar.LargeChange;
if (_VScrollBar.Visible == false)
{
_VScrollPos = 0;
_VScrollBar.Value = 0;
_VScrollBar.Show();
_VScrollBar.BringToFront();
}
else
{
if (_VScrollBar.Value > _VScrollBar.Maximum - _VScrollBar.LargeChange)
_VScrollBar.Value = _VScrollBar.Maximum - _VScrollBar.LargeChange;
}
_VScrollBar.Refresh();
}
else if (_VScrollBar != null)
{
_VScrollPos = 0;
_VScrollBar.ValueChanged -= _VExtScrollBar_ValueChanged;
_VScrollBar.Dispose();
_VScrollBar = null;
}
}
#endregion
#region _VExtScrollBar_ValueChanged
/// <summary>
/// Processes Extended appointments scrollBar changes
/// </summary>
/// <param name="sender">object</param>
/// <param name="e">EventArgs</param>
void _VExtScrollBar_ValueChanged(object sender, EventArgs e)
{
int vdelta = -_VScrollBar.Value - _VScrollPos;
if (vdelta != 0)
{
_VScrollPos = -_VScrollBar.Value;
// Now that we have calculated the items height and
// width, invoke a Recalc on the item
for (int i = 0; i < _CalendarItems.Count; i++)
{
CalendarItem item = _CalendarItems[i];
Rectangle r = item.Bounds;
r.Y += vdelta;
item.Bounds = r;
}
Refresh();
}
}
#endregion
#endregion
#region Reset / update view
/// <summary>
/// Resets the AllDayPanel view
/// </summary>
public void ResetView()
{
_VScrollPos = 0;
if (_VScrollBar != null)
{
_VScrollBar.ValueChanged -= _VExtScrollBar_ValueChanged;
_VScrollBar.Dispose();
_VScrollBar = null;
}
}
/// <summary>
/// Updates the AllDayPanel view
/// </summary>
public void UpdateView()
{
if (_WeekDayView.IsViewSelected == true)
{
if (_VScrollBar != null)
_VScrollBar.Show();
}
else
{
if (_VScrollBar != null)
_VScrollBar.Hide();
}
}
#endregion
#region Paint processing
/// <summary>
/// Draws extended appointments
/// </summary>
/// <param name="e">ItemPaintArgs</param>
public override void Paint(ItemPaintArgs e)
{
Graphics g = e.Graphics;
if (e.ClipRectangle.IntersectsWith(Bounds))
{
Region regSave = g.Clip;
g.SetClip(Bounds, CombineMode.Intersect);
using (Brush br =
_WeekDayView.WeekDayColor.BrushPart(
(int) eCalendarWeekDayPart.DayAllDayEventBackground, Bounds))
{
g.FillRectangle(br, Bounds);
}
using (Pen pen = new Pen(
_WeekDayView.WeekDayColor.GetColor((int) eCalendarWeekDayPart.DayViewBorder)))
{
g.DrawLine(pen, Bounds.X, Bounds.Y, Bounds.X, Bounds.Bottom);
g.DrawLine(pen, Bounds.Right - 1, Bounds.Y, Bounds.Right - 1, Bounds.Bottom);
}
// Loop through each day in each week, displaying
// the associated day content
int selItem = -1;
for (int i = 0; i < _CalendarItems.Count; i++)
{
// Initiate the paint
if (_CalendarItems[i].Displayed == true)
{
if (_CalendarItems[i].IsSelected == true)
selItem = i;
else
_CalendarItems[i].Paint(e);
}
}
if (selItem >= 0)
_CalendarItems[selItem].Paint(e);
// Restore the original clip region
g.Clip = regSave;
}
}
#endregion
#region Copy implementation
/// <summary>
/// Returns copy of the item.
/// </summary>
public override BaseItem Copy()
{
AllDayPanel objCopy = new AllDayPanel(WeekDayView);
CopyToItem(objCopy);
return (objCopy);
}
/// <summary>
/// Copies the AllDayPanel specific properties to new instance of the item.
/// </summary>
/// <param name="copy">New AllDayPanel instance</param>
protected override void CopyToItem(BaseItem copy)
{
AllDayPanel objCopy = copy as AllDayPanel;
base.CopyToItem(objCopy);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,319 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
public class ColumnList
{
#region Private variables
private List<List<SlotItem>> _SList = new List<List<SlotItem>>();
private int _Id;
#endregion
public ColumnList()
{
}
public ColumnList(int id)
{
_Id = id;
}
#region Public properties
/// <summary>
/// Gets the column slot Id
/// </summary>
public int Id
{
get { return (_Id); }
set { _Id = value; }
}
/// <summary>
/// Gets the column slot list
/// </summary>
public List<List<SlotItem>> SList
{
get { return (_SList); }
}
#endregion
#region Public methods
#region AddColumnSlot
/// <summary>
/// Adds a CalendarItem to the running slot list
/// </summary>
/// <param name="item">CalendarItem to add</param>
/// <param name="n">Slot level to add the item to</param>
/// <returns>The added slot item</returns>
public SlotItem AddColumnSlot(CalendarItem item, int n)
{
// Add a new SlotItem list if we have exceeded
// the current list count
if (n >= _SList.Count)
_SList.Add(new List<SlotItem>());
// Determine whether this item can fit in the
// the slot list at the current level
SlotItem si = GetColumnSlot(item, n);
if (si != null)
{
// The item won't fit, so allocate a new slot
// item and add it to the list
si.AddPeerSlot(
AddColumnSlot(item, n + 1), n + 1);
}
else
{
// The item will fit, so add it to the list
si = new SlotItem(item);
_SList[n].Add(si);
// Look ahead to see it we have a peer slot
// in a future slot list
while (n + 1 < _SList.Count)
{
n++;
SlotItem ni = GetColumnSlot(item, n);
if (ni != null)
{
si.AddPeerSlot(ni, n);
break;
}
}
}
// Return the added slot item
return (si);
}
/// <summary>
/// Returns the SlotItem (if present) in the given list for
/// the CalendarItem in question
/// </summary>
/// <param name="item">CalendarItem</param>
/// <param name="n">Slot level to scan</param>
/// <returns>SlotItem, if found</returns>
private SlotItem GetColumnSlot(CalendarItem item, int n)
{
if (n < _SList.Count)
{
// Loop through each SlotItem at the given
// level, looking for an intersection with the
// given CalendarItem
List<SlotItem> list = _SList[n];
for (int i = 0; i < list.Count; i++)
{
SlotItem si = list[i];
DateTime start = item.StartTime > si.CItem.StartTime ? item.StartTime : si.CItem.StartTime;
DateTime end = item.EndTime < si.CItem.EndTime ? item.EndTime : si.CItem.EndTime;
// If we found an item, return it
if ((start < end) ||
(start <= end && ( item.StartTime == item.EndTime || si.CItem.StartTime == si.CItem.EndTime)))
return (si);
}
}
// Nothing currently at that slot
return (null);
}
#endregion
#region CountColumns
/// <summary>
/// Counts the number of columns for
/// each column zero entry slot lists
/// </summary>
public void CountColumns()
{
if (_SList.Count > 0)
{
for (int i = 0; i < _SList[0].Count; i++)
{
SlotItem si = _SList[0][i];
SetColumnCount(si, GetColumnCount(si, 1));
}
}
}
/// <summary>
/// Gets the max column count from all
/// zero level slot paths
/// </summary>
/// <param name="si">Initial SlotItem</param>
/// <param name="count">Running level count</param>
/// <returns></returns>
private int GetColumnCount(SlotItem si, int count)
{
if (si.Count > 0)
return (si.Count);
int maxCount = count;
if (si.SList != null)
{
for (int i = 0; i < si.SList.Count; i++)
{
int c = GetColumnCount(si.SList[i], count + 1);
if (c > maxCount)
maxCount = c;
}
}
return (maxCount);
}
/// <summary>
/// Sets all column entry counts to the given
/// count
/// </summary>
/// <param name="si">Initial SlotItem</param>
/// <param name="count">Count</param>
private void SetColumnCount(SlotItem si, int count)
{
if (si.SList != null)
{
for (int i = 0; i < si.SList.Count; i++)
SetColumnCount(si.SList[i], count);
}
if (si.Count == 0)
si.Count = count;
}
#endregion
#region Clear
/// <summary>
/// Clears the Column slot list
/// </summary>
public void Clear()
{
_SList.Clear();
}
#endregion
#endregion
}
#region SlotItem class definition
public class SlotItem
{
#region Private variables
private CalendarItem _CItem; // CalendarItem
private List<SlotItem> _SList; // List of peer SlotItems
private int _Count; // Count of peer items
private int _Column;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="cItem">CalendarItem</param>
public SlotItem(CalendarItem cItem)
{
_CItem = cItem;
}
#region Public properties
/// <summary>
/// Gets and sets the slots CalendarItem
/// </summary>
public CalendarItem CItem
{
get { return (_CItem); }
set { _CItem = value; }
}
/// <summary>
/// Gets the peer SlotItem list
/// </summary>
public List<SlotItem> SList
{
get { return (_SList); }
}
/// <summary>
/// Gets and sets the peer level count
/// </summary>
public int Count
{
get { return (_Count); }
set { _Count = value; }
}
/// <summary>
/// Gets and sets the peer column
/// </summary>
public int Column
{
get { return (_Column); }
set { _Column = value; }
}
#endregion
#region Public methods
/// <summary>
/// Adds a slot to the peer SlotItem list
/// </summary>
/// <param name="si">SlotItem to add</param>
/// <param name="column">Slot column</param>
public void AddPeerSlot(SlotItem si, int column)
{
if (si != null)
{
if (_SList == null)
_SList = new List<SlotItem>();
if (_SList.Contains(si) == false)
{
si.Column = column;
_SList.Add(si);
}
}
}
#endregion
}
#endregion
}
#endif

View File

@@ -0,0 +1,212 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Drawing;
using DevComponents.Schedule.Model;
namespace DevComponents.DotNetBar.Schedule
{
public class DayColumn
{
#region Consts
public const int NumberOfTimeSlices = 48;
#endregion
#region Private variables
private Rectangle _Bounds; // Slot bounding rectangle
private DateTime _Date; // Column date
private float _TimeSliceHeight; // TimeSlice height
private WorkTime _BusyStartTime; // Busy time
private WorkTime _BusyEndTime;
private WorkTime _WorkStartTime; // Work time
private WorkTime _WorkEndTime;
private List<CalendarItem> // Column CalendarItems
_CalendarItems = new List<CalendarItem>();
private bool _NeedRecalcLayout = true;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="timeSliceHeight">Slice height</param>
public DayColumn(float timeSliceHeight)
{
_TimeSliceHeight = timeSliceHeight;
}
#region Public properties
#region BoundingRect
/// <summary>
/// Gets and sets the week bounding Rectangle
/// </summary>
public Rectangle Bounds
{
get { return (_Bounds); }
set
{
if (_Bounds.Equals(value) == false)
{
int yOffset = value.Y - _Bounds.Y;
_Bounds = value;
if (yOffset != 0)
OffsetItemRects(yOffset);
}
}
}
/// <summary>
/// Offsets the bounding rectangles for the
/// DayColumn's non-extended appointments
/// </summary>
/// <param name="yOffset">Amount to offset</param>
private void OffsetItemRects(int yOffset)
{
for (int i = 0; i < _CalendarItems.Count; i++)
{
Rectangle r = _CalendarItems[i].Bounds;
r.Y += yOffset;
_CalendarItems[i].Bounds = r;
}
}
#endregion
#region Date
/// <summary>
/// Gets and sets the column date
/// </summary>
public DateTime Date
{
get { return (_Date); }
set { _Date = value; }
}
#endregion
#region TimeSliceHeight
/// <summary>
/// Gets and sets the TimeSlice height
/// </summary>
public float TimeSliceHeight
{
get { return (_TimeSliceHeight); }
set { _TimeSliceHeight = value; }
}
#endregion
#region WorkTime properties
/// <summary>
/// Gets and sets the busy time start
/// </summary>
public WorkTime BusyStartTime
{
get { return (_BusyStartTime); }
set { _BusyStartTime = value; }
}
/// <summary>
/// Gets and sets the busy time end
/// </summary>
public WorkTime BusyEndTime
{
get { return (_BusyEndTime); }
set { _BusyEndTime = value; }
}
/// <summary>
/// Gets and sets the work time start
/// </summary>
public WorkTime WorkStartTime
{
get { return (_WorkStartTime); }
set { _WorkStartTime = value; }
}
/// <summary>
/// Gets and sets the work time end
/// </summary>
public WorkTime WorkEndTime
{
get { return (_WorkEndTime); }
set { _WorkEndTime = value; }
}
#endregion
#region CalendarItems
/// <summary>
/// Gets the column CalendarItems list
/// </summary>
public List<CalendarItem> CalendarItems
{
get { return (_CalendarItems); }
}
#endregion
#region NeedRecalcLayout
public bool NeedRecalcLayout
{
get { return (_NeedRecalcLayout); }
set { _NeedRecalcLayout = value; }
}
#endregion
#endregion
#region Public methods
/// <summary>
/// Determines if the given time is tagged as a "Busy time"
/// </summary>
/// <param name="time">WorkTime to test</param>
/// <returns>true if specified "time" is a Busy time</returns>
public bool IsBusyTime(WorkTime time)
{
return ((!BusyStartTime.IsEmpty && !BusyEndTime.IsEmpty) &&
(time >= BusyStartTime && time < BusyEndTime));
}
/// <summary>
/// Determines if the given time is tagged as a "Work time"
/// </summary>
/// <param name="time">WorkTime to test</param>
/// <returns>true if specified "time" is a Work time</returns>
public bool IsWorkTime(WorkTime time)
{
if (WorkStartTime <= WorkEndTime)
return (time >= WorkStartTime && time < WorkEndTime);
return (time < WorkEndTime || time >= WorkStartTime);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,44 @@
#if FRAMEWORK20
using System;
namespace DevComponents.DotNetBar.Schedule
{
public class DayView : WeekDayView
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="calendarView"></param>
public DayView(CalendarView calendarView)
: base(calendarView, eCalendarView.Day)
{
}
#region RecalcSize support
/// <summary>
/// Normalizes the user specified start and end dates
/// </summary>
/// <param name="startDate">[out] Normalized start date</param>
/// <param name="endDate">[out] Normalized end date</param>
protected override void NormalizeDates(out DateTime startDate, out DateTime endDate)
{
startDate = this.StartDate;
// If both values are unset, then set them to
// today's date
if (startDate == DateTime.MinValue)
startDate = DateTime.Today.Date;
endDate = startDate;
DaysOfTheWeek = new DaysOfTheWeek(startDate.DayOfWeek, 1);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,986 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using DevComponents.Schedule.Model;
using System.ComponentModel;
namespace DevComponents.DotNetBar.Schedule
{
internal class ModelWeekDayViewConnector : ModelViewConnector
{
#region Private variables
private CalendarModel _Model; // The associated CalendarModel
private WeekDayView _View; // The associated WeekDayView
private bool _IsConnected; // Connection status
private uint _RefreshCount;
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="model">Assoc CalendarModel</param>
/// <param name="weekDayView">Assoc WeekDayView</param>
public ModelWeekDayViewConnector(CalendarModel model, WeekDayView weekDayView)
{
_Model = model;
_View = weekDayView;
}
#region Public properties
/// <summary>
/// Gets the connection status
/// </summary>
public override bool IsConnected
{
get { return (_IsConnected); }
}
#endregion
#region Connect processing
/// <summary>
/// Performs Model connection processing
/// </summary>
public override void Connect()
{
VerifyModel();
if (_IsConnected)
Disconnect();
LoadData();
// Get notification on Model property changes
_Model.PropertyChanged += ModelPropertyChanged;
_Model.SubPropertyChanged += ModelSubPropertyChanged;
_View.CalendarView.CustomItems.CollectionChanged +=
CustomItemsCollectionChanged;
_IsConnected = true;
}
#endregion
#region Disconnect processing
/// <summary>
/// Severs the Model/WeekDayView connection
/// </summary>
public override void Disconnect()
{
VerifyModel();
if (_IsConnected)
{
// Clear all AllDayPanel items
ClearAllDayPanelItems();
// Loop through each DayColumn, clearing each
// associated view connection
for (int i = 0; i < _View.DayColumns.Length; i++)
ClearWeekDayColumn(_View.DayColumns[i]);
_View.SubItems.Clear();
// Stop notification on Model property changes
_Model.PropertyChanged -= ModelPropertyChanged;
_Model.SubPropertyChanged -= ModelSubPropertyChanged;
_View.CalendarView.CustomItems.CollectionChanged -=
CustomItemsCollectionChanged;
_IsConnected = false;
OnSubItemsChanged();
}
}
#region ClearAllDayPanelItems
private void ClearAllDayPanelItems()
{
List<CalendarItem> items = _View.AllDayPanel.CalendarItems;
for (int i = items.Count - 1; i >= 0; i--)
{
AppointmentWeekDayView view = items[i] as AppointmentWeekDayView;
if (view != null)
{
view.IsSelectedChanged -= _View.ItemIsSelectedChanged;
view.Appointment = null;
view.IsSelected = false;
view.AllDayPanel = null;
}
items.RemoveAt(i);
}
_View.AllDayPanel.SubItems.Clear();
}
#endregion
#region ClearWeekDayColumn
/// <summary>
/// Clears individual DayColumn view connections
/// </summary>
/// <param name="dayColumn">DayColumn</param>
private void ClearWeekDayColumn(DayColumn dayColumn)
{
if (dayColumn.CalendarItems.Count > 0)
{
// Loop through each CalendarItem, resetting
// it's associated connection
for (int i = dayColumn.CalendarItems.Count - 1; i >= 0; i--)
{
AppointmentWeekDayView view =
dayColumn.CalendarItems[i] as AppointmentWeekDayView;
if (view != null)
{
view.IsSelectedChanged -= _View.ItemIsSelectedChanged;
view.Appointment = null;
view.IsSelected = false;
view.DayColumn = null;
}
dayColumn.CalendarItems.RemoveAt(i);
}
}
}
#endregion
#endregion
#region LoadData processing
/// <summary>
/// Loads Model/WeekDayView connection data
/// </summary>
private void LoadData()
{
DayColumn[] dcs = _View.DayColumns;
if (dcs.Length > 0)
{
_RefreshCount++;
DateTime startDate = dcs[0].Date;
DateTime endDate = DateTimeHelper.EndOfDay(dcs[dcs.Length - 1].Date);
DateTime appStartDate = startDate.AddMonths(-1);
List<Appointment> appts = GetAppointmentList(_Model, appStartDate, endDate);
for (int i = 0; i < dcs.Length; i++)
{
DayColumn dc = dcs[i];
UpdateColumnAppts(dc, appts);
UpdateCustomItems(dc);
}
UpdateAllDayPanelView(appts, startDate, endDate);
UpdateAllDayPanelCustomItems();
OnSubItemsChanged();
}
}
#region UpdateColumnAppts
private void UpdateColumnAppts(DayColumn dayColumn, List<Appointment> appointments)
{
foreach (Appointment app in appointments)
{
DateTime date = dayColumn.Date.Date;
if (date >= app.StartTime.Date && date <= app.EndTime.Date)
{
if (IsAppointmentVisible(app))
{
// Get the assoc view
if (_View.IsAllDayItem(app) == false)
{
AppointmentWeekDayView view = GetViewFromColumn(dayColumn, app, false) ??
GetViewFromAllDayPanel(app, true) ??
GetNewView(app);
if (view.StartTime != app.StartTime || view.EndTime != app.EndTime)
dayColumn.NeedRecalcLayout = true;
// Set the view start and end times to
// match the assoc appointment
view.StartTime = app.StartTime;
view.EndTime = app.EndTime;
view.RefreshCount = _RefreshCount;
// Update the DayColumn data
if (view.DayColumn == null)
{
view.DayColumn = dayColumn;
dayColumn.CalendarItems.Add(view);
dayColumn.NeedRecalcLayout = true;
_View.SubItems.Add(view);
_View.UpdateItemOrder(view);
}
}
}
}
}
// Update workDay details
UpdateWorkDayDetails(dayColumn);
}
#endregion
#region UpdateCustomItems
private void UpdateCustomItems(DayColumn dayColumn)
{
CustomCalendarItemCollection items = _View.CalendarView.CustomItems;
if (items != null)
{
for (int i = 0; i < items.Count; i++)
{
CustomCalendarItem item = items[i];
if (IsCustomItemVisible(item) == true && _View.IsAllDayItem(item) == false &&
(item.StartTime < dayColumn.Date.AddDays(1) && item.EndTime > dayColumn.Date))
{
item.CalendarView = _View.CalendarView;
CustomCalendarItem ci = GetItemFromColumn(dayColumn, item, false);
if (ci == null)
{
ci = GetItemFromAllDayPanel(item, true) ?? GetNewCustomItem(item);
dayColumn.CalendarItems.Add(ci);
dayColumn.NeedRecalcLayout = true;
_View.SubItems.Add(ci);
_View.UpdateItemOrder(ci);
}
ci.StartTime = item.StartTime;
ci.EndTime = item.EndTime;
ci.RefreshCount = _RefreshCount;
dayColumn.NeedRecalcLayout = true;
}
}
}
}
#endregion
#endregion
#region RefreshData processing
/// <summary>
/// Refreshes the data in a previously established
/// and loaded connection
/// </summary>
public void RefreshData()
{
CalendarItem selItem = _View.SelectedItem;
LoadData();
List<CalendarItem> removedViews = null;
foreach (DayColumn dc in _View.DayColumns)
RemoveOutdatedViews(dc, ref removedViews);
RemoveOutdatedAllDayViews(ref removedViews);
ProcessRemovedData(removedViews);
if (selItem != null)
{
selItem.IsSelected = false;
selItem.IsSelected = true;
}
}
#region RemoveOutdatedViews
private void RemoveOutdatedViews(
DayColumn dayColumn, ref List<CalendarItem> removedViews)
{
for (int i = dayColumn.CalendarItems.Count - 1; i >= 0; i--)
{
CalendarItem view = dayColumn.CalendarItems[i];
if (view != null)
{
if (view.RefreshCount != _RefreshCount)
{
if (removedViews == null)
removedViews = new List<CalendarItem>();
removedViews.Add(view);
_View.SubItems._Remove(view);
_View.NeedRecalcSize = true;
dayColumn.CalendarItems.Remove(view);
}
}
}
}
#endregion
#region RemoveOutdatedAllDayViews
private void RemoveOutdatedAllDayViews(ref List<CalendarItem> removedViews)
{
for (int i = _View.AllDayPanel.CalendarItems.Count - 1; i >= 0; i--)
{
CalendarItem view =
_View.AllDayPanel.CalendarItems[i] as CalendarItem;
if (view != null)
{
if (view.RefreshCount != _RefreshCount ||
_View.IsAllDayItem(view) == false)
{
if (removedViews == null)
removedViews = new List<CalendarItem>();
removedViews.Add(view);
_View.AllDayPanel.CalendarItems.RemoveAt(i);
_View.AllDayPanel.SubItems.Remove(view);
_View.NeedRecalcLayout = true;
}
}
}
}
#endregion
#region ProcessRemovedData
private void ProcessRemovedData(List<CalendarItem> removedViews)
{
if (removedViews != null && removedViews.Count > 0)
{
for (int i = 0; i < removedViews.Count; i++)
{
CalendarItem item = removedViews[i];
item.IsSelectedChanged -= _View.ItemIsSelectedChanged;
item.Dispose();
}
_View.NeedRecalcLayout = true;
}
}
#endregion
#endregion
#region UpdateAllDayPanelView
private void UpdateAllDayPanelView(
List<Appointment> appts, DateTime startDate, DateTime endDate)
{
// Loop through each appointment
// updating the assoc view accordingly
foreach (Appointment app in appts)
{
if (app.StartTime < endDate && app.EndTime > startDate)
{
if (IsAppointmentVisible(app))
{
// Get the assoc view
if (_View.IsAllDayItem(app) == true)
{
AppointmentWeekDayView view =
GetViewFromAllColumns(app, true) ??
GetViewFromAllDayPanel(app, false) ??
GetNewView(app);
// Set the view start and end times to
// match the assoc appointment
view.StartTime = app.StartTime;
view.EndTime = app.EndTime;
view.RefreshCount = _RefreshCount;
if (view.AllDayPanel == null)
{
view.AllDayPanel = _View.AllDayPanel;
_View.AllDayPanel.CalendarItems.Add(view);
_View.AllDayPanel.SubItems.Add(view);
_View.NeedRecalcLayout = true;
}
}
}
}
}
}
#endregion
#region UpdateAllDayPanelCustomItems
private void UpdateAllDayPanelCustomItems()
{
CustomCalendarItemCollection items = _View.CalendarView.CustomItems;
if (items != null)
{
DateTime startDate = _View.StartDate;
DateTime endDate = _View.EndDate.AddDays(1);
for (int i = 0; i < items.Count; i++)
{
CustomCalendarItem item = items[i];
if (IsCustomItemVisible(item) == true && _View.IsAllDayItem(item) == true &&
(item.StartTime < endDate && item.EndTime > startDate))
{
item.CalendarView = _View.CalendarView;
CustomCalendarItem ci = GetItemFromAllDayPanel(item, false);
if (ci == null)
{
ci = GetItemFromAllColumns(item, true);
if (ci == null)
ci = GetNewCustomItem(item);
_View.AllDayPanel.CalendarItems.Add(ci);
_View.NeedRecalcLayout = true;
_View.AllDayPanel.SubItems.Add(ci);
}
if (ci.StartTime != item.StartTime || ci.EndTime != item.EndTime)
{
ci.StartTime = item.StartTime;
ci.EndTime = item.EndTime;
_View.NeedRecalcLayout = true;
}
}
}
}
}
#endregion
#region UpdateWorkDayDetails
/// <summary>
/// Updates DayColumn workday details
/// </summary>
/// <param name="dayColumn">DayColumn to update</param>
private void UpdateWorkDayDetails(DayColumn dayColumn)
{
// Update workDay timings
Owner owner = _Model.Owners[_View.OwnerKey];
if (owner == null || GetCalendarWorkDays(dayColumn, owner.CalendarWorkDays) == false)
{
if (GetCalendarWorkDays(dayColumn, _Model.CalendarWorkDays) == false)
{
if (owner == null || GetWorkDays(dayColumn, owner.WorkDays) == false)
{
if (GetWorkDays(dayColumn, _Model.WorkDays) == false)
{
dayColumn.WorkStartTime = new WorkTime();
dayColumn.WorkEndTime = new WorkTime();
}
}
}
}
}
#region GetCalendarWorkDays
/// <summary>
/// GetCalendarWorkDays
/// </summary>
/// <param name="dayColumn"></param>
/// <param name="calendarWorkDays"></param>
/// <returns></returns>
private bool GetCalendarWorkDays(
DayColumn dayColumn, CalendarWorkDayCollection calendarWorkDays)
{
if (calendarWorkDays != null && calendarWorkDays.Count > 0)
{
CalendarWorkDay cwd = calendarWorkDays[dayColumn.Date];
if (cwd != null)
{
dayColumn.WorkStartTime = cwd.WorkStartTime;
dayColumn.WorkEndTime = cwd.WorkEndTime;
return (true);
}
}
return (false);
}
#endregion
#region GetWorkDays
/// <summary>
/// GetWorkDays
/// </summary>
/// <param name="dayColumn"></param>
/// <param name="workDays"></param>
/// <returns></returns>
private bool GetWorkDays(
DayColumn dayColumn, WorkDayCollection workDays)
{
if (workDays != null && workDays.Count > 0)
{
WorkDay wd = workDays[dayColumn.Date.DayOfWeek];
if (wd != null)
{
dayColumn.WorkStartTime = wd.WorkStartTime;
dayColumn.WorkEndTime = wd.WorkEndTime;
}
else
{
dayColumn.WorkStartTime = new WorkTime();
dayColumn.WorkEndTime = new WorkTime();
}
return (true);
}
return (false);
}
#endregion
#endregion
#region GetView routines
#region GetViewFromAll
private AppointmentWeekDayView
GetViewFromAll(Appointment app, bool remove)
{
AppointmentWeekDayView view = GetViewFromAllColumns(app, remove);
if (view != null)
return (view);
return (GetViewFromAllDayPanel(app, remove));
}
#endregion
#region GetViewFromAllColumns
private AppointmentWeekDayView
GetViewFromAllColumns(Appointment app, bool remove)
{
for (int i = 0; i < _View.NumberOfColumns; i++)
{
AppointmentWeekDayView view =
GetViewFromColumn(_View.DayColumns[i], app, remove);
if (view != null)
return (view);
}
return (null);
}
#endregion
#region GetViewFromColumn
private AppointmentWeekDayView
GetViewFromColumn(DayColumn dayColumn, Appointment appointment, bool remove)
{
foreach (CalendarItem item in dayColumn.CalendarItems)
{
AppointmentWeekDayView view = item as AppointmentWeekDayView;
if (view != null && view.Appointment == appointment)
{
if (remove == true)
{
dayColumn.CalendarItems.Remove(view);
_View.SubItems.Remove(view);
view.DayColumn = null;
}
return (view);
}
}
return (null);
}
#endregion
#region GetViewFromAllDayPanel
private AppointmentWeekDayView
GetViewFromAllDayPanel(Appointment appointment, bool remove)
{
foreach (CalendarItem item in _View.AllDayPanel.CalendarItems)
{
AppointmentWeekDayView view = item as AppointmentWeekDayView;
if (view != null && view.Appointment == appointment)
{
if (remove == true)
{
_View.AllDayPanel.CalendarItems.Remove(view);
_View.AllDayPanel.SubItems.Remove(view);
view.AllDayPanel = null;
}
return (view);
}
}
return (null);
}
#endregion
#endregion
#region GetItem routines
#region GetItemFromColumn
private CustomCalendarItem
GetItemFromColumn(DayColumn dayColumn, CustomCalendarItem item, bool remove)
{
foreach (CalendarItem citem in dayColumn.CalendarItems)
{
CustomCalendarItem view = citem as CustomCalendarItem;
if (view != null && (view == item || view.BaseCalendarItem == item))
{
if (remove == true)
dayColumn.CalendarItems.Remove(view);
return (view);
}
}
return (null);
}
#endregion
#region GetItemFromAllColumns
private CustomCalendarItem
GetItemFromAllColumns(CustomCalendarItem item, bool remove)
{
for (int i = 0; i < _View.NumberOfColumns; i++)
{
CustomCalendarItem view =
GetItemFromColumn(_View.DayColumns[i], item, false);
if (view != null)
return (view);
}
return (null);
}
#endregion
#region GetItemFromAllDayPanel
private CustomCalendarItem
GetItemFromAllDayPanel(CustomCalendarItem item, bool remove)
{
foreach (CalendarItem citem in _View.AllDayPanel.CalendarItems)
{
CustomCalendarItem view = citem as CustomCalendarItem;
if (view != null && (view == item || view.BaseCalendarItem == item))
{
if (remove == true)
_View.AllDayPanel.CalendarItems.Remove(view);
return (view);
}
}
return (null);
}
#endregion
#endregion
#region GetNewView
/// <summary>
/// Gets a new appointment view
/// </summary>
/// <param name="appointment">Appointment</param>
/// <returns>New view</returns>
private AppointmentWeekDayView GetNewView(Appointment appointment)
{
AppointmentWeekDayView view = new AppointmentWeekDayView(_View, appointment);
view.Tooltip = appointment.Tooltip;
view.IsSelectedChanged += _View.ItemIsSelectedChanged;
return (view);
}
#endregion
#region GetNewCustomItem
private CustomCalendarItem GetNewCustomItem(CustomCalendarItem item)
{
CustomCalendarItem ci = (CustomCalendarItem)item.Copy();
ci.BaseCalendarItem = item;
ci.IsSelectedChanged += _View.ItemIsSelectedChanged;
return (ci);
}
#endregion
#region View support routines
/// <summary>
/// Returns the view
/// </summary>
/// <returns></returns>
public override eCalendarView GetView()
{
return (eCalendarView.Week);
}
/// <summary>
/// Verifies the Model and MonthView are valid
/// </summary>
private void VerifyModel()
{
if (_Model == null)
throw new NullReferenceException("CalendarModel must be set on connector.");
if (_View == null)
throw new NullReferenceException("WeekDayCalendarView must be set on connector.");
}
#endregion
#region Model property change processing
/// <summary>
/// Handles Model property change notifications
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == CalendarModel.AppointmentsPropertyName)
{
RefreshData();
UpdateDisplay();
}
else if (e.PropertyName == CalendarModel.WorkDaysPropertyName)
{
for (int i = 0; i < _View.NumberOfColumns; i++)
UpdateWorkDayDetails(_View.DayColumns[i]);
_View.CalendarView.CalendarPanel.RecalcSize();
}
}
#endregion
#region ModelSubPropertyChanged
/// <summary>
/// Handles ModelSubProperty change notifications
/// </summary>
/// <param name="sender">object</param>
/// <param name="e">SubPropertyChangedEventArgs</param>
private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e)
{
if (e.Source is WorkDay)
{
for (int i = 0; i < _View.NumberOfColumns; i++)
UpdateWorkDayDetails(_View.DayColumns[i]);
_View.CalendarView.CalendarPanel.RecalcSize();
}
else if (e.Source is Owner)
{
Owner owner = (Owner) e.Source;
if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key))
{
if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName)
_View.DisplayName = owner.DisplayName;
else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme"))
_View.CalendarColor = owner.ColorScheme;
}
}
else if (e.Source is Appointment)
{
Appointment app = e.Source as Appointment;
AppointmentWeekDayView appView;
string name = e.PropertyChangedArgs.PropertyName;
if (name.Equals("Tooltip"))
{
appView = GetViewFromAll(app, false);
if (appView != null)
appView.Tooltip = app.Tooltip;
}
else if (name.Equals("IsSelected"))
{
appView = GetViewFromAll(app, false);
if (appView != null)
appView.IsSelected = app.IsSelected;
}
else if (name.Equals("CategoryColor") || name.Equals("TimeMarkedAs") || name.Equals("ImageKey"))
{
appView = GetViewFromAll(app, false);
if (appView != null)
appView.Refresh();
}
else if (name.Equals("OwnerKey"))
{
if (_View.CalendarView.IsMultiCalendar == true)
{
if (_View.OwnerKey == app.OwnerKey)
{
RefreshData();
UpdateDisplay();
}
else
{
appView = GetViewFromAll(app, false);
if (appView != null)
{
RefreshData();
UpdateDisplay();
}
}
}
}
else if (name.Equals("Visible"))
{
RefreshData();
UpdateDisplay();
}
}
}
#endregion
#region CustomItems_CollectionChanged
void CustomItemsCollectionChanged(object sender, EventArgs e)
{
RefreshData();
UpdateDisplay();
}
#endregion
#region UpdateDisplay
private void UpdateDisplay()
{
if (_View.Displayed == true)
{
if (_View.NeedRecalcLayout == false)
{
for (int i = 0; i < _View.NumberOfColumns; i++)
{
if (_View.DayColumns[i].NeedRecalcLayout)
{
_View.RecalcSize();
break;
}
}
}
}
}
#endregion
#region OnSubItemsChanged
private void OnSubItemsChanged()
{
System.Windows.Forms.Cursor.Position =
System.Windows.Forms.Cursor.Position;
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,59 @@
#if FRAMEWORK20
namespace DevComponents.DotNetBar.Schedule
{
partial class PosWin
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// PosWin
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.CausesValidation = false;
this.ClientSize = new System.Drawing.Size(1, 1);
this.ControlBox = false;
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Location = new System.Drawing.Point(1000, 1000);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "PosWin";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "PosWin";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.PosWin_Paint);
this.ResumeLayout(false);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,132 @@
#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Schedule
{
public partial class PosWin : Form
{
#region Private variables
private string _PosText = ""; // Window content
private int _PosHeight; // Calculated window height
#endregion
/// <summary>
/// Constructor
/// </summary>
public PosWin()
{
InitializeComponent();
}
#region CreateParams / show support
// This code permits us to be able to create a
// window with a drop shadow
private const int CS_DROPSHADOW = 0x00020000;
protected override CreateParams CreateParams
{
get
{
CreateParams parameters = base.CreateParams;
parameters.ClassStyle =
(parameters.ClassStyle | CS_DROPSHADOW);
return (parameters);
}
}
protected override bool ShowWithoutActivation
{
get { return true; }
}
#endregion
#region Public properties
/// <summary>
/// Gets and sets the window content text
/// </summary>
public string PosText
{
get { return (_PosText); }
set
{
if (_PosText != value)
{
_PosText = value;
this.Refresh();
}
}
}
/// <summary>
/// Gets the calculated window height
/// </summary>
public int PosHeight
{
get
{
if (_PosHeight <= 0)
{
using (Graphics g = CreateGraphics())
{
eTextFormat tf = eTextFormat.Default |
eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter;
Size sz = TextDrawing.MeasureString(g, "ABC", SystemFonts.CaptionFont, 0, tf);
_PosHeight = sz.Height + 4;
}
}
return (_PosHeight);
}
}
#endregion
#region Paint processing
private void PosWin_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
eTextFormat tf = eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter;
Size sz = TextDrawing.MeasureString(g, _PosText, SystemFonts.CaptionFont, 0, tf);
sz.Width += 6;
sz.Height += 4;
this.Size = sz;
int swidth = Screen.FromControl(this).Bounds.Width;
if (Location.X + sz.Width > swidth)
Location = new Point(swidth - sz.Width, Location.Y);
Rectangle r = new Rectangle(0, 0, sz.Width - 1, sz.Height - 1);
g.DrawRectangle(Pens.Black, r);
TextDrawing.DrawString(g, _PosText, SystemFonts.CaptionFont, Color.Black, r, tf);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,760 @@
#if FRAMEWORK20
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.DotNetBar.Schedule
{
public class TimeRulerPanel : BaseItem
{
#region Private Variables
private CalendarView _CalendarView; // Assoc CalendarView
private int _VScrollPos; // Vertical scroll position
private TimeRulerColor _ViewColor = // View display color table
new TimeRulerColor();
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="calendarView"></param>
public TimeRulerPanel(CalendarView calendarView)
{
_CalendarView = calendarView;
Name = "TimeRulerPanel";
HookEvents(true);
}
#region Private properties
#region General display properties
/// <summary>
/// Gets the TimeRuler font
/// </summary>
private Font TimeRulerFont
{
get { return (_CalendarView.TimeRulerFont); }
}
/// <summary>
/// Gets the TimeRuler font (small)
/// </summary>
private Font TimeRulerFontSm
{
get { return (_CalendarView.TimeRulerFontSm); }
}
#endregion
#region Time Slice Properties
/// <summary>
/// Gets the default Time Slice height
/// </summary>
private float TimeSliceHeight
{
get { return (_CalendarView.TimeSliceHeight); }
}
/// <summary>
/// Gets the TimeSlotDuration
/// </summary>
private int TimeSlotDuration
{
get { return (_CalendarView.TimeSlotDuration); }
}
/// <summary>
/// Gets the SlotsPerHour
/// </summary>
private int SlotsPerHour
{
get { return (_CalendarView.SlotsPerHour); }
}
/// <summary>
/// Gets the NumberOfSlices
/// </summary>
private int NumberOfSlices
{
get { return (_CalendarView.NumberOfSlices); }
}
/// <summary>
/// Gets the starting Time Slice
/// </summary>
private int StartSlice
{
get { return (_CalendarView.StartSlice); }
}
#endregion
#region AM / PM designators
/// <summary>
/// Gets the culturally correct AM time designator
/// </summary>
private string AmDesignator
{
get
{
return (ScheduleSettings.GetActiveCulture().
DateTimeFormat.AMDesignator.ToLower());
}
}
/// <summary>
/// Gets the culturally correct PM time designator
/// </summary>
private string PmDesignator
{
get
{
return (ScheduleSettings.GetActiveCulture().
DateTimeFormat.PMDesignator.ToLower());
}
}
#endregion
#endregion
#region Hook / Unhook Events
/// <summary>
/// Routine hooks all necessary events for this control
/// </summary>
/// <param name="hook">True to hook, false to unhook</param>
private void HookEvents(bool hook)
{
if (hook == true)
{
_CalendarView.LabelTimeSlotsChanged += CalendarView_LabelTimeSlotsChanged;
_CalendarView.Is24HourFormatChanged += CalendarView_Is24HourFormatChanged;
_CalendarView.TimeSlotDurationChanged += CalendarView_TimeSlotDurationChanged;
_CalendarView.TimeIndicatorsChanged += CalendarView_TimeIndicatorsChanged;
_CalendarView.TimeIndicatorTimeChanged += CalendarView_TimeIndicatorTimeChanged;
_CalendarView.WeekDayVScrollPanel.ScrollBarChanged += VScrollPanel_ScrollBarChanged;
}
else
{
_CalendarView.LabelTimeSlotsChanged -= CalendarView_LabelTimeSlotsChanged;
_CalendarView.Is24HourFormatChanged -= CalendarView_Is24HourFormatChanged;
_CalendarView.TimeSlotDurationChanged -= CalendarView_TimeSlotDurationChanged;
_CalendarView.TimeIndicatorsChanged -= CalendarView_TimeIndicatorsChanged;
_CalendarView.TimeIndicatorTimeChanged -= CalendarView_TimeIndicatorTimeChanged;
_CalendarView.WeekDayVScrollPanel.ScrollBarChanged -= VScrollPanel_ScrollBarChanged;
}
}
#endregion
#region Event Processing
#region CalendarView_LabelTimeSlotsChanged
/// <summary>
/// Processes LabelTimeSlotsChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CalendarView_LabelTimeSlotsChanged(
object sender, LabelTimeSlotsChangedEventArgs e)
{
Refresh();
}
#endregion
#region CalendarView_Is24HourFormatChanged
/// <summary>
/// Processes Is24HourFormatChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CalendarView_Is24HourFormatChanged(
object sender, Is24HourFormatChangedEventArgs e)
{
Refresh();
}
#endregion
#region CalendarView_TimeSlotDurationChanged
/// <summary>
/// Processes TimeSlotDurationChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CalendarView_TimeSlotDurationChanged(
object sender, TimeSlotDurationChangedEventArgs e)
{
Refresh();
}
#endregion
#region CalendarView_TimeIndicatorsChanged
/// <summary>
/// Processes CalendarView_TimeIndicatorsChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CalendarView_TimeIndicatorsChanged(object sender, EventArgs e)
{
Refresh();
}
#endregion
#region CalendarView_TimeIndicatorTimeChanged
/// <summary>
/// Processes CalendarView_TimeIndicatorTimeChanged events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CalendarView_TimeIndicatorTimeChanged(
object sender, TimeIndicatorTimeChangedEventArgs e)
{
Refresh();
}
#endregion
#region VScrollPanel_ScrollBarChanged
void VScrollPanel_ScrollBarChanged(object sender, EventArgs e)
{
Refresh();
Rectangle r = Bounds;
r.Y = _CalendarView.WeekDayVScrollPanel.Bounds.Y;
r.Height = _CalendarView.WeekDayVScrollPanel.Bounds.Height;
Bounds = r;
_VScrollPos = -_CalendarView.WeekDayVScrollPanel.ScrollBar.Value;
Refresh();
}
#endregion
#endregion
#region Paint processing
/// <summary>
/// Paint processing routine
/// </summary>
/// <param name="e"></param>
public override void Paint(ItemPaintArgs e)
{
int sliceStart, sliceEnd;
int sliceCount = GetSliceRange(e, out sliceStart, out sliceEnd);
if (sliceCount > 0)
{
_ViewColor.SetColorTable();
DrawTimeRuler(e, sliceStart, sliceEnd);
}
}
#region Slice Support Routines
/// <summary>
/// Calculates the range of slices needed to be drawn
/// to satisfy the specified paint request
/// </summary>
/// <param name="e">ItemPaintArgs</param>
/// <param name="sliceStart">[out] Slice start index</param>
/// <param name="sliceEnd">[out] Slice end index</param>
/// <returns>Slice range count (end - start)</returns>
internal int GetSliceRange(ItemPaintArgs e, out int sliceStart, out int sliceEnd)
{
// Calc our starting index
int start = 0;
while (start < NumberOfSlices)
{
Rectangle r = GetSliceRect(start);
if (r.Bottom > Bounds.Top)
{
if (r.Bottom > e.ClipRectangle.Y)
break;
}
start++;
}
// Calc our ending index
int end = start;
while (end < NumberOfSlices)
{
Rectangle r = GetSliceRect(end);
if (r.Y >= e.ClipRectangle.Bottom)
break;
end++;
}
// Set the user supplied 'out' values, and
// return the range count to the caller
if (end - start == 0)
{
sliceStart = 0;
sliceEnd = 0;
return (0);
}
sliceStart = start;
sliceEnd = end - 1;
return (end - start);
}
/// <summary>
/// Gets the given slice rectangle
/// </summary>
/// <param name="slice">Slice</param>
/// <returns>Bounding rectangle</returns>
private Rectangle GetSliceRect(int slice)
{
Rectangle r = Bounds;
float n = slice * TimeSliceHeight;
r.Y += (int)(n) + _VScrollPos;
r.Height = (int)(n + TimeSliceHeight) - (int)n;
return (r);
}
#endregion
#region DrawTimeRuler
/// <summary>
/// Draws the TimeRuler
/// </summary>
/// <param name="e">ItemPaintArgs</param>
/// <param name="sliceStart"></param>
/// <param name="sliceEnd"></param>
private void DrawTimeRuler(ItemPaintArgs e, int sliceStart, int sliceEnd)
{
Graphics g = e.Graphics;
Region regSav = g.Clip;
g.SetClip(Bounds);
DrawBackGround(g);
DrawTimeIndicators(g, sliceStart, sliceEnd);
DrawRulerContent(g, sliceStart, sliceEnd);
// Restore our original clip region
g.Clip = regSav;
}
#endregion
#region DrawBackGround
/// <summary>
/// DrawBackGround
/// </summary>
/// <param name="g"></param>
private void DrawBackGround(Graphics g)
{
using (Brush br = _ViewColor.BrushPart((int)eTimeRulerPart.TimeRulerBackground, Bounds))
g.FillRectangle(br, Bounds);
}
#endregion
#region DrawTimeIndicators
#region DrawTimeIndicators
/// <summary>
/// Draws TimeIndicators
/// </summary>
/// <param name="g"></param>
/// <param name="sliceStart"></param>
/// <param name="sliceEnd"></param>
private void DrawTimeIndicators(Graphics g, int sliceStart, int sliceEnd)
{
DateTime start, end;
GetViewDates(out start, out end);
Rectangle r = Rectangle.Union(GetSliceRect(sliceStart), GetSliceRect(sliceEnd));
for (int i = 0; i < _CalendarView.TimeIndicators.Count; i++)
{
TimeIndicator ti = _CalendarView.TimeIndicators[i];
if (ti.IndicatorArea == eTimeIndicatorArea.All ||
ti.IndicatorArea == eTimeIndicatorArea.Header)
{
if (ti.IsVisible())
{
DateTime time = ti.IndicatorDisplayTime;
if (time >= start && time < end)
DrawTimeIndicator(g, r, ti);
}
}
}
}
#endregion
#region DrawTimeIndicator
#region DrawTimeIndicator
/// <summary>
/// Draws individual TimeIndicators
/// </summary>
/// <param name="g"></param>
/// <param name="sRect"></param>
/// <param name="ti"></param>
private void DrawTimeIndicator(Graphics g, Rectangle sRect, TimeIndicator ti)
{
Rectangle r = GetIndicatorRect(ti);
if (r.IntersectsWith(sRect) == true)
{
if (r.Height > 0)
{
ColorDef cdef = GetIndicatorColor(ti);
if (cdef != null)
{
using (Brush br = _ViewColor.BrushPart(cdef, r))
{
if (br is LinearGradientBrush)
((LinearGradientBrush)br).WrapMode = WrapMode.TileFlipX;
g.FillRectangle(br, r);
}
}
}
Color color = GetIndicatorBorder(ti);
if (color.IsEmpty == false)
{
using (Pen pen = new Pen(color))
g.DrawLine(pen, r.X + 1, r.Bottom, r.Right - 1, r.Bottom);
}
}
}
#endregion
#region GetIndicatorColor
/// <summary>
/// Gets the Indicator Back color
/// </summary>
/// <param name="ti"></param>
/// <returns></returns>
private ColorDef GetIndicatorColor(TimeIndicator ti)
{
ColorDef cdef = ti.IndicatorColor;
if (cdef == null || cdef.IsEmpty == true)
cdef = _ViewColor.GetColorDef((int)eTimeRulerPart.TimeRulerIndicator);
return (cdef);
}
#endregion
#region GetIndicatorBorder
/// <summary>
/// Gets the Indicator Border color
/// </summary>
/// <param name="ti"></param>
/// <returns></returns>
private Color GetIndicatorBorder(TimeIndicator ti)
{
return (ti.BorderColor.IsEmpty == false ? ti.BorderColor :
_ViewColor.GetColor((int)eTimeRulerPart.TimeRulerIndicatorBorder));
}
#endregion
#endregion
#region GetViewDates
/// <summary>
/// GetViewDates
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
private void GetViewDates(out DateTime start, out DateTime end)
{
switch (_CalendarView.SelectedView)
{
case eCalendarView.Day:
start = _CalendarView.DayViewDate;
end = _CalendarView.DayViewDate.AddDays(1);
break;
default:
start = _CalendarView.WeekViewStartDate;
end = _CalendarView.WeekViewEndDate.AddDays(1);
break;
}
}
#endregion
#region GetIndicatorRect
/// <summary>
/// GetIndicatorRect
/// </summary>
/// <param name="ti"></param>
/// <returns></returns>
private Rectangle GetIndicatorRect(TimeIndicator ti)
{
DateTime time = ti.IndicatorDisplayTime;
int offset = (int)(time.Hour * SlotsPerHour * TimeSliceHeight +
(TimeSliceHeight * time.Minute) / TimeSlotDuration);
offset -= (int)(StartSlice * TimeSliceHeight);
Rectangle r = Bounds;
r.Y += (offset - ti.Thickness + _VScrollPos);
r.Height = ti.Thickness;
return (r);
}
#endregion
#endregion
#region DrawRulerContent
private void DrawRulerContent(Graphics g, int sliceStart, int sliceEnd)
{
Point pt1 = new Point();
Point pt2 = new Point();
using (Pen pen = new Pen(
_ViewColor.GetColor((int)eTimeRulerPart.TimeRulerBorder)))
{
pt1.X = 3;
pt2.X = Bounds.Width - 4;
for (int i = sliceStart; i <= sliceEnd; i++)
{
Rectangle r = GetSliceRect(i);
// Draw an hourly separation border line
if ((i % SlotsPerHour) == 0)
{
pt1.Y = pt2.Y = r.Y;
g.DrawLine(pen, pt1, pt2);
}
// Draw the time text
DrawTimeRulerText(g, r, i);
}
}
}
#endregion
#region DrawTimeRulerText
/// <summary>
/// Draws the time text
/// </summary>
/// <param name="g"></param>
/// <param name="r"></param>
/// <param name="slice"></param>
private void DrawTimeRulerText(Graphics g, Rectangle r, int slice)
{
// Get our hour and minute display text
slice += StartSlice;
int hour = slice / SlotsPerHour;
int minute = (slice % SlotsPerHour) * TimeSlotDuration;
if (_CalendarView.LabelTimeSlots == true || minute == 0)
{
string sHour = GetRulerHour(hour);
string sMinute = GetRulerMinute(hour, minute);
// Setup for our output
Color color = _ViewColor.GetColor(
(int)eTimeRulerPart.TimeRulerForeground);
eTextFormat tf = eTextFormat.Top | eTextFormat.Left | eTextFormat.NoPadding;
Size sz = TextDrawing.MeasureString(g, sHour, TimeRulerFont, 0, tf);
Rectangle r2 = new Rectangle(Bounds.X, r.Y + 1,
Bounds.Width / 2, (int)TimeSliceHeight - 1);
// If we are displaying an hourly marker, then display
// it as an offset hour and minute (or AM/PM designator) display
if (minute == 0)
{
r2.X = r2.Right - sz.Width;
if (r2.X < 0)
r2.X = 0;
r2.Width = sz.Width;
TextDrawing.DrawString(g, sHour, TimeRulerFont, color, r2, tf);
r2.X = r2.Right + 2;
r2.Y += 1;
tf = eTextFormat.Top | eTextFormat.Left | eTextFormat.NoPadding;
TextDrawing.DrawString(g, sMinute, TimeRulerFontSm, color, r2, tf);
}
else
{
// Non-hourly display
r2.Width = Bounds.Width - 4;
r2.Y += 2;
tf = eTextFormat.Top | eTextFormat.Right | eTextFormat.NoPadding;
TextDrawing.DrawString(g,
sHour + ScheduleSettings.GetActiveCulture().DateTimeFormat.TimeSeparator +
sMinute, TimeRulerFontSm, color, r2, tf);
}
}
}
/// <summary>
/// Gets the hourly display text
/// </summary>
/// <param name="hour">Hour</param>
/// <returns>Hourly text</returns>
private string GetRulerHour(int hour)
{
if (_CalendarView.Is24HourFormat == false)
{
int h = hour % 12;
hour = (h == 0) ? 12 : h;
}
else
{
int h = hour % 24;
hour = (h == 0) ? 0 : h;
}
return (hour.ToString(ScheduleSettings.TimeRulerHourFormatString));
}
/// <summary>
/// Gets the minute display text
/// </summary>
/// <param name="hour">Hour</param>
/// <param name="minute">Minute</param>
/// <returns>Minute text</returns>
private string GetRulerMinute(int hour, int minute)
{
if (minute == 0 && _CalendarView.Is24HourFormat == false)
{
hour %= 24;
if (hour == 0)
return (AmDesignator);
if (hour == 12)
return (PmDesignator);
}
return (minute.ToString(ScheduleSettings.TimeRulerMinuteFormatString));
}
#endregion
#endregion
#region IDisposable Members
protected override void Dispose(bool disposing)
{
if (disposing == true && IsDisposed == false)
HookEvents(false);
base.Dispose(disposing);
}
#endregion
#region Copy
/// <summary>
/// Returns copy of the item.
/// </summary>
public override BaseItem Copy()
{
TimeRulerPanel objCopy = new TimeRulerPanel(_CalendarView);
CopyToItem(objCopy);
return (objCopy);
}
/// <summary>
/// Copies the TimeRulerPanel specific properties to new instance of the item.
/// </summary>
/// <param name="copy">New TimeRulerPanel instance</param>
protected override void CopyToItem(BaseItem copy)
{
TimeRulerPanel objCopy = copy as TimeRulerPanel;
base.CopyToItem(objCopy);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,27 @@
#if FRAMEWORK20
namespace DevComponents.DotNetBar.Schedule
{
public class WeekDayVScrollPanel : VScrollPanel
{
public WeekDayVScrollPanel(CalendarView calendarView)
: base(calendarView)
{
}
#region Private properties
protected override int ScrollPanelSmallChange
{
get { return ((int)CalendarView.TimeSliceHeight); }
}
protected override int ScrollPanelMaximum
{
get { return ((int)(CalendarView.TimeSliceHeight * CalendarView.NumberOfSlices)); }
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,177 @@
#if FRAMEWORK20
using System;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Schedule
{
public class WeekView : WeekDayView
{
public WeekView(CalendarView calendarView)
: base(calendarView, eCalendarView.Week)
{
}
#region RecalcSize support
/// <summary>
/// Normalizes the user specified start and end dates
/// </summary>
/// <param name="startDate">[out] Normalized start date</param>
/// <param name="endDate">[out] Normalized end date</param>
protected override void NormalizeDates(out DateTime startDate, out DateTime endDate)
{
startDate = this.StartDate;
endDate = this.EndDate;
DaysOfTheWeek = new DaysOfTheWeek(startDate.DayOfWeek, DaysInWeek);
}
#endregion
#region ProcessUpDownKey
/// <summary>
/// Processes Up and Down key events
/// </summary>
/// <param name="objArg"></param>
/// <param name="dy"></param>
protected override void ProcessUpDownKey(KeyEventArgs objArg, int dy)
{
if (ValidDateSelection())
{
DateTime startDate = CalendarView.DateSelectionStart.Value;
DateTime endDate = CalendarView.DateSelectionEnd.Value;
if (startDate.Equals(DateSelectionAnchor.Value) == true)
startDate = endDate.AddMinutes(-CalendarView.TimeSlotDuration);
int col = GetColumnFromDate(startDate);
startDate = startDate.AddMinutes(dy);
if (GetColumnFromDate(startDate) == col)
{
if (col < 0)
{
startDate = CalendarView.DateSelectionStart.Value;
col = GetColumnFromDate(startDate);
}
if (col < 0)
{
startDate = CalendarView.DateSelectionEnd.Value;
col = GetColumnFromDate(startDate);
}
if (col >= 0)
{
endDate = startDate.AddMinutes(CalendarView.TimeSlotDuration);
DateTime sd = DayColumns[col].Date.AddMinutes(CalendarView.StartSlice * CalendarView.TimeSlotDuration);
DateTime ed = sd.AddMinutes(CalendarView.NumberOfActiveSlices * CalendarView.TimeSlotDuration);
if (startDate >= sd && endDate <= ed)
{
ExtendSelection(ref startDate, ref endDate);
CalendarView.DateSelectionStart = startDate;
CalendarView.DateSelectionEnd = endDate;
EnsureSelectionVisible();
}
}
}
}
objArg.Handled = true;
}
#endregion
#region ProcessLeftRightKey
/// <summary>
/// Processes Left and Right Key events
/// </summary>
/// <param name="objArg"></param>
/// <param name="dx"></param>
protected override void ProcessLeftRightKey(KeyEventArgs objArg, int dx)
{
objArg.Handled = true;
if (ValidDateSelection())
{
DateTime startDate = CalendarView.DateSelectionStart.Value;
DateTime endDate = CalendarView.DateSelectionEnd.Value;
bool newRange = (startDate < DayColumns[0].Date ||
endDate > DayColumns[NumberOfColumns - 1].Date.AddDays(1));
if (CalendarView.WeekDayCanExtendRange == true || newRange == false)
{
bool cancelled = false;
if ((objArg.Modifiers & Keys.Shift) == Keys.Shift)
{
if (startDate.Equals(DateSelectionAnchor.Value) == true)
startDate = endDate.AddMinutes(-CalendarView.TimeSlotDuration);
startDate = startDate.AddDays(dx);
endDate = startDate.AddMinutes(CalendarView.TimeSlotDuration);
if (IsNewRange(startDate, endDate) == true)
{
if (CalendarView.WeekDayCanExtendRange == false)
return;
cancelled = CalendarView.DoViewDateChanging(this,
StartDate, EndDate, ref startDate, ref endDate);
if (cancelled == false)
CalendarView.EnsureVisible(startDate, startDate.AddDays(1));
}
ExtendSelection(ref startDate, ref endDate);
}
else
{
startDate = startDate.AddDays(dx);
endDate = endDate.AddDays(dx);
if (IsNewRange(startDate, endDate) == true)
{
if (CalendarView.WeekDayCanExtendRange == false)
return;
cancelled = CalendarView.DoViewDateChanging(this,
StartDate, EndDate, ref startDate, ref endDate);
if (cancelled == false)
CalendarView.EnsureVisible(startDate, startDate.AddDays(1));
}
DateSelectionAnchor = startDate;
}
if (cancelled == false)
{
CalendarView.DateSelectionStart = startDate;
CalendarView.DateSelectionEnd = endDate;
}
EnsureSelectionVisible();
}
}
}
private bool IsNewRange(DateTime startDate, DateTime endDate)
{
return (startDate < DayColumns[0].Date ||
endDate > DayColumns[NumberOfColumns - 1].Date.AddDays(1));
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,769 @@
using System;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
namespace DevComponents.DotNetBar.Schedule
{
internal class WinApi
{
#region Windows Messages
public enum WindowsMessages
{
WM_NCPAINT = 0x0085,
WM_NCCALCSIZE = 0x0083,
WM_NCACTIVATE = 0x0086,
WM_SETTEXT = 0x000C,
WM_INITMENUPOPUP = 0x0117,
WM_WINDOWPOSCHANGED = 0x0047,
WM_NCHITTEST = 0x0084,
WM_ERASEBKGND = 0x0014,
WM_NCMOUSEMOVE = 0xA0,
WM_NCLBUTTONDOWN = 0xA1,
WM_NCMOUSELEAVE = 0x2A2,
WM_NCLBUTTONUP = 0xA2,
WM_NCMOUSEHOVER = 0x2A0,
WM_SETCURSOR = 0x20,
WM_SETICON = 0x0080,
WM_HSCROLL = 0x0114,
WM_VSCROLL = 0x115,
WM_MOUSEWHEEL = 0x020A,
WM_STYLECHANGED = 0x7D,
WM_NCLBUTTONDBLCLK = 0xA3,
WM_MOUSEACTIVATE = 0x21,
WM_MOUSEMOVE = 0x0200,
WM_MDISETMENU = 0x230,
WM_MDIREFRESHMENU = 0x234,
WM_KEYDOWN = 0x0100,
WM_SIZE = 0x5,
WM_DWMCOMPOSITIONCHANGED = 0x031E,
WM_DRAWITEM = 0x002B,
SBM_SETPOS = 0x00E0,
SBM_SETSCROLLINFO = 0x00E9,
EM_GETMODIFY = 0x00B8,
EM_SETMODIFY = 0x00B9,
WM_LBUTTONUP = 0x0202,
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONDBLCLK = 0x0203,
WM_SYSTIMER = 0x0118,
WM_SETFOCUS = 0x0007,
WM_KILLFOCUS = 0x0008,
WM_PAINT = 0x000F,
WM_COMMAND = 0x0111,
WM_CTLCOLORBTN = 0x0135,
WM_CTLCOLORSCROLLBAR = 0x0137,
WM_MDIACTIVATE = 0x222,
WM_CAPTURECHANGED = 0x0215,
CB_GETDROPPEDSTATE = 0x0157,
WVR_VALIDRECTS = 0x400,
WM_GETMINMAXINFO = 0x0024,
WM_APPCOMMAND = 0x0319
}
public enum ComboNotificationCodes : int
{
CBN_DROPDOWN = 7,
CBN_CLOSEUP = 8
}
public enum MouseKeyState : int
{
MK_LBUTTON = 0x0001,
MK_RBUTTON = 0x0002,
MK_SHIFT = 0x0004,
MK_CONTROL = 0x0008,
MK_MBUTTON = 0x0010,
MK_XBUTTON1 = 0x0020,
MK_XBUTTON2 = 0x0040
}
/// <summary>Options available when a form is tested for mose positions.</summary>
public enum WindowHitTestRegions
{
/// <summary>HTERROR: On the screen background or on a dividing line between windows
/// (same as HTNOWHERE, except that the DefWindowProc function produces a system
/// beep to indicate an error).</summary>
Error = -2,
/// <summary>HTTRANSPARENT: In a window currently covered by another window in the
/// same thread (the message will be sent to underlying windows in the same thread
/// until one of them returns a code that is not HTTRANSPARENT).</summary>
TransparentOrCovered = -1,
/// <summary>HTNOWHERE: On the screen background or on a dividing line between
/// windows.</summary>
NoWhere = 0,
/// <summary>HTCLIENT: In a client area.</summary>
ClientArea = 1,
/// <summary>HTCAPTION: In a title bar.</summary>
TitleBar = 2,
/// <summary>HTSYSMENU: In a window menu or in a Close button in a child window.</summary>
SystemMenu = 3,
/// <summary>HTGROWBOX: In a size box (same as HTSIZE).</summary>
GrowBox = 4,
/// <summary>HTMENU: In a menu.</summary>
Menu = 5,
/// <summary>HTHSCROLL: In a horizontal scroll bar.</summary>
HorizontalScrollBar = 6,
/// <summary>HTVSCROLL: In the vertical scroll bar.</summary>
VerticalScrollBar = 7,
/// <summary>HTMINBUTTON: In a Minimize button. </summary>
MinimizeButton = 8,
/// <summary>HTMAXBUTTON: In a Maximize button.</summary>
MaximizeButton = 9,
/// <summary>HTLEFT: In the left border of a resizable window (the user can click
/// the mouse to resize the window horizontally).</summary>
LeftSizeableBorder = 10,
/// <summary>HTRIGHT: In the right border of a resizable window (the user can click
/// the mouse to resize the window horizontally).</summary>
RightSizeableBorder = 11,
/// <summary>HTTOP: In the upper-horizontal border of a window.</summary>
TopSizeableBorder = 12,
/// <summary>HTTOPLEFT: In the upper-left corner of a window border.</summary>
TopLeftSizeableCorner = 13,
/// <summary>HTTOPRIGHT: In the upper-right corner of a window border.</summary>
TopRightSizeableCorner = 14,
/// <summary>HTBOTTOM: In the lower-horizontal border of a resizable window (the
/// user can click the mouse to resize the window vertically).</summary>
BottomSizeableBorder = 15,
/// <summary>HTBOTTOMLEFT: In the lower-left corner of a border of a resizable
/// window (the user can click the mouse to resize the window diagonally).</summary>
BottomLeftSizeableCorner = 16,
/// <summary>HTBOTTOMRIGHT: In the lower-right corner of a border of a resizable
/// window (the user can click the mouse to resize the window diagonally).</summary>
BottomRightSizeableCorner = 17,
/// <summary>HTBORDER: In the border of a window that does not have a sizing
/// border.</summary>
NonSizableBorder = 18,
/// <summary>HTOBJECT: Unknown...No Documentation Found</summary>
Object = 19,
/// <summary>HTCLOSE: In a Close button.</summary>
CloseButton = 20,
/// <summary>HTHELP: In a Help button.</summary>
HelpButton = 21,
/// <summary>HTSIZE: In a size box (same as HTGROWBOX). (Same as GrowBox).</summary>
SizeBox = GrowBox,
/// <summary>HTREDUCE: In a Minimize button. (Same as MinimizeButton).</summary>
ReduceButton = MaximizeButton,
/// <summary>HTZOOM: In a Maximize button. (Same as MaximizeButton).</summary>
ZoomButton = MaximizeButton,
}
public enum GWL
{
GWL_WNDPROC = (-4),
GWL_HINSTANCE = (-6),
GWL_HWNDPARENT = (-8),
GWL_STYLE = (-16),
GWL_EXSTYLE = (-20),
GWL_USERDATA = (-21),
GWL_ID = (-12)
}
public enum RedrawWindowFlags : uint
{
RDW_INVALIDATE = 0x0001,
RDW_INTERNALPAINT = 0x0002,
RDW_ERASE = 0x0004,
RDW_VALIDATE = 0x0008,
RDW_NOINTERNALPAINT = 0x0010,
RDW_NOERASE = 0x0020,
RDW_NOCHILDREN = 0x0040,
RDW_ALLCHILDREN = 0x0080,
RDW_UPDATENOW = 0x0100,
RDW_ERASENOW = 0x0200,
RDW_FRAME = 0x0400,
RDW_NOFRAME = 0x0800
}
[Flags()]
public enum WindowStyles
{
WS_VISIBLE = 0x10000000,
WS_CAPTION = 0x00C00000,
WS_BORDER = 0x800000,
WS_DLGFRAME = 0x400000,
WS_THICKFRAME = 0x00040000
}
#endregion
#region Windows API
[DllImport("user32")]
public static extern IntPtr WindowFromPoint(POINT p);
[DllImport("user32.dll")]
public static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern short GetKeyState(int keyCode);
[DllImport("user32.dll")]
public static extern bool IsZoomed(IntPtr hWnd);
//[DllImport("user32.dll")]
//public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr BeginPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
[System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
[DllImport("gdi32.dll")]
public static extern int ExcludeClipRect(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
[DllImport("user32")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool GetTextMetrics(HandleRef hdc, TEXTMETRIC tm);
[DllImport("user32.dll")]
public static extern bool SetMenu(IntPtr hWnd, IntPtr hMenu);
[DllImport("user32.dll")]
public static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32")]
public static extern bool RedrawWindow(IntPtr hWnd, [In] ref RECT lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags);
[DllImport("user32")]
public static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags);
[DllImport("user32")]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT r);
[DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollBarInfo")]
public static extern int GetScrollBarInfo(IntPtr hWnd, uint idObject, ref SCROLLBARINFO psbi);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int SetScrollInfo(HandleRef hWnd, int fnBar, ref SCROLLINFO si, bool redraw);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern bool AdjustWindowRectEx(ref RECT lpRect, int dwStyle,
bool bMenu, int dwExStyle);
// This static method is required because legacy OSes do not support
// GetWindowLongPtr
public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex)
{
if (IntPtr.Size == 8)
return GetWindowLongPtr64(hWnd, nIndex);
else
return new IntPtr(GetWindowLong32(hWnd, nIndex));
}
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
public static extern int GetWindowLong32(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int MapWindowPoints(IntPtr hwndFrom, IntPtr hwndTo, ref POINT lpPoints, [MarshalAs(UnmanagedType.U4)] int cPoints);
[DllImport("user32")]
public static extern bool PostMessage(int hWnd, int Msg, int wParam, int lParam);
[DllImport("user32")]
public static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateDIBSection(IntPtr hdc, BITMAPINFO pbmi, uint iUsage, int ppvBits, IntPtr hSection, uint dwOffset);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
[DllImport("gdi32")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32")]
public static extern bool DeleteObject(int hObject);
public delegate void TimerDelegate(IntPtr hWnd, IntPtr uMsg, IntPtr idEvent, int dwTime);
[DllImport("user32.dll")]
public static extern UIntPtr SetTimer(IntPtr hWnd, UIntPtr nIDEvent, uint uElapse, TimerDelegate lpTimerFunc);
[DllImport("user32.dll")]
public static extern bool KillTimer(IntPtr hWnd, UIntPtr uIDEvent);
#endregion
#region Structures
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class TEXTMETRIC
{
public int tmHeight;
public int tmAscent;
public int tmDescent;
public int tmInternalLeading;
public int tmExternalLeading;
public int tmAveCharWidth;
public int tmMaxCharWidth;
public int tmWeight;
public int tmOverhang;
public int tmDigitizedAspectX;
public int tmDigitizedAspectY;
public char tmFirstChar;
public char tmLastChar;
public char tmDefaultChar;
public char tmBreakChar;
public byte tmItalic;
public byte tmUnderlined;
public byte tmStruckOut;
public byte tmPitchAndFamily;
public byte tmCharSet;
}
[StructLayout(LayoutKind.Sequential)]
public struct SCROLLBARINFO
{
public int cbSize;
public RECT rcScrollBar;
public int dxyLineButton;
public int xyThumbTop;
public int xyThumbBottom;
public int reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public int[] rgstate;
}
public enum eScrollBarDirection
{
SB_HORZ = 0,
SB_VERT = 1
}
public enum eScrollInfoMask
{
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS
}
[StructLayout(LayoutKind.Sequential)]
public struct SCROLLINFO
{
public int cbSize;
public int fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
public POINT(System.Drawing.Point p)
{
this.x = p.X;
this.y = p.Y;
}
public POINT(int x, int y)
{
this.x = x;
this.y = y;
}
public override string ToString()
{
return string.Format("{0},{1}", x, y);
}
}
public enum ShowWindowCommands : int
{
/// <summary>
/// Hides the window and activates another window.
/// </summary>
Hide = 0,
/// <summary>
/// Activates and displays a window. If the window is minimized or
/// maximized, the system restores it to its original size and position.
/// An application should specify this flag when displaying the window
/// for the first time.
/// </summary>
Normal = 1,
/// <summary>
/// Activates the window and displays it as a minimized window.
/// </summary>
ShowMinimized = 2,
/// <summary>
/// Maximizes the specified window.
/// </summary>
Maximize = 3, // is this the right value?
/// <summary>
/// Activates the window and displays it as a maximized window.
/// </summary>
ShowMaximized = 3,
/// <summary>
/// Displays a window in its most recent size and position. This value
/// is similar to <see cref="Win32.ShowWindowCommand.Normal"/>, except
/// the window is not actived.
/// </summary>
ShowNoActivate = 4,
/// <summary>
/// Activates the window and displays it in its current size and position.
/// </summary>
Show = 5,
/// <summary>
/// Minimizes the specified window and activates the next top-level
/// window in the Z order.
/// </summary>
Minimize = 6,
/// <summary>
/// Displays the window as a minimized window. This value is similar to
/// <see cref="Win32.ShowWindowCommand.ShowMinimized"/>, except the
/// window is not activated.
/// </summary>
ShowMinNoActive = 7,
/// <summary>
/// Displays the window in its current size and position. This value is
/// similar to <see cref="Win32.ShowWindowCommand.Show"/>, except the
/// window is not activated.
/// </summary>
ShowNA = 8,
/// <summary>
/// Activates and displays the window. If the window is minimized or
/// maximized, the system restores it to its original size and position.
/// An application should specify this flag when restoring a minimized window.
/// </summary>
Restore = 9,
/// <summary>
/// Sets the show state based on the SW_* value specified in the
/// STARTUPINFO structure passed to the CreateProcess function by the
/// program that started the application.
/// </summary>
ShowDefault = 10,
/// <summary>
/// <b>Windows 2000/XP:</b> Minimizes a window, even if the thread
/// that owns the window is not responding. This flag should only be
/// used when minimizing windows from a different thread.
/// </summary>
ForceMinimize = 11
}
public struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public POINT ptMinPosition;
public POINT ptMaxPosition;
public RECT rcNormalPosition;
}
/// <summary>
/// Retrieves the show state and the restored, minimized, and maximized positions of the specified window.
/// </summary>
/// <param name="hWnd">
/// A handle to the window.
/// </param>
/// <param name="lpwndpl">
/// A pointer to the WINDOWPLACEMENT structure that receives the show state and position information.
/// <para>
/// Before calling GetWindowPlacement, set the length member to sizeof(WINDOWPLACEMENT). GetWindowPlacement fails if lpwndpl-> length is not set correctly.
/// </para>
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero.
/// <para>
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
/// </para>
/// </returns>
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);
[StructLayout(LayoutKind.Sequential)]
public struct NCCALCSIZE_PARAMS
{
public RECT rgrc0, rgrc1, rgrc2;
public IntPtr lppos;
}
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x, y;
public int cx, cy;
public int flags;
public override string ToString()
{
return string.Format("x={0}, y={1}, right={2}, bottom={3}", x, y, cx, cy);
}
}
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public RECT(int left_, int top_, int right_, int bottom_)
{
Left = left_;
Top = top_;
Right = right_;
Bottom = bottom_;
}
public RECT(Rectangle r)
{
Left = r.Left;
Top = r.Top;
Right = r.Right;
Bottom = r.Bottom;
}
public int Height { get { return Bottom - Top; } }
public int Width { get { return Right - Left; } }
public Size Size { get { return new Size(Width, Height); } }
public Point Location { get { return new Point(Left, Top); } }
// Handy method for converting to a System.Drawing.Rectangle
public Rectangle ToRectangle()
{ return Rectangle.FromLTRB(Left, Top, Right, Bottom); }
public static RECT FromRectangle(Rectangle rectangle)
{
return new RECT(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom);
}
public override int GetHashCode()
{
return Left ^ ((Top << 13) | (Top >> 0x13))
^ ((Width << 0x1a) | (Width >> 6))
^ ((Height << 7) | (Height >> 0x19));
}
#region Operator overloads
public static implicit operator Rectangle(RECT rect)
{
return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
public static implicit operator RECT(Rectangle rect)
{
return new RECT(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
public override string ToString()
{
return "Left=" + this.Left + ", Top=" + this.Top + ", Right=" + this.Right + ", Bottom=" + this.Bottom;
}
#endregion
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct PAINTSTRUCT
{
public IntPtr hdc;
public int fErase;
public WinApi.RECT rcPaint;
public int fRestore;
public int fIncUpdate;
public int Reserved1;
public int Reserved2;
public int Reserved3;
public int Reserved4;
public int Reserved5;
public int Reserved6;
public int Reserved7;
public int Reserved8;
}
[StructLayout(LayoutKind.Sequential)]
public class BITMAPINFO
{
public int biSize = 0;
public int biWidth = 0;
public int biHeight = 0;
public short biPlanes = 0;
public short biBitCount = 0;
public int biCompression = 0;
public int biSizeImage = 0;
public int biXPelsPerMeter = 0;
public int biYPelsPerMeter = 0;
public int biClrUsed = 0;
public int biClrImportant = 0;
public byte bmiColors_rgbBlue = 0;
public byte bmiColors_rgbGreen = 0;
public byte bmiColors_rgbRed = 0;
public byte bmiColors_rgbReserved = 0;
}
public enum eObjectId : uint
{
OBJID_CLIENT = 0xFFFFFFFC,
OBJID_VSCROLL = 0xFFFFFFFB,
OBJID_HSCROLL = 0xFFFFFFFA
}
public enum eStateFlags
{
STATE_SYSTEM_INVISIBLE = 0x00008000,
STATE_SYSTEM_OFFSCREEN = 0x00010000,
STATE_SYSTEM_PRESSED = 0x00000008,
STATE_SYSTEM_UNAVAILABLE = 0x00000001
}
#endregion
#region Functions
public enum AppCommands
{
APPCOMMAND_BROWSER_BACKWARD = 1,
APPCOMMAND_BROWSER_FORWARD = 2
}
private static int FAPPCOMMAND_MASK = 0xF000;
public static int GetAppCommandLParam(IntPtr lParam)
{
return HIWORD(lParam) & ~FAPPCOMMAND_MASK;
}
public static int LOWORD(int n)
{
return (short)(n & 0xffff);
}
public static int HIWORD(int n)
{
return (int)((n >> 0x10) & 0xffff);
}
public static int LOWORD(IntPtr n)
{
return LOWORD((int)((long)n));
}
public static int HIWORD(IntPtr n)
{
return HIWORD((int)((long)n));
}
public static IntPtr CreateLParam(int loWord, int hiWord)
{
byte[] bx = BitConverter.GetBytes(loWord);
byte[] by = BitConverter.GetBytes(hiWord);
byte[] blp = new byte[] { bx[0], bx[1], by[0], by[1] };
return new IntPtr(BitConverter.ToInt32(blp, 0));
}
#endregion
#region DWM
[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("dwmapi.dll")]
public static extern int DwmSetWindowAttribute(
IntPtr hWnd,
int dwAttribute,
ref int attributeValue,
int sizeOfValueRetrived
);
[DllImport("dwmapi.dll")]
public static extern int DwmGetWindowAttribute(
IntPtr hwnd,
int dwAttribute,
ref int pvAttribute,
int sizeOfValueRetrived);
[DllImport("dwmapi.dll", PreserveSig = false)]
static extern bool DwmIsCompositionEnabled();
[DllImport("dwmapi.dll")]
public static extern int DwmDefWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, out IntPtr plResult);
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "DefWindowProcW")]
public static extern IntPtr DefWindowProc(IntPtr hWnd, WindowsMessages Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "DefWindowProcW")]
public static extern IntPtr DefWindowProc(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins);
public static void ExtendGlass(IntPtr handle, int glassHeight)
{
MARGINS margins = new MARGINS();
margins.cxLeftWidth = 0;
margins.cxRightWidth = 0;
margins.cyTopHeight = glassHeight;
margins.cyBottomHeight = 0;
int result = DwmExtendFrameIntoClientArea(handle, ref margins);
}
public static bool IsGlassEnabled
{
get
{
if (System.Environment.OSVersion.Version.Major < 6)
return false;
return DwmIsCompositionEnabled();
}
}
public enum DWMWINDOWATTRIBUTE : int
{
DWMWA_NCRENDERING_ENABLED = 1,
DWMWA_NCRENDERING_POLICY = 2,
DWMWA_TRANSITIONS_FORCEDISABLED = 3,
DWMWA_ALLOW_NCPAINT = 4,
DWMWA_LAST = 5
}
public enum DWMNCRENDERINGPOLICY : int
{
DWMNCRP_USEWINDOWSTYLE = 0,
DWMNCRP_DISABLED = 1,
DWMNCRP_ENABLED = 2,
DWMNCRP_LAST = 3
}
public enum WVR
{
ALIGNTOP = 0x0010,
ALIGNLEFT = 0x0020,
ALIGNBOTTOM = 0x0040,
ALIGNRIGHT = 0x0080,
HREDRAW = 0x0100,
VREDRAW = 0x0200,
VALIDRECTS = 0x0400,
REDRAW = HREDRAW | VREDRAW,
}
#endregion
}
}

View File

@@ -0,0 +1,395 @@
#if FRAMEWORK20
using System;
using DevComponents.Schedule.Model;
using System.ComponentModel;
using System.Collections.Generic;
namespace DevComponents.DotNetBar.Schedule
{
internal class ModelYearViewConnector : ModelViewConnector
{
#region Static data
static private List<Appointment> _lineAppts;
static private int _lineState; // Refresh state
static private DateTime _lineStartTime; // YearView start date
static private DateTime _lineEndTime; // YearView end date
#endregion
#region Private variables
private CalendarModel _Model; // The associated CalendarModel
private YearView _View; // The associated YearView
private bool _IsConnected; // Connection status
private int _ViewState; // View refresh state
#endregion
/// <summary>
/// Constructor
/// </summary>
/// <param name="model">Assoc CalendarModel</param>
/// <param name="yearView">Assoc YearView</param>
public ModelYearViewConnector(CalendarModel model, YearView yearView)
{
_Model = model;
_View = yearView;
}
#region Public properties
/// <summary>
/// Gets the connection status
/// </summary>
public override bool IsConnected
{
get { return _IsConnected; }
}
#endregion
#region Internal properties
internal int ViewState
{
get { return (_ViewState); }
}
#endregion
#region Connect processing
/// <summary>
/// Performs Model connection processing
/// </summary>
public override void Connect()
{
// Load the connection data
if (_IsConnected)
Disconnect();
LoadData(_ViewState == _lineState);
// Get notification on Model property changes
_Model.PropertyChanged += ModelPropertyChanged;
_Model.SubPropertyChanged += ModelSubPropertyChanged;
_View.CalendarView.CustomItems.CollectionChanged += CustomItemsCollectionChanged;
_IsConnected = true;
}
#endregion
#region Disconnect processing
/// <summary>
/// Severs the Model/MonthView connection
/// </summary>
public override void Disconnect()
{
if (_IsConnected)
{
// Loop through each week, clearing each
// associated view connection
for (int i = 0; i < _View.YearMonths.Length; i++)
_View.YearMonths[i].AppBits.SetAll(false);
// Stop notification on Model property changes
_Model.PropertyChanged -= ModelPropertyChanged;
_Model.SubPropertyChanged -= ModelSubPropertyChanged;
_View.CalendarView.CustomItems.CollectionChanged -= CustomItemsCollectionChanged;
_IsConnected = false;
}
}
#endregion
#region LoadData processing
/// <summary>
/// Loads Model/YearView connection data
/// </summary>
private void LoadData(bool reload)
{
if (reload == true ||
_lineStartTime != _View.StartDate || _lineEndTime != _View.EndDate)
{
_lineStartTime = _View.StartDate;
_lineEndTime = _View.EndDate;
_lineAppts = GetAppointmentList(_Model, _View.StartDate, _View.EndDate.AddDays(1));
}
if (reload == true)
_lineState = _lineState ^ 1;
_ViewState = _lineState;
foreach (YearMonth yearMonth in _View.YearMonths)
yearMonth.AppBits.SetAll(false);
int rootMonth = _View.StartDate.Year * 12 + _View.StartDate.Month;
for (int i = 0; i < _lineAppts.Count; i++)
{
Appointment app = _lineAppts[i];
if (IsAppointmentVisible(app) == true)
{
int day = app.StartTime.Day - 1;
int month = (app.StartTime.Year * 12 + app.StartTime.Month) - rootMonth;
DateTime date = app.StartTime;
if (month < 0)
{
day = 0;
month = 0;
if (_View.YearMonths.Length > 0)
date = _View.YearMonths[0].StartDate;
}
if (month < _View.YearMonths.Length)
{
YearMonth ym = _View.YearMonths[month];
while (date < app.EndTime || (date == app.EndTime && app.StartTime == app.EndTime))
{
if (day >= ym.DaysInMonth)
{
month++;
if (month >= _View.YearMonths.Length)
break;
ym = _View.YearMonths[month];
day = 0;
}
ym.AppBits.Set(day++, true);
date = date.AddDays(1);
}
}
}
}
foreach (YearMonth yearMonth in _View.YearMonths)
UpdateCustomItems(yearMonth);
}
#endregion
#region UpdateCustomItems
/// <summary>
/// UpdateCustomItems
/// </summary>
/// <param name="yearMonth"></param>
private void UpdateCustomItems(YearMonth yearMonth)
{
CustomCalendarItemCollection items = _View.CalendarView.CustomItems;
if (items != null && items.Count > 0)
{
for (int i = 0; i < items.Count; i++)
{
CustomCalendarItem item = items[i];
if (IsCustomItemVisible(item) == true &&
(item.StartTime.Year == yearMonth.StartDate.Year && item.StartTime.Month == yearMonth.StartDate.Month))
{
yearMonth.AppBits.Set(item.StartTime.Day - 1, true);
break;
}
}
}
}
#endregion
#region CustomItems_CollectionChanged
/// <summary>
/// Handles CustomItemCollection change events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CustomItemsCollectionChanged(object sender, EventArgs e)
{
LoadData(_ViewState == _lineState);
_View.NeedRecalcLayout = true;
_View.NeedRecalcSize = true;
}
#endregion
#region GetFirstAppointment
/// <summary>
/// GetFirstAppointment
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
internal Appointment GetFirstAppointment(DateTime date)
{
Appointment app = null;
AppointmentSubsetCollection asc = _Model.GetDay(date).Appointments;
if (asc.Count > 0)
{
for (int i = 0; i < asc.Count; i++)
{
if (IsAppointmentVisible(asc[i]) == true)
{
if (app == null || asc[i].StartTime < app.StartTime)
app = asc[i];
}
}
return (app);
}
return (null);
}
#endregion
#region GetFirstCustomItem
/// <summary>
/// GetFirstCustomItem
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
internal CustomCalendarItem GetFirstCustomItem(DateTime date)
{
CustomCalendarItemCollection items = _View.CalendarView.CustomItems;
if (items != null && items.Count > 0)
{
for (int i = 0; i < items.Count; i++)
{
CustomCalendarItem item = items[i];
if (IsCustomItemVisible(item) == true &&
(item.StartTime.Date == date.Date))
{
return (item);
}
}
}
return (null);
}
#endregion
#region GetView
/// <summary>
/// Returns the Month view
/// </summary>
/// <returns></returns>
public override eCalendarView GetView()
{
return (eCalendarView.Year);
}
#endregion
#region ResetModelData
/// <summary>
/// ResetModelData
/// </summary>
static internal void ResetModelData()
{
_lineStartTime = DateTime.MinValue;
}
#endregion
#region ModelPropertyChanged
/// <summary>
/// Handles Model property change notifications
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == CalendarModel.AppointmentsPropertyName)
{
LoadData(_ViewState == _lineState);
_View.NeedRecalcSize = true;
_View.Refresh();
}
}
#endregion
#region ModelSubPropertyChanged
/// <summary>
/// Handles ModelSubProperty change notifications
/// </summary>
/// <param name="sender">object</param>
/// <param name="e">SubPropertyChangedEventArgs</param>
private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e)
{
if (e.Source is Owner)
{
Owner owner = (Owner)e.Source;
if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key))
{
if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName)
_View.DisplayName = owner.DisplayName;
else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme"))
_View.CalendarColor = owner.ColorScheme;
}
}
else if (e.Source is Appointment)
{
Appointment app = e.Source as Appointment;
string name = e.PropertyChangedArgs.PropertyName;
if (name.Equals("OwnerKey"))
{
if (_View.CalendarView.IsMultiCalendar == true)
{
if (_View.OwnerKey == app.OwnerKey)
{
LoadData(_ViewState == _lineState);
_View.NeedRecalcSize = true;
_View.Refresh();
}
}
}
else if (name.Equals("Visible"))
{
LoadData(true);
}
}
}
#endregion
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More