Subversion Repositories svn1-original

Rev

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

Rev Author Line No. Line
176 - 1
#include "qmconfig.h"
2
#include "mainwindow.h"
3
#include <QFileDialog>
4
#include <QObject>
5
#include <QMessageBox>
178 - 6
#include <QFileInfo>
7
#include <QFile>
176 - 8
 
9
// Global Data
180 - 10
QmConfig    config;
176 - 11
 
180 - 12
 
178 - 13
/*
14
**  Local definitions
15
*/
16
char        datfile[20];                         /* Name of the data file */
17
char        filebase[20];                        /* Event file name base */
18
char        filepath[100];
176 - 19
 
180 - 20
void QmConfig::load(const QString &cnfFile)
176 - 21
{
22
    fileName = cnfFile;
23
    if ( !fileName.endsWith(".cnf",Qt::CaseInsensitive))
24
    {
25
        fileName.append(".cnf");
26
    }
27
    if (cnfFile.isEmpty())
28
    {
29
        fileName = QFileDialog::getOpenFileName(0, "Select Config File",
178 - 30
                                                         filepath,
176 - 31
                                                         "Data (*.cnf);;All (*.*)",
32
                                                         0,
33
 
34
                                                         );
35
    }
36
 
37
    //  No file selected
38
    //  Just exit
39
    if (fileName.isEmpty())
40
    {
178 - 41
        qDebug("No Config file selected");
176 - 42
        exit(1);
43
    }
44
 
178 - 45
    //
46
    //  Setup ffile names
47
    //
48
    QFileInfo info (fileName);
49
    strncpy(filebase, qPrintable(info.baseName()), 8);
50
    strcpy( datfile, filebase );
51
    strcat( datfile, ".dat" );
52
 
53
    strncpy(filepath, qPrintable(info.absolutePath()), sizeof(filepath)-3);
54
    strcat(filepath, "/");
55
    qDebug("FilePath:%s", filepath );
56
 
176 - 57
    if ( !open_read_config() )
58
    {
59
        if (QMessageBox::Cancel == QMessageBox::question ( 0,
60
                                                       "Config Load Error",
61
                                                       "Cannot load or read configuration file.\n"
62
                                                       "If you continue a new configuration will be created\n"
63
                                                       "If you cancel then the application will terminate.",
64
                                                       QMessageBox::Ok | QMessageBox::Cancel
65
                                                       ) )
66
        {
178 - 67
            qDebug("Cancel to bad config");
176 - 68
            exit(2);
69
        }
70
    }
71
}
72
 
73
 
74
bool QmConfig::open_read_config( void )
75
{
76
    bool result;
77
    // Open the file
180 - 78
    QFile configFile;
176 - 79
    configFile.setFileName(fileName);
80
    if ( ! configFile.open(QIODevice::ReadOnly) )
81
    {
82
        MainWindow::showMessage("Cannot open config File");
83
        return (false );
84
    }
85
 
180 - 86
    result = read_config(configFile);
176 - 87
    configFile.close();
88
 
89
    if ( result )
90
    {
91
        /*
92
         **  Post read calculations and fixups
93
         */
180 - 94
        if( datafilename[0] )
176 - 95
        {
180 - 96
            strcpy( datfile, datafilename );
176 - 97
            strcat( datfile, ".dat" );
98
        }
180 - 99
        nonequestrian_class = lookup_class( nonequestrian_class_abr );
176 - 100
    }
101
    return result;
102
}
103
 
104
/*========================================================================
105
 *
106
 *  Read in the configuration file
107
 *
108
 *  Purpose:
109
 *      This function is called to read in the configuration file
110
 *      NOTE: Must be maintained with the Writer function
111
 *
112
 *  Parameters:
113
 *      fcon        File number of the config file
114
 *
115
 *  Returns:
116
 *      FALSE if an error is encountered
117
 *
118
 *========================================================================*/
119
 
180 - 120
bool QmConfig::read_config( QFile &configFile  )
176 - 121
{
122
    int         len;                            /* Length of data read */
123
    int         fsize;                          /* Length of desired data */
124
 
125
    /*
126
     * Event name
127
     */
128
qDebug( "Reading: Event Name" );
180 - 129
    fsize = sizeof( event_name );
130
    len = configFile.read( event_name, fsize );
176 - 131
    if( len != fsize )
132
        return ( FALSE );
133
 
134
    /*
135
     * Leg names
136
     */
137
qDebug( "Reading: Leg Names" );
180 - 138
    fsize = sizeof( leg_name );
139
    len = configFile.read( (char *)leg_name, fsize );
176 - 140
    if( len != fsize )
141
        return ( FALSE );
142
 
143
    /*
144
     * Team definitions
145
     */
146
qDebug( "Reading: Team Defs" );
180 - 147
    fsize = sizeof( t_def  );
148
    len = configFile.read( (char *)t_def, fsize );
176 - 149
    if( len != fsize )
150
        return ( FALSE );
151
 
152
    /*
153
     * Number of legs
154
     */
155
 
156
qDebug( "Reading: Leg Nums" );
180 - 157
    fsize = sizeof( num_legs  );
158
    len = configFile.read( (char *)&num_legs, fsize );
176 - 159
    if( len != fsize)
160
        return ( FALSE );
161
 
162
    /*
163
     * Number of team splits
164
     */
165
 
166
qDebug( "Reading: Team Splits" );
180 - 167
    fsize = sizeof( num_teams  );
168
    len = configFile.read( (char *)&num_teams, fsize );
176 - 169
    if( len != fsize )
170
        return ( FALSE );
171
 
180 - 172
    min_team = t_def[0].start;
173
    max_team = t_def[num_teams - 1].end;
176 - 174
 
175
    /*
176
     * Class information
177
     */
178
qDebug( "Reading: Class Data" );
180 - 179
    fsize = sizeof( team_class  );
180
    len = configFile.read( (char *)team_class, fsize );
176 - 181
    if( len != fsize )
182
        return ( FALSE );
180 - 183
    fsize = sizeof( num_class  );
184
    len = configFile.read( (char *)&num_class, fsize);
176 - 185
    if( len != fsize )
186
        return ( FALSE );
187
 
188
    /*
189
     * Country list
190
     */
191
 
192
qDebug( "Reading: Country Data, Name" );
180 - 193
    fsize = sizeof( country_name  );
194
    len = configFile.read( (char *)country_name, fsize );
176 - 195
    if( len != fsize )
196
        return ( FALSE );
197
 
198
qDebug( "Reading: Country Data, Number" );
180 - 199
    fsize = sizeof( num_countries  );
200
    len = configFile.read( (char *)&num_countries, fsize );
176 - 201
    if( len != fsize )
202
        return ( FALSE );
203
 
204
    /*
205
     * Addendum file
206
     */
207
 
208
qDebug( "Reading: Addendum File" );
180 - 209
    fsize = sizeof( addendum );
210
    len = configFile.read( addendum, fsize );
176 - 211
    if( len != fsize )
212
        return ( configFile.atEnd() );
213
 
214
    /*
215
     * Name of the data file
216
     */
217
 
218
qDebug( "Reading: Name of data file" );
180 - 219
    fsize = sizeof( datafilename );
220
    len = configFile.read( datafilename, fsize );
176 - 221
    if( len != fsize )
222
        return ( configFile.atEnd() );
223
 
224
    /*
225
     **  Non-equestrian configuration information
226
     */
227
qDebug( "Reading: NonEquest" );
180 - 228
    fsize = sizeof( nonequestrian_class_abr );
229
    len = configFile.read( nonequestrian_class_abr, fsize );
176 - 230
    if( len != fsize )
231
        return ( configFile.atEnd() );
232
 
233
qDebug( "Reading: NonEquest-2" );
180 - 234
    fsize = sizeof( equestrian_leg );
235
    len = configFile.read( (char *)&equestrian_leg, fsize );
176 - 236
    if( len != fsize )
237
        return ( FALSE );
238
 
239
    /*
240
    **  .txt file output control. Lines per page and perf-skipping
241
    */
242
qDebug( "Reading: Output Control" );
180 - 243
    fsize = sizeof( lines_per_page );
244
    len = configFile.read( (char *)&lines_per_page, fsize );
176 - 245
    if( len != fsize )
246
        return ( configFile.atEnd() );
247
 
248
qDebug( "Reading: Output Control-2" );
180 - 249
    fsize = sizeof( perf_skip );
250
    len = configFile.read( (char *)&perf_skip, fsize );
176 - 251
    if( len != fsize )
252
        return ( FALSE );
253
 
254
qDebug( "Reading: Winners Info" );
180 - 255
    fsize = sizeof( class_winners );
256
    len = configFile.read( (char *)&class_winners, fsize );
176 - 257
    if( len != fsize )
258
        return ( FALSE );
259
 
260
qDebug( "Reading: Hall of Fame Info" );
180 - 261
    fsize = sizeof( hall_fame );
262
    len = configFile.read( (char *)&hall_fame, fsize );
176 - 263
    if( len != fsize )
264
        return ( FALSE );
265
 
266
qDebug( "Reading: Hall of Fame Numbers" );
180 - 267
    fsize = sizeof( hall_fame );
268
    len = configFile.read( (char *)&num_fame, fsize );
176 - 269
    if( len != fsize )
270
        return ( configFile.atEnd() );
271
 
272
 
273
    return ( TRUE );
274
}
275
 
276
 
277
/*========================================================================
278
 *
279
 *  Write out the configuration file
280
 *
281
 *  Purpose:
282
 *      This function is called to write the configuration file
283
 *      NOTE: Must be maintained with the Reader function
284
 *
285
 *  Parameters:
286
 *      None
287
 *
288
 *  Returns:
289
 *      FALSE   : Error encountered
290
 *
291
 *========================================================================*/
292
 
293
bool QmConfig::write_config( void )
294
{
178 - 295
    if (fileName.isEmpty())
296
    {
297
        qDebug("No Config file selected");
298
        return(false);
299
    }
176 - 300
    /*
301
     **  Open as a binary file
302
     */
178 - 303
    QFile file;
304
    file.setFileName(fileName);
176 - 305
    if ( ! file.open(QIODevice::WriteOnly | QIODevice::Truncate) )
306
    {
178 - 307
        qDebug("File error: %s", qPrintable(file.errorString()));
308
        MainWindow::showMessage("Cannot open config file");
176 - 309
        return (false);
310
    }
311
 
312
     /*
313
     **  Write out multiple structures
314
     **     Event name
315
     **     Leg names
316
     **     Team definitions
317
     **     Number of legs
318
     **     Number fo team splits
319
     **     Class information
320
     **     Number of defined classes
321
     **     Country list
322
     **     Number of defined countries
180 - 323
     **     Legend addendum file name
176 - 324
     **     Data file name
325
     */
326
 
180 - 327
    file.write( (const char *) event_name, sizeof( event_name ) );
328
    file.write( (const char *) leg_name, sizeof( leg_name ) );
329
    file.write( (const char *) t_def, sizeof( t_def ) );
330
    file.write( (const char *) &num_legs, sizeof( num_legs ) );
331
    file.write( (const char *) &num_teams, sizeof( num_teams ) );
332
    file.write( (const char *) team_class, sizeof( team_class ) );
333
    file.write( (const char *) &num_class, sizeof( num_class ) );
334
    file.write( (const char *) country_name, sizeof( country_name ) );
335
    file.write( (const char *) &num_countries, sizeof( num_countries ) );
336
    file.write( (const char *) addendum, sizeof( addendum ) );
337
    file.write( (const char *) datafilename, sizeof( datafilename ) );
338
    file.write( (const char *) nonequestrian_class_abr, sizeof( nonequestrian_class_abr ) );
339
    file.write( (const char *) &equestrian_leg, sizeof( equestrian_leg ) );
340
    file.write( (const char *) &lines_per_page, sizeof( lines_per_page ) );
341
    file.write( (const char *) &perf_skip, sizeof( perf_skip ) );
342
    file.write( (const char *) &class_winners, sizeof( class_winners ) );
343
    file.write( (const char *) &hall_fame, sizeof( hall_fame ) );
344
    file.write( (const char *) &num_fame, sizeof( num_fame ) );
176 - 345
 
346
    file.close();
347
    return ( TRUE );
348
}
178 - 349
 
350
/*========================================================================
351
 *
352
 *  Qsort callback: Sort by team
353
 *
354
 *  Purpose:
355
 *      Function used by the team definition sort operation
356
 *      It will compare two entries of the team def structure and return an
357
 *      integer for gt eq lt conditions.
358
 *      Note : If the start is 0 the team entry does exist and is placed at the
359
 *      end of the sorted list.
360
 *
361
 *  Parameters:
362
 *      a           comparision entry
363
 *      b           comparision entry
364
 *
365
 *  Returns:
366
 *      gt, eq, lt as required
367
 *
368
 *========================================================================*/
369
 
370
int f_comp_int( const void *aa, const void *bb )
371
{
372
    const ty_t_def *a = (ty_t_def *)aa;
373
    const ty_t_def *b = (ty_t_def *)bb;
374
 
375
    if( a->start == 0 )
376
        return ( 1 );
377
    else if( b->start == 0 )
378
        return ( -1 );
379
    else
380
        return ( a->start - b->start );
381
}
382
 
383
/*========================================================================
384
 *
385
 *  Compact a string
386
 *
387
 *  Purpose:
388
 *      This function is called remove leading and trailing spaces from
389
 *      a string. Treats other non-printing characters as leading
390
 *      spaces. This solves a problem when importing data from a
391
 *      Microsoft CSV file with empty fields.
392
 *
393
 *  Parameters:
394
 *      str     Address of the string to compact
395
 *
396
 *  Returns:
397
 *      Nothing
398
 *
399
 *========================================================================*/
400
 
401
void compact( char *str )
402
{
403
    char       *ptr;
404
 
405
    ptr = str;
406
    while( *str && ( isspace( *str ) || !isprint( *str ) ) )
407
        str++;
408
    strcpy( ptr, str );
409
}
410
 
411
/*========================================================================
412
 *
413
 *  Validate a team number
414
 *
415
 *  Purpose:
416
 *      This function is called to validate a team number
417
 *
418
 *  Parameters:
419
 *      x       Number to validate
420
 *
421
 *  Returns:
422
 *      TRUE    : Valid
423
 *      FALSE   : Not valid
424
 *
425
 *========================================================================*/
426
 
427
bool valid_field( int x )
428
{
429
    int         i;
430
 
431
    for( i = 0; i < config.num_teams; i++ )
432
    {
433
        if( x <= config.t_def[i].end && x >= config.t_def[i].start )
434
            return ( TRUE );
435
        if( x < config.t_def[i].start )
436
            break;                               /* Because the list is sorted */
437
    }
438
    return ( FALSE );
439
}
440
 
441
/*========================================================================
442
 *
443
 *  Get a class descriptor from existing text
444
 *
445
 *  Purpose:
446
 *      This function is called to Get a class descriptor
447
 *
448
 *  Parameters:
449
 *      text    - User text to examine
450
 *      config  - configuration dtaa to use
451
 *
452
 *  Returns:
453
 *      An integer which is the index into the  config.team_class array
454
 *      The integer is in the range 1 .. num_class
455
 *      A value fo zero indicates the text was not found.
456
 *
457
 *========================================================================*/
458
 
180 - 459
int QmConfig::lookup_class( const char *text )
178 - 460
{
461
    int         i;
462
 
180 - 463
//    if( config_ptr == NULL )
464
//        config_ptr = &config;
178 - 465
 
466
    /*
467
     * Attempt to locate the entered class in the list of defined classes
468
     */
469
 
180 - 470
    for( i = 0; i < num_class; i++ )
178 - 471
    {
180 - 472
        if( toupper(text[0]) == toupper(team_class[i].abr[0]) &&
473
            toupper(text[1]) == toupper(team_class[i].abr[1]) )
178 - 474
            return ( ++i );
475
    }
476
    return ( 0 );
477
}
181 - 478
 
479
#ifdef DISPLAY_STRUCTURES
480
/*============================================================================
481
**
482
**  Display structure information
483
**
484
**  Purpose:    Display internal structure information
485
**
486
**  Parameters: Nothing
487
**
488
**  Returns:    Nothing directly
489
**
490
**===========================================================================*/
491
 
492
/*
493
**  esize - A macro to return the size of a structure element
494
**  element - print element information
495
*/
496
#define esize( st, el) ( sizeof(((st *)0)->el))
497
#define element( st, el) \
498
    printf( "Offset of %-15s :%4d, Size:%d   \n", #el, offsetof( st, el), esize(st, el) );
499
 
500
void display_structures(void)
501
{
502
    printf( "Structure: leg_type\n" );
503
    element( leg_type, start    );
504
    element( leg_type, end      );
505
    element( leg_type, elapsed  );
506
    element( leg_type, l_place  );
507
    element( leg_type, le_place );
508
    element( leg_type, lc_place );
509
    element( leg_type, lec_place);
510
    element( leg_type, manual   );
511
    printf( "Sizeof %-18s :%4d\n", "leg_type", sizeof(leg_type) );
512
 
513
 
514
    printf( "\n" );
515
    printf( "Structure: team_type\n" );
516
    element( team_type, numb   );
517
    element( team_type, name   );
518
    element( team_type, leg    );
519
    element( team_type, members);
520
    element( team_type, class  );
521
    element( team_type, country);
522
    element( team_type, flags  );
523
    printf( "Sizeof %-18s :%4d\n", "team_type", sizeof(team_type) );
524
 
525
    printf( "\n" );
526
    printf( "Structure: MARA_CFG\n" );
527
    element( MARA_CFG, event_name      );
528
    element( MARA_CFG, leg_name        );
529
    element( MARA_CFG, t_def           );
530
    element( MARA_CFG, num_legs        );
531
    element( MARA_CFG, num_teams       );
532
    element( MARA_CFG, max_team        );
533
    element( MARA_CFG, min_team        );
534
    element( MARA_CFG, team_class      );
535
    element( MARA_CFG, num_class       );
536
    element( MARA_CFG, country_name    );
537
    element( MARA_CFG, num_countries   );
538
    element( MARA_CFG, addendum        );
539
    element( MARA_CFG, datafilename    );
540
    printf( "Sizeof %-18s :%4d\n", "MARA_CFG", sizeof(MARA_CFG) );
541
}
542
#endif