Subversion Repositories svn1

Rev

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

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