Subversion Repositories svn1-original

Rev

Rev 199 | Details | Compare with Previous | Last modification | View Log | RSS feed

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