Subversion Repositories svn1-original

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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