Subversion Repositories svn1

Rev

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