mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-05-20 15:02:27 +02:00
* Split the 'RDApplication' class into the base class 'RDCoreApplication' and 'RDApplication'. Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
1663 lines
46 KiB
C++
1663 lines
46 KiB
C++
// rdlogmodel.cpp
|
|
//
|
|
// Data model for Rivendell logs
|
|
//
|
|
// (C) Copyright 2020 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 <stdio.h>
|
|
|
|
#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)
|
|
{
|
|
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);
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
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)
|
|
{
|
|
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().sprintf("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) {
|
|
beginRemoveRows(QModelIndex(),0,lineCount()-1);
|
|
for(int i=0;i<d_log_lines.size();i++) {
|
|
delete d_log_lines.at(i);
|
|
}
|
|
d_log_lines.clear();
|
|
endRemoveRows();
|
|
}
|
|
d_log_name="";
|
|
d_max_id=0;
|
|
}
|
|
|
|
|
|
int RDLogModel::validate(QString *report,const QDate &date)
|
|
{
|
|
QString sql;
|
|
RDSqlQuery *q;
|
|
RDSqlQuery *q1;
|
|
int errs=0;
|
|
|
|
//
|
|
// Report Header
|
|
//
|
|
*report="Rivendell Log Exception Report\n";
|
|
*report+=QString("Generated at: ")+
|
|
QDate::currentDate().toString("MM/dd/yyyy")+" - "+
|
|
QTime::currentTime().toString("hh:mm:ss")+"\n";
|
|
*report+=QString("Log: ")+d_log_name+"\n";
|
|
*report+=QString("Effective Airdate: ")+date.toString("MM/dd/yyyy")+"\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().sprintf("NUMBER=%d",logLine(i)->cartNumber());
|
|
q=new RDSqlQuery(sql);
|
|
if(!q->first()) {
|
|
*report+=QString(" ")+
|
|
logLine(i)->startTime(RDLogLine::Logged).toString("hh:mm:ss")+
|
|
QString().sprintf(" - 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().sprintf("(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().sprintf("(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(" ")+
|
|
logLine(i)->startTime(RDLogLine::Logged).toString("hh:mm:ss")+
|
|
QString().sprintf(" - 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().sprintf("%d validation exception found.\n\n",errs);
|
|
}
|
|
else {
|
|
*report+=QString().sprintf("%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().sprintf("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) {
|
|
switch(ll->timeType()) {
|
|
case RDLogLine::Hard:
|
|
return QString("T")+ll->startTime(RDLogLine::Logged).
|
|
toString("hh:mm:ss.zzz").left(10);
|
|
break;
|
|
|
|
default:
|
|
if(d_start_time_style==RDLogModel::Estimated) {
|
|
if(ll->startTime(RDLogLine::Predicted).isNull()) {
|
|
return blockStartTime(line).toString("hh:mm:ss.zzz").left(10);
|
|
}
|
|
else {
|
|
return ll->startTime(RDLogLine::Predicted).
|
|
toString("hh:mm:ss.zzz").left(10);
|
|
}
|
|
}
|
|
else { // Scheduled
|
|
if(ll->startTime(RDLogLine::Logged).isNull()) {
|
|
return QString("");
|
|
}
|
|
else {
|
|
return ll->startTime(RDLogLine::Logged).
|
|
toString("hh:mm:ss.zzz").left(10);
|
|
}
|
|
}
|
|
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="select NAME,COLOR 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;
|
|
}
|
|
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().addMSecs(q->value(2).toInt())); // Start Time
|
|
line.setStartTime(RDLogLine::Logged,
|
|
QTime().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().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));
|
|
}
|
|
delete q;
|
|
|
|
LoadNowNext(start_line);
|
|
|
|
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
|
|
"from CUTS where "+
|
|
QString().sprintf("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());
|
|
}
|
|
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().sprintf("%d,",ll->id())+
|
|
QString().sprintf("%d,",line)+
|
|
QString().sprintf("%u,",ll->cartNumber())+
|
|
QString().sprintf("%d,",QTime().msecsTo(ll->startTime(RDLogLine::Logged)))+
|
|
QString().sprintf("%d,",ll->timeType())+
|
|
QString().sprintf("%d,",ll->transType())+
|
|
QString().sprintf("%d,",ll->startPoint(RDLogLine::LogPointer))+
|
|
QString().sprintf("%d,",ll->endPoint(RDLogLine::LogPointer))+
|
|
QString().sprintf("%d,",ll->segueStartPoint(RDLogLine::LogPointer))+
|
|
QString().sprintf("%d,",ll->segueEndPoint(RDLogLine::LogPointer))+
|
|
QString().sprintf("%d,",ll->type())+
|
|
"\""+RDEscapeString(ll->markerComment())+"\","+
|
|
"\""+RDEscapeString(ll->markerLabel())+"\","+
|
|
QString().sprintf("%d,",ll->graceTime())+
|
|
QString().sprintf("%d,",ll->source())+
|
|
RDCheckDateTime(ll->extStartTime(),"hh:mm:ss")+","+
|
|
QString().sprintf("%d,",ll->extLength())+
|
|
"\""+RDEscapeString(ll->extData())+"\","+
|
|
"\""+RDEscapeString(ll->extEventId())+"\","+
|
|
"\""+RDEscapeString(ll->extAnncType())+"\","+
|
|
"\""+RDEscapeString(ll->extCartName())+"\","+
|
|
QString().sprintf("%d,",ll->fadeupPoint(RDLogLine::LogPointer))+
|
|
QString().sprintf("%d,",ll->fadeupGain())+
|
|
QString().sprintf("%d,",ll->fadedownPoint(RDLogLine::LogPointer))+
|
|
QString().sprintf("%d,",ll->fadedownGain())+
|
|
QString().sprintf("%d,",ll->segueGain())+
|
|
"\""+RDEscapeString(ll->linkEventName())+"\","+
|
|
QString().sprintf("%d,",QTime().msecsTo(ll->linkStartTime()))+
|
|
QString().sprintf("%d,",ll->linkLength())+
|
|
QString().sprintf("%d,",ll->linkId())+
|
|
"\""+RDYesNo(ll->linkEmbedded())+"\","+
|
|
"\""+RDEscapeString(ll->originUser())+"\","+
|
|
RDCheckDateTime(ll->originDateTime(),"yyyy-MM-dd hh:mm:ss")+","+
|
|
QString().sprintf("%d,",ll->linkStartSlop())+
|
|
QString().sprintf("%d,",ll->linkEndSlop())+
|
|
QString().sprintf("%d,",ll->duckUpGain())+
|
|
QString().sprintf("%d,",ll->duckDownGain())+
|
|
QString().sprintf("%d)",ll->eventLength());
|
|
*query += sql;
|
|
}
|
|
|
|
void RDLogModel::SaveLine(int line)
|
|
{
|
|
QString values = "";
|
|
InsertLineValues(&values, line);
|
|
InsertLines(values);
|
|
}
|
|
|
|
|
|
void RDLogModel::LoadNowNext(unsigned from_line)
|
|
{
|
|
QStringList groups;
|
|
QList<bool> now_nexts;
|
|
|
|
//
|
|
// Load the Lookup Table
|
|
//
|
|
RDSqlQuery *q=new RDSqlQuery("select NAME,ENABLE_NOW_NEXT from GROUPS");
|
|
while(q->next()) {
|
|
groups.push_back(QString(q->value(0).toString()));
|
|
now_nexts.push_back(RDBool(q->value(1).toString()));
|
|
}
|
|
delete q;
|
|
|
|
for(int i=from_line;i<d_log_lines.size();i++) {
|
|
for(int j=0;j<groups.size();j++) {
|
|
if(d_log_lines[i]->groupName()==groups[j]) {
|
|
d_log_lines[i]->setNowNextEnabled(now_nexts[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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("Start Time"));
|
|
ret.push_back(tr("Trans"));
|
|
ret.push_back(tr("Cart"));
|
|
ret.push_back(tr("Group"));
|
|
ret.push_back(tr("Length"));
|
|
ret.push_back(tr("Title"));
|
|
ret.push_back(tr("Artist"));
|
|
ret.push_back(tr("Client"));
|
|
ret.push_back(tr("Agency"));
|
|
ret.push_back(tr("Label"));
|
|
ret.push_back(tr("Source"));
|
|
ret.push_back(tr("Ext Data"));
|
|
ret.push_back(tr("Line ID"));
|
|
ret.push_back(tr("Count"));
|
|
|
|
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); // Start 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(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: // Client
|
|
return ll->client();
|
|
|
|
case 8: // Agency
|
|
return ll->agency();
|
|
|
|
case 9: // Label
|
|
return ll->markerLabel();
|
|
|
|
case 10: // Source
|
|
return RDLogLine::sourceText(ll->source());
|
|
|
|
case 11: // Ext Data
|
|
return ll->extData();
|
|
|
|
case 12: // Line ID
|
|
return QString().sprintf("%d",ll->id());
|
|
|
|
case 13: // Count
|
|
return QString().sprintf("%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 d_palette.color(QPalette::Foreground);
|
|
}
|
|
|
|
|
|
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));
|
|
}
|
|
}
|