Subversion Repositories svn1-original

Rev

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