Subversion Repositories svn1-original

Rev

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