Rev 300 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "qmdialogloadexternalteams.h"//#include "ui_qmdialogloadexternalteams.h"#include "QFile"#include "QTextStream"#include "mainwindow.h"#include <QRegExp>#include <QtGui/QHBoxLayout>#include <QtGui/QVBoxLayout>#include <QtGui/QWidget>#include <QHeaderView>#include <QtWebKit/QtWebKit>#include "consts.h"#include "structs.h"#include "proto.h"/*----------------------------------------------------------------------------** FUNCTION : QmDialogLoadExternalTeams**** DESCRIPTION : Load team data from a CSV file****** INPUTS : efile - name of file** parent - parent widget**** RETURNS :**----------------------------------------------------------------------------*/QmDialogLoadExternalTeams::QmDialogLoadExternalTeams(const QString &efile,QWidget *parent) :QDialog(parent){//// Create Windows//createWindow();fileName->setText(efile);// Open the users fileQFile file(efile);if ( ! file.open(QIODevice::ReadOnly | QIODevice::Text) ){MainWindow::showMessage("Cannot open external data file");return;}MainWindow::showMessage("Loading External Data");// Process Each line of the fileQTextStream in(&file);QRegExp csv_split("\"?,\"?");while (!in.atEnd()){QString line = in.readLine();line = line.trimmed(); // Remove leading and training White Spaceline.remove(0xA0); // M$ special uglynessline.remove(0xC2); // M$ special uglynessbool has_RefError = hasRefError(line);QStringList parts = splitCsvData(line);insertParts( parts, has_RefError );}// Post Load fix uptableWidget->resizeColumnsToContents();reportErrors( bad_cat, bad_refs);}/*----------------------------------------------------------------------------** FUNCTION : QmDialogLoadExternalTeams**** DESCRIPTION : Load team data from a Web Page****** INPUTS : efile - name of file (display only)** data - Address of the webpage data loaded in memory** parent - parent widget**** RETURNS :**----------------------------------------------------------------------------*/QmDialogLoadExternalTeams::QmDialogLoadExternalTeams(const QString &efile, QByteArray *data ,QWidget *parent) :QDialog(parent){// Create the basic WindowcreateWindow();fileName->setText(efile);// Parse the data. It is an html file//MainWindow::showMessage("Parsing HTML");//qDebug("Data size: %d", data->length());QWebPage page;QWebFrame * frame = page.mainFrame();frame->setContent(*data);/*** Get the first table** Get all rows** Get all data items in each row*/QWebElement document = frame->documentElement();QWebElement firstTable = document.findFirst("table");QWebElementCollection elements = firstTable.findAll("tr");foreach(QWebElement e, elements){//qDebug()<< "e element" <<e.tagName() << ":" << e.toPlainText();//qDebug("-----Row");bool has_RefError = hasRefError(e.toPlainText());QWebElementCollection td = e.findAll("td");QStringList parts;foreach(QWebElement e, td){//qDebug()<< e.tagName() << ":" << e.toPlainText();parts.append(e.toPlainText());}insertParts( parts, has_RefError );}// Post Load fix uptableWidget->resizeColumnsToContents();reportErrors( bad_cat, bad_refs);}/*----------------------------------------------------------------------------** FUNCTION : createWindow**** DESCRIPTION : Create the basic window** Used in multiple places****** INPUTS :**** RETURNS :**----------------------------------------------------------------------------*/void QmDialogLoadExternalTeams::createWindow(void){bad_cat = 0;bad_refs = 0;resize(550, 500);setSizeGripEnabled(true);setWindowTitle("Load External Team Data");QVBoxLayout *verticalLayout;verticalLayout = new QVBoxLayout(this);verticalLayout->setContentsMargins(0, 0, 0, 0);QVBoxLayout *verticalLayout2;verticalLayout2 = new QVBoxLayout();verticalLayout2->setContentsMargins(5, 5, 5, 5);QHBoxLayout *horizontalLayout;horizontalLayout = new QHBoxLayout();groupBox = new QGroupBox(this);groupBox->setTitle("Data");verticalLayout->addWidget(groupBox);groupBox->setLayout(verticalLayout2);tableWidget = new QTableWidget(groupBox);tableWidget->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);tableWidget->setGeometry(QRect(15, 21, 501, 421));tableWidget->setCornerButtonEnabled(false);tableWidget->verticalHeader()->setVisible(false);tableWidget->verticalHeader()->setDefaultSectionSize(20);tableWidget->verticalHeader()->setHighlightSections(true);verticalLayout2->addWidget(tableWidget);fileName = new QLineEdit(this);fileName->setObjectName(QString::fromUtf8("fileName"));fileName->setGeometry(QRect(20, 470, 331, 20));fileName->setReadOnly(true);horizontalLayout->addWidget(fileName);load = new QPushButton(this);load->setObjectName(QString::fromUtf8("load"));load->setGeometry(QRect(370, 470, 75, 23));load->setText("Load");horizontalLayout->addWidget(load);cancel = new QPushButton(this);cancel->setObjectName(QString::fromUtf8("cancel"));cancel->setGeometry(QRect(460, 470, 75, 23));cancel->setAutoDefault(false);cancel->setText("Cancel");horizontalLayout->addWidget(cancel);verticalLayout->addLayout(horizontalLayout);// Insert column headerstableWidget->setColumnCount(3 + ( 2 * config.num_legs) );QStringList labels;labels << "Team" << "Team Name" << "Cat";for (int ii = 1; ii <= config.num_legs; ii++ ){labels += QString("Leg:%1").arg(QString::number(ii));labels += QString("Age:%1").arg(QString::number(ii));}tableWidget->setHorizontalHeaderLabels(labels);// Connect up buttonsconnect (load, SIGNAL(clicked()), this, SLOT(loadData()));connect(cancel, SIGNAL(clicked()), this, SLOT(close()));}/*----------------------------------------------------------------------------** FUNCTION : insertParts**** DESCRIPTION : Insert raw data into the display table****** INPUTS : parts - Ref to a list of parts** has_RefError - Data has Ref Error**** RETURNS :**----------------------------------------------------------------------------*/void QmDialogLoadExternalTeams::insertParts(QStringList &parts, bool has_RefError){QString first = parts.value(0);bool ok;if ( first.isEmpty() )return;int team = first.toInt(&ok);if ( ! ok || team <= 0 )return;int ii = tableWidget->rowCount();tableWidget->setRowCount(1 + ii );// Insert Team numberQTableWidgetItem *item = new QTableWidgetItem(first);tableWidget->setItem(ii, 0, item );parts.removeFirst();if ( has_RefError ){item->setBackgroundColor(QColor(0,0,200,50));bad_refs++;}// Extract Team Nameitem = new QTableWidgetItem( parts.value(0) );tableWidget->setItem(ii, 1, item );if ( hasRefError(parts.value(0)) ){item->setBackgroundColor(QColor(0,0,200,50));}parts.removeFirst();// Extract Team Catitem = new QTableWidgetItem( parts.value(0)) ;tableWidget->setItem(ii, 2, item );if (config.lookup_class(qPrintable(parts.value(0)) ) <= 0 ){item->setBackgroundColor(QColor(200,0,0,50));bad_cat++;}if ( hasRefError(parts.value(0)) ){item->setBackgroundColor(QColor(0,0,200,50));}parts.removeFirst();int yy = 0;while ( parts.count() > 0){// Name of competitoritem = new QTableWidgetItem( parts.value(0));tableWidget->setItem(ii, 3+yy, item);if ( hasRefError(parts.value(0)) ){item->setBackgroundColor(QColor(0,0,200,50));}parts.removeFirst();// Not loading age at the moment// Reason: The CSV file is being create with a '0' for the NE teams#if DO_AGE_LOAD// Posible age - if its a numberint age = parts.value(0).toInt(&ok);if ( ok ){if ( age > 0 ){tableWidget->setItem(ii, 4+yy, new QTableWidgetItem( parts.value(0)));}parts.removeFirst();}#endifyy += 2;}}/*----------------------------------------------------------------------------** FUNCTION : ~QmDialogLoadExternalTeams**** DESCRIPTION : Class destructor****** INPUTS :**** RETURNS :**----------------------------------------------------------------------------*/QmDialogLoadExternalTeams::~QmDialogLoadExternalTeams(){}/*----------------------------------------------------------------------------** FUNCTION : loadData**** DESCRIPTION : Store the data from the table into the database****** INPUTS :**** RETURNS :**----------------------------------------------------------------------------*/void QmDialogLoadExternalTeams::loadData(void){qDebug ("LoadData");team_type team_buf;int bad_cat = 0;int bad_refs = 0;for ( int ii = 0; ii < tableWidget->rowCount(); ii++){if ( tableWidget->isRowHidden(ii)){continue;}bool bad = false;QTableWidgetItem *item;item = tableWidget->item(ii,0);if (item){int team = item->data(Qt::EditRole).toInt();if ( team > 0 && team <= config.max_team ){g_record( team, &team_buf );// Nameitem = tableWidget->item(ii,1);if (item){strncpy(team_buf.name , qPrintable(item->data(Qt::EditRole).toString()), sizeof(team_buf.name));}// Categoryitem = tableWidget->item(ii,2);if (item){int category = config.lookup_class(qPrintable(item->data(Qt::EditRole).toString()) );if (category){team_buf.teamclass = category;}else{bad_cat++;bad = true;}}// Team member names and agesint member = 0;for (int yy = 3; yy < tableWidget->columnCount(); yy+= 2, member++){if (member > config.num_legs){break;}item = tableWidget->item(ii,yy);if (item){strncpy(team_buf.members[member].name , qPrintable(item->data(Qt::EditRole).toString()), sizeof(team_buf.members[member].name));if ( hasRefError(item->data(Qt::EditRole).toString()) ){bad = true;bad_refs++;}}item = tableWidget->item(ii,1+yy);if (item){int age = item->data(Qt::EditRole).toInt();if (age){team_buf.members[member].age = age;}}}team_buf.flags.valid = TRUE;put_team_record( team, &team_buf );}else{bad = true;}}else{bad = true;}if (!bad){tableWidget->hideRow(ii);}}// Report errorsreportErrors( bad_cat, bad_refs);}/*----------------------------------------------------------------------------** FUNCTION : reportErrors**** DESCRIPTION : Report errors on the main window****** INPUTS : bad_cat - count of category erors** bad_refs - count of Reference errors**** RETURNS :**----------------------------------------------------------------------------*/void QmDialogLoadExternalTeams::reportErrors( int bad_cat, int bad_refs ){if ( bad_cat && bad_refs ){MainWindow::showMessage("Invalid Categories in data and bad REFs");}else if (bad_cat){MainWindow::showMessage("Invalid Categories in data");}else if (bad_refs){MainWindow::showMessage("Imported data has bad REFs");}}/*========================================================================** Generate team name file** Purpose:* This function is called to Generate team name file in the format* that can be read by the load command** The file contains team number,Team name,Team class* The operator is prompted to enter the name of the file** Parameters:* None** Returns:* Nothing**========================================================================*/void QmDialogLoadExternalTeams::storeData(const QString &efile){QFile file(efile);if ( ! file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) ){MainWindow::showMessage("Cannot open external data file");return;}QTextStream out(&file);// Print headingsout << toCsv("Team Number");out << "," << toCsv("Team Name");out << "," << toCsv("Class Abr");for( int j = 1; j <= config.num_legs; j++ ){out << "," << toCsv("Competitor Name");out << "," << toCsv("Age");}out << endl;/** Put the data into the file*/team_type team_buf;for(int i = config.min_team; i <= config.max_team; i++ ){if( valid_field( i ) && g_record( i, &team_buf ) ){/*** Basic information** - Team number** - Full team name*/out << toCsv(team_buf.numb);out << "," << toCsv(team_buf.name);out << "," << toCsv(team_buf.teamclass == 0 ? "" : config.team_class[team_buf.teamclass - 1].abr);for(int j = 1; j <= config.num_legs; j++ ){out << "," << toCsv(team_buf.members[j-1].name);out << "," << toCsv(team_buf.members[j-1].age);}out <<endl;}}}QStringList QmDialogLoadExternalTeams::splitCsvData( const QString str){QStringList results;const QChar *data = str.constData();while (!data->isNull()){QString result;bool quoted = false;/*** Extract the next record*/while ( TRUE ){QChar uch = *data;/*** End of the field*/if ( uch == '\n' || uch == '\r' || uch == '\0' )break;data++;/*** Ugly character from MS CSV files** Not too sure what the 194 is. It looks like a 0xA0 in the raw data*/if ( uch == (char) 0xA0 || uch == (char)194 ){continue;}if ( !quoted && uch == ',' ){break;}/*** An unquoted " will start scanning for a matching quote*/if ( !quoted && uch == '"' ){quoted = true;continue;}/*** A quoted " may be an embedded quote or the end of a quote*/if ( quoted && uch == '"' ){if ( *data != '"' ){quoted = FALSE;continue;}/*** Skip one " and pick up the next*/++data;}/*** Save this character*/result += uch;}/*** Clean up the extracted string*/results += result.trimmed();}return results;}/*----------------------------------------------------------------------------** FUNCTION : hasRefError**** DESCRIPTION : Determine if a string contains an Excel Reference** error: #REF!****** INPUTS : data - String to test**** RETURNS : True: Is an error**----------------------------------------------------------------------------*/bool QmDialogLoadExternalTeams::hasRefError( const QString data){return data.contains("#REF!");}/*========================================================================** Generate team name file** Purpose:* This function is called to Generate team name file** The file contains team number,Team name,Team class* The operator is prompted to enter the name of the file** Parameters:* None** Returns:* Nothing**========================================================================*/void QmDialogLoadExternalTeams::storeTeamInfo(const QString &efile){QFile file(efile);if ( ! file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) ){MainWindow::showMessage("Cannot open external team info file");return;}QTextStream out(&file);/** Put the data into the file*/team_type team_buf;for(int i = config.min_team; i <= config.max_team; i++ ){if( valid_field( i ) && g_record( i, &team_buf ) ){/*** Basic information** - Team number** - Full team name** - Category*/out.setFieldAlignment(QTextStream::AlignLeft);out.setFieldWidth(5);out << team_buf.numb;out.setFieldWidth(0);out << ",";out.setFieldWidth(MAX_TM_NAME+1);out << team_buf.name;out.setFieldWidth(0);out << ",";out << (team_buf.teamclass <= 0 ? "" : config.team_class[team_buf.teamclass - 1].abr);out <<endl;}}}QString QmDialogLoadExternalTeams::toCsv(const QString &str){QString result = QString(str);if ( result.contains("\"") || result.contains(",") ){result.replace("\"", "\"\"");result.prepend("\"");result.append("\"");}return result;}QString QmDialogLoadExternalTeams::toCsv(const int data){return QString::number(data);}