Subversion Repositories svn1-original

Rev

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