Subversion Repositories svn1-original

Rev

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