mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-07-07 20:06:39 +02:00
TI-66: Move with :adjust leaves overlapping intervals.
- Implement 'overwrite' overlap resolution strategy - Add convenience methods to Range - also fixes TI-85: :adjust creates overlapping interval
This commit is contained in:
parent
963d4ac7ae
commit
48ed980c76
4 changed files with 70 additions and 54 deletions
|
@ -41,6 +41,8 @@
|
|||
segfault
|
||||
(thanks to Thomas Lauf).
|
||||
- TI-65 The 'tags' command should support a filter
|
||||
- TI-66 Move with :adjust leaves overlapping intervals.
|
||||
(thanks to A M)
|
||||
- TI-67 Summary with parameters shows wrong ids
|
||||
(thanks to Bodo Graumann)
|
||||
- TI-68 Cannot shorten interval which has been moved into an exclusion.
|
||||
|
@ -58,6 +60,8 @@
|
|||
(Thanks to A M).
|
||||
- TI-78 Tag parsing broken for tags starting with "or_"
|
||||
(Thanks to Lukas Barth).
|
||||
- TI-85 :adjust creates overlapping interval
|
||||
(thanks to Tim Ruffing)
|
||||
- TI-90 Let 'continue' accept a date or a date range
|
||||
- TI-91 Timewarrior does not compile on DragonFly
|
||||
(Thanks to Michael Neumann).
|
||||
|
|
|
@ -94,6 +94,18 @@ bool Range::is_ended () const
|
|||
return end.toEpoch () > 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Range::is_empty () const
|
||||
{
|
||||
return start == end;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Range::contains (const Datetime &datetime) const
|
||||
{
|
||||
return start <= datetime && (! is_ended () || end >= datetime);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Detect the following overlap cases:
|
||||
//
|
||||
|
|
|
@ -45,6 +45,9 @@ public:
|
|||
bool is_open () const;
|
||||
bool is_started () const;
|
||||
bool is_ended () const;
|
||||
bool is_empty () const;
|
||||
|
||||
bool contains (const Datetime&) const;
|
||||
|
||||
bool overlap (const Range&) const;
|
||||
bool encloses (const Range&) const;
|
||||
|
|
101
src/validate.cpp
101
src/validate.cpp
|
@ -103,65 +103,62 @@ static void autoAdjust (
|
|||
for (auto& overlap : overlaps)
|
||||
debug (" " + overlap.dump ());
|
||||
|
||||
// Without (adjust == true), overlapping intervals are an error condition.
|
||||
if (! adjust && overlaps.size ())
|
||||
if (! overlaps.empty ())
|
||||
{
|
||||
if (! adjust)
|
||||
throw std::string("You cannot overlap intervals. Correct the start/end "
|
||||
"time, or specify the :adjust hint.");
|
||||
|
||||
// TODO If there is overlap, and the tags are the same, merge.
|
||||
// implement overwrite resolution, i.e. the new interval overwrites existing intervals
|
||||
for (auto& overlap : overlaps)
|
||||
{
|
||||
bool start_within_overlap = overlap.range.contains (interval.range.start);
|
||||
bool end_within_overlap = interval.range.end != 0 && overlap.range.contains (interval.range.end);
|
||||
|
||||
// TODO Accumulate identifiable and correctable cases here.
|
||||
/*
|
||||
// Closed
|
||||
if (start_within_overlap && !end_within_overlap)
|
||||
{
|
||||
// start date of new interval within old interval
|
||||
Interval modified {overlap};
|
||||
modified.range.end = interval.range.start;
|
||||
database.modifyInterval (overlap, modified);
|
||||
}
|
||||
else if (!start_within_overlap && end_within_overlap)
|
||||
{
|
||||
// end date of new interval within old interval
|
||||
Interval modified {overlap};
|
||||
modified.range.start = interval.range.end;
|
||||
database.modifyInterval (overlap, modified);
|
||||
}
|
||||
else if (!start_within_overlap && !end_within_overlap)
|
||||
{
|
||||
// new interval encloses old interval
|
||||
database.deleteInterval (overlap);
|
||||
}
|
||||
else
|
||||
{
|
||||
// new interval enclosed by old interval
|
||||
Interval split2 {overlap};
|
||||
Interval split1 {overlap};
|
||||
|
||||
int [-----]
|
||||
ovl [-----]
|
||||
split1.range.end = interval.range.start;
|
||||
split2.range.start = interval.range.end;
|
||||
|
||||
int [-----]
|
||||
ovl [-----]
|
||||
|
||||
int [-]
|
||||
ovl [-----]
|
||||
|
||||
int [-----]
|
||||
ovl [-]
|
||||
|
||||
int [-----]
|
||||
ovl [-----]
|
||||
|
||||
// Interval is open
|
||||
|
||||
int [--
|
||||
ovl [-----]
|
||||
|
||||
int [--
|
||||
ovl [-----]
|
||||
|
||||
int [--
|
||||
ovl [-----]
|
||||
|
||||
int [--
|
||||
ovl [-]
|
||||
|
||||
int [--
|
||||
ovl [-----]
|
||||
|
||||
// Overlap is open
|
||||
|
||||
int [-----]
|
||||
ovl [--
|
||||
|
||||
int [-----]
|
||||
ovl [--
|
||||
|
||||
int [-]
|
||||
ovl [--
|
||||
|
||||
int [-----]
|
||||
ovl [--
|
||||
|
||||
*/
|
||||
if (split1.range.is_empty ())
|
||||
{
|
||||
database.deleteInterval (overlap);
|
||||
}
|
||||
else
|
||||
{
|
||||
database.modifyInterval (overlap, split1);
|
||||
}
|
||||
|
||||
if (! split2.range.is_empty ())
|
||||
{
|
||||
database.addInterval (split2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue