Subversion Repositories svn1

Rev

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