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
|
segfault
|
||||||
(thanks to Thomas Lauf).
|
(thanks to Thomas Lauf).
|
||||||
- TI-65 The 'tags' command should support a filter
|
- 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
|
- TI-67 Summary with parameters shows wrong ids
|
||||||
(thanks to Bodo Graumann)
|
(thanks to Bodo Graumann)
|
||||||
- TI-68 Cannot shorten interval which has been moved into an exclusion.
|
- TI-68 Cannot shorten interval which has been moved into an exclusion.
|
||||||
|
@ -58,6 +60,8 @@
|
||||||
(Thanks to A M).
|
(Thanks to A M).
|
||||||
- TI-78 Tag parsing broken for tags starting with "or_"
|
- TI-78 Tag parsing broken for tags starting with "or_"
|
||||||
(Thanks to Lukas Barth).
|
(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-90 Let 'continue' accept a date or a date range
|
||||||
- TI-91 Timewarrior does not compile on DragonFly
|
- TI-91 Timewarrior does not compile on DragonFly
|
||||||
(Thanks to Michael Neumann).
|
(Thanks to Michael Neumann).
|
||||||
|
|
|
@ -94,6 +94,18 @@ bool Range::is_ended () const
|
||||||
return end.toEpoch () > 0;
|
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:
|
// Detect the following overlap cases:
|
||||||
//
|
//
|
||||||
|
|
|
@ -45,6 +45,9 @@ public:
|
||||||
bool is_open () const;
|
bool is_open () const;
|
||||||
bool is_started () const;
|
bool is_started () const;
|
||||||
bool is_ended () const;
|
bool is_ended () const;
|
||||||
|
bool is_empty () const;
|
||||||
|
|
||||||
|
bool contains (const Datetime&) const;
|
||||||
|
|
||||||
bool overlap (const Range&) const;
|
bool overlap (const Range&) const;
|
||||||
bool encloses (const Range&) const;
|
bool encloses (const Range&) const;
|
||||||
|
|
105
src/validate.cpp
105
src/validate.cpp
|
@ -103,65 +103,62 @@ static void autoAdjust (
|
||||||
for (auto& overlap : overlaps)
|
for (auto& overlap : overlaps)
|
||||||
debug (" " + overlap.dump ());
|
debug (" " + overlap.dump ());
|
||||||
|
|
||||||
// Without (adjust == true), overlapping intervals are an error condition.
|
if (! overlaps.empty ())
|
||||||
if (! adjust && overlaps.size ())
|
{
|
||||||
throw std::string ("You cannot overlap intervals. Correct the start/end "
|
if (! adjust)
|
||||||
"time, or specify the :adjust hint.");
|
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.
|
if (start_within_overlap && !end_within_overlap)
|
||||||
/*
|
{
|
||||||
// Closed
|
// 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 [-----]
|
split1.range.end = interval.range.start;
|
||||||
ovl [-----]
|
split2.range.start = interval.range.end;
|
||||||
|
|
||||||
int [-----]
|
if (split1.range.is_empty ())
|
||||||
ovl [-----]
|
{
|
||||||
|
database.deleteInterval (overlap);
|
||||||
int [-]
|
}
|
||||||
ovl [-----]
|
else
|
||||||
|
{
|
||||||
int [-----]
|
database.modifyInterval (overlap, split1);
|
||||||
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 (! split2.range.is_empty ())
|
||||||
|
{
|
||||||
|
database.addInterval (split2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue