is_weak_ref is now weak_ref
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Field / .ToDo / TimeRange.pm
CommitLineData
ddccc6a2 1package Reaction::UI::ViewPort::Field::TimeRange;
2
3use Reaction::Class;
4use Reaction::Types::DateTime;
5use DateTime;
6use DateTime::SpanSet;
7use Time::ParseDate ();
8
81393881 9use namespace::clean -except => [ qw(meta) ];
10extends 'Reaction::UI::ViewPort::InterfaceModel::Field';
ddccc6a2 11
ddccc6a2 12
ddccc6a2 13
81393881 14has '+value' => (isa => 'DateTime::SpanSet');
ddccc6a2 15
81393881 16#has '+layout' => (default => 'timerange');
ddccc6a2 17
81393881 18has value_string =>
19 (isa => 'Str', is => 'rw', lazy_fail => 1, trigger_adopt('value_string'));
ddccc6a2 20
81393881 21has delete_label => (
22 isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' },
23);
ddccc6a2 24
81393881 25has parent => (
26 isa => 'Reaction::UI::ViewPort::TimeRangeCollection',
27 is => 'ro',
28 required => 1,
aa2b2a70 29 weak_ref => 1
81393881 30);
31sub _build_value_string {
32 my $self = shift;
33 #return '' unless $self->has_value;
34 #return $self->value_string;
35};
36sub value_array {
37 my $self = shift;
38 return split(',', $self->value_string);
39};
40sub adopt_value_string {
41 my ($self) = @_;
42 my @values = $self->value_array;
43 for my $idx (0 .. 3) { # last value is repeat
44 if (length $values[$idx]) {
45 my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1);
46 $values[$idx] = DateTime->from_epoch( epoch => $epoch );
ddccc6a2 47 }
81393881 48 }
49 $self->value($self->range_to_spanset(@values));
50};
51sub range_to_spanset {
52 my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_;
53 my $spanset = DateTime::SpanSet->empty_set;
54 if (!$pattern || $pattern eq 'none') {
55 my $span = DateTime::Span->from_datetimes(
56 start => $time_from, end => $time_to
57 );
58 $spanset = $spanset->union( $span );
59 } else {
60 my $duration = $time_to - $time_from;
61 my %args = ( days => $time_from->day + 2,
62 hours => $time_from->hour,
63 minutes => $time_from->minute,
64 seconds => $time_from->second );
65
66 delete $args{'days'} if ($pattern eq 'daily');
67 delete @args{qw/hours days/} if ($pattern eq 'hourly');
68 $args{'days'} = $time_from->day if ($pattern eq 'monthly');
69 my $start_set = DateTime::Event::Recurrence->$pattern( %args );
70 my $iter = $start_set->iterator( start => $repeat_from, end => $repeat_to );
71 while ( my $dt = $iter->next ) {
72 my $endtime = $dt + $duration;
73 my $new_span = DateTime::Span->from_datetimes(
74 start => $dt,
75 end => $endtime
76 );
77 $spanset = $spanset->union( $new_span );
ddccc6a2 78 }
81393881 79 }
80 return $spanset;
81};
82sub delete {
83 my ($self) = @_;
84 $self->parent->remove_range_vp($self);
85};
ddccc6a2 86
81393881 87override accept_events => sub { ('value_string', 'delete', super()) };
ddccc6a2 88
81393881 89__PACKAGE__->meta->make_immutable;
ddccc6a2 90
ddccc6a2 91
921;
93
94=head1 NAME
95
96Reaction::UI::ViewPort::Field::TimeRange
97
98=head1 SYNOPSIS
99
100=head1 DESCRIPTION
101
102=head1 METHODS
103
104=head2 value
105
106 Accessor for a L<DateTime::SpanSet> object.
107
108=head2 value_string
109
110 Returns: Encoded range string representing the value.
111
112=head2 value_array
113
114 Returns: Arrayref of the elements of C<value_string>.
115
116=head2 parent
117
118 L<Reaction::UI::ViewPort::TimeRangeCollection> object.
119
120=head2 range_to_spanset
121
122 Arguments: $self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern
123 where $time_from, $time_to, $repeat_from, $repeat_to are L<DateTime>
124 objects, and $pattern is a L<DateTime::Event::Recurrence> method name
125
126 Returns: $spanset
127
128=head2 delete
129
130 Removes TimeRange from C<parent> collection.
131
132=head2 delete_label
133
134 Label for the delete option. Default: 'Delete'.
135
136=head1 SEE ALSO
137
138=head2 L<Reaction::UI::ViewPort::Field>
139
140=head2 L<Reaction::UI::ViewPort::TimeRangeCollection>
141
142=head1 AUTHORS
143
144See L<Reaction::Class> for authors.
145
146=head1 LICENSE
147
148See L<Reaction::Class> for the license.
149
150=cut