Rev 176 | Rev 199 | 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 DataQmConfig config;/*** Local definitions*/char datfile[20]; /* Name of the data file */char filebase[20]; /* Event file name base */char filepath[100];void QmConfig::load(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 fileQFile configFile;configFile.setFileName(fileName);if ( ! configFile.open(QIODevice::ReadOnly) ){MainWindow::showMessage("Cannot open config File");return (false );}result = read_config(configFile);configFile.close();if ( result ){/*** Post read calculations and fixups*/if( datafilename[0] ){strcpy( datfile, datafilename );strcat( datfile, ".dat" );}nonequestrian_class = lookup_class( nonequestrian_class_abr );}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( QFile &configFile ){int len; /* Length of data read */int fsize; /* Length of desired data *//** Event name*/qDebug( "Reading: Event Name" );fsize = sizeof( event_name );len = configFile.read( event_name, fsize );if( len != fsize )return ( FALSE );/** Leg names*/qDebug( "Reading: Leg Names" );fsize = sizeof( leg_name );len = configFile.read( (char *)leg_name, fsize );if( len != fsize )return ( FALSE );/** Team definitions*/qDebug( "Reading: Team Defs" );fsize = sizeof( t_def );len = configFile.read( (char *)t_def, fsize );if( len != fsize )return ( FALSE );/** Number of legs*/qDebug( "Reading: Leg Nums" );fsize = sizeof( num_legs );len = configFile.read( (char *)&num_legs, fsize );if( len != fsize)return ( FALSE );/** Number of team splits*/qDebug( "Reading: Team Splits" );fsize = sizeof( num_teams );len = configFile.read( (char *)&num_teams, fsize );if( len != fsize )return ( FALSE );min_team = t_def[0].start;max_team = t_def[num_teams - 1].end;/** Class information*/qDebug( "Reading: Class Data" );fsize = sizeof( team_class );len = configFile.read( (char *)team_class, fsize );if( len != fsize )return ( FALSE );fsize = sizeof( num_class );len = configFile.read( (char *)&num_class, fsize);if( len != fsize )return ( FALSE );/** Country list*/qDebug( "Reading: Country Data, Name" );fsize = sizeof( country_name );len = configFile.read( (char *)country_name, fsize );if( len != fsize )return ( FALSE );qDebug( "Reading: Country Data, Number" );fsize = sizeof( num_countries );len = configFile.read( (char *)&num_countries, fsize );if( len != fsize )return ( FALSE );/** Addendum file*/qDebug( "Reading: Addendum File" );fsize = sizeof( addendum );len = configFile.read( addendum, fsize );if( len != fsize )return ( configFile.atEnd() );/** Name of the data file*/qDebug( "Reading: Name of data file" );fsize = sizeof( datafilename );len = configFile.read( datafilename, fsize );if( len != fsize )return ( configFile.atEnd() );/*** Non-equestrian configuration information*/qDebug( "Reading: NonEquest" );fsize = sizeof( nonequestrian_class_abr );len = configFile.read( nonequestrian_class_abr, fsize );if( len != fsize )return ( configFile.atEnd() );qDebug( "Reading: NonEquest-2" );fsize = sizeof( equestrian_leg );len = configFile.read( (char *)&equestrian_leg, fsize );if( len != fsize )return ( FALSE );/*** .txt file output control. Lines per page and perf-skipping*/qDebug( "Reading: Output Control" );fsize = sizeof( lines_per_page );len = configFile.read( (char *)&lines_per_page, fsize );if( len != fsize )return ( configFile.atEnd() );qDebug( "Reading: Output Control-2" );fsize = sizeof( perf_skip );len = configFile.read( (char *)&perf_skip, fsize );if( len != fsize )return ( FALSE );qDebug( "Reading: Winners Info" );fsize = sizeof( class_winners );len = configFile.read( (char *)&class_winners, fsize );if( len != fsize )return ( FALSE );qDebug( "Reading: Hall of Fame Info" );fsize = sizeof( hall_fame );len = configFile.read( (char *)&hall_fame, fsize );if( len != fsize )return ( FALSE );qDebug( "Reading: Hall of Fame Numbers" );fsize = sizeof( hall_fame );len = configFile.read( (char *)&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 addendum file name** Data file name*/file.write( (const char *) event_name, sizeof( event_name ) );file.write( (const char *) leg_name, sizeof( leg_name ) );file.write( (const char *) t_def, sizeof( t_def ) );file.write( (const char *) &num_legs, sizeof( num_legs ) );file.write( (const char *) &num_teams, sizeof( num_teams ) );file.write( (const char *) team_class, sizeof( team_class ) );file.write( (const char *) &num_class, sizeof( num_class ) );file.write( (const char *) country_name, sizeof( country_name ) );file.write( (const char *) &num_countries, sizeof( num_countries ) );file.write( (const char *) addendum, sizeof( addendum ) );file.write( (const char *) datafilename, sizeof( datafilename ) );file.write( (const char *) nonequestrian_class_abr, sizeof( nonequestrian_class_abr ) );file.write( (const char *) &equestrian_leg, sizeof( equestrian_leg ) );file.write( (const char *) &lines_per_page, sizeof( lines_per_page ) );file.write( (const char *) &perf_skip, sizeof( perf_skip ) );file.write( (const char *) &class_winners, sizeof( class_winners ) );file.write( (const char *) &hall_fame, sizeof( hall_fame ) );file.write( (const char *) &num_fame, sizeof( 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 QmConfig::lookup_class( const char *text ){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 < num_class; i++ ){if( toupper(text[0]) == toupper(team_class[i].abr[0]) &&toupper(text[1]) == toupper(team_class[i].abr[1]) )return ( ++i );}return ( 0 );}#ifdef DISPLAY_STRUCTURES/*============================================================================**** Display structure information**** Purpose: Display internal structure information**** Parameters: Nothing**** Returns: Nothing directly****===========================================================================*//*** esize - A macro to return the size of a structure element** element - print element information*/#define esize( st, el) ( sizeof(((st *)0)->el))#define element( st, el) \printf( "Offset of %-15s :%4d, Size:%d \n", #el, offsetof( st, el), esize(st, el) );void display_structures(void){printf( "Structure: leg_type\n" );element( leg_type, start );element( leg_type, end );element( leg_type, elapsed );element( leg_type, l_place );element( leg_type, le_place );element( leg_type, lc_place );element( leg_type, lec_place);element( leg_type, manual );printf( "Sizeof %-18s :%4d\n", "leg_type", sizeof(leg_type) );printf( "\n" );printf( "Structure: team_type\n" );element( team_type, numb );element( team_type, name );element( team_type, leg );element( team_type, members);element( team_type, class );element( team_type, country);element( team_type, flags );printf( "Sizeof %-18s :%4d\n", "team_type", sizeof(team_type) );printf( "\n" );printf( "Structure: MARA_CFG\n" );element( MARA_CFG, event_name );element( MARA_CFG, leg_name );element( MARA_CFG, t_def );element( MARA_CFG, num_legs );element( MARA_CFG, num_teams );element( MARA_CFG, max_team );element( MARA_CFG, min_team );element( MARA_CFG, team_class );element( MARA_CFG, num_class );element( MARA_CFG, country_name );element( MARA_CFG, num_countries );element( MARA_CFG, addendum );element( MARA_CFG, datafilename );printf( "Sizeof %-18s :%4d\n", "MARA_CFG", sizeof(MARA_CFG) );}#endif