Subversion Repositories svn1-original

Rev

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

Rev Author Line No. Line
148 - 1
#include "qmdialogloadexternalteams.h"
242 - 2
//#include "ui_qmdialogloadexternalteams.h"
149 - 3
#include "QFile"
4
#include "QTextStream"
5
#include "mainwindow.h"
6
#include <QRegExp>
225 - 7
#include <QtGui/QHBoxLayout>
8
#include <QtGui/QVBoxLayout>
9
#include <QtGui/QWidget>
242 - 10
#include <QHeaderView>
148 - 11
 
149 - 12
#include    "consts.h"
13
#include    "structs.h"
14
#include    "proto.h"
15
 
16
QmDialogLoadExternalTeams::QmDialogLoadExternalTeams(const QString &efile,QWidget *parent) :
225 - 17
    QDialog(parent)
228 - 18
{
225 - 19
 
20
    //
21
    // Create Windows
22
    //
23
    resize(550, 500);
24
    setSizeGripEnabled(true);
149 - 25
    setWindowTitle("Load External Team Data");
26
 
225 - 27
    QVBoxLayout *verticalLayout;
28
    verticalLayout = new QVBoxLayout(this);
29
    verticalLayout->setContentsMargins(0, 0, 0, 0);
30
 
227 - 31
    QVBoxLayout *verticalLayout2;
32
    verticalLayout2 = new QVBoxLayout(this);
33
    verticalLayout2->setContentsMargins(5, 5, 5, 5);
34
 
225 - 35
    QHBoxLayout *horizontalLayout;
36
    horizontalLayout = new QHBoxLayout();
37
 
38
    groupBox = new QGroupBox(this);
39
    groupBox->setTitle("Data");
228 - 40
    verticalLayout->addWidget(groupBox);
41
    groupBox->setLayout(verticalLayout2);
225 - 42
 
228 - 43
    tableWidget = new QTableWidget(groupBox);
44
    tableWidget->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
45
    tableWidget->setGeometry(QRect(15, 21, 501, 421));
46
    tableWidget->setCornerButtonEnabled(false);
47
    tableWidget->verticalHeader()->setVisible(false);
48
    tableWidget->verticalHeader()->setDefaultSectionSize(20);
49
    tableWidget->verticalHeader()->setHighlightSections(true);
50
    verticalLayout2->addWidget(tableWidget);
225 - 51
 
52
    fileName = new QLineEdit(this);
53
    fileName->setObjectName(QString::fromUtf8("fileName"));
54
    fileName->setGeometry(QRect(20, 470, 331, 20));
55
    fileName->setReadOnly(true);
56
    fileName->setText(efile);
57
    horizontalLayout->addWidget(fileName);
58
 
59
 
60
 
61
    load = new QPushButton(this);
62
    load->setObjectName(QString::fromUtf8("load"));
63
    load->setGeometry(QRect(370, 470, 75, 23));
64
    load->setText("Load");
65
    horizontalLayout->addWidget(load);
66
 
67
    cancel = new QPushButton(this);
68
    cancel->setObjectName(QString::fromUtf8("cancel"));
69
    cancel->setGeometry(QRect(460, 470, 75, 23));
70
    cancel->setAutoDefault(false);
71
    cancel->setText("Cancel");
72
    horizontalLayout->addWidget(cancel);
73
 
74
    verticalLayout->addLayout(horizontalLayout);
75
 
76
 
149 - 77
    // Open the users file
78
 
79
    QFile file(efile);
80
    if ( ! file.open(QIODevice::ReadOnly | QIODevice::Text) )
81
    {
82
        MainWindow::showMessage("Cannot open external data file");
83
        return;
84
    }
153 - 85
    MainWindow::showMessage("Loading External Data");
149 - 86
 
153 - 87
    // Insert column headers
225 - 88
    tableWidget->setColumnCount(3 + ( 2 * config.num_legs) );
153 - 89
    QStringList labels;
90
    labels << "Team" << "Team Name" << "Cat";
91
    for (int ii = 1; ii <= config.num_legs; ii++ )
92
    {
93
        labels += QString("Leg:%1").arg(QString::number(ii));
155 david 94
        labels += QString("Age:%1").arg(QString::number(ii));
153 - 95
    }
225 - 96
    tableWidget->setHorizontalHeaderLabels(labels);
149 - 97
 
98
    // Process Each line of the file
99
    QTextStream in(&file);
100
    int ii = 0;
152 - 101
    int bad_cat = 0;
275 david 102
    bool has_RefError;
103
    int  bad_refs = 0;
149 - 104
    QRegExp csv_split("\"?,\"?");
105
    while (!in.atEnd())
106
    {
228 - 107
        QString line = in.readLine();
108
        line = line.trimmed();             // Remove leading and training White Space
109
        line.remove(0xA0);                 // M$ special uglyness
276 david 110
        line.remove(0xC2);                 // M$ special uglyness
149 - 111
 
275 david 112
        has_RefError = hasRefError(line);
228 - 113
        QStringList parts = splitCsvData(line);
114
        QString first = parts.value(0);
115
        bool ok;
116
        if ( first.isEmpty() )
117
            continue;
118
        int team = first.toInt(&ok);
119
        if ( ! ok || team <= 0 )
120
            continue;
121
        tableWidget->setRowCount(1+ii);
149 - 122
 
228 - 123
        // Insert Team number
275 david 124
        QTableWidgetItem *item = new QTableWidgetItem(first);
125
        tableWidget->setItem(ii, 0, item );
228 - 126
        parts.removeFirst();
275 david 127
        if ( has_RefError )
128
        {
129
            item->setBackgroundColor(QColor(0,0,200,50));
130
            bad_refs++;
131
        }
149 - 132
 
228 - 133
        // Extract Team Name
275 david 134
        item = new QTableWidgetItem( parts.value(0) );
135
        tableWidget->setItem(ii, 1, item );
136
        if ( hasRefError(parts.value(0)) )
137
        {
138
            item->setBackgroundColor(QColor(0,0,200,50));
139
        }
228 - 140
        parts.removeFirst();
275 david 141
 
228 - 142
        // Extract Team Cat
275 david 143
        item = new QTableWidgetItem( parts.value(0)) ;
228 - 144
        tableWidget->setItem(ii, 2, item );
149 - 145
 
180 - 146
        if (config.lookup_class(qPrintable(parts.value(0)) ) <= 0 )
152 - 147
        {
148
            item->setBackgroundColor(QColor(200,0,0,50));
149
            bad_cat++;
150
        }
275 david 151
        if ( hasRefError(parts.value(0)) )
152
        {
153
            item->setBackgroundColor(QColor(0,0,200,50));
154
        }
152 - 155
        parts.removeFirst();
275 david 156
 
228 - 157
        int yy = 0;
158
        while ( parts.count() > 0)
159
        {
160
            // Name of competitor
275 david 161
            item = new QTableWidgetItem( parts.value(0));
162
            tableWidget->setItem(ii, 3+yy, item);
163
            if ( hasRefError(parts.value(0)) )
164
            {
165
                item->setBackgroundColor(QColor(0,0,200,50));
166
            }
228 - 167
            parts.removeFirst();
275 david 168
 
149 - 169
 
228 - 170
// Not loading age at the moment
171
// Reason: The CSV file is being create with a '0' for the NE teams
172
#if DO_AGE_LOAD
173
            // Posible age - if its a number
174
            int age = parts.value(0).toInt(&ok);
175
            if ( ok )
176
            {
177
                if ( age > 0 )
178
                {
179
                    tableWidget->setItem(ii, 4+yy, new QTableWidgetItem( parts.value(0)));
180
                }
181
                parts.removeFirst();
182
            }
183
#endif
184
            yy += 2;
185
        }
186
        ii++;
187
    }
225 - 188
    tableWidget->resizeColumnsToContents();
149 - 189
 
152 - 190
    // Report errors
275 david 191
    reportErrors( bad_cat, bad_refs);
276 david 192
 
150 david 193
    // Connect up buttons
149 - 194
 
225 - 195
    connect (load, SIGNAL(clicked()), this, SLOT(loadData()));
196
    connect(cancel, SIGNAL(clicked()), this, SLOT(close()));
148 - 197
}
198
 
199
QmDialogLoadExternalTeams::~QmDialogLoadExternalTeams()
200
{
225 - 201
 
148 - 202
}
150 david 203
 
204
void QmDialogLoadExternalTeams::loadData(void)
205
{
206
    qDebug ("LoadData");
207
    team_type team_buf;
152 - 208
    int bad_cat = 0;
275 david 209
    int bad_refs = 0;
225 - 210
    for ( int ii = 0; ii < tableWidget->rowCount(); ii++)
150 david 211
    {
225 - 212
        if ( tableWidget->isRowHidden(ii))
152 - 213
        {
214
            continue;
215
        }
216
        bool bad = false;
150 david 217
        QTableWidgetItem *item;
225 - 218
        item = tableWidget->item(ii,0);
150 david 219
        if (item)
220
        {
221
            int team = item->data(Qt::EditRole).toInt();
222
            if ( team > 0 && team <= config.max_team )
223
            {
224
                g_record( team, &team_buf );
225
 
226
                // Name
225 - 227
                item = tableWidget->item(ii,1);
150 david 228
                if (item)
229
                {
230
                    strncpy(team_buf.name , qPrintable(item->data(Qt::EditRole).toString()), sizeof(team_buf.name));
231
                }
232
 
233
                // Category
225 - 234
                item = tableWidget->item(ii,2);
150 david 235
                if (item)
236
                {
180 - 237
                    int category = config.lookup_class(qPrintable(item->data(Qt::EditRole).toString()) );
150 david 238
                    if (category)
239
                    {
240
                        team_buf.teamclass = category;
241
                    }
152 - 242
                    else
243
                    {
244
                        bad_cat++;
245
                        bad = true;
246
                    }
150 david 247
                }
248
 
249
                // Team member names and ages
250
                int member = 0;
225 - 251
                for (int yy = 3; yy < tableWidget->columnCount(); yy+= 2, member++)
150 david 252
                {
151 david 253
                    if (member > config.num_legs)
254
                    {
255
                        break;
256
                    }
225 - 257
                    item = tableWidget->item(ii,yy);
150 david 258
                    if (item)
259
                    {
260
                        strncpy(team_buf.members[member].name , qPrintable(item->data(Qt::EditRole).toString()), sizeof(team_buf.members[member].name));
275 david 261
                        if ( hasRefError(item->data(Qt::EditRole).toString()) )
262
                        {
263
                            bad = true;
264
                            bad_refs++;
265
                        }
150 david 266
                    }
225 - 267
                    item = tableWidget->item(ii,1+yy);
150 david 268
                    if (item)
269
                    {
270
                        int age = item->data(Qt::EditRole).toInt();
271
                        if (age)
272
                        {
273
                            team_buf.members[member].age = age;
274
                        }
275
                    }
276
                }
277
 
253 - 278
                team_buf.flags.valid = TRUE;
150 david 279
                put_team_record( team, &team_buf );
280
            }
152 - 281
            else
282
            {
283
                bad = true;
284
            }
150 david 285
        }
152 - 286
        else
287
        {
288
            bad = true;
289
        }
290
        if (!bad)
291
        {
225 - 292
            tableWidget->hideRow(ii);
152 - 293
        }
150 david 294
    }
152 - 295
 
296
    // Report errors
275 david 297
    reportErrors( bad_cat, bad_refs);
298
}
299
 
300
/*----------------------------------------------------------------------------
301
** FUNCTION           : reportErrors
302
**
303
** DESCRIPTION        : Report errors on the main window
304
**
305
**
306
** INPUTS             : bad_cat - count of category erors
307
**                      bad_refs - count of Reference errors
308
**
309
** RETURNS            :
310
**
311
----------------------------------------------------------------------------*/
312
 
313
void QmDialogLoadExternalTeams::reportErrors( int bad_cat, int bad_refs )
314
{
315
    if ( bad_cat && bad_refs )
152 - 316
    {
275 david 317
        MainWindow::showMessage("Invalid Categories in data and bad REFs");
318
    }
319
    else if (bad_cat)
320
    {
152 - 321
        MainWindow::showMessage("Invalid Categories in data");
322
    }
275 david 323
    else if (bad_refs)
324
    {
325
        MainWindow::showMessage("Imported data has bad REFs");
326
    }
327
 
150 david 328
}
153 - 329
 
330
/*========================================================================
331
 *
332
 *  Generate team name file
333
 *
334
 *  Purpose:
335
 *      This function is called to Generate team name file in the format
336
 *      that can be read by the load command
337
 *
338
 *      The file contains team number,Team name,Team class
339
 *      The operator is prompted to enter the name of the file
340
 *
341
 *  Parameters:
342
 *      None
343
 *
344
 *  Returns:
345
 *      Nothing
346
 *
347
 *========================================================================*/
348
void QmDialogLoadExternalTeams::storeData(const QString &efile)
349
{
350
    QFile file(efile);
351
    if ( ! file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) )
352
    {
353
        MainWindow::showMessage("Cannot open external data file");
354
        return;
355
    }
356
    QTextStream out(&file);
357
 
358
    // Print headings
155 david 359
    out << toCsv("Team Number");
360
    out << "," << toCsv("Team Name");
361
    out << "," <<  toCsv("Class Abr");
153 - 362
 
363
    for( int j = 1; j <= config.num_legs; j++ )
364
    {
155 david 365
        out << "," << toCsv("Competitor Name");
366
        out << "," << toCsv("Age");
153 - 367
    }
368
    out << endl;
369
 
370
    /*
371
     * Put the data into the file
372
     */
174 - 373
    team_type   team_buf;
153 - 374
    for(int i = config.min_team; i <= config.max_team; i++ )
375
    {
376
        if( valid_field( i ) && g_record( i, &team_buf ) )
377
        {
378
            /*
379
            **  Basic information
380
            **      - Team number
381
            **      - Full team name
382
            */
155 david 383
            out << toCsv(team_buf.numb);
384
            out << "," << toCsv(team_buf.name);
385
            out << "," << toCsv(team_buf.teamclass == 0 ? "" : config.team_class[team_buf.teamclass - 1].abr);
153 - 386
 
387
            for(int j = 1; j <= config.num_legs; j++ )
388
            {
155 david 389
                out << "," << toCsv(team_buf.members[j-1].name);
390
                out << "," << toCsv(team_buf.members[j-1].age);
153 - 391
            }
392
            out <<endl;
393
        }
394
    }
395
}
155 david 396
 
397
QStringList QmDialogLoadExternalTeams::splitCsvData( const QString str)
398
{
399
    QStringList results;
400
 
401
    const QChar *data = str.constData();
402
    while (!data->isNull())
403
    {
404
        QString result;
405
        bool quoted = false;
406
        /*
407
        **  Extract the next record
408
        */
409
        while ( TRUE )
410
        {
411
            QChar uch = *data;
412
 
413
            /*
414
            **  End of the field
415
            */
416
            if ( uch == '\n' || uch == '\r' || uch == '\0' )
417
                break;
418
 
419
            data++;
420
 
421
            /*
422
            ** Ugly character from MS CSV files
276 david 423
            ** Not too sure what the 194 is. It looks like a 0xA0 in the raw data
155 david 424
            */
276 david 425
            if ( uch == (char) 0xA0 || uch == (char)194 )
155 david 426
            {
427
                continue;
428
            }
429
 
430
            if ( !quoted && uch == ',' )
431
            {
432
                break;
433
            }
434
 
435
            /*
436
            **  An unquoted " will start scanning for a matching quote
437
            */
438
            if ( !quoted && uch == '"' )
439
            {
440
                quoted = true;
441
                continue;
442
            }
443
 
444
            /*
445
            **  A quoted " may be an embedded quote or the end of a quote
446
            */
447
            if ( quoted && uch == '"' )
448
            {
449
                if ( *data != '"' )
450
                {
451
                    quoted = FALSE;
452
                    continue;
453
                }
454
 
455
                /*
456
                **  Skip one " and pick up the next
457
                */
458
                ++data;
459
            }
460
 
461
            /*
462
            **  Save this character
463
            */
464
            result += uch;
465
        }
466
 
467
        /*
468
        **  Clean up the extracted string
469
        */
470
        results += result.trimmed();
471
     }
472
    return results;
473
}
275 david 474
/*----------------------------------------------------------------------------
475
** FUNCTION           : hasRefError
476
**
477
** DESCRIPTION        : Determine if a string contains an Excel Reference
478
**                      error: #REF!
479
**
480
**
481
** INPUTS             : data - String to test
482
**
483
** RETURNS            : True: Is an error
484
**
485
----------------------------------------------------------------------------*/
155 david 486
 
275 david 487
bool QmDialogLoadExternalTeams::hasRefError( const QString data)
488
{
489
    return data.contains("#REF!");
490
}
491
 
156 david 492
/*========================================================================
493
 *
494
 *  Generate team name file
495
 *
496
 *  Purpose:
497
 *      This function is called to Generate team name file
498
 *
499
 *      The file contains team number,Team name,Team class
500
 *      The operator is prompted to enter the name of the file
501
 *
502
 *  Parameters:
503
 *      None
504
 *
505
 *  Returns:
506
 *      Nothing
507
 *
508
 *========================================================================*/
509
 
510
void QmDialogLoadExternalTeams::storeTeamInfo(const QString &efile)
511
{
512
    QFile file(efile);
513
    if ( ! file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) )
514
    {
515
        MainWindow::showMessage("Cannot open external team info file");
516
        return;
517
    }
518
    QTextStream out(&file);
519
 
520
     /*
521
     * Put the data into the file
522
     */
174 - 523
    team_type   team_buf;
156 david 524
    for(int i = config.min_team; i <= config.max_team; i++ )
525
    {
526
        if( valid_field( i ) && g_record( i, &team_buf ) )
527
        {
528
            /*
529
            **  Basic information
530
            **      - Team number
531
            **      - Full team name
532
            **      - Category
533
            */
534
            out.setFieldAlignment(QTextStream::AlignLeft);
535
            out.setFieldWidth(5);
536
            out << team_buf.numb;
537
            out.setFieldWidth(0);
538
            out << ",";
539
            out.setFieldWidth(MAX_TM_NAME+1);
540
            out << team_buf.name;
541
            out.setFieldWidth(0);
542
            out << ",";
543
            out << (team_buf.teamclass <= 0 ? "" : config.team_class[team_buf.teamclass - 1].abr);
544
            out <<endl;
545
        }
546
    }
547
}
548
 
155 david 549
QString QmDialogLoadExternalTeams::toCsv(const QString &str)
550
{
551
    QString result = QString(str);
552
    if ( result.contains("\"") || result.contains(",") )
553
    {
554
        result.replace("\"", "\"\"");
555
        result.prepend("\"");
556
        result.append("\"");
557
    }
558
    return result;
559
}
560
 
561
QString QmDialogLoadExternalTeams::toCsv(const int data)
562
{
563
    return QString::number(data);
564
}