mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-07-07 20:06:39 +02:00
Let Interval inherit from Range
- Remove 1 level of indirection - Remove public field Interval::range (instead use interval directly)
This commit is contained in:
parent
0d33700336
commit
9dd106116c
30 changed files with 289 additions and 280 deletions
105
src/data.cpp
105
src/data.cpp
|
@ -117,7 +117,7 @@ Interval getFilter (const CLI& cli)
|
|||
if (args.size () == 1 &&
|
||||
args[0] == "<date>")
|
||||
{
|
||||
filter.range = {Datetime (start), 0};
|
||||
filter.setRange ({Datetime (start), 0});
|
||||
}
|
||||
|
||||
// from <date>
|
||||
|
@ -125,7 +125,7 @@ Interval getFilter (const CLI& cli)
|
|||
args[0] == "from" &&
|
||||
args[1] == "<date>")
|
||||
{
|
||||
filter.range = {Datetime (start), 0};
|
||||
filter.setRange ({Datetime (start), 0});
|
||||
}
|
||||
|
||||
// <date> to/- <date>
|
||||
|
@ -134,7 +134,7 @@ Interval getFilter (const CLI& cli)
|
|||
(args[1] == "to" || args[1] == "-") &&
|
||||
args[2] == "<date>")
|
||||
{
|
||||
filter.range = {Datetime (start), Datetime (end)};
|
||||
filter.setRange ({Datetime (start), Datetime (end)});
|
||||
}
|
||||
|
||||
// from <date> to/- <date>
|
||||
|
@ -144,7 +144,7 @@ Interval getFilter (const CLI& cli)
|
|||
(args[2] == "to" || args[2] == "-") &&
|
||||
args[3] == "<date>")
|
||||
{
|
||||
filter.range = {Datetime (start), Datetime (end)};
|
||||
filter.setRange ({Datetime (start), Datetime (end)});
|
||||
}
|
||||
|
||||
// <date> for <duration>
|
||||
|
@ -153,7 +153,7 @@ Interval getFilter (const CLI& cli)
|
|||
args[1] == "for" &&
|
||||
args[2] == "<duration>")
|
||||
{
|
||||
filter.range = {Datetime (start), Datetime (start) + Duration (duration).toTime_t ()};
|
||||
filter.setRange ({Datetime (start), Datetime (start) + Duration (duration).toTime_t ()});
|
||||
}
|
||||
|
||||
// from <date> for <duration>
|
||||
|
@ -163,7 +163,7 @@ Interval getFilter (const CLI& cli)
|
|||
args[2] == "for" &&
|
||||
args[3] == "<duration>")
|
||||
{
|
||||
filter.range = {Datetime (start), Datetime (start) + Duration (duration).toTime_t ()};
|
||||
filter.setRange ({Datetime (start), Datetime (start) + Duration (duration).toTime_t ()});
|
||||
}
|
||||
|
||||
// <duration> before <date>
|
||||
|
@ -172,7 +172,7 @@ Interval getFilter (const CLI& cli)
|
|||
args[1] == "before" &&
|
||||
args[2] == "<date>")
|
||||
{
|
||||
filter.range = {Datetime (start) - Duration (duration).toTime_t (), Datetime (start)};
|
||||
filter.setRange ({Datetime (start) - Duration (duration).toTime_t (), Datetime (start)});
|
||||
}
|
||||
|
||||
// <duration> after <date>
|
||||
|
@ -181,7 +181,7 @@ Interval getFilter (const CLI& cli)
|
|||
args[1] == "after" &&
|
||||
args[2] == "<date>")
|
||||
{
|
||||
filter.range = {Datetime (start), Datetime (start) + Duration (duration).toTime_t ()};
|
||||
filter.setRange ({Datetime (start), Datetime (start) + Duration (duration).toTime_t ()});
|
||||
}
|
||||
|
||||
// <duration> ago
|
||||
|
@ -189,7 +189,7 @@ Interval getFilter (const CLI& cli)
|
|||
args[0] == "<duration>" &&
|
||||
args[1] == "ago")
|
||||
{
|
||||
filter.range = {now - Duration (duration).toTime_t (), 0};
|
||||
filter.setRange ({now - Duration (duration).toTime_t (), 0});
|
||||
}
|
||||
|
||||
// for <duration>
|
||||
|
@ -197,14 +197,14 @@ Interval getFilter (const CLI& cli)
|
|||
args[0] == "for" &&
|
||||
args[1] == "<duration>")
|
||||
{
|
||||
filter.range = {now - Duration (duration).toTime_t (), now};
|
||||
filter.setRange ({now - Duration (duration).toTime_t (), now});
|
||||
}
|
||||
|
||||
// <duration>
|
||||
else if (args.size () == 1 &&
|
||||
args[0] == "<duration>")
|
||||
{
|
||||
filter.range = {now - Duration (duration).toTime_t (), now};
|
||||
filter.setRange ({now - Duration (duration).toTime_t (), now});
|
||||
}
|
||||
|
||||
// Unrecognized date range construct.
|
||||
|
@ -213,10 +213,10 @@ Interval getFilter (const CLI& cli)
|
|||
throw std::string ("Unrecognized date range: '") + join (" ", args) + "'.";
|
||||
}
|
||||
|
||||
if (filter.range.start > now)
|
||||
if (filter.start > now)
|
||||
throw std::string ("Time tracking cannot be set in the future.");
|
||||
|
||||
if (filter.range.end != 0 && filter.range.start > filter.range.end)
|
||||
if (filter.end != 0 && filter.start > filter.end)
|
||||
throw std::string ("The end of a date range must be after the start.");
|
||||
|
||||
return filter;
|
||||
|
@ -359,7 +359,8 @@ std::vector <Interval> subset (
|
|||
{
|
||||
std::vector <Interval> all;
|
||||
for (auto& interval : intervals) {
|
||||
if (range.intersects (interval.range)) {
|
||||
if (range.intersects (interval))
|
||||
{
|
||||
all.push_back (interval);
|
||||
}
|
||||
}
|
||||
|
@ -376,29 +377,29 @@ std::vector <Interval> flatten (
|
|||
|
||||
std::vector <Range> enclosed;
|
||||
for (auto& e : exclusions)
|
||||
if (interval.range.encloses (e))
|
||||
if (interval.encloses (e))
|
||||
enclosed.push_back (e);
|
||||
|
||||
Datetime now;
|
||||
for (auto& result : subtractRanges ({interval.range}, enclosed))
|
||||
for (auto& result : subtractRanges ({interval}, enclosed))
|
||||
{
|
||||
Interval chunk {interval};
|
||||
chunk.range = result;
|
||||
chunk.setRange (result);
|
||||
|
||||
// Only historical data is included.
|
||||
if (chunk.range.start <= now)
|
||||
if (chunk.start <= now)
|
||||
{
|
||||
// Closed chunk ranges in the future need to be adjusted.
|
||||
if (! chunk.range.is_open () &&
|
||||
chunk.range.end > now)
|
||||
if (! chunk.is_open () &&
|
||||
chunk.end > now)
|
||||
{
|
||||
// If the interval is open, so must be chunk.
|
||||
if (interval.range.is_open ())
|
||||
chunk.range.end = {0};
|
||||
if (interval.is_open ())
|
||||
chunk.end = {0};
|
||||
|
||||
// Otherwise truncate to now.
|
||||
else
|
||||
chunk.range.end = now;
|
||||
chunk.end = now;
|
||||
}
|
||||
|
||||
all.push_back (chunk);
|
||||
|
@ -496,17 +497,17 @@ Range outerRange (const std::vector <Interval>& intervals)
|
|||
Range outer;
|
||||
for (auto& interval : intervals)
|
||||
{
|
||||
if (interval.range.start < outer.start || outer.start.toEpoch () == 0)
|
||||
outer.start = interval.range.start;
|
||||
if (interval.start < outer.start || outer.start.toEpoch () == 0)
|
||||
outer.start = interval.start;
|
||||
|
||||
// Deliberately mixed start/end.
|
||||
if (interval.range.start > outer.end)
|
||||
outer.end = interval.range.start;
|
||||
if (interval.start > outer.end)
|
||||
outer.end = interval.start;
|
||||
|
||||
if (interval.range.end > outer.end)
|
||||
outer.end = interval.range.end;
|
||||
if (interval.end > outer.end)
|
||||
outer.end = interval.end;
|
||||
|
||||
if (! interval.range.is_ended ())
|
||||
if (! interval.is_ended ())
|
||||
outer.end = Datetime ();
|
||||
}
|
||||
|
||||
|
@ -517,10 +518,10 @@ Range outerRange (const std::vector <Interval>& intervals)
|
|||
// An interval matches a filter interval if the start/end overlaps, and all
|
||||
// filter interval tags are found in the interval.
|
||||
//
|
||||
// [1] interval.range.end.toEpoch () == 0
|
||||
// [2] interval.range.end > filter.range.start
|
||||
// [3] filter.range.end.toEpoch () == 0
|
||||
// [4] interval.range.start < filter.range.end
|
||||
// [1] interval.end.toEpoch () == 0
|
||||
// [2] interval.end > filter.start
|
||||
// [3] filter.end.toEpoch () == 0
|
||||
// [4] interval.start < filter.end
|
||||
//
|
||||
// Match: (1 || 2) && (3 || 4)
|
||||
|
||||
|
@ -552,9 +553,9 @@ Range outerRange (const std::vector <Interval>& intervals)
|
|||
//
|
||||
bool matchesFilter (const Interval& interval, const Interval& filter)
|
||||
{
|
||||
if ((filter.range.start.toEpoch () == 0 &&
|
||||
filter.range.end.toEpoch () == 0
|
||||
) || interval.range.intersects (filter.range))
|
||||
if ((filter.start.toEpoch () == 0 &&
|
||||
filter.end.toEpoch () == 0
|
||||
) || interval.intersects (filter))
|
||||
{
|
||||
for (auto& tag : filter.tags ())
|
||||
if (! interval.hasTag (tag))
|
||||
|
@ -567,7 +568,7 @@ bool matchesFilter (const Interval& interval, const Interval& filter)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Take an interval and clip it to the range.
|
||||
// Take an interval and clip it to the
|
||||
Interval clip (const Interval& interval, const Range& range)
|
||||
{
|
||||
if (! range.is_started () ||
|
||||
|
@ -575,13 +576,13 @@ Interval clip (const Interval& interval, const Range& range)
|
|||
return interval;
|
||||
|
||||
Interval clipped {interval};
|
||||
if (clipped.range.start.toEpoch () &&
|
||||
clipped.range.start < range.start)
|
||||
clipped.range.start = range.start;
|
||||
if (clipped.start.toEpoch () &&
|
||||
clipped.start < range.start)
|
||||
clipped.start = range.start;
|
||||
|
||||
if (clipped.range.end.toEpoch () &&
|
||||
clipped.range.end > range.end)
|
||||
clipped.range.end = range.end;
|
||||
if (clipped.end.toEpoch () &&
|
||||
clipped.end > range.end)
|
||||
clipped.end = range.end;
|
||||
|
||||
return clipped;
|
||||
}
|
||||
|
@ -600,16 +601,16 @@ std::vector <Interval> getTracked (
|
|||
// [earliest start, infinity)
|
||||
//
|
||||
// Avoid assigning a zero-width range - leave it unstarted instead.
|
||||
if (! filter.range.is_started ())
|
||||
if (! filter.is_started ())
|
||||
{
|
||||
auto outer = outerRange (inclusions);
|
||||
if (outer.total ())
|
||||
filter.range = outer;
|
||||
filter.setRange (outer);
|
||||
|
||||
// Use an infinite range instead of the last end date; this prevents
|
||||
// issues when there is an empty range [q, q) at the end of a filter
|
||||
// [p, q), in which case there is no overlap or intersection.
|
||||
filter.range.end = 0;
|
||||
filter.end = 0;
|
||||
}
|
||||
|
||||
std::vector <Interval> intervals = inclusions;
|
||||
|
@ -618,11 +619,11 @@ std::vector <Interval> getTracked (
|
|||
{
|
||||
auto latest = inclusions.back ();
|
||||
|
||||
if (latest.range.is_open ())
|
||||
if (latest.is_open ())
|
||||
{
|
||||
// Get the set of expanded exclusions that overlap the range defined by the
|
||||
// timeline.
|
||||
auto exclusions = getAllExclusions (rules, filter.range);
|
||||
auto exclusions = getAllExclusions (rules, filter);
|
||||
if (! exclusions.empty ())
|
||||
{
|
||||
intervals.pop_back ();
|
||||
|
@ -630,7 +631,7 @@ std::vector <Interval> getTracked (
|
|||
for (auto& interval : flatten (latest, exclusions))
|
||||
{
|
||||
if (latest.synthetic ||
|
||||
latest.range != interval.range)
|
||||
latest != interval)
|
||||
interval.synthetic = true;
|
||||
|
||||
intervals.push_back (interval);
|
||||
|
@ -656,9 +657,9 @@ std::vector <Range> getUntracked (
|
|||
{
|
||||
std::vector <Range> inclusion_ranges;
|
||||
for (auto& i : subset (filter, getAllInclusions (database)))
|
||||
inclusion_ranges.push_back (i.range);
|
||||
inclusion_ranges.push_back (i);
|
||||
|
||||
auto available = subtractRanges ({filter.range}, getAllExclusions (rules, filter.range));
|
||||
auto available = subtractRanges ({filter}, getAllExclusions (rules, filter));
|
||||
auto untracked = subtractRanges (available, inclusion_ranges);
|
||||
debug (format ("Loaded {1} untracked ranges", untracked.size ()));
|
||||
return untracked;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue