Subversion Repositories svn1

Rev

Rev 236 | Rev 286 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
95 david 1
#include "qmconfclass.h"
174 - 2
#include "qmconfig.h"
95 david 3
#include "ui_qmconfclass.h"
99 david 4
#include    "consts.h"
5
#include    "structs.h"
6
#include    "proto.h"
180 - 7
#include "mainwindow.h"
95 david 8
 
99 david 9
#include "QTableWidgetItem"
107 david 10
#include "spinboxdelegate.h"
11
#include "timedelegate.h"
111 david 12
#include "textdelegate.h"
180 - 13
#include <QMenu>
99 david 14
 
227 - 15
#define COL_ABR 0
16
#define COL_CLASS 1
17
#define COL_TIME 2
18
#define COL_WINNERS 3
19
#define COL_NE 4
20
#define COL_NE_WINNERS 5
21
#define COL_ST_TOTAL 6
228 - 22
#define COL_ST_VALID 7
23
#define COL_ST_DISQ 8
24
#define COL_ST_NONEQ 9
25
#define COL_ST_VET 10
284 david 26
#define COL_ST_CEV 11
27
#define COL_ST_CNE 12
28
#define COL_COUNT 13
227 - 29
 
30
 
104 - 31
QmConfClass::QmConfClass(QWidget *parent) :
95 david 32
    QWidget(parent),
104 - 33
    ui(new Ui::QmConfClass)
95 david 34
{
35
    ui->setupUi(this);
181 - 36
    populating = false;
37
    connect(ui->pushButtonSave, SIGNAL(clicked(bool)), this, SLOT(save()) );
38
    connect(ui->pushButtonRestore, SIGNAL(clicked(bool)), this, SLOT(cancel()) );
99 david 39
 
109 david 40
    QStringList labels;
228 - 41
    labels << "Abr" << "Full Name" << "Start Time" << "Winners" << "NE" << "NE Winners";
109 david 42
 
107 david 43
 
180 - 44
    ui->tableWidget->setRowCount(config.num_class + 1);
227 - 45
    ui->tableWidget->setColumnCount(COL_COUNT);
180 - 46
    ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
47
    connect(ui->tableWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &)));
181 - 48
    connect(ui->tableWidget, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int,int)));
180 - 49
 
50
 
107 david 51
    /*
52
    **  Setup delegated for specialised editing
53
    */
227 - 54
    ui->tableWidget->setItemDelegateForColumn(COL_ABR, new textDelegate(2));
55
    ui->tableWidget->setItemDelegateForColumn(COL_CLASS, new textDelegate(LEN_CLASS_NAME));
56
    ui->tableWidget->setItemDelegateForColumn(COL_TIME, new timeDelegate());
57
    ui->tableWidget->setItemDelegateForColumn(COL_WINNERS, new SpinBoxDelegate(0,50));
58
    ui->tableWidget->setItemDelegateForColumn(COL_NE_WINNERS, new SpinBoxDelegate(0,50));
107 david 59
 
99 david 60
    populate();
180 - 61
 
62
 
63
    // Wire in the status button
64
    connect(ui->statusButton, SIGNAL(clicked()), this, SLOT(updateStatus()));
65
    statusShown = false;
227 - 66
    ui->tableWidget->setColumnHidden(COL_ST_TOTAL, true);
228 - 67
    ui->tableWidget->setColumnHidden(COL_ST_VALID, true);
227 - 68
    ui->tableWidget->setColumnHidden(COL_ST_DISQ, true);
69
    ui->tableWidget->setColumnHidden(COL_ST_NONEQ, true);
70
    ui->tableWidget->setColumnHidden(COL_ST_VET, true);
284 david 71
    ui->tableWidget->setColumnHidden(COL_ST_CEV, true);
72
    ui->tableWidget->setColumnHidden(COL_ST_CNE, true);
180 - 73
 
284 david 74
    labels << "Total" << "Valid" <<"Disqual" << "NonEq" << "VetCheck" << "Comp Ev" << " Comp NE";
180 - 75
 
76
    ui->tableWidget->setHorizontalHeaderLabels(labels);
111 david 77
    ui->tableWidget->resizeColumnsToContents();
180 - 78
 
95 david 79
}
80
 
104 - 81
void QmConfClass::populate(void)
99 david 82
{
181 - 83
    populating = true;
180 - 84
    ui->tableWidget->setRowCount(config.num_class + 1);
99 david 85
    for ( int ii = 0; ii < MAX_CLASS; ii++)
86
    {
227 - 87
        ui->tableWidget->setItem(ii, COL_ABR, new QTableWidgetItem(config.team_class[ii].abr) );
88
        ui->tableWidget->setItem(ii, COL_CLASS, new QTableWidgetItem(config.team_class[ii].full_name ));
105 - 89
 
111 david 90
        if ( *config.team_class[ii].abr )
91
        {
92
            QTableWidgetItem *item;
93
            item = new QTableWidgetItem();
94
            item->setData(Qt::EditRole,QTime().addSecs(config.team_class[ii].start) );
227 - 95
            ui->tableWidget->setItem(ii, COL_TIME, item);
107 david 96
 
111 david 97
            item = new QTableWidgetItem();
98
            item->setData(Qt::EditRole,config.class_winners[ii] );
227 - 99
            ui->tableWidget->setItem(ii, COL_WINNERS, item);
181 - 100
 
101
            item = new QTableWidgetItem();
102
            item->setCheckState(config.nonequestrian_class == 1 + ii ? Qt::Checked : Qt::Unchecked);
227 - 103
            ui->tableWidget->setItem(ii, COL_NE, item);
181 - 104
 
227 - 105
            item = new QTableWidgetItem();
106
            item->setData(Qt::EditRole,config.class_ne_winners[ii] );
107
            ui->tableWidget->setItem(ii, COL_NE_WINNERS, item);
111 david 108
        }
99 david 109
    }
181 - 110
    updateChanged(false);
111
    populating = false;
99 david 112
}
113
 
104 - 114
void QmConfClass::save(void)
99 david 115
{
104 - 116
    /*
117
    **    Copy original data
118
    */
176 - 119
    QmConfig newcfg(config);
104 - 120
 
121
    /*
122
    **  Extract the data from the Widgets
123
    */
124
    for ( int ii = 0; ii < MAX_CLASS; ii++)
125
    {
227 - 126
        QTableWidgetItem *item = ui->tableWidget->item ( ii, COL_ABR );
111 david 127
        if ( item )
128
        {
129
            strncpy(newcfg.team_class[ii].abr, qPrintable(item->text()), sizeof(newcfg.team_class[ii].abr)-1);
130
        }
131
        else
132
        {
133
            *newcfg.team_class[ii].abr = 0;
134
        }
104 - 135
 
227 - 136
        item = ui->tableWidget->item ( ii, COL_CLASS );
111 david 137
        if ( item )
138
        {
139
            strncpy(newcfg.team_class[ii].full_name, qPrintable(item->text()), sizeof(newcfg.team_class[ii].full_name)-1);
140
        }
141
        else
142
        {
143
            *newcfg.team_class[ii].full_name = 0;
144
        }
108 david 145
 
227 - 146
        item = ui->tableWidget->item( ii, COL_TIME );
111 david 147
        if ( item )
148
        {
195 david 149
            QVariant data = item->data(Qt::EditRole);
150
            if (data.isValid())
151
            {
152
                newcfg.team_class[ii].start = QTime(0,0,0).secsTo(item->data(Qt::EditRole).toTime());
153
            }
154
            else
155
            {
156
                newcfg.team_class[ii].start = -1;
157
            }
111 david 158
        }
159
        else
160
        {
195 david 161
            newcfg.team_class[ii].start = -1;
111 david 162
        }
163
 
227 - 164
        item = ui->tableWidget->item( ii, COL_WINNERS );
111 david 165
        if ( item )
166
        {
167
            newcfg.class_winners[ii] = item->data(Qt::EditRole).toInt();
168
        }
169
        else
170
        {
171
            newcfg.class_winners[ii] = 0;
172
        }
227 - 173
 
174
        item = ui->tableWidget->item( ii, COL_NE );
181 - 175
        if ( item )
176
        {
177
            if ( item->checkState() == Qt::Checked)
178
            {
179
                newcfg.nonequestrian_class = ii;
180
                strncpy(newcfg.nonequestrian_class_abr, newcfg.team_class[ii].abr, sizeof(newcfg.team_class[ii].abr)-1);
181
            }
182
        }
227 - 183
 
184
        item = ui->tableWidget->item( ii, COL_NE_WINNERS );
185
        if ( item )
186
        {
187
            newcfg.class_ne_winners[ii] = item->data(Qt::EditRole).toInt();
188
        }
189
        else
190
        {
191
            newcfg.class_ne_winners[ii] = 0;
192
        }
104 - 193
    }
194
 
181 - 195
    // Validate the data
196
    try
104 - 197
    {
181 - 198
        MainWindow::showMessage( "Saving Config");
104 - 199
 
181 - 200
        /*
201
         **  Now do the Class definitions
202
         */
203
 
204
        for( int i = 0; i < MAX_CLASS; i++ )
104 - 205
        {
181 - 206
            compact( newcfg.team_class[i].abr );
207
            compact( newcfg.team_class[i].full_name );
104 - 208
        }
181 - 209
 
210
        for( int i = 0; i < MAX_CLASS; i++ )
104 - 211
        {
181 - 212
            if( ( newcfg.team_class[i].abr[0] == '\0' ) != ( newcfg.team_class[i].full_name[0] == '\0' ) )
213
            {
214
                throw( "Configuration error. Class without description" );
215
 
216
            }
217
            if( newcfg.team_class[i].abr[0] != '\0' && newcfg.team_class[i].start < 0L )
218
            {
219
                throw( "Configuration error. Bad start time on class" );
220
 
221
            }
104 - 222
        }
223
 
181 - 224
        newcfg.num_class = 0;
225
        for( int i = 0; i < MAX_CLASS; i++ )
226
            if( newcfg.team_class[i].full_name[0] )
227
                newcfg.num_class++;
104 - 228
 
181 - 229
        for( int i = newcfg.num_class; i < MAX_CLASS; i++ )
230
            if( newcfg.team_class[i].full_name[0] )
231
            {
232
                throw( "Configuration error: Missing Class name. Gaps not allowed" );
233
 
234
            }
235
 
236
        if( newcfg.num_class == 0 )
104 - 237
        {
181 - 238
            throw( "Error: No categories defined" );
239
 
104 - 240
        }
241
 
181 - 242
        newcfg.nonequestrian_class = newcfg.lookup_class( newcfg.nonequestrian_class_abr );
243
        if( newcfg.equestrian_leg && newcfg.nonequestrian_class == 0 )
244
            MainWindow::showMessage( "WARNING: Non-equestrian class not found" );
104 - 245
 
181 - 246
        /*
247
        **  Sanity test of the data
248
        */
249
        for( int i = 0; i < MAX_CLASS; i++ )
250
        {
251
            if( newcfg.team_class[i].abr[0] != '\0' && newcfg.class_winners[i] == 0 )
252
            {
104 - 253
 
181 - 254
                MainWindow::showMessage( QString("Warning: Class without winners:") + newcfg.team_class[i].abr );
255
            }
111 david 256
        }
257
 
227 - 258
        /*
259
        ** Cannot mix winners for NE class and NE Winners for each class
260
        */
261
        if (newcfg.nonequestrian_class)
262
        {
263
            newcfg.class_ne_winners_by_class = false;
264
            for( int i = 0; i < MAX_CLASS; i++ )
265
            {
228 - 266
                if ( newcfg.class_ne_winners[i])
267
                {
268
                    newcfg.class_ne_winners_by_class = true;
269
                    break;
270
                }
227 - 271
            }
272
            if (newcfg.class_winners[newcfg.nonequestrian_class - 1] && newcfg.class_ne_winners_by_class )
273
            {
274
                MainWindow::showMessage( QString("Should not mix NE winners by each class and by NE Class"));
275
                //throw( "Error: Cannot mix NE winners by each class and by NE Class" );
276
            }
277
        }
278
 
279
 
104 - 280
        config = newcfg;
176 - 281
        config.write_config();
181 - 282
        updateChanged(false);
283
 
104 - 284
    }
181 - 285
    catch (const char * str )
286
    {
287
        MainWindow::showMessage(str);
288
    }
104 - 289
 
99 david 290
}
291
 
104 - 292
void QmConfClass::cancel(void)
99 david 293
{
294
    populate();
295
}
296
 
104 - 297
QmConfClass::~QmConfClass()
95 david 298
{
299
    delete ui;
300
}
301
 
180 - 302
void QmConfClass::ctxMenu(const QPoint & pos)
303
{
304
    qDebug("Context Menu");
305
    QMenu *menu = new QMenu;
181 - 306
    QTableWidgetItem *item = ui->tableWidget->itemAt(pos);
180 - 307
    menu->addAction(tr("New Category"), this, SLOT(ctxMenuAddRow()));
308
    if (item)
309
    {
310
        menu->addAction(tr("Delete Category"), this, SLOT(ctxMenuDeleteRow()));
311
    }
312
   menu->exec(ui->tableWidget->mapToGlobal(pos));
313
 
314
}
315
 
316
void QmConfClass::ctxMenuDeleteRow(void)
317
{
318
    //qDebug ("DELETE ROW: %d", ui->tableWidget->currentRow () );
319
    ui->tableWidget->removeRow(ui->tableWidget->currentRow ());
189 - 320
    updateChanged(true);
180 - 321
}
322
 
323
void QmConfClass::ctxMenuAddRow(void)
324
{
325
    ui->tableWidget->setRowCount( 1+ ui->tableWidget->rowCount());
326
}
327
 
328
void QmConfClass::updateStatus(void)
329
{
189 - 330
    populating = true;
180 - 331
    if (!statusShown)
332
    {
227 - 333
        ui->tableWidget->setColumnHidden(COL_ST_TOTAL, false);
228 - 334
        ui->tableWidget->setColumnHidden(COL_ST_VALID, false);
227 - 335
        ui->tableWidget->setColumnHidden(COL_ST_DISQ, false);
336
        ui->tableWidget->setColumnHidden(COL_ST_NONEQ, false);
337
        ui->tableWidget->setColumnHidden(COL_ST_VET, false);
284 david 338
        ui->tableWidget->setColumnHidden(COL_ST_CEV, false);
339
        ui->tableWidget->setColumnHidden(COL_ST_CNE, false);
180 - 340
        statusShown = true;
341
    }
342
 
343
    if( load_report_data() )
344
    {
345
        t_class_summary data;
346
        calc_class_summary( & data );
347
 
348
        // Insert summary data
349
        int ii;
350
        for (ii = 0; ii < config.num_class; ii++)
351
        {
352
            QTableWidgetItem *item;
353
            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].total));
354
            item->setFlags(Qt::NoItemFlags);
227 - 355
            ui->tableWidget->setItem(ii,COL_ST_TOTAL, item );
180 - 356
 
228 - 357
            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].valid));
358
            item->setFlags(Qt::NoItemFlags);
359
            ui->tableWidget->setItem(ii,COL_ST_VALID, item );
360
 
180 - 361
            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].disqualified)) ;
362
            item->setFlags(Qt::NoItemFlags);
227 - 363
            ui->tableWidget->setItem(ii,COL_ST_DISQ, item);
180 - 364
 
365
            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].non_equestrian));
366
            item->setFlags(Qt::NoItemFlags);
227 - 367
            ui->tableWidget->setItem(ii,COL_ST_NONEQ, item);
225 - 368
 
369
            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].vet_check));
370
            item->setFlags(Qt::NoItemFlags);
227 - 371
            ui->tableWidget->setItem(ii,COL_ST_VET, item);
284 david 372
 
373
            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].valid_ev));
374
            item->setFlags(Qt::NoItemFlags);
375
            ui->tableWidget->setItem(ii,COL_ST_CEV, item);
376
 
377
            item = new QTableWidgetItem(QString::number(data.teamclass[ii+1].valid_ne));
378
            item->setFlags(Qt::NoItemFlags);
379
            ui->tableWidget->setItem(ii,COL_ST_CNE, item);
380
 
180 - 381
        }
382
 
383
        ui->tableWidget->resizeColumnsToContents();
384
        ui->tableWidget->resizeRowsToContents();
385
    }
189 - 386
    populating = false;
180 - 387
}
388
 
181 - 389
void QmConfClass::cellChanged(int row,int col)
390
{
391
    if ( populating )
392
        return;
393
    updateChanged(true);
394
    populating = true;
395
    //qDebug("Cell changed: %d, %d", row, col);
227 - 396
    if (col == COL_NE)
181 - 397
    {
398
        for (int ii = 0; ii < ui->tableWidget->rowCount(); ii++)
399
        {
227 - 400
            QTableWidgetItem *item = ui->tableWidget->item(ii, COL_NE);
181 - 401
            if (item)
402
            {
403
                item->setCheckState(ii == row ? Qt::Checked : Qt::Unchecked);
404
            }
405
        }
406
    }
407
    populating = false;
408
}
409
 
410
void QmConfClass::updateChanged(bool newDirty)
411
{
412
    if (newDirty != dirty)
413
    {
414
        dirty = newDirty;
415
        if (dirty)
416
        {
417
            ui->pushButtonSave->setEnabled(true);
226 - 418
            ui->pushButtonSave->setStyleSheet("background-color: rgb(255, 0, 0);");
181 - 419
        }
420
        else
421
        {
422
            ui->pushButtonSave->setEnabled(false);
226 - 423
            ui->pushButtonSave->setStyleSheet("");
181 - 424
        }
425
    }
426
}
427
 
104 - 428
void QmConfClass::changeEvent(QEvent *e)
95 david 429
{
430
    QWidget::changeEvent(e);
431
    switch (e->type()) {
432
    case QEvent::LanguageChange:
433
        ui->retranslateUi(this);
434
        break;
435
    default:
436
        break;
437
    }
438
}