/************************************************************************* * Copyright (C) 1995 Embedded Solutions * All rights reserved * * file: src\print.c * * purpose: Module to interface to the printer channel (file) * * functions * open_printer - Open the printer * close_printer - Close the printer * print - Print to to the printer * printbanner - Print a page banner * * programmer: David Purdie * * revision date by reason * 00.0 27/01/95 DDP Tidies up the program and formatted the file * **************************************************************************/ #include #include #include #include #include #include #include "mainwindow.h" #include "consts.h" #include "structs.h" #include "proto.h" FILE *pfile; /* Fd of the printer channel */ time_t pri_time; /* Time printer is opened - for banners */ int print_width; /* Width of the printout */ report_type print_html = text; /* Printing with HTML */ size_t print_col = 0; /* Current print column */ int print_line = 0; /* Current print line */ size_t print_underline_start; /* Start of underline */ size_t print_underline_end; /* End of underline */ long print_current_colour; /* Current printing colour */ QString printFileName; /* Last printer file opened */ char print_href[200]; /* Current HREF string */ /*======================================================================== * * Open the printer * * Purpose: * This function is called to open the printer and prepare to print * * Parameters: * name Name of print file * ext Ext of the print file * width Width of the printed file * html Printing in HTML mode * * Returns: * TRUE if the printer can be attached * * * Note: Use an "htm" file extension as DOS cannot handle 4 letter extensions *========================================================================*/ bool open_printer( const QString name, const char *ext, int width, report_type html, const char *title ) { QString pname; /* ** Determine the name of the file ** May need to modify the extension if it is an HTML file */ if ( html ) { if ( html == printed ) pname = p_filename( !name.isEmpty() ? name : FileBase, ext ,"prn.html" ); else pname = p_filename( !name.isEmpty() ? name : FileBase, ext ,"html" ); } else { pname = p_filename( !name.isEmpty() ? name : FileBase, ext ,"txt" ); } /* ** Now use basic function */ return open_printer_name (pname, width, html, title ); } /*---------------------------------------------------------------------------- * FUNCTION : open_printer_name * * DESCRIPTION : Open a printer with a known name * * This function is called to open the printer and prepare to print * * Parameters: * pname Name of print file * width Width of the printed file * html Printing in HTML mode * * Returns: * TRUE if the printer can be attached * * * Note: Use an "htm" file extension as DOS cannot handle 4 letter extensions ----------------------------------------------------------------------------*/ bool open_printer_name( const QString pname, int width, report_type htmltype, const char *title ) { printFileName = FilePath; switch (htmltype) { case printed: printFileName.append("webtxt/"); break; case html: printFileName.append("web/"); break; default: printFileName.append("text/"); break; } /* ** Ensure that the directory exists */ { QDir dir(FilePath); dir.mkpath(printFileName); } /* ** Append the filename to the directory */ printFileName.append(pname); print_width = width ? width : 80; print_col = 0; print_line = 0; print_underline_start = -1; print_underline_end = -1; print_current_colour = 0; /* ** Open the printer ** Ensure that it is opened in text mode */ //qDebug() << "Opening File: " << qPrintable(printFileName); if( ( pfile = fopen( qPrintable(printFileName), "wt" ) ) != NULL ) { time( &pri_time ); /* Latch the time */ /* ** Print out the HTML file header */ if ( htmltype ) { print( "\n" ); print( "\n" ); print( "%s - %s\n", config.event_name, title ); // print( "\n"); print( "\n" ); print( "\n" ); print ("
"); print( "
" );
            print_html = html;
        }

        /*
        **  Print out a common banner
        */
        printbanner(title);
    }
    else
    {
        MainWindow::showMessage("Printer not available");
    }
    return ( pfile != 0 );
}

const QString &getPrinterFile(void)
{
    return printFileName;
}

/*========================================================================
 *
 *  Close the printer
 *
 *  Purpose:
 *      This function is called to close and release the printer
 *      All reports are terminated with a formfeed
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      TRUE if the printer channel can be released
 *
 *========================================================================*/

bool close_printer(void)
{
    if ( print_html )
    {
        print_html = text;
        print( "
\n" ); print( "\n" ); print( "\n" ); print( "\n" ); } else { print( "\014" ); } fclose( pfile ); return ( TRUE ); } /*======================================================================== * * Print to to the printer * * Purpose: * This function is called to do print data on the printer * Track current character index so as to assist in tracking the * use of underline. * * Assume: * New lines are at the end of a line printed. This does allow for * a single new-line. * * * Parameters: * Standard printf type parameters * * Returns: * TRUE : Operation was succesful * *========================================================================*/ size_t print( const char *format, ... ) { va_list ap; char pp[200]; size_t len; bool eol = FALSE; /* ** If this is the start of a new line then we may need to colour it */ if ( print_col == 0 && print_html && (print_line & 1) ) { print_colour( HTML_COLOUR_GREEN ); } /* ** If this is the start of a new line then we may need to perform ** a perf-skip */ if ( print_col == 0 && print_line && ! print_html && config.lines_per_page && config.perf_skip ) { if ( 0 == ((print_line + 2) % (config.lines_per_page - config.perf_skip)) ) { int count = config.perf_skip; while ( count-- ) fwrite( "\n", 1, 1, pfile ); } } va_start( ap, format ); len = vsprintf( pp, format, ap ); va_end( ap ); /* ** Detect the end of a line and flag for later processing */ if ( len > 0 && pp[len - 1] == '\n' ) { len--; eol = TRUE; } // Insert pre-set HTML HREF into the string if (print_html && *print_href) { int iStart = 0; size_t iEnd = len; //char *debugPtr = pp; for (int ii = 0; ii < len; ii++) { if (pp[ii] != ' ') { iStart = ii; break; } } for (size_t ii = len-1; ii >= iStart; ii--) { if (pp[ii] != ' ') { iEnd = ii + 1; break; } } //debugPtr = print_href; strncat(print_href, &pp[iStart], iEnd - iStart); strcat(print_href, ""); strncat(print_href, &pp[iEnd], len - iEnd ); strcpy(&pp[iStart], print_href); len = strlen(pp); } *print_href = 0; if ( len ) { fwrite( pp, 1, len, pfile ); print_col += len; } /* ** Perform End of Line operation before printing the final newline */ if ( eol ) { print_line++; /* ** Detect the end of a non-HTML underline */ print_underline ( FALSE ); if ( print_underline_start < print_underline_end ) { size_t length; fwrite( "\n", 1, 1, pfile ); length = print_underline_start; while( length-- ) fwrite( " ", 1, 1, pfile ); length = print_underline_end - print_underline_start; while ( length-- ) fwrite( "=", 1, 1, pfile ); } print_underline_start = -1; print_underline_end = -1; print_col = 0; /* ** Track the background colour */ if ( print_html ) { print_colour( 0 ); } /* ** Now print the final newline */ fwrite( "\n", 1, 1, pfile ); len ++; } return ( len ); } /*======================================================================== * * Print to to the printer * * Purpose: * This function is called to do print data on the printer * * Assume: * One CSV field per print * New lines are at the end of a line printed. This does allow for * a single new-line. * * * Parameters: * Standard printf type parameters * * Returns: * TRUE : Operation was succesful * *========================================================================*/ int csv_print( const char *format, ... ) { va_list ap; char pp[200]; int len; bool eol = FALSE; va_start( ap, format ); len = vsprintf( pp, format, ap ); va_end( ap ); /* ** Detect the end of a line and flag for later processing */ if ( len > 0 && pp[len - 1] == '\n' ) { len--; eol = TRUE; } if ( ! eol ) { if ( print_col ) fwrite( ",", 1, 1, pfile ); fwrite( "\"", 1, 1, pfile ); fwrite( pp, 1, len, pfile ); print_col += len; fwrite( "\"", 1, 1, pfile ); } /* ** Perform End of Line operation before printing the final newline */ if ( eol ) { print_line++; print_col = 0; /* ** Now print the final newline */ fwrite( "\n", 1, 1, pfile ); len ++; } return ( len ); } /*======================================================================== * * Print to to the printer without any frills * * Purpose: * This function is called to do print data on the printer * * Parameters: * Standard printf type parameters * * Returns: * TRUE : Operation was succesful * *========================================================================*/ int raw_print( const char *format, ... ) { va_list ap; char pp[200]; int len; va_start( ap, format ); len = vsprintf( pp, format, ap ); va_end( ap ); fwrite( pp, 1, len, pfile ); return ( len ); } /*======================================================================== * * Control bolding * * Purpose: * This function is called to turn bolding on and off * This function will ONLY affect HTML printing * * Parameters: * on - TRUE * * Returns: * Nothing * *========================================================================*/ void print_bold( bool on ) { if ( print_html ) { if ( on ) raw_print( "" ); else raw_print( "" ); } } /*======================================================================== * * Control underline * * Purpose: * This function is called to turn underline on and off * This function will ONLY affect HTML printing and Non-HTML printing * But in a different manner * * Parameters: * on - TRUE * * Returns: * Nothing * *========================================================================*/ void print_underline( bool on ) { if ( print_html ) { /* ** For HTML printing underline is simple */ if ( on ) { raw_print( "" ); print_underline_start = 1; } else if ( print_underline_start > 0 ) { raw_print( "" ); print_underline_start = 0; } } else { /* ** Non-HTML printing ** Store underline start and stop column */ if ( on ) print_underline_start = print_col; else if ( print_underline_start >= 0 ) print_underline_end = print_col; } } /*======================================================================== * * Control colour - HTML printing only * * Purpose: * This function is called to change the background colour within * HTML text * * Parameters: * colour - Colour control string * or NULL to trun colour OFF * * * Returns: * Nothing * *========================================================================*/ void print_colour( long colour ) { if ( print_html ) { if ( print_current_colour ) { raw_print( "" ); print_current_colour = 0L; } if ( colour ) { print_current_colour = colour; raw_print( "", colour ); } } } /*======================================================================== * * Print a page banner * * Purpose: * This function is called to print a page banner * * Parameters: * None * * Returns: * Nothing * *========================================================================*/ void printbanner( const char *title ) { size_t l, s; if ( !title ) return; l = strlen( config.event_name ); s = ( print_width - l ) / 2; print( "%*s", s, "" ); if ( print_html == html ) print( "", p_filename(FileBase, "index" ,"html").toStdString().c_str()); print_underline( TRUE); print_bold( TRUE ); print( "%s", config.event_name ); print_bold( FALSE ); print_underline( FALSE ); if ( print_html == html ) print( "" ); print( "\n" ); /* ** Print out one line with the report title ** on the left and the report time on the right */ if ( title ) print( "%s", title ); s = print_width - print_col - 24 - 4; print( "%*s", s , "" ); /* ** Debug support - dummy the print time */ QString dbgDate = QProcessEnvironment::systemEnvironment().value("MARA_REPORT_DATE", "") ; if (dbgDate.length() > 1) { print( "%.24s", qPrintable(dbgDate) ); } else { print( "%.24s", ctime( &pri_time ) ); } print( "\n" ); print( "\n" ); } /*======================================================================== * * Format a filename * * Purpose: * This function is called create a suitably formatted filename * for use in an HTML tag or by the file system * * * Parameters: * filename - Base filename * suffix - Optional part of the basename * If present is used to create part of the basename * ext - Extension * * Returns: * A QString that will reference the file * *========================================================================*/ QString p_filename( const QString filename, const QString suffix, const QString ext ) { QString name; if (!suffix.isEmpty()) { name = filename + "_" + suffix; } else { name = filename; } name = name.append(".").append(ext); //qDebug() << "p_filename" << filename << ":" << suffix << ":" << ext << " -> " << name; return name; } /*======================================================================== * * Print to a temp string buffer * * Purpose: * This function is similar to sprintf() except that the routine * maintains a list of string buffers and will return one to the * user. * * This function allows a user to create small, short lived * printed strings, without the memory managment overhead. * * Down-side. Use the string quickly. * Strings have a limited length * * Parameters: * Standard printf type parameters * * Returns: * TRUE : Operation was succesful * *========================================================================*/ #define TBUF_COUNT 5 /* Number of buffers */ #define TBUF_LENGTH 100 /* Max length of a single print */ char *tprintf( const char *format, ... ) { static char tbuf[TBUF_COUNT][TBUF_LENGTH]; static int index = 0; va_list ap; char *pp; /* ** Get the next entry from the small store */ index++; if( index >= TBUF_COUNT ) index = 0; pp = tbuf[index]; va_start( ap, format ); vsprintf( pp, format, ap ); va_end( ap ); return ( pp ); } /*======================================================================== * * Set HTML HREF to be used in the next print * * Purpose: * Create and save a printf like string so that it will be used * to create an HTML HREF * * Down-side. Can only have one at a time * Only valid for the next print * Strings have a limited length * * Parameters: * Standard printf type parameters * * Returns: * TRUE : Operation was succesful * *========================================================================*/ char *setHref( const char *format, ... ) { va_list ap; *print_href = 0; va_start( ap, format ); vsprintf( print_href, format, ap ); va_end( ap ); return ( print_href ); } /*---------------------------------------------------------------------------- ** FUNCTION : url_encode ** ** DESCRIPTION : URL encoded version of a string ** ** ** INPUTS : string to encode ** ** RETURNS : Encoded string ** ** WARNING : Uses a small circular pool of strings so that the ** user doesn't need to worry about string release ** ----------------------------------------------------------------------------*/ char * url_encode(const QString str) { static char tbuf[TBUF_COUNT][TBUF_LENGTH * 3]; static int index = 0; char *pp; /* ** Get the next entry from the small store */ index++; if( index >= TBUF_COUNT ) index = 0; pp = tbuf[index]; char *pbuf = pp; QUrl url = QUrl(str); QString encodedUrl = url.toString(QUrl::FullyEncoded); std::string sstr= encodedUrl.toStdString(); const char * data = sstr.c_str(); // TODO - no limit check on the converted data while (*data) { *pbuf++ = *data++; } *pbuf = '\0'; //qDebug() << "url_encode:" << str << ":" << pp; return pp; } /********************************* EOF ***********************************/