Advertisement
Guest User

DatePeriodEdit

a guest
Mar 2nd, 2013
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 49.75 KB | None | 0 0
  1. Imports Microsoft.VisualBasic
  2. Imports System
  3. Imports System.Collections.Generic
  4. Imports System.Text
  5. Imports DevExpress.XtraEditors.Registrator
  6. Imports System.ComponentModel
  7. Imports DevExpress.XtraEditors.ViewInfo
  8. Imports DevExpress.XtraEditors.Drawing
  9. Imports DevExpress.XtraEditors
  10. Imports DevExpress.XtraEditors.Repository
  11. Imports DevExpress.XtraEditors.Popup
  12. Imports DevExpress.XtraEditors.Controls
  13. Imports DevExpress.XtraEditors.Calendar
  14. Imports System.Windows.Forms
  15. Imports System.Drawing
  16. Imports DevExpress.Utils.Serializing
  17. Imports System.Globalization
  18. Imports DevExpress.Utils
  19. Imports DevExpress.Data.Utils
  20. Imports System.Collections
  21. <UserRepositoryItem("RegisterDatePeriodEdit")> _
  22. Public Class RepositoryItemDatePeriodEdit
  23.     Inherits RepositoryItemDateEdit
  24.     Private _AllowedDateRange() As Date
  25.     Private _OptionsSelection As OptionsSelection
  26.     Private _PeriodsStoreMode As StoreMode
  27.     Private _SeparatorChar As Char = ","c
  28.     Public Const DatePeriodEditName As String = "DatePeriodEdit"
  29.     Shared Sub New()
  30.         RegisterDatePeriodEdit()
  31.     End Sub
  32.     Public Sub New()
  33.         _OptionsSelection = New OptionsSelection()
  34.         TextEditStyle = TextEditStyles.DisableTextEditor
  35.     End Sub
  36.     Public Overrides ReadOnly Property EditorTypeName() As String
  37.         Get
  38.             Return DatePeriodEditName
  39.         End Get
  40.     End Property
  41.     Public Shared Sub RegisterDatePeriodEdit()
  42.         EditorRegistrationInfo.Default.Editors.Add(New EditorClassInfo(DatePeriodEditName, GetType(DatePeriodEdit), GetType(RepositoryItemDatePeriodEdit), GetType(DateEditViewInfo), New ButtonEditPainter(), True))
  43.     End Sub
  44.     <Description("Gets or sets how the editor store periods selected via the calendar ."), Category(CategoryName.Format), DefaultValue(StoreMode.Default)> _
  45.     Public Overridable Property PeriodsStoreMode() As StoreMode
  46.         Get
  47.             Return _PeriodsStoreMode
  48.         End Get
  49.         Set(ByVal value As StoreMode)
  50.             If PeriodsStoreMode = value Then
  51.                 Return
  52.             End If
  53.             Me._PeriodsStoreMode = value
  54.         End Set
  55.     End Property
  56.     <Description("Gets or sets the character separating periods"), Category(CategoryName.Format), DefaultValue(","c)> _
  57.     Public Overridable Property SeparatorChar() As Char
  58.         Get
  59.             Return Me._SeparatorChar
  60.         End Get
  61.         Set(ByVal value As Char)
  62.             If SeparatorChar = value Then
  63.                 Return
  64.             End If
  65.             Me._SeparatorChar = value
  66.             OnPropertiesChanged()
  67.         End Set
  68.     End Property
  69.     <Browsable(False)> _
  70.     Public Overrides ReadOnly Property Mask() As DevExpress.XtraEditors.Mask.MaskProperties
  71.         Get
  72.             Return MyBase.Mask
  73.         End Get
  74.     End Property
  75.     <Browsable(False)> _
  76.     Public Overrides ReadOnly Property EditFormat() As FormatInfo
  77.         Get
  78.             Return MyBase.DisplayFormat
  79.         End Get
  80.     End Property
  81.     <Browsable(False)> _
  82.     Public Shadows ReadOnly Property VistaEditTime() As DefaultBoolean
  83.         Get
  84.             Return MyBase.VistaEditTime
  85.         End Get
  86.     End Property
  87.     <Browsable(False)> _
  88.     Public Shadows ReadOnly Property VistaDisplayMode() As DefaultBoolean
  89.         Get
  90.             Return MyBase.VistaDisplayMode
  91.         End Get
  92.     End Property
  93.     <Browsable(False)> _
  94.     Public Shadows ReadOnly Property EditMask() As String
  95.         Get
  96.             Return MyBase.EditMask
  97.         End Get
  98.     End Property
  99.     <Description("Provides access to the settings used to selection."), Category(CategoryName.Properties), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
  100.     Public ReadOnly Property OptionsSelection() As OptionsSelection
  101.         Get
  102.             Return _OptionsSelection
  103.         End Get
  104.     End Property
  105.     Public Property AllowedDateRange() As Date()
  106.         Get
  107.             Return Me._AllowedDateRange
  108.         End Get
  109.         Set(ByVal value As Date())
  110.             Me._AllowedDateRange = value
  111.         End Set
  112.     End Property
  113.     Public Overrides Sub Assign(ByVal item As RepositoryItem)
  114.         MyBase.Assign(item)
  115.         Dim source As RepositoryItemDatePeriodEdit = TryCast(item, RepositoryItemDatePeriodEdit)
  116.         Me._OptionsSelection = source.OptionsSelection
  117.         Me._SeparatorChar = source.SeparatorChar
  118.         Me._PeriodsStoreMode = source.PeriodsStoreMode
  119.     End Sub
  120.     Protected Overrides Function IsNullValue(ByVal editValue As Object) As Boolean
  121.         If TypeOf editValue Is PeriodsSet Then
  122.             Return (CType(editValue, PeriodsSet)).Periods.Count = 0
  123.         End If
  124.         If TypeOf editValue Is String Then
  125.             Dim [set] As PeriodsSet = PeriodsSet.Parse(CStr(editValue))
  126.             If [set] IsNot Nothing Then
  127.                 Return [set].Periods.Count = 0
  128.             End If
  129.         End If
  130.         Return False
  131.     End Function
  132.     Public Overloads Overrides Function GetDisplayText(ByVal format As FormatInfo, ByVal editValue As Object) As String
  133.         Dim displayText As String = String.Empty
  134.         Dim [set] As PeriodsSet = TryCast(editValue, PeriodsSet)
  135.         If [set] IsNot Nothing Then
  136.             displayText = [set].ToString(format.FormatString, SeparatorChar)
  137.         Else
  138.             If TypeOf editValue Is String Then
  139.                 displayText = PeriodsSet.Parse(CStr(editValue)).ToString(format.FormatString, SeparatorChar)
  140.             End If
  141.         End If
  142.         Dim e As New CustomDisplayTextEventArgs(editValue, displayText)
  143.         If format IsNot EditFormat Then
  144.             RaiseCustomDisplayText(e)
  145.         End If
  146.         Return e.DisplayText
  147.     End Function
  148. End Class
  149. Public Class DatePeriodEdit
  150.     Inherits DateEdit
  151.     Shared Sub New()
  152.         RepositoryItemDatePeriodEdit.RegisterDatePeriodEdit()
  153.     End Sub
  154.     Public Sub New()
  155.         MyBase.New()
  156.         EditValue = New PeriodsSet()
  157.     End Sub
  158.     Public Overrides Property EditValue() As Object
  159.         Get
  160.             Dim value As PeriodsSet = TryCast(MyBase.EditValue, PeriodsSet)
  161.             If Properties.PeriodsStoreMode = StoreMode.String Then
  162.                 If value IsNot Nothing Then
  163.                     Return value.ToString()
  164.                 Else
  165.                     Return String.Empty
  166.                 End If
  167.             Else
  168.                 If value IsNot Nothing Then
  169.                     Return value
  170.                 Else
  171.                     Return New PeriodsSet()
  172.                 End If
  173.             End If
  174.         End Get
  175.         Set(ByVal value As Object)
  176.             If TypeOf value Is PeriodsSet Then
  177.                 MyBase.EditValue = value
  178.                 Return
  179.             End If
  180.             If TypeOf value Is String Then
  181.                 MyBase.EditValue = PeriodsSet.Parse(CStr(value))
  182.                 Return
  183.             End If
  184.             MyBase.EditValue = value
  185.         End Set
  186.     End Property
  187.     Public Overrides ReadOnly Property EditorTypeName() As String
  188.         Get
  189.             Return RepositoryItemDatePeriodEdit.DatePeriodEditName
  190.         End Get
  191.     End Property
  192.     <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
  193.     Public Shadows ReadOnly Property Properties() As RepositoryItemDatePeriodEdit
  194.         Get
  195.             Return TryCast(MyBase.Properties, RepositoryItemDatePeriodEdit)
  196.         End Get
  197.     End Property
  198.     Protected Overrides Function CreatePopupForm() As PopupBaseForm
  199.         Return New VistaPopupDatePeriodEditForm(Me)
  200.     End Function
  201.     Protected Overrides Function ExtractParsedValue(ByVal e As ConvertEditValueEventArgs) As Object
  202.         Return e.Value
  203.     End Function
  204. End Class
  205. Public Class VistaPopupDatePeriodEditForm
  206.     Inherits VistaPopupDateEditForm
  207.     Public Sub New(ByVal ownerEdit As DatePeriodEdit)
  208.         MyBase.New(ownerEdit)
  209.     End Sub
  210.     Protected Overrides Function CreateCalendar() As DateEditCalendar
  211.         Dim c As New VistaDatePeriodEditCalendar(OwnerEdit.Properties, OwnerEdit.EditValue)
  212.         AddHandler c.OkClick, AddressOf OnOkClick
  213.         Return c
  214.     End Function
  215.     Public Overrides ReadOnly Property ResultValue() As Object
  216.         Get
  217.             Return Calendar.TotalPeriods.GetCopy()
  218.         End Get
  219.     End Property
  220.     Public Overridable Shadows ReadOnly Property Calendar() As VistaDatePeriodEditCalendar
  221.         Get
  222.             Return TryCast(MyBase.Calendar, VistaDatePeriodEditCalendar)
  223.         End Get
  224.     End Property
  225. End Class
  226. Public Class VistaDatePeriodEditCalendar
  227.     Inherits VistaDateEditCalendar
  228.     Private _TotalPeriods, _TotalPeriodsCopy As PeriodsSet
  229.     Private _AllowMark As Boolean
  230.     Private _ViewLevel As ViewLevel
  231.     Public Sub New(ByVal item As RepositoryItemDatePeriodEdit, ByVal editDate As Object)
  232.         MyBase.New(item, editDate)
  233.         Selection.Clear()
  234.         Multiselect = True
  235.         Dim editValue As PeriodsSet = TryCast(Properties.OwnerEdit.EditValue, PeriodsSet)
  236.         _TotalPeriods = New PeriodsSet()
  237.         _ViewLevel = GetNewLevel(Properties.OptionsSelection.DefaultLevel, Properties.OptionsSelection.DefaultLevel)
  238.         CreatePrevImage(False)
  239.     End Sub
  240.     Public Overrides Sub ResetState(ByVal editDate As Object, ByVal dt As DateTime)
  241.         UpdateTotalPeriods(editDate)
  242.         MyBase.ResetState(editDate, dt)
  243.         If TotalPeriods.Periods.Count = 0 Then
  244.             DateTime = Date.Now
  245.         Else
  246.             DateTime = TotalPeriods(0).Begin
  247.         End If
  248.         ViewLevel = GetNewLevel(ViewLevel, ViewLevel)
  249.     End Sub
  250.     Public Overridable Shadows Property DateTime() As DateTime
  251.         Get
  252.             Return MyBase.DateTime.Date
  253.         End Get
  254.         Set(ByVal value As DateTime)
  255.             MyBase.DateTime = value.Date
  256.         End Set
  257.     End Property
  258.     Protected Overridable Sub UpdateTotalPeriods(ByVal value As Object)
  259.         Dim editValue As PeriodsSet = TryCast(value, PeriodsSet)
  260.         TotalPeriods.Periods.Clear()
  261.         If editValue IsNot Nothing Then
  262.             TotalPeriods = editValue.GetCopy()
  263.         Else
  264.             If TypeOf value Is String Then
  265.                 TotalPeriods = PeriodsSet.Parse(CStr(value))
  266.             End If
  267.         End If
  268.     End Sub
  269.     Protected Overridable ReadOnly Property CtrlKeyPressed() As Boolean
  270.         Get
  271.             Return (System.Windows.Forms.Control.ModifierKeys And Keys.Control) <> 0
  272.         End Get
  273.     End Property
  274.     Protected Overrides Sub OnDateTimeCommit(ByVal value As Object, ByVal cleared As Boolean)
  275.     End Sub
  276.     Protected Friend Overridable Shadows ReadOnly Property Properties() As RepositoryItemDatePeriodEdit
  277.         Get
  278.             Return TryCast(MyBase.Properties, RepositoryItemDatePeriodEdit)
  279.         End Get
  280.     End Property
  281.     Protected Friend Overridable Function GetSwitchState() As Boolean
  282.         Return SwitchState
  283.     End Function
  284.     Protected Overrides Function CreateInfoArgs() As DateEditInfoArgs
  285.         Return New VistaDatePeriodEditInfoArgs(Me)
  286.     End Function
  287.     Protected Overrides Function CreatePainter() As DateEditPainter
  288.         Return New VistaDatePeriodEditPainter(Me)
  289.     End Function
  290.     Protected Overrides Function CreateSelectionState() As DateEditCalendarStateBase
  291.         Return New VistaDatePeriodEditCalendarSelectState(Me)
  292.     End Function
  293.     Public Overridable Property TotalPeriods() As PeriodsSet
  294.         Get
  295.             Return _TotalPeriods
  296.         End Get
  297.         Set(ByVal value As PeriodsSet)
  298.             _TotalPeriods = value
  299.         End Set
  300.     End Property
  301.     Protected Friend Overridable Function GetDayCells() As DayNumberCellInfoCollection
  302.         Return Calendars(0).DayCells
  303.     End Function
  304.     Protected Overrides Sub OnMoveVertical(ByVal dir As Integer)
  305.     End Sub
  306.     Protected Overrides Sub OnMoveHorizontal(ByVal dir As Integer)
  307.     End Sub
  308.     Protected Overrides Sub SetViewCore(ByVal v As DateEditCalendarViewType)
  309.     End Sub
  310.     Public Overrides Property View() As DateEditCalendarViewType
  311.         Get
  312.             Return ConvertViewLevelToView(ViewLevel)
  313.         End Get
  314.         Set(ByVal value As DateEditCalendarViewType)
  315.         End Set
  316.     End Property
  317.     Protected Overrides Sub SetSelection(ByVal [date] As DateTime)
  318.     End Sub
  319.     Protected Overloads Overrides Sub SetSelectionRange(ByVal [date] As DateTime)
  320.     End Sub
  321.     Public Overridable Property ViewLevel() As ViewLevel
  322.         Get
  323.             Return _ViewLevel
  324.         End Get
  325.         Set(ByVal value As ViewLevel)
  326.             Dim newValue As ViewLevel = GetNewLevel(value, ViewLevel)
  327.             Dim oldValue As ViewLevel = ViewLevel
  328.             If oldValue = newValue Then
  329.                 Return
  330.             End If
  331.             Dim oldView, newView As DateEditCalendarViewType
  332.             If oldValue = ViewLevel.Days AndAlso newValue = ViewLevel.Weeks Then
  333.                 oldView = DateEditCalendarViewType.MonthInfo
  334.                 newView = DateEditCalendarViewType.YearInfo
  335.             Else
  336.                 oldView = ConvertViewLevelToView(oldValue)
  337.                 newView = ConvertViewLevelToView(newValue)
  338.             End If
  339.             OnViewChanging(oldView, newView)
  340.             _ViewLevel = newValue
  341.             OnViewChanged(oldView, newView)
  342.         End Set
  343.     End Property
  344.     Protected Overridable Function GetNewLevel(ByVal newLevel As ViewLevel, ByVal currentLevel As ViewLevel) As ViewLevel
  345.         Dim lowLevel As ViewLevel = Properties.OptionsSelection.LowLevel
  346.         Dim highLevel As ViewLevel = Properties.OptionsSelection.HightLevel
  347.         If (Not Properties.OptionsSelection.ShowWeekLevel) Then
  348.             If lowLevel = ViewLevel.Weeks Then
  349.                 lowLevel = ViewLevel.Months
  350.             End If
  351.             If highLevel = ViewLevel.Weeks Then
  352.                 highLevel = ViewLevel.Days
  353.             End If
  354.         End If
  355.         If lowLevel > highLevel Then
  356.             Return currentLevel
  357.         End If
  358.         If newLevel < lowLevel Then
  359.             Return lowLevel
  360.         End If
  361.         If newLevel > highLevel Then
  362.             Return highLevel
  363.         End If
  364.         Return newLevel
  365.     End Function
  366.     Public Overridable Sub ViewLevelUp()
  367.         If ViewLevel = ViewLevel.Days Then
  368.             If Properties.OptionsSelection.ShowWeekLevel Then
  369.                 ViewLevel = ViewLevel.Weeks
  370.             Else
  371.                 ViewLevel = ViewLevel.Months
  372.             End If
  373.         ElseIf ViewLevel = ViewLevel.Weeks Then
  374.             ViewLevel = ViewLevel.Months
  375.         Else
  376.             ViewLevel = ViewLevel.Years
  377.         End If
  378.     End Sub
  379.     Public Overridable Sub ViewLevelDown()
  380.         If ViewLevel = ViewLevel.Years Then
  381.             ViewLevel = ViewLevel.Months
  382.         ElseIf ViewLevel = ViewLevel.Months Then
  383.             If Properties.OptionsSelection.ShowWeekLevel Then
  384.                 ViewLevel = ViewLevel.Weeks
  385.             Else
  386.                 ViewLevel = ViewLevel.Days
  387.             End If
  388.         Else
  389.             ViewLevel = ViewLevel.Days
  390.         End If
  391.     End Sub
  392.     Protected Overridable Function ConvertViewLevelToView(ByVal level As ViewLevel) As DateEditCalendarViewType
  393.         If level = ViewLevel.Days Then
  394.             Return DateEditCalendarViewType.MonthInfo
  395.         End If
  396.         If level = ViewLevel.Weeks Then
  397.             Return DateEditCalendarViewType.MonthInfo
  398.         End If
  399.         If level = ViewLevel.Months Then
  400.             Return DateEditCalendarViewType.YearInfo
  401.         End If
  402.         If level = ViewLevel.Years Then
  403.             Return DateEditCalendarViewType.YearsInfo
  404.         End If
  405.         Return DateEditCalendarViewType.YearsInfo
  406.     End Function
  407.     Protected Overridable Sub MarkSelectedDay()
  408.         If Selection.Count = 0 Then
  409.             Return
  410.         End If
  411.         MarkPeriod(Selection(0), Selection(1))
  412.     End Sub
  413.     Protected Overridable Sub MarkPeriod(ByVal begin As DateTime, ByVal [end] As DateTime)
  414.         If Properties.OptionsSelection.MultiselectBehaviour = MultiselectBehaviour.Merging Then
  415.             TotalPeriods.MergeWith(begin, [end])
  416.         ElseIf Properties.OptionsSelection.MultiselectBehaviour = MultiselectBehaviour.Intersection Then
  417.             TotalPeriods.IntersectWith(begin, [end])
  418.         ElseIf Properties.OptionsSelection.MultiselectBehaviour = MultiselectBehaviour.Disabled Then
  419.             If (Not TotalPeriods.ContainPeriod(begin, [end])) Then
  420.                 TotalPeriods.Periods.Clear()
  421.             End If
  422.             TotalPeriods.IntersectWith(begin, [end])
  423.         End If
  424.         UpdateSelection()
  425.         Selection.Clear()
  426.     End Sub
  427.     Protected Friend Overridable Sub UpdateSelection()
  428.         UpdateExistingCellsState()
  429.         Invalidate()
  430.     End Sub
  431.     Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
  432.         MyBase.OnMouseDown(e)
  433.         Dim hit As CalendarHitInfo = GetHitInfo(e)
  434.         _TotalPeriodsCopy = _TotalPeriods.GetCopy()
  435.         If (Not CtrlKeyPressed) Then
  436.             If (hit.InfoType = CalendarHitInfoType.Item) OrElse hit.InfoType = CalendarHitInfoType.WeekNumber OrElse hit.InfoType = CalendarHitInfoType.Unknown Then
  437.                 TotalPeriods.Periods.Clear()
  438.             End If
  439.         End If
  440.     End Sub
  441.     Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
  442.         _AllowMark = True
  443.         MyBase.OnMouseUp(e)
  444.         If (Not _AllowMark) Then
  445.             Return
  446.         End If
  447.         MarkSelectedDay()
  448.     End Sub
  449.     Protected Overrides Sub OnItemClick(ByVal hitInfo As CalendarHitInfo)
  450.         Dim cell As DayNumberCellInfo = TryCast(hitInfo.HitObject, DayNumberCellInfo)
  451.         If cell IsNot Nothing Then
  452.             ChangeDateOnItemClick(cell)
  453.             If ViewLevel = Properties.OptionsSelection.LowLevel OrElse (CtrlKeyPressed AndAlso Properties.OptionsSelection.MultiselectBehaviour <> MultiselectBehaviour.Disabled) Then
  454.                 MarkItemOnClick(cell)
  455.             Else
  456.                 TotalPeriods = _TotalPeriodsCopy.GetCopy()
  457.                 ViewLevelDown()
  458.             End If
  459.         End If
  460.     End Sub
  461.     Protected Overridable Sub MarkItemOnClick(ByVal cell As DayNumberCellInfo)
  462.         Dim begin As DateTime = CalcPeriodBeginDateTime(cell.Date)
  463.         If ViewLevel = ViewLevel.Days Then
  464.             MarkPeriod(begin, CalcPeriodEndDateTime(begin, ViewLevel))
  465.         ElseIf ViewLevel = ViewLevel.Weeks Then
  466.             MarkPeriod(begin, CalcPeriodEndDateTime(begin, ViewLevel))
  467.         ElseIf ViewLevel = ViewLevel.Months Then
  468.             MarkPeriod(begin, CalcPeriodEndDateTime(begin, ViewLevel))
  469.         ElseIf ViewLevel = ViewLevel.Years Then
  470.             MarkPeriod(begin, CalcPeriodEndDateTime(begin, ViewLevel))
  471.         End If
  472.     End Sub
  473.     Protected Overridable Sub ChangeDateOnItemClick(ByVal cell As DayNumberCellInfo)
  474.         If _ViewLevel = ViewLevel.Weeks Then
  475.             Return
  476.         End If
  477.         Dim maxDate As DateTime = DateTime
  478.         If cell.Date.Month <> DateTime.Month Then
  479.             maxDate = cell.Date
  480.         Else
  481.             maxDate = CalcPeriodEndDateTime(cell.Date, ViewLevel)
  482.         End If
  483.         If _ViewLevel < ViewLevel.Months Then
  484.             If DateTime.Month < maxDate.Month Then
  485.                 If DateTime.Year = maxDate.Year Then
  486.                     OnRightArrowClick()
  487.                 Else
  488.                     OnLeftArrowClick()
  489.                 End If
  490.             ElseIf DateTime.Month > maxDate.Month Then
  491.                 If DateTime.Year = maxDate.Year Then
  492.                     OnLeftArrowClick()
  493.                 Else
  494.                     OnRightArrowClick()
  495.                 End If
  496.             End If
  497.             Return
  498.         End If
  499.         If ViewLevel = ViewLevel.Days Then
  500.             DateTime = New DateTime(cell.Date.Year, cell.Date.Month, CorrectDay(DateTime.Year, cell.Date.Month, cell.Date.Day), 0, 0, 0)
  501.         ElseIf ViewLevel = ViewLevel.Weeks Then
  502.             DateTime = New DateTime(cell.Date.Year, cell.Date.Month, CorrectDay(DateTime.Year, cell.Date.Month, DateTime.Day), 0, 0, 0)
  503.         ElseIf ViewLevel = ViewLevel.Months Then
  504.             DateTime = New DateTime(DateTime.Year, cell.Date.Month, CorrectDay(DateTime.Year, cell.Date.Month, DateTime.Day), 0, 0, 0)
  505.         ElseIf ViewLevel = ViewLevel.Years Then
  506.             DateTime = New DateTime(cell.Date.Year, DateTime.Month, CorrectDay(cell.Date.Year, DateTime.Month, DateTime.Day), 0, 0, 0)
  507.         End If
  508.     End Sub
  509.     Protected Overrides Sub ProcessClick(ByVal hit As CalendarHitInfo)
  510.         _AllowMark = False
  511.         MyBase.ProcessClick(hit)
  512.         If hit.InfoType = CalendarHitInfoType.WeekNumber Then
  513.             onWeekNuberClick(hit)
  514.         End If
  515.     End Sub
  516.     Protected Overrides Sub IncView()
  517.         ViewLevelUp()
  518.     End Sub
  519.     Protected Overrides Sub DecView()
  520.         ViewLevelDown()
  521.     End Sub
  522.     Protected Overridable Sub onWeekNuberClick(ByVal hit As CalendarHitInfo)
  523.         Dim week As DayNumberCellInfo = TryCast(hit.HitObject, DayNumberCellInfo)
  524.         If week IsNot Nothing AndAlso Properties.OptionsSelection.MultiselectBehaviour <> MultiselectBehaviour.Disabled Then
  525.             MarkPeriod(week.Date, week.Date.AddDays(7).AddSeconds(-1))
  526.         End If
  527.     End Sub
  528.     Protected Overrides Sub OnClearClick()
  529.         TotalPeriods.Periods.Clear()
  530.         UpdateExistingCellsState()
  531.         Invalidate()
  532.     End Sub
  533.     Protected Overrides Sub OnCancelClick()
  534.         Properties.OwnerEdit.CancelPopup()
  535.     End Sub
  536.     Public Overridable Function CalcPeriodBeginDateTime(ByVal beginDate As DateTime) As DateTime
  537.         Return beginDate.Date
  538.     End Function
  539.     Public Overridable Function CalcPeriodEndDateTime(ByVal beginDate As DateTime, ByVal level As ViewLevel) As DateTime
  540.         Dim endDate As DateTime = beginDate
  541.         If level = ViewLevel.Days Then
  542.             endDate = endDate.AddDays(1)
  543.             endDate = endDate.AddSeconds(-1)
  544.         ElseIf level = ViewLevel.Weeks Then
  545.             endDate = endDate.AddDays(7)
  546.             endDate = endDate.AddSeconds(-1)
  547.         ElseIf level = ViewLevel.Months Then
  548.             endDate = endDate.AddMonths(1)
  549.             endDate = endDate.AddSeconds(-1)
  550.         ElseIf level = ViewLevel.Years Then
  551.             endDate = endDate.AddYears(1)
  552.             endDate = endDate.AddSeconds(-1)
  553.         End If
  554.         Return endDate
  555.     End Function
  556.     Protected Overrides Function GetStartSelectionByState(ByVal [date] As DateTime) As DateTime
  557.         If ViewLevel = ViewLevel.Weeks Then
  558.             Return GetFirstDayOfTheWeek([date])
  559.         End If
  560.         Return MyBase.GetStartSelectionByState([date])
  561.     End Function
  562.     Protected Overrides Function GetEndSelectionByState(ByVal dt As DateTime) As DateTime
  563.         If ViewLevel = ViewLevel.Weeks Then
  564.             Return GetLastDayOfTheWeek(dt)
  565.         End If
  566.         Return MyBase.GetEndSelectionByState(dt)
  567.     End Function
  568.     Protected Overridable Function GetFirstDayOfTheWeek(ByVal [date] As DateTime) As DateTime
  569.         Dim dt As New DateTime([date].Year, [date].Month, [date].Day, 0, 0, 0)
  570.         Do While dt.DayOfWeek <> FirstDayOfWeek
  571.             dt = dt.AddDays(-1)
  572.         Loop
  573.         Return dt
  574.     End Function
  575.     Protected Overridable Function GetLastDayOfTheWeek(ByVal [date] As DateTime) As DateTime
  576.         Dim dt As DateTime = GetFirstDayOfTheWeek([date])
  577.         dt = dt.AddDays(7).AddSeconds(-1)
  578.         Return dt
  579.     End Function
  580. End Class
  581. Public Class VistaDatePeriodEditInfoArgs
  582.     Inherits VistaDateEditInfoArgs
  583.     Public Sub New(ByVal calendar As VistaDatePeriodEditCalendar)
  584.         MyBase.New(calendar)
  585.     End Sub
  586.     Protected Overrides Function IsMultiselectDateSelected(ByVal cell As DayNumberCellInfo) As Boolean
  587.         Dim selected As Boolean = MyBase.IsMultiselectDateSelected(cell)
  588.         Dim patchCell As CustomDayNumberCellInfo = TryCast(cell, CustomDayNumberCellInfo)
  589.         If patchCell IsNot Nothing Then
  590.             Dim endDate As DateTime = Calendar.CalcPeriodEndDateTime(cell.Date, Calendar.ViewLevel)
  591.             patchCell.Marked = Calendar.TotalPeriods.ContainPeriod(cell.Date, endDate)
  592.             patchCell.ContainMark = Calendar.TotalPeriods.ContainPartOfPeriod(cell.Date, endDate)
  593.             If selected Then
  594.                 If Calendar.Properties.OptionsSelection.MultiselectBehaviour = MultiselectBehaviour.Merging OrElse (Calendar.Properties.OptionsSelection.MultiselectBehaviour = MultiselectBehaviour.Intersection AndAlso patchCell.Marked = True) Then
  595.                     patchCell.ContainMark = False
  596.                 End If
  597.                 If patchCell.Marked AndAlso Calendar.Properties.OptionsSelection.MultiselectBehaviour = MultiselectBehaviour.Intersection Then
  598.                     selected = False
  599.                 End If
  600.                 patchCell.Marked = False
  601.             End If
  602.         End If
  603.         Return selected
  604.     End Function
  605.     Protected Overrides Function IsDateActive(ByVal cell As DayNumberCellInfo) As Boolean
  606.         If Calendar.ViewLevel = ViewLevel.Weeks Then
  607.             Return True
  608.         End If
  609.         Return MyBase.IsDateActive(cell)
  610.     End Function
  611.     Protected Overloads Overrides Sub CalcItemsInfo()
  612.         If Calendar.ViewLevel = ViewLevel.Weeks Then
  613.             CalcWeekItemsInfo()
  614.         Else
  615.             MyBase.CalcItemsInfo()
  616.         End If
  617.     End Sub
  618.     Protected Overridable Sub CalcWeekItemsInfo()
  619.         DayCells.Clear()
  620.         WeekCells.Clear()
  621.         Dim rect As New Rectangle(New Point(DateClientRect.X + DistanceFromLeftToCell, DateClientRect.Y), New Size((DateClientRect.Width - 4) / 2, DateClientRect.Height \ 3))
  622.         Dim currInfo As DayNumberCellInfo
  623.         For row As Integer = 0 To 2
  624.             For col As Integer = 0 To 1
  625.                 currInfo = CreateWeekCellInfo(row, col)
  626.                 If currInfo IsNot Nothing Then
  627.                     currInfo.SetAppearance(Appearance)
  628.                     currInfo.TextBounds = CalcCellTextRect(currInfo.Text, rect)
  629.                     currInfo.Bounds = rect
  630.                     DayCells.Add(currInfo)
  631.                 End If
  632.                 rect.Offset(rect.Width, 0)
  633.             Next col
  634.             rect.X = DateClientRect.X + DistanceFromLeftToCell
  635.             rect.Offset(0, rect.Height)
  636.         Next row
  637.         UpdateExistingCellsState()
  638.     End Sub
  639.     Protected Overridable Function CreateWeekCellInfo(ByVal row As Integer, ByVal col As Integer) As DayNumberCellInfo
  640.         Dim currInfo As DayNumberCellInfo
  641.         Dim dt As DateTime = FirstVisibleDate.AddDays(14 * row + 7 * col)
  642.         currInfo = New CustomDayNumberCellInfo(dt)
  643.         Dim endDay As DateTime = currInfo.Date.AddDays(6)
  644.         Dim dateSeparator As String = " "
  645.         currInfo.Text = Calendar.DateFormat.GetAbbreviatedMonthName(currInfo.Date.Month) & dateSeparator & currInfo.Date.Day & " - " & Calendar.DateFormat.GetAbbreviatedMonthName(endDay.Month) & dateSeparator & endDay.Day
  646.         Return currInfo
  647.     End Function
  648.     Public Overridable Shadows ReadOnly Property Calendar() As VistaDatePeriodEditCalendar
  649.         Get
  650.             Return TryCast(MyBase.Calendar, VistaDatePeriodEditCalendar)
  651.         End Get
  652.     End Property
  653.     Protected Overrides Function CreateDayCell(ByVal dt As DateTime) As DayNumberCellInfo
  654.         Return New CustomDayNumberCellInfo(dt)
  655.     End Function
  656.     Protected Overrides Function CreateMonthCellInfo(ByVal row As Integer, ByVal col As Integer) As DayNumberCellInfo
  657.         Dim oldInfo As DayNumberCellInfo
  658.         oldInfo = MyBase.CreateMonthCellInfo(row, col)
  659.         If oldInfo Is Nothing Then
  660.             Return oldInfo
  661.         End If
  662.         Dim patchedInfo As New CustomDayNumberCellInfo(oldInfo.Date)
  663.         patchedInfo.Text = oldInfo.Text
  664.         Return patchedInfo
  665.     End Function
  666.     Protected Overrides Function CreateYearCellInfo(ByVal row As Integer, ByVal col As Integer) As DayNumberCellInfo
  667.         Dim oldInfo As DayNumberCellInfo
  668.         oldInfo = MyBase.CreateYearCellInfo(row, col)
  669.         If oldInfo Is Nothing Then
  670.             Return oldInfo
  671.         End If
  672.         Dim patchedInfo As New CustomDayNumberCellInfo(oldInfo.Date)
  673.         patchedInfo.Text = oldInfo.Text
  674.         Return patchedInfo
  675.     End Function
  676.     Public Overrides Function GetHitInfo(ByVal e As MouseEventArgs) As CalendarHitInfo
  677.         Dim baseHitInfo As CalendarHitInfo = MyBase.GetHitInfo(e)
  678.         If baseHitInfo.InfoType <> CalendarHitInfoType.Unknown Then
  679.             Return baseHitInfo
  680.         End If
  681.         If OkButtonRect.Contains(e.Location) Then
  682.             baseHitInfo.InfoType = CalendarHitInfoType.Ok
  683.             baseHitInfo.Bounds = OkButtonRect
  684.         ElseIf CancelButtonRect.Contains(e.Location) Then
  685.             baseHitInfo.InfoType = CalendarHitInfoType.Cancel
  686.             baseHitInfo.Bounds = CancelButtonRect
  687.         End If
  688.         If ShowWeekNumbers Then
  689.             For i As Integer = 0 To WeekCells.Count - 1
  690.                 If WeekCells(i).Bounds.Contains(e.Location) Then
  691.                     Dim [date] As New DateTime(DayCells(0).Date.Year, DayCells(0).Date.Month, DayCells(0).Date.Day, 0, 0, 0)
  692.                     [date] = [date].AddDays(7 * i)
  693.                     Dim cell As New DayNumberCellInfo([date])
  694.                     baseHitInfo.InfoType = CalendarHitInfoType.WeekNumber
  695.                     baseHitInfo.HitObject = cell
  696.                 End If
  697.             Next i
  698.         End If
  699.         Return baseHitInfo
  700.     End Function
  701.     Protected Overrides Sub CalcHeaderInfo()
  702.         MyBase.CalcHeaderInfo()
  703.         Dim indent As Integer = GetButtonRect(Rectangle.Empty).Width \ 2
  704.         ClearRect = New Rectangle(LeftArrowInfo.Bounds.Right + indent, Content.Bottom + IndentFromDateInfoToClearText, ClearRect.Width, ClearRect.Height)
  705.         OkRect = New Rectangle(LeftArrowInfo.Bounds.Right + (RightArrowInfo.Bounds.X - LeftArrowInfo.Bounds.Right - OkRect.Width) / 2, Content.Bottom + IndentFromDateInfoToClearText, OkRect.Width, OkRect.Height)
  706.         CancelRect = New Rectangle(RightArrowInfo.Bounds.X - indent - CancelRect.Right, Content.Bottom + IndentFromDateInfoToClearText, CancelRect.Width, CancelRect.Height)
  707.         OkButtonRect = GetButtonRect(OkRect)
  708.         CancelButtonRect = GetButtonRect(CancelRect)
  709.         ClearButtonRect = GetButtonRect(ClearRect)
  710.     End Sub
  711. End Class
  712. Public Class VistaDatePeriodEditPainter
  713.     Inherits VistaDateEditPainter
  714.     Public Sub New(ByVal calendar As DateEditCalendarBase)
  715.         MyBase.New(calendar)
  716.     End Sub
  717.     Protected Overrides Sub DrawContent(ByVal info As DevExpress.XtraEditors.Calendar.CalendarObjectInfoArgs)
  718.         MyBase.DrawContent(info)
  719.     End Sub
  720.     Protected Overrides Sub DrawDayCell(ByVal info As CalendarObjectInfoArgs, ByVal cell As DayNumberCellInfo)
  721.         Dim isDrawn As Boolean = False
  722.         Dim patchCell As CustomDayNumberCellInfo = TryCast(cell, CustomDayNumberCellInfo)
  723.         If patchCell IsNot Nothing Then
  724.             isDrawn = DrawPatchedCell(info, patchCell)
  725.         End If
  726.         If (Not isDrawn) Then
  727.             MyBase.DrawDayCell(info, cell)
  728.         End If
  729.     End Sub
  730.     Protected Overridable Function DrawPatchedCell(ByVal info As CalendarObjectInfoArgs, ByVal cell As CustomDayNumberCellInfo) As Boolean
  731.         cell.Today = cell.Marked
  732.         MyBase.DrawDayCell(info, cell)
  733.         If (Not cell.Marked) Then
  734.             If cell.ContainMark Then
  735.                 MarkCellContent(info, cell)
  736.             End If
  737.         End If
  738.         Return True
  739.     End Function
  740.     Protected Overrides Sub DrawWeekdaysAbbreviation(ByVal info As CalendarObjectInfoArgs)
  741.         If (CType(info.Calendar, VistaDatePeriodEditCalendar)).ViewLevel = ViewLevel.Weeks Then
  742.             Return
  743.         End If
  744.         MyBase.DrawWeekdaysAbbreviation(info)
  745.     End Sub
  746.     Protected Overridable Sub MarkCellContent(ByVal info As CalendarObjectInfoArgs, ByVal cell As DayNumberCellInfo)
  747.         Dim width As Integer = cell.Bounds.Width \ 3, height As Integer = cell.Bounds.Height \ 3
  748.         Dim r As New Rectangle(cell.Bounds.Location, New Size(width, height))
  749.         r.Offset(width * 2, height * 2)
  750.         Dim icon As New DayNumberCellInfo(cell.Date)
  751.         icon.Today = True
  752.         icon.Bounds = r
  753.         icon.Text = String.Empty
  754.         icon.Selected = True
  755.         MyBase.DrawDayCell(info, icon)
  756.     End Sub
  757.     Protected Overrides Sub DrawHeader(ByVal info As CalendarObjectInfoArgs)
  758.         MyBase.DrawHeader(info)
  759.         Dim vdi As VistaDateEditInfoArgs = TryCast(info, VistaDateEditInfoArgs)
  760.         If vdi Is Nothing Then
  761.             Return
  762.         End If
  763.         DrawOk(vdi)
  764.         DrawCancel(vdi)
  765.     End Sub
  766. End Class
  767. Public Class VistaDatePeriodEditCalendarSelectState
  768.     Inherits VistaDateEditCalendarSelectState
  769.     Public Sub New(ByVal control As DateEditCalendarBase)
  770.         MyBase.New(control)
  771.     End Sub
  772.     Public Overridable ReadOnly Property DatePeriodCalendar() As VistaDatePeriodEditCalendar
  773.         Get
  774.             Return TryCast(VistaCalendar, VistaDatePeriodEditCalendar)
  775.         End Get
  776.     End Property
  777.     Protected Overloads Overrides Sub UpdateSelection(ByVal e As MouseEventArgs)
  778.         If DatePeriodCalendar.Properties.OptionsSelection.MultiselectBehaviour = MultiselectBehaviour.Disabled Then
  779.             Return
  780.         End If
  781.         Dim oldSelectionCount As Integer = DatePeriodCalendar.Selection.Count
  782.         MyBase.UpdateSelection(e)
  783.         If oldSelectionCount <> DatePeriodCalendar.Selection.Count AndAlso DatePeriodCalendar.Selection.Count = 0 Then
  784.             DatePeriodCalendar.UpdateSelection()
  785.         End If
  786.     End Sub
  787.     Protected Overrides ReadOnly Property ShiftKeyPressed() As Boolean
  788.         Get
  789.             Return False
  790.         End Get
  791.     End Property
  792.     Protected Overrides Sub FindMinMaxDateInRect(ByVal rect As Rectangle, ByRef minDate As DateTime, ByRef maxDate As DateTime, ByVal inverse As Boolean)
  793.         Dim down, up As Point
  794.         If inverse Then
  795.             down = New Point(rect.Left, rect.Bottom)
  796.             up = New Point(rect.Right, rect.Top)
  797.         Else
  798.             up = rect.Location
  799.             down = New Point(rect.Right, rect.Bottom)
  800.         End If
  801.         Dim minCell, maxCell As DayNumberCellInfo
  802.         minCell = GetCellByPoint(down, False)
  803.         maxCell = GetCellByPoint(up, False)
  804.         minDate = DateTime.MaxValue
  805.         maxDate = DateTime.MinValue
  806.         If minCell IsNot Nothing AndAlso maxCell IsNot Nothing Then
  807.             If maxCell IsNot minCell Then
  808.                 If minCell.Date < maxCell.Date Then
  809.                     minDate = minCell.Date
  810.                     maxDate = maxCell.Date
  811.                 Else
  812.                     maxDate = minCell.Date
  813.                     minDate = maxCell.Date
  814.                 End If
  815.             End If
  816.         End If
  817.     End Sub
  818.     Protected Overrides Function GetCellByPoint(ByVal pt As Point, ByVal nearestLeft As Boolean) As DayNumberCellInfo
  819.         For Each cell As DayNumberCellInfo In DatePeriodCalendar.GetDayCells()
  820.             If cell.Bounds.Contains(pt) Then
  821.                 Return cell
  822.             End If
  823.         Next cell
  824.         Return Nothing
  825.     End Function
  826. End Class
  827. Public Class CustomDayNumberCellInfo
  828.     Inherits DayNumberCellInfo
  829.     Private marked_Renamed As Boolean
  830.     Private containMark_Renamed As Boolean
  831.     Public Sub New(ByVal [date] As DateTime)
  832.         MyBase.New([date])
  833.         marked_Renamed = False
  834.         containMark_Renamed = False
  835.     End Sub
  836.     Public Property Marked() As Boolean
  837.         Get
  838.             Return marked_Renamed
  839.         End Get
  840.         Set(ByVal value As Boolean)
  841.             marked_Renamed = value
  842.         End Set
  843.     End Property
  844.     Public Property ContainMark() As Boolean
  845.         Get
  846.             Return containMark_Renamed
  847.         End Get
  848.         Set(ByVal value As Boolean)
  849.             containMark_Renamed = value
  850.         End Set
  851.     End Property
  852. End Class
  853. <TypeConverter(GetType(ExpandableObjectConverter))> _
  854. Public Class OptionsSelection
  855.     Private multiselectBehaviour_Renamed As MultiselectBehaviour
  856.     Private lowLevel_Renamed, highLevel, defaultLevel_Renamed As ViewLevel
  857.     Private showWeekLevel_Renamed As Boolean
  858.     Public Sub New()
  859.         multiselectBehaviour_Renamed = MultiselectBehaviour.Merging
  860.         lowLevel_Renamed = ViewLevel.Days
  861.         highLevel = ViewLevel.Years
  862.         defaultLevel_Renamed = ViewLevel.Days
  863.         showWeekLevel_Renamed = False
  864.     End Sub
  865.     <Description("Allow chose multiselection behaviour."), Category(CategoryName.Properties), DefaultValue(MultiselectBehaviour.Merging)> _
  866.     Public Property MultiselectBehaviour() As MultiselectBehaviour
  867.         Get
  868.             Return multiselectBehaviour_Renamed
  869.         End Get
  870.         Set(ByVal value As MultiselectBehaviour)
  871.             multiselectBehaviour_Renamed = value
  872.         End Set
  873.     End Property
  874.     <Description("Allow chose weather week level will be shown."), Category(CategoryName.Properties), DefaultValue(False)> _
  875.     Public Property ShowWeekLevel() As Boolean
  876.         Get
  877.             Return showWeekLevel_Renamed
  878.         End Get
  879.         Set(ByVal value As Boolean)
  880.             showWeekLevel_Renamed = value
  881.         End Set
  882.     End Property
  883.     <Description("Allow chose the lowest navigation level."), Category(CategoryName.Properties), DefaultValue(ViewLevel.Days)> _
  884.     Public Property LowLevel() As ViewLevel
  885.         Get
  886.             Return lowLevel_Renamed
  887.         End Get
  888.         Set(ByVal value As ViewLevel)
  889.             lowLevel_Renamed = value
  890.         End Set
  891.     End Property
  892.     <Description("Allow chose the highest navigation level."), Category(CategoryName.Properties), DefaultValue(ViewLevel.Years)> _
  893.     Public Property HightLevel() As ViewLevel
  894.         Get
  895.             Return highLevel
  896.         End Get
  897.         Set(ByVal value As ViewLevel)
  898.             highLevel = value
  899.         End Set
  900.     End Property
  901.     <Description("Allow chose the first shown level."), Category(CategoryName.Properties), DefaultValue(ViewLevel.Days)> _
  902.     Public Property DefaultLevel() As ViewLevel
  903.         Get
  904.             Return defaultLevel_Renamed
  905.         End Get
  906.         Set(ByVal value As ViewLevel)
  907.             defaultLevel_Renamed = value
  908.         End Set
  909.     End Property
  910. End Class
  911. Public Enum MultiselectBehaviour
  912.     Merging
  913.     Intersection
  914.     Disabled
  915. End Enum
  916. Public Enum ViewLevel
  917.     Days
  918.     Weeks
  919.     Months
  920.     Years
  921. End Enum
  922. Public Enum StoreMode
  923.     [Default]
  924.     PeriodsSet
  925.     [String]
  926. End Enum
  927. Public Class Period
  928.     Implements IComparable
  929.     Private begin_Renamed, end_Renamed As DateTime
  930.     Public Sub New(ByVal begin As DateTime, ByVal [end] As DateTime)
  931.         Me.begin_Renamed = begin.Date
  932.         Me.end_Renamed = EndOfDay([end])
  933.     End Sub
  934.     Public Sub New(ByVal [date] As DateTime)
  935.         Me.New([date], [date])
  936.     End Sub
  937.     Public Shared Function EndOfDay(ByVal [date] As DateTime) As DateTime
  938.         Return [date].Date.AddDays(1).AddSeconds(-1)
  939.     End Function
  940.     Public Shared Function BeginOfDay(ByVal [date] As DateTime) As DateTime
  941.         Return [date].Date
  942.     End Function
  943.     Public Property Begin() As DateTime
  944.         Get
  945.             Return begin_Renamed
  946.         End Get
  947.         Set(ByVal value As DateTime)
  948.             If Begin <> value Then
  949.                 begin_Renamed = value.Date
  950.             End If
  951.         End Set
  952.     End Property
  953.     Public Property [End]() As DateTime
  954.         Get
  955.             Return end_Renamed
  956.         End Get
  957.         Set(ByVal value As DateTime)
  958.             If [End] <> value Then
  959.                 end_Renamed = EndOfDay(value)
  960.             End If
  961.         End Set
  962.     End Property
  963.     Public Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
  964.         Dim dp As Period = TryCast(obj, Period)
  965.         If dp IsNot Nothing Then
  966.             Return Me.Begin.CompareTo(dp.Begin)
  967.         Else
  968.             Throw New ArgumentException("Object is not a DatePeriod")
  969.         End If
  970.     End Function
  971.     Public Overrides Function ToString() As String
  972.         If Begin.Date = [End].Date Then
  973.             Return Begin.ToString("d")
  974.         End If
  975.         Return Begin.ToString("d") & " - " & [End].ToString("d")
  976.     End Function
  977.     Public Overridable Overloads Function ToString(ByVal formatString As String) As String
  978.         If formatString = String.Empty Then
  979.             Return ToString()
  980.         End If
  981.         If Begin.Date = [End].Date Then
  982.             Return Begin.ToString(formatString)
  983.         End If
  984.         Return Begin.ToString(formatString) & " - " & [End].ToString(formatString)
  985.     End Function
  986.     Public Overridable Overloads Function ToString(ByVal format As IFormatProvider) As String
  987.         If format Is Nothing Then
  988.             Return ToString()
  989.         End If
  990.         If Begin.Date = [End].Date Then
  991.             Return Begin.ToString(format)
  992.         End If
  993.         Return Begin.ToString(format) & " - " & [End].ToString(format)
  994.     End Function
  995.     Public Shared Function Parse(ByVal str As String, ByVal format As IFormatProvider) As Period
  996.         str = str.Trim()
  997.         If str.Contains(" - ") Then
  998.             Dim success As Boolean = True
  999.             Dim periodSeparators(0) As String
  1000.             periodSeparators(0) = " - "
  1001.             Dim sides() As String = String.Format("{0}", str).Split(periodSeparators, StringSplitOptions.RemoveEmptyEntries)
  1002.             Dim dates(1) As DateTime
  1003.             Dim i As Integer = 0
  1004.             For Each dateStr As String In sides
  1005.                 If i > 1 Then
  1006.                     Continue For
  1007.                 End If
  1008.                 Dim stringDate As String = dateStr.Trim()
  1009.                 success = success AndAlso DateTime.TryParse(stringDate, format, DateTimeStyles.None, dates(i))
  1010.                 i += 1
  1011.             Next dateStr
  1012.             If success Then
  1013.                 If dates(0) <= dates(1) Then
  1014.                     Return New Period(dates(0), dates(1))
  1015.                 End If
  1016.             End If
  1017.         Else
  1018.             Dim dt As DateTime
  1019.             If DateTime.TryParse(str, format, DateTimeStyles.None, dt) Then
  1020.                 Return New Period(dt)
  1021.             End If
  1022.         End If
  1023.         Return Nothing
  1024.     End Function
  1025. End Class
  1026. Public Class PeriodsSet
  1027.     Private periods_Renamed As ArrayList
  1028.     Protected Shared ReadOnly Property DefaultSeparator() As Char
  1029.         Get
  1030.             Return ","c
  1031.         End Get
  1032.     End Property
  1033.     Protected Shared ReadOnly Property InvariantCulture() As CultureInfo
  1034.         Get
  1035.             Return New CultureInfo(String.Empty)
  1036.         End Get
  1037.     End Property
  1038.     Public Sub New()
  1039.         periods_Renamed = New ArrayList()
  1040.     End Sub
  1041.     Default Public Property Item(ByVal index As Integer) As Period
  1042.         Get
  1043.             Return TryCast(periods_Renamed(index), Period)
  1044.         End Get
  1045.         Set(ByVal value As Period)
  1046.             periods_Renamed(index) = value
  1047.         End Set
  1048.     End Property
  1049.     Protected Overridable Function Add(ByVal value As Period) As Integer
  1050.         For Each dp As Period In periods_Renamed
  1051.             If dp.Begin.Date = value.End.Date.AddDays(1) Then
  1052.                 dp.Begin = value.Begin
  1053.                 Return periods_Renamed.IndexOf(dp)
  1054.             End If
  1055.             If dp.End.Date = value.Begin.Date.AddDays(-1) Then
  1056.                 dp.End = value.End
  1057.                 Return periods_Renamed.IndexOf(dp)
  1058.             End If
  1059.         Next dp
  1060.         periods_Renamed.Add(value)
  1061.         periods_Renamed.Sort()
  1062.         Return periods_Renamed.IndexOf(value)
  1063.     End Function
  1064.     Public ReadOnly Property Periods() As ArrayList
  1065.         Get
  1066.             Return periods_Renamed
  1067.         End Get
  1068.     End Property
  1069.     Public Sub IntersectWith(ByVal begin As DateTime, ByVal [end] As DateTime)
  1070.         If begin.Date > [end].Date Then
  1071.             Return
  1072.         End If
  1073.         begin = Period.BeginOfDay(begin)
  1074.         [end] = Period.EndOfDay([end])
  1075.         Dim i As Integer = 0
  1076.         Do While i < Periods.Count
  1077.             If begin <= Me(i).Begin AndAlso [end] >= Me(i).End Then
  1078.                 Dim oldBegin As DateTime = Me(i).Begin, oldEnd As DateTime = Me(i).End
  1079.                 periods_Renamed.RemoveAt(i)
  1080.                 IntersectWith(begin, oldBegin.AddSeconds(-1))
  1081.                 IntersectWith(oldEnd.AddSeconds(1), [end])
  1082.                 Return
  1083.             End If
  1084.             i += 1
  1085.         Loop
  1086.         For Each dp As Period In periods_Renamed
  1087.             If begin > dp.Begin AndAlso [end] < dp.End Then
  1088.                 Dim periodEnd As DateTime = dp.End
  1089.                 dp.End = begin.AddSeconds(-1)
  1090.                 IntersectWith([end].AddSeconds(1), periodEnd)
  1091.                 Return
  1092.             End If
  1093.         Next dp
  1094.         For i_1 As Integer = 0 To Periods.Count - 1
  1095.             If begin = Me(i_1).Begin Then
  1096.                 Me(i_1).Begin = [end].AddSeconds(1)
  1097.                 Return
  1098.             End If
  1099.             If [end] = Me(i_1).End Then
  1100.                 Me(i_1).End = begin.AddSeconds(-1)
  1101.                 Return
  1102.             End If
  1103.         Next i_1
  1104.         For i_2 As Integer = 0 To Periods.Count - 1
  1105.             If begin >= Me(i_2).Begin AndAlso begin <= Me(i_2).End Then
  1106.                 Dim oldEnd As DateTime = Me(i_2).End
  1107.                 Me(i_2).End = begin.AddSeconds(-1)
  1108.                 begin = oldEnd.AddSeconds(1)
  1109.             End If
  1110.             If [end] >= Me(i_2).Begin AndAlso [end] <= Me(i_2).End Then
  1111.                 Dim oldBegin As DateTime = Me(i_2).Begin
  1112.                 Me(i_2).Begin = [end].AddSeconds(1)
  1113.                 [end] = oldBegin.AddSeconds(-1)
  1114.             End If
  1115.         Next i_2
  1116.         Add(New Period(begin, [end]))
  1117.     End Sub
  1118.     Public Sub MergeWith(ByVal begin As DateTime, ByVal [end] As DateTime)
  1119.         If begin.Date > [end].Date Then
  1120.             Return
  1121.         End If
  1122.         begin = Period.BeginOfDay(begin)
  1123.         [end] = Period.EndOfDay([end])
  1124.         If ContainPeriod(begin, [end]) Then
  1125.             Return
  1126.         End If
  1127.         For i As Integer = 0 To Periods.Count - 1
  1128.             If begin <= Me(i).Begin AndAlso [end] >= Me(i).End Then
  1129.                 periods_Renamed.RemoveAt(i)
  1130.                 MergeWith(begin, [end])
  1131.                 Return
  1132.             End If
  1133.         Next i
  1134.         Dim beginPeriod As Period = Nothing, endPeriod As Period = Nothing
  1135.         For i_1 As Integer = 0 To Periods.Count - 1
  1136.             If begin >= Me(i_1).Begin AndAlso begin <= Me(i_1).End Then
  1137.                 beginPeriod = Me(i_1)
  1138.             End If
  1139.             If [end] >= Me(i_1).Begin AndAlso [end] <= Me(i_1).End Then
  1140.                 endPeriod = Me(i_1)
  1141.             End If
  1142.         Next i_1
  1143.         If beginPeriod IsNot Nothing AndAlso endPeriod IsNot Nothing Then
  1144.             beginPeriod.End = endPeriod.End
  1145.             periods_Renamed.Remove(endPeriod)
  1146.             Return
  1147.         End If
  1148.         If beginPeriod IsNot Nothing Then
  1149.             beginPeriod.End = [end]
  1150.             Return
  1151.         End If
  1152.         If endPeriod IsNot Nothing Then
  1153.             endPeriod.Begin = begin
  1154.             Return
  1155.         End If
  1156.         Add(New Period(begin, [end]))
  1157.     End Sub
  1158.     Public Function ContainPeriod(ByVal item As Object) As Boolean
  1159.         Dim dp As Period = TryCast(item, Period)
  1160.         If dp IsNot Nothing Then
  1161.             Return ContainPeriod(dp.Begin, dp.End)
  1162.         End If
  1163.         Return False
  1164.     End Function
  1165.     Public Overridable Function ContainPeriod(ByVal begin As DateTime, ByVal [end] As DateTime) As Boolean
  1166.         For i As Integer = 0 To Periods.Count - 1
  1167.             If begin >= Me(i).Begin AndAlso [end] <= Me(i).End Then
  1168.                 Return True
  1169.             End If
  1170.         Next i
  1171.         Return False
  1172.     End Function
  1173.     Public Overridable Function ContainPartOfPeriod(ByVal begin As DateTime, ByVal [end] As DateTime) As Boolean
  1174.         If ContainPeriod(begin, [end]) Then
  1175.             Return True
  1176.         End If
  1177.         For i As Integer = 0 To Periods.Count - 1
  1178.             If (begin <= Me(i).Begin AndAlso [end] >= Me(i).Begin) OrElse (begin <= Me(i).End AndAlso [end] >= Me(i).End) Then
  1179.                 Return True
  1180.             End If
  1181.         Next i
  1182.         Return False
  1183.     End Function
  1184.     Public Overridable Function GetCopy() As PeriodsSet
  1185.         Dim result As New PeriodsSet()
  1186.         For Each period As Period In periods_Renamed
  1187.             result.Add(period)
  1188.         Next period
  1189.         Return result
  1190.     End Function
  1191.     Public Overridable Overloads Function ToString(ByVal format As IFormatProvider, ByVal separator As Char) As String
  1192.         Dim str As String = String.Empty
  1193.         For Each dp As Period In periods_Renamed
  1194.             str = str & dp.ToString(format) + separator.ToString() & " "
  1195.         Next dp
  1196.         If str.Length > 2 Then
  1197.             str = str.Remove(str.Length - 2)
  1198.         End If
  1199.         Return str
  1200.     End Function
  1201.     Public Overridable Overloads Function ToString(ByVal formatString As String, ByVal separator As Char) As String
  1202.         Dim str As String = String.Empty
  1203.         For Each dp As Period In periods_Renamed
  1204.             str = str & dp.ToString(formatString) + separator.ToString() & " "
  1205.         Next dp
  1206.         If str.Length > 2 Then
  1207.             str = str.Remove(str.Length - 2)
  1208.         End If
  1209.         Return str
  1210.     End Function
  1211.     Public Overrides Function ToString() As String
  1212.         Return ToString(InvariantCulture, DefaultSeparator)
  1213.     End Function
  1214.     Public Shared Function Parse(ByVal str As String) As PeriodsSet
  1215.         Return Parse(str, InvariantCulture, DefaultSeparator)
  1216.     End Function
  1217.     Public Shared Function Parse(ByVal str As String, ByVal format As IFormatProvider, ByVal separatorChar As Char) As PeriodsSet
  1218.         Dim result As New PeriodsSet()
  1219.         Dim periodSet() As String = String.Format("{0}", str).Split(separatorChar)
  1220.         For Each periodStr As String In periodSet
  1221.             Dim dp As Period = Period.Parse(periodStr, format)
  1222.             If dp IsNot Nothing Then
  1223.                 result.Add(dp)
  1224.             End If
  1225.         Next periodStr
  1226.         Return result
  1227.     End Function
  1228. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement