Rivendellaudio/lib/rdlogmodel.cpp
Fred Gleason 485383d46b 2024-01-12 Fred Gleason <fredg@paravelsystems.com>
* Documented the meaning of the 'RDLogLine::StartTimeType' enum
	in 'lib/rdlog_line.h'.
	* Changed the default value of the 'RDLogLine::Imported' start time
	from '00:00:00' to NULL.
	* Fixed a regression in rdairplay(1) that caused the 'Sch. Time'
	column to be removed from the Full Log lists.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
2024-01-12 12:16:05 -05:00

1725 lines
48 KiB
C++

// rdlogmodel.cpp
//
// Data model for Rivendell logs
//
// (C) Copyright 2020-2022 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include "rdapplication.h"
#include "rdconf.h"
#include "rdescape_string.h"
#include "rdlog.h"
#include "rdlog_line.h"
#include "rdlogmodel.h"
RDLogModel::RDLogModel(const QString &logname,bool read_only,QObject *parent)
: QAbstractTableModel(parent)
{
d_log_name=logname;
d_read_only=read_only;
MakeModel();
}
RDLogModel::RDLogModel(QObject *parent)
: QAbstractTableModel(parent)
{
d_read_only=false;
MakeModel();
}
RDLogModel::~RDLogModel()
{
if(d_fms!=NULL) {
delete d_fms;
}
if(d_bold_fms!=NULL) {
delete d_bold_fms;
}
for(int i=0;i<d_log_lines.size();i++) {
delete d_log_lines[i];
}
}
QPalette RDLogModel::palette()
{
return d_palette;
}
void RDLogModel::setPalette(const QPalette &pal)
{
d_palette=pal;
}
QFont RDLogModel::normalFont() const
{
return d_font;
}
QFont RDLogModel::boldFont() const
{
return d_bold_font;
}
void RDLogModel::setFont(const QFont &font)
{
int width;
QString sql;
RDSqlQuery *q=NULL;
d_font=font;
if(d_fms!=NULL) {
delete d_fms;
}
d_fms=new QFontMetrics(d_font);
d_bold_font=font;
d_bold_font.setBold(true);
if(d_bold_fms!=NULL) {
delete d_bold_fms;
}
d_bold_fms=new QFontMetrics(d_bold_font);
//
// Calculate Minimum Column Widths
//
if(rda->showTwelveHourTime()) {
d_size_hints[0]=QSize(40+d_bold_fms->width("T00:00:00.0 AM"),0);
}
else {
d_size_hints[0]=QSize(40+d_bold_fms->width("T00:00:00.0"),0);
}
width=d_bold_fms->width(tr("PLAY"));
if(d_bold_fms->width(tr("SEGUE"))>width) {
width=d_bold_fms->width(tr("SEGUE"));
}
if(d_bold_fms->width(tr("STOP"))>width) {
width=d_bold_fms->width(tr("STOP"));
}
d_size_hints[1]=QSize(10+width,0);
d_size_hints[2]=QSize(10+d_bold_fms->width("000000"),0);
width=0;
sql=QString("select ")+
"`NAME` "+ // 00
"from `GROUPS`";
q=new RDSqlQuery(sql);
while(q->next()) {
if(d_bold_fms->width(q->value(0).toString())>width) {
width=d_bold_fms->width(q->value(0).toString());
}
}
delete q;
d_size_hints[3]=QSize(10+width,0);
d_size_hints[4]=QSize(10+d_bold_fms->width("8:88:88"),0);
width=0;
for(int i=0;i<RDLogLine::LastSource;i++) {
RDLogLine::Source src=(RDLogLine::Source)i;
if(d_bold_fms->width(RDLogLine::sourceText(src))>width) {
width=d_bold_fms->width(RDLogLine::sourceText(src));
}
}
d_size_hints[10]=QSize(10+width,0);
}
int RDLogModel::columnCount(const QModelIndex &parent) const
{
return d_headers.size();
}
int RDLogModel::rowCount(const QModelIndex &parent) const
{
if(d_read_only) {
return lineCount();
}
return 1+lineCount();
}
QVariant RDLogModel::headerData(int section,Qt::Orientation orient,int role) const
{
if((orient==Qt::Horizontal)&&(role==Qt::DisplayRole)) {
return d_headers.at(section);
}
return QVariant();
}
QVariant RDLogModel::data(const QModelIndex &index,int role) const
{
QString str;
RDLogLine *ll=NULL;
int col=index.column();
int row=index.row();
if((ll=logLine(row))!=NULL) {
switch((Qt::ItemDataRole)role) {
case Qt::DisplayRole:
return cellText(col,row,ll);
case Qt::DecorationRole:
return cellIcon(col,row,ll);
case Qt::FontRole:
return cellTextFont(col,row,ll);
case Qt::TextColorRole:
return cellTextColor(col,row,ll);
case Qt::BackgroundRole:
return rowBackgroundColor(row,ll);
case Qt::SizeHintRole:
return d_size_hints.at(col);
case Qt::TextAlignmentRole:
return d_alignments.at(col);
default:
break;
}
}
else { // End of log marker
if(((Qt::ItemDataRole)role==Qt::DisplayRole)&&(index.column()==5)) {
return tr("--- end of log ---");
}
}
return QVariant();
}
bool RDLogModel::exists()
{
return RDLog::exists(d_log_name);
}
bool RDLogModel::exists(int line)
{
if((int)d_log_lines.size()>line) {
return true;
}
return false;
}
bool RDLogModel::exists(const QTime &hard_time,int except_line)
{
for(int i=0;i<lineCount();i++) {
if((logLine(i)->timeType()==RDLogLine::Hard)&&
(logLine(i)->startTime(RDLogLine::Logged)==hard_time)&&
(i!=except_line)) {
return true;
}
}
return false;
}
QString RDLogModel::logName() const
{
return d_log_name;
}
void RDLogModel::setLogName(QString logname)
{
// clear();
RDLog *log=new RDLog(logname);
d_log_name=log->name(); // So we normalize the case
delete log;
}
QString RDLogModel::serviceName() const
{
return d_service_name;
}
int RDLogModel::load(bool track_ptrs)
{
RDLogLine line;
QString sql;
RDSqlQuery *q;
beginResetModel();
//
// Get the service name
//
sql=QString("select `SERVICE` from `LOGS` where ")+
"`NAME`='"+RDEscapeString(d_log_name)+"'";
q=new RDSqlQuery(sql);
if(q->next()) {
d_service_name=q->value(0).toString();
}
delete q;
RDLog *log=new RDLog(d_log_name);
d_max_id=log->nextId();
delete log;
LoadLines(d_log_name,0,track_ptrs);
endResetModel();
return d_log_lines.size();
}
void RDLogModel::saveModified(RDConfig *config,bool update_tracks)
{
for(int i=0;i<d_log_lines.size();i++) {
if(d_log_lines[i]->hasBeenModified()) {
save(config,update_tracks, i);
}
}
}
void RDLogModel::save(RDConfig *config,bool update_tracks,int line)
{
QString sql;
RDSqlQuery *q;
if(d_log_name.isEmpty()) {
return;
}
if(line<0) {
if(exists()) {
sql=QString("delete from `LOG_LINES` where ")+
"`LOG_NAME`='"+RDEscapeString(d_log_name)+"'";
RDSqlQuery::apply(sql);
}
if (d_log_lines.size() > 0) {
QString values = "";
for(int i=0;i<d_log_lines.size();i++) {
InsertLineValues(&values, i);
if (i<d_log_lines.size()-1) {
values += ",";
}
}
InsertLines(values);
}
}
else {
sql=QString("delete from `LOG_LINES` where ")+
"`LOG_NAME`='"+RDEscapeString(d_log_name)+"' && "+
QString::asprintf("`COUNT`=%d",line);
q=new RDSqlQuery(sql);
delete q;
SaveLine(line);
// BPM - Clear the modified flag
d_log_lines[line]->clearModified();
}
RDLog *log=new RDLog(d_log_name);
if(log->nextId()<nextId()) {
log->setNextId(nextId());
}
if(update_tracks) {
log->updateTracks();
}
delete log;
}
int RDLogModel::append(const QString &logname,bool track_ptrs)
{
return LoadLines(logname,d_max_id,track_ptrs);
}
void RDLogModel::clear()
{
if(d_log_lines.size()>0) {
beginResetModel();
for(int i=0;i<d_log_lines.size();i++) {
delete d_log_lines.at(i);
}
d_log_lines.clear();
endResetModel();
}
d_log_name="";
d_max_id=0;
}
int RDLogModel::validate(QString *report,const QDate &date)
{
QString sql;
RDSqlQuery *q;
RDSqlQuery *q1;
int errs=0;
QDateTime now=QDateTime::currentDateTime();
//
// Report Header
//
*report="Rivendell Log Exception Report\n";
*report+=QString("Generated at: ")+
rda->shortDateString(now.date())+" - "+
rda->timeString(now.time())+"\n";
*report+=QString("Log: ")+d_log_name+"\n";
*report+=QString("Effective Airdate: ")+rda->shortDateString(date)+"\n";
*report+="\n";
//
// Line Scan
//
for(int i=0;i<lineCount();i++) {
if(logLine(i)->cartNumber()>0) {
sql=QString("select ")+
"`TYPE`,"+ // 00
"`TITLE` "+ // 01
"from `CART` where "+
QString::asprintf("`NUMBER`=%d",logLine(i)->cartNumber());
q=new RDSqlQuery(sql);
if(!q->first()) {
*report+=QString(" ")+
rda->timeString(logLine(i)->startTime(RDLogLine::Logged))+
QString::asprintf(" - missing cart %06d",logLine(i)->cartNumber())+
"\n";
errs++;
}
else {
if((RDCart::Type)q->value(0).toInt()==RDCart::Audio) {
if(logLine(i)->startTime(RDLogLine::Logged).isNull()) {
//
// Handle events with no logged start time (e.g. manual inserts)
//
//TODO do we need to verify date here?
sql=QString("select `CUT_NAME` from `CUTS` where ")+
QString::asprintf("(`CART_NUMBER`=%u)&&",logLine(i)->cartNumber())+
"((`START_DATETIME` is null)||"+
"(`START_DATETIME`<='"+date.toString("yyyy-MM-dd")+" 23:59:59'))&&"+
"((`END_DATETIME` is null)||"+
"(`END_DATETIME`>='"+date.toString("yyyy-MM-dd")+" 00:00:00'))&&"+
"("+RDDowCode(date.dayOfWeek())+"='Y')&&(LENGTH>0)";
}
else {
//TODO Do we need to verify date and logLine(i)->startTime?
sql=QString("select `CUT_NAME` from `CUTS` where ")+
QString::asprintf("(`CART_NUMBER`=%u)&&",logLine(i)->cartNumber())+
"((`START_DATETIME` is null)||"+
"(`START_DATETIME`<='"+date.toString("yyyy-MM-dd")+" "+
logLine(i)->startTime(RDLogLine::Logged).toString("hh:mm:ss")+
"'))&&"+
"((`END_DATETIME` is null)||"+
"(`END_DATETIME`>='"+date.toString("yyyy-MM-dd")+" "+
logLine(i)->startTime(RDLogLine::Logged).toString("hh:mm:ss")+
"'))&&"+
"((`START_DAYPART` is null)||"+
"(`START_DAYPART`<='"+
logLine(i)->startTime(RDLogLine::Logged).
toString("hh:mm:ss")+"'))&&"+
"((`END_DAYPART` is null)||"+
"(`END_DAYPART`>='"+logLine(i)->startTime(RDLogLine::Logged).
toString("hh:mm:ss")+"'))&&"+
"("+RDDowCode(date.dayOfWeek())+"='Y')&&(LENGTH>0)";
}
q1=new RDSqlQuery(sql);
if(!q1->first()) {
*report+=QString(" ")+
rda->timeString(logLine(i)->startTime(RDLogLine::Logged))+
QString::asprintf(" - cart %06d [",logLine(i)->cartNumber())+
q->value(1).toString()+"] "+QObject::tr("is not playable")+"\n";
errs++;
}
delete q1;
}
}
delete q;
}
}
*report+="\n";
if(errs==1) {
*report+=QString::asprintf("%d validation exception found.\n\n",errs);
}
else {
*report+=QString::asprintf("%d validation exceptions found.\n\n",errs);
}
return errs;
}
void RDLogModel::update(int line)
{
if(d_log_name.isEmpty()) {
return;
}
if(d_log_lines[line]->cartNumber()>0) {
QString sql=QString("select ")+
"`CART`.`TYPE`,"+ // 00
"`CART`.`GROUP_NAME`,"+ // 01
"`CART`.`TITLE`,"+ // 02
"`CART`.`ARTIST`,"+ // 03
"`CART`.`ALBUM`,"+ // 04
"`CART`.`YEAR`,"+ // 05
"`CART`.`LABEL`,"+ // 06
"`CART`.`CLIENT`,"+ // 07
"`CART`.`AGENCY`,"+ // 08
"`CART`.`USER_DEFINED`,"+ // 09
"`CART`.`FORCED_LENGTH`,"+ // 10
"`CART`.`CUT_QUANTITY`,"+ // 11
"`CART`.`LAST_CUT_PLAYED`,"+ // 12
"`CART`.`PLAY_ORDER`,"+ // 13
"`CART`.`ENFORCE_LENGTH`,"+ // 14
"`CART`.`PRESERVE_PITCH`,"+ // 15
"`CART`.`PUBLISHER`,"+ // 16
"`CART`.`COMPOSER`,"+ // 17
"`CART`.`USAGE_CODE`,"+ // 18
"`CART`.`AVERAGE_SEGUE_LENGTH`,"+ // 19
"`CART`.`VALIDITY`,"+ // 20
"`CART`.`NOTES`,"+ // 21
"`GROUPS`.`COLOR` "+ // 22
"from `CART` left join `GROUPS` "+
"on `CART`.`GROUP_NAME`=`GROUPS`.`NAME` where "+
QString::asprintf("`CART`.`NUMBER`=%u",d_log_lines[line]->cartNumber());
RDSqlQuery *q=new RDSqlQuery(sql);
if(q->first()) {
switch((RDCart::Type)q->value(0).toInt()) {
case RDCart::Audio:
d_log_lines[line]->setType(RDLogLine::Cart);
break;
case RDCart::Macro:
d_log_lines[line]->setType(RDLogLine::Macro);
break;
default:
break;
}
d_log_lines[line]->
setCartType((RDCart::Type)q->value(0).toInt()); // Cart Type
d_log_lines[line]->setGroupName(q->value(1).toString()); // Group Name
d_log_lines[line]->setTitle(q->value(2).toString()); // Title
d_log_lines[line]->setArtist(q->value(3).toString()); // Artist
d_log_lines[line]->setPublisher(q->value(16).toString()); // Publisher
d_log_lines[line]->setComposer(q->value(17).toString()); // Composer
d_log_lines[line]->setAlbum(q->value(4).toString()); // Album
d_log_lines[line]->setYear(q->value(5).toDate()); // Year
d_log_lines[line]->setLabel(q->value(6).toString()); // Label
d_log_lines[line]->setClient(q->value(7).toString()); // Client
d_log_lines[line]->setAgency(q->value(8).toString()); // Agency
d_log_lines[line]->setUserDefined(q->value(9).toString()); // User Defined
d_log_lines[line]->setUsageCode((RDCart::UsageCode)q->value(16).toInt());
d_log_lines[line]->setForcedLength(q->value(10).toUInt()); // Forced Length
d_log_lines[line]->setAverageSegueLength(q->value(19).toUInt());
d_log_lines[line]->setCutQuantity(q->value(11).toUInt()); // Cut Quantity
d_log_lines[line]->setLastCutPlayed(q->value(12).toUInt()); // Last Cut Played
d_log_lines[line]->
setPlayOrder((RDCart::PlayOrder)q->value(13).toUInt()); // Play Order
d_log_lines[line]->
setEnforceLength(RDBool(q->value(14).toString())); // Enforce Length
d_log_lines[line]->
setPreservePitch(RDBool(q->value(15).toString())); // Preserve Pitch
d_log_lines[line]->setValidity((RDCart::Validity)q->value(20).toInt());
d_log_lines[line]->setCartNotes(q->value(21).toString()); // Cart Notes
d_log_lines[line]->setGroupColor(q->value(22).toString()); // Group Color
}
else {
d_log_lines[line]->setValidity(RDCart::NeverValid);
}
delete q;
}
emitDataChanged(line);
}
int RDLogModel::lineCount() const
{
return d_log_lines.size();
}
void RDLogModel::insert(int line,int num_lines,bool preserve_trans)
{
if(!preserve_trans) {
if((line>0)&&(d_log_lines[line-1]!=NULL)) {
d_log_lines[line-1]->setEndPoint(-1,RDLogLine::LogPointer);
d_log_lines[line-1]->setSegueStartPoint(-1,RDLogLine::LogPointer);
d_log_lines[line-1]->setSegueEndPoint(-1,RDLogLine::LogPointer);
emitDataChanged(line-1);
}
if(line<(lineCount()-1)) {
d_log_lines[line]->setStartPoint(-1,RDLogLine::LogPointer);
d_log_lines[line]->setHasCustomTransition(false);
emitDataChanged(line);
}
}
if(line<lineCount()) {
beginInsertRows(QModelIndex(),line,line+num_lines-1);
for(int i=0;i<num_lines;i++) {
d_log_lines.insert(line+i,new RDLogLine());
d_log_lines[line+i]->setId(++d_max_id);
}
endInsertRows();
return;
}
if(line>=lineCount()) {
beginInsertRows(QModelIndex(),lineCount(),lineCount()+num_lines-1);
for(int i=0;i<num_lines;i++) {
d_log_lines.push_back(new RDLogLine());
d_log_lines.back()->setId(++d_max_id);
}
endInsertRows();
return;
}
}
void RDLogModel::remove(int line,int num_lines,bool preserve_trans)
{
if(!preserve_trans) {
if(line>0) {
d_log_lines[line-1]->setEndPoint(-1,RDLogLine::LogPointer);
d_log_lines[line-1]->setSegueStartPoint(-1,RDLogLine::LogPointer);
d_log_lines[line-1]->setSegueEndPoint(-1,RDLogLine::LogPointer);
emitDataChanged(line-1);
}
if(line<((int)d_log_lines.size()-num_lines)) {
d_log_lines[line+num_lines]->setStartPoint(-1,RDLogLine::LogPointer);
d_log_lines[line+num_lines]->setHasCustomTransition(false);
emitDataChanged(line+num_lines);
}
}
beginRemoveRows(QModelIndex(),line,line+num_lines-1);
for(int i=0;i<num_lines;i++) {
delete d_log_lines.at(line);
d_log_lines.removeAt(line);
}
endRemoveRows();
}
void RDLogModel::move(int from_line,int to_line)
{
int src_offset=0;
int dest_offset=1;
RDLogLine *srcline;
RDLogLine *destline;
if(to_line<from_line) {
src_offset=1;
dest_offset=0;
}
insert(to_line+dest_offset,1);
if((to_line+1)>=lineCount()) {
to_line=lineCount()-1;
dest_offset=0;
}
if(((destline=logLine(to_line+dest_offset))==NULL)||
(srcline=logLine(from_line+src_offset))==NULL) {
remove(to_line+dest_offset,1);
return;
}
*destline=*srcline;
destline->clearTrackData(RDLogLine::AllTrans);
remove(from_line+src_offset,1);
}
void RDLogModel::copy(int from_line,int to_line)
{
RDLogLine *srcline;
RDLogLine *destline;
insert(to_line,1);
if(((destline=logLine(to_line))==NULL)||
(srcline=logLine(from_line))==NULL) {
remove(to_line,1);
return;
}
*destline=*srcline;
destline->clearExternalData();
destline->clearTrackData(RDLogLine::AllTrans);
destline->setSource(RDLogLine::Manual);
}
int RDLogModel::length(int from_line,int to_line,QTime *sched_time)
{
if(sched_time!=NULL) {
*sched_time=QTime();
}
if(to_line<0) {
to_line=lineCount();
for(int i=from_line;i<lineCount();i++) {
if(logLine(i)->timeType()==RDLogLine::Hard) {
to_line=i;
i=lineCount();
if(sched_time!=NULL) {
*sched_time=logLine(i)->startTime(RDLogLine::Logged);
}
}
}
}
int len=0;
for(int i=from_line;i<to_line;i++) {
if(((i+1)>=lineCount())||(logLine(i+1)->transType()!=RDLogLine::Segue)||
(logLine(i)->segueStartPoint()<0)) {
len+=logLine(i)->forcedLength();
}
else {
len+=logLine(i)->segueStartPoint()-logLine(i)->startPoint();
}
}
return len;
}
int RDLogModel::lengthToStop(int from_line,QTime *sched_time)
{
int to_line=-1;
for(int i=from_line;i<lineCount();i++) {
if(logLine(i)->transType()==RDLogLine::Stop) {
to_line=i;
}
}
if(to_line<0) {
return -1;
}
return length(from_line,to_line,sched_time);
}
bool RDLogModel::blockLength(int *nominal_length,int *actual_length,int line)
{
*nominal_length=0;
*actual_length=0;
QTime start_time;
int start_line=-1;
QTime end_time;
int end_line=-1;
if((line<0)||(line>(lineCount()-1))) {
*nominal_length=0;
*actual_length=0;
return false;
}
//
// Find Block Start
//
for(int i=line;i>=0;i--) {
if(logLine(i)->timeType()==RDLogLine::Hard) {
start_time=logLine(i)->startTime(RDLogLine::Logged);
start_line=i;
i=-1;
}
}
if(start_line<0) {
return false;
}
//
// Find Block End
//
for(int i=line+1;i<lineCount();i++) {
if(logLine(i)->timeType()==RDLogLine::Hard) {
end_time=logLine(i)->startTime(RDLogLine::Logged);
end_line=i;
i=lineCount();
}
}
if(end_line<0) {
return false;
}
//
// Calculate Lengths
//
*nominal_length=start_time.msecsTo(end_time);
for(int i=start_line;i<end_line;i++) {
if((i<(lineCount()+1))&&((logLine(i+1)->transType()==RDLogLine::Segue))) {
*actual_length+=logLine(i)->averageSegueLength();
}
else {
*actual_length+=logLine(i)->forcedLength();
}
}
return true;
}
QTime RDLogModel::blockStartTime(int line) const
{
int actual_length=0;
QTime start_time(0,0,0);
QTime return_time(0,0,0);
int start_line=0;
if((line<0)||(line>(lineCount()-1))) {
actual_length=0;
return return_time;
}
//
// Find Block Start
//
for(int i=line;i>=0;i--) {
if(logLine(i)->timeType()==RDLogLine::Hard) {
start_time=logLine(i)->startTime(RDLogLine::Logged);
start_line=i;
i=-1;
}
}
if(start_line == line) {
return start_time;
}
//
// Calculate Lengths
//
for(int i=start_line;i<line;i++) {
if((i<(lineCount()+1))&&((logLine(i+1)->transType()==RDLogLine::Segue))) {
if(logLine(i)->segueStartPoint(RDLogLine::LogPointer)<0) {
actual_length+=100*(logLine(i)->averageSegueLength()/100);
}
else {
if(logLine(i)->startPoint(RDLogLine::LogPointer)<0) {
actual_length+=(logLine(i)->segueStartPoint(RDLogLine::LogPointer)-
logLine(i)->startPoint(RDLogLine::CartPointer));
}
else {
actual_length+=(logLine(i)->segueStartPoint(RDLogLine::LogPointer)-
logLine(i)->startPoint(RDLogLine::LogPointer));
}
}
}
else {
actual_length+=100*(logLine(i)->forcedLength()/100);
}
}
return_time=start_time.addMSecs(actual_length);
return return_time;
}
RDLogLine *RDLogModel::logLine(int line) const
{
if((line<0)||(line>=d_log_lines.size())) {
return NULL;
}
return d_log_lines[line];
}
void RDLogModel::setLogLine(int line,RDLogLine *ll)
{
int id=d_log_lines[line]->id();
*d_log_lines[line]=*ll;
d_log_lines[line]->setId(id);
}
RDLogLine *RDLogModel::loglineById(int id, bool ignore_holdovers) const
{
int line = lineById(id, ignore_holdovers);
if(line == -1)
return NULL;
else
return d_log_lines[line];
}
int RDLogModel::lineById(int id, bool ignore_holdovers) const
{
for(int i=0;i<lineCount();i++) {
if(ignore_holdovers && d_log_lines[i]->isHoldover()) {
continue;
}
if(d_log_lines[i]->id()==id) {
return i;
}
}
return -1;
}
int RDLogModel::lineByStartHour(int hour,RDLogLine::StartTimeType type) const
{
for(int i=0;i<lineCount();i++) {
if(!d_log_lines[i]->startTime(type).isNull()&&
(d_log_lines[i]->startTime(type).hour()==hour)) {
return i;
}
}
return -1;
}
int RDLogModel::lineByStartHour(int hour) const
{
int line=-1;
if((line=lineByStartHour(hour,RDLogLine::Initial))<0) {
if((line=lineByStartHour(hour,RDLogLine::Predicted))<0) {
line=lineByStartHour(hour,RDLogLine::Imported);
}
}
return line;
}
int RDLogModel::nextTimeStart(QTime after)
{
for(int i=0;i<d_log_lines.size();i++) {
if((d_log_lines[i]->timeType()==RDLogLine::Hard)&&
(d_log_lines[i]->startTime(RDLogLine::Logged)>after)) {
return i;
}
}
return -1;
}
RDLogLine::TransType RDLogModel::nextTransType(int line)
{
if(line<(lineCount()-1)) {
return logLine(line+1)->transType();
}
return RDLogLine::Stop;
}
void RDLogModel::removeCustomTransition(int line)
{
if((line<0)||(line>(lineCount()-1))) {
return;
}
logLine(line)->setStartPoint(-1,RDLogLine::LogPointer);
logLine(line)->setFadeupPoint(-1,RDLogLine::LogPointer);
logLine(line)->setFadeupGain(0);
logLine(line)->setDuckUpGain(0);
logLine(line)->setHasCustomTransition(false);
if(line<1) {
return;
}
if(logLine(line-1)->type()!=RDLogLine::Track) {
logLine(line-1)->setEndPoint(-1,RDLogLine::LogPointer);
logLine(line-1)->setSegueStartPoint(-1,RDLogLine::LogPointer);
logLine(line-1)->setSegueEndPoint(-1,RDLogLine::LogPointer);
logLine(line-1)->setSegueGain(RD_FADE_DEPTH);
logLine(line-1)->setFadedownPoint(-1,RDLogLine::LogPointer);
logLine(line-1)->setFadedownGain(0);
logLine(line-1)->setDuckDownGain(0);
return;
}
if(line<2) {
return;
}
logLine(line-2)->setEndPoint(-1,RDLogLine::LogPointer);
logLine(line-2)->setSegueStartPoint(-1,RDLogLine::LogPointer);
logLine(line-2)->setSegueEndPoint(-1,RDLogLine::LogPointer);
logLine(line-2)->setSegueGain(RD_FADE_DEPTH);
logLine(line-2)->setFadedownPoint(-1,RDLogLine::LogPointer);
logLine(line-2)->setFadedownGain(0);
logLine(line-2)->setDuckDownGain(0);
}
int RDLogModel::nextId() const
{
int id=-1;
for(int i=0;i<lineCount();i++) {
if(d_log_lines[i]->id()>id) {
id=d_log_lines[i]->id();
}
}
return id+1;
}
int RDLogModel::nextLinkId() const
{
int id=-1;
for(int i=0;i<lineCount();i++) {
if(d_log_lines[i]->linkId()>id) {
id=d_log_lines[i]->linkId();
}
}
return id+1;
}
QString RDLogModel::xml() const
{
QString ret;
ret+="<logList>\n";
for(int i=0;i<lineCount();i++) {
ret+=logLine(i)->xml(i);
}
ret+="</logList>\n";
return ret;
}
void RDLogModel::setTransition(int line,RDLogLine::TransType trans)
{
RDLogLine *ll=NULL;
if((ll=logLine(line))!=NULL) {
if(ll->transType()!=trans) {
ll->setTransType(trans);
emitDataChanged(line);
}
}
}
void RDLogModel::processNotification(RDNotification *notify)
{
RDLogLine *ll=NULL;
if(notify->type()==RDNotification::CartType) {
unsigned cartnum=notify->id().toUInt();
for(int i=0;i<lineCount();i++) {
if(((ll=logLine(i))!=NULL)&&
((ll->type()==RDLogLine::Cart)||(ll->type()==RDLogLine::Macro))&&
(ll->cartNumber()==cartnum)) {
ll->refreshCart();
emitDataChanged(i);
}
}
}
}
void RDLogModel::setStartTimeStyle(RDLogModel::StartTimeStyle style)
{
if(d_start_time_style!=style) {
d_start_time_style=style;
emit dataChanged(createIndex(0,0),createIndex(lineCount(),0));
}
}
QString RDLogModel::StartTimeString(int line) const
{
RDLogLine *ll=logLine(line);
if(ll!=NULL) {
QString code="H";
switch(ll->timeType()) {
case RDLogLine::Hard:
if(ll->graceTime()<0) {
code="S";
}
return code+rda->tenthsTimeString(ll->startTime(RDLogLine::Logged));
break;
default:
if(d_start_time_style==RDLogModel::Estimated) {
if(ll->startTime(RDLogLine::Predicted).isNull()) {
return rda->tenthsTimeString(blockStartTime(line));
}
else {
return rda->tenthsTimeString(ll->startTime(RDLogLine::Predicted));
}
}
else { // Scheduled
if(ll->startTime(RDLogLine::Logged).isNull()) {
return QString("");
}
else {
return rda->tenthsTimeString(ll->startTime(RDLogLine::Logged));
}
}
break;
}
}
return QString();
}
int RDLogModel::LoadLines(const QString &logname,int id_offset,bool track_ptrs)
{
RDLogLine line;
RDSqlQuery *q1;
QString sql;
RDSqlQuery *q;
bool prev_custom=false;
unsigned lines=0;
unsigned start_line=d_log_lines.size();
//
// Load the group color table
//
std::map<QString,QColor> group_colors;
sql=QString("select ")+
"`NAME`,"+ // 00
"`COLOR` "+ // 01
"from `GROUPS`";
q=new RDSqlQuery(sql);
while(q->next()) {
group_colors[q->value(0).toString()]=QColor(q->value(1).toString());
}
delete q;
//
// Load log lines
//
sql=QString("select ")+
"`LOG_LINES`.`LINE_ID`,"+ // 00
"`LOG_LINES`.`CART_NUMBER`,"+ // 01
"`LOG_LINES`.`START_TIME`,"+ // 02
"`LOG_LINES`.`TIME_TYPE`,"+ // 03
"`LOG_LINES`.`TRANS_TYPE`,"+ // 04
"`LOG_LINES`.`START_POINT`,"+ // 05
"`LOG_LINES`.`END_POINT`,"+ // 06
"`LOG_LINES`.`SEGUE_START_POINT`,"+ // 07
"`LOG_LINES`.`SEGUE_END_POINT`,"+ // 08
"`CART`.`TYPE`,"+ // 09
"`CART`.`GROUP_NAME`,"+ // 10
"`CART`.`TITLE`,"+ // 11
"`CART`.`ARTIST`,"+ // 12
"`CART`.`ALBUM`,"+ // 13
"`CART`.`YEAR`,"+ // 14
"`CART`.`LABEL`,"+ // 15
"`CART`.`CLIENT`,"+ // 16
"`CART`.`AGENCY`,"+ // 17
"`CART`.`USER_DEFINED`,"+ // 18
"`CART`.`CONDUCTOR`,"+ // 19
"`CART`.`SONG_ID`,"+ // 20
"`CART`.`FORCED_LENGTH`,"+ // 21
"`CART`.`CUT_QUANTITY`,"+ // 22
"`CART`.`LAST_CUT_PLAYED`,"+ // 23
"`CART`.`PLAY_ORDER`,"+ // 24
"`CART`.`ENFORCE_LENGTH`,"+ // 25
"`CART`.`PRESERVE_PITCH`,"+ // 26
"`LOG_LINES`.`TYPE`,"+ // 27
"`LOG_LINES`.`COMMENT`,"+ // 28
"`LOG_LINES`.`LABEL`,"+ // 29
"`LOG_LINES`.`GRACE_TIME`,"+ // 30
"`LOG_LINES`.`SOURCE`,"+ // 31
"`LOG_LINES`.`EXT_START_TIME`,"+ // 32
"`LOG_LINES`.`EXT_LENGTH`,"+ // 33
"`LOG_LINES`.`EXT_DATA`,"+ // 34
"`LOG_LINES`.`EXT_EVENT_ID`,"+ // 35
"`LOG_LINES`.`EXT_ANNC_TYPE`,"+ // 36
"`LOG_LINES`.`EXT_CART_NAME`,"+ // 37
"`CART`.`ASYNCRONOUS`,"+ // 38
"`LOG_LINES`.`FADEUP_POINT`,"+ // 39
"`LOG_LINES`.`FADEUP_GAIN`,"+ // 40
"`LOG_LINES`.`FADEDOWN_POINT`,"+ // 41
"`LOG_LINES`.`FADEDOWN_GAIN`,"+ // 42
"`LOG_LINES`.`SEGUE_GAIN`,"+ // 43
"`CART`.`PUBLISHER`,"+ // 44
"`CART`.`COMPOSER`,"+ // 45
"`CART`.`USAGE_CODE`,"+ // 46
"`CART`.`AVERAGE_SEGUE_LENGTH`,"+ // 47
"`LOG_LINES`.`LINK_EVENT_NAME`,"+ // 48
"`LOG_LINES`.`LINK_START_TIME`,"+ // 49
"`LOG_LINES`.`LINK_LENGTH`,"+ // 50
"`LOG_LINES`.`LINK_ID`,"+ // 51
"`LOG_LINES`.`LINK_EMBEDDED`,"+ // 52
"`LOG_LINES`.`ORIGIN_USER`,"+ // 53
"`LOG_LINES`.`ORIGIN_DATETIME`,"+ // 54
"`CART`.`VALIDITY`,"+ // 55
"`LOG_LINES`.`LINK_START_SLOP`,"+ // 56
"`LOG_LINES`.`LINK_END_SLOP`,"+ // 57
"`LOG_LINES`.`DUCK_UP_GAIN`,"+ // 58
"`LOG_LINES`.`DUCK_DOWN_GAIN`,"+ // 59
"`CART`.`START_DATETIME`,"+ // 60
"`CART`.`END_DATETIME`,"+ // 61
"`LOG_LINES`.`EVENT_LENGTH`,"+ // 62
"`CART`.`USE_EVENT_LENGTH`,"+ // 63
"`CART`.`NOTES` "+ // 64
"from `LOG_LINES` left join `CART` "+
"on `LOG_LINES`.`CART_NUMBER`=`CART`.`NUMBER` where "+
"`LOG_LINES`.`LOG_NAME`='"+RDEscapeString(logname)+"' "+
"order by `COUNT`";
q=new RDSqlQuery(sql);
if(q->size()<=0) {
delete q;
return 0;
}
beginInsertRows(QModelIndex(),lineCount(),q->size()+lineCount()-1);
for(int i=0;i<q->size();i++) {
lines++;
line.clear();
q->next();
line.setType((RDLogLine::Type)q->value(27).toInt()); // Type
line.setId(q->value(0).toInt()+id_offset); // Log Line ID
if((q->value(0).toInt()+id_offset)>d_max_id) {
d_max_id=q->value(0).toInt()+id_offset;
}
line.setStartTime(RDLogLine::Imported,
QTime(0,0,0).addMSecs(q->value(2).toInt())); // Start Time
line.setStartTime(RDLogLine::Logged,
QTime(0,0,0).addMSecs(q->value(2).toInt()));
line.
setTimeType((RDLogLine::TimeType)q->value(3).toInt()); // Time Type
line.
setTransType((RDLogLine::TransType)q->value(4).toInt()); // Trans Type
line.setMarkerComment(q->value(28).toString()); // Comment
line.setMarkerLabel(q->value(29).toString()); // Label
line.setGraceTime(q->value(30).toInt()); // Grace Time
line.setUseEventLength(RDBool(q->value(63).toString())); // Use Event Length
line.setEventLength(q->value(62).toInt()); // Event Length
line.setSource((RDLogLine::Source)q->value(31).toUInt());
line.setLinkEventName(q->value(48).toString()); // Link Event Name
line.setLinkStartTime(QTime(0,0,0).addMSecs(q->value(49).toInt())); // Link Start Time
line.setLinkLength(q->value(50).toInt()); // Link Length
line.setLinkStartSlop(q->value(56).toInt()); // Link Start Slop
line.setLinkEndSlop(q->value(57).toInt()); // Link End Slop
line.setLinkId(q->value(51).toInt()); // Link ID
line.setLinkEmbedded(RDBool(q->value(52).toString())); // Link Embedded
line.setOriginUser(q->value(53).toString()); // Origin User
line.setOriginDateTime(q->value(54).toDateTime()); // Origin DateTime
switch(line.type()) {
case RDLogLine::Cart:
line.setCartNumber(q->value(1).toUInt()); // Cart Number
line.setStartPoint(q->value(5).toInt(),RDLogLine::LogPointer);
line.setEndPoint(q->value(6).toInt(),RDLogLine::LogPointer);
line.setSegueStartPoint(q->value(7).toInt(),RDLogLine::LogPointer);
line.setSegueEndPoint(q->value(8).toInt(),RDLogLine::LogPointer);
line.setCartType((RDCart::Type)q->value(9).toInt()); // Cart Type
line.setGroupName(q->value(10).toString()); // Group Name
line.setGroupColor(group_colors[q->value(10).toString()]);
line.setTitle(q->value(11).toString()); // Title
line.setArtist(q->value(12).toString()); // Artist
line.setPublisher(q->value(44).toString()); // Publisher
line.setComposer(q->value(45).toString()); // Composer
line.setAlbum(q->value(13).toString()); // Album
line.setYear(q->value(14).toDate()); // Year
line.setLabel(q->value(15).toString()); // Label
line.setClient(q->value(16).toString()); // Client
line.setAgency(q->value(17).toString()); // Agency
line.setUserDefined(q->value(18).toString()); // User Defined
line.setCartNotes(q->value(64).toString()); // Cart Notes
line.setConductor(q->value(19).toString()); // Conductor
line.setSongId(q->value(20).toString()); // Song ID
line.setUsageCode((RDCart::UsageCode)q->value(46).toInt());
line.setForcedLength(q->value(21).toUInt()); // Forced Length
if(q->value(7).toInt()<0) {
line.setAverageSegueLength(q->value(47).toInt());
}
else {
line.
setAverageSegueLength(q->value(7).toInt()-q->value(5).toInt());
}
line.setCutQuantity(q->value(22).toUInt()); // Cut Quantity
line.setLastCutPlayed(q->value(23).toUInt()); // Last Cut Played
line.
setPlayOrder((RDCart::PlayOrder)q->value(24).toUInt()); // Play Ord
line.
setEnforceLength(RDBool(q->value(25).toString())); // Enforce Length
line.
setPreservePitch(RDBool(q->value(26).toString())); // Preserve Pitch
if(!q->value(32).isNull()) { // Ext Start Time
line.setExtStartTime(q->value(32).toTime());
}
if(!q->value(33).isNull()) { // Ext Length
line.setExtLength(q->value(33).toInt());
}
if(!q->value(34).isNull()) { // Ext Data
line.setExtData(q->value(34).toString());
}
if(!q->value(35).isNull()) { // Ext Event ID
line.setExtEventId(q->value(35).toString());
}
if(!q->value(36).isNull()) { // Ext Annc. Type
line.setExtAnncType(q->value(36).toString());
}
if(!q->value(37).isNull()) { // Ext Cart Name
line.setExtCartName(q->value(37).toString());
}
if(!q->value(39).isNull()) { // FadeUp Point
line.setFadeupPoint(q->value(39).toInt(),RDLogLine::LogPointer);
}
if(!q->value(40).isNull()) { // FadeUp Gain
line.setFadeupGain(q->value(40).toInt());
}
if(!q->value(41).isNull()) { // FadeDown Point
line.setFadedownPoint(q->value(41).toInt(),RDLogLine::LogPointer);
}
if(!q->value(42).isNull()) { // FadeDown Gain
line.setFadedownGain(q->value(42).toInt());
}
if(!q->value(43).isNull()) { // Segue Gain
line.setSegueGain(q->value(43).toInt());
}
if(!q->value(58).isNull()) { // Duck Up Gain
line.setDuckUpGain(q->value(58).toInt());
}
if(!q->value(59).isNull()) { // Duck Down Gain
line.setDuckDownGain(q->value(59).toInt());
}
if(!q->value(60).isNull()) { // Start Datetime
line.setStartDatetime(q->value(60).toDateTime());
}
if(!q->value(61).isNull()) { // End Datetime
line.setEndDatetime(q->value(61).toDateTime());
}
line.setValidity((RDCart::Validity)q->value(55).toInt()); // Validity
break;
case RDLogLine::Macro:
line.setCartNumber(q->value(1).toUInt()); // Cart Number
line.setCartType((RDCart::Type)q->value(9).toInt()); // Cart Type
line.setGroupName(q->value(10).toString()); // Group Name
line.setGroupColor(group_colors[q->value(10).toString()]);
line.setTitle(q->value(11).toString()); // Title
line.setArtist(q->value(12).toString()); // Artist
line.setPublisher(q->value(44).toString()); // Publisher
line.setComposer(q->value(45).toString()); // Composer
line.setAlbum(q->value(13).toString()); // Album
line.setYear(q->value(14).toDate()); // Year
line.setLabel(q->value(15).toString()); // Label
line.setClient(q->value(16).toString()); // Client
line.setAgency(q->value(17).toString()); // Agency
line.setUserDefined(q->value(18).toString()); // User Defined
line.setCartNotes(q->value(64).toString()); // Cart Notes
line.setForcedLength(q->value(21).toUInt()); // Forced Length
line.setAverageSegueLength(q->value(21).toInt());
if(!q->value(32).isNull()) { // Ext Start Time
line.setExtStartTime(q->value(32).toTime());
}
if(!q->value(33).isNull()) { // Ext Length
line.setExtLength(q->value(33).toInt());
}
if(!q->value(34).isNull()) { // Ext Data
line.setExtData(q->value(34).toString());
}
if(!q->value(35).isNull()) { // Ext Event ID
line.setExtEventId(q->value(35).toString());
}
if(!q->value(36).isNull()) { // Ext Annc. Type
line.setExtAnncType(q->value(36).toString());
}
if(!q->value(37).isNull()) { // Ext Cart Name
line.setExtCartName(q->value(37).toString());
}
if(!q->value(38).isNull()) { // Asyncronous
line.setAsyncronous(RDBool(q->value(38).toString()));
}
break;
case RDLogLine::Marker:
break;
case RDLogLine::Track:
break;
case RDLogLine::Chain:
sql=QString("select `DESCRIPTION` from `LOGS` where ")+
"`NAME`='"+RDEscapeString(line.markerLabel())+"'";
q1=new RDSqlQuery(sql);
if(q1->first()) {
line.setMarkerComment(q1->value(0).toString());
}
delete q1;
break;
default:
break;
}
line.setHasCustomTransition(prev_custom||(q->value(5).toInt()>=0)||\
(q->value(39).toInt()>=0));
if(line.type()==RDLogLine::Cart) {
prev_custom=(q->value(6).toInt()>=0)||(q->value(7).toInt()>=0)||
(q->value(8).toInt()>=0)||(q->value(41).toInt()>=0);
}
else {
prev_custom=false;
}
line.clearModified();
d_log_lines.push_back(new RDLogLine(line));
}
endInsertRows();
delete q;
if(track_ptrs) {
//
// Load default cart pointers for "representative" cuts. This is
// really only useful when setting up a voice tracker.
//
for(int i=start_line;i<lineCount();i++) {
RDLogLine *ll=logLine(i);
if(ll->cartType()==RDCart::Audio) {
sql=QString("select ")+
"`START_POINT`,"+ // 00
"`END_POINT`,"+ // 01
"`SEGUE_START_POINT`,"+ // 02
"`SEGUE_END_POINT`,"+ // 03
"`TALK_START_POINT`,"+ // 04
"`TALK_END_POINT`,"+ // 05
"`HOOK_START_POINT`,"+ // 06
"`HOOK_END_POINT`,"+ // 07
"`FADEUP_POINT`,"+ // 08
"`FADEDOWN_POINT`,"+ // 09
"`CUT_NAME`,"+ // 10
"`ORIGIN_NAME`,"+ // 11
"`ORIGIN_DATETIME`,"+ // 12
"`DESCRIPTION`,"+ // 13
"`ISRC`,"+ // 14
"`ISCI`,"+ // 15
"`RECORDING_MBID`,"+ // 16
"`RELEASE_MBID` "+ // 17
"from `CUTS` where "+
QString::asprintf("`CART_NUMBER`=%u ",ll->cartNumber())+
"order by `CUT_NAME`";
q=new RDSqlQuery(sql);
if(q->first()) {
ll->setStartPoint(q->value(0).toInt(),RDLogLine::CartPointer);
ll->setEndPoint(q->value(1).toInt(),RDLogLine::CartPointer);
ll->setSegueStartPoint(q->value(2).toInt(),RDLogLine::CartPointer);
ll->setSegueEndPoint(q->value(3).toInt(),RDLogLine::CartPointer);
ll->setTalkStartPoint(q->value(4).toInt());
ll->setTalkEndPoint(q->value(5).toInt());
ll->setHookStartPoint(q->value(6).toInt());
ll->setHookEndPoint(q->value(7).toInt());
ll->setFadeupPoint(q->value(8).toInt(),RDLogLine::CartPointer);
ll->setFadedownPoint(q->value(9).toInt(),RDLogLine::CartPointer);
ll->setCutNumber(RDCut::cutNumber(q->value(10).toString()));
ll->setOriginUser(q->value(11).toString());
ll->setOriginDateTime(q->value(12).toDateTime());
ll->setDescription(q->value(13).toString());
ll->setIsrc(q->value(14).toString());
ll->setIsci(q->value(15).toString());
ll->setRecordingMbId(q->value(16).toString());
ll->setReleaseMbId(q->value(17).toString());
}
delete q;
}
}
}
return lines;
}
void RDLogModel::InsertLines(QString values) {
QString sql;
RDSqlQuery *q;
sql = QString("insert into LOG_LINES (")+
"`LOG_NAME`,"+ // 00
"`LINE_ID`,"+ // 01
"`COUNT`,"+ // 02
"`CART_NUMBER`,"+ // 03
"`START_TIME`,"+ // 04
"`TIME_TYPE`,"+ // 05
"`TRANS_TYPE`,"+ // 06
"`START_POINT`,"+ // 07
"`END_POINT`,"+ // 08
"`SEGUE_START_POINT`,"+ // 09
"`SEGUE_END_POINT`,"+ // 10
"`TYPE`,"+ // 11
"`COMMENT`,"+ // 12
"`LABEL`,"+ // 13
"`GRACE_TIME`,"+ // 14
"`SOURCE`,"+ // 15
"`EXT_START_TIME`,"+ // 16
"`EXT_LENGTH`,"+ // 17
"`EXT_DATA`,"+ // 18
"`EXT_EVENT_ID`,"+ // 19
"`EXT_ANNC_TYPE`,"+ // 20
"`EXT_CART_NAME`,"+ // 21
"`FADEUP_POINT`,"+ // 22
"`FADEUP_GAIN`,"+ // 23
"`FADEDOWN_POINT`,"+ // 24
"`FADEDOWN_GAIN`,"+ // 25
"`SEGUE_GAIN`,"+ // 26
"`LINK_EVENT_NAME`,"+ // 27
"`LINK_START_TIME`,"+ // 28
"`LINK_LENGTH`,"+ // 29
"`LINK_ID`,"+ // 30
"`LINK_EMBEDDED`,"+ // 31
"`ORIGIN_USER`,"+ // 32
"`ORIGIN_DATETIME`,"+ // 33
"`LINK_START_SLOP`,"+ // 34
"`LINK_END_SLOP`,"+ // 35
"`DUCK_UP_GAIN`,"+ // 36
"`DUCK_DOWN_GAIN`,"+ // 37
"`EVENT_LENGTH`) "+ // 38
"values "+values;
q=new RDSqlQuery(sql);
delete q;
}
void RDLogModel::InsertLineValues(QString *query, int line)
{
// one line to save query space
RDLogLine *ll=d_log_lines[line];
QString sql=QString("(")+
"'"+RDEscapeString(d_log_name)+"',"+
QString::asprintf("%d,",ll->id())+
QString::asprintf("%d,",line)+
QString::asprintf("%u,",ll->cartNumber())+
QString::asprintf("%d,",QTime(0,0,0).msecsTo(ll->startTime(RDLogLine::Logged)))+
QString::asprintf("%d,",ll->timeType())+
QString::asprintf("%d,",ll->transType())+
QString::asprintf("%d,",ll->startPoint(RDLogLine::LogPointer))+
QString::asprintf("%d,",ll->endPoint(RDLogLine::LogPointer))+
QString::asprintf("%d,",ll->segueStartPoint(RDLogLine::LogPointer))+
QString::asprintf("%d,",ll->segueEndPoint(RDLogLine::LogPointer))+
QString::asprintf("%d,",ll->type())+
"'"+RDEscapeString(ll->markerComment())+"',"+
"'"+RDEscapeString(ll->markerLabel())+"',"+
QString::asprintf("%d,",ll->graceTime())+
QString::asprintf("%d,",ll->source())+
RDCheckDateTime(ll->extStartTime(),"hh:mm:ss")+","+
QString::asprintf("%d,",ll->extLength())+
"'"+RDEscapeString(ll->extData())+"',"+
"'"+RDEscapeString(ll->extEventId())+"',"+
"'"+RDEscapeString(ll->extAnncType())+"',"+
"'"+RDEscapeString(ll->extCartName())+"',"+
QString::asprintf("%d,",ll->fadeupPoint(RDLogLine::LogPointer))+
QString::asprintf("%d,",ll->fadeupGain())+
QString::asprintf("%d,",ll->fadedownPoint(RDLogLine::LogPointer))+
QString::asprintf("%d,",ll->fadedownGain())+
QString::asprintf("%d,",ll->segueGain())+
"'"+RDEscapeString(ll->linkEventName())+"',"+
QString::asprintf("%d,",QTime(0,0,0).msecsTo(ll->linkStartTime()))+
QString::asprintf("%d,",ll->linkLength())+
QString::asprintf("%d,",ll->linkId())+
"'"+RDYesNo(ll->linkEmbedded())+"',"+
"'"+RDEscapeString(ll->originUser())+"',"+
RDCheckDateTime(ll->originDateTime(),"yyyy-MM-dd hh:mm:ss")+","+
QString::asprintf("%d,",ll->linkStartSlop())+
QString::asprintf("%d,",ll->linkEndSlop())+
QString::asprintf("%d,",ll->duckUpGain())+
QString::asprintf("%d,",ll->duckDownGain())+
QString::asprintf("%d)",ll->eventLength());
*query += sql;
}
void RDLogModel::SaveLine(int line)
{
QString values = "";
InsertLineValues(&values, line);
InsertLines(values);
}
void RDLogModel::emitDataChanged(int row)
{
QModelIndex left=createIndex(row,0);
QModelIndex right=createIndex(row,columnCount());
emit dataChanged(left,right);
}
void RDLogModel::emitAllDataChanged()
{
QModelIndex left=createIndex(0,0);
QModelIndex right=createIndex(lineCount(),columnCount());
emit dataChanged(left,right);
}
QStringList RDLogModel::headerTexts() const
{
QStringList ret;
ret.push_back(tr("Est. Time")); // 00
ret.push_back(tr("Trans")); // 01
ret.push_back(tr("Cart")); // 02
ret.push_back(tr("Group")); // 03
ret.push_back(tr("Length")); // 04
ret.push_back(tr("Title")); // 05
ret.push_back(tr("Artist")); // 06
ret.push_back(tr("Sch. Time")); // 07
ret.push_back(tr("Client")); // 08
ret.push_back(tr("Agency")); // 09
ret.push_back(tr("Label")); // 10
ret.push_back(tr("Source")); // 11
ret.push_back(tr("Ext Data")); // 12
ret.push_back(tr("Line ID")); // 13
ret.push_back(tr("Count")); // 14
return ret;
}
QList<int> RDLogModel::columnAlignments() const
{
QList<int> ret;
int left=Qt::AlignLeft|Qt::AlignVCenter;
int center=Qt::AlignCenter;
int right=Qt::AlignRight|Qt::AlignVCenter;
ret.push_back(right); // Estimated Time
ret.push_back(center); // Trans
ret.push_back(center); // Cart
ret.push_back(center); // Group
ret.push_back(right); // Length
ret.push_back(left); // Title
ret.push_back(left); // Artist
ret.push_back(right); // Scheduled Time
ret.push_back(left); // Client
ret.push_back(left); // Agency
ret.push_back(left); // Label
ret.push_back(left); // Source
ret.push_back(left); // Ext Data
ret.push_back(right); // Line ID
ret.push_back(right); // Count
return ret;
}
QPixmap RDLogModel::cellIcon(int col,int row,RDLogLine *ll) const
{
if(col==0) {
return rda->iconEngine()->typeIcon(ll->type(),ll->source());
}
return QPixmap();
}
QString RDLogModel::cellText(int col,int line,RDLogLine *ll) const
{
switch(col) {
case 0: // Start Time
return StartTimeString(line);
case 1: // Transition
return RDLogLine::transText(ll->transType());
case 2: // Cart Number
return ll->cartNumberText();
case 3: // Group
return ll->groupName();
case 4: // Length
return ll->forcedLengthText();
case 5: // Title
return ll->titleText();
case 6: // Artist
return ll->artist();
case 7: // Scheduled Time
return rda->timeString(ll->startTime(RDLogLine::Imported));
case 8: // Client
return ll->client();
case 9: // Agency
return ll->agency();
case 10: // Label
return ll->markerLabel();
case 11: // Source
return RDLogLine::sourceText(ll->source());
case 12: // Ext Data
switch(ll->type()) {
case RDLogLine::MusicLink:
case RDLogLine::TrafficLink:
return ll->linkSummaryText();
case RDLogLine::Cart:
case RDLogLine::Marker:
case RDLogLine::Macro:
case RDLogLine::OpenBracket:
case RDLogLine::CloseBracket:
case RDLogLine::Chain:
case RDLogLine::Track:
case RDLogLine::UnknownType:
return ll->extData();
}
break;
case 13: // Line ID
return QString::asprintf("%d",ll->id());
case 14: // Count
return QString::asprintf("%d",line);
}
return QString();
}
QFont RDLogModel::cellTextFont(int col,int line,RDLogLine *ll) const
{
if(col==3) {
return d_bold_font;
}
return d_font;
}
QColor RDLogModel::cellTextColor(int col,int line,RDLogLine *ll) const
{
switch(col) {
case 0:
if(ll->timeType()==RDLogLine::Hard) {
return Qt::blue;
}
break;
case 3:
return ll->groupColor();
}
return RDGetTextColor(rowBackgroundColor(line,ll));
}
QColor RDLogModel::rowBackgroundColor(int line,RDLogLine *ll) const
{
return d_palette.color(QPalette::Base);
}
void RDLogModel::MakeModel()
{
d_fms=NULL;
d_bold_fms=NULL;
d_start_time_style=RDLogModel::Scheduled;
d_max_id=0;
QStringList headers=headerTexts();
QList<int> alignments=columnAlignments();
if(headers.size()!=alignments.size()) {
fprintf(stderr,"header/alignment size mismatch\n");
exit(1);
}
for(int i=0;i<headers.size();i++) {
d_headers.push_back(headers.at(i));
d_alignments.push_back(alignments.at(i));
d_size_hints.push_back(QVariant());
}
}