Files
comun/utile/hpdf/ReportOutput/_frxcursor.vc2

2627 lines
88 KiB
Plaintext

*--------------------------------------------------------------------------------------------------------------------------------------------------------
* (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!!
*--------------------------------------------------------------------------------------------------------------------------------------------------------
*< FOXBIN2PRG: Version="1.21" SourceFile="_frxcursor.vcx" CPID="1252" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries)
*
*
DEFINE CLASS frxcursor AS custom && Provides methods to translate and manipulate various values in label and report tables (LBXs and FRXs)
*< CLASSDATA: Baseclass="custom" Timestamp="" Scale="Pixels" Uniqueid="" />
#INCLUDE "_frxcursor.h"
*<DefinedPropArrayMethod>
*m: binstringtoint && Returns a numeric equivalent of a given binary number given in byte string form.
*m: bintoint && Returns the integer form of binary data. Parameter: cBinary
*m: charsettolocale && Converts a given Font Charset to a candidate locale Id for use with the STRCONV() function. Parameters: nCharSet
*m: createbandcursor && Creates a cursor with alias "bands" containing records of information for each band in the report. Assumes source alias is "FRX" unless specified. Parameters: [cFrxAlias]
*m: createcalcresetoncursor && Creates a cursor with alias "reset_on" that contains records of information for each prompt in the Calculation Reset combobox. Parameters: [cFrxAlias]
*m: createdefaultprintenvcursor && Creates a one-row cursor with the same structure as the FRX. Default parameters are "frx", "defPrnEnv". Parameters: [ cFrxAlias [, cDestinationAlias]]
*m: creategroupcursor && Creates a cursor with the alias "groups" containing records of information about each data group in the specified report cursor, default "frx". Parameters: [cFrxAlias]
*m: createobjcursorrecord && Called from .createObjectCursor(). Parameter: cDestinationAlias
*m: createobjectcursor && Creates a cursor (default alias: "objects") of records for each object record in the report alias. Parameters: [ cFrxAlias [, cDestinationAlias [, iFilterMode ]]]
*m: createvariablecursor && Creates a cursor with the alias "vars" containing records of information for each report variable in the report. Parameters: [cFrxAlias]
*m: frutopixels && Returns the pixel value of a given measurement in FRUs.
*m: getbandfor && Returns a SCATTER NAME band object for the specified object ID. Calls .createObjectCursor() if necessary. Parameters: cObjectID [, lStart]
*m: getfrutextheight && Reutrns the height of a given string in FRUs. Parameters: cText, cTypeface, iSize [, cStyle ]
*m: getfrutextwidth && Returns the width of a given string in FRUs. Parameters: cText, cTypeface, iSize [, cStyle ]
*m: getfrxtimestamp && Returns a FOX system file timestamp from a datetime value, any data type. Parameter: [vDateTime]
*m: getmetadatadomdoc && Returns a reference to an MSXml.DomDocument with the metadata xml loaded. Assumes FRX is located on desired record.
*m: getobjectsinband && Returns a collection of UNIQUEIDs (or RECNOs) for each object in a given band. Calls .createObjectCursor() if necessary. Parameters: cBandId [, lRecnos]
*m: getreportattribute && Returns the value of a given report/header attribute. The FRX cursor must be open. Parameters: cToken [, iAlternate]
*m: getselectedobjectcount && Returns the number of selected objects in the frx cursor. Parameter: [cFrxAlias]
*m: gettargettypetext && Returns a readable string version of a target Type+Code. Parameters: iObjectType, iObjectCode
*m: gettimestampstring && Returns a readable string version of a Fox system timestamp, using current date settings. Parameter: iStamp
*m: getunitvaluefromfru && Returns a given unit value for a given value in FRUs, depending on the units. Parameters: nFruValue, iUnits
*m: gorec && Restores record pointer with bounds checking. Parameters: i, cAlias
*m: hasband && Returns .T. if the report has the specified band type. Calls .createBandCursor() if necessary. Parameters: iObjCode
*m: hasdetailheader && Returns .T. if the specified detail band has an associated detail header band. Calls .createBandCursor() if necessary. Parameters: cUniqueId
*m: hasprotectionflag && Returns .T. if the given binary data contains a specific bit set. Parameters: cBytes, iBit
*m: insertband && Inserts a band record into an frx cursor. Assumes that the FRX is currently selected and that the record pointer is located appropriately. Parameter: iObjCode
*m: insertdataenvrecord && Inserts a data environment object record into an FRX cursor. Assumes that the record pointer is appropriately located. Parameters: ID, NAME, EXPR, CODE
*m: insertdetailband && Inserts a detail band into the frx cursor. Assumes: the record pointer is located appropriately. Parameters: none
*m: insertdetailheaderfooter && Inserts detail header and footer bands into the frx cursor. Assumes: record pointer is located on the detail band record. Parameters: none
*m: insertsummaryband && Inserts a summary band into the frx cursor. Parameters: lBreakToNewPage, lPageHeader, lPageFooter
*m: inserttitleband && Inserts a title band into the frx cursor. Parameter: lBreakToNewPage
*m: inttobin && Returns a binary form of an integer. Parameter: iNumber
*m: inttobinstring && Returns a string of bytes, the binary version of a given integer.
*m: pixelstofru && Returns the FRU value of a given measurement in pixels.
*m: popprintenv && Restores the printer environment from a previously saved cursor. See .PushPrintEnvToCursor() method. Assumes: previously saved cursor is currently selected.
*m: pushprintenvtocursor && Saves the current printer environment to a cursor. Parameter: cSavedInAlias
*m: setcolumncount && Adds or removes columns (and column header/footer records) from the FRX cursor. Assumes: the frx cursor is selected. Parameters: iColumns
*m: stripquotes && Returns a string with embraced string delimiters removed. Parameters: cString
*m: synchobjectpositions && Updates VPOS values in the FRX cursor for each object, based on which band the object starts in, and the current height of each band as expressed in the bands cursor. Assumes: band and object cursors exist; current alias is frx cursor; no recno restore.
*p: screendpi && Contains the working DPI of the ReportDesigner. Currently hard-coded to 96.
*p: _memberdata && XML Metadata for customizable properties
*</DefinedPropArrayMethod>
*<PropValue>
Name = "frxcursor"
screendpi = 96
_memberdata = <VFPData>
<memberdata name="getmetadatadomdoc" type="Method" display="GetMetadataDomDoc" favorites="false" override="false" script=""/>
<memberdata name="createvariablecursor" type="Method" display="CreateVariableCursor"/>
<memberdata name="binstringtoint" type="Method" display="BinStringToInt"/>
<memberdata name="bintoint" type="Method" display="BinToInt"/>
<memberdata name="charsettolocale" type="Method" display="CharsetToLocale"/>
<memberdata name="createbandcursor" type="Method" display="CreateBandCursor"/>
<memberdata name="createcalcresetoncursor" type="Method" display="CreateCalcResetOnCursor"/>
<memberdata name="createdefaultprintenvcursor" type="Method" display="CreateDefaultPrintEnvCursor"/>
<memberdata name="creategroupcursor" type="Method" display="CreateGroupCursor"/>
<memberdata name="createobjcursorrecord" type="Method" display="CreateObjCursorRecord"/>
<memberdata name="createobjectcursor" type="Method" display="CreateObjectCursor"/>
<memberdata name="frutopixels" type="Method" display="FruToPixels"/>
<memberdata name="getbandfor" type="Method" display="GetBandFor"/>
<memberdata name="getfrutextheight" type="Method" display="GetFruTextHeight"/>
<memberdata name="getfrutextwidth" type="Method" display="GetFruTextWidth"/>
<memberdata name="getfrxtimestamp" type="Method" display="GetFrxTimeStamp"/>
<memberdata name="getobjectsinband" type="Method" display="GetObjectsInBand"/>
<memberdata name="getreportattribute" type="Method" display="GetReportAttribute"/>
<memberdata name="getselectedobjectcount" type="Method" display="GetSelectedObjectCount"/>
<memberdata name="gettargettypetext" type="Method" display="GetTargetTypeText"/>
<memberdata name="gettimestampstring" type="Method" display="GetTimeStampString"/>
<memberdata name="getunitvaluefromfru" type="Method" display="GetUnitValueFromFru"/>
<memberdata name="gorec" type="Method" display="GoRec"/>
<memberdata name="hasband" type="Method" display="HasBand"/>
<memberdata name="hasdetailheader" type="Method" display="HasDetailHeader"/>
<memberdata name="hasprotectionflag" type="Method" display="HasProtectionFlag"/>
<memberdata name="insertband" type="Method" display="InsertBand"/>
<memberdata name="insertdataenvrecord" type="Method" display="InsertDataEnvRecord"/>
<memberdata name="insertdetailband" type="Method" display="InsertDetailBand"/>
<memberdata name="insertdetailheaderfooter" type="Method" display="InsertDetailHeaderFooter"/>
<memberdata name="insertsummaryband" type="Method" display="InsertSummaryBand"/>
<memberdata name="inserttitleband" type="Method" display="InsertTitleBand"/>
<memberdata name="inttobin" type="Method" display="IntToBin"/>
<memberdata name="inttobinstring" type="Method" display="IntToBinString"/>
<memberdata name="pixelstofru" type="Method" display="PixelsToFru"/>
<memberdata name="popprintenv" type="Method" display="PopPrintEnv"/>
<memberdata name="pushprintenvtocursor" type="Method" display="PushPrintEnvToCursor"/>
<memberdata name="screendpi" type="Property" display="ScreenDPI"/>
<memberdata name="setcolumncount" type="Method" display="SetColumnCount"/>
<memberdata name="stripquotes" type="Method" display="StripQuotes"/>
<memberdata name="synchobjectpositions" type="Method" display="SynchObjectPositions"/>
<memberdata name="runtimemode" type="Property" display="RuntimeMode"/>
</VFPData>
*</PropValue>
PROCEDURE binstringtoint && Returns a numeric equivalent of a given binary number given in byte string form.
*=======================================================
* BinstringToInt( char )
*
* Returns a numeric equivalent of a binary data in string
* form.
*
* BinChar & Integer conversion, based on code by RS
*=======================================================
lparameter cByte
local iReturn, i, b
iReturn = 0
for m.i = len( m.cByte ) to 1 step -1
b = asc( substr( m.cByte, m.i, 1 ))
iReturn = (m.iReturn*256) + m.b
endfor
return m.iReturn
ENDPROC
PROCEDURE bintoint && Returns the integer form of binary data. Parameter: cBinary
*=======================================================
* BinToInt( cBytes )
*
* Returns an integer form of binary data
*=======================================================
LPARAMETERS tcBinary
LOCAL lcInteger,lnInteger,lnCount,lnStrLen
IF EMPTY(tcBinary)
RETURN 0
ENDIF
lnStrLen=LEN(tcBinary)
lnInteger=0
FOR lnCount = 0 TO (lnStrLen-1)
IF SUBSTR(tcBinary,lnStrLen-lnCount,1)=="1"
lnInteger=lnInteger+2^lnCount
ENDIF
ENDFOR
RETURN INT(lnInteger)
ENDPROC
PROCEDURE charsettolocale && Converts a given Font Charset to a candidate locale Id for use with the STRCONV() function. Parameters: nCharSet
*=======================================================
* CharsetToLocale( nCharset )
*
* We need to map a given Font Charset to a candidate locale
* for use with the STRCONV() function.
*
*----------------------------------------------------------
* References: Q224804, Q232625
* also http://www.science.co.il/Language-Locale-Codes.asp
*
* Charset------------------- CodePage---- Locale (hex / dec)
* 0 Western 1252 1033
* 178 Arabic 1256, 864 0x0401 / 1025 (saudi)
* 186 Baltic 1257, 0x0425 / 1061
* 134 Chinese Simplified 936 0x0804 / 2052
* 136 Chinese Traditional 950 0x0404 / 1028
* 238 Central European 1250, 0x0405 / 1029 (Czech)
* 204 Cyrillic 1251, 855 0x0419 / 1049 (Russian)
* 161 Greek 1253, 869 0x0408 / 1032
* 177 Hebrew 1255 0x040d / 1037
* 128 Japanese 932 0x0411 / 1041
* 129 Korean 1361, 949 0x0412 / 1042
* 162 Turkish 1254, 857 0x041f / 1055
* 163 Vietnamese 1258 0x042a / 1066
*=======================================================
lparameter nCharset
do case
case inlist( m.nCharset, -1, 1 )
* Charset not assigned or system default
* Map to default locale:
return 0
case inlist( m.nCharset, 0 )
* 0 = Western
return 1033
case inlist( m.nCharset, 2, 77, 255 )
* These are generic. Map to default locale?
return 0
case m.nCharset = 178
* 178 Arabic 1256, 864 0x0401 / 1025 (saudi)
return 1025
case m.nCharset = 186
* 186 Baltic 1257, 0x0425 / 1061
return 1061
case m.nCharset = 134
* 134 Chinese Simplified 936 0x0804 / 2052
return 2052
case m.nCharset = 136
* 136 Chinese Traditional 950 0x0404 / 1028
return 1028
case m.nCharset = 238
* 238 Central European 1250, 0x0405 / 1029 (Czech)
return 1029
case m.nCharset = 204
* 204 Cyrillic 1251, 855 0x0419 / 1049 (Russian)
return 1049
case m.nCharset = 161
* 161 Greek 1253, 869 0x0408 / 1032
return 1032
case m.nCharset = 177
* 177 Hebrew 1255 0x040d / 1037
return 1037
case m.nCharset = 128
* 128 Japanese 932 0x0411 / 1041
return 1041
case m.nCharset = 129
* 129 Korean 1361, 949 0x0412 / 1042
return 1042
case m.nCharset = 162
* 162 Turkish 1254, 857 0x041f / 1055
return 1055
case m.nCharset = 163
* 163 Vietnamese 1258 0x042a / 1066
return 1066
otherwise
return 0
endcase
return 0
ENDPROC
PROCEDURE createbandcursor && Creates a cursor with alias "bands" containing records of information for each band in the report. Assumes source alias is "FRX" unless specified. Parameters: [cFrxAlias]
*=======================================================
* CreateBandCursor()
*
* Creats a cursor with the alias "bands" containing records
* of information for each band in the report.
*
* Returns .T. if successfully created.
*=======================================================
lparameter tcFrxAlias
if empty( m.tcFrxAlias )
tcFrxAlias = 'frx'
endif
if not used(m.tcFrxAlias)
return .F.
endif
local curSel, curRec
curSel = select()
curRec = recno(m.tcFrxAlias)
*-------------------------------------------------------
* create the bands cursor:
*-------------------------------------------------------
if used("bands")
use in bands
endif
select 0
create cursor bands ( ;
UNIQUEID c(10), ;
OBJTYPE N(2,0), ;
OBJCODE n(3,0), ;
EXPR M, ;
BANDLABEL c(35), ;
START n(9,3), ;
STOP n(9,3), ;
HEIGHT n(9,3), ;
P_START i, ;
P_STOP i, ;
P_HEIGHT i, ;
R_START i, ;
R_STOP i, ;
RESETTOTAL i, ;
BAND_SEQ i, ;
REL_BAND_ID c(10), ;
REC_NO i )
*-------------------------------------------------------
* Initialise stuff:
*-------------------------------------------------------
local nStart, iStart, iDetailCount
local cSuffix, iBandCount, oRec
local oGroup, oHeader
local lcTitleId, lcSummaryId
nStart = 0.000
iStart = 0
oGroup = newobject("Collection")
oHeader = newobject("Collection")
iBandCount = 0
iDetailCount = 0
store "" to lcTitleId, lcSummaryId
*-------------------------------------------------------
* Scan through the band records, building up the information
* and then insert a new record into the bands cursor:
*-------------------------------------------------------
select (m.tcFrxAlias)
scan for OBJTYPE = FRX_OBJTYP_BAND ;
and not deleted() and ;
PLATFORM = FRX_PLATFORM_WINDOWS
*----------------------------------------------
* Initialise the record buffer
*----------------------------------------------
select bands
scatter memo blank name oRec
select (m.tcFrxAlias)
iBandCount = m.iBandCount + 1
oRec.BAND_SEQ = m.iBandCount
*----------------------------------------------
* Transfer over some field values:
*----------------------------------------------
oRec.UNIQUEID = UNIQUEID
oRec.REC_NO = recno()
oRec.OBJTYPE = OBJTYPE
oRec.OBJCODE = OBJCODE
oRec.EXPR = EXPR
oRec.BANDLABEL = THIS.getTargetTypeText( OBJTYPE, OBJCODE )
*----------------------------------------------
* Save for later:
*----------------------------------------------
if OBJCODE = FRX_OBJCOD_TITLE
lcTitleID = UNIQUEID
endif
if OBJCODE = FRX_OBJCOD_SUMMARY
lcSummaryID = UNIQUEID
endif
*----------------------------------------------
* Determine related header/footer IDs:
*----------------------------------------------
do case
case inlist( OBJCODE, FRX_OBJCOD_PAGEHEADER, FRX_OBJCOD_COLHEADER, FRX_OBJCOD_GROUPHEADER, FRX_OBJCOD_DETAILHEADER )
*-------------------------------------
* Push the header ID on the stack:
*-------------------------------------
oHeader.Add( UNIQUEID )
case inlist( OBJCODE, FRX_OBJCOD_PAGEFOOTER, FRX_OBJCOD_COLFOOTER, FRX_OBJCOD_GROUPFOOTER, FRX_OBJCOD_DETAILFOOTER )
*-------------------------------------
* Pop the related header ID off the stack and
* store it:
*-------------------------------------
oRec.REL_BAND_ID = oHeader.Item( oHeader.Count )
oHeader.Remove( oHeader.Count )
endcase
*----------------------------------------------
* Some bands need extra info in their labels:
*----------------------------------------------
do case
case OBJCODE = FRX_OBJCOD_GROUPHEADER
cSuffix = ":" + trim(EXPR)
oGroup.Add( m.cSuffix )
oRec.RESETTOTAL = FRX_RESETTOTAL_GROUP_OFFSET + oGroup.Count
case OBJCODE = FRX_OBJCOD_DETAIL
iDetailCount = m.iDetailCount + 1
oRec.RESETTOTAL = FRX_RESETTOTAL_DETAIL_OFFSET + m.iDetailCount
cSuffix = " " + transform( m.iDetailCount ) ;
+ iif(not empty( trim(EXPR)), ":" + trim(EXPR), "")
case OBJCODE = FRX_OBJCOD_GROUPFOOTER
cSuffix = oGroup.Item( oGroup.Count )
oGroup.Remove( oGroup.Count )
otherwise
cSuffix = ""
endcase
oRec.BANDLABEL = oRec.BANDLABEL + m.cSuffix
*----------------------------------------------
* Band dimensions:
*----------------------------------------------
oRec.HEIGHT = HEIGHT
oRec.P_HEIGHT = THIS.FruToPixels( HEIGHT )
oRec.START = m.nStart
oRec.STOP = m.nStart + oRec.HEIGHT + BAND_SEPARATOR_HEIGHT_FRUS
nStart = oRec.STOP
oRec.P_START = m.iStart
oRec.P_STOP = m.iStart + oRec.P_HEIGHT + BAND_SEPARATOR_HEIGHT_PIXELS - 1
iStart = oRec.P_STOP + 1
*----------------------------------------------
* Run-time Band dimensions:
*----------------------------------------------
oRec.R_START = oRec.P_START - 18
oRec.R_STOP = oRec.P_STOP - 2 && per RICHSTA
* oRec.R_STOP = oRec.P_STOP - 3 && empirically
*----------------------------------------------
* Add the record to the cursor:
*----------------------------------------------
insert into bands from name oRec
endscan
*----------------------------------------------
* Retro-fit the Headers' relative Footer band id:
*----------------------------------------------
select bands
local iRec, cFooterId, cBandId
scan
if not empty( REL_BAND_ID )
iRec = recno()
m.cFooterId = UNIQUEID
m.cHeaderId = REL_BAND_ID
locate for UNIQUEID = m.cHeaderId
if found()
replace REL_BAND_ID with m.cFooterId
endif
go m.iRec
endif
endscan
if not empty( m.lcTitleId ) and not empty( m.lcSummaryId )
*----------------------------------------------
* Match up relative band ids:
*----------------------------------------------
locate for UNIQUEID = m.lcTitleID
replace REL_BAND_ID with m.lcSummaryId
locate for UNIQUEID = m.lcSummaryID
replace REL_BAND_ID with m.lcTitleId
endif
go top in bands
release oGroup, oHeader
THIS.goRec(m.curRec, m.tcFrxAlias)
select (m.curSel)
return .T.
ENDPROC
PROCEDURE createcalcresetoncursor && Creates a cursor with alias "reset_on" that contains records of information for each prompt in the Calculation Reset combobox. Parameters: [cFrxAlias]
*=======================================================
* CreateCalcResetOnCursor()
*
* Creates a cursor with the alias "reset_on" containing records
* of information for each prompt in the Calculation Reset combobox.
*
* Returns .T. if successfully created.
*=======================================================
lparameter tcFrxAlias
if empty( m.tcFrxAlias )
tcFrxAlias = 'frx'
endif
if not used(m.tcFrxAlias)
return .F.
endif
local curSel, curRec, iGroupCount, iDetailCount, iNum
curSel = select()
*-------------------------------------------------------
* create the reset_on cursor:
*-------------------------------------------------------
if used("reset_on")
use in reset_on
endif
create cursor reset_on (;
UNIQUEID c(10), ;
OBJCODE n(2,0) , ;
PROMPT_TEXT c(30), ;
RESETTOTAL i )
*-----------------------------------------------------------
* Add in the report/Page resets:
*-----------------------------------------------------------
insert into reset_on values ( "", 0, ENDOFREPORT_LOC, FRX_RESETTOTAL_ENDOFREPORT )
insert into reset_on values ( "", 0, ENDOFPAGE_LOC, FRX_RESETTOTAL_ENDOFPAGE )
select (m.tcFrxAlias)
curRec = recno()
*-----------------------------------------------------------
* Add in the column reset if there are multi-cols:
*-----------------------------------------------------------
locate for OBJTYPE = FRX_OBJTYP_REPORTHEADER ;
and PLATFORM = FRX_PLATFORM_WINDOWS
if VPOS > 1
insert into reset_on values ( "", 0, ENDOFCOLUMN_LOC, FRX_RESETTOTAL_ENDOFCOLUMN )
else
insert into reset_on values ( "", 0, "\"+ENDOFCOLUMN_LOC, FRX_RESETTOTAL_ENDOFCOLUMN )
endif
*-----------------------------------------------------------
* Only add in the group reset if there are groups:
*-----------------------------------------------------------
count for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_GROUPHEADER ;
and PLATFORM = FRX_PLATFORM_WINDOWS ;
to iGroupCount
if m.iGroupCount > 0
iNum = 1
insert into reset_on values ( "", 0, "\-", 1001 )
scan for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_GROUPHEADER ;
and PLATFORM = FRX_PLATFORM_WINDOWS
insert into reset_on values ( ;
&tcFrxAlias..UNIQUEID, ;
&tcFrxAlias..OBJCODE, ;
GROUP_BY_LOC + trim(&tcFrxAlias..EXPR), ;
FRX_RESETTOTAL_GROUP_OFFSET + m.iNum )
iNum = m.iNum + 1
endscan
endif
*-----------------------------------------------------------
* Only add in the detail reset if this is a multi-detail report:
*-----------------------------------------------------------
count for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_DETAIL ;
and PLATFORM = FRX_PLATFORM_WINDOWS ;
to iDetailCount
if m.iDetailCount > 1
iNum = 1
insert into reset_on values ( "", 0, "\-", 1002 )
scan for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_DETAIL ;
and PLATFORM = FRX_PLATFORM_WINDOWS
insert into reset_on values ( ;
&tcFrxAlias..UNIQUEID, ;
&tcFrxAlias..OBJCODE, ;
DETAIL_LOC + transform(m.iNum), ;
FRX_RESETTOTAL_DETAIL_OFFSET + m.iNum )
iNum = m.iNum + 1
endscan
endif
THIS.goRec(m.curRec, m.tcFrxAlias)
select (m.curSel)
return .t.
ENDPROC
PROCEDURE createdefaultprintenvcursor && Creates a one-row cursor with the same structure as the FRX. Default parameters are "frx", "defPrnEnv". Parameters: [ cFrxAlias [, cDestinationAlias]]
*=======================================================
* CreateDefaultPrintEnvCursor( <frxAlias>, <dataenvAlias> )
*
* Creates a one-row cursor with the same structure as the
* FRX. Default parameters are "frx", "defPrnEnv".
*=======================================================
lparameters lcFrxAlias, lcPEAlias
local curSel
curSel = select()
if empty( m.lcFrxAlias )
lcFrxAlias = 'frx'
endif
if empty( m.lcPEAlias )
lcPEAlias = 'defPrnEnv'
endif
select * ;
from (m.lcFrxAlias) ;
where OBJTYPE = FRX_OBJTYP_REPORTHEADER ;
and PLATFORM = FRX_PLATFORM_WINDOWS ;
into cursor (m.lcPEAlias) ;
readwrite
=sys(1037,2)
select (m.curSel)
return
ENDPROC
PROCEDURE creategroupcursor && Creates a cursor with the alias "groups" containing records of information about each data group in the specified report cursor, default "frx". Parameters: [cFrxAlias]
*=======================================================
* CreateGroupCursor()
*
* Creats a cursor with the alias "groups" containing records
* of information for each data group in the report.
* Used mainly by PanelGrouping class.
*
* Returns .T. if successfully created.
*=======================================================
lparameter tcFrxAlias
if empty( m.tcFrxAlias )
tcFrxAlias = 'frx'
endif
if not used(m.tcFrxAlias)
return .F.
endif
curSel = select()
*-------------------------------------------------------
* get the current report measurement units and tell our
* converter to use them:
*-------------------------------------------------------
local iUnits
iUnits = THIS.getReportAttribute("UNITS")
*-------------------------------------------------------
* create the groups cursor:
*-------------------------------------------------------
if used("groups")
use in groups
endif
select 0
create cursor groups ( ;
UNIQUEID c(10), ;
EXPR M, ;
PAGINATE i, ;
REPRINT l, ;
THRESH n(9,3), ;
FOOTER_ID c(10) )
*-------------------------------------------------------
* Initialise stuff:
*-------------------------------------------------------
local iPaginate, iCurRec, nThreshold, lisMultiCol
iPaginate = 0
iCurRec = recno(m.tcFrxAlias)
lIsMultiCol = THIS.getReportAttribute("MULTICOLUMN")
*-------------------------------------------------------
* Scan through the group header records, building up the information
* and then insert a new record into the groups cursor:
*-------------------------------------------------------
select (m.tcFrxAlias)
scan for OBJTYPE = FRX_OBJTYP_BAND and ;
OBJCODE = FRX_OBJCOD_GROUPHEADER and ;
not deleted() and ;
PLATFORM = FRX_PLATFORM_WINDOWS
*-------------------------------------
* Pagination: try:
*
* 1 ( ) Normal (none set)
* 2 ( ) Start on new column (COLBREAK)
* 3 ( ) Start on new page (PAGEBREAK)
* 4 ( ) Start on new page 1 (PAGEBREAK+RESETPAGE)
*-------------------------------------
do case
case PAGEBREAK and RESETPAGE
iPaginate = 4
case PAGEBREAK
iPaginate = 3
case COLBREAK
if m.lIsMultiCol
iPaginate = 2
else
*--------------------------------
* Even though this option used to be set to "new column",
* the report only has one column, so reset to default:
*--------------------------------
iPaginate = 1
endif
otherwise
iPaginate = 1
endcase
*-------------------------------------
* Calculate threshold in local units:
*-------------------------------------
nThreshold = THIS.getUnitValueFromFRU( WIDTH, m.iUnits )
insert into groups values ( ;
&tcFrxAlias..UNIQUEID, ;
&tcFrxAlias..EXPR, ;
m.iPaginate, ;
&tcFrxAlias..NOREPEAT, ;
m.nThreshold, ;
"" )
endscan
*-------------------------------------------------------
* Now grab the group footer IDs as well. Note of course
* that they are in reverse order to the headers (nesting):
*-------------------------------------------------------
go bottom in groups
scan for OBJTYPE = FRX_OBJTYP_BAND and ;
OBJCODE = FRX_OBJCOD_GROUPFOOTER and ;
not deleted() and ;
PLATFORM = FRX_PLATFORM_WINDOWS
select groups
replace FOOTER_ID with &tcFrxAlias..UNIQUEID
skip -1
select (m.tcFrxAlias)
endscan
*-------------------------------------------------------
* Restore the record pointer in FRX (important)
*-------------------------------------------------------
THIS.goRec(m.icurRec, m.tcFrxAlias)
select (m.curSel)
return .T.
ENDPROC
PROCEDURE createobjcursorrecord && Called from .createObjectCursor(). Parameter: cDestinationAlias
*=======================================================
* createObjCursorRecord()
*
* Assumes: current alias is the source
*=======================================================
lparameters tcDestAlias, tlRuntimeMode
local srcAlias, lIsGroup, oRec
srcAlias = alias()
lIsGroup = .F.
select (m.tcDestAlias)
scatter memo blank name oRec
select (m.srcAlias)
oRec.REC_NO = recno()
do case
case OBJTYPE = FRX_OBJTYP_LABEL
oRec.CTYPE = TARGET_TEXT_LABEL_LOC
* oRec.OBJNAME = TARGET_TEXT_LABEL_LOC + ": " + trim(EXPR)
oRec.OBJNAME = THIS.stripQuotes(trim(EXPR))
oRec.OBJ_PICT = "pslabel.bmp"
oRec.LOCALE_ID = THIS.CharsetToLocale( RESOID )
oRec.TYPE_SEQ = 1
case OBJTYPE = FRX_OBJTYP_FIELD
oRec.CTYPE = TARGET_FIELD_LOC
* oRec.OBJNAME = TARGET_FIELD_LOC + ": " + trim(EXPR)
oRec.OBJNAME = THIS.stripQuotes(trim(EXPR))
oRec.OBJ_PICT = "pseditbx.bmp"
oRec.LOCALE_ID = THIS.CharsetToLocale( RESOID )
oRec.TYPE_SEQ = 2
case OBJTYPE = FRX_OBJTYP_LINE
oRec.CTYPE = TARGET_LINE_LOC
oRec.OBJNAME = TARGET_LINE_LOC
oRec.OBJ_PICT = "psline.bmp"
oRec.TYPE_SEQ = 3
case OBJTYPE = FRX_OBJTYP_RECTANGLE
oRec.CTYPE = TARGET_BOX_LOC
oRec.OBJNAME = TARGET_BOX_LOC
oRec.OBJ_PICT = "pshape.bmp"
oRec.TYPE_SEQ = 4
case OBJTYPE = FRX_OBJTYP_PICTURE
oRec.CTYPE = TARGET_PICTURE_LOC
if not empty( NAME )
* oRec.OBJNAME = TARGET_PICTURE_LOC + ": " + trim(NAME)
oRec.OBJNAME = THIS.stripQuotes(trim(NAME))
else
* oRec.OBJNAME = TARGET_PICTURE_LOC + ": " + trim(PICTURE)
oRec.OBJNAME = THIS.stripQuotes(trim(PICTURE))
endif
oRec.OBJ_PICT = "psolebnd.bmp"
oRec.TYPE_SEQ = 5
case OBJTYPE = FRX_OBJTYP_GROUP
oRec.CTYPE = TARGET_GROUPED_LOC
oRec.OBJNAME = TARGET_GROUPED_LOC + " (" + trans(HPOS)+")"
oRec.OBJ_PICT = "group2.bmp"
lIsGroup = .T.
oRec.TYPE_SEQ = 6
endcase
oRec.UNIQUEID = UNIQUEID
oRec.OBJTYPE = OBJTYPE
oRec.OBJCODE = OBJCODE
oRec.EXPR = EXPR
oRec.VPOS = VPOS
oRec.HPOS = HPOS
oRec.HEIGHT = HEIGHT
oRec.P_START = THIS.FruToPixels( VPOS )
oRec.P_HEIGHT = THIS.FruToPixels( HEIGHT )
oRec.P_STOP = (oRec.P_START + oRec.P_HEIGHT - 1)
oRec.WIDTH = WIDTH
oRec.SELECTED = CURPOS
if not m.lIsGroup
if m.tlRuntimeMode
*--------------------------------------------------------
* Determine the object's location, start and end bands,
* as determined by the report run-time engine, using the
* two adjusted lookup cursors we created earlier:
*--------------------------------------------------------
*-------------------------------------------
* Scan bottom up for start points:
*-------------------------------------------
select bands
go bottom
do while .T.
if R_START <= oRec.P_START
oRec.START_BAND_ID = UNIQUEID
oRec.BANDLABEL = trim(BANDLABEL)
oRec.BAND_OFFSET = oRec.P_START - P_START
oRec.BAND_SEQ = BAND_SEQ
exit
endif
if recno()=1
exit
endif
skip -1 in bands
enddo
*-------------------------------------------
* scan top down for end points:
*-------------------------------------------
select bands
go top
*-------------------------------------------
* This difference between object types
* was determined through empirical testing.
* It may have some flaws.
*-------------------------------------------
do case
case inlist(oRec.OBJTYPE, FRX_OBJTYP_LABEL )
locate for R_STOP > oRec.P_STOP
otherwise
locate for R_STOP >= oRec.P_STOP
endcase
if found()
*-------------------------------------------
* an object cannot end in a band above
* that in which it starts:
*-------------------------------------------
if BAND_SEQ >= oRec.BAND_SEQ
oRec.END_BAND_ID = UNIQUEID
else
oRec.END_BAND_ID = oRec.START_BAND_ID
endif
else
*---------------------------------------------------
* The object runs off the bottom of the band array.
* Force the object to end in the Page Footer:
*---------------------------------------------------
locate for OBJCODE = FRX_OBJCOD_PAGEFOOTER
if found()
oRec.END_BAND_ID = UNIQUEID
endif
endif
*---------------------------------------------------
* Show both start and end bands against the object:
*---------------------------------------------------
if oRec.END_BAND_ID <> oRec.START_BAND_ID
oRec.BANDLABEL = oRec.BANDLABEL + "..." + trim(BANDLABEL)
endif
*---------------------------------------------------
* If an object starts and ends in two different bands...
*---------------------------------------------------
if oRec.START_BAND_ID <> oRec.END_BAND_ID
select bands
locate for UNIQUEID = oRec.START_BAND_ID
if empty( REL_BAND_ID ) or REL_BAND_ID # oRec.END_BAND_ID
*---------------------------------------------------
* ...that are not a matched Header-Footer pair,
* then the object is forced into the PageHeader band.
*---------------------------------------------------
locate for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_PAGEHEADER
oRec.START_BAND_ID = UNIQUEID
do case
case inlist(oRec.OBJTYPE, FRX_OBJTYP_RECTANGLE )
oRec.BANDLABEL = TARGET_UNPREDICTABLE_LOC + " (" + trim(oRec.BANDLABEL) + ")"
otherwise
oRec.BANDLABEL = TARGET_FORCED_PAGEHEADER_LOC + " (" + trim(oRec.BANDLABEL) + ")"
endcase
oRec.BAND_SEQ = 99
oRec.END_BAND_ID = ""
oRec.BAND_OFFSET = oRec.P_START - P_START && real start, not the run-time one
endif
endif
else
*--------------------------------------------------------
* Determine the object's location, start and end bands,
* as determined by the Report Designer:
*--------------------------------------------------------
select bands
locate for P_START <= oRec.P_START ;
and P_STOP >= oRec.P_START
if found()
oRec.START_BAND_ID = UNIQUEID
oRec.BAND_OFFSET = oRec.P_START - P_START
oRec.BANDLABEL = trim(BANDLABEL)
oRec.BAND_SEQ = BAND_SEQ
endif
select bands
locate for P_START <= oRec.P_STOP ;
and P_STOP >= oRec.P_STOP
if found()
oRec.END_BAND_ID = UNIQUEID
if oRec.END_BAND_ID <> oRec.START_BAND_ID
oRec.BANDLABEL = oRec.BANDLABEL + " - " + trim(BANDLABEL)
endif
endif
endif
endif
insert into (m.tcDestAlias) from name oRec
select (m.srcAlias)
return
ENDPROC
PROCEDURE createobjectcursor && Creates a cursor (default alias: "objects") of records for each object record in the report alias. Parameters: [ cFrxAlias [, cDestinationAlias [, iFilterMode ]]]
*=======================================================
* CreateObjectCursor()
*
* Creates a cursor (alias: objects) of records for each
* object in the report.
* Returns .T. if successful.
* Calls .createBandCursor() if necessary.
*=======================================================
lparameter tcFrxAlias, tcDestAlias, tiFilter, tlRuntimeMode
*-------------------------------------------------------
* Ensure parameters are initialised appropriately:
*-------------------------------------------------------
if vartype( m.tiFilter ) = "L"
tiFilter = OBJCSR_ALL_OBJECTS_IGNORE_GROUPS
endif
if empty( m.tcDestAlias )
tcDestAlias = 'objects'
endif
if empty( m.tcFrxAlias )
tcFrxAlias = 'frx'
endif
local curSel, curRec
curSel = select()
if not used(m.tcFrxAlias)
return .F.
else
curRec = recno(m.tcFrxAlias)
endif
if not used('bands')
if not THIS.createBandCursor(m.tcFrxAlias)
select (m.curSel)
return .F.
endif
endif
*-------------------------------------------------------
* create the objects cursor:
*-------------------------------------------------------
if used( m.tcDestAlias )
use in (m.tcDestAlias)
endif
select 0
create cursor &tcDestAlias ( ;
UNIQUEID c(10), ;
OBJTYPE N(2,0), ;
OBJCODE n(3,0), ;
EXPR M, ;
VPOS n(9,3), ;
HPOS n(9,3), ;
HEIGHT n(9,3),;
WIDTH n(9,3),;
OBJNAME c(50),;
LOCALE_ID i, ;
P_START i, ;
P_STOP i, ;
P_HEIGHT i, ;
BAND_OFFSET i, ;
START_BAND_ID c(10),;
END_BAND_ID c(10), ;
BANDLABEL c(75), ;
SELECTED l, ;
OBJ_PICT c(12), ;
BAND_SEQ i, ;
REC_NO i, ;
TYPE_SEQ i, ;
CTYPE c(10) )
*-------------------------------------------------------
* Select object records from the FRX:
*-------------------------------------------------------
do case
case m.tiFilter = OBJCSR_ALL_OBJECTS_IGNORE_GROUPS
*-------------------------------------------------
* all object records (ignoring grouped items):
*-------------------------------------------------
select (m.tcFrxAlias)
scan for inlist( OBJTYPE, FRX_OBJTYP_LABEL, FRX_OBJTYP_FIELD, ;
FRX_OBJTYP_LINE, FRX_OBJTYP_RECTANGLE, FRX_OBJTYP_PICTURE ) and ;
not deleted() and ;
PLATFORM = FRX_PLATFORM_WINDOWS
THIS.createObjCursorRecord( tcDestAlias, m.tlRuntimeMode )
endscan
case m.tiFilter = OBJCSR_SHOW_ALL_OBJECTS
*-------------------------------------------------
* All objects+grouped objects in report:
* Show groups as separate objects
* do not expand grouped objects
*-------------------------------------------------
select (m.tcFrxAlias)
scan for inlist( OBJTYPE, FRX_OBJTYP_LABEL, FRX_OBJTYP_FIELD, ;
FRX_OBJTYP_LINE, FRX_OBJTYP_RECTANGLE, FRX_OBJTYP_PICTURE ) and ;
not deleted() and ;
PLATFORM = FRX_PLATFORM_WINDOWS
THIS.createObjCursorRecord( tcDestAlias, m.tlRuntimeMode )
endscan
*-------------------------------------------------
* Now remove the grouped ones
*-------------------------------------------------
local iGrpStart, iGrpCount
scan for OBJTYPE = FRX_OBJTYP_GROUP
iGrpStart = VPOS
iGrpCount = HPOS
select (m.tcDestAlias)
go m.iGrpStart
delete next m.iGrpCount
select (m.tcFrxAlias)
endscan
*-------------------------------------------------
* Now add the groups themselves
*-------------------------------------------------
scan for OBJTYPE = FRX_OBJTYP_GROUP
THIS.createObjCursorRecord( tcDestAlias, m.tlRuntimeMode )
endscan
case m.tiFilter = OBJCSR_FILTER_ON_SELECTED
*-------------------------------------------------
* All currently selected object records:
* do not show grouped objects
* Show groups as separate objects
*-------------------------------------------------
select (m.tcFrxAlias)
scan for inlist( OBJTYPE, FRX_OBJTYP_LABEL, FRX_OBJTYP_FIELD, ;
FRX_OBJTYP_LINE, FRX_OBJTYP_RECTANGLE, FRX_OBJTYP_PICTURE ) and ;
not deleted() and ;
CURPOS and ;
PLATFORM = FRX_PLATFORM_WINDOWS
THIS.createObjCursorRecord( tcDestAlias, m.tlRuntimeMode )
endscan
*-------------------------------------------------
* Now add any selected grouped items themselves:
*-------------------------------------------------
scan for OBJTYPE = FRX_OBJTYP_GROUP and ;
CURPOS and ;
PLATFORM = FRX_PLATFORM_WINDOWS
THIS.createObjCursorRecord( tcDestAlias, m.tlRuntimeMode )
endscan
endcase
go top in (m.tcDestAlias)
THIS.goRec(m.curRec, m.tcFrxAlias)
select (m.curSel)
return .T.
ENDPROC
PROCEDURE createvariablecursor && Creates a cursor with the alias "vars" containing records of information for each report variable in the report. Parameters: [cFrxAlias]
*=======================================================
* CreateVariableCursor()
*
* Creats a cursor with the alias "vars" containing records
* of information for each report variable in the report.
* Used mostly by panelVariables class
*
* Returns .T. if successfully created.
*=======================================================
lparameter tcFrxAlias
if empty( m.tcFrxAlias )
tcFrxAlias = 'frx'
endif
if not used(m.tcFrxAlias)
return .F.
endif
curSel = select()
*-------------------------------------------------------
* This is needed later on:
*-------------------------------------------------------
if not used("reset_on")
THIS.createCalcResetOnCursor()
endif
*-------------------------------------------------------
* create the vars cursor:
*-------------------------------------------------------
if used("vars")
use in vars
endif
select 0
create cursor vars ( ;
UNIQUEID C(10), ;
VARNAME M, ;
VALUE_TO_STORE M, ;
INITIAL_VALUE M, ;
RELEASE_VAR L, ;
CALC_TYPE N(2,0), ;
RESET_ON N(2,0), ;
REC_NO I )
*-------------------------------------------------------
* Initialise stuff:
*-------------------------------------------------------
local iCurRec, iResetOn
iCurRec = recno(m.tcFrxAlias)
*-------------------------------------------------------
* Scan through the variable records, building up the information
* and then insert a new record into the vars cursor:
*-------------------------------------------------------
select (m.tcFrxAlias)
scan for OBJTYPE = FRX_OBJTYP_VARIABLE and ;
not deleted() and ;
PLATFORM = FRX_PLATFORM_WINDOWS
select reset_on
locate for RESETTOTAL = &tcFrxAlias..RESETTOTAL
insert into vars values ( ;
&tcFrxAlias..UNIQUEID, ;
&tcFrxAlias..NAME, ;
&tcFrxAlias..EXPR, ;
&tcFrxAlias..TAG, ;
&tcFrxAlias..UNIQUE, ;
&tcFrxAlias..TOTALTYPE+1, ;
recno("reset_on"), ;
recno(m.tcFrxAlias) )
endscan
*-------------------------------------------------------
* Restore the record pointer in FRX (important)
*-------------------------------------------------------
THIS.goRec(m.icurRec, m.tcFrxAlias)
select (m.curSel)
return .T.
ENDPROC
PROCEDURE frutopixels && Returns the pixel value of a given measurement in FRUs.
*=======================================================
* FruToPixels( num )
*
* returns the value in pixels of a given FRU measurement.
*=======================================================
lparameter nFRU
local iPixels
*------------------------------------
* Fixed for SP1:
* use the .screenDPI property instead of
* the hard-coded 96 dpi value. The ReportBuilder
* client will reset .screenDPI to 96 so that it
* is correct for design-time report designer use.
*------------------------------------
*iPixels = round((m.nFRU * 96)/10000,3)
iPixels = round((m.nFRU * this.screenDPI)/10000,3)
return int( m.iPixels )
ENDPROC
PROCEDURE getbandfor && Returns a SCATTER NAME band object for the specified object ID. Calls .createObjectCursor() if necessary. Parameters: cObjectID [, lStart]
*=======================================================
* GetBandFor( UNIQUEID [, lStart ] )
*
* Returns a SCATTER NAME band object for the specified
* object.
* Calls .createObjectCursor() if necessary.
*=======================================================
lparameters cObjectId, lStart
if not used('frx')
return null
endif
if parameters() < 2
lStart = .T.
endif
if not used('objects')
THIS.createObjectCursor()
endif
local curSel, iRec, oBand
curSel = select()
oBand = null
select objects
locate for UNIQUEID = m.cObjectId
if found()
select bands
if m.lStart
locate for UNIQUEID = objects.START_BAND_ID
else
locate for UNIQUEID = objects.END_BAND_ID
endif
endif
if not found()
go bottom
endif
*scatter fields UNIQUEID, OBJCODE, BANDLABEL, RESETTOTAL, REC_NO ;
* name oBand
scatter name oBand
select (m.curSel)
return oBand
ENDPROC
PROCEDURE getfrutextheight && Reutrns the height of a given string in FRUs. Parameters: cText, cTypeface, iSize [, cStyle ]
*=======================================================
* GetFruTextHeight( cText, cTypeface, iSize [, cStyle ] )
*
* Returns the height of a given string in FRUs
*=======================================================
lparameters cText, cTypeFace, iSize, cStyle
if parameters() < 4
cStyle = "N"
endif
*-------------------------------------------------------
* obtain text height in pixels:
*-------------------------------------------------------
local iHeight
iHeight = fontmetric(1, cTypeFace, iSize, cStyle )
*-------------------------------------------------------
* convert pixels to FRU:
*-------------------------------------------------------
*------------------------------------
* Fixed for SP1:
* use the .screenDPI property instead of
* the hard-coded 96 dpi value. The ReportBuilder
* client will reset .screenDPI to 96 so that it
* is correct for design-time report designer use.
*------------------------------------
return this.pixelsToFru( m.iHeight )
ENDPROC
PROCEDURE getfrutextwidth && Returns the width of a given string in FRUs. Parameters: cText, cTypeface, iSize [, cStyle ]
*=======================================================
* GetFruTextWidth( cText, cTypeface, iSize [, cStyle ] )
*
* Returns the width of a given string in FRUs
*=======================================================
lparameters cText, cTypeFace, iSize, cStyle
if parameters() < 4
cStyle = "N"
endif
*-------------------------------------------------------
* obtain text width in pixels. Remember that txtwidth() returns
* number of equivalent average characters, so must multiply by
* the overall average character width:
*-------------------------------------------------------
local iWidth
iWidth = txtwidth( cText, cTypeFace, iSize, cStyle )
iWidth = m.iWidth * fontmetric(6, cTypeFace, iSize, cStyle )
*-------------------------------------------------------
* convert pixels to FRU using screen dpi:
*-------------------------------------------------------
*------------------------------------
* Fixed for SP1:
* use the .screenDPI property instead of
* the hard-coded 96 dpi value. The ReportBuilder
* client will reset .screenDPI to 96 so that it
* is correct for design-time report designer use.
*------------------------------------
return this.pixelsToFru( m.iWidth )
ENDPROC
PROCEDURE getfrxtimestamp && Returns a FOX system file timestamp from a datetime value, any data type. Parameter: [vDateTime]
#define DEBUGGING .F.
*=======================================================
* GetFrxTimeStamp( vDateTime )
*
* Returns a FOX system file timestamp
* from a date time value, any data type
*
* Calls: intToBin(), binToInt() from browser.scx code
*=======================================================
lparameter tvDateTime
*-------------------------------------------------------
* Default to current datetime
*-------------------------------------------------------
LOCAL ltDateTime, lvFoxTimeStamp, lvTemp
ltDateTime = CTOT(TRANSFORM(tvDateTime))
IF EMPTY(ltDateTime)
ltDateTime = DATETIME()
ENDIF
#IF DEBUGGING
ACTI SCREEN
CLEAR
? ltDateTime
#ENDIF
*-------------------------------------------------------
* bits 4-0, seconds in two-second increments
*-------------------------------------------------------
lvTemp = SEC(ltDateTime) / 2
lvFoxTimeStamp = PADL(RIGHT(THIS.IntToBin(lvTemp),5),5,"0")
#IF DEBUGGING
? lvTemp
? lvFoxTimeStamp
?
#ENDIF
*-------------------------------------------------------
* bits 10-5, minutes
*-------------------------------------------------------
lvTemp = MINUTE(ltDateTime)
lvFoxTimeStamp = PADL(RIGHT(THIS.IntToBin(lvTemp),6),6,"0") + lvFoxTimeStamp
#IF DEBUGGING
? lvTemp
? lvFoxTimeStamp
?
#ENDIF
*-------------------------------------------------------
* bits 15-11, hours
*-------------------------------------------------------
lvTemp = HOUR(ltDateTime)
lvFoxTimeStamp = PADL(RIGHT(THIS.IntToBin(lvTemp),5),5,"0") + lvFoxTimeStamp
#IF DEBUGGING
? lvTemp
? lvFoxTimeStamp
?
#ENDIF
*-------------------------------------------------------
* bits 20-16, days
*-------------------------------------------------------
lvTemp = DAY(ltDateTime)
lvFoxTimeStamp = PADL(RIGHT(THIS.IntToBin(lvTemp),5),5,"0") + lvFoxTimeStamp
#IF DEBUGGING
? lvTemp
? lvFoxTimeStamp
?
#ENDIF
*-------------------------------------------------------
* bits 24-21, months
*-------------------------------------------------------
lvTemp = MONTH(ltDateTime)
lvFoxTimeStamp = PADL(RIGHT(THIS.IntToBin(lvTemp),4),4,"0") + lvFoxTimeStamp
#IF DEBUGGING
? lvTemp
? lvFoxTimeStamp
?
#ENDIF
*-------------------------------------------------------
* bits 31-25, years with a 1980 offset
*-------------------------------------------------------
lvTemp = YEAR(ltDateTime)-1980
lvFoxTimeStamp = PADL(RIGHT(THIS.IntToBin(lvTemp),7),7,"0") + lvFoxTimeStamp
#IF DEBUGGING
? lvTemp
? LEN(lvFoxTimeStamp)
? lvFoxTimeStamp
?
#ENDIF
lvFoxTimeStamp = THIS.BinToInt(lvFoxTimeStamp)
RETURN lvFoxTimeStamp
ENDPROC
PROCEDURE getmetadatadomdoc && Returns a reference to an MSXml.DomDocument with the metadata xml loaded. Assumes FRX is located on desired record.
*=======================================================
* GetMetadataDomDoc( <frx> )
*
* Returns a reference to an MSXml.DomDocument with the
* XML stored in the STYLE column of the current record in
* the frx cursor. Default alias is "frx".
*
* Check for null in case of errors.
*
* If the STYLE field is empty, a default XML document is
* returned.
*=======================================================
lparameter lcFrxAlias
local curSel, cXml, oDom
if empty( m.lcFrxAlias )
lcFrxAlias = 'frx'
endif
if not used(m.lcFrxAlias)
return .null.
endif
curSel = select()
select (m.lcFrxAlias)
*------------------------------------------------------
* Extract the metadata XML from STYLE field of frx cursor
* record, and put default xml in if its empty:
*------------------------------------------------------
cXml = STYLE
if empty( m.cXml )
text noshow to m.cXml
<VFPData>
<reportdata name="" type="R" script="" execute="" execwhen="" class="" classlib="" declass="" declasslib=""/>
</VFPData>
endtext
replace STYLE with m.cXml
endif
select (m.curSel)
*------------------------------------------------------
* Create a DomDocument and load up the xml.
*------------------------------------------------------
oDom = createobject("MSXml.DomDocument")
oDom.loadXML( m.cXml )
return oDom
ENDPROC
PROCEDURE getobjectsinband && Returns a collection of UNIQUEIDs (or RECNOs) for each object in a given band. Calls .createObjectCursor() if necessary. Parameters: cBandId [, lRecnos]
*=======================================================
* GetObjectsInBand( UNIQUEID [, lRecnos ] )
*
* returns a Collection of UNIQUEID values for each object
* in a given Band.
* Calls .createObjectCursor() if necessary.
*=======================================================
lparameter cBandId, lRecnos
local oBandObjects, curSel
curSel = select()
oBandObjects = newobject("Collection")
if not used("objects")
THIS.createObjectCursor()
endif
select objects
scan
if objects.START_BAND_ID = m.cBandId
*-------------------------------------------------------
* the object is defined as starting in this band
*-------------------------------------------------------
if m.lRecnos
oBandObjects.Add( objects.REC_NO )
else
oBandObjects.Add( objects.UNIQUEID )
endif
endif
endscan
select (m.curSel)
return oBandObjects
ENDPROC
PROCEDURE getreportattribute && Returns the value of a given report/header attribute. The FRX cursor must be open. Parameters: cToken [, iAlternate]
*=======================================================
* GetReportAttribute( cToken [, iAlt] )
*
* Returns the value of a given report (or header) attribute.
* The FRX cursor must be open.
*=======================================================
lparameters cKey, iAlt
if parameters()<2
iAlt = 0
endif
if not used('frx')
return .F.
endif
local curSel, curRec, vRetVal
curSel = select()
select frx
curRec = recno()
locate for OBJTYPE = FRX_OBJTYP_REPORTHEADER and ;
PLATFORM = FRX_PLATFORM_WINDOWS
do case
case upper(m.cKey) = "UNITS"
if m.iAlt = 0
vRetVal = RULER
else
do case
case RULER = FRX_RULER_FRUS
vRetVal = UNITS_FRU_LOC
case RULER = FRX_RULER_INCHES
vRetVal = UNITS_INCHES_LOC
case RULER = FRX_RULER_METRIC
vRetVal = UNITS_METRIC_LOC
case RULER = FRX_RULER_PIXELS
vRetVal = UNITS_PIXELS_LOC
case RULER = FRX_RULER_CHARACTERS
vRetVal = UNITS_CHARACTERS_LOC
otherwise
vRetVal = "?"
endcase
endif
case upper(m.cKey) = "MULTICOLUMN"
*-------------------------------------------------------
* If a report has multiple columns,
* then the column width is not the default:
*-------------------------------------------------------
*vRetVal = (WIDTH <> -1)
*-------------------------------------------------------
* could also check for existence of ColumnHeader:
*-------------------------------------------------------
*vRetVal = THIS.hasBand(OBJCODE_COLHEADER)
*-------------------------------------------------------
* or just how many columns?
*-------------------------------------------------------
vRetVal = (VPOS > 1)
case upper(m.cKey) = "COLUMNCOUNT"
vRetVal = VPOS
case upper(m.cKey) = "PROTECTION"
vRetVal = ORDER
case upper(m.cKey) = "SNAKED_COLUMNS"
vRetVal = BOTTOM
*case upper(m.cKey) = "DEFAULT FONT"
endcase
THIS.goRec( m.curRec, 'frx')
select (m.curSel)
return m.vRetVal
ENDPROC
PROCEDURE getselectedobjectcount && Returns the number of selected objects in the frx cursor. Parameter: [cFrxAlias]
*=======================================================
* getSelectedObjectCount( <frx> )
*
*=======================================================
lparameter lcFrxAlias
if empty( m.lcFrxAlias )
lcFrxAlias = "frx"
endif
local cursel, curRec, selCount
curSel = select()
select (m.lcFrxAlias)
curRec = recno()
count for CURPOS and ;
PLATFORM = FRX_PLATFORM_WINDOWS and ;
OBJTYPE <> 1 ;
to m.selCount
go m.curRec
select (m.curSel)
return m.selCount
ENDPROC
PROCEDURE gettargettypetext && Returns a readable string version of a target Type+Code. Parameters: iObjectType, iObjectCode
*=======================================================
* GetTargetTypeText( OBJTYPE, OBJCODE )
*
* Returns a readable string version of a target Type/Code
*=======================================================
lparameters nObjType, nObjCode
if parameters() = 0
nObjType = -1
nObjCode = -1
endif
do case
case m.nObjType = FRX_OBJTYPE_MULTISELECT
return TARGET_MULTISELECT_LOC
case m.nObjType = FRX_OBJTYP_COMMENT
return TARGET_REPORT_COMMENT_LOC
case m.nObjType = FRX_OBJTYP_REPORTHEADER
return TARGET_REPORT_GLOBAL_LOC
case m.nObjType = 2
return TARGET_WORKAREA_LOC
case m.nObjType = 3
return TARGET_INDEX_LOC
case m.nObjType = 4
return TARGET_RELATION_LOC
case m.nObjType = FRX_OBJTYP_LABEL
return TARGET_TEXT_LABEL_LOC
case m.nObjType = FRX_OBJTYP_LINE
return TARGET_LINE_LOC
case m.nObjType = FRX_OBJTYP_RECTANGLE
return TARGET_BOX_LOC
case m.nObjType = FRX_OBJTYP_FIELD
return TARGET_FIELD_LOC
case m.nObjType = FRX_OBJTYP_BAND
do case
case m.nObjCode = FRX_OBJCOD_TITLE
return TARGET_TITLE_LOC
case m.nObjCode = FRX_OBJCOD_PAGEHEADER
return TARGET_PAGE_HEADER_LOC
case m.nObjCode = FRX_OBJCOD_COLHEADER
return TARGET_COL_HEADER_LOC
case m.nObjCode = FRX_OBJCOD_GROUPHEADER
return TARGET_GROUP_HEADER_LOC
case m.nObjCode = FRX_OBJCOD_DETAIL
return TARGET_DETAIL_LOC
case m.nObjCode = FRX_OBJCOD_GROUPFOOTER
return TARGET_GROUP_FOOTER_LOC
case m.nObjCode = FRX_OBJCOD_COLFOOTER
return TARGET_COL_FOOTER_LOC
case m.nObjCode = FRX_OBJCOD_PAGEFOOTER
return TARGET_PAGE_FOOTER_LOC
case m.nObjCode = FRX_OBJCOD_SUMMARY
return TARGET_SUMMARY_LOC
case m.nObjCode = FRX_OBJCOD_DETAILHEADER
return TARGET_DETAIL_HEADER_LOC
case m.nObjCode = FRX_OBJCOD_DETAILFOOTER
return TARGET_DETAIL_FOOTER_LOC
otherwise
return TARGET_UNKNOWN_BAND_LOC
endcase
case m.nObjType = FRX_OBJTYP_GROUP
return TARGET_GROUPED_LOC
case m.nObjType = FRX_OBJTYP_PICTURE
return TARGET_PICTURE_LOC
case m.nObjType = FRX_OBJTYP_VARIABLE
return TARGET_VARIABLE_LOC
case m.nObjType = FRX_OBJTYP_PDRIVER
return TARGET_PDRIVER_LOC
case m.nObjType = FRX_OBJTYP_FONTRES
return TARGET_FONTRESO_LOC
case m.nObjType = FRX_OBJTYP_DATAENV
return TARGET_DATAENV_LOC
case m.nObjType = FRX_OBJTYP_DATAOBJ
return TARGET_CURSOR_LOC
otherwise
return TARGET_UNKNOWN_LOC
endcase
ENDPROC
PROCEDURE gettimestampstring && Returns a readable string version of a Fox system timestamp, using current date settings. Parameter: iStamp
*=======================================================
* GetTimeStampString( iStamp )
*
* Returns a readable string version of a Fox system
* timestamp, using current date settings
*=======================================================
lparameter tiStamp
IF EMPTY(tiStamp) OR TYPE("tiStamp") # "N"
RETURN ""
ENDIF
LOCAL lnYearoffset,lcYear,lcMonth,;
lcDay,lcHour,lcMinute,lcSecond
*-------------------------------------------------------
* lnYearoffset = INT(tiStamp/2^25) && bits 31-25
*-------------------------------------------------------
lnYearoffset = BITRSHIFT(tiStamp,25)
lcYear = STR(1980 + lnYearoffset)
*-------------------------------------------------------
* lcMonth = STR(INT(tiStamp/2^21) % 2^4) && bits 24-21
*-------------------------------------------------------
lcMonth = STR(BITRSHIFT(tiStamp,21) % 2^4)
*-------------------------------------------------------
* lcDay = STR(INT(tiStamp/2^16) % 2^5) && bits 20-16
*-------------------------------------------------------
lcDay = STR(BITRSHIFT(tiStamp,16) % 2^5)
*-------------------------------------------------------
* lcHour = STR(INT(tiStamp/2^11) % 2^5) && bits 15-11
*-------------------------------------------------------
lcHour = STR(BITRSHIFT(tiStamp,11) % 2^5)
*-------------------------------------------------------
* lcMinute = STR(INT(tiStamp/2^5) % 2^6) && bits 10-5
*-------------------------------------------------------
lcMinute = STR(BITRSHIFT(tiStamp,5) % 2^6)
*-------------------------------------------------------
* lcSecond = STR(INT(tiStamp%2^5) * 2) && bits 4-0 (two-second increments)
*-------------------------------------------------------
lcSecond = STR(BITLSHIFT(tiStamp%2^5,1))
RETURN TTOC({^&lcYear./&lcMonth./&lcDay. &lcHour.:&lcMinute.:&lcSecond.})
ENDPROC
PROCEDURE getunitvaluefromfru && Returns a given unit value for a given value in FRUs, depending on the units. Parameters: nFruValue, iUnits
*-------------------------------------------------
* Return a given unit value for a given value in FRUs,
* depending on the Units:
*-------------------------------------------------
lparameter nFruValue, iUnits
do case
case inlist( m.iUnits, FRX_RULER_INCHES, FRX_RULER_OFF)
return (m.nFruValue / 10000)
case m.iUnits = FRX_RULER_METRIC
return (m.nFruValue / (0.3937 * 10000))
case m.iUnits = FRX_RULER_CHARACTERS
*---------------------------------------------------------
* 1 char = 833.33 FRU
* 1 char = 1/12 inch
*---------------------------------------------------------
return (m.nFruValue / 833.33)
*case THIS.units = FRX_RULER_PIXELS
otherwise
*---------------------------------------------------------
* Designer fixed at 96 dpi
*---------------------------------------------------------
return (m.nFruValue * 96 / 10000 )
endcase
ENDPROC
PROCEDURE gorec && Restores record pointer with bounds checking. Parameters: i, cAlias
*=======================================================
* GoRec( i, cAlias )
*
* restores record pointer with bounds checking
*=======================================================
lparameter iRec, cAlias
if parameters() < 2
cAlias = alias()
endif
if between( iRec, 1, reccount(m.cAlias) )
go m.iRec in (m.cAlias)
endif
return
ENDPROC
PROCEDURE hasband && Returns .T. if the report has the specified band type. Calls .createBandCursor() if necessary. Parameters: iObjCode
*=======================================================
* HasBand( objCode )
*
* Returns .T. if the report has the specified type of
* band record.
* Calls .createBandCursor() if necessary.
*=======================================================
lparameter iObjCode
if not used('bands')
THIS.createBandCursor()
endif
local curSel, lRetVal
curSel = select()
lRetVal = .F.
select bands
locate for OBJCODE = m.iObjCode
if found()
lRetVal = .T.
endif
select (m.curSel)
return m.lRetVal
ENDPROC
PROCEDURE hasdetailheader && Returns .T. if the specified detail band has an associated detail header band. Calls .createBandCursor() if necessary. Parameters: cUniqueId
*=======================================================
* HasDetailHeader( UNIQUED )
*
* Returns .T. if the specifed Detail band has an associated
* "detail header" band.
*
* Calls .createBandCursor() if necessary.
*=======================================================
lparameter cUniqueId
if not used('bands')
THIS.createBandCursor()
endif
local curSel, lRetval
curSel = select()
lRetVal = .F.
select bands
locate for UNIQUEID = m.cUniqueId
skip -1
lRetVal = (OBJTYPE = FRX_OBJTYP_BAND and OBJCODE = FRX_OBJCOD_DETAILHEADER)
select (m.curSel)
return m.lRetVal
ENDPROC
PROCEDURE hasprotectionflag && Returns .T. if the given binary data contains a specific bit set. Parameters: cBytes, iBit
*=======================================================
* HasProtectionFlag( cBytes, iBit )
*
* Returns .T. if the given binary data contains a specific
* bit set to true.
*
* Uses: BinstringToInt()
*=======================================================
lparameters cBinstring, iFlagBit
local iProtFlags
iProtFlags = THIS.BinstringToInt( m.cBinstring )
return bittest( m.iProtFlags, m.iFlagBit )
ENDPROC
PROCEDURE Init
*=======================================================
* Init()
*=======================================================
*---------------------------------
* Determine the screen DPI:
*---------------------------------
#define LOGPIXELSX 88
declare integer GetDeviceCaps in WIN32API integer HDC, integer item
declare integer GetDC in WIN32API integer hWnd
*declare integer DeleteDC in WIN32API integer HDC
declare integer ReleaseDC in WIN32API integer hWnd, integer HDC
local hdc, screenDPI
hdc = GetDC(0)
THIS.screenDPI = GetDeviceCaps( m.hdc, LOGPIXELSX )
ReleaseDC( 0, m.hdc )
*DeleteDC( m.hdc )
*------------------------------------
* Fixed for SP1:
* The ReportBuilder client will
* reset .ScreenDPI to 96 so that it is correct
* for design-time report designer use, even if
* at run-time the app is running on higher-res
* screens.
*------------------------------------
ENDPROC
PROCEDURE insertband && Inserts a band record into an frx cursor. Assumes that the FRX is currently selected and that the record pointer is located appropriately. Parameter: iObjCode
*=======================================================
* InsertBand()
*
* Inserts a band into an FRX.
* Assumes that the record pointer is located appropriately.
*=======================================================
lparameters liObjCode
insert blank
replace ;
PLATFORM with FRX_PLATFORM_WINDOWS, ;
UNIQUEID with sys(2015), ;
OBJTYPE with FRX_OBJTYP_BAND, ;
OBJCODE with m.liObjCode, ;
NOREPEAT with .F., ;
PAGEBREAK with .F., ;
COLBREAK with .F., ;
RESETPAGE with .F., ;
PLAIN with .F., ;
CURPOS with .F.
return
ENDPROC
PROCEDURE insertdataenvrecord && Inserts a data environment object record into an FRX cursor. Assumes that the record pointer is appropriately located. Parameters: ID, NAME, EXPR, CODE
*=======================================================
* InsertDataEnvRecord( ID, NAME, EXPR, CODE )
*
* Inserts a data-environment object record into an FRX.
* Assumes that the record pointer is located appropriately.
*=======================================================
lparameters liObjType, lcName, lcExpr, lcMethods
insert blank
replace ;
PLATFORM with FRX_PLATFORM_WINDOWS, ;
OBJTYPE with m.liObjType, ;
NAME with m.lcName, ;
EXPR with m.lcExpr, ;
TAG with m.lcMethods, ;
ENVIRON with .F., ;
CURPOS with .F.
return
ENDPROC
PROCEDURE insertdetailband && Inserts a detail band into the frx cursor. Assumes: the record pointer is located appropriately. Parameters: none
*=======================================================
* InsertDetailBand()
*
* Inserts a detail band into an FRX.
* Assumes that the record pointer is located appropriately.
*=======================================================
THIS.insertBand( FRX_OBJCOD_DETAIL )
return
ENDPROC
PROCEDURE insertdetailheaderfooter && Inserts detail header and footer bands into the frx cursor. Assumes: record pointer is located on the detail band record. Parameters: none
*=======================================================
* InsertDetailHeaderFooter()
*
* Inserts Detail Header and Footer bands into the FRX.
* Assumes: we are positioned on the detail band:
*=======================================================
insert blank
replace ;
PLATFORM with FRX_PLATFORM_WINDOWS, ;
UNIQUEID with sys(2015), ;
OBJTYPE with FRX_OBJTYP_BAND, ;
OBJCODE with FRX_OBJCOD_DETAILFOOTER
skip -1
insert before blank
replace ;
PLATFORM with FRX_PLATFORM_WINDOWS, ;
UNIQUEID with sys(2015), ;
OBJTYPE with FRX_OBJTYP_BAND, ;
OBJCODE with FRX_OBJCOD_DETAILHEADER
skip
return
ENDPROC
PROCEDURE insertsummaryband && Inserts a summary band into the frx cursor. Parameters: lBreakToNewPage, lPageHeader, lPageFooter
*=======================================================
* InsertSummaryBand( lNewPage, lPageHeader, lPageFooter )
*
* Inserts a Summary band into an FRX
*=======================================================
lparameter lNewPage, lPageHeader, lPageFooter
locate for OBJTYPE = FRX_OBJTYP_BAND and ;
OBJCODE = FRX_OBJCOD_PAGEFOOTER
THIS.insertBand( FRX_OBJCOD_SUMMARY )
replace ;
HEIGHT with 5000.000, ;
PAGEBREAK with m.lNewPage, ;
EJECTBEFOR with m.lPageHeader, ;
EJECTAFTER with m.lPageFooter
return
ENDPROC
PROCEDURE inserttitleband && Inserts a title band into the frx cursor. Parameter: lBreakToNewPage
*=======================================================
* InsertTitleBand( lNewPage )
*
* Inserts a Title band record into the FRX
*=======================================================
lparameter lNewPage
go top
*-------------------------------------------------------
* will be inserted as the second record (as is appropriate)
*-------------------------------------------------------
THIS.insertBand( FRX_OBJCOD_TITLE )
replace ;
HEIGHT with 5000.000, ;
PAGEBREAK with m.lNewPage
return
ENDPROC
PROCEDURE inttobin && Returns a binary form of an integer. Parameter: iNumber
*=======================================================
* IntToBin( int )
*
* Returns a binary form of an integer
*=======================================================
LPARAMETERS tnInteger
LOCAL lnInteger,lcBinary,lnDivisor,lnCount
IF EMPTY(tnInteger)
RETURN "0"
ENDIF
lnInteger=INT(tnInteger)
lcBinary=""
FOR lnCount = 31 TO 0 STEP -1
lnDivisor=2^lnCount
IF lnDivisor>lnInteger
lcBinary=lcBinary+"0"
LOOP
ENDIF
lcBinary=lcBinary+IIF((lnInteger/lnDivisor)>0,"1","0")
lnInteger=INT(lnInteger-lnDivisor)
ENDFOR
RETURN lcBinary
ENDPROC
PROCEDURE inttobinstring && Returns a string of bytes, the binary version of a given integer.
*=======================================================
* InttoBinString( int )
*
* Returns a string of bytes, the binary version of a
* given integer.
*
* BinChar & Integer conversion, based on code by RS
*=======================================================
lparameter i
local cBytes, b
cBytes = ""
do while m.i <> 0
b = m.i % 256
i = floor( m.i/256 )
cBytes = m.cBytes + chr(m.b)
enddo
return m.cBytes
ENDPROC
PROCEDURE pixelstofru && Returns the FRU value of a given measurement in pixels.
*=======================================================
* PixelsToFru( int )
*
* return a value in FRUs of a given pixel dimension
*=======================================================
lparameter nPix
*------------------------------------
* Fixed for SP1:
* use the .screenDPI property instead of
* the hard-coded 96 dpi value. The ReportBuilder
* client will reset .screenDPI to 96 so that it
* is correct for design-time report designer use.
*------------------------------------
*return round(( nPix * 10000 )/96 , 3 )
return round(( nPix * 10000 )/this.screenDPI , 3 )
ENDPROC
PROCEDURE popprintenv && Restores the printer environment from a previously saved cursor. See .PushPrintEnvToCursor() method. Assumes: previously saved cursor is currently selected.
*=======================================================
* popPrintEnv()
*
* assumes the FRX file to pop from is selected.
*=======================================================
result = sys(1037,3)
return
ENDPROC
PROCEDURE pushprintenvtocursor && Saves the current printer environment to a cursor. Parameter: cSavedInAlias
*=======================================================
* pushPrintEnvToCursor( <alias> )
*=======================================================
lparameter cRegisterAlias
local curSel
curSel = select()
select * ;
from frx ;
where .F. ;
into cursor (m.cRegisterAlias) ;
readwrite
append Blank
result = sys(1037,2)
select (m.curSel)
return
ENDPROC
PROCEDURE setcolumncount && Adds or removes columns (and column header/footer records) from the FRX cursor. Assumes: the frx cursor is selected. Parameters: iColumns
*=======================================================
* SetColumnCount( iCols )
*
* Adds or subtracts columns (and column header/footer
* records from the FRX.
* Assumes: the current workarea contains the FRX cursor.
* Calls: .createObjectCursor() if necessary.
*=======================================================
lparameter iCols
local lHasColBands, curRec, cFrxAlias
cFrxAlias = alias()
curRec = recno( m.cFrxAlias )
locate for OBJTYPE = FRX_OBJTYP_REPORTHEADER and ;
PLATFORM = FRX_PLATFORM_WINDOWS
replace VPOS with m.iCols
locate for OBJTYPE = FRX_OBJTYP_BAND and ;
OBJCODE = FRX_OBJCOD_COLHEADER and ;
PLATFORM = FRX_PLATFORM_WINDOWS
lHasColBands = found()
THIS.goRec(m.curRec, m.cFrxAlias)
if (m.lHasColBands and m.iCols = 1) or ;
(not m.lHasColBands and m.iCols > 1)
THIS.createObjectCursor()
do case
case (m.lHasColBands and m.iCols = 1)
*-------------------------------------------------------
* Remove the column header/footer bands:
*-------------------------------------------------------
locate for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_COLHEADER ;
and PLATFORM = FRX_PLATFORM_WINDOWS
if found()
delete
endif
locate for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_COLFOOTER ;
and PLATFORM = FRX_PLATFORM_WINDOWS
if found()
delete
endif
case (not m.lHasColBands and m.iCols > 1)
*-------------------------------------------------------
* Insert the column header/footer bands:
*-------------------------------------------------------
locate for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_PAGEHEADER ;
and PLATFORM = FRX_PLATFORM_WINDOWS
insert blank
replace ;
PLATFORM with FRX_PLATFORM_WINDOWS, ;
UNIQUEID with sys(2015), ;
OBJTYPE with FRX_OBJTYP_BAND, ;
OBJCODE with FRX_OBJCOD_COLHEADER, ;
NOREPEAT with .F., ;
PAGEBREAK with .F., ;
COLBREAK with .F., ;
RESETPAGE with .F., ;
PLAIN with .F., ;
CURPOS with .F.
locate for OBJTYPE = FRX_OBJTYP_BAND ;
and OBJCODE = FRX_OBJCOD_PAGEFOOTER ;
and PLATFORM = FRX_PLATFORM_WINDOWS
insert before blank
replace ;
PLATFORM with FRX_PLATFORM_WINDOWS, ;
UNIQUEID with sys(2015), ;
OBJTYPE with FRX_OBJTYP_BAND, ;
OBJCODE with FRX_OBJCOD_COLFOOTER, ;
NOREPEAT with .F., ;
PAGEBREAK with .F., ;
COLBREAK with .F., ;
RESETPAGE with .F., ;
PLAIN with .F., ;
CURPOS with .F.
endcase
*-------------------------------------------------------
* Refresh the band cursor:
*-------------------------------------------------------
THIS.createBandCursor()
*-------------------------------------------------------
* Using the offsets in object cursor and the
* new band heights in band cursor, re-sync the
* objects' positions:
*-------------------------------------------------------
THIS.synchObjectPositions()
THIS.goRec(m.curRec, m.cFrxAlias)
endif
return
ENDPROC
PROCEDURE stripquotes && Returns a string with embraced string delimiters removed. Parameters: cString
lparameter lcValue
do case
case left( m.lcValue, 1 ) == ["] and right( m.lcValue, 1 ) == ["]
return substr( m.lcValue, 2, len( m.lcValue ) - 2 )
case left( m.lcValue, 1 ) == ['] and right( m.lcValue, 1 ) == [']
return substr( m.lcValue, 2, len( m.lcValue ) - 2 )
otherwise
return m.lcValue
endcase
ENDPROC
PROCEDURE synchobjectpositions && Updates VPOS values in the FRX cursor for each object, based on which band the object starts in, and the current height of each band as expressed in the bands cursor. Assumes: band and object cursors exist; current alias is frx cursor; no recno restore.
*=======================================================
* SynchObjectPositions()
*
* Updates the VPOS values in the FRX for each object,
* based on which band the object starts in, and the current
* height of each band as expressed in the bands cursor.
*
* Assumes:
* - bands and objects cursors have been prepared,
* - current alias is an FRX cursor
*=======================================================
local curSel, curRec, cUID
curSel = select()
curRec = recno()
*-------------------------------------------------------
* Scan through the FRX cursor,
* updating the VPOS to maintain the
* same relative offset from the band it belongs to.
*-------------------------------------------------------
scan for inlist( OBJTYPE, ;
FRX_OBJTYP_LABEL, FRX_OBJTYP_FIELD, FRX_OBJTYP_LINE, ;
FRX_OBJTYP_RECTANGLE, FRX_OBJTYP_PICTURE ) and ;
not deleted() and ;
PLATFORM = FRX_PLATFORM_WINDOWS
cUID = UNIQUEID
*-------------------------------------------------------
* for each object, restore the relative positions:
*-------------------------------------------------------
select objects
locate for UNIQUEID = cUID
select bands
locate for UNIQUEID = objects.START_BAND_ID
select (curSel)
if found("bands") and found("objects")
*-------------------------------------------------------
* The bands and objects cursors use pixel-based math, so
* convert back to FRUs:
*-------------------------------------------------------
replace VPOS with ;
THIS.pixelsToFru( bands.P_START + objects.BAND_OFFSET )
endif
endscan
THIS.GoRec( m.curRec, alias() )
return
ENDPROC
ENDDEFINE
DEFINE CLASS frxdevicehelper AS custom
*<ClassComment>
*This class knows how to read printer environment information. Usage:
*
* x = NEWOBJECT( "frxDeviceHelper" )
* IF x.LoadDeviceInfo( cDRIVER, cDEVICE, frx.TAG2 )
* ? x.DpiX
* ? x.DpiY
* :
* etc
*</ClassComment>
*< CLASSDATA: Baseclass="custom" Timestamp="" Scale="Pixels" Uniqueid="" />
#INCLUDE "_frxcursor.h"
*<DefinedPropArrayMethod>
*m: loaddeviceinfo && Parses out print device parameters into member properties given specific device information: Parameters: cDriver, cDevice, cDevMode. Assumes current VFP default printer if no parameters specified.
*m: loadfromfrx && Loads printer device parameters from an FRX cursor header record. Restores recno and selected alias. Params: [ cFrxAlias ] (assumes "frx" if none specified.)
*m: loadfromhdc
*m: loadfromstrings && Loads printer device parameters from string variables. Params: cExpr, cTag
*p: actualx && Physical width of page in device units
*p: actualy && Physical length of page in device units
*p: dpix && Logical pixels-per-inch in the X dimension
*p: dpiy && Logical pixels-per-inch in the Y dimension
*p: errormessage && Occurs when the Valid event returns false (.F.), and provides a means to display an error message.
*p: mmx && Horizontal page size in millimeters
*p: mmy && Vertical page size in millimeters
*p: offsetx && Physical printable page left margin
*p: offsety && Physical printable page top margin
*p: orientation && 0=Portrait, 1=Landscape
*p: printablex && Horizontal page width in pixels
*p: printabley && Vertical page length in pixels
*p: _memberdata && XML Metadata for customizable properties
*</DefinedPropArrayMethod>
*<PropValue>
actualx = 0
actualy = 0
dpix = 0
dpiy = 0
errormessage = ("")
mmx = 0
mmy = 0
Name = "frxdevicehelper"
offsetx = 0
offsety = 0
orientation = 0
printablex = 0
printabley = 0
_memberdata = <VFPData>
<memberdata name="loaddeviceinfo" type="Method" display="LoadDeviceInfo" favorites="false" override="false" script=""/>
<memberdata name="loadfromfrx" type="Method" display="LoadFromFrx" favorites="false" override="false" script=""/>
<memberdata name="loadfromstrings" type="Method" display="LoadFromStrings" favorites="false" override="false" script=""/>
<memberdata name="loadfromhdc" type="Method" display="LoadFromHDC" favorites="false" override="false" script=""/>
<memberdata name="dpix" type="Property" display="DpiX" favorites="false" override="false" script=""/>
<memberdata name="dpiy" type="Property" display="DpiY" favorites="false" override="false" script=""/>
<memberdata name="offsetx" type="Property" display="OffsetX" favorites="false" override="false" script=""/>
<memberdata name="offsety" type="Property" display="OffsetY" favorites="false" override="false" script=""/>
<memberdata name="actualx" type="Property" display="ActualX" favorites="false" override="false" script=""/>
<memberdata name="actualy" type="Property" display="ActualY" favorites="false" override="false" script=""/>
<memberdata name="mmx" type="Property" display="mmX" favorites="false" override="false" script=""/>
<memberdata name="mmy" type="Property" display="mmY" favorites="false" override="false" script=""/>
<memberdata name="printablex" type="Property" display="PrintableX" favorites="false" override="false" script=""/>
<memberdata name="printabley" type="Property" display="PrintableY" favorites="false" override="false" script=""/>
<memberdata name="orientation" type="Property" display="Orientation" favorites="false" override="false" script=""/>
</VFPData>
*</PropValue>
PROCEDURE Init
declare integer GetLastError ;
in win32api
declare integer SetLastError ;
in win32api ;
integer i
declare integer CreateIC ;
in gdi32 ;
string lpszDriver, ;
string lpszDevice, ;
string lpszOutput, ;
string lpdvmInit
declare integer GetDeviceCaps ;
in gdi32 ;
integer hdc, ;
integer nIndex
declare integer DeleteDC ;
in gdi32 ;
integer hdc
return .T.
ENDPROC
PROCEDURE loaddeviceinfo && Parses out print device parameters into member properties given specific device information: Parameters: cDriver, cDevice, cDevMode. Assumes current VFP default printer if no parameters specified.
lparameters lcDriver, lcDevice, lcDEVMODE
THIS.errorMessage = ""
local lRetVal
lRetVal = .T.
if empty( m.lcDevice )
*---------------------------------------
* Use default printer settings:
*---------------------------------------
lcDriver = ""
lcDevice = set("PRINTER",3)
lcDEVMODE = ""
endif
try
local iHDC, vResult
iHDC = CreateIC( m.lcDriver, m.lcDevice, chr(0), m.lcDEVMODE )
if m.iHDC = 0
error CREATE_IC_FAILURE_LOC
else
THIS.LoadFromHDC( m.iHDC )
vResult = DeleteDC( m.iHDC )
endif
catch to oErr
THIS.errorMessage = oErr.message
lRetVal = .F.
endtry
return m.lRetVal
ENDPROC
PROCEDURE loadfromfrx && Loads printer device parameters from an FRX cursor header record. Restores recno and selected alias. Params: [ cFrxAlias ] (assumes "frx" if none specified.)
lparameter lcFrxAlias
THIS.errorMessage = ""
local curSel, curRec, lRetVal
store .F. to lRetVal
if empty(m.lcFrxAlias)
lcFrxAlias = "frx"
endif
if not used( m.lcFrxAlias )
return m.lRetVal
endif
*--------------------------------
* Save current data/cursor state:
*--------------------------------
curSel = select()
select (m.lcFrxAlias)
curRec = recno()
locate for PLATFORM="WINDOWS" and OBJTYPE = 1 and OBJCODE = 53
if found()
*---------------------------------------------------
* Get the device info settings:
*---------------------------------------------------
lRetVal = THIS.LoadFromStrings( EXPR, TAG2 )
endif
*---------------------------------------------------
* Restore data/cursor state:
*---------------------------------------------------
if m.curRec <= reccount()
go m.curRec
endif
select (m.curSel)
return m.lRetVal
ENDPROC
PROCEDURE loadfromhdc
lparameters tiHDC
#define HORZSIZE 4 && Horizontal size in millimeters
#define VERTSIZE 6 && Vertical size in millimeters
#define HORZRES 8 && Printable page width / Horizontal width in pixels
#define VERTRES 10 && Printable page length / Vertical height in pixels
#define LOGPIXELSX 88 && DPI / Logical pixels/inch in X dimension
#define LOGPIXELSY 90 && DPI / Logical pixels/inch in Y dimension
#define PHYSICALWIDTH 110 && Actual page width / Physical Width in device units
#define PHYSICALHEIGHT 111 && Actual page length / Physical Height in device units
#define PHYSICALOFFSETX 112 && Printable page left margin / Physical Printable Area x margin
#define PHYSICALOFFSETY 113 && Printable page top margin / Physical Printable Area y margin
with THIS
.dpiX = GetDeviceCaps( m.tiHDC, LOGPIXELSX )
.dpiY = GetDeviceCaps( m.tiHDC, LOGPIXELSY )
.OffsetX = GetDeviceCaps( m.tiHDC, PHYSICALOFFSETX )
.OffsetY = GetDeviceCaps( m.tiHDC, PHYSICALOFFSETY )
.PrintableX = GetDeviceCaps( m.tiHDC, HORZRES )
.PrintableY = GetDeviceCaps( m.tiHDC, VERTRES )
.mmX = GetDeviceCaps( m.tiHDC, HORZSIZE )
.mmY = GetDeviceCaps( m.tiHDC, VERTSIZE )
.ActualX = GetDeviceCaps( m.tiHDC, PHYSICALWIDTH )
.ActualY = GetDeviceCaps( m.tiHDC, PHYSICALHEIGHT )
endwith
return
ENDPROC
PROCEDURE loadfromstrings && Loads printer device parameters from string variables. Params: cExpr, cTag
lparameters tcEXPR, tcTAG2
local i, cLine, cDriver, lDriver, cDevice, lDevice
*---------------------------------------------------
* Read DRIVER and DEVICE values from EXPR
*---------------------------------------------------
for i = 1 to memlines(m.tcEXPR)
cLine = mline(m.tcEXPR,m.i)
do case
case m.cLine = "DRIVER=" and not m.lDriver
cDriver = substr(m.cLine,8)
lDriver = .T.
case m.cLine = "DEVICE=" and not m.lDevice
cDevice = substr(m.cLine,8)
lDevice = .T.
endcase
if m.lDevice and m.lDriver
exit
endif
endfor
*---------------------------------------------------
* Get the device info settings:
*---------------------------------------------------
return THIS.LoadDeviceInfo( m.cDriver, m.cDevice, m.tcTAG2 )
ENDPROC
ENDDEFINE