diff --git a/lib/rdlog_event.cpp b/lib/rdlog_event.cpp index d02b6cd0..6b368afd 100644 --- a/lib/rdlog_event.cpp +++ b/lib/rdlog_event.cpp @@ -626,20 +626,22 @@ void RDLogEvent::setLogLine(int line,RDLogLine *ll) } -RDLogLine *RDLogEvent::loglineById(int id) const +RDLogLine *RDLogEvent::loglineById(int id, bool ignore_holdovers) const { - for(int i=0;iid()==id) { - return log_line[i]; - } - } - return NULL; + int line = lineById(id, ignore_holdovers); + if(line == -1) + return NULL; + else + return log_line[line]; } -int RDLogEvent::lineById(int id) const +int RDLogEvent::lineById(int id, bool ignore_holdovers) const { for(int i=0;iisHoldover()) { + continue; + } if(log_line[i]->id()==id) { return i; } diff --git a/lib/rdlog_event.h b/lib/rdlog_event.h index c44ac061..46ae3f52 100644 --- a/lib/rdlog_event.h +++ b/lib/rdlog_event.h @@ -61,8 +61,8 @@ class RDLogEvent QTime blockStartTime(int line); RDLogLine *logLine(int line) const; void setLogLine(int line,RDLogLine *ll); - RDLogLine *loglineById(int id) const; - int lineById(int id) const; + RDLogLine *loglineById(int id, bool ignore_holdovers=false) const; + int lineById(int id, bool ignore_holdovers=false) const; int lineByStartHour(int hour,RDLogLine::StartTimeType type) const; int lineByStartHour(int hour) const; int nextTimeStart(QTime after); diff --git a/lib/rdlog_line.cpp b/lib/rdlog_line.cpp index 4972d136..e0de1876 100644 --- a/lib/rdlog_line.cpp +++ b/lib/rdlog_line.cpp @@ -174,6 +174,7 @@ void RDLogLine::clear() log_link_id=-1; log_link_embedded=false; log_start_source=RDLogLine::StartUnknown; + is_holdover = false; } @@ -2093,3 +2094,13 @@ QString RDLogLine::sourceText(RDLogLine::Source src) } return QObject::tr("Unknown"); } + +bool RDLogLine::isHoldover() const +{ + return is_holdover; +} + +void RDLogLine::setHoldover(bool b) +{ + is_holdover = b; +} diff --git a/lib/rdlog_line.h b/lib/rdlog_line.h index 037fccfe..4855fc8f 100644 --- a/lib/rdlog_line.h +++ b/lib/rdlog_line.h @@ -265,6 +265,8 @@ class RDLogLine static QString typeText(RDLogLine::Type type); static QString timeTypeText(RDLogLine::TimeType type); static QString sourceText(RDLogLine::Source src); + bool isHoldover() const; + void setHoldover(bool); private: int log_id; @@ -368,6 +370,7 @@ class RDLogLine int log_link_end_slop; int log_link_id; bool log_link_embedded; + bool is_holdover; }; diff --git a/rdairplay/log_play.cpp b/rdairplay/log_play.cpp index eeb25369..68e20fdc 100644 --- a/rdairplay/log_play.cpp +++ b/rdairplay/log_play.cpp @@ -503,7 +503,7 @@ void LogPlay::load() if(lines[running-1]<(size()-1)) { remove(lines[running-1]+1,size()-lines[running-1]-1,false); } - for(int i=running-2;i>0;i--) { + for(int i=running-1;i>0;i--) { remove(lines[i-1]+1,lines[i]-lines[i-1]-1,false); } if(lines[0]!=0) { @@ -511,6 +511,12 @@ void LogPlay::load() } } + // Note that events left in the log are holdovers from a previous log. + // Their IDs may clash with those of events in the log we will now load, + // and it may be appropriate to ignore them in that case. + for(int i = 0, ilim = size(); i != ilim; ++i) + logLine(i)->setHoldover(true); + // // Load Events // @@ -588,6 +594,7 @@ bool LogPlay::refresh() int current_id=-1; int lines[TRANSPORT_QUANTITY]; int running; + int first_non_holdover = 0; if(play_macro_running) { play_refresh_pending=true; @@ -633,7 +640,12 @@ bool LogPlay::refresh() for(int i=0;istatus()!=RDLogLine::Scheduled) { - if((s=e->loglineById(d->id()))!=NULL) { + if((!d->isHoldover()) && (s=e->loglineById(d->id()))!=NULL) { + // A holdover event may be finished or active, + // but should not supress the addition of an + // event with the same ID in this log. + // Incrementing its ID here may flag it as an orphan + // to be removed in step 4. s->incrementPass(); } d->incrementPass(); @@ -649,6 +661,15 @@ bool LogPlay::refresh() } } + // Find first non-holdover event, where start-of-log + // new events should be added: + for(int i=0;isize();i++) { + if(logLine(i)->isHoldover()) + ++first_non_holdover; + else + break; + } + // // Pass 3: Add New Events // @@ -656,15 +677,15 @@ bool LogPlay::refresh() s=e->logLine(i); if(s->pass()==0) { if((prev_line=(i-1))<0) { // First Event - insert(0,s,false,true); + insert(first_non_holdover,s,false,true); } else { prev_id=e->logLine(prev_line)->id(); - insert(lineById(prev_id)+1,s,false,true); + insert(lineById(prev_id, /*ignore_holdovers=*/true)+1,s,false,true); } } else { - loglineById(s->id())->incrementPass(); + loglineById(s->id(), /*ignore_holdovers=*/true)->incrementPass(); } } @@ -681,13 +702,16 @@ bool LogPlay::refresh() // // Restore Next Event // - if(current_id!=-1 && e->loglineById(current_id)!=NULL) { //Make Next after currently playing cart - if((next_line=lineById(current_id))>=0) { + if(current_id!=-1 && e->loglineById(current_id)!=NULL) { + // Make Next after currently playing cart + // The next event cannot have been a holdover, + // as holdovers are always either active or finished. + if((next_line=lineById(current_id, /*ignore_holdovers=*/true))>=0) { makeNext(next_line+1,false); } } else { - if((next_line=lineById(next_id))>=0) { + if((next_line=lineById(next_id, /*ignore_holdovers=*/true))>=0) { makeNext(next_line,false); } }