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