Subversion Repositories svn1-original

Rev

Rev 230 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "qmconfclass.h"
#include "qmconfig.h"
#include "ui_qmconfclass.h"
#include    "consts.h"
#include    "structs.h"
#include    "proto.h"
#include "mainwindow.h"

#include "QTableWidgetItem"
#include "spinboxdelegate.h"
#include "timedelegate.h"
#include "textdelegate.h"
#include <QMenu>

#define COL_ABR 0
#define COL_CLASS 1
#define COL_TIME 2
#define COL_WINNERS 3
#define COL_NE 4
#define COL_NE_WINNERS 5
#define COL_ST_TOTAL 6
#define COL_ST_DISQ 7
#define COL_ST_NONEQ 8
#define COL_ST_VET 9
#define COL_COUNT 10


QmConfClass::QmConfClass(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QmConfClass)
{
    ui->setupUi(this);
    populating = false;
    connect(ui->pushButtonSave, SIGNAL(clicked(bool)), this, SLOT(save()) );
    connect(ui->pushButtonRestore, SIGNAL(clicked(bool)), this, SLOT(cancel()) );

    QStringList labels;
         labels << "Abr" << "Full Name" << "Start Time" << "Winners" << "NE" << "NE Winners";


    ui->tableWidget->setRowCount(config.num_class + 1);
    ui->tableWidget->setColumnCount(COL_COUNT);
    ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->tableWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &)));
    connect(ui->tableWidget, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int,int)));


    /*
    **  Setup delegated for specialised editing
    */
    ui->tableWidget->setItemDelegateForColumn(COL_ABR, new textDelegate(2));
    ui->tableWidget->setItemDelegateForColumn(COL_CLASS, new textDelegate(LEN_CLASS_NAME));
    ui->tableWidget->setItemDelegateForColumn(COL_TIME, new timeDelegate());
    ui->tableWidget->setItemDelegateForColumn(COL_WINNERS, new SpinBoxDelegate(0,50));
    ui->tableWidget->setItemDelegateForColumn(COL_NE_WINNERS, new SpinBoxDelegate(0,50));

    populate();


    // Wire in the status button
    connect(ui->statusButton, SIGNAL(clicked()), this, SLOT(updateStatus()));
    statusShown = false;
    ui->tableWidget->setColumnHidden(COL_ST_TOTAL, true);
    ui->tableWidget->setColumnHidden(COL_ST_DISQ, true);
    ui->tableWidget->setColumnHidden(COL_ST_NONEQ, true);
    ui->tableWidget->setColumnHidden(COL_ST_VET, true);

    labels << "Total" <<"Disqual" << "NonEq" << "VetCheck";

    ui->tableWidget->setHorizontalHeaderLabels(labels);
    ui->tableWidget->resizeColumnsToContents();

}

void QmConfClass::populate(void)
{
    populating = true;
    ui->tableWidget->setRowCount(config.num_class + 1);
    for ( int ii = 0; ii < MAX_CLASS; ii++)
    {
        ui->tableWidget->setItem(ii, COL_ABR, new QTableWidgetItem(config.team_class[ii].abr) );
        ui->tableWidget->setItem(ii, COL_CLASS, new QTableWidgetItem(config.team_class[ii].full_name ));

        if ( *config.team_class[ii].abr )
        {
            QTableWidgetItem *item;
            item = new QTableWidgetItem();
            item->setData(Qt::EditRole,QTime().addSecs(config.team_class[ii].start) );
            ui->tableWidget->setItem(ii, COL_TIME, item);

            item = new QTableWidgetItem();
            item->setData(Qt::EditRole,config.class_winners[ii] );
            ui->tableWidget->setItem(ii, COL_WINNERS, item);

            item = new QTableWidgetItem();
            item->setCheckState(config.nonequestrian_class == 1 + ii ? Qt::Checked : Qt::Unchecked);
            ui->tableWidget->setItem(ii, COL_NE, item);

            item = new QTableWidgetItem();
            item->setData(Qt::EditRole,config.class_ne_winners[ii] );
            ui->tableWidget->setItem(ii, COL_NE_WINNERS, item);
        }
    }
    updateChanged(false);
    populating = false;
}

void QmConfClass::save(void)
{
    /*
    **    Copy original data
    */
    QmConfig newcfg(config);

    /*
    **  Extract the data from the Widgets
    */
    for ( int ii = 0; ii < MAX_CLASS; ii++)
    {
        QTableWidgetItem *item = ui->tableWidget->item ( ii, COL_ABR );
        if ( item )
        {
            strncpy(newcfg.team_class[ii].abr, qPrintable(item->text()), sizeof(newcfg.team_class[ii].abr)-1);
        }
        else
        {
            *newcfg.team_class[ii].abr = 0;
        }

        item = ui->tableWidget->item ( ii, COL_CLASS );
        if ( item )
        {
            strncpy(newcfg.team_class[ii].full_name, qPrintable(item->text()), sizeof(newcfg.team_class[ii].full_name)-1);
        }
        else
        {
            *newcfg.team_class[ii].full_name = 0;
        }

        item = ui->tableWidget->item( ii, COL_TIME );
        if ( item )
        {
            QVariant data = item->data(Qt::EditRole);
            if (data.isValid())
            {
                newcfg.team_class[ii].start = QTime(0,0,0).secsTo(item->data(Qt::EditRole).toTime());
            }
            else
            {
                newcfg.team_class[ii].start = -1;
            }
        }
        else
        {
            newcfg.team_class[ii].start = -1;
        }

        item = ui->tableWidget->item( ii, COL_WINNERS );
        if ( item )
        {
            newcfg.class_winners[ii] = item->data(Qt::EditRole).toInt();
        }
        else
        {
            newcfg.class_winners[ii] = 0;
        }

        item = ui->tableWidget->item( ii, COL_NE );
        if ( item )
        {
            if ( item->checkState() == Qt::Checked)
            {
                newcfg.nonequestrian_class = ii;
                strncpy(newcfg.nonequestrian_class_abr, newcfg.team_class[ii].abr, sizeof(newcfg.team_class[ii].abr)-1);
            }
        }

        item = ui->tableWidget->item( ii, COL_NE_WINNERS );
        if ( item )
        {
            newcfg.class_ne_winners[ii] = item->data(Qt::EditRole).toInt();
        }
        else
        {
            newcfg.class_ne_winners[ii] = 0;
        }
    }
    
    // Validate the data
    try
    {
        MainWindow::showMessage( "Saving Config");

        /*
         **  Now do the Class definitions
         */

        for( int i = 0; i < MAX_CLASS; i++ )
        {
            compact( newcfg.team_class[i].abr );
            compact( newcfg.team_class[i].full_name );
        }

        for( int i = 0; i < MAX_CLASS; i++ )
        {
            if( ( newcfg.team_class[i].abr[0] == '\0' ) != ( newcfg.team_class[i].full_name[0] == '\0' ) )
            {
                throw( "Configuration error. Class without description" );

            }
            if( newcfg.team_class[i].abr[0] != '\0' && newcfg.team_class[i].start < 0L )
            {
                throw( "Configuration error. Bad start time on class" );

            }
        }

        newcfg.num_class = 0;
        for( int i = 0; i < MAX_CLASS; i++ )
            if( newcfg.team_class[i].full_name[0] )
                newcfg.num_class++;

        for( int i = newcfg.num_class; i < MAX_CLASS; i++ )
            if( newcfg.team_class[i].full_name[0] )
            {
                throw( "Configuration error: Missing Class name. Gaps not allowed" );

            }

        if( newcfg.num_class == 0 )
        {
            throw( "Error: No categories defined" );

        }

        newcfg.nonequestrian_class = newcfg.lookup_class( newcfg.nonequestrian_class_abr );
        if( newcfg.equestrian_leg && newcfg.nonequestrian_class == 0 )
            MainWindow::showMessage( "WARNING: Non-equestrian class not found" );

        /*
        **  Sanity test of the data
        */
        for( int i = 0; i < MAX_CLASS; i++ )
        {
            if( newcfg.team_class[i].abr[0] != '\0' && newcfg.class_winners[i] == 0 )
            {

                MainWindow::showMessage( QString("Warning: Class without winners:") + newcfg.team_class[i].abr );
            }
        }

        /*
        ** Cannot mix winners for NE class and NE Winners for each class
        */
        if (newcfg.nonequestrian_class)
        {
            newcfg.class_ne_winners_by_class = false;
            for( int i = 0; i < MAX_CLASS; i++ )
            {
                newcfg.class_ne_winners_by_class = true;
                break;
            }
            if (newcfg.class_winners[newcfg.nonequestrian_class - 1] && newcfg.class_ne_winners_by_class )
            {
                MainWindow::showMessage( QString("Should not mix NE winners by each class and by NE Class"));
                //throw( "Error: Cannot mix NE winners by each class and by NE Class" );
            }
        }


        config = newcfg;
        config.write_config();
        updateChanged(false);

    }
    catch (const char * str )
    {
        MainWindow::showMessage(str);
    }

}

void QmConfClass::cancel(void)
{
    populate();
}

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

void QmConfClass::ctxMenu(const QPoint & pos)
{
    qDebug("Context Menu");
    QMenu *menu = new QMenu;
    QTableWidgetItem *item = ui->tableWidget->itemAt(pos);
    menu->addAction(tr("New Category"), this, SLOT(ctxMenuAddRow()));
    if (item)
    {
        menu->addAction(tr("Delete Category"), this, SLOT(ctxMenuDeleteRow()));
    }
   menu->exec(ui->tableWidget->mapToGlobal(pos));

}

void QmConfClass::ctxMenuDeleteRow(void)
{
    //qDebug ("DELETE ROW: %d", ui->tableWidget->currentRow () );
    ui->tableWidget->removeRow(ui->tableWidget->currentRow ());
    updateChanged(true);
}

void QmConfClass::ctxMenuAddRow(void)
{
    ui->tableWidget->setRowCount( 1+ ui->tableWidget->rowCount());
}

void QmConfClass::updateStatus(void)
{
    populating = true;
    if (!statusShown)
    {
        ui->tableWidget->setColumnHidden(COL_ST_TOTAL, false);
        ui->tableWidget->setColumnHidden(COL_ST_DISQ, false);
        ui->tableWidget->setColumnHidden(COL_ST_NONEQ, false);
        ui->tableWidget->setColumnHidden(COL_ST_VET, false);
        statusShown = true;
    }

    if( load_report_data() )
    {
        t_class_summary data;
        calc_class_summary( & data );

        // Insert summary data
        int ii;
        for (ii = 0; ii < config.num_class; ii++)
        {
            QTableWidgetItem *item;
            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].total));
            item->setFlags(Qt::NoItemFlags);
            ui->tableWidget->setItem(ii,COL_ST_TOTAL, item );

            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].disqualified)) ;
            item->setFlags(Qt::NoItemFlags);
            ui->tableWidget->setItem(ii,COL_ST_DISQ, item);

            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].non_equestrian));
            item->setFlags(Qt::NoItemFlags);
            ui->tableWidget->setItem(ii,COL_ST_NONEQ, item);

            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].vet_check));
            item->setFlags(Qt::NoItemFlags);
            ui->tableWidget->setItem(ii,COL_ST_VET, item);
        }

        ui->tableWidget->resizeColumnsToContents();
        ui->tableWidget->resizeRowsToContents();
    }
    populating = false;
}

void QmConfClass::cellChanged(int row,int col)
{
    if ( populating )
        return;
    updateChanged(true);
    populating = true;
    //qDebug("Cell changed: %d, %d", row, col);
    if (col == COL_NE)
    {
        for (int ii = 0; ii < ui->tableWidget->rowCount(); ii++)
        {
            QTableWidgetItem *item = ui->tableWidget->item(ii, COL_NE);
            if (item)
            {
                item->setCheckState(ii == row ? Qt::Checked : Qt::Unchecked);
            }
        }
    }
    populating = false;
}

void QmConfClass::updateChanged(bool newDirty)
{
    if (newDirty != dirty)
    {
        dirty = newDirty;
        if (dirty)
        {
            ui->pushButtonSave->setEnabled(true);
            ui->pushButtonSave->setStyleSheet("background-color: rgb(255, 0, 0);");
        }
        else
        {
            ui->pushButtonSave->setEnabled(false);
            ui->pushButtonSave->setStyleSheet("");
        }
    }
}

void QmConfClass::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}