Subversion Repositories svn1-original

Rev

Rev 347 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "qmdialoguploadlegtimes.h"
#include "qmdialoguploadlegtimes_ui.cpp"
#include "QTableWidgetItem"
#include "QFile"
#include "QString"
#include "QFileDialog"
#include "QClipboard"
#include "QRegExp"
#include "mainwindow.h"
#include "QTextStream"
#include "timedelegate.h"
#include "qmconfig.h"

#include    "consts.h"
#include    "structs.h"
#include    "proto.h"

QmDialogUploadLegTimes::QmDialogUploadLegTimes(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QmDialogUploadLegTimes)
{
    ui->setupUi(this);
    setSizeGripEnabled(true);
    ui->legNumber->setMaximum(config.num_legs);

    // Connect up buttons
    connect(ui->load, SIGNAL(clicked()), this, SLOT(load()));
    connect(ui->fromClip, SIGNAL(clicked()), this, SLOT(fromClip()));
    connect(ui->clear, SIGNAL(clicked()), this, SLOT(clear()));
    connect(ui->cancel,SIGNAL(clicked()), this, SLOT(close()));
    connect(ui->update,SIGNAL(clicked()), this, SLOT(update()));
    connect(ui->deltaTime, SIGNAL(timeChanged(QTime)), this, SLOT(updateDeltaDisplay()));
    connect(ui->hideOk, SIGNAL(clicked()), this, SLOT(updateDeltaDisplay()));


    // Set up the table
    // First column is not a 'time' column
    ui->tableWidget->setColumnCount(1);
    ui->tableWidget->setHorizontalHeaderItem ( 0, new QTableWidgetItem ("Team"));
    addColumn("Delta");
    addColumn("Used");
    addColumn("Time");

    // Wire up the table
    connect(ui->tableWidget,SIGNAL(itemDoubleClicked (QTableWidgetItem*)), this,SLOT(itemActivated(QTableWidgetItem*)));

    // Init status
    ui->status->setText("Load Leg File");
}

QmDialogUploadLegTimes::~QmDialogUploadLegTimes()
{
    delete ui;
}

void QmDialogUploadLegTimes::addColumn(QString hdr)
{
    int col = ui->tableWidget->columnCount();
    ui->tableWidget->insertColumn(col);

    // Insert header
    ui->tableWidget->setHorizontalHeaderItem ( col, new QTableWidgetItem (hdr));

    // Insert Time Delegate
    ui->tableWidget->setItemDelegateForColumn(col, new timeDelegate());
}

void QmDialogUploadLegTimes::clear(void)
{
    ui->tableWidget->clearContents();
    ui->tableWidget->setRowCount(0);

    // Update Error information
    updateDeltaDisplay();
}

void QmDialogUploadLegTimes::fromClip(void)
{
    QClipboard *clipboard = QApplication::clipboard();
    QString text = clipboard->text();
    if (text.length() > 0) {
        QStringList list = text.split(QRegExp("[\\r\\n]"));

        ui->status->setText("Loading Data");
        for (int i = 0; i < list.size(); ++i)
        {
            processOneLine(list.at(i));
        }

        // Update Error information
        updateDeltaDisplay();
    }
}
void QmDialogUploadLegTimes::processOneLine(QString line)
{
    QStringList parts;
    line = line.trimmed();             // Remove leading and training White Space
    if (line.size() <= 0)
        return;

    //  An array of possible imput parsers
    //
    QRegExp lineFormats[] = {
        QRegExp ("^(\\d+)\\s+(\\d+:\\d+:\\d+)$"),                           // 022 12:13:14
        QRegExp ("^(\\d+)\\s+\\d+-\\d+-\\d+\\s+(\\d+:\\d+:\\d+)\\.\\d+$"),  // 022 2019-08-01 12:13:14.123
        QRegExp ("^\\d+,(\\d+),(\\d+:\\d+:\\d+)$"),                         // 001,022,12:13:14
    };

    for( unsigned int idx = 0 ; idx <(sizeof(lineFormats)/sizeof(*lineFormats)); idx++ )
    {
        if(lineFormats[idx].indexIn(line) == 0)
        {
            parts = lineFormats[idx].capturedTexts();
        }
    }

    if ( parts.empty())
    {
        qDebug("Funny Line regex: %s", qPrintable(line));
        return;
    }

    QString first = parts.value(1);
    if ( parts.count() != 3)
    {
        qDebug("Funny Line parts: %s", qPrintable(line));
        return;
    }

    bool ok;
    int team = first.toInt(&ok);
    if ( ! ok || team <= 0 || team > 999 )
    {
        qDebug("Bad Team Number: %s", qPrintable(line));
        return;
    }
    if (team > ui->tableWidget->rowCount())
    {
        ui->tableWidget->setRowCount(team);
    }

    QTableWidgetItem *item = ui->tableWidget->item(team-1,0);
    if (!item)
    {
        item = new QTableWidgetItem(QString::number(team));
        item->setFlags(item->flags() & ~(Qt::ItemIsEditable|Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled));
        ui->tableWidget->setItem(team-1,0,item);
        item->setData(Qt::ToolTipRole,"Team Number");

        item = new QTableWidgetItem("");
        item->setFlags(item->flags() & ~(Qt::ItemIsEditable|Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled));
        ui->tableWidget->setItem(team-1,1,item);
        item->setData(Qt::ToolTipRole,"Max delta");

        item = new QTableWidgetItem("");
        item->setFlags(item->flags() & ~(Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled));
        ui->tableWidget->setItem(team-1,2,item);
        item->setData(Qt::ToolTipRole,"Use this data");
    }

    //  Insert the time at the first available slot
    //  Scan for max an min as we go
    int ii;
    QTableWidgetItem *titem = NULL;
    QTime ltime = QTime::fromString(parts.value(2),"hh:mm:ss");
    unsigned int lsecs = QTime(0,0,0).secsTo(ltime);
    if ( lsecs <= 0)
    {
        qDebug("Funny Line: %s", qPrintable(line));
        return;
    }
    //qDebug("Tead: %d, Secs: %d", team, lsecs );
    unsigned int min_time = lsecs;
    unsigned int max_time = lsecs;
    bool empty_cell_found = false;

    for (ii=3 ; ii <= ui->tableWidget->columnCount() - 1; ii++)
    {
        titem = ui->tableWidget->item(team-1,ii);
        if (! titem)
        {
            // Empty cell found
            empty_cell_found = true;
            break;
        }

        QTime entry = titem->data(Qt::EditRole).toTime();
        unsigned int secs = QTime(0,0,0).secsTo(entry);
        if ( secs < min_time )
            min_time = secs;
        if (secs > max_time)
            max_time = secs;
    }

    // No space found for the data - add a new column
    if ( ! empty_cell_found )
    {
        addColumn("Time");
        ii = ui->tableWidget->columnCount() - 1;
    }

    // Insert data into cell
    titem = new QTableWidgetItem();
    titem->setData(Qt::EditRole, ltime);
    titem->setFlags(titem->flags() & ~(Qt::ItemIsEditable|Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled));
    ui->tableWidget->setItem(team-1,ii,titem);
    //qDebug("Team: %d, %d of %d", team-1, ii, ui->tableWidget->columnCount() );

    if (ii == 3)
    {
        titem = new QTableWidgetItem();
        titem->setData(Qt::EditRole, ltime);
        ui->tableWidget->setItem(team-1,2,titem);
        titem->setBackgroundColor(QColor(0,255,0,30));
    }

    int delta = max_time - min_time;
    if ( delta )
    {
        ui->tableWidget->item(team-1,1)->setData(Qt::EditRole, QTime().addSecs(delta));
    }
}

void QmDialogUploadLegTimes::load(void)
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Load File"),
                                                 appSettings->value("LegTimeUpload/LastFile",filepath).toString(),
                                                 tr("Legs (*leg*);;Data (*.leg);;Text (*.txt);;Csv (*.csv);;All (*.*)"),
                                                 0,
                                                 QFileDialog::ReadOnly);
    if ( fileName.isEmpty() )
    {
        MainWindow::showMessage("No File Specified");
        return;
    }

    appSettings->setValue("LegTimeUpload/LastFile", fileName); 


    // Open the file

    QFile file(fileName);
    if ( ! file.open(QIODevice::ReadOnly | QIODevice::Text) )
    {
        MainWindow::showMessage("Cannot open Leg Data file");
        return;
    }
    ui->status->setText("Loading Data");
    // Insert column headers
    ui->tableWidget->clearContents();
    ui->tableWidget->setRowCount(0);


    // Process Each line of the file
    //  Format (original) is TeamNumber Time
    //  Format (alternate) is TeamNumber Date Time
    //                                       Time has milliseconds
    QTextStream in(&file);
    while (!in.atEnd())
    {
        processOneLine(in.readLine());
    }

    // Update Error information
    updateDeltaDisplay();

}

void QmDialogUploadLegTimes::updateDeltaDisplay( void )
{
    bool isFlagged = false;
    QTime maxDelta(0,0,0,0);
    QTime delta = ui->deltaTime->time();
    //qDebug("New Delta: %s", qPrintable(ui->deltaTime->time().toString()));
    for ( int ii = 0; ii < ui->tableWidget->rowCount(); ii++)
    {
        bool show = true;
        QTableWidgetItem *item;
        item = ui->tableWidget->item(ii, 1);
        if (item)
        {
            QTime time = item->data(Qt::EditRole).toTime();
            if ( time > maxDelta)
            {
                maxDelta = time;
            }
            if ( time > delta )
            {
                item->setBackgroundColor(QColor(255,0,0,50));
                isFlagged = true;
            }
            else
            {
                item->setBackgroundColor(QColor(255,255,255));
                if ( ui->hideOk->isChecked())
                {
                    show = false;
                }
            }
        }

        // Hide if not a valid time and we have no time ebtry for it
        if ( !valid_field(ii+1) && item == NULL )
        {
            show = false;
        }
        ui->tableWidget->setRowHidden(ii,!show);

    }
    //ui->maxDeltaTime->setText(QString::number(QTime(0,0,0).secsTo(maxDelta)));
    ui->maxDeltaTime->setText(maxDelta.toString("hh:mm:ss"));
    if (isFlagged)
    {
        ui->status->setText("Large Delta Times");
    }
    else
    {

    }
}

void QmDialogUploadLegTimes::update(void)
{
    team_type   team_buf;
    int leg = ui->legNumber->value() ;
    if (leg <= 0 || leg > config.num_legs)
    {
        ui->status->setText("Must select leg number");
        return;
    }

    // Insert the first time into the desired leg
    for ( int ii = 0; ii < ui->tableWidget->rowCount(); ii++)
    {
        QTableWidgetItem *item;
        item = ui->tableWidget->item(ii, 0);
        if (item)
        {
            int team = item->data(Qt::EditRole).toInt();
            if( valid_field( team ) && g_record( team, &team_buf ) )
            {
                item = ui->tableWidget->item(ii, 2);
                if (item)
                {
                    QTime time = item->data(Qt::EditRole).toTime();
                    int secs = QTime(0,0,0).secsTo(time);

                    if ( ui->legStart->isChecked())
                    {
                        team_buf.leg[leg].start = secs;
                        team_buf.leg[leg].manual = TRUE;
                    }
                    else
                    {
                        team_buf.leg[leg].end = secs;
                    }
                    set_times( &team_buf );                 /* Calc start of next leg */
                    test_times( &team_buf, 0 );             /* Calc elapsed times etc */
                    put_team_record( team, &team_buf );
                    ui->tableWidget->hideRow(ii);
                }
            }
        }
     }
}

void QmDialogUploadLegTimes::itemActivated ( QTableWidgetItem * uitem )
{
    // Use this item for the time, but only if the item is from a 'time' column
    if ( uitem->column() >= 3 )
    {
        QTableWidgetItem *titem = new QTableWidgetItem(*uitem);
        titem->setFlags(titem->flags()| Qt::ItemIsEditable);
        ui->tableWidget->setItem(uitem->row(),2,titem);
        titem->setBackgroundColor(QColor(0,0,255,30));
    }
}