Subversion Repositories svn1

Rev

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

Rev Author Line No. Line
91 - 1
/*************************************************************************
2
 *          Copyright (C) 1995 Embedded Solutions
3
 *                      All rights reserved
4
 *
5
 * file:        src\print.c
6
 *
7
 * purpose: Module to interface to the printer channel (file)
8
 *
9
 * functions
10
 *      open_printer            - Open the printer
11
 *      close_printer           - Close the printer
12
 *      print                   - Print to to the printer
13
 *      printbanner             - Print a page banner
14
 *
15
 * programmer: David Purdie
16
 *
17
 * revision date        by      reason
18
 *  00.0    27/01/95    DDP     Tidies up the program and formatted the file
19
 *
20
 **************************************************************************/
174 - 21
#include <QString>
91 - 22
#include    <stdio.h>
23
#include    <time.h>
24
#include    <stdarg.h>
170 - 25
#include    "mainwindow.h"
91 - 26
 
27
#include    "consts.h"
28
#include    "structs.h"
29
#include    "proto.h"
30
 
31
FILE       *pfile;                               /* Fd of the printer channel */
32
long        pri_time;                            /* Time printer is opened - for banners */
33
int         print_width;                         /* Width of the printout */
34
report_type print_html = text;                   /* Printing with HTML */
35
int         print_col = 0;                       /* Current print column */
36
int         print_line = 0;                      /* Current print line */
37
int         print_underline_start;               /* Start of underline */
38
int         print_underline_end;                 /* End of underline */
39
long        print_current_colour;                /* Current printing colour */
40
 
41
/*========================================================================
42
 *
43
 *  Open the printer
44
 *
45
 *  Purpose:
46
 *      This function is called to open the printer and prepare to print
47
 *
48
 *  Parameters:
49
 *      name        Name of print file
50
 *      ext         Ext of the print file
51
 *      width       Width of the printed file
52
 *      html        Printing in HTML mode
53
 *
54
 *  Returns:
55
 *      TRUE if the printer can be attached
56
 *
57
 *
58
 *  Note: Use an "htm" file extension as DOS cannot handle 4 letter extensions
59
 *========================================================================*/
60
 
61
bool open_printer( const char *name, const char *ext, int width, report_type html, const char *title )
62
{
63
    char    *pname;
64
 
65
    /*
66
    **  Determine the name of the file
67
    **  May need to modify the extension if it is an HTML file
68
    */
69
    if ( html )
70
    {
71
        if ( html == printed )
72
            pname = p_filename( name[0] ? name : filebase, ext ,"prn.html" );
73
        else
74
            pname = p_filename( name[0] ? name : filebase, ext ,"html" );
75
    }
76
    else
77
    {
78
        pname = p_filename( filebase, name[0] ? name : "", ext[0] ? ext : "lst" );
79
    }
80
 
81
    /*
82
    **  Now use basic function
83
    */
84
    return open_printer_name (pname, width, html, title );
85
}
86
 
87
/*----------------------------------------------------------------------------
88
 * FUNCTION           : open_printer_name
89
 *
90
 * DESCRIPTION        : Open a printer with a known name
91
 *
92
 *      This function is called to open the printer and prepare to print
93
 *
94
 *  Parameters:
95
 *      pname       Name of print file
96
 *      width       Width of the printed file
97
 *      html        Printing in HTML mode
98
 *
99
 *  Returns:
100
 *      TRUE if the printer can be attached
101
 *
102
 *
103
 *  Note: Use an "htm" file extension as DOS cannot handle 4 letter extensions
104
----------------------------------------------------------------------------*/
105
 
106
bool open_printer_name( const char *pname, int width, report_type html, const char *title )
107
{
174 - 108
    QString printFileName(filepath);
109
    printFileName.append(pname);
110
 
91 - 111
    print_width = width ? width : 80;
112
    print_col = 0;
113
    print_line = 0;
114
    print_underline_start = -1;
115
    print_underline_end = -1;
116
    print_current_colour = 0;
117
 
118
    /*
119
    **  Open the printer
120
    **  Ensure that it is opened in text mode
121
    */
174 - 122
    if( ( pfile = fopen( qPrintable(printFileName), "wt" ) ) != NULL )
91 - 123
    {
124
        time( &pri_time );                       /* Latch the time */
125
 
126
        /*
127
        **  Print out the HTML file header
128
        */
129
        if ( html )
130
        {
131
            print( "<HTML>\n" );
132
            print( "<HEAD>\n" );
133
            print( "<TITLE>%s - %s</TITLE>\n", config.event_name, title );
134
//            print( "<LINK rel=\"stylesheet\" href=\"brmr.css\" type=\"text/css\">\n");
135
            print( "</HEAD>\n" );
136
            print( "<BODY LANG=\"en-US\">\n" );
137
            print( "<PRE>" );
138
            print_html = html;
139
        }
140
 
141
        /*
142
        **  Print out a common banner
143
        */
144
        printbanner(title);
145
    }
146
    else
147
    {
170 - 148
        MainWindow::showMessage("Printer not available");
91 - 149
    }
150
    return ( pfile != 0 );
151
}
152
 
153
/*========================================================================
154
 *
155
 *  Close the printer
156
 *
157
 *  Purpose:
158
 *      This function is called to close and release the printer
159
 *      All reports are terminated with a formfeed
160
 *
161
 *  Parameters:
162
 *      None
163
 *
164
 *  Returns:
165
 *      TRUE if the printer channel can be released
166
 *
167
 *========================================================================*/
168
 
169
bool close_printer(void)
170
{
171
    if ( print_html )
172
    {
173
        print_html = text;
174
        print( "</PRE>\n" );
175
        print( "</BODY>\n" );
176
        print( "</HTML>\n" );
177
    }
178
    else
179
    {
180
        print( "\014" );
181
    }
182
    fclose( pfile );
183
    return ( TRUE );
184
}
185
 
186
/*========================================================================
187
 *
188
 *  Print to to the printer
189
 *
190
 *  Purpose:
191
 *      This function is called to do print data on the printer
192
 *      Track current character index so as to assist in tracking the
193
 *      use of underline.
194
 *
195
 *  Assume:
196
 *      New lines are at the end of a line printed. This does allow for
197
 *      a single new-line.
198
 *
199
 *
200
 *  Parameters:
201
 *      Standard printf type parameters
202
 *
203
 *  Returns:
204
 *      TRUE : Operation was succesful
205
 *
206
 *========================================================================*/
207
 
208
int print( const char *format, ... )
209
{
210
    va_list     ap;
211
    char        pp[200];
212
    int         len;
213
    bool        eol = FALSE;
214
 
215
 
216
    /*
217
    **  If this is the start of a new line then we may need to colour it
218
    */
219
    if ( print_col == 0 && print_html && (print_line & 1) )
220
    {
221
        print_colour( HTML_COLOUR_GREEN );
222
    }
223
 
224
    /*
225
    **  If this is the start of a new line then we may need to perform
226
    **  a perf-skip
227
    */
228
    if ( print_col == 0 && print_line && ! print_html && config.lines_per_page && config.perf_skip )
229
    {
230
        if ( 0 == ((print_line + 2) % (config.lines_per_page - config.perf_skip)) )
231
        {
232
            int count = config.perf_skip;
233
            while ( count-- )
234
                fwrite( "\n", 1, 1, pfile );
235
        }
236
    }
237
 
238
    va_start( ap, format );
239
    len = vsprintf( pp, format, ap );
240
    va_end( ap );
241
 
242
    /*
243
    **  Detect the end of a line and flag for later processing
244
    */
245
    if ( len > 0 && pp[len - 1] == '\n' )
246
    {
247
        len--;
248
        eol = TRUE;
249
    }
250
 
251
    if ( len )
252
    {
253
        fwrite( pp, 1, len, pfile );
254
        print_col += len;
255
    }
256
 
257
    /*
258
    **  Perform End of Line operation before printing the final newline
259
    */
260
    if ( eol )
261
    {
262
        print_line++;
263
 
264
        /*
265
        **  Detect the end of a non-HTML underline
266
        */
267
        print_underline ( FALSE );
268
        if ( print_underline_start < print_underline_end )
269
        {
270
            int length;
271
 
272
            fwrite( "\n", 1, 1, pfile );
273
 
274
            length = print_underline_start;
275
            while( length-- )
276
                fwrite( " ", 1, 1, pfile );
277
 
278
            length = print_underline_end - print_underline_start;
279
            while ( length-- )
280
                fwrite( "=", 1, 1, pfile );
281
        }
282
 
283
        print_underline_start = -1;
284
        print_underline_end = -1;
285
        print_col = 0;
286
 
287
        /*
288
        **  Track the background colour
289
        */
290
        if ( print_html )
291
        {
292
            print_colour( 0 );
293
        }
294
 
295
        /*
296
        **  Now print the final newline
297
        */
298
        fwrite( "\n", 1, 1, pfile );
299
        len ++;
300
    }
301
 
302
    return ( len );
303
}
304
 
305
/*========================================================================
306
 *
307
 *  Print to to the printer
308
 *
309
 *  Purpose:
310
 *      This function is called to do print data on the printer
311
 *
312
 *  Assume:
313
 *      One CSV field per print
314
 *      New lines are at the end of a line printed. This does allow for
315
 *      a single new-line.
316
 *
317
 *
318
 *  Parameters:
319
 *      Standard printf type parameters
320
 *
321
 *  Returns:
322
 *      TRUE : Operation was succesful
323
 *
324
 *========================================================================*/
325
 
326
int csv_print( const char *format, ... )
327
{
328
    va_list     ap;
329
    char        pp[200];
330
    int         len;
331
    bool        eol = FALSE;
332
 
333
 
334
    va_start( ap, format );
335
    len = vsprintf( pp, format, ap );
336
    va_end( ap );
337
 
338
    /*
339
    **  Detect the end of a line and flag for later processing
340
    */
341
    if ( len > 0 && pp[len - 1] == '\n' )
342
    {
343
        len--;
344
        eol = TRUE;
345
    }
346
 
347
    if ( ! eol )
348
    {
349
        if ( print_col )
350
            fwrite( ",", 1, 1, pfile );
351
        fwrite( "\"", 1, 1, pfile );
352
        fwrite( pp, 1, len, pfile );
353
        print_col += len;
354
        fwrite( "\"", 1, 1, pfile );
355
    }
356
 
357
    /*
358
    **  Perform End of Line operation before printing the final newline
359
    */
360
    if ( eol )
361
    {
362
        print_line++;
363
        print_col = 0;
364
 
365
        /*
366
        **  Now print the final newline
367
        */
368
        fwrite( "\n", 1, 1, pfile );
369
        len ++;
370
    }
371
 
372
    return ( len );
373
}
374
 
375
 
376
/*========================================================================
377
 *
378
 *  Print to to the printer without any frills
379
 *
380
 *  Purpose:
381
 *      This function is called to do print data on the printer
382
 *
383
 *  Parameters:
384
 *      Standard printf type parameters
385
 *
386
 *  Returns:
387
 *      TRUE : Operation was succesful
388
 *
389
 *========================================================================*/
390
 
391
int raw_print( const char *format, ... )
392
{
393
    va_list     ap;
394
    char        pp[200];
395
    int         len;
396
 
397
 
398
    va_start( ap, format );
399
    len = vsprintf( pp, format, ap );
400
    va_end( ap );
401
 
402
    fwrite( pp, 1, len, pfile );
403
 
404
    return ( len );
405
}
406
 
407
 
408
/*========================================================================
409
 *
410
 *  Control bolding
411
 *
412
 *  Purpose:
413
 *      This function is called to turn bolding on and off
414
 *      This function will ONLY affect HTML printing
415
 *
416
 *  Parameters:
417
 *      on              - TRUE
418
 *
419
 *  Returns:
420
 *      Nothing
421
 *
422
 *========================================================================*/
423
 
424
void print_bold( bool on )
425
{
426
    if ( print_html )
427
    {
428
        if ( on )
429
            raw_print( "<B>" );
430
        else
431
            raw_print( "</B>" );
432
    }
433
}
434
 
435
/*========================================================================
436
 *
437
 *  Control underline
438
 *
439
 *  Purpose:
440
 *      This function is called to turn underline on and off
441
 *      This function will ONLY affect HTML printing and Non-HTML printing
442
 *      But in a different manner
443
 *
444
 *  Parameters:
445
 *      on              - TRUE
446
 *
447
 *  Returns:
448
 *      Nothing
449
 *
450
 *========================================================================*/
451
 
452
void print_underline( bool on )
453
{
454
    if ( print_html )
455
    {
456
        /*
457
        **  For HTML printing underline is simple
458
        */
459
        if ( on )
460
        {
461
            raw_print( "<U>" );
462
            print_underline_start = 1;
463
        }
464
        else if ( print_underline_start > 0 )
465
        {
466
            raw_print( "</U>" );
467
            print_underline_start = 0;
468
        }
469
    }
470
    else
471
    {
472
        /*
473
        **  Non-HTML printing
474
        **  Store underline start and stop column
475
        */
476
        if ( on )
477
            print_underline_start = print_col;
478
        else if ( print_underline_start >= 0 )
479
            print_underline_end = print_col;
480
    }
481
}
482
 
483
/*========================================================================
484
 *
485
 *  Control colour - HTML printing only
486
 *
487
 *  Purpose:
488
 *      This function is called to change the background colour within
489
 *      HTML text
490
 *
491
 *  Parameters:
492
 *      colour      - Colour control string
493
 *                    or NULL to trun colour OFF
494
 *
495
 *
496
 *  Returns:
497
 *      Nothing
498
 *
499
 *========================================================================*/
500
 
501
void print_colour( long colour )
502
{
503
    if ( print_html )
504
    {
505
        if ( print_current_colour )
506
        {
507
            raw_print( "</SPAN>" );
508
            print_current_colour = 0L;
509
        }
510
 
511
        if ( colour )
512
        {
513
            print_current_colour = colour;
514
            raw_print( "<SPAN STYLE=\"background: #%6.6lx\">", colour );
515
        }
516
    }
517
}
518
 
519
 
520
/*========================================================================
521
 *
522
 *  Print a page banner
523
 *
524
 *  Purpose:
525
 *      This function is called to print a page banner
526
 *
527
 *  Parameters:
528
 *      None
529
 *
530
 *  Returns:
531
 *      Nothing
532
 *
533
 *========================================================================*/
534
 
535
void printbanner( const char *title )
536
{
537
    int         l, s;
538
 
539
    if ( !title )
540
        return;
541
 
542
    l = strlen( config.event_name );
543
    s = ( print_width - l ) / 2;
544
    print( "%*s", s, "" );
545
 
546
    if ( print_html == html )
547
        print( "<A HREF=\"%s\">", p_filename(filebase, "index" ,"html"));
548
    print_underline( TRUE);
549
    print_bold( TRUE );
550
 
551
    print( "%s", config.event_name );
552
 
553
    print_bold( FALSE );
554
    print_underline( FALSE );
555
    if ( print_html == html )
556
        print( "</A>" );
557
 
558
    print( "\n" );
559
 
560
    /*
561
    **  Print out one line with the report title
562
    **  on the left and the report time on the right
563
    */
564
    if ( title )
565
        print( "%s", title );
566
 
567
    s = print_width - print_col - 24 - 4;
568
    print( "%*s", s , "" );
569
 
570
    print( "%.24s", ctime( &pri_time ) );
571
    print( "\n" );
572
    print( "\n" );
573
}
574
 
575
 
576
/*========================================================================
577
 *
578
 *  Format a filename
579
 *
580
 *  Purpose:
581
 *      This function is called create a suitably formatted filename
582
 *      for use in an HTML tag or by the file system
583
 *
584
 *      Currently all output filenames are created in uppercase
585
 *      This is a limitation of DOS
586
 *      This function is used to ensure that all files are created with
587
 *      an uppercase name and that all HTML file references are also
588
 *      in uppercase.
589
 *
590
 *
591
 *  Parameters:
592
 *      filename        - Base filename
593
 *      Suffix          - Optional part of the basename
594
 *                        If present is used to create part of the basename
595
 *      ext             - Extension
596
 *
597
 *  Returns:
598
 *      Address of a static string that will reference the file
599
 *
600
 *========================================================================*/
601
 
602
char * p_filename( const char *filename, const char *suffix, const char *ext )
603
{
604
    char    *name;
605
    char    *cptr;
606
 
607
#ifndef LONG_FILE_NAMES
608
    /*
609
    **  Limit the filename to 8.3 format
610
    **  This is a limitation of the underlying file access library
611
    **  and may be removed in the future
612
    */
613
    if ( suffix[0] )
614
        name = tprintf ( "%.4s_%.3s.%.3s", filename, suffix, ext );
615
    else
616
        name = tprintf ( "%.8s.%.3s", filename, ext );
617
 
618
 
619
    /*
620
    **  Uppercase the filename
621
    */
622
    cptr = name;
623
    while ( *cptr )
624
    {
625
        *cptr = toupper( *cptr );
626
        cptr++;
627
    }
628
#else
629
    /*
630
    **  This compiler and runtime library supports
631
    **  long filenames - created printed filenames in lower case
632
    */
633
    if ( suffix[0] )
634
        name = tprintf ( "%s_%s.%s", filename, suffix, ext );
635
    else
636
        name = tprintf ( "%s_%s.%s", filename, ext, "txt" );
637
 
638
    cptr = name;
639
    while ( *cptr )
640
    {
641
        *cptr = tolower( *cptr );
642
        cptr++;
643
    }
644
#endif
645
 
646
    return( name );
647
}
648
 
649
 
650
/*========================================================================
651
 *
652
 *  Print to a temp string buffer
653
 *
654
 *  Purpose:
655
 *      This function is similar to sprintf() except that the routine
656
 *      maintains a list of string buffers and will return one to the
657
 *      user.
658
 *
659
 *      This function allows a user to create small, short lived
660
 *      printed strings, without the memory managment overhead.
661
 *
662
 *      Down-side. Use the string quickly.
663
 *                 Strings have a limited length
664
 *
665
 *  Parameters:
666
 *      Standard printf type parameters
667
 *
668
 *  Returns:
669
 *      TRUE : Operation was succesful
670
 *
671
 *========================================================================*/
672
 
673
#define TBUF_COUNT  5               /* Number of buffers */
674
#define TBUF_LENGTH 100             /* Max length of a single print */
675
 
676
char *tprintf( const char *format, ... )
677
{
678
    static char tbuf[TBUF_COUNT][TBUF_LENGTH];
679
    static int  index = 0;
680
 
681
    va_list     ap;
682
    char       *pp;
683
 
684
    /*
685
    **  Get the next entry from the small store
686
    */
687
    index++;
688
    if( index >= TBUF_COUNT )
689
        index = 0;
690
    pp = tbuf[index];
691
 
692
    va_start( ap, format );
693
    vsprintf( pp, format, ap );
694
    va_end( ap );
695
 
696
    return ( pp );
697
}
698
 
699
/*----------------------------------------------------------------------------
700
** FUNCTION           : to_hex
701
**
702
** DESCRIPTION        : Converts an integer value to its hex character
703
**
704
**
705
** INPUTS             : code        - Code to convert
706
**
707
** RETURNS            : Character representation
708
**
709
----------------------------------------------------------------------------*/
710
 
711
char to_hex(char code)
712
{
713
  static char hex[] = "0123456789abcdef";
714
  return hex[code & 0x0f];
715
}
716
 
717
/*----------------------------------------------------------------------------
718
** FUNCTION           : url_encode
719
**
720
** DESCRIPTION        : URL encoded version of a string
721
**
722
**
723
** INPUTS             : string to encode
724
**
725
** RETURNS            : Encoded string
726
**
727
** WARNING            : Uses a small circular pool of strings so that the
728
**                      user doesn't need to worry about string release
729
**
730
----------------------------------------------------------------------------*/
731
char *url_encode(const char *str)
732
{
733
    static char tbuf[TBUF_COUNT][TBUF_LENGTH * 3];
734
    static int  index = 0;
735
    char       *pp;
736
 
737
    /*
738
    **  Get the next entry from the small store
739
    */
740
    index++;
741
    if( index >= TBUF_COUNT )
742
        index = 0;
743
    pp = tbuf[index];
744
 
745
    const char *pstr = str;
746
    char *pbuf = pp;
747
 
748
    while (*pstr)
749
    {
750
        if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
751
            *pbuf++ = *pstr;
752
        else if (*pstr == ' ')
753
            *pbuf++ = '+';
754
        else
755
        {
756
            *pbuf++ = '%';
757
            *pbuf++ = to_hex(*pstr >> 4);
758
            *pbuf++ = to_hex(*pstr & 15);
759
        }
760
        pstr++;
761
    }
762
    *pbuf = '\0';
763
  return pp;
764
}
765
 
766
/********************************* EOF ***********************************/