Subversion Repositories svn1-original

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
146 david 1
/*============================================================================
2
**
3
**  Project/Product : 
4
**  Filename        : qmteamdisplay.cpp
5
**  Author(s)       : DDP
6
**
7
**  Description     : Display and Update Team Information
8
**
9
**
10
**  Information     :
11
**   Compiler       : ANSI C++
12
**   Target         : 
13
**
14
***==========================================================================*/
15
 
130 david 16
#include "qmteamdisplay.h"
17
#include "ui_qmteamdisplay.h"
116 david 18
#include "spinboxdelegate.h"
19
#include "timedelegate.h"
20
#include "textdelegate.h"
312 david 21
#include "mainwindow.h"
319 david 22
#include "QmEditAddendum.h"
116 david 23
 
146 david 24
/*----------------------------------------------------------------------------
25
** FUNCTION           : qmTeamDisplay
26
**
27
** DESCRIPTION        : Construct a new widget
28
**
29
**
30
** INPUTS             :
31
**
32
** RETURNS            :
33
**
34
----------------------------------------------------------------------------*/
35
 
36
 
259 - 37
qmTeamDisplay::qmTeamDisplay(QWidget *parent, int initialTeam, bool useDone) :
116 david 38
    QWidget(parent),
130 david 39
    ui(new Ui::QmTeamDisplay)
116 david 40
{
41
    ui->setupUi(this);
42
    team = 0;
181 - 43
    dirty = true;
259 - 44
    populating = false;
45
    enableDone = useDone;
116 david 46
 
47
    /*
146 david 48
    **  Set delegates to assist in editing the members table
49
    **      Name
50
    **      Sex
51
    **      Age
52
    */
117 david 53
    ui->members->setItemDelegateForColumn(0, new textDelegate(MAX_PERSON_NAME));
54
    ui->members->setItemDelegateForColumn(2, new SpinBoxDelegate(0,120));
116 david 55
 
320 david 56
    ui->members->verticalHeader()->setVisible(true);
57
    QStringList labels;
58
    for ( int ii = 0 ; ii < config.num_legs; ii++)
59
    {
60
        labels << config.leg_name[ii];
61
    }
62
    ui->members->setVerticalHeaderLabels(labels);
63
 
125 david 64
    /*
65
    ** Insert widgets for the Team Times
66
    */
365 david 67
    for (int ii = 0; ii <= MAX_LEGS; ii++) {
68
        lt[ii] = NULL;
69
    }
70
 
71
 
146 david 72
    for ( int ii = 1 ; ii <= config.num_legs; ii++)
122 david 73
    {
130 david 74
        lt[ii] = new QmLegTimes(ii, config.leg_name[ii-1]);
123 david 75
        ui->legTime_layout->addWidget(lt[ii]);
125 david 76
        connect (lt[ii], SIGNAL(dataChanged()), this, SLOT(recalculateTimes()) );
122 david 77
    }
127 - 78
    lt[0] = new QmLegTimes(0, "Overall Event");
79
    ui->legTime_layout->addWidget(lt[0]);
122 david 80
 
146 david 81
    /*
317 david 82
    ** Init initial displayed team
83
    */
84
    team = initialTeam ? initialTeam : config.min_team;
85
 
86
    /*
146 david 87
    **  Connect up various signals
88
    */
181 - 89
    connect(ui->pushButtonSave, SIGNAL(clicked()), this, SLOT(save()) );
90
    connect(ui->pushButtonRestore, SIGNAL(clicked()), this, SLOT(cancel()) );
116 david 91
    connect(ui->teamNumber, SIGNAL(valueChanged(int)), this, SLOT(populate(int)) );
181 - 92
 
263 - 93
    connect(ui->name, SIGNAL(textEdited(QString)), this, SLOT(changed()) );
181 - 94
    connect(ui->category , SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
184 - 95
    connect(ui->category , SIGNAL(currentIndexChanged(int)), this, SLOT(updateCategory()));
181 - 96
    connect(ui->members , SIGNAL(cellChanged(int,int)), this, SLOT(changed()));
97
    connect(ui->disqualified , SIGNAL(clicked(bool)), this, SLOT(changed()));
245 - 98
    connect(ui->nonEquestrian , SIGNAL(clicked(bool)), this, SLOT(recalculateTimes()));
181 - 99
    connect(ui->disabled , SIGNAL(clicked(bool)), this, SLOT(changed()));
229 - 100
    connect(ui->VetCheck , SIGNAL(clicked(bool)), this, SLOT(changed()));
181 - 101
 
319 david 102
    connect(ui->editNote, SIGNAL(clicked()), this, SLOT(editNote()));
103
 
181 - 104
    updateChanged(false);
116 david 105
}
106
 
146 david 107
/*----------------------------------------------------------------------------
108
** FUNCTION           : ~qmTeamDisplay
109
**
110
** DESCRIPTION        : Destructor
111
**
112
**
113
** INPUTS             :
114
**
115
** RETURNS            :
116
**
117
----------------------------------------------------------------------------*/
118
 
130 david 119
qmTeamDisplay::~qmTeamDisplay()
116 david 120
{
121
    delete ui;
122
}
123
 
146 david 124
/*----------------------------------------------------------------------------
312 david 125
** FUNCTION           : showEvent
126
**
127
** DESCRIPTION        : Slot that is wired into the main windows widget
128
**                      It will be called when the main window widget changes
129
**                      If this display is the current display, then load new data
130
**
131
** INPUTS             : index of the tab that now has focus
132
**
133
----------------------------------------------------------------------------*/
134
 
135
void qmTeamDisplay::showEvent ( QShowEvent * event )
136
{
318 david 137
    //qDebug("showEvent::showEvent");
312 david 138
    if ( ! event->spontaneous() )
139
    {
316 david 140
        if ( ! dirty)
141
        {
317 david 142
            populate(team);
316 david 143
        }
312 david 144
    }
145
}
146
 
147
/*----------------------------------------------------------------------------
259 - 148
** FUNCTION           : blockSignals
149
**
150
** DESCRIPTION        : Block signal from widgets that set Changed
151
**                      while populating the display
152
**
153
**
154
** INPUTS             : state - New blocking state
155
**
156
** RETURNS            : Nothing
157
**
158
----------------------------------------------------------------------------*/
159
 
160
void qmTeamDisplay::blockSignals(bool state)
161
{
162
//    ui->pushButtonSave->blockSignals(state);
163
//    ui->pushButtonRestore->blockSignals(state);
164
//    ui->teamNumber->blockSignals(state);
165
 
166
    ui->name->blockSignals(state);
167
    ui->category->blockSignals(state);
168
    ui->members->blockSignals(state);
169
    ui->disqualified->blockSignals(state);
170
    ui->nonEquestrian->blockSignals(state);
171
    ui->disabled->blockSignals(state);
172
    ui->VetCheck->blockSignals(state);
173
 
365 david 174
    for ( int ii = 0 ; ii <= MAX_LEGS; ii++)
259 - 175
    {
365 david 176
        if (lt[ii]) {
177
            lt[ii]->blockSignals(state);
178
        }
259 - 179
    }
180
}
181
 
182
/*----------------------------------------------------------------------------
146 david 183
** FUNCTION           : populate
184
**
185
** DESCRIPTION        : Populate the widget with data
186
**
187
**
188
** INPUTS             : team_number         - Team number to use
189
**
190
** RETURNS            :
191
**
192
----------------------------------------------------------------------------*/
193
 
130 david 194
void qmTeamDisplay::populate(int team_number)
116 david 195
{
365 david 196
    if (MainWindow::shutDown) {
197
        return;
198
    }
199
 
146 david 200
    /*
201
    **  Update the spinner that describes the current team number
202
    */
181 - 203
    populating = true;
259 - 204
    blockSignals(true);
146 david 205
 
142 david 206
    ui->teamNumber->setMaximum(config.max_team);
219 - 207
    ui->teamNumber->setMinimum(config.min_team);
143 david 208
    ui->teamNumber->setValue(team_number);
116 david 209
    team = team_number;
146 david 210
 
211
    /*
212
    **  Read in team data
213
    **  This will persist within this widget
214
    */
116 david 215
    g_record( team, &team_buf );
216
 
217
    /*
218
    ** Basic Data
219
    */
220
    ui->name->setText( team_buf.name );
221
    ui->category_abr->setText( config.team_class[team_buf.teamclass - 1].abr );
222
 
317 david 223
    /*
224
    ** ComboBox for Category selection
225
    **  Save category index as data inthe combobox
226
    **  Do not show the NE category - it should be selected
227
    */
228
    ui->category->clear();
229
    int selectedIndex = -1;
230
    for ( int ii = 0; ii < config.num_class ; ii++)
231
    {
232
        if (config.team_class[ii].abr[0] && (config.nonequestrian_class != ii + 1))
233
        {
234
            ui->category->addItem(config.team_class[ii].full_name, ii);
235
            if (ii == team_buf.teamclass - 1)
236
            {
237
                selectedIndex = ui->category->count() - 1;
318 david 238
                //qDebug("ComboIndex:%d",ii);
317 david 239
            }
240
        }
241
    }
242
    ui->category->setCurrentIndex(selectedIndex);
243
 
140 - 244
    ui->disqualified->setCheckState(team_buf.flags.disqualified ? Qt::Checked : Qt::Unchecked);
245
    ui->nonEquestrian->setCheckState(team_buf.flags.non_equestrian ? Qt::Checked : Qt::Unchecked);
142 david 246
    ui->disabled->setCheckState( !team_buf.flags.valid ? Qt::Checked : Qt::Unchecked);
229 - 247
    ui->VetCheck->setCheckState( team_buf.flags.vet_check ? Qt::Checked : Qt::Unchecked);
140 - 248
 
116 david 249
    /*
250
    ** Team Member data
146 david 251
    **       Name
252
    **      Sex
253
    **      Age
116 david 254
    */
142 david 255
    int age_sum = 0;
116 david 256
    for ( int ii = 0; ii < config.num_legs; ii ++)
257
    {
258
         QTableWidgetItem *item;
259
        ui->members->setItem(ii, 0, new QTableWidgetItem(team_buf.members[ii].name) );
260
 
261
        item = new QTableWidgetItem();
142 david 262
        item->setFlags(Qt::ItemIsTristate | item->flags());
116 david 263
        enum Qt::CheckState sex;
264
        switch ( team_buf.members[ii].sex )
265
        {
117 david 266
            case male:   sex = Qt::Unchecked;        break;
267
            case female: sex = Qt::Checked;          break;
268
            default:     sex = Qt::PartiallyChecked; break;
116 david 269
        }
142 david 270
        //qDebug("RSex:%d, %d, %d, %d", team, ii, sex, team_buf.members[ii].sex);
116 david 271
        item->setCheckState(sex );
272
        ui->members->setItem(ii, 1, item );
273
 
274
        item = new QTableWidgetItem();
275
        item->setData(Qt::EditRole,team_buf.members[ii].age);
276
        ui->members->setItem(ii, 2, item );
142 david 277
 
278
        /*
279
        **  Sum ages
280
        **  -1 indicates invalid age
281
        */
282
        if ( age_sum >= 0 )
283
        {
284
            ushort age = team_buf.members[ii].age;
285
            if ( age > 0 && age < 255 )
286
            {
287
                age_sum += age;
288
            }
289
            else
290
            {
291
                age_sum = -1;
292
            }
293
        }
116 david 294
    }
146 david 295
    ui->members->resizeColumnsToContents();
142 david 296
 
146 david 297
    /*
319 david 298
    **  Mainatain the display of total age
146 david 299
    */
142 david 300
    if ( age_sum <= 0 )
301
    {
302
        ui->totalAge->setText("--");
303
    }
304
    else
305
    {
306
        ui->totalAge->setText(QString::number(age_sum));
307
    }
308
 
123 david 309
 
310
    /*
311
    ** Leg Times
312
    */
127 - 313
    for ( int ii = 0 ; ii <= config.num_legs; ii++)
123 david 314
    {
127 - 315
        lt[ii]->setData(&team_buf.leg[ii]);
123 david 316
    }
181 - 317
 
319 david 318
    /*
319
    **  Team Note
320
    */
321
    populateNote();
322
 
259 - 323
    updateChanged(false);
186 - 324
    populating = false;
259 - 325
    blockSignals(false);
326
 
116 david 327
}
328
 
184 - 329
void qmTeamDisplay::updateCategory(void)
330
{
317 david 331
    int currentIndex = ui->category->currentIndex();
332
    if (currentIndex >= 0)
333
    {
334
        int itemData = ui->category->itemData(currentIndex).toInt();
335
        ui->category_abr->setText( config.team_class[itemData].abr );
336
    }
184 - 337
}
338
 
146 david 339
/*----------------------------------------------------------------------------
340
** FUNCTION           : recalculateTimes
341
**
342
** DESCRIPTION        : Recalculate and update all the times for the legs
343
**
344
**
345
** INPUTS             : None
346
**
347
** RETURNS            :
348
**
349
----------------------------------------------------------------------------*/
350
 
130 david 351
void qmTeamDisplay::recalculateTimes( void )
125 david 352
{
127 - 353
    for ( int ii = 0 ; ii <= config.num_legs; ii++)
125 david 354
    {
127 - 355
        lt[ii]->getData(&team_buf.leg[ii]);
125 david 356
    }
245 - 357
    suckData();
125 david 358
    set_times( &team_buf );
359
    test_times( &team_buf, 0 );
127 - 360
    for ( int ii = 0 ; ii <= config.num_legs; ii++)
125 david 361
    {
127 - 362
        lt[ii]->setData(&team_buf.leg[ii]);
125 david 363
    }
181 - 364
 
365
    // Flag data as changed
366
    changed();
125 david 367
}
368
 
146 david 369
/*----------------------------------------------------------------------------
245 - 370
** FUNCTION           : suckData
146 david 371
**
245 - 372
** DESCRIPTION        : Save the data back to memory
146 david 373
**
374
** INPUTS             :
375
**
376
** RETURNS            :
377
**
378
----------------------------------------------------------------------------*/
379
 
245 - 380
void qmTeamDisplay::suckData(void)
116 david 381
{
125 david 382
    /*
383
    ** Extract data from the widgets
384
    ** The time stuff is done on the fly as it changes
385
    */
127 - 386
    strncpy(team_buf.name , qPrintable(ui->name->text()), sizeof(team_buf.name));
387
 
317 david 388
    int currentIndex = ui->category->currentIndex();
389
    if (currentIndex >= 0)
390
    {
391
        int itemData = ui->category->itemData(currentIndex).toInt();
392
        team_buf.teamclass = itemData + 1;
393
    }
394
 
140 - 395
    team_buf.flags.disqualified =  ( ui->disqualified->checkState () == Qt::Checked);
396
    team_buf.flags.non_equestrian =  ( ui->nonEquestrian->checkState () == Qt::Checked);
142 david 397
    team_buf.flags.valid =  ( ui->disabled->checkState () != Qt::Checked);
229 - 398
    team_buf.flags.vet_check =  ( ui->VetCheck->checkState () == Qt::Checked);
140 - 399
 
127 - 400
    /*
401
    ** Extract Team Member Data
402
    */
403
    for ( int ii = 0; ii < config.num_legs; ii ++)
404
    {
405
        QTableWidgetItem *item;
406
        item = ui->members->item ( ii, 0 );
407
        strncpy(team_buf.members[ii].name , qPrintable(item->text()), sizeof(team_buf.members[ii].name));
408
 
409
        //TODO: Make Sex edit work
410
        item = ui->members->item ( ii, 1 );
142 david 411
        enum Qt::CheckState sex = item->checkState();
412
        switch (sex)
127 - 413
        {
414
            case Qt::Unchecked: team_buf.members[ii].sex = male;  break;
415
            case Qt::Checked: team_buf.members[ii].sex = female; break;
416
            default: team_buf.members[ii].sex = unknown; break;
417
        }
142 david 418
        //qDebug("WSex:%d, %d, %d, %d", team, ii, sex, team_buf.members[ii].sex);
127 - 419
 
420
        item = ui->members->item ( ii, 2 );
421
        team_buf.members[ii].age = item->data(Qt::EditRole).toInt();
422
 
423
    }
245 - 424
}
127 - 425
 
245 - 426
/*----------------------------------------------------------------------------
427
** FUNCTION           : save
428
**
429
** DESCRIPTION        : Save the data back to disk
259 - 430
**                      Also called if nothing to save - ie Done Mode
245 - 431
**
432
** INPUTS             :
433
**
434
** RETURNS            :
435
**
436
----------------------------------------------------------------------------*/
437
 
438
void qmTeamDisplay::save(void)
439
{
259 - 440
    if ( dirty )
441
    {
442
        /*
443
        ** Save the record back to disk
444
        */
445
        suckData();
446
        put_team_record( team, &team_buf );
447
        populate(team);
448
    }
449
    else
450
    {
451
        if ( enableDone )
452
            emit dialogDone(1);
453
    }
116 david 454
}
455
 
146 david 456
/*----------------------------------------------------------------------------
457
** FUNCTION           : cancel
458
**
459
** DESCRIPTION        : Kill of any edited data
460
**                      Redisplay the team data
461
**
462
** INPUTS             :
463
**
464
** RETURNS            :
465
**
466
----------------------------------------------------------------------------*/
467
 
468
 
130 david 469
void qmTeamDisplay::cancel(void)
116 david 470
{
471
    populate(team);
472
}
473
 
181 - 474
void qmTeamDisplay::changed(void)
475
{
259 - 476
//QObject * who = sender () ;
477
//qDebug ("Changed: %p", who);
181 - 478
    if (populating)
479
        return;
480
    updateChanged(true);
259 - 481
 
181 - 482
}
483
 
484
void qmTeamDisplay::updateChanged(bool newDirty)
485
{
259 - 486
    //qDebug("updateChanged: %d, %d -> %d", populating, dirty, newDirty );
181 - 487
    if (newDirty != dirty)
488
    {
489
        dirty = newDirty;
490
        if (dirty)
491
        {
492
            ui->Changed->setVisible(true);
493
            ui->teamNumber->setEnabled(false);
494
            ui->pushButtonSave->setEnabled(true);
230 - 495
            ui->pushButtonSave->setStyleSheet("background-color: rgb(255, 0, 0);");
259 - 496
            ui->pushButtonSave->setText("Save");
305 david 497
 
498
            //  Only valid when within a dialog
499
            //  Now have the dialog swallow <return>
500
            //ui->pushButtonSave->setDefault(true);
181 - 501
        }
502
        else
503
        {
504
            ui->Changed->setVisible(false);
505
            ui->teamNumber->setEnabled(true);
259 - 506
            //ui->pushButtonSave->setEnabled(false);
230 - 507
            ui->pushButtonSave->setStyleSheet("");
259 - 508
 
509
            if ( enableDone )
510
                ui->pushButtonSave->setText("Done");
181 - 511
        }
512
    }
513
}
514
 
146 david 515
/*----------------------------------------------------------------------------
516
** FUNCTION           : changeEvent
517
**
518
** DESCRIPTION        :
519
**
520
**
521
** INPUTS             :
522
**
523
** RETURNS            :
524
**
525
----------------------------------------------------------------------------*/
526
 
130 david 527
void qmTeamDisplay::changeEvent(QEvent *e)
116 david 528
{
214 - 529
//qDebug("qmTeamDisplay ChangeEvent: %d",e->type());
116 david 530
    QWidget::changeEvent(e);
531
    switch (e->type()) {
532
    case QEvent::LanguageChange:
533
        ui->retranslateUi(this);
534
        break;
535
    default:
536
        break;
537
    }
538
}
319 david 539
 
540
/*----------------------------------------------------------------------------
541
** FUNCTION           : populateNote
542
**
543
** DESCRIPTION        : Populate the Note area of the team display
544
**                      Must be called during populate as
545
**
546
**
547
** INPUTS             :
548
**
549
** RETURNS            :
550
**
551
----------------------------------------------------------------------------*/
552
 
553
void qmTeamDisplay::populateNote(void)
554
{
555
    noteFileName = "TeamNote_" + QString::number(team) + ".txt";
320 david 556
    //qDebug("NoteFile:%s",qPrintable(noteFileName));
319 david 557
 
320 david 558
    //  Clear combobox before we add text
559
    ui->noteText->clear();
560
 
319 david 561
    QFile noteFile(QString(filepath) + noteFileName);
562
    if ( noteFile.open( QIODevice::ReadOnly ) )
563
    {
564
        QTextStream stream( &noteFile );
565
        QString line;
320 david 566
        do {
567
             line = stream.readLine();
568
             if (line.isNull())
569
                 break;
570
             ui->noteText->addItem(line);
571
         } while (true);
319 david 572
        noteFile.close();
573
    }
320 david 574
    ui->noteText->setStyleSheet( ui->noteText->count() ? "background-color: #FFFFCB;" : "");
319 david 575
 
576
    /*
577
    ** Delete empy files to keep things clean
578
    */
579
    if (noteFile.size() == 0 )
580
    {
581
        noteFile.remove();
582
    }
583
}
584
 
585
/*----------------------------------------------------------------------------
586
** FUNCTION           : editNote
587
**
588
** DESCRIPTION        : Edit the Team Note in a  modal dialog box
589
**
590
** INPUTS             :
591
**
592
** RETURNS            :
593
**
594
----------------------------------------------------------------------------*/
595
 
596
void qmTeamDisplay::editNote(void)
597
{
320 david 598
    QmEditAddendum dialog(QmConfig::getAddendemFile(noteFileName, true), true);
319 david 599
     dialog.exec();
600
     populateNote();
601
}