campo-sirio/cb5/r4report.c

1383 lines
34 KiB
C
Raw Normal View History

/* r4report.c (c)Copyright Sequiter Software Inc., 1991-1994. All rights reserved. */
#include "d4all.h"
#ifdef S4WINDOWS
#include <commdlg.h>
#endif
#define ABS(x) ((x<0)?-1*(x):x)
void S4FUNCTION expr4calc_reset( CODE4 S4PTR * ) ;
/* Function: report4index_type()
PARAMETERS: none
DESCRIPTION: used by the CR executable to determine the index
RETURNS: an integer value, defined in r4report.h, specifying the index */
int S4FUNCTION report4index_type()
{
#ifdef S4MDX
return r4mdx;
#endif
#ifdef S4NDX
return r4ndx;
#endif
#ifdef S4CLIPPER
return r4cli;
#endif
#ifdef S4FOX
return r4fox;
#endif
}
/* FOR A DESCRIPTION SEE THE CODEREPORTER MANUAL */
PREPORT4 S4FUNCTION report4init( RELATE4 *relate )
{
REPORT4 *r4 ;
CODE4 *code_base;
#ifdef S4WINDOWS
LOGFONT lfont;
#endif
if( !relate )
{
return NULL;
}
code_base = relate->code_base;
/* you can only have one report open at a time */
if( code_base->num_reports != 0 )
{
e4describe( code_base, e4report, E4_REP_ONE, 0, 0 );
return NULL;
}
/* allocate the REPORT4 structure */
r4 = (REPORT4 *) u4alloc_free( code_base, sizeof(REPORT4) ) ;
if ( r4 == 0 )
{
e4describe( code_base, e4report, E4_REP_REPALLOC, 0, 0 );
return NULL ;
}
/* reset the list members */
memset( &r4->groups, 0, sizeof(r4->groups) );
memset( &r4->styles, 0, sizeof(r4->styles) );
memset( &r4->active_objects, 0, sizeof(r4->active_objects) );
memset( &r4->obj_type_info, 0, sizeof(r4->obj_type_info) );
/* set the code_base, relate, and default_date_format members */
r4->code_base = code_base ;
r4->relate = relate ;
#ifdef S4WINDOWS
lstrcpy( r4->default_date_format, code_base->date_format );
#else
strcpy( r4->default_date_format, code_base->date_format );
#endif
/* turn off auto_open of index files */
r4->code_base->auto_open = 0;
/* set the default margin and page size */
r4->margin_left = 250;
r4->margin_right = 250;
r4->report_width = 8000 ;
r4->report_height = 11000;
/* set the default symbols */
r4->decimal_point = '.' ;
r4->thousand_separator = ',' ;
r4->currency_symbol[0] = '$';
r4->currency_symbol[1] = '\0';
/* by default output is to the screen */
r4->output_code = r4->output_handle = 1;
/* default units of display are points: applys to the CR executable */
r4->units = UNIT4POINTS ;
/* no grid by default: applys to the CR executable */
r4->sensitivity_x = r4->sensitivity_y = 0;
/* by default save report with pathnames */
r4->pathnames = 1;
/* create the default style */
#ifdef S4WINDOWS
/* if not being called by the CR executable */
if( !code_base->s4cr2 )
{
memset( &lfont, 0, sizeof(R4LOGFONT) );
strcpy(lfont.lfFaceName,"MS Serif" );
#ifdef S4GERMAN
style4create( (PREPORT4)r4, (PR4LOGFONT)&lfont, (char *)"Normal", (R4COLORREF)NULL, (int)10 );
#else
style4create( (PREPORT4)r4, (PR4LOGFONT)&lfont, (char *)"Plain Text", (R4COLORREF)NULL, (int)10 );
#endif
r4->active_style = (PSTYLE4)l4first( &r4->styles );
}
#else
#ifdef S4GERMAN
style4create( r4, "Normal", 0, NULL, 0, NULL );
#else
style4create( r4, "Plain Text", 0, NULL, 0, NULL );
#endif
r4->active_style = (PSTYLE4)l4first( &r4->styles );
#endif
/* create the title/summary and page header/footer groups */
group4create_title_summary( r4 );
group4create_pgheader_pgfooter( r4 );
if( r4 )
r4->code_base->num_reports = 1;
else
r4->code_base->num_reports = 0;
return r4 ;
}
#ifdef S4WINDOWS
/* frees the windows font associated with the object by releasing the
font from the objects windows device context. This function is
only used through the report4free_styles fctn */
void report4set_obj_font_free( OBJ4 *obj )
{
OBJ4 *obj_on;
HDC hDC;
obj_on = (OBJ4 *)l4first( &obj->contained );
while( obj_on )
{
report4set_obj_font_free( obj_on );
obj_on = (OBJ4 *)l4next( &obj->contained, obj_on );
}
hDC = GetDC( obj->hWnd );
SelectObject( hDC, GetStockObject(SYSTEM_FONT) );
ReleaseDC( obj->hWnd, hDC );
}
#endif
void report4free_styles( REPORT4 *report )
{
#ifdef S4WINDOWS
GROUP4 *group_on;
AREA4 *area_on;
OBJ4 *obj_on;
#endif
STYLE4 *style_on, *style_next;
/* if this is a report in windows de-select the font from the device context
of every object */
#ifdef S4WINDOWS
if( report->page_header_footer )
{
area_on = (AREA4 *)l4first( &report->page_header_footer->header_areas );
while( area_on )
{
obj_on = (OBJ4 *)l4first( &area_on->objects );
while( obj_on )
{
report4set_obj_font_free( obj_on );
obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on );
}
area_on = (AREA4 *)l4next( &report->page_header_footer->header_areas, area_on );
}
area_on = (AREA4 *)l4first( &report->page_header_footer->footer_areas );
while( area_on )
{
obj_on = (OBJ4 *)l4first( &area_on->objects );
while( obj_on )
{
report4set_obj_font_free( obj_on );
obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on );
}
area_on = (AREA4 *)l4next( &report->page_header_footer->footer_areas, area_on );
}
}
group_on = (GROUP4 *)l4first( &report->groups );
while( group_on )
{
area_on = (AREA4 *)l4first( &group_on->header_areas );
while( area_on )
{
obj_on = (OBJ4 *)l4first( &area_on->objects );
while( obj_on )
{
report4set_obj_font_free( obj_on );
obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on );
}
area_on = (AREA4 *)l4next( &group_on->header_areas, area_on );
}
area_on = (AREA4 *)l4first( &group_on->footer_areas );
while( area_on )
{
obj_on = (OBJ4 *)l4first( &area_on->objects );
while( obj_on )
{
report4set_obj_font_free( obj_on );
obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on );
}
area_on = (AREA4 *)l4next( &group_on->footer_areas, area_on );
}
group_on = (GROUP4 *)l4next( &report->groups, group_on );
}
#endif
/* free the STYLE4 structures in the style list */
style_on = (STYLE4 *)l4first( &report->styles );
while( style_on )
{
style_next = (STYLE4 *)l4next( &report->styles, style_on );
style4free( report, style_on );
style_on = style_next;
}
}
/* SEE the CODEREPORTER MANUAL FOR A DESCRIPTION */
void S4FUNCTION report4free( REPORT4 *r4, int free_relate, int close_files )
{
GROUP4 *group_on, *group_next;
RELATE4 *relate;
POUT4OBJ o4obj;
if ( r4 == 0 ) return ;
if( r4->code_base->num_reports != 1 )
{
e4describe( r4->code_base, e4report, E4_REP_NONE, 0, 0 ) ;
}
r4->code_base->num_reports = 0 ;
/* free the report name and file_name */
if( r4->report_name )
u4free( r4->report_name );
if( r4->report_file_name )
u4free( r4->report_file_name );
/* free the reports styles */
report4free_styles( r4 );
/* free the page header/footer group */
if( r4->page_header_footer )
{
group4free( r4->page_header_footer );
r4->page_header_footer = NULL;
}
/* free all the other groups */
group_on = (GROUP4 *)l4first( &r4->groups );
while( group_on )
{
group_next = (GROUP4 *)l4next( &r4->groups, group_on );
group4free( group_on );
group_on = group_next;
}
/* free the additional record buffers in the DATA4 structures in the relation
*/
relate = r4->relate;
while( relate )
{
if( relate->old_record )
{
u4free( relate->old_record );
relate->old_record = NULL;
}
relate4next( &relate );
}
/* if the free relate flag was set, free the relate */
if (free_relate)
relate4free(r4->relate, close_files);
/* free the printer name */
if( r4->printer_name )
u4free( r4->printer_name );
/* free all calculations/totals in the calc list */
expr4calc_reset( r4->code_base ) ;
/* free up the memory pools for totals and calcs */
mem4release( r4->code_base->total_memory ) ;
r4->code_base->total_memory = 0 ;
mem4release( r4->code_base->calc_memory ) ;
r4->code_base->calc_memory = 0 ;
/* free the report caption */
if( r4->report_caption )
{
u4free( r4->report_caption );
}
/* free the output data file name */
if( r4->dfile_name )
u4free( r4->dfile_name );
/* free any data file output OUT4OBJ structs */
while( (o4obj = (POUT4OBJ)l4pop(&r4->output_objs)) != NULL )
u4free( o4obj );
u4free( r4 ) ;
}
#ifdef S4WINDOWS
/* Get an information context for either the specified or default printer */
HDC S4FUNCTION report4get_printerIC ( REPORT4 *report )
{
char szPrinter [64] ;
char *szDevice, *szDriver, *szOutput ;
if ( report->printer_name == 0 )
{
GetProfileString( "windows", "device", ",,,", szPrinter, 80 ) ;
if ( ! (szDevice = strtok( szPrinter, ",")) ) return 0 ;
if ( ! (szDriver = strtok( NULL, ", ")) ) return 0 ;
if ( ! (szOutput = strtok( NULL, ", ")) ) return 0 ;
}
else
{
GetProfileString( "devices", report->printer_name, "=,", szPrinter, 80) ;
szDevice = report->printer_name ;
if ( ! (szDriver = strtok( szPrinter, ", ")) ) return 0 ;
if ( ! (szOutput = strtok( NULL, ", ")) ) return 0 ;
}
return CreateIC (szDriver, szDevice, szOutput, NULL) ;
}
/* Get the device context for the default printer */
HDC S4FUNCTION report4get_printerDC ( void )
{
static char szPrinter [80] ;
char *szDevice, *szDriver, *szOutput ;
GetProfileString( "windows", "device", ",,,", szPrinter, 80 ) ;
if ( ! (szDevice = strtok( szPrinter, ",")) ) return 0 ;
if ( ! (szDriver = strtok( NULL, ", ")) ) return 0 ;
if ( ! (szOutput = strtok( NULL, ", ")) ) return 0 ;
return CreateDC (szDriver, szDevice, szOutput, NULL) ;
}
/* Create the output fonts for printing */
void report4output_screen_fonts( REPORT4 *report )
{
STYLE4 *style_on;
#ifdef S4WIN32
LOGFONT *plf;
#else
PR4LOGFONT plf;
#endif
int tempval;
style_on = (STYLE4 *)l4first( &report->styles );
while( style_on )
{
if( !style_on->printer_font )
{
#ifdef S4WIN32
plf = &( style_on->ntFont ) ;
#else
plf = &( style_on->lfont ) ;
#endif
/* due to the different resolution of the printer and screen we have
to temporarily change the lfHeight member of the LOGFONT struct and
create a font for printing */
tempval = plf->lfHeight;
plf->lfHeight = -MulDiv(style_on->point_size,
GetDeviceCaps(report->printerDC,LOGPIXELSY),72);
style_on->printer_font = CreateFontIndirect((const LOGFONT FAR*)plf);
plf->lfHeight = tempval;
}
style_on = (STYLE4 *)l4next( &report->styles, style_on );
}
}
/* USED FOR CREATING A DIALOG TEMPLATE ON THE FLY, this is used to create
the dialog used during printing in windows to allow cancellation of the
printing process, the only reason this function is necessary is because
we do not use a resource file with the CodeBase DLL */
GLOBALHANDLE NewDlgTemplate(DWORD Style, WORD X, WORD Y, WORD CX, WORD CY,
LPSTR Menu, LPSTR Class, LPSTR Text,
LPSTR TypeFace, WORD PtSize)
{
DlgTemplateHeader far *lpDT;
LPSTR lpsztemp;
GLOBALHANDLE hDTemplate;
long needed_size;
needed_size = sizeof( DlgTemplateHeader ) + lstrlen(Menu) + 1 +
lstrlen(Class) + 1 + lstrlen(Text) + 1;
if( TypeFace[0] )
needed_size += lstrlen(TypeFace) + 1 + sizeof(short);
hDTemplate = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, needed_size );
if( hDTemplate == NULL )
return hDTemplate;
lpDT = (DlgTemplateHeader far * )GlobalLock( hDTemplate );
lpDT->dtStyle = WS_VISIBLE | Style;
lpDT->dtX = X;
lpDT->dtY = Y;
lpDT->dtCX = CX;
lpDT->dtCY = CY;
lpsztemp = ((LPSTR)lpDT) + sizeof( *lpDT );
lpsztemp = (char far *)memcpy( lpsztemp, Menu, ((lstrlen(Menu)>80)?81:lstrlen(Menu)+1) );
lpsztemp = (char far *)memcpy( lpsztemp, Class, ((lstrlen(Class)>80)?81:lstrlen(Class)+1) );
lpsztemp = (char far *)memcpy( lpsztemp, Text, ((lstrlen(Text)>80)?81:lstrlen(Text)+1) );
if( TypeFace[0] )
{
*((short far *)lpsztemp) = PtSize;
memcpy( lpsztemp+sizeof(short), TypeFace,((lstrlen(TypeFace)>80)?81:lstrlen(TypeFace)+1) );
lpDT->dtStyle |= DS_SETFONT;
}
GlobalUnlock( hDTemplate );
return hDTemplate;
}
/* USED FOR CREATING A DIALOG TEMPLATE ON THE FLY, this is used to create
the dialog used during printing in windows to allow cancellation of the
printing process, the only reason this function is necessary is because
we do not use a resource file with the CodeBase DLL */
BOOL AddDlgItem( GLOBALHANDLE DlgTmp, DWORD Style, WORD X, WORD Y, WORD CX,
WORD CY, LPSTR Class, LPSTR Text, BYTE DataLen, LPSTR Data,
int id )
{
DlgTemplateHeader far *lpDT;
DlgItemTemplateHeader far *lpDIT;
LPSTR lpsztemp;
GLOBALHANDLE hDTemplate;
unsigned new_size, BlockSize;
BlockSize = TemplateSize( DlgTmp );
new_size = BlockSize + sizeof(DlgItemTemplateHeader) +
lstrlen(Class) + 1 + lstrlen(Text) + 1 + 1;
hDTemplate = GlobalReAlloc( DlgTmp, new_size, GMEM_ZEROINIT | GMEM_MOVEABLE );
if( hDTemplate == NULL )
return FALSE;
lpDT = (DlgTemplateHeader far * )GlobalLock( hDTemplate );
lpDIT = (DlgItemTemplateHeader far *)(((LPSTR)lpDT)+BlockSize);
lpDIT->dtilX = X;
lpDIT->dtilY = Y;
lpDIT->dtilCX = (CX < lpDT->dtCX)?CX:lpDT->dtCX;
lpDIT->dtilCY = (CY < lpDT->dtCY)?CY:lpDT->dtCY;
lpDIT->dtilID = id;
lpDIT->dtilStyle = WS_VISIBLE | WS_CHILD | Style;
lpsztemp = (char far *)(lpDIT)+sizeof(*lpDIT);
lpsztemp = (char far *)memcpy( lpsztemp, Class, ((lstrlen(Class)>80)?81:lstrlen(Class)+1) );
lpsztemp = (char far *)memcpy( lpsztemp, Text, ((lstrlen(Text)>80)?81:lstrlen(Text)+1) );
if( DataLen )
memcpy( lpsztemp, Data, DataLen );
lpDT->dtItemCount++;
GlobalUnlock( hDTemplate );
return TRUE;
}
/* USED FOR CREATING A DIALOG TEMPLATE ON THE FLY, this is used to create
the dialog used during printing in windows to allow cancellation of the
printing process, the only reason this function is necessary is because
we do not use a resource file with the CodeBase DLL */
int TemplateSize( GLOBALHANDLE hDlgTmp )
{
DlgTemplateHeader far *lpDT;
LPSTR lpstr, lpbase;
int isize;
int i;
lpDT = (DlgTemplateHeader far *)GlobalLock( hDlgTmp );
lpbase = (LPSTR)lpDT;
lpstr = (LPSTR)( lpDT + 1 );
isize = sizeof( *lpDT );
lpstr = lpbase+(isize+=(lstrlen(lpstr)+1));
lpstr = lpbase+(isize+=(lstrlen(lpstr)+1));
lpstr = lpbase+(isize+=(lstrlen(lpstr)+1));
if((lpDT->dtStyle)&DS_SETFONT)
{
isize += sizeof(short);
lpstr += sizeof(short);
lpstr = lpbase+(isize+=(lstrlen(lpstr)+1));
}
for( i = 0; i < lpDT->dtItemCount; i++ )
{
lpstr = lpbase+(isize+=sizeof(DlgItemTemplateHeader));
lpstr = lpbase+(isize+=(lstrlen(lpstr)+1));
lpstr = lpbase+(isize+=(lstrlen(lpstr)+1));
if( *lpstr )
{
isize += *lpstr;
lpstr += *lpstr;
}
isize++;
}
GlobalUnlock( hDlgTmp );
return isize;
}
/**************************************************************************
* registers window classes for the output window and the page window
**************************************************************************/
int report4register_classes( PREPORT4 report )
{
WNDCLASS wc;
HINSTANCE reginst;
if( report->hWnd == NULL )
{
#ifdef S4RDB
MessageBox( NULL, "No parentwindow in report structure.", "Error", MB_OK );
#endif
return -1;
}
#ifdef S4WIN32
reginst = (HINSTANCE)GetWindowLong( report->hWnd, GWL_HINSTANCE );
#else
reginst = (HINSTANCE)GetWindowWord( report->hWnd, GWW_HINSTANCE );
#endif
wc.cbClsExtra = 0;
wc.hInstance = reginst;
wc.hCursor = LoadCursor(NULL,IDC_WAIT);
wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.style = CS_DBLCLKS | CS_GLOBALCLASS;
wc.lpfnWndProc = PreViewProc;
wc.cbWndExtra = 18;
wc.hIcon = NULL;
wc.lpszClassName = "PreViewWin";
#ifdef S4RDB
if( (RegisterClass( &wc )) == NULL )
{
MessageBox( NULL, "Failed to register PreViewWin class", "ERROR", MB_OK );
return -1;
}
#else
RegisterClass( &wc );
#endif
wc.hbrBackground = GetStockObject( WHITE_BRUSH );
wc.lpfnWndProc = OutputPageProc;
wc.lpszClassName = "OutputPageWin";
#ifdef S4RDB
if( (RegisterClass( &wc )) == NULL )
{
MessageBox( NULL, "Failed to register OutputPageWin class", "ERROR", MB_OK );
return -1;
}
#else
RegisterClass( &wc );
#endif
wc.lpszClassName = "MouseEat";
wc.lpfnWndProc = MouseEatProc;
#ifdef S4RDB
if( (RegisterClass( &wc )) == NULL )
{
MessageBox( NULL, "Failed to register MouseEat class", "ERROR", MB_OK );
return -1;
}
#else
RegisterClass( &wc );
#endif
return 0;
}
#endif
/****************************************************************************
* recursively calculates the position (x,y) and size (w,h) of an object and
* all the contained objects in device coordinates
****************************************************************************/
#ifdef S4WINDOWS
#ifdef __cplusplus
void report4obj_to_dev(OBJ4 *obj, HDC hDC )
#else
void report4obj_to_dev(obj, hDC )
OBJ4 *obj ;
HDC hDC ;
#endif
#else
#ifdef __cplusplus
void report4obj_to_dev(OBJ4 *obj )
#else
void report4obj_to_dev(obj )
OBJ4 *obj ;
#endif
#endif
{
OBJ4 *obj_on;
#ifdef S4WINDOWS
POINT pt[2];
/* use the device context */
pt[0].x = (int)obj->x;
pt[0].y = (int)obj->y;
pt[1].x = (int)obj->w;
pt[1].y = (int)obj->h;
LPtoDP( hDC, pt, 2 );
obj->dev_x = pt[0].x;
obj->dev_y = ABS(pt[0].y);
obj->dev_w = pt[1].x;
obj->dev_h = ABS(pt[1].y);
#else
/* in the non-windows case we simply transfer the 1000's of an inch
values */
obj->dev_x = (obj->x);
obj->dev_y = (obj->y);
obj->dev_w = (obj->w);
obj->dev_h = (obj->h);
#endif
obj_on = (OBJ4 *)l4first( &obj->contained );
while( obj_on )
{
#ifdef S4WINDOWS
report4obj_to_dev( obj_on, hDC );
#else
report4obj_to_dev( obj_on );
#endif
obj_on = (OBJ4 *)l4next( &obj->contained, obj_on );
}
return;
}
/**************************************************************************
* calculates group and object sizes in device coordinates
***************************************************************************/
#ifdef S4WINDOWS
#ifdef __cplusplus
void report4calc_obj_dev(REPORT4 *report, HDC hDC )
#else
void report4calc_obj_dev(report, hDC )
REPORT4 *report ;
HDC hDC ;
#endif
#else
#ifdef __cplusplus
void report4calc_obj_dev(REPORT4 *report )
#else
void report4calc_obj_dev(report )
REPORT4 *report ;
#endif
#endif
{
GROUP4 *group_on;
AREA4 *area_on;
OBJ4 *obj_on;
#ifdef S4WINDOWS
POINT pt[2];
SetMapMode( hDC, MM_HIENGLISH );
SetMapMode( hDC, MM_ANISOTROPIC );
if( report->output_code == 0 )
{
pt[0].x = (int)(report->margin_left - report->hard_margin_left);
pt[0].y = (int)(report->margin_top - report->hard_margin_top);
pt[1].x = (int)(report->margin_right - report->hard_margin_right);
pt[1].y = (int)(report->margin_bottom - report->hard_margin_bottom);
}
else
{
pt[0].x = (int)(report->margin_left);
pt[0].y = (int)(report->margin_top);
pt[1].x = (int)(report->margin_right);
pt[1].y = (int)(report->margin_bottom);
}
LPtoDP( hDC, pt, 2 );
report->dev_margin_left = pt[0].x;
report->dev_margin_top = ABS(pt[0].y);
report->dev_margin_right = pt[1].x;
report->dev_margin_bottom = ABS(pt[1].y);
#else
report->dev_margin_left = (report->margin_left);
report->dev_margin_right = (report->margin_right);
report->dev_margin_top = (report->margin_top);
report->dev_margin_bottom = (report->margin_bottom);
#endif
group_on = report->page_header_footer;
if( group_on )
{
area_on = (AREA4 *)l4first( &group_on->header_areas );
while( area_on )
{
#ifdef S4WINDOWS
pt[0].x = 0;
pt[0].y = (UINT)area_on->height;
LPtoDP( hDC, pt, 1 );
area_on->height_dev = ABS(pt[0].y);
#else
area_on->height_dev = (area_on->height);
#endif
obj_on = (OBJ4 *)l4first( &area_on->objects );
while( obj_on )
{
#ifdef S4WINDOWS
report4obj_to_dev( obj_on, hDC );
#else
report4obj_to_dev( obj_on );
#endif
obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on );
}
area_on = (AREA4 *)l4next( &group_on->header_areas, area_on );
}
area_on = (AREA4 *)l4first( &group_on->footer_areas );
while( area_on )
{
#ifdef S4WINDOWS
pt[0].x = 0;
pt[0].y = (UINT)area_on->height;
LPtoDP( hDC, pt, 1 );
area_on->height_dev = ABS(pt[0].y);
#else
area_on->height_dev = (area_on->height);
#endif
obj_on = (OBJ4 *)l4first( &area_on->objects );
while( obj_on )
{
#ifdef S4WINDOWS
report4obj_to_dev( obj_on, hDC );
#else
report4obj_to_dev( obj_on );
#endif
obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on );
}
area_on = (AREA4 *)l4next( &group_on->footer_areas, area_on );
}
}
group_on = (GROUP4 *)l4first( &report->groups );
while( group_on )
{
area_on = (AREA4 *)l4first( &group_on->header_areas );
while( area_on )
{
#ifdef S4WINDOWS
pt[0].x = 0;
pt[0].y = (UINT)area_on->height;
LPtoDP( hDC, pt, 1 );
area_on->height_dev = ABS(pt[0].y);
#else
area_on->height_dev = (area_on->height);
#endif
obj_on = (OBJ4 *)l4first( &area_on->objects );
while( obj_on )
{
#ifdef S4WINDOWS
report4obj_to_dev( obj_on, hDC );
#else
report4obj_to_dev( obj_on );
#endif
obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on );
}
area_on = (AREA4 *)l4next( &group_on->header_areas, area_on );
}
area_on = (AREA4 *)l4first( &group_on->footer_areas );
while( area_on )
{
#ifdef S4WINDOWS
pt[0].x = 0;
pt[0].y = (UINT)area_on->height;
LPtoDP( hDC, pt, 1 );
area_on->height_dev = ABS(pt[0].y);
#else
area_on->height_dev = (area_on->height);
#endif
obj_on = (OBJ4 *)l4first( &area_on->objects );
while( obj_on )
{
#ifdef S4WINDOWS
report4obj_to_dev( obj_on, hDC );
#else
report4obj_to_dev( obj_on );
#endif
obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on );
}
area_on = (AREA4 *)l4next( &group_on->footer_areas, area_on );
}
group_on = (GROUP4 *)l4next( &report->groups, group_on );
}
}
/* make a call to the relate4query_set() function */
int S4FUNCTION report4querySet( PREPORT4 report, char S4PTR *expr )
{
return relate4query_set( report->relate, expr );
}
/* make a call to the relate4sort_set() function */
int S4FUNCTION report4sortSet( PREPORT4 report, char S4PTR *expr )
{
return relate4sort_set( report->relate, expr );
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4caption( PREPORT4 report, char S4PTR *caption )
{
if( report == NULL )
{
return -1;
}
if( report->report_caption )
u4free( report->report_caption );
report->report_caption = NULL;
if( !caption )
return 0;
report->report_caption = (char *)u4alloc_free( report->code_base, strlen(caption)+1 );
if( !report->report_caption )
{
e4describe( report->code_base, e4report, E4_REP_CAPALLOC, 0, 0 );
return -1;
}
strcpy( report->report_caption, caption );
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4groupHardResets( PREPORT4 report, int reset_flag )
{
int temp;
if( !report )
return -1;
if( reset_flag < 0 )
{
e4describe( report->code_base, e4parm, E4_REP_BADRESET, 0, 0 );
return -1;
}
temp = report->hard_resets_flag;
report->hard_resets_flag = reset_flag;
return temp;
}
#ifdef S4WINDOWS
/* Calls the printer setup/seletion common dialog in Windows */
void S4FUNCTION report4printerSelect( PREPORT4 report )
{
static PRINTDLG pd;
memset( &pd, 0, sizeof(PRINTDLG) );
pd.lStructSize = sizeof( PRINTDLG );
pd.hwndOwner = report->hWnd;
pd.Flags = PD_RETURNDC | PD_PRINTSETUP;
pd.hDevMode = NULL;
pd.hDevNames = NULL;
if( PrintDlg( &pd ) != 0 )
{
report->printerDC = pd.hDC;
}
}
#endif
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4output( PREPORT4 report, int output_handle, int use_styles )
{
if( ! report )
{
return -1;
}
report->output_handle = output_handle;
report->use_styles = use_styles;
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4pageSize( PREPORT4 report, long pg_height, long pg_width, int unit_type )
{
long pgh = pg_height, pgw = pg_width;
if( !report )
{
return -1;
}
if( unit_type )
{
pgw = (long)( pg_width * 100 );
pgh = (long)(((float)pg_height * 1000.0)/6.0 + 0.5 );
}
report->report_width = pgw- report->margin_left - report->margin_right;
report->report_height = pgh - report->margin_top - report->margin_bottom;
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4margins( PREPORT4 report, long left, long right, long top, long bottom, int unit_type )
{
long rm = right, lm = left, tm = top, bm = bottom;
if( !report )
{
/*error message; */
return -1;
}
if( unit_type )
{
rm = right * 100;
lm = left * 100;
tm = (int)(((float)top*1000.0)/6.0);
bm = (int)(((float)bottom*1000.0)/6.0);
}
report->report_width = report->report_width + report->margin_left + report->margin_right;
report->report_height = report->report_height + report->margin_top + report->margin_bottom;
report->margin_right = rm;
report->margin_left = lm;
report->margin_top = tm;
report->margin_bottom = bm;
report->report_width = report->report_width - rm - lm;
report->report_height = report->report_height - tm - bm;
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4currency( PREPORT4 report, char *currency )
{
if( !report )
{
return -1;
}
if( !currency )
report->currency_symbol[0] = '\0';
else
u4ncpy( report->currency_symbol, currency, sizeof(report->currency_symbol) );
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4decimal( PREPORT4 report, char decimal )
{
if( !report )
{
return -1;
}
report->decimal_point = decimal;
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4separator( PREPORT4 report, char separator )
{
if( !report )
{
return -1;
}
report->thousand_separator = separator;
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4titlePage( PREPORT4 report, int title_page )
{
int temp;
if( !report )
{
return -1;
}
if( title_page < 0 )
{
e4describe( report->code_base, e4parm, E4_REP_BADTITLE, 0, 0 );
return -1;
}
temp = report->pgbrk_title;
report->pgbrk_title = title_page;
return temp;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4toScreen( PREPORT4 report, int to_screen )
{
if( !report )
{
return -1;
}
if( to_screen < 0 )
{
e4describe( report->code_base, e4parm, E4_REP_BADSCREEN, 0, 0 );
return -1;
}
if( to_screen > 0 )
report->output_code = to_screen;
else
report->output_code = 0;
return 0;
}
#ifdef S4WINDOWS
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4parent( PREPORT4 report, HWND parent )
{
if( !report )
{
return -1;
}
report->hWnd = parent;
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
HDC S4FUNCTION report4printerDC( PREPORT4 report, HDC hDC )
{
HDC temp;
if( !report )
{
return (HDC)-1;
}
temp = report->printerDC;
report->printerDC = hDC;
return temp;
}
#endif
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4dateFormat( PREPORT4 report, char *date_format )
{
if( !report || !date_format )
{
return -1;
}
u4ncpy( report->default_date_format, date_format, sizeof(report->default_date_format) );
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4pageSizeGet( PREPORT4 report, long *page_width,
long *page_height )
{
if( !report )
{
return -1;
}
*page_width = report->dev_page_width;
*page_height = report->dev_page_height;
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4pageMarginsGet( PREPORT4 report, long S4PTR *margin_left,
long S4PTR *margin_right, long S4PTR *margin_top, long S4PTR *margin_bottom )
{
if( !report )
{
return -1;
}
*margin_right = report->dev_margin_right;
*margin_left = report->dev_margin_left;
*margin_bottom = report->dev_margin_bottom;
*margin_top = report->dev_margin_top;
return 0;
}
/* SEE THE CODEREPORTER MANUAL */
int S4FUNCTION report4dataDo( PREPORT4 report )
{
char *f4info;
FIELD4INFO *f4infoi;
DATA4 *dfile;
POUT4OBJ oobj;
long bsize = 8198;
int rc, i, trl;
PGROUP4 group;
if( !report->output_group || !report->dfile_name || report->output_objs.n_link <= 0 )
{
e4describe( report->code_base, e4rep_data, E4_REP_NODSETUP, (char *)0, (char *)0 );
return -1;
}
/* allocate an array of FIELD4INFO structures */
f4info = (char *)u4alloc_er( report->code_base, (report->output_objs.n_link+1)*sizeof(FIELD4INFO) );
if( !f4info )
{
e4describe( report->code_base, e4rep_data, E4_REP_NODCREATE, report->dfile_name, (char *)0 );
return -1;
}
/* fill the FIELD4INFO structures */
oobj = NULL;
for( i = 0; i < report->output_objs.n_link; i++ )
{
f4infoi = (FIELD4INFO *)(f4info + i * sizeof(FIELD4INFO) );
oobj = (POUT4OBJ)l4next( &report->output_objs, oobj );
f4infoi->name = (char *)u4alloc_free( report->code_base, strlen(oobj->obj->field_name)+1 );
strcpy( f4infoi->name, oobj->obj->field_name );
f4infoi->type = oobj->obj->field_type;
f4infoi->len = oobj->obj->field_len;
f4infoi->dec = oobj->obj->field_dec;
}
trl = report->code_base->read_only;
report->code_base->read_only = 0;
/* create the new data file */
dfile = d4create( report->code_base, report->dfile_name, (FIELD4INFO *)f4info, NULL );
if( !dfile )
{
e4describe( report->code_base, e4rep_data, E4_REP_NODCREATE, report->dfile_name, (char *)0 );
u4free( f4info );
report->code_base->read_only = trl;
return -1;
}
report->code_base->read_only = trl;
/* associate the fields in the new data file with the output objects in the
report */
oobj = NULL;
for( i = 0; i < report->output_objs.n_link; i++ )
{
oobj = (POUT4OBJ)l4next( &report->output_objs, oobj );
oobj->obj->field = d4field( dfile, oobj->obj->field_name );
}
/* temporarily remove all the internal group flags */
group = (PGROUP4) l4first( &report->groups );
while( group )
{
group->trepeat_header = group->repeat_header;
group->tswap_header = group->swap_header;
group->tswap_footer = group->swap_footer;
group->treset_page = group->reset_page;
group->treset_pagenum = group->reset_pagenum;
group->repeat_header = 0;
group->swap_header = 0;
group->swap_footer = 0;
group->reset_page = 0;
group->reset_pagenum = 0;
group = (PGROUP4)l4next( &report->groups, group );
}
report->for_dbf = 1;
report->data_file = dfile;
report->rcount = 0;
report->dfile_buf = NULL;
/* allocate as large a buffer as you can */
while( report->dfile_buf == NULL )
{
report->dfile_buf = (char *)u4alloc_free( report->code_base, bsize );
if( report->dfile_buf == NULL )
bsize -= 1000;
if( bsize <= 0 )
break;
}
if( report->dfile_buf == NULL )
#ifndef __SC__
return 0;
#else
return 0;
#endif
/* set up the new datafile for fast writing */
file4seq_write_init( &report->dfile_seq, &dfile->file, (long)d4record_position(dfile,1L),
report->dfile_buf, (unsigned)bsize );
d4append_start( dfile, 0 );
if( f4info )
{
for( i = 0; i < report->output_objs.n_link; i++ )
{
f4infoi = (FIELD4INFO *)(f4info + i * sizeof(FIELD4INFO) );
u4free( f4infoi->name );
}
u4free( f4info );
}
/* start the report */
report4pageInit( report );
#ifdef S4WINDOWS
if( report->hWnd2 )
{
ReleaseCapture();
DestroyWindow( report->hWnd2 );
report->hWnd2 = NULL;
}
while( (rc = report4generatePage( report, 0 )) >= 0 )
#else
while( (rc = report4generatePage( report )) >= 0 )
#endif
{
if( rc == 2 )
break;
}
/* clean up after the report */
report4pageFree( report );
report->for_dbf = 0;
/* flush the buffer to the new data file */
file4seq_write_flush( &report->dfile_seq );
report->data_file->file.is_exclusive = 1;
report->data_file->num_recs = report->rcount;
d4update_header( report->data_file, 1, 1 );
d4close( report->data_file );
if( report->dfile_buf )
{
u4free( report->dfile_buf );
report->dfile_buf = NULL;
}
group = (PGROUP4) l4first( &report->groups );
while( group )
{
group->repeat_header = group->trepeat_header;
group->swap_header = group->tswap_header;
group->swap_footer = group->tswap_footer;
group->reset_page = group->treset_page;
group->reset_pagenum = group->treset_pagenum;
group = (PGROUP4)l4next( &report->groups, group );
}
oobj = NULL;
for( i = 0; i < report->output_objs.n_link; i++ )
{
oobj = (POUT4OBJ)l4next( &report->output_objs, oobj );
oobj->obj->field = NULL;
}
return 0;
}
#ifdef S4VBASIC
int S4FUNCTION report4decimal_v( PREPORT4 report, char *decimal )
{
if ( c4parm_check( report->code_base, 1, "report4decimal():" ) ) return -1 ;
#ifndef S4VB_DOS
return report4decimal( report, (char) decimal[0] ) ;
#else
return report4decimal( report, (char) c4str(decimal)[0] ) ;
#endif
}
int S4FUNCTION report4separator_v( PREPORT4 report, char *separator )
{
if ( c4parm_check( report->code_base, 1, "report4decimal():" ) ) return -1 ;
#ifndef S4VB_DOS
return report4separator( report, (char) separator[0] ) ;
#else
return report4separator( report, (char) c4str(separator)[0] ) ;
#endif
}
#ifdef S4VB_DOS
int S4FUNCTION report4caption_v ( PREPORT4 report, char *caption )
{
return report4caption( report, c4str(caption) ) ;
}
int S4FUNCTION report4currency_v ( PREPORT4 report, char *currency )
{
return report4currency( report, c4str(currency) ) ;
}
int S4FUNCTION report4dateFormat_v( PREPORT4 report, char *format )
{
return report4dateFormat( report, c4str(format) ) ;
}
int S4FUNCTION report4querySet_v( PREPORT4 report, char *query_expr )
{
return report4querySet( report, c4str(query_expr) );
}
int S4FUNCTION report4sortSet_v( PREPORT4 report, char *sort_expr )
{
return report4sortSet( report, c4str(sort_expr) );
}
#endif /* S4VB_DOS */
#endif /* S4VBASIC */