Subversion Repositories svn1-original

Rev

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