Rev 172 | Rev 175 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "qmconfig.h"#include "mainwindow.h"#include <QFileDialog>#include <QObject>#include <QMessageBox>#include <QFileInfo>#include <QFile>// Global DataMARA_CFG config;QString fileName;/*** Local definitions*/char confile[20]; /* Name of the config file */char datfile[20]; /* Name of the data file */char filebase[20]; /* Event file name base */char filepath[100];QmConfig::QmConfig(const QString &cnfFile){fileName = cnfFile;if ( !fileName.endsWith(".cnf",Qt::CaseInsensitive)){fileName.append(".cnf");}if (cnfFile.isEmpty()){fileName = QFileDialog::getOpenFileName(0, "Select Config File",filepath,"Data (*.cnf);;All (*.*)",0,0);}// No file selected// Just exitif (fileName.isEmpty()){qDebug("No Config file selected");exit(1);}//// Setup ffile names//QFileInfo info (fileName);strncpy(filebase, qPrintable(info.baseName()), 8);strcpy( datfile, filebase );strcat( datfile, ".dat" );strncpy(filepath, qPrintable(info.absolutePath()), sizeof(filepath)-3);strcat(filepath, "/");qDebug("FilePath:%s", filepath );if ( !open_read_config() ){if (QMessageBox::Cancel == QMessageBox::question ( 0,"Config Load Error","Cannot load or read configuration file.\n""If you continue a new configuration will be created\n""If you cancel then the application will terminate.",QMessageBox::Ok | QMessageBox::Cancel) ){qDebug("Cancel to bad config");exit(2);}}}bool QmConfig::open_read_config( void ){bool result;// Open the fileconfigFile.setFileName(fileName);if ( ! configFile.open(QIODevice::ReadOnly) ){MainWindow::showMessage("Cannot open config File");return (false );}result = read_config();configFile.close();if ( result ){/*** Post read calculations and fixups*/if( config.datafilename[0] ){strcpy( datfile, config.datafilename );strcat( datfile, ".dat" );}config.nonequestrian_class = lookup_class( config.nonequestrian_class_abr, &config );}return result;}/*========================================================================** Read in the configuration file** Purpose:* This function is called to read in the configuration file* NOTE: Must be maintained with the Writer function** Parameters:* fcon File number of the config file** Returns:* FALSE if an error is encountered**========================================================================*/bool QmConfig::read_config( void ){int len; /* Length of data read */int fsize; /* Length of desired data *//** Event name*/qDebug( "Reading: Event Name" );fsize = sizeof( config.event_name );len = configFile.read( config.event_name, fsize );if( len != fsize )return ( FALSE );/** Leg names*/qDebug( "Reading: Leg Names" );fsize = sizeof( config.leg_name );len = configFile.read( (char *)config.leg_name, fsize );if( len != fsize )return ( FALSE );/** Team definitions*/qDebug( "Reading: Team Defs" );fsize = sizeof( config.t_def );len = configFile.read( (char *)config.t_def, fsize );if( len != fsize )return ( FALSE );/** Number of legs*/qDebug( "Reading: Leg Nums" );fsize = sizeof( config.num_legs );len = configFile.read( (char *)&config.num_legs, fsize );if( len != fsize)return ( FALSE );/** Number of team splits*/qDebug( "Reading: Team Splits" );fsize = sizeof( config.num_teams );len = configFile.read( (char *)&config.num_teams, fsize );if( len != fsize )return ( FALSE );config.min_team = config.t_def[0].start;config.max_team = config.t_def[config.num_teams - 1].end;/** Class information*/qDebug( "Reading: Class Data" );fsize = sizeof( config.team_class );len = configFile.read( (char *)config.team_class, fsize );if( len != fsize )return ( FALSE );fsize = sizeof( config.num_class );len = configFile.read( (char *)&config.num_class, fsize);if( len != fsize )return ( FALSE );/** Country list*/qDebug( "Reading: Country Data, Name" );fsize = sizeof( config.country_name );len = configFile.read( (char *)config.country_name, fsize );if( len != fsize )return ( FALSE );qDebug( "Reading: Country Data, Number" );fsize = sizeof( config.num_countries );len = configFile.read( (char *)&config.num_countries, fsize );if( len != fsize )return ( FALSE );/** Addendum file*/qDebug( "Reading: Addendum File" );fsize = sizeof( config.addendum );len = configFile.read( config.addendum, fsize );if( len != fsize )return ( configFile.atEnd() );/** Name of the data file*/qDebug( "Reading: Name of data file" );fsize = sizeof( config.datafilename );len = configFile.read( config.datafilename, fsize );if( len != fsize )return ( configFile.atEnd() );/*** Non-equestrian configuration information*/qDebug( "Reading: NonEquest" );fsize = sizeof( config.nonequestrian_class_abr );len = configFile.read( config.nonequestrian_class_abr, fsize );if( len != fsize )return ( configFile.atEnd() );qDebug( "Reading: NonEquest-2" );fsize = sizeof( config.equestrian_leg );len = configFile.read( (char *)&config.equestrian_leg, fsize );if( len != fsize )return ( FALSE );/*** .txt file output control. Lines per page and perf-skipping*/qDebug( "Reading: Output Control" );fsize = sizeof( config.lines_per_page );len = configFile.read( (char *)&config.lines_per_page, fsize );if( len != fsize )return ( configFile.atEnd() );qDebug( "Reading: Output Control-2" );fsize = sizeof( config.perf_skip );len = configFile.read( (char *)&config.perf_skip, fsize );if( len != fsize )return ( FALSE );qDebug( "Reading: Winners Info" );fsize = sizeof( config.class_winners );len = configFile.read( (char *)&config.class_winners, fsize );if( len != fsize )return ( FALSE );qDebug( "Reading: Hall of Fame Info" );fsize = sizeof( config.hall_fame );len = configFile.read( (char *)&config.hall_fame, fsize );if( len != fsize )return ( FALSE );qDebug( "Reading: Hall of Fame Numbers" );fsize = sizeof( config.hall_fame );len = configFile.read( (char *)&config.num_fame, fsize );if( len != fsize )return ( configFile.atEnd() );return ( TRUE );}/*========================================================================** Write out the configuration file** Purpose:* This function is called to write the configuration file* NOTE: Must be maintained with the Reader function** Parameters:* None** Returns:* FALSE : Error encountered**========================================================================*/bool QmConfig::write_config( void ){if (fileName.isEmpty()){qDebug("No Config file selected");return(false);}/*** Open as a binary file*/QFile file;file.setFileName(fileName);if ( ! file.open(QIODevice::WriteOnly | QIODevice::Truncate) ){qDebug("File error: %s", qPrintable(file.errorString()));MainWindow::showMessage("Cannot open config file");return (false);}/*** Write out multiple structures** Event name** Leg names** Team definitions** Number of legs** Number fo team splits** Class information** Number of defined classes** Country list** Number of defined countries** Legend config.addendum file name** Data file name*/file.write( (const char *) config.event_name, sizeof( config.event_name ) );file.write( (const char *) config.leg_name, sizeof( config.leg_name ) );file.write( (const char *) config.t_def, sizeof( config.t_def ) );file.write( (const char *) &config.num_legs, sizeof( config.num_legs ) );file.write( (const char *) &config.num_teams, sizeof( config.num_teams ) );file.write( (const char *) config.team_class, sizeof( config.team_class ) );file.write( (const char *) &config.num_class, sizeof( config.num_class ) );file.write( (const char *) config.country_name, sizeof( config.country_name ) );file.write( (const char *) &config.num_countries, sizeof( config.num_countries ) );file.write( (const char *) config.addendum, sizeof( config.addendum ) );file.write( (const char *) config.datafilename, sizeof( config.datafilename ) );file.write( (const char *) config.nonequestrian_class_abr, sizeof( config.nonequestrian_class_abr ) );file.write( (const char *) &config.equestrian_leg, sizeof( config.equestrian_leg ) );file.write( (const char *) &config.lines_per_page, sizeof( config.lines_per_page ) );file.write( (const char *) &config.perf_skip, sizeof( config.perf_skip ) );file.write( (const char *) &config.class_winners, sizeof( config.class_winners ) );file.write( (const char *) &config.hall_fame, sizeof( config.hall_fame ) );file.write( (const char *) &config.num_fame, sizeof( config.num_fame ) );file.close();return ( TRUE );}/*========================================================================** Qsort callback: Sort by team** Purpose:* Function used by the team definition sort operation* It will compare two entries of the team def structure and return an* integer for gt eq lt conditions.* Note : If the start is 0 the team entry does exist and is placed at the* end of the sorted list.** Parameters:* a comparision entry* b comparision entry** Returns:* gt, eq, lt as required**========================================================================*/int f_comp_int( const void *aa, const void *bb ){const ty_t_def *a = (ty_t_def *)aa;const ty_t_def *b = (ty_t_def *)bb;if( a->start == 0 )return ( 1 );else if( b->start == 0 )return ( -1 );elsereturn ( a->start - b->start );}/*========================================================================** Compact a string** Purpose:* This function is called remove leading and trailing spaces from* a string. Treats other non-printing characters as leading* spaces. This solves a problem when importing data from a* Microsoft CSV file with empty fields.** Parameters:* str Address of the string to compact** Returns:* Nothing**========================================================================*/void compact( char *str ){char *ptr;ptr = str;while( *str && ( isspace( *str ) || !isprint( *str ) ) )str++;strcpy( ptr, str );}/*========================================================================** Validate a team number** Purpose:* This function is called to validate a team number** Parameters:* x Number to validate** Returns:* TRUE : Valid* FALSE : Not valid**========================================================================*/bool valid_field( int x ){int i;for( i = 0; i < config.num_teams; i++ ){if( x <= config.t_def[i].end && x >= config.t_def[i].start )return ( TRUE );if( x < config.t_def[i].start )break; /* Because the list is sorted */}return ( FALSE );}/*========================================================================** Get a class descriptor from existing text** Purpose:* This function is called to Get a class descriptor** Parameters:* text - User text to examine* config - configuration dtaa to use** Returns:* An integer which is the index into the config.team_class array* The integer is in the range 1 .. num_class* A value fo zero indicates the text was not found.**========================================================================*/int lookup_class( const char *text, MARA_CFG * config_ptr ){int i;if( config_ptr == NULL )config_ptr = &config;/** Attempt to locate the entered class in the list of defined classes*/for( i = 0; i < config_ptr->num_class; i++ ){if( toupper(text[0]) == toupper(config_ptr->team_class[i].abr[0]) &&toupper(text[1]) == toupper(config_ptr->team_class[i].abr[1]) )return ( ++i );}return ( 0 );}