Rev 232 | Rev 290 | 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_VALID 7#define COL_ST_DISQ 8#define COL_ST_NONEQ 9#define COL_ST_VET 10#define COL_COUNT 11QmConfClass::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 buttonconnect(ui->statusButton, SIGNAL(clicked()), this, SLOT(updateStatus()));statusShown = false;ui->tableWidget->setColumnHidden(COL_ST_TOTAL, true);ui->tableWidget->setColumnHidden(COL_ST_VALID, true);ui->tableWidget->setColumnHidden(COL_ST_DISQ, true);ui->tableWidget->setColumnHidden(COL_ST_NONEQ, true);ui->tableWidget->setColumnHidden(COL_ST_VET, true);labels << "Total" << "Valid" <<"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 datatry{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++ ){if ( newcfg.class_ne_winners[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_VALID, 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 dataint 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].valid));item->setFlags(Qt::NoItemFlags);ui->tableWidget->setItem(ii,COL_ST_VALID, 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;}}