home *** CD-ROM | disk | FTP | other *** search
/ Total C++ 2 / TOTALCTWO.iso / vfp5.0 / vfp / tools / convert / convert.prg < prev    next >
Text File  |  1996-08-21  |  273KB  |  9,026 lines

  1. *- See C_CONVERSION_LOC in CONVERT.H for current version #
  2.  
  3. *- Visual FoxPro 3.0 Converter Utility
  4. *- (c) Microsoft Corporation 1995
  5. *-
  6. *-
  7. *- Developer Note:
  8. *-
  9. *- The following hidden properties are used in converted forms:
  10. *-
  11. *- 1)  ReleaseErase
  12. *- 
  13. *-     This is used by controls to indicate that when they are
  14. *- released, their image should remain on the form. Read uses this
  15. *- because when you do after a READ terminates, the images of the
  16. *- objects remain on the form.
  17. *- 
  18. *- 2)  ReleaseWindows
  19. *- 
  20. *-     This is used by converted forms to support the Release
  21. *- Windows checkbox in the generate or project manager dialog.
  22. *- 
  23. *- 3)  ErasePage
  24. *- 
  25. *-     Nested READs within a form are accomplished using "invisible"
  26. *- form pages.  When READ switches form pages, he doesn't want to erase
  27. *- the objects at the prior read level, so he makes the ErasePage
  28. *- property be false.
  29. *- 
  30. *- 
  31. *- Changes: Support for Macintosh (10/16/95 jd)
  32. *-          Support for Visual Foxpro 5.0 (05/16/96 jd)
  33. *-
  34.  
  35. #INCLUDE "convert.h"
  36.  
  37. PARAMETER pFilename,pFiletype,pVersion,pProgCall
  38.  
  39. *- pFileName:    fully qualified name of file to convert (C)
  40. *- pFileType:    type of file (C)
  41. *- pVersion:    version of file (C)
  42. *- pProgCall:    new param -- if .T., is being called from within another app (jd 07/25/96)
  43.  
  44. LOCAL i
  45.  
  46. PRIVATE gTransport            && which transporter to use
  47. PRIVATE gReturnVal            && name of file to return to VFP
  48. PRIVATE gLog                && accumulate log file info
  49. PRIVATE gError                && global error flag
  50. PRIVATE gAShowMe            && display transporter dialog?
  51. PRIVATE gOPJX                && PJX object
  52. PRIVATE gOMaster            && Master object
  53. PRIVATE gOTherm                && thermometer object
  54. PRIVATE giCallingProg        && index into PROGRAM()
  55.  
  56. gTransport = ""
  57. gReturnVal = -1
  58. gLog = ""
  59. gError = .F.
  60.  
  61. *- hold responses to transporter dialog
  62. DIMENSION gAShowMe[N_MAXTRANFILETYPES,9]
  63. FOR i = 1 TO N_MAXTRANFILETYPES
  64.     gAShowMe[i,1] = .T.        && show the dialog?
  65.     gAShowMe[i,2] = 1        && choice
  66.     gAShowMe[i,3] = ""        && font name
  67.     gAShowMe[i,4] = 0        && font size
  68.     gAShowMe[i,5] = ""        && font style
  69.     gAShowMe[i,6] = ""        && from platform
  70.     gAShowMe[i,7] = .T.        && convert new objects
  71.     gAShowMe[i,8] = .T.        && convert more recently modified objects
  72.     gAShowMe[i,9] = .T.        && replace all objects
  73. NEXT
  74.  
  75. gOPJX = .NULL.
  76. gOTherm = .NULL.
  77. giCallingProg = 0
  78.  
  79. DO CASE
  80.     CASE PARAMETERS() = 0
  81.         *- new feature for selectively converting 3.0 SCX and VCX files
  82.         m.pFileType = C_SCREENTYPEPARM
  83.         m.pFileName = ""
  84.         m.pVersion = C_30VERS
  85.     CASE PARAMETERS() == 3 AND PROGRAM(0) = "CONVERT"
  86.         *- okay -- classic mode of calling convert.app
  87.     CASE TYPE("pProgCall") == 'L' AND pProgCall
  88.         *- is being called from another program -- need to trap index into PROGRAM()
  89.         LOCAL i
  90.         FOR i = 1 TO 128
  91.             IF PROGRAM() == PROGRAM(i)
  92.                 giCallingProg = MAX(1,i - 1)
  93.                 EXIT
  94.             ENDIF
  95.         NEXT
  96.         *- note: if this fails (i.e., can;t locate current program in the PROGRAM()
  97.         *- array, giCallingProg will remain at 0 (MASTER)
  98.     OTHERWISE
  99.         *- called with wrong parameters
  100.         =MESSAGEBOX(E_BADCALL_LOC)
  101.         RETURN gReturnVal
  102. ENDCASE
  103.  
  104. IF SUBSTR(vers(),8,13) < C_LATESTVER
  105.     =MESSAGEBOX(E_BADFOX1_LOC + C_LATESTVER + E_BADFOX2_LOC)
  106.     RETURN gReturnVal
  107. ENDIF
  108.  
  109. IF EMPTY(_transport)
  110.     *- if not specified, use the built-in one
  111.     gTransport = "transprt"
  112. ELSE
  113.     IF FILE(_transport)
  114.         gTransport = _transport
  115.     ELSE
  116.         =MESSAGEBOX(E_NOTRANS_LOC)
  117.         RETURN
  118.     ENDIF
  119. ENDIF
  120.  
  121. gOMaster = CREATE("MasterConvert",m.pFilename,m.pFiletype,m.pVersion)
  122. IF TYPE("gOMaster") # "O"
  123.     *- error creating object, so fail
  124.     =MESSAGEBOX(E_NOSTART_LOC)
  125.     RETURN gReturnVal
  126. ENDIF
  127.  
  128. IF gOMaster.lHadError
  129.     *- problem with parms, or some other kind of initialization problem
  130.     =MESSAGEBOX(E_NOSTART_LOC)
  131. ELSE
  132.     gOMaster.DoConvert
  133. ENDIF
  134.  
  135. gOPJX = .NULL.
  136. gOTherm = .NULL.
  137. gOMaster = .NULL.
  138.  
  139. RELEASE gOTherm, gOPJX, gOMaster
  140.  
  141. IF gError
  142.     *- some kind of fatal error occurred, so clean up as best we can
  143.     *- CLEAR ALL
  144.     RETURN -1
  145. ENDIF
  146.  
  147. RETURN gReturnVal
  148.  
  149. *------------------------------------------------*
  150.  
  151.  
  152. **************************************************
  153. ******************* Classes **********************
  154. **************************************************
  155.  
  156. *************************************
  157. DEFINE CLASS Cvt AS custom
  158. *************************************
  159.     *- this class is a base class for all other classes
  160.     *- and provides for certain properties and methods they have in common
  161.  
  162.     lHadError = .F.
  163.     lLog = .F.                && log file?
  164.     cLogFile = ""            && the file to write the log to
  165.     lDevMode = .F.            && dev mode?
  166.     cCodeFile = ""            && cCodeFile
  167.     lLocalErr = .F.            &&
  168.     lHadLocErr = .F.
  169.     lShown1994 = .F.
  170.     cCurrentFile = ""        && the file currently being processed
  171.     dtStartTime = CTOT(DT_DFLTTIME)
  172.     dtEndTime = CTOT(DT_DFLTTIME)
  173.  
  174.     *------------------------------------
  175.     PROCEDURE Error                && Cvt
  176.     *------------------------------------
  177.         PARAMETER errorNum, method, line
  178.  
  179.         LOCAL iCtr, iFH, cErrMsg
  180.  
  181.         IF THIS.lLocalErr
  182.             *- enable testing for certain conditions without 
  183.             *- bringing down the house
  184.             THIS.lHadLocErr = .T.
  185.             RETURN
  186.         ENDIF
  187.             
  188.         *- turn off Escape
  189.         ON ESCAPE
  190.         SET ESCAPE OFF
  191.  
  192.         IF errorNum = 0
  193.             *- user pressed <escape>, and wants to cancel
  194.             cErrMsg = C_ESCLOGMSG_LOC
  195.         ELSE
  196.             ON ERROR m.err = .T.        && keep from returning here
  197.             cErrMsg = E_FATAL1_LOC + C_CRLF + ;
  198.                     E_ERR1_LOC + message() + C_CRLF + ;
  199.                     E_ERR2_LOC + ALLT(STR(m.Errornum)) + C_CRLF + ;
  200.                     E_ERR3_LOC + m.Method + C_CRLF + ;
  201.                     E_ERR5_LOC + message(1)+ C_CRLF + ;
  202.                     E_ERR6_LOC + IIF(EMPTY(THIS.cCurrentFile),E_ERR7_LOC,THIS.cCurrentFile)
  203.  
  204.         ENDIF
  205.  
  206.         THIS.lHadError = .T.
  207.  
  208.         *- force write an error to a logfile
  209.         IF EMPTY(THIS.cLogFile) AND errorNum # 0
  210.             *- not logging, so make up a name
  211.             THIS.cLogFile = SET("DEFA") + CURDIR() + C_ERRLOG_LOC + '.' + C_LOGEXT
  212.             iCtr = 1
  213.             DO WHILE FILE(THIS.cLogFile) AND m.iCtr < 99
  214.                 THIS.cLogFile = SET("DEFA") + CURDIR() + LEFT(C_ERRLOG_LOC,6) + RIGHT(STR(iCtr + 100),2) + '.' + C_LOGEXT
  215.                 m.iCtr = m.iCtr + 1
  216.             ENDDO
  217.         ENDIF
  218.  
  219.         *- open logfile
  220.         IF !EMPTY(THIS.cLogFile)
  221.             IF m.errornum == I_DISKFULLERR
  222.                 *- disk is full, so use MESSAGEBOX
  223.                 =MESSAGEBOX(E_DISKFULL_LOC)
  224.             ELSE
  225.                 iFH = FCREATE(THIS.cLogFile)
  226.                 IF iFH >= 0
  227.                     *- opened file okay
  228.                     *- add error info
  229.                     IF TYPE("glog") # 'C'
  230.                         *- something happened -- maybe the Transporter killed it
  231.                         gLog = ""
  232.                     ENDIF
  233.                     m.gLog = m.gLog + C_CRLF + m.cErrMsg + C_CRLF
  234.                     =FWRITE(iFH,m.gLog)
  235.                     =FCLOSE(iFH)
  236.                 ENDIF
  237.             ENDIF        && disk is full
  238.         ENDIF
  239.  
  240.         IF L_DEBUG AND L_DEBUGSUSPEND
  241.             ACTI WIND DEBUG
  242.             SUSPEND
  243.         ENDIF
  244.  
  245.         *- attempt to extricate from this mess
  246.         *- maybe the erring object was an object on a screen
  247.         DO CASE
  248.             CASE TYPE("THIS.formRef") = 'O'
  249.                 *- true if SCX Object
  250.                 THIS.formRef.Cleanup
  251.                 IF THIS.formRef.projCall
  252.                     *- the erring object was part of a project
  253.                     gOPJX.Cleanup
  254.                 ENDIF
  255.             CASE TYPE("THIS.projcall") = "L"
  256.                 *- true if a screen or report
  257.                 IF THIS.projCall
  258.                     gOPJX.Cleanup
  259.                 ELSE
  260.                     THIS.Cleanup
  261.                 ENDIF
  262.             OTHERWISE
  263.             *CASE TYPE("THIS.pjx25alias") = "C"
  264.                 *- true if a project
  265.                 THIS.Cleanup
  266.         ENDCASE
  267.         IF ErrorNum # 0
  268.             gOTherm = .NULL.
  269.             IF m.errornum # I_DISKFULLERR
  270.                 IF MESSAGEBOX(E_FATAL_LOC + E_FATAL2_LOC + SYS(2027,THIS.cLogFile) + E_FATAL3_LOC,MB_YESNO) = IDYES
  271.                     MODIFY FILE (THIS.cLogFile)
  272.                 ENDIF
  273.             ENDIF
  274.         ENDIF
  275.         gError = .T.
  276.         IF giCallingProg > 1
  277.             *- special case, if converter was called from within a program (jd 07/25/96)
  278.             LOCAL cCallingProg
  279.             cCallingProg = PROGRAM(giCallingProg)
  280.             RETURN TO &cCallingProg
  281.         ELSE
  282.             RETURN TO MASTER
  283.         ENDIF
  284.     
  285.     ENDPROC        &&  Error
  286.  
  287.     *------------------------------------
  288.     PROCEDURE WriteLog            && Cvt
  289.     *------------------------------------
  290.         PARAMETER cFileName,cAction
  291.  
  292.         *- changed to always accumulate log -- THIS.llog isn't always available! (jd 02/13/96)
  293.         m.gLog = m.gLog + UPPER(cFileName) + IIF(EMPTY(cAction),"",": " + cAction) + C_CRLF
  294.  
  295.     ENDPROC
  296.  
  297.     *------------------------------------
  298.     PROCEDURE BeginLog            && Cvt
  299.     *------------------------------------
  300.         PARAMETER cFileName
  301.  
  302.         THIS.dtStartTime = DATETIME()
  303.         THIS.WriteLog(m.cFileName,C_BEGIN_LOC + " " + TTOC(DATETIME()))
  304.  
  305.     ENDPROC
  306.  
  307.     *------------------------------------
  308.     PROCEDURE EndLog            && Cvt
  309.     *------------------------------------
  310.         PARAMETER cFileName
  311.  
  312.         THIS.dtEndTime = DATETIME()
  313.         THIS.WriteLog(SYS(2027,m.cFileName),C_END_LOC + ": " + TTOC(DATETIME()) + " " + ;
  314.             IIF(THIS.dtStartTime # CTOT(DT_DFLTTIME),"(" + C_SUCCESSCONV_LOC + LTRIM(STR(THIS.dtEndTime - THIS.dtStartTime)) + ;
  315.             C_SECONDS_LOC + ")",""))
  316.  
  317.     ENDPROC
  318.  
  319.  
  320.     *------------------------------------
  321.     PROCEDURE IsDBF                && Cvt
  322.     *------------------------------------
  323.     *- Check to see if the file can be opened as a DBF
  324.  
  325.         PARAMETER cFile
  326.  
  327.         LOCAL m.lDBF, m.savearea
  328.  
  329.         m.lDBF = .T.
  330.  
  331.         m.savearea = SELECT()
  332.         SELECT 0
  333.  
  334.         THIS.lLocalErr = .T.
  335.         USE (m.cFile) 
  336.         THIS.lLocalErr = .F.
  337.  
  338.         IF THIS.lHadLocErr
  339.             m.lDBF = .F.
  340.             THIS.lHadLocErr = .F.
  341.         ENDIF
  342.         USE
  343.  
  344.         SELECT (m.savearea)
  345.  
  346.         RETURN m.lDBF
  347.  
  348.     ENDPROC
  349.  
  350.     *------------------------------------
  351.     PROCEDURE GetPlatformCount
  352.     *------------------------------------
  353.         *- Get a list of the platforms in this file.
  354.         *- return in passed array
  355.  
  356.         PARAMETER cSCXFile, aPlatforms
  357.  
  358.         IF !FILE(cSCXFile) OR !Readable(m.cSCXFile) OR !THIS.IsDBF(cSCXFile)
  359.             *- We have a problem. Return and it will be sorted out later
  360.             RETURN
  361.         ENDIF
  362.  
  363.         USE (cSCXFile) ALIAS _temppct IN 0
  364.         SELECT DISTINCT platform ;
  365.             FROM _temppct ;
  366.             WHERE !DELETED() ;
  367.             INTO ARRAY aPlatforms
  368.  
  369.         USE IN _temppct
  370.  
  371.     ENDPROC
  372.  
  373.     *------------------------------------
  374.     FUNCTION GetPlatform        && ConverterBase
  375.     *------------------------------------
  376.         PARAMETER iPlatform
  377.         *- need to deal with creating files for other platforms than the current one
  378.         iPlatform = IIF(PARAMETERS() = 0, 1, iPlatform)
  379.         IF iPlatform = 1
  380.             DO CASE
  381.                 CASE _windows
  382.                     RETURN C_WINDOWS
  383.                 CASE _mac
  384.                     RETURN C_MAC
  385.                 CASE _dos
  386.                     RETURN C_DOS
  387.                 CASE _unix    
  388.                     RETURN C_UNIX
  389.             ENDCASE
  390.         ELSE
  391.             DO CASE
  392.                 CASE _windows
  393.                     RETURN C_MAC
  394.                 CASE _mac
  395.                     RETURN C_WINDOWS
  396.             ENDCASE
  397.         ENDIF
  398.     ENDFUNC
  399.  
  400.     *------------------------------------
  401.     PROCEDURE Cleanup            && Cvt
  402.     *------------------------------------
  403.         *- this proc is called by Error, and tries to put things back the way they were
  404.         *- this should be overridden, and given something to do
  405.     ENDPROC
  406.  
  407. ENDDEFINE
  408.  
  409. *************************************
  410. DEFINE CLASS MasterConvert AS Cvt
  411. *************************************
  412.     
  413.     *- Classes which can be replaced with others if
  414.     *- MasterConvert is sub-classed
  415.     scxConverterClass = "SCXSingleScreenConverter"
  416.     scx30ConverterClass = "SCX30Converter"
  417.     pjxConverterClass = "PJXConverter"
  418.     mnxConverterClass = ""
  419.     frxConverterClass = "FRXConverter"
  420.     fpcConverterClass = "FPCConverter"
  421.     db4ScrConverterClass = "DB4ScrConverter"
  422.     db4FrmConverterClass = "DB4FrmConverter"
  423.     db4LblConverterClass = "DB4LblConverter"
  424.     db4CatConverterClass = "DB4CatConverter"
  425.     db4QbeConverterClass = "DB4QbeConverter"
  426.     fmtConverterClass = "FmtConverter"
  427.     
  428.     *- Environment vars to save/restore
  429.     PROTECTED oldtalk, oldsafe, oldnotify, oldMess, oldmemowid,;
  430.         oldClass, oldProc, oldData, oldCompat, oldCollate, oldBlock,;
  431.         oldTrBe, oldFullPath, oldUDFParm, oldOnEscape, oldDevo, oldDebug,;
  432.         oldError, oldExact, oldDefault, oldKeyComp, oldCPDialog,;
  433.         oldPoint, oldSep, oldPath, oldLibr
  434.  
  435.     *- the SET() function here stores the default values, not the current settings!
  436.     oldtalk     = SET("TALK")
  437.     oldsafe     = SET("SAFETY")
  438.     oldescape   = SET("ESCAPE")
  439.     oldOnEscape    = ON("ESCAPE")
  440.     oldnotify   = SET("NOTIFY")
  441.     oldmess     = SET("MESSAGE",1)
  442.     oldmemowid  = SET("MEMOWIDTH")
  443.     oldClass    = SET("CLASS")
  444.     oldDefault    = SET("DEFA") + CURDIR()
  445.     oldProc     = SET("PROC")
  446.     oldData     = DBC()                        && remember full path to database (jd 04/15/96)
  447.     oldCompat   = SET("COMPATIBLE")
  448.     oldExclus   = SET("EXCLUSIVE")
  449.     oldCollate  = SET("COLLATE")
  450.     oldBlock    = SET("BLOCK")
  451.     oldTrBe     = SET("TRBE")
  452.     oldFullPath = SET("FULLPATH")
  453.     oldUDFParm  = SET("UDFP")
  454.     oldDevo        = SET("DEVE")
  455.     oldDebug    = SET("DEBUG")
  456.     oldError    = ON("ERROR")
  457.     oldExact    = SET("EXACT")
  458.     oldKeyComp    = SET("KEYCOMP")
  459.     oldCPDialog    = SET("CPDIALOG")
  460.     oldPoint    = SET("POINT")
  461.     oldSep        = SET("SEPARATOR")
  462.     oldPath        = SET("PATH")
  463.     oldLibr        = SET("LIBRARY")            && remember libraries -- may conflict with converter PROCs (jd 06/20/96)
  464.  
  465.     nCurrentWorkarea = 0
  466.     nNewWorkarea = 0
  467.     lUserCall = .T.                && converter was called by program vs. _CONVERTER
  468.  
  469.     cBackDir = ""                && backup directory for project conversions
  470.  
  471.     lHandled = .F.                && has it been dealt with?
  472.  
  473.     *- PARAMETERS and other settings
  474.     DIMENSION aConvParms[13]
  475.     aConvParms[ 1] = ""            && FP25 file name
  476.     aConvParms[ 2] = ""            && file type
  477.     aConvParms[ 3] = ""            && file version
  478.     aConvParms[ 4] = ""            && FP30 file name
  479.     aConvParms[ 5] = .T.        && platform only
  480.     aConvParms[ 6] = .F.        && special effect
  481.     aConvParms[ 7] = .F.        && developer mode
  482.     aConvParms[ 8] = ""            && code file if dev mode
  483.     aConvParms[ 9] = .F.        && create log file?
  484.     aConvParms[10] = ""            && logfile name
  485.     aConvParms[11] = .T.        && make backup
  486.     aConvParms[12] = 1            && only convert records for current platform
  487.     aConvParms[13] = 1            && which platform?
  488.  
  489.     *----------------------------------
  490.     PROCEDURE Init        && MasterConvert
  491.     *----------------------------------
  492.         PARAMETER pFilename, pFiletype, pVersion
  493.     
  494.         *- Check for program intercepted via FoxPro _CONVERTER
  495.         *- Note:  If you are subclassing converter, make sure 
  496.         *- to properly handle parameter.
  497.         *- Converter now supports no params, so only check for file if something was passed
  498.         IF PARAMETERS() = 3 AND TYPE('m.pFilename') = "C" ;
  499.           AND IIF(EMPTY(m.pFilename),.T.,FILE(m.pFilename)) AND ;
  500.           TYPE('m.pFiletype') = "C"
  501.             THIS.lUserCall = .F.
  502.             THIS.aConvParms[2] = m.pFiletype
  503.             THIS.aConvParms[3] = m.pVersion
  504.             THIS.aConvParms[4] = IIF(EMPTY(m.pFilename),"",SYS(2027,m.pFilename))            && use platform specific name
  505.         ELSE
  506.             *- incorrect set of parms passed
  507.             THIS.lHadError = .T.
  508.             RETURN
  509.         ENDIF
  510.  
  511.         THIS.nCurrentWorkarea = SELECT()
  512.         THIS.lUserCall = .T.                && converter was called by program vs. _CONVERTER
  513.  
  514.         *- values were set above
  515.                 
  516.         SET TALK OFF
  517.         SET SAFETY OFF
  518.         SET NOTIFY OFF
  519.         SET LIBRARY TO                        && close libraries -- may conflict with converter PROCs (jd 06/20/96)
  520.         
  521.  
  522.         IF L_SHOWVERSION
  523.             SET MESSAGE TO C_CONVERSION_LOC + IIF(L_DEBUG," -- DEBUGGING ON","")
  524.         ELSE
  525.             SET MESSAGE TO " "
  526.         ENDIF
  527.  
  528.         SET ESCAPE OFF
  529.  
  530.         SET PROCEDURE TO "foreign" ADDITIVE        && This has the subclasses for converting non-FoxPro files
  531.         SET PROCEDURE TO "conprocs" ADDITIVE
  532.  
  533.         SET MEMOWIDTH TO 256
  534.         SET COMPATIBLE OFF
  535.         SET EXCLUSIVE ON
  536.         SET COLLATE TO "MACHINE"
  537.         SET BLOCK TO N_BLOCKSZ
  538.         SET TRBETWEEN OFF
  539.         SET FULLPATH ON
  540.         SET UDFPARMS TO VALUE
  541.  
  542.         IF !L_DEBUG
  543.             SET DEVELOPMENT OFF
  544.             SET DEBUG OFF
  545.         ELSE
  546.             SET DEVELOPMENT ON
  547.             SET DEBUG ON
  548.         ENDIF
  549.  
  550.         SET EXACT OFF
  551.  
  552.         *- set KEYCOMP to appropriate platform
  553.         IF _mac
  554.             *SET KEYCOMP TO MAC
  555.         ELSE
  556.             SET KEYCOMP TO WINDOWS
  557.         ENDIF
  558.  
  559.         *- turn off code page conversion during conversion
  560.         SET CPDIALOG OFF
  561.  
  562.         ON ERROR
  563.  
  564.         *- for now, close data -- need to close only VFP databases when it;s working
  565.         IF !EMPTY(THIS.olddata)
  566.         *-    CLOSE DATABASE
  567.             SET DATABASE TO
  568.         ENDIF
  569.  
  570.         SET CLASS TO SprTherm ADDITIVE            && thermometer classes
  571.         SET CLASS TO CvtAlert ADDITIVE            && alert classes
  572.  
  573.         SET POINT TO '.'                        && RED00NXM -- prevent invalid values in spinners  (jd 04/15/95)
  574.         SET SEPARATOR TO ','
  575.  
  576.         SELECT 0
  577.         THIS.nNewWorkarea = SELECT()
  578.  
  579.     ENDPROC        &&  Init
  580.     
  581.     *----------------------------------
  582.     PROCEDURE Destroy
  583.     *----------------------------------
  584.         LOCAL cOld
  585.  
  586.         IF THIS.oldsafe = "ON"
  587.             SET SAFETY ON
  588.         ENDIF
  589.  
  590.         IF THIS.oldnotify = "ON"
  591.             SET NOTIFY ON
  592.         ENDIF
  593.  
  594.         IF EMPTY(THIS.oldmess)
  595.             SET MESSAGE TO
  596.         ELSE
  597.             SET MESSAGE TO THIS.oldmess
  598.         ENDIF
  599.  
  600.         IF THIS.oldtalk= "ON"
  601.             SET TALK ON
  602.         ENDIF
  603.  
  604.         SET MEMOWIDTH TO (THIS.oldmemowid)
  605.  
  606.         m.cOld = THIS.oldOnEscape
  607.         ON ESCAPE &cOld
  608.  
  609.         m.cOld = THIS.oldescape
  610.         SET ESCAPE &cOld
  611.  
  612.         m.cOld = THIS.oldCompat
  613.         SET COMPATIBLE &cOld
  614.  
  615.         m.cOld = THIS.oldExclus
  616.         SET EXCLUSIVE &cOld
  617.  
  618.         SET BLOCK TO THIS.oldBlock
  619.         SET COLLATE TO THIS.oldCollate
  620.  
  621.         m.cOld = THIS.OldClass
  622.         SET CLASS TO &cOld
  623.  
  624.         SET DEFAULT TO (THIS.oldDefault)
  625.  
  626.         IF "FOREIGN" $ SET("PROCEDURE")
  627.             RELEASE PROCEDURE foreign
  628.         ENDIF
  629.         IF "CONPROCS" $ SET("PROCEDURE")
  630.             RELEASE PROCEDURE conprocs
  631.         ENDIF
  632.  
  633.         m.cOld = THIS.oldTrbe
  634.         SET TRBETWEEN &cOld
  635.  
  636.         m.cOld = THIS.oldFullPath
  637.         SET FULLPATH &cOld
  638.  
  639.         m.cOld = THIS.oldUDFParm
  640.         SET UDFPARMS TO &cOld
  641.  
  642.         m.cOld = THIS.oldDevo
  643.         SET DEVELOPMENT &cOld    &&crashes build 4.104
  644.  
  645.         m.cOld = THIS.oldDebug
  646.         SET DEBUG &cOld
  647.  
  648.         m.cOld = THIS.oldExact
  649.         SET EXACT &cOld
  650.  
  651.         m.cOld = THIS.oldKeyComp
  652.         SET KEYCOMP TO &cOld
  653.  
  654.         m.cOld = THIS.oldCPDialog
  655.         SET CPDIALOG &cOld
  656.  
  657.         SET POINT TO (THIS.oldPoint)        && reset these values (jd 04/15/96)
  658.         SET SEPARATOR TO (THIS.oldSep)
  659.  
  660.         m.cOld = THIS.oldPath                && restore path, in case we changed it (jd 06/11/96)
  661.         SET PATH TO &cOld
  662.         
  663.         m.cOld = THIS.oldLibr                && remember libraries -- may conflict with converter PROCs (jd 06/20/96)
  664.         SET LIBRARY TO &cOld
  665.         
  666.         m.cOld = THIS.oldError
  667.         ON ERROR &cOld
  668.  
  669.         IF !EMPTY(THIS.olddata)                && restore database (jd 04/15/96)
  670.             OPEN DATABASE (THIS.olddata)
  671.         ENDIF
  672.  
  673.         SELECT (THIS.nCurrentWorkarea)
  674.  
  675.     ENDPROC        &&  Masterconvert:Destroy
  676.  
  677.  
  678.     *----------------------------------
  679.     PROCEDURE DoConvert        && masterconvert
  680.     *----------------------------------
  681.         PRIVATE g_platforms
  682.         PRIVATE aParms, oConvObject
  683.         PRIVATE g_platforms
  684.         PRIVATE cConvType
  685.         
  686.  
  687.         *- needed for GENSCRN stuff
  688.         DIMENSION g_platforms[1]
  689.         g_platforms = ""
  690.  
  691.         *- THIS.aConvParms[2] = m.pFiletype
  692.         *- THIS.aConvParms[3] = m.pVersion
  693.         *- THIS.aConvParms[4] = m.pFilename
  694.  
  695.         m.cConvType = THIS.aConvParms[2]
  696.         
  697.         DO CASE
  698.             CASE m.cConvType = C_SCREENTYPEPARM AND THIS.aConvParms[3] = C_30VERS AND ;
  699.                 EMPTY(THIS.aConvParms[4])
  700.                 *- new option (6/10/96) -- converter was called with no parameters, so show dialog
  701.                 *- for selecting SCX and VCX files, for conversion
  702.                 *- get the file or folder to update
  703.                 
  704.                 
  705.                 m.iFileDir = 1
  706.                 m.cFile = ""
  707.                 m.lSCX = .T.
  708.                 m.lVCX = .T.
  709.                 m.lRecurse = .F.
  710.                 
  711.                 *- note: we use aParms[12] to hold the lSet30Defaults value
  712.                 
  713.                 IF !THIS.GetOpts("cvtdlog30scx",C_SELECTFILE_LOC)
  714.                     RETURN
  715.                 ENDIF
  716.  
  717.                 THIS.aConvParms[1] = ""            && this was filled in by GetOpts -- clear so it causes no problems later
  718.  
  719.                 gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  720.                     C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  721.                 IF THIS.aConvParms[12] > 1
  722.                     gOTherm.Update(0)
  723.                 ENDIF
  724.                 
  725.                 *- if only doing a file, we don;t care about these values
  726.                 lSCX = IIF(iFileDir == 1,.T.,lSCX)
  727.                 lVCX = IIF(iFileDir == 1,.T.,lVCX)
  728.                 
  729.                 UpdateSCX(m.cFile, lRecurse)        && in ConProcs.PRG
  730.                 
  731.             CASE m.cConvType = C_SCREENTYPEPARM AND THIS.aConvParms[3] = C_30VERS
  732.                 *- a 3.0 SCX or VCX -- we need to re-compile, and maybe
  733.                 *- set properties that match VFP 3.0 defaults
  734.  
  735.                 *- verify user wants to convert
  736.                 IF !THIS.GetOpts("cvtalert30scx",C_CONVERT1_LOC + PARTIALFNAME(THIS.aConvParms[4],C_FILELEN) + C_CONVERT2_LOC)
  737.                     RETURN
  738.                 ENDIF
  739.  
  740.                 THIS.aConvParms[1] = ""            && this was filled in by GetOpts -- clear so it causes no problems later
  741.  
  742.                 gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  743.                     C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  744.                 IF THIS.aConvParms[12] > 1
  745.                     gOTherm.Update(0)
  746.                 ENDIF
  747.  
  748.                 =ACOPY(THIS.aConvParms,aParms)
  749.                 oConvObject = CREATE(THIS.scx30ConverterClass, @aParms, .T.)
  750.  
  751.                 IF TYPE("oConvObject") # 'O'
  752.                     *- object was not created
  753.                     THIS.lHadError = .T.
  754.                     gReturnVal = -1
  755.                     RETURN
  756.                 ENDIF
  757.  
  758.                 IF oConvObject.lHadError
  759.                     *- error creating converter object: 
  760.                     *- assume error has already been presented to user
  761.                     THIS.lHadError = .T.
  762.                     RELEASE oConvObject
  763.                     gReturnVal = -1
  764.                     RETURN
  765.                 ENDIF
  766.  
  767.                 gReturnVal = oConvObject.Converter()
  768.  
  769.                 RELEASE oConvObject
  770.  
  771.             CASE m.cConvType = C_SCREENTYPEPARM
  772.             
  773.                 *- determine number of platforms
  774.                 DIMENSION aPlatforms[1]
  775.                 aPlatforms[1] = ""
  776.                 THIS.GetPlatformCount(THIS.aConvParms[4], @aPlatforms)
  777.                 IF EMPTY(aPlatforms[1])
  778.                     *- was unable to determine platforms
  779.                     RETURN
  780.                 ENDIF
  781.                 IF ALEN(aPlatforms,1) > 1
  782.                     IF ASCAN(aPlatforms,C_WINDOWS) > 0 AND ASCAN(aPlatforms,C_MAC) > 0
  783.                         *- both platforms are there
  784.                         THIS.aConvParms[12] = 2
  785.                     ENDIF
  786.                 ENDIF
  787.  
  788.                 *- verify user wants to convert
  789.                 IF !THIS.GetOpts("cvtalertscx",C_CONVERT1_LOC + PARTIALFNAME(THIS.aConvParms[4],C_FILELEN) + C_CONVERT2_LOC)
  790.                     RETURN
  791.                 ENDIF
  792.  
  793.                 THIS.aConvParms[1] = ""            && this was filled in by GetOpts -- clear so it causes no problems later
  794.  
  795.                 gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  796.                     C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  797.                 gOTherm.Update(0)
  798.  
  799.                 *- of both platforms are present, and user wants to convert both,
  800.                 *- need to create two files
  801.                 FOR kPlat = 1 TO THIS.aConvParms[12]
  802.  
  803.                         =ACOPY(THIS.aConvParms,aParms)
  804.  
  805.                         aParms[13] = m.kPlat
  806.  
  807.                         oConvObject = CREATE(THIS.scxConverterClass, @aParms, (kPlat == 1))    && only back up first time around
  808.  
  809.                         IF TYPE("oConvObject") # 'O'
  810.                             *- object was not created
  811.                             THIS.lHadError = .T.
  812.                             gReturnVal = -1
  813.                         RETURN
  814.                     ENDIF
  815.                     
  816.                     IF oConvObject.lHadError
  817.                         *- error creating converter object: 
  818.                         *- assume error has already been presented to user
  819.                         THIS.lHadError = .T.
  820.                         RELEASE oConvObject
  821.                         gReturnVal = -1
  822.                         RETURN
  823.                     ENDIF
  824.  
  825.                     gReturnVal = oConvObject.Converter()
  826.  
  827.                     RELEASE oConvObject
  828.  
  829.                 NEXT
  830.  
  831.                 IF TYPE(gReturnVal) == "C"
  832.                     *- successful conversion
  833.                     *- if multiple platforms, return form name for the current platform
  834.                     IF THIS.aConvParms[12] > 1 AND _mac
  835.                         gReturnVal = JustStem(gReturnVal) + C_MACEXT + "." + JustExt(gReturnVal)
  836.                     ENDIF
  837.                 ENDIF
  838.  
  839.                 SET MESSAGE TO C_PROJTASK1_LOC
  840.  
  841.  
  842.                 lHandled = .T.            && it's been dealt with?
  843.  
  844.  
  845.             CASE m.cConvType = C_PROJECTTYPEPARM OR ;
  846.                     m.cConvType = C_CATALOGTYPEPARM
  847.                 *- a project or catalog
  848.  
  849.                 LOCAL theClass, cFileType, lMakeBackDir, cobjname, cCvtMsg
  850.                 PRIVATE cFileName
  851.  
  852.                 cFileName = THIS.aConvParms[4]
  853.                 lMakeBackDir = .T.
  854.  
  855.                 *- always show "both platforms" option if project...
  856.                 THIS.aConvParms[12] = 2
  857.                 
  858.                 cCvtMsg = C_CONVERT4_LOC
  859.  
  860.                 DO CASE
  861.                     CASE m.cConvType = C_PROJECTTYPEPARM AND THIS.aConvParms[3] = "3.0"
  862.                         *- FP 3.x project
  863.                         m.theClass = THIS.pjxConverterClass
  864.                         m.cFileType = C_CONVERT3p_LOC
  865.                         m.cobjname = "cvtalertpjx3"
  866.                         cCvtMsg = C_CONVERT2_LOC
  867.                     CASE m.cConvType = C_PROJECTTYPEPARM
  868.                         *- FP 2.x project
  869.                         m.theClass = THIS.pjxConverterClass
  870.                         m.cFileType = C_CONVERT3p_LOC
  871.                         m.cobjname = "cvtalertpjx"
  872.                     CASE m.cConvType = C_CATALOGTYPEPARM AND THIS.aConvParms[3] = C_FOXVERSIONPARM
  873.                         *- FP 2.6 catalog
  874.                         m.theClass = THIS.fpcConverterClass
  875.                         m.cFileType = C_CONVERT3c_LOC
  876.                         m.cobjname = "cvtalertpjx"
  877.                     CASE m.cConvType = C_CATALOGTYPEPARM AND THIS.aConvParms[3] = C_DB4VERSIONPARM
  878.                         *- dBASE IV catalog
  879.                         lMakeBackDir = .F.
  880.                         m.theClass = THIS.db4CatConverterClass
  881.                         m.cFileType = C_CONVERT3c_LOC
  882.                         m.cobjname = "cvtalertcat"
  883.                     OTHERWISE
  884.                         *- ? error -- bad parm
  885.                         RETURN
  886.                 ENDCASE
  887.  
  888.                 *- verify user wants to convert
  889.                 IF !THIS.GetOpts(m.cobjname, C_CONVERT3_LOC + m.cFileType + PARTIALFNAME(SYS(2027,pFileName),C_FILELEN) + m.cCvtMsg)
  890.                     RETURN
  891.                 ENDIF
  892.  
  893.                 m.gOTherm = CREATEOBJ(C_THERMCLASS2,C_THERMTITLE_LOC, "", 0, 0,;
  894.                     C_THERMMSG1_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  895.                 gOTherm.Update(0)
  896.  
  897.                 =ACOPY(THIS.aConvParms,aParms)
  898.                 oConvObject = CREATE(m.theClass, @aParms)
  899.  
  900.                 IF TYPE("oConvObject") # 'O' OR THIS.lHadError
  901.                     *- object was not created
  902.                     THIS.lHadError = .T.
  903.                     RETURN
  904.                 ENDIF
  905.                 
  906.                 IF oConvObject.lHadError
  907.                     *- error creating converter object: 
  908.                     *- assume error has already been presented to user
  909.                     THIS.lHadError = .T.
  910.                     RELEASE oConvObject
  911.                     RETURN
  912.                 ENDIF
  913.  
  914.                 SET MESSAGE TO C_PROJTASK4_LOC
  915.  
  916.                 gReturnVal = oConvObject.Converter()
  917.  
  918.                 RELEASE oConvObject
  919.  
  920.                 lHandled = .T.            && it's been dealt with?
  921.                 
  922.             CASE m.cConvType = C_REPORTTYPEPARM
  923.  
  924.                 *- verify user wants to convert
  925.                 IF !THIS.GetOpts("cvtalertfrx",C_CONVERT3_LOC + ;
  926.                     IIF(JUSTEXT(THIS.aConvParms[4]) = "LBX",C_CONVERT3l_LOC,C_CONVERT3r_LOC) + ;
  927.                     PARTIALFNAME(THIS.aConvParms[4],C_FILELEN) + C_CONVERT2_LOC)
  928.                     RETURN
  929.                 ENDIF
  930.  
  931.                 THIS.aConvParms[1] = ""            && this was filled in by GetOpts -- clear so it causes no problems later
  932.                 =ACOPY(THIS.aConvParms,aParms)
  933.  
  934.                 gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  935.                     C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  936.                 gOTherm.Update(0)
  937.  
  938.                 oConvObject = CREATE(THIS.frxConverterClass, @aParms, .T.)
  939.  
  940.                 IF TYPE("oConvObject") # 'O'
  941.                     *- object was not created
  942.                     THIS.lHadError = .T.
  943.                     RETURN
  944.                 ENDIF
  945.                 
  946.                 IF oConvObject.lHadError
  947.                     *- error creating converter object: 
  948.                     *- assume error has already been presented to user
  949.                     oConvObject = .NULL.
  950.                     RELEASE oConvObject
  951.                     THIS.lHadError = .T.
  952.                     RETURN
  953.                 ENDIF
  954.                 
  955.                 IF oConvObject.lConverted
  956.                     *- file was transported from one 3.0 platform to another
  957.                     gReturnVal = oConvObject.cFRX2files
  958.                     RETURN
  959.                 ENDIF
  960.  
  961.                 SET MESSAGE TO C_PROJTASK2_LOC
  962.  
  963.                 gReturnVal = oConvObject.Converter()
  964.  
  965.                 RELEASE oConvObject
  966.  
  967.                 lHandled = .T.            && it's been dealt with?
  968.  
  969.             
  970.             CASE m.cConvType = C_LABELTYPEPARM
  971.             
  972.             CASE m.cConvType = C_MENUTYPEPARM
  973.             
  974.             CASE m.cConvType = C_DB4QUERYTYPEPARM
  975.             
  976.             CASE m.cConvType = C_DB4FORMTYPEPARM
  977.             
  978.             CASE m.cConvType = C_DB4REPORTTYPEPARM
  979.             
  980.             CASE m.cConvType = C_DB4LABELTYPEPARM
  981.             
  982.             CASE m.cConvType = C_FMTTYPEPARM
  983.                         
  984.                 m.gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  985.                     C_THERMMSG3_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  986.                 gOTherm.Update(0)
  987.  
  988.                 =ACOPY(THIS.aConvParms,aParms)
  989.                 oConvObject = CREATE(THIS.fmtConverterClass, @aParms)
  990.                 IF TYPE("oConvObject") # 'O'
  991.                     *- object was not created
  992.                     THIS.lHadError = .T.
  993.                     RETURN
  994.                 ENDIF
  995.                 
  996.                 IF oConvObject.lHadError
  997.                     *- error creating SCX object: 
  998.                     *- assume error has already been presented to user
  999.                     THIS.lHadError = .T.
  1000.                     RELEASE oConvObject
  1001.                     RETURN
  1002.                 ENDIF
  1003.  
  1004.                 gReturnVal = oConvObject.Converter()
  1005.  
  1006.                 RELEASE oConvObject
  1007.  
  1008.                 lHandled = .T.            && it's been dealt with?
  1009.  
  1010.             CASE m.cConvType = C_FPLUSFRXTYPEPARM
  1011.             
  1012.  
  1013.         ENDCASE
  1014.  
  1015.     ENDPROC        &&  DoConvert
  1016.  
  1017.     *----------------------------------
  1018.     FUNCTION GetOpts        && masterconvert
  1019.     *----------------------------------
  1020.         *- display confirmation dialog, with options
  1021.         PARAMETER objname,cMsg
  1022.  
  1023.         PRIVATE oAlert, cBackDir, cLogFile, cCodeFile, lLog, lDevMode, lBackUp
  1024.         PRIVATE nOptDev, nCvt, iPlatformCount
  1025.  
  1026.         STORE "" TO cBackDir, cLogFile, cCodeFile
  1027.         STORE .F. TO lLog, lDevMode
  1028.         lBackup = .T.
  1029.         iBothPlat = 0
  1030.  
  1031.         m.cBackDir = ADDBS(JUSTPATH(THIS.aConvParms[4]))
  1032.  
  1033.         nOptDev = 1
  1034.         nCvt = 0
  1035.         oAlert = CREATEOBJ(m.objname,cMsg)
  1036.         IF TYPE("oAlert.chkBothPlat") == "O"
  1037.             oAlert.chkBothPlat.Enabled = (THIS.aConvParms[12] > 1)
  1038.         ENDIF
  1039.         IF TYPE("oAlert.chkSet30Def") == "O"
  1040.             oAlert.chkSet30Def.Enabled = .T.
  1041.         ENDIF
  1042.         oAlert.Show
  1043.         oAlert = .NULL.
  1044.         RELEASE oALert
  1045.         IF m.nCvt # 1
  1046.             RETURN .F.
  1047.         ENDIF
  1048.         THIS.aConvParms[ 7] = m.lDevMode        && developer mode
  1049.         THIS.aConvParms[ 8] = m.cCodeFile        && code file if dev mode
  1050.         THIS.aConvParms[ 9] = m.llog            && create log file?
  1051.         THIS.aConvParms[10] = m.cLogFile        && logfile name
  1052.         THIS.aConvParms[ 1] = m.cBackDir        && backup directory
  1053.         THIS.aConvParms[11] = m.lBackup            && make backup
  1054.         THIS.aConvParms[12] = m.iBothPlat + 1    && only convert screen records for current platform
  1055.     ENDFUNC
  1056.  
  1057.     *----------------------------------
  1058.     FUNCTION GetVersion
  1059.     *----------------------------------
  1060.         RETURN C_CONVERSION_LOC
  1061.  
  1062.     ENDFUNC
  1063.  
  1064.         
  1065. ENDDEFINE        &&  MasterConvert
  1066.  
  1067.  
  1068. **********************************************
  1069. DEFINE CLASS ConverterBase AS Cvt
  1070. **********************************************
  1071. *- This is the abstract base class for all converter 
  1072. *- objects. A converter object converts a particular
  1073. *- item, e.g., a project, a screen, etc.
  1074.  
  1075.     *- global instance variables
  1076.     nTimeStamp = 0 
  1077.  
  1078.     old25file = ""            && old 2.5 file name
  1079.     c25alias = ""            && old 2.5/2.6 alias
  1080.     cNew30File = ""            && new 3.0 file name
  1081.     new30alias = ""            && new 3.0 file alias  (or 4.0 for PJX)
  1082.  
  1083.     platonly = ""            && platform only option (Windows)
  1084.     oldfiletype = ""        && file type
  1085.     oldfilever = ""            && file version
  1086.     platform = C_ALL        && platform name
  1087.  
  1088.     cSetSkip = ""            && SET SKIP TO commands
  1089.     lAutoOpen = .F.            && Auto open tables in dataenvironment?
  1090.     lAutoClose = .F.        && Auto close tables in dataenvironment?
  1091.  
  1092.     lTransDlog = .F.        && Force the transporter dialog to show
  1093.  
  1094.     DIMENSION a_dimes[1]    && arrays that need to be "externalized"
  1095.     a_dimes = ""
  1096.  
  1097.     *- these are used by most of the children, so put here
  1098.     nDeffont1 = 1     && default screen FONT(1) -- height
  1099.     nDeffont5 = 0     && default screen FONT(5) -- extra leading
  1100.     nDeffont6 = 1     && default screen FONT(1) -- width
  1101.     cDefcolor = ""    && default background color
  1102.  
  1103.     nRecCount = 0
  1104.     nTmpCount = 1
  1105.  
  1106.     lBackup = .F.                && backup files (as .S2X, .S2T)
  1107.     iPlatformCount = 1            && only convert records for current platform
  1108.  
  1109.     *------------------
  1110.     PROCEDURE PreForm
  1111.     *------------------
  1112.         *- this is an external hook to preprocess
  1113.         *- form object via subclassing
  1114.     ENDPROC
  1115.  
  1116.     *------------------
  1117.     PROCEDURE PostForm
  1118.     *------------------
  1119.         *- this is an external hook to postprocess
  1120.         *- form object via subclassing
  1121.         
  1122.     ENDPROC
  1123.  
  1124.     *------------------------------------
  1125.     FUNCTION TStamp
  1126.     *------------------------------------
  1127.         * Generates a FoxPro 2.5-style timestamp
  1128.         PARAMETER wzpdate,wzptime
  1129.         PRIVATE d,t
  1130.  
  1131.         m.d = IIF(EMPTY(m.wzpdate),DATE(),m.wzpdate)
  1132.         m.t = IIF(EMPTY(m.wzptime),TIME(),m.wzptime)
  1133.  
  1134.         RETURN ((YEAR(m.d)-1980) * 2 ** 25);
  1135.          + (MONTH(m.d)           * 2 ** 21);
  1136.          + (DAY(m.d)             * 2 ** 16);
  1137.          + (VAL(LEFT(m.t,2))     * 2 ** 11);
  1138.          + (VAL(SUBSTR(m.t,4,2)) * 2 **  5);
  1139.          +  VAL(RIGHT(m.t,2))
  1140.     ENDFUNC        &&  TStamp
  1141.     
  1142.     *---------------------------
  1143.     FUNCTION AddQuotes
  1144.     *---------------------------
  1145.         PARAMETER pstring
  1146.         DO CASE
  1147.         CASE AT('"',m.pstring) = 0
  1148.             RETURN '"' + m.pstring + '"'    
  1149.         CASE AT("'",m.pstring) = 0
  1150.             RETURN "'" + m.pstring + "'"    
  1151.         OTHERWISE
  1152.             RETURN '[' + m.pstring + ']'    
  1153.         ENDCASE
  1154.     ENDFUNC
  1155.  
  1156.     *---------------------------
  1157.     FUNCTION AddProp
  1158.     *---------------------------
  1159.  
  1160.         *- Adds property to property list
  1161.         *- Converts if necessary
  1162.         *- Parameters:
  1163.         *-    fp30prop - property name
  1164.         *-    fp25fld - 2.5 field contents
  1165.         *-    fp30parent - parent reference (optional if needed)
  1166.         PARAMETER fp30prop,fp25fld,fp30parent
  1167.  
  1168.         IF INLIST(m.fp30prop,;
  1169.                     M_BACKCOLOR,;
  1170.                     M_MODE,;
  1171.                     M_PENSIZE,;
  1172.                     M_FONTBOLD)
  1173.             IF THIS.IsDefault(fp30prop,m.fp25fld)
  1174.                 RETURN
  1175.             ENDIF
  1176.         ENDIF
  1177.  
  1178.         DO CASE
  1179.             CASE EMPTY(m.fp30prop)
  1180.                 RETURN
  1181.                 
  1182.             CASE TYPE('m.fp25fld') = "C"
  1183.                 DO CASE
  1184.                     CASE LEN(m.fp25fld)=0
  1185.                         RETURN
  1186.                     CASE INLIST(m.fp30prop,;
  1187.                         M_PEN,;
  1188.                         M_BACKCOLOR,;
  1189.                         M_FILLCOLOR,;
  1190.                         M_DISFORECOLOR,;
  1191.                         M_DISBACKCOLOR,;
  1192.                         M_ITEMFORECOLOR,;
  1193.                         M_ITEMBACKCOLOR,;
  1194.                         M_DISITEMFORECOLOR,;
  1195.                         M_DISITEMBACKCOLOR,;
  1196.                         M_SELITEMBACKCOLOR,;
  1197.                         M_BORDERCOLOR,;
  1198.                         M_FPICTURE,;
  1199.                         M_ICON)
  1200.                         m.fp25fld = ALLTRIM(m.fp25fld)
  1201.                     CASE INLIST(m.fp30prop,;
  1202.                         M_FONTFACE,;
  1203.                         M_NAME,;
  1204.                         M_DATASOURCE,;
  1205.                         M_ALIAS,;
  1206.                         M_ORDER,;
  1207.                         M_CHILDALIAS,;
  1208.                         M_CHILDINDEXTAG,;
  1209.                         M_PARENTALIAS,;
  1210.                         M_PARENTINDEXEXPR,;
  1211.                         M_INITIALALIAS,;
  1212.                         M_ASSOCWINDS)
  1213.                         *- catch indirect references here
  1214.                           m.fp25fld = IIF(LEFT(ALLTRIM(m.fp25fld),1) = "(",;
  1215.                               ALLTRIM(m.fp25fld),;
  1216.                               THIS.addquotes(ALLTRIM(m.fp25fld)))
  1217.                     CASE INLIST(m.fp30prop,;
  1218.                             M_CURSORSRC)
  1219.                         m.fp25fld = ALLTRIM(m.fp25fld)
  1220.                     CASE INLIST(m.fp30prop,;
  1221.                             M_CAPTION,;
  1222.                             M_VALUE) AND LEFT(m.fp25fld,1) $ ["'[]
  1223.                         *- an expression in a label/say
  1224.                         *- or a value that needs parens
  1225.                         m.fp25fld = "(" + ALLTRIM(m.fp25fld) + ")"
  1226.                     CASE INLIST(m.fp30prop,;
  1227.                             M_CAPTION) OR AT(LEFT(m.fp25fld,1),["'[]) # 0
  1228.                         m.fp25fld = ALLTRIM(m.fp25fld)
  1229.                     OTHERWISE
  1230.                         m.fp25fld = "(" + ALLTRIM(m.fp25fld) + ")"
  1231.                 ENDCASE
  1232.             CASE TYPE('m.fp25fld') = "N"
  1233.                 m.fp25fld= ALLTRIM(STR(m.fp25fld))
  1234.             CASE TYPE('m.fp25fld') = "L"
  1235.                 m.fp25fld= IIF(m.fp25fld,".T.",".F.")
  1236.             CASE TYPE('m.fp25fld') = "D"
  1237.                 m.fp25fld= "{" + DTOC(m.fp25fld) + "}"
  1238.         ENDCASE
  1239.         
  1240.         IF TYPE('m.fp30parent')='C' AND !EMPTY(m.fp30parent)
  1241.             m.fp30prop = m.fp30parent + "." + m.fp30prop
  1242.         ENDIF
  1243.  
  1244.         IF LEN(m.fp25Fld) > 254        && RED00N4G
  1245.             *- changed action here -- now logs error and continues on
  1246.             THIS.WriteLog(E_WARNING_LOC,E_PROPTOOLONG_LOC + ALLTRIM(STR(recno())))
  1247.             IF TYPE("oForm.cCurrentFile") == 'C'
  1248.                 =MESSAGEBOX(E_WARNING_LOC + " - " + E_PROPTOOLONG_LOC + ALLTRIM(STR(recno())) + ;
  1249.                 ', ' + ALLT(oForm.cCurrentFile) + '.' + E_EXPRNOCONV_LOC + E_SEELOGFILE_LOC)
  1250.             ELSE
  1251.                 =MESSAGEBOX(E_WARNING_LOC + " - " + E_PROPTOOLONG_LOC + ALLTRIM(STR(recno())) + '.' + ;
  1252.                 E_EXPRNOCONV_LOC+ E_SEELOGFILE_LOC)
  1253.             ENDIF
  1254.             *- oForm.lHadError = .T.
  1255.             RETURN
  1256.         ENDIF
  1257.         
  1258.         THIS.fp3prop = THIS.fp3prop + ;
  1259.             m.fp30prop + C_SEP + m.fp25fld + C_CRLF
  1260.  
  1261.         RETURN
  1262.         
  1263.     ENDFUNC        && AddProp
  1264.     
  1265.     *---------------------------
  1266.     FUNCTION IsDefault
  1267.     *---------------------------
  1268.         PARAMETER cProp,cValue
  1269.  
  1270.         DO CASE
  1271.             CASE TYPE('m.cValue') = "N"
  1272.                 m.cValue = ALLT(STR(cValue))
  1273.             CASE TYPE('m.cValue') = "L"
  1274.                 m.cValue = IIF(cValue,".T.",".F")
  1275.         ENDCASE
  1276.  
  1277.         DO CASE
  1278.             CASE cProp = M_BACKCOLOR
  1279.                 RETURN .F.
  1280.                 *RETURN (cValue == "255,255,255")
  1281.             CASE cProp = M_MODE
  1282.                 RETURN (cValue == "1")
  1283.             CASE cProp = M_PENSIZE
  1284.                 RETURN (cValue == "1")
  1285.             CASE cProp = M_FONTBOLD
  1286.                 RETURN (cValue == ".T.")
  1287.             OTHERWISE
  1288.                 RETURN .F.
  1289.         ENDCASE
  1290.  
  1291.     ENDFUNC
  1292.  
  1293.     *---------------------------
  1294.     FUNCTION ClearProp
  1295.     *---------------------------
  1296.         *- clear accumulated properties
  1297.         THIS.fp3prop = ""
  1298.         
  1299.     ENDFUNC        && ClearProp
  1300.  
  1301.     *------------------------------------
  1302.     FUNCTION AddMethods            && ConverterBase
  1303.     *------------------------------------
  1304.         PARAMETER newmethod,fp25fld,ctype,newprop
  1305.         *- newmethod - method if procedure
  1306.         *- ctype= 0 -> Expression
  1307.         *- ctype= 1 -> Proc
  1308.         *- newprop - property if expression
  1309.         *- if newprop empty used newmethod
  1310.  
  1311.         LOCAL cTmp, savearea, gendir, m.newmethod2, m.gendircount
  1312.  
  1313.  
  1314.         IF EMPTY(ALLT(m.fp25fld))
  1315.           RETURN
  1316.         ENDIF
  1317.  
  1318.         IF m.ctype = 0    && expression used
  1319.             IF PARAMETERS() > 3 && expression with property
  1320.                 THIS.AddProp(m.newprop,m.fp25fld)
  1321.                 RETURN
  1322.             ENDIF
  1323.             *- check for GENSCRN tricks
  1324.             IF INLIST(UPPER(LEFT(ALLTRIM(m.fp25fld),3)),".T.",".F.") ;
  1325.                 AND LEN(ALLTRIM(m.fp25fld)) > 3
  1326.                 m.fp25fld = LEFT(ALLTRIM(m.fp25fld),3) + ;
  1327.                     " " + CHR(38) + CHR(38) + SUBSTR(ALLTRIM(m.fp25fld),4)
  1328.             ENDIF
  1329.             IF "SYS(16" $ UPPER(m.fp25fld)
  1330.                 m.fp25fld = STRTRAN(m.fp25fld,"SYS(16","_SYS(16")
  1331.                 m.fp25fld = STRTRAN(m.fp25fld,"sys(16","_sys(16")
  1332.                 m.fp25fld = STRTRAN(m.fp25fld,"Sys(16","_Sys(16")
  1333.             ENDIF
  1334.             m.fp25fld = "RETURN " +  m.fp25fld
  1335.         ENDIF
  1336.  
  1337.         m.savearea = SELECT()
  1338.         
  1339.         REPLACE _FOX3SPR.temp1 WITH m.fp25fld
  1340.         REPLACE _FOX3SPR.temp4 WITH CleanWhite(_FOX3SPR.temp1)
  1341.         SELECT _FOX3SPR
  1342.         THIS.FindArry
  1343.  
  1344.         *- comment out #REGION directives
  1345.         DO WHILE .T.
  1346.             m.gendir = MemoFind("#REGI","temp4",.T.,.F.,.F.,.F.,.T.)
  1347.             IF m.gendir = C_NULL
  1348.                 EXIT
  1349.             ENDIF
  1350.  
  1351.             *- Comment out directive
  1352.             _MLINE = 0
  1353.             nLine = MemoFind("#REGI","temp4",.T.,.T.,m.gendircount,.F.,.T.)
  1354.             cTmp = MLINE(temp1,nLine - 1)                        && set _MLINE
  1355.             REPLACE temp1 WITH STUFF(temp1,_MLINE + IIF(nLine <= 1,0,2),0,'*')
  1356.             cTmp = MLINE(temp4,nLine - 1)                        && set _MLINE
  1357.             REPLACE temp4 WITH STUFF(temp4,_MLINE + IIF(nLine <= 1,0,1),0,'*')
  1358.         ENDDO
  1359.         m.fp25fld = temp1
  1360.  
  1361.         IF USED(THIS.c25alias)
  1362.             SELECT (THIS.c25alias)
  1363.         ELSE
  1364.             SELECT (m.savearea)
  1365.         ENDIF
  1366.  
  1367.         *- see if multiple procs in the procedure section
  1368.         *- if so, strip out and move to .SPR file, since 3.0
  1369.         *- won't expect more than one proc in a method...
  1370.         *- there's no PROC or FUNC line for the VALID
  1371.         IF INLIST(m.newmethod,;
  1372.                     M_VALID,;
  1373.                     M_VALID2,;
  1374.                     M_ERROR,;
  1375.                     M_MESSAGE,;
  1376.                     M_ACTIVATE,;
  1377.                     M_DEACTIVATE,;
  1378.                     M_SHOW,;
  1379.                     M_WHEN,;
  1380.                     M_WHEN2)
  1381.             m.cTmp = UPPER(m.fp25fld)
  1382.             IF OCCURS("PROC",m.cTmp) + OCCURS("FUNC",m.cTmp) > 0
  1383.                 *- get other procs, and put them in SPR file
  1384.                 *- use correct field name
  1385.                 m.newmethod2 = IIF(UPPER(LEFT(m.newmethod,4)) = "READ",SUBS(m.newmethod,5),;
  1386.                                 IIF(UPPER(LEFT(m.newmethod,5)) = "ERROR",LEFT(m.newmethod,5),m.newmethod))
  1387.                 DO extractprocs WITH 0,m.newmethod2
  1388.                 *- Move the stuff to a holding place for now
  1389.                 IF !EMPTY(_FOX3SPR.sprmemo) AND m.newmethod # M_SHOW
  1390.                     REPLACE _FOX3SPR.temp3 WITH C_CRLF + _FOX3SPR.sprmemo ADDITIVE
  1391.                     REPLACE _FOX3SPR.sprmemo WITH ""
  1392.                 ENDIF
  1393.                 IF INLIST(m.newmethod,;
  1394.                     M_VALID2,;
  1395.                     M_WHEN2)
  1396.                     *- throw away everything up to first PROC or FUNC
  1397.                     LOCAL iFunc,iProc
  1398.                     cTmp = C_CR + STRTRAN(m.fp25fld,C_CRLF,C_CR)
  1399.                     iFunc = AT(C_CR + "FUNC",cTmp)
  1400.                     iProc = AT(C_CR + "PROC",cTmp)
  1401.                     iFunc = IIF(iFunc = 0,99999999,iFunc)
  1402.                     iProc = IIF(iProc = 0,99999999,iProc)
  1403.                     m.fp25fld = SUBS(cTmp,2,MIN(iFunc, iProc) - 2)    && we added a CR at the beginning
  1404.                 ENDIF
  1405.             ENDIF
  1406.         ENDIF
  1407.         *- Add method code to fp3method
  1408.         IF !EMPTY(m.fp25fld)
  1409.             THIS.fp3method = THIS.fp3method + ;
  1410.                 "PROCEDURE " + m.newmethod + C_CRLF + ;
  1411.                     m.fp25fld + IIF(RIGHT(m.fp25fld,2) = C_CRLF OR ;
  1412.                      RIGHT(m.fp25fld,1) = C_CR,"",C_CRLF) + ;
  1413.                 "ENDPROC" + C_CRLF + C_CRLF
  1414.         ENDIF
  1415.         
  1416.         SELECT (m.savearea)
  1417.  
  1418.         RETURN
  1419.     ENDFUNC        && ConverterBase:AddMethods
  1420.  
  1421.  
  1422.     *--------------------------------------
  1423.     FUNCTION FindArry        && ConverterBase
  1424.     *--------------------------------------
  1425.         *- look for DIMENSION or DECLARE, and add to list a_Dimes list, so they
  1426.         *- can be "externalized" in the .SPR file
  1427.  
  1428.         *- assume that code to be searched is in _FOX3SPR.temp1, and that table
  1429.         *- is open in the current work area
  1430.         *- also, code in temp4 is stripped of leading white space
  1431.  
  1432.         LOCAL m.nArryCt, m.cArryName, m.nArryLen, m.j, m.iPlace, m.cTemp, m.nCtr
  1433.  
  1434.         m.nArryCt = 1
  1435.         DO WHILE .T.
  1436.             m.cArryName = UPPER(MemoFind("DECL","temp4",.T.,.F.,m.nArryCt,.T.,.T.))
  1437.             IF m.cArryName = C_NULL
  1438.                 EXIT
  1439.             ENDIF
  1440.             IF RIGHT(TRIM(m.cArryName),1) = ";"
  1441.                 *- a continued DECLARE, so take some special measures
  1442.                 m.cArryName = ""
  1443.                 iPlace = MemoFind("DECL","temp4",.T.,.T.,m.nArryCt,.T.,.T.)
  1444.                 IF m.iPlace = 0
  1445.                     *- this should be an impossibility -- couldn;t find where it was
  1446.                     EXIT
  1447.                 ENDIF
  1448.                 cTemp = MLINE(temp1,m.iPlace)
  1449.                 *- check for continued DECLARE
  1450.                 m.nCtr = 1
  1451.                 DO WHILE .T.
  1452.                     m.cArryName = m.cArryName + m.cTemp
  1453.                     IF RIGHT(m.cTemp,1) # ";"
  1454.                         EXIT
  1455.                     ELSE
  1456.                         m.cTemp = MLINE(temp1,m.iPlace + m.nCtr)
  1457.                         m.nCtr = m.nCtr + 1
  1458.                     ENDIF
  1459.                 ENDDO
  1460.                 m.cArryName = STRTRAN(SUBS(m.cArryName,AT("DECL",UPPER(m.cArryName)) + 4),";","")
  1461.             ENDIF
  1462.             m.nArryCt = m.nArryCt + 1
  1463.             m.nArryLen = ALEN(THIS.a_Dimes)
  1464.             IF !EMPTY(THIS.a_Dimes[1])
  1465.                 DIMENSION THIS.a_Dimes[m.nArryLen + 1]
  1466.                 m.nArryLen = m.nArryLen + 1
  1467.             ENDIF
  1468.             IF  UPPER(LEFT(m.cArryName,2)) == "A " OR ;
  1469.                 UPPER(LEFT(m.cArryName,3)) == "AR " OR ;
  1470.                 UPPER(LEFT(m.cArryName,4)) == "ARE "
  1471.                 THIS.a_Dimes[m.nArryLen] = SUBS(m.cArryName,AT(' ',m.cArryName) + 1)
  1472.             ELSE
  1473.                 THIS.a_Dimes[m.nArryLen] = m.cArryName
  1474.             ENDIF
  1475.         ENDDO
  1476.         m.nArryCt = 1
  1477.         DO WHILE .T.
  1478.             m.cArryName = UPPER(MemoFind("DIME","temp4",.T.,.F.,m.nArryCt,.T.,.T.))
  1479.             IF m.cArryName = C_NULL
  1480.                 EXIT
  1481.             ENDIF
  1482.             IF RIGHT(TRIM(m.cArryName),1) = ";"
  1483.                 *- a continued DECLARE, so take some special measures
  1484.                 m.cArryName = ""
  1485.                 iPlace = MemoFind("DIME","temp4",.T.,.T.,m.nArryCt,.T.,.T.)
  1486.                 IF m.iPlace = 0
  1487.                     *- this should be an impossibility -- couldn;t find where it was
  1488.                     EXIT
  1489.                 ENDIF
  1490.                 cTemp = MLINE(temp1,m.iPlace)
  1491.                 *- check for continued DECLARE
  1492.                 m.nCtr = 1
  1493.                 DO WHILE .T.
  1494.                     m.cArryName = m.cArryName + m.cTemp
  1495.                     IF RIGHT(m.cTemp,1) # ";"
  1496.                         EXIT
  1497.                     ELSE
  1498.                         m.cTemp = MLINE(temp1,m.iPlace + m.nCtr)
  1499.                         m.nCtr = m.nCtr + 1
  1500.                     ENDIF
  1501.                 ENDDO
  1502.                 m.cArryName = STRTRAN(SUBS(m.cArryName,AT("DIME",UPPER(m.cArryName)) + 4),";","")
  1503.             ENDIF
  1504.             m.nArryCt = m.nArryCt + 1
  1505.             m.nArryLen = ALEN(THIS.a_Dimes)
  1506.             IF !EMPTY(THIS.a_Dimes[1])
  1507.                 DIMENSION THIS.a_Dimes[m.nArryLen + 1]
  1508.                 m.nArryLen = m.nArryLen + 1
  1509.             ENDIF
  1510.             IF  UPPER(LEFT(m.cArryName,2)) == "N " OR ;
  1511.                 UPPER(LEFT(m.cArryName,3)) == "NS " OR ;
  1512.                 UPPER(LEFT(m.cArryName,4)) == "NSI " OR ;
  1513.                 UPPER(LEFT(m.cArryName,5)) == "NSIO " OR ;
  1514.                 UPPER(LEFT(m.cArryName,6)) == "NSION "
  1515.                 THIS.a_Dimes[m.nArryLen] = SUBS(m.cArryName,AT(' ',m.cArryName) + 1)
  1516.             ELSE
  1517.                 THIS.a_Dimes[m.nArryLen] = m.cArryName
  1518.             ENDIF
  1519.         ENDDO
  1520.  
  1521.     ENDFUNC        && ConverterBase:FindArry
  1522.  
  1523.     *------------------------------------
  1524.     FUNCTION OpenFile        && ConverterBase
  1525.     *------------------------------------
  1526.         PARAMETER cFile
  1527.  
  1528.         PRIVATE cThisAlias
  1529.         LOCAL m.nfh
  1530.                 
  1531.         *- cFile is the file to open
  1532.         m.cThisAlias= "S" + LEFT(SYS(3),7)
  1533.  
  1534.         SELECT 0
  1535.         
  1536.         *- now try to open file
  1537.         IF FILE(m.cFile)
  1538.             DO CASE
  1539.                 CASE !Readable(m.cFile)
  1540.                     *- file is already open
  1541.                     THIS.WriteLog(JUSTFNAME(m.cFile),TRIM(E_FILE_LOC) + E_NOCONVERT2_LOC)
  1542.                     =MESSAGEBOX(E_NOOPEN_LOC + m.cFile + ". " + E_FILEOPEN_LOC)
  1543.                     THIS.lHadError = .T.
  1544.                 CASE pReadOnly(cFile)
  1545.                     *- if read only, we can;t do anything with it... (jd 04/15/95, RED00M77)
  1546.                     THIS.WriteLog(JUSTFNAME(m.cFile),TRIM(E_FILE_LOC) + E_NOCONVERT3_LOC)
  1547.                     =MESSAGEBOX(TRIM(m.cFile) + E_NOCONVERT3_LOC)
  1548.                     THIS.lHadError = .T.
  1549.                 CASE THIS.IsDBF(m.cFile)
  1550.                     *- success
  1551.                     USE (m.cFile) ALIAS (m.cThisAlias) EXCLUSIVE
  1552.                 OTHERWISE
  1553.                     THIS.WriteLog(JUSTFNAME(m.cFile),E_INVALDBF_LOC)
  1554.                     =MESSAGEBOX(E_FILE_LOC + m.cFile + E_NOCONVERT2_LOC)
  1555.                     THIS.lHadError = .T.
  1556.             ENDCASE
  1557.         ELSE
  1558.             *- log the error
  1559.             THIS.WriteLog(JUSTFNAME(m.cFile),TRIM(E_FILE_LOC) + E_NOCONVERT1_LOC)
  1560.             =MESSAGEBOX(E_FILE_LOC + m.cFile + E_NOCONVERT1_LOC)
  1561.             THIS.lHadError = .T.
  1562.         ENDIF
  1563.  
  1564.         *- Check if had error opening file
  1565.         IF THIS.lHadError
  1566.             RETURN ""
  1567.         ENDIF
  1568.  
  1569.         RETURN m.cThisAlias
  1570.  
  1571.     ENDFUNC        && ConverterBase:OpenFile
  1572.     
  1573.  
  1574.     *------------------------------------
  1575.     FUNCTION GetVarPrefix        && ConverterBase
  1576.     *------------------------------------
  1577.         PARAMETER cClassType
  1578.  
  1579.         DO CASE
  1580.             CASE cClassType = T_LABEL
  1581.                 RETURN "lbl"
  1582.             CASE cClassType = T_SAY
  1583.                 RETURN "txt"
  1584.             CASE cClassType = T_EDIT
  1585.                 RETURN "edt"
  1586.             CASE cClassType = T_LINE
  1587.                 RETURN "lin"
  1588.             CASE cClassType = T_SHAPE
  1589.                 RETURN "shp"
  1590.             CASE cClassType = T_INV
  1591.                 RETURN "cmg"
  1592.             CASE cClassType = T_BTNGRP OR;
  1593.                 cClassType = T_BTN
  1594.                 RETURN "cmg"
  1595.             CASE cClassType = T_PICT
  1596.                 RETURN "img"
  1597.             CASE cClassType = T_RADIO
  1598.                 RETURN "opt"
  1599.             CASE cClassType = T_RADIOGRP
  1600.                 RETURN "opg"
  1601.             CASE cClassType = T_CBOX
  1602.                 RETURN "chk"
  1603.             CASE cClassType = T_POPUP
  1604.                 RETURN "cbo"
  1605.             CASE cClassType = T_SPIN
  1606.                 RETURN "spn"
  1607.             CASE cClassType = T_OLE
  1608.                 RETURN "ole"
  1609.             CASE cClassType = T_LIST
  1610.                 RETURN "lst"
  1611.             CASE cClassType = T_DATANAV
  1612.                 RETURN "de"
  1613.             CASE cClassType = T_CURSOR
  1614.                 RETURN "crs"
  1615.             CASE cClassType = T_RELATION
  1616.                 RETURN "rel"
  1617.             CASE cClassType = T_FSET
  1618.                 RETURN "frs"
  1619.             CASE cClassType = T_FORM
  1620.                 RETURN "frm"
  1621.             CASE cClassType = T_PAGE
  1622.                 RETURN "pgf"
  1623.             OTHERWISE
  1624.                 RETURN "c"
  1625.         ENDCASE
  1626.     ENDFUNC
  1627.  
  1628.     *------------------------------------
  1629.     FUNCTION Converter
  1630.     *------------------------------------
  1631.         *- this method should always be overridden
  1632.         WAIT WINDOW "Called Converter function that wasn't overridden!"
  1633.         RETURN -1
  1634.     ENDFUNC
  1635.     
  1636.     *------------------------------------
  1637.     FUNCTION ok2nuke
  1638.     *------------------------------------
  1639.         *- Emulate SAFETY ON
  1640.  
  1641.         PARAMETER cFileName
  1642.         LOCAL m.nresult
  1643.  
  1644.         DO CASE
  1645.             CASE _WINDOWS
  1646.                 RETURN MESSAGEBOX(UPPER(JustFName(m.cFileName)) + C_OVERWRITE_LOC,MB_YESNO) = IDYES
  1647.             OTHERWISE
  1648.                 *- not implemented yet
  1649.                 RETURN .F.
  1650.         ENDCASE
  1651.  
  1652.     ENDFUNC        && ok2nuke
  1653.  
  1654.     *----------------------------------
  1655.     PROCEDURE CompileFRX
  1656.     *----------------------------------
  1657.         *- take code from TAG field of DataEnvironment record, and 
  1658.         *- compile it as an FXP, then append it into the TAG2 field
  1659.         *- There is no "COMPILE REPORT" command
  1660.         *- Assume we are positioned on the appropriate record
  1661.         LOCAL cTmpFile
  1662.  
  1663.         cTmpFile = SYS(3) + ".PRG"
  1664.  
  1665.         COPY MEMO tag TO (cTmpFile)
  1666.         COMPILE (cTmpFile)
  1667.         IF !_mac
  1668.             APPEND MEMO tag2 FROM (FORCEEXT(cTmpFile,"FXP"))
  1669.         ELSE
  1670.             LOCAL iFH, iBuffer
  1671.             iFH = FOPEN(FORCEEXT(cTmpFile,"FXP"))
  1672.             IF iFH # -1
  1673.                 DO WHILE !FEOF(iFH)
  1674.                     iBuffer = FREAD(iFH, N_BUFFSZ)
  1675.                     REPLACE tag2 WITH iBuffer ADDITIVE
  1676.                 ENDDO
  1677.                 =FCLOSE(iFH)
  1678.             ELSE
  1679.                 *- some kind of error
  1680.             ENDIF
  1681.         ENDIF
  1682.         ERASE (cTmpFile)
  1683.         ERASE (FORCEEXT(cTmpFile,"FXP"))
  1684.  
  1685.         RETURN
  1686.  
  1687.     ENDPROC        && CompileFRX
  1688.  
  1689.  
  1690. ENDDEFINE        &&  ConverterBase 
  1691.  
  1692.  
  1693. **********************************************
  1694. DEFINE CLASS PJXConverterBase AS ConverterBase
  1695. **********************************************
  1696.  
  1697.     *- methods that might be changed in a sub-classed
  1698.     scxConverterClass = "SCXSingleScreenConverter"
  1699.     scx30ConverterClass = "SCX30Converter"
  1700.     frxConverterClass = "FRXConverter"
  1701.  
  1702.     curscxid = 1        && project current setid
  1703.     highscxid = 0        && project high setid
  1704.     isproj = .T.
  1705.     cHomeDir = ""
  1706.     cBackDir = ""
  1707.     cOutFile = ""
  1708.     cStubFile = ""
  1709.     pjxName = ""
  1710.     pjx25Alias = ""        && 2.5 project alias
  1711.     pjxVersion = ""
  1712.     lIsMain = .F.
  1713.     lEncrypt = .F.
  1714.     lSaveCode = .T.        && saveCode option (6.8.96 jd)
  1715.     cDevInfo = ""
  1716.     lDebug = .F.
  1717.     lExclude = .F.
  1718.     nScreenSets = 0        && number of undeleted screen sets in project
  1719.     nScreenCtr = 0        && counter for screens actually converted
  1720.     cFull30PJXName = ""    && fully-qualifed name of new PJX
  1721.     f2Files = ""        && holder for 2.x FRX file name
  1722.     f3files = ""        && holder for 3.x FRX file name
  1723.     cMemoExt = ""        && extension for memo files for files of this type
  1724.  
  1725.     DIMENSION a_pjxsets[10]
  1726.  
  1727.     *----------------------------------
  1728.     PROCEDURE CreatePJX        && PJXConverterBase
  1729.     *----------------------------------
  1730.         PRIVATE cTmpPJXName
  1731.  
  1732.         m.cTmpPJXName = ADDBS(JUSTPATH(THIS.pjxName)) + "P" + LEFT(SYS(3),7) + ".PJX"
  1733.  
  1734.         *- create new PJX file
  1735.         CREATE TABLE (m.cTmpPJXName) ;
  1736.             (name        m,;
  1737.             type        c(1),;
  1738.             id            n(10),;
  1739.             timestamp   n(10),;
  1740.             outfile     m,;
  1741.             homedir     m,;
  1742.             exclude     l,;
  1743.             mainprog    l,;
  1744.             savecode    l,;
  1745.             debug       l,;
  1746.             encrypt     l,;
  1747.             nologo      l,;
  1748.             cmntstyle   n(1),;
  1749.             objrev      n(5),;
  1750.             devinfo     m,;
  1751.             symbols     m,;
  1752.             object      m,;
  1753.             ckval       n(6),;
  1754.             cpid        n(5),;
  1755.             ostype      c(4),;
  1756.             oscreator   c(4),;
  1757.             comments    m,;
  1758.             reserved1   m,;
  1759.             reserved2   m,;
  1760.             sccdata     m,;
  1761.             local       l,;
  1762.             key         c(32),;
  1763.             user        m)
  1764.  
  1765.         THIS.new30alias = ALIAS()
  1766.  
  1767.         *- Add header comment record  && added SaveCode (6.8.96 jd)
  1768.         INSERT INTO (THIS.new30alias) ;
  1769.             (name, timestamp, type, homedir, saveCode, objrev, debug, encrypt, devinfo);
  1770.             VALUES (JUSTFNAME(THIS.pjxName),THIS.nTimeStamp,;
  1771.                 "H", JUSTPATH(THIS.pjxName) + C_NULL, ;
  1772.                 THIS.lSaveCode, C_PJXVERSTAMP, THIS.lDebug, THIS.lEncrypt, THIS.cDevInfo)
  1773.         THIS.p30to40
  1774.         
  1775.     ENDPROC        &&   CreatePJX
  1776.  
  1777.     *----------------------------------
  1778.     PROCEDURE InsertSCX            && PJXConverterBase
  1779.     *----------------------------------
  1780.         *- add appropriate record(s) to 3.0 PJX file
  1781.         *- additional work is done in subclassed InsertSCX
  1782.         IF !THIS.lDevMode
  1783.             *- if Dev Mode (aka "Visual Conversion"), don;t need SPRs
  1784.             *- also add record for [new] SPR file
  1785.             INSERT INTO (THIS.new30alias) ;
  1786.                     (name,;
  1787.                     timestamp,;
  1788.                     type,;
  1789.                     exclude,;
  1790.                     mainprog,;
  1791.                     cpid,;
  1792.                     key);
  1793.                 VALUES(;
  1794.                     SYS(2014,THIS.cStubFile,DBF(THIS.new30alias)) + CHR(0),;
  1795.                     THIS.nTimeStamp,;
  1796.                     C_PRGTYPE,;
  1797.                     THIS.lExclude,;
  1798.                     THIS.lIsMain,;
  1799.                     IIF(CPCURRENT() # 0, CPCURRENT(),CPDBF(THIS.new30alias)),;
  1800.                     UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  1801.         ENDIF
  1802.  
  1803.     ENDPROC        && InsertSCX
  1804.  
  1805.     *------------------------------------
  1806.     PROCEDURE CloseFiles            && PJXConverterBase
  1807.     *------------------------------------
  1808.         IF USED(THIS.pjx25Alias)
  1809.             USE IN (THIS.pjx25Alias)
  1810.         ENDIF
  1811.  
  1812.         IF USED(THIS.new30alias)
  1813.             IF THIS.lLog
  1814.                 SELECT (THIS.new30alias)
  1815.                 IF TYPE("user") = "M"
  1816.                     GO TOP
  1817.                     REPLACE user WITH m.gLog + C_CRLF + C_LOGEND_LOC + " [" + TTOC(DATETIME()) + "]" + C_CRLF
  1818.                     COPY MEMO user TO (THIS.cLogFile)
  1819.                 ENDIF
  1820.             ENDIF
  1821.             USE IN (THIS.new30alias)
  1822.         ENDIF            
  1823.  
  1824.     ENDPROC
  1825.  
  1826.     *------------------
  1827.     PROCEDURE BackFiles
  1828.     *------------------
  1829.         PARAMETER cField, cType, cDesc
  1830.         PRIVATE cBackName,cTmpFname, m.cTmpFnameOld, m.lNoFinds, m.savearea,;
  1831.             cCurDir, i, nCvt
  1832.  
  1833.         LOCAL cOldPath, cNewPath, cThisPath, cFName
  1834.  
  1835.         *- make sure project file locations are up-to-date
  1836.         m.savearea = SELECT()
  1837.         SELECT (THIS.pjx25Alias)
  1838.  
  1839.         *- copy first time only
  1840.         IF !FILE(THIS.cBackDir + JUSTFNAME(THIS.cCurrentFile)) AND THIS.lBackUp
  1841.             COPY FILE (THIS.cCurrentFile) TO THIS.cBackDir + JUSTFNAME(THIS.cCurrentFile)
  1842.             COPY FILE (FORCEEXT(THIS.cCurrentFile,THIS.cMemoExt)) TO (FORCEEXT(THIS.cBackDir + JUSTFNAME(THIS.cCurrentFile),THIS.cMemoExt))
  1843.         ENDIF
  1844.  
  1845.         cOldPath = SET("PATH")
  1846.         cNewPath = m.cOldPath
  1847.         
  1848.         nCvt = 0
  1849.  
  1850.         SCAN FOR !(type $ 'SH') AND !DELETED()            && type $ m.cType AND !DELETED()
  1851.             cFName = ALLTRIM(IIF(AT(CHR(0),&cField) > 0,LEFT(&cField,AT(CHR(0),&cField)-1),&cField))
  1852.             IF !_MAC AND OCCURS(":",cFName) > 1
  1853.                 *- FULLPATH will fail on this path, and since it is invalid for DOS etc.,
  1854.                 *- translate ":" into "\" and let user find the files
  1855.                 cFName = STRTRAN(cFName,":","\")
  1856.             ENDIF
  1857.             cTmpFname = FULLPATH(cFName,THIS.cHomeDir)
  1858.             IF !FILE(cTmpFname)
  1859.                 *- it;s not in the place where it's supposed to be
  1860.                 *- is it in the path?
  1861.                 IF FILE(JustFName(cTmpFname))
  1862.                     *- let Fox find the correct path, in the SET PATH
  1863.                     m.cTmpFname = FULLPATH(JustFName(m.cTmpFname))
  1864.                 ELSE
  1865.                     *- try to locate file first
  1866.                     IF m.nCvt = 3
  1867.                         *- ignore all
  1868.                         THIS.WriteLog(cTmpFname,E_FILE_LOC + JustFName(cTmpFname) + E_NOCONVERT1_LOC)
  1869.                         LOOP
  1870.                     ENDIF
  1871.                     *- cvtLocate is based on the cvtAlertFrx. so it uses the same variables
  1872.                     oLocate = CREATEOBJECT("cvtLocate",C_LOCFILE3_LOC)
  1873.                     oLocate.Show
  1874.                     RELEASE oLocate
  1875.                     DO CASE
  1876.                         CASE m.nCvt = 1
  1877.                             *- locate
  1878.                             m.cTmpFnameOld = m.cTmpFname
  1879.                             m.cTmpFname = ""
  1880.                             THIS.lLocalErr = .T.
  1881.                             m.cTmpFname = LOCFILE(JUSTFNAME(m.cTmpFnameOld),JUSTEXT(m.cTmpFnameOld),C_LOCFILE2_LOC)
  1882.                             THIS.lLocalErr = .F.
  1883.                         CASE m.nCvt = 2 OR m.nCvt = 3
  1884.                             *- ignore
  1885.                             THIS.WriteLog(cTmpFname,E_FILE_LOC + JustFName(cTmpFname) + E_NOCONVERT1_LOC)
  1886.                             LOOP
  1887.                         OTHERWISE
  1888.                             *- cancel
  1889.                             m.cTmpFname = ""
  1890.                     ENDCASE
  1891.                 ENDIF
  1892.  
  1893.                 *- if found, update project
  1894.                 IF EMPTY(m.cTmpFname)
  1895.                     *- cancelled, so quit conversion
  1896.                     THIS.lHadError = .T.
  1897.                     RETURN
  1898.                 ELSE
  1899.                     REPLACE &cField WITH m.cTmpFname
  1900.                     *- and remember this location
  1901.                     m.cThisPath = JUSTPATH(cTmpFname)
  1902.                     IF !(m.cThisPath $ m.cNewPath)
  1903.                         cNewPath = m.cNewPath + "," + m.cThisPath
  1904.                         SET PATH TO &cNewPath
  1905.                     ENDIF
  1906.                 ENDIF
  1907.             ENDIF
  1908.  
  1909.         ENDSCAN
  1910.  
  1911.         *- restore path
  1912.         SET PATH TO &cOldPath
  1913.  
  1914.         SELECT (m.savearea)
  1915.         
  1916.         IF THIS.lBackUp
  1917.             gOTherm.Update2(0,C_BACKFILES_LOC)
  1918.         
  1919.             SELECT &cField, type FROM DBF(THIS.pjx25Alias) ;
  1920.                 WHERE type $ m.cType AND !DELETED() ;
  1921.                 INTO ARRAY tmparr
  1922.  
  1923.             IF _TALLY = 0
  1924.                 RETURN
  1925.             ENDIF
  1926.  
  1927.             m.lNoFinds = .F.
  1928.  
  1929.             FOR i = 1 TO _TALLY
  1930.                 *- Copy files to backup directory
  1931.                 m.cTmpFname = FULLPATH(ALLTRIM(IIF(AT(CHR(0),tmparr[m.i,1]) > 0,;
  1932.                     LEFT(tmparr[m.i,1],AT(CHR(0),tmparr[m.i,1])-1),tmparr[m.i,1])),THIS.cHomeDir)
  1933.                 m.cBackName = THIS.cBackDir + JUSTFNAME(STRTRAN(tmparr[m.i,1],C_NULL))
  1934.  
  1935.                 IF !FILE(m.cTmpFname)   && is file there?
  1936.                     *- if not there, log the error and continue
  1937.                     THIS.WriteLog(JUSTFNAME(STRTRAN(tmparr[m.i,1],C_NULL)),E_NOFILE_LOC + TRIM(m.cDesc) + E_NOBACKUP_LOC)
  1938.                     m.lNoFinds = .T.
  1939.                     LOOP
  1940.                 ENDIF
  1941.  
  1942.                 IF !FILE(m.cBackName)   && check if file already copied over
  1943.                     COPY FILE (m.cTmpFname) TO (m.cBackName)
  1944.                     DO CASE
  1945.                         CASE tmparr[m.i,2] $ 'sK' OR tmparr[m.i,2] = 'scx'
  1946.                             *- assume screen/form
  1947.                             COPY FILE (FORCEEXT(m.cTmpFname,C_SCTEXT)) TO (FORCEEXT(m.cBackName,C_SCTEXT))
  1948.                         CASE tmparr[m.i,2] == 'V' OR tmparr[m.i,2] = 'vcx'
  1949.                             *- assume visual class
  1950.                             COPY FILE (FORCEEXT(m.cTmpFname,C_VCTEXT)) TO (FORCEEXT(m.cBackName,C_VCTEXT))
  1951.                         CASE tmparr[m.i,2] = 'R' OR tmparr[m.i,2] = 'frx'
  1952.                             *- assume report form
  1953.                             COPY FILE (FORCEEXT(m.cTmpFname,"FRT")) TO (FORCEEXT(m.cBackName,"FRT"))
  1954.                         CASE tmparr[m.i,2] $ 'B' OR tmparr[m.i,2] = 'lbx'
  1955.                             *- assume report form
  1956.                             COPY FILE (FORCEEXT(m.cTmpFname,"LBT")) TO (FORCEEXT(m.cBackName,"LBT"))
  1957.                     ENDCASE
  1958.                 ENDIF
  1959.             ENDFOR
  1960.             
  1961.             IF m.lNoFinds
  1962.                 IF MESSAGEBOX(E_NOFINDS_LOC,1) = IDCANCEL
  1963.                     gOMaster.lHadError = .T.
  1964.                 ENDIF
  1965.             ENDIF
  1966.  
  1967.         ENDIF        && THIS.lBackUp
  1968.  
  1969.  
  1970.     ENDPROC        && PJXConverterBase:BackFiles
  1971.     
  1972.     *----------------------------------
  1973.     PROCEDURE CompileAllScx            && PJXConverterBase
  1974.     *----------------------------------
  1975.         *- compile the SCX files in the converted project (save till end)
  1976.         LOCAL cFile, lIs30File, cPath, cErrFile
  1977.  
  1978.         THIS.WriteLog("","")
  1979.  
  1980.         SELECT (THIS.new30alias)
  1981.         
  1982.         cPATH = SET("PATH") + ',' + JustPath(THIS.pjxName)
  1983.         
  1984.         SCAN FOR type = C_SCXTYPE OR type = C_VCXTYPE
  1985.  
  1986.             m.lIs30File = .F.
  1987.  
  1988.             IF FILE(THIS.cHomeDir + STRTRAN(name,C_NULL,""))
  1989.                 cFile = THIS.cHomeDir + STRTRAN(name,C_NULL,"")
  1990.                 *- make sure file is converted and openable (maybe user bailed from transporting)
  1991.                 IF Readable(m.cFile) AND THIS.IsDBF(m.cFile)
  1992.                     SELECT 0
  1993.                     USE (m.cFile) EXCLUSIVE
  1994.                     IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  1995.                         *- okay -- it's a 3.0 file
  1996.                         m.lIs30File = .T.
  1997.                     ENDIF
  1998.                     USE
  1999.                     SELECT (THIS.new30alias)
  2000.                 ENDIF
  2001.                 IF m.lIs30File
  2002.                     THIS.WriteLog(SYS(2027,m.cFile),C_COMPILE_LOC)
  2003.                     THIS.lLocalErr = .T.
  2004.                     
  2005.                     cErrFile = AddBS(JustPath(m.cFile)) + JustStem(m.cFile) + ".ERR"
  2006.                     IF FILE(m.cErrFile)
  2007.                         ERASE (m.cErrFile)
  2008.                     ENDIF
  2009.                     
  2010.                     COMPILE FORM (m.cFile)                    
  2011.  
  2012.                     IF THIS.lHadLocErr OR FILE(m.cErrFile)
  2013.                         THIS.WriteLog(SYS(2027,m.cFile),E_NOINCLUDE_LOC)
  2014.                         =MESSAGEBOX(E_NOINCLUDE1_LOC + SYS(2027,m.cFile) + E_NOINCLUDE2_LOC)
  2015.                         THIS.lHadLocErr = .F.
  2016.                     ENDIF
  2017.                     THIS.lLocalErr = .F.
  2018.                 ENDIF
  2019.             ENDIF
  2020.         ENDSCAN
  2021.  
  2022.     ENDPROC        && PJXConverterBase:CompileAllScx
  2023.  
  2024. #if 0
  2025.     *------------------------------------
  2026.     PROCEDURE Error                && Cvt
  2027.     *------------------------------------
  2028.         PARAMETER errorNum, method, line
  2029.  
  2030.         IF errorNum = 1994
  2031.             *- can;t find .h file
  2032.             THIS.lHadLocErr = .T.
  2033.             
  2034.             RETURN
  2035.         ENDIF
  2036.         
  2037.         ConverterBase::Error(errorNum, method, line)
  2038.         
  2039.     ENDPROC
  2040. #endif
  2041.  
  2042.     *----------------------------------
  2043.     PROCEDURE CompileAllFrx            && PJXConverterBase
  2044.     *----------------------------------
  2045.         *- compile the FRX files in the converted project (save till end)
  2046.         LOCAL cFile
  2047.  
  2048.         SELECT (THIS.new30alias)
  2049.         SCAN FOR type $ C_REPORT + C_LABEL
  2050.  
  2051.             IF FILE(THIS.cHomeDir + STRTRAN(name,C_NULL,""))
  2052.                 cFile = THIS.cHomeDir + STRTRAN(name,C_NULL,"")
  2053.                 *- make sure file is converted and openable (maybe user bailed from transporting)
  2054.                 IF Readable(m.cFile) AND THIS.IsDBF(m.cFile)
  2055.                     SELECT 0
  2056.                     USE (m.cFile) EXCLUSIVE
  2057.                     IF FCOUNT() = C_30FRXFLDS AND FIELD(75) = "USER"
  2058.                         *- okay -- it's a 3.0 file
  2059.                         LOCATE FOR objtype = N_FRX_DATAENV AND platform = THIS.platform
  2060.                         IF FOUND()
  2061.                             THIS.CompileFRX
  2062.                             THIS.WriteLog(SYS(2027,m.cFile),C_COMPILE_LOC)
  2063.                         ENDIF
  2064.                     ENDIF
  2065.                     USE
  2066.                     SELECT (THIS.new30alias)
  2067.                 ENDIF
  2068.             ENDIF
  2069.         ENDSCAN
  2070.  
  2071.     ENDPROC        && CompileAllFrx
  2072.  
  2073.     *----------------------------------
  2074.     PROCEDURE CompileAllDBC
  2075.     *----------------------------------
  2076.         *- compile the DBC files in the converted project (save till end)
  2077.         LOCAL cFile, lIs30File, lOpenShared, i, iCnt, cOldDataBase
  2078.         LOCAL ARRAY aDBC[1]
  2079.         
  2080.         THIS.WriteLog("","")
  2081.  
  2082.         cOldDataBase = SET("DATABASE")
  2083.         
  2084.         SELECT (THIS.new30alias)
  2085.         SCAN FOR type = C_DBCTYPE
  2086.  
  2087.             m.lIs30File = .F.
  2088.  
  2089.             IF FILE(THIS.cHomeDir + STRTRAN(name,C_NULL,""))
  2090.                 cFile = THIS.cHomeDir + STRTRAN(name,C_NULL,"")
  2091.                 *- make sure file is converted and openable (maybe user bailed from transporting)
  2092.                 IF Readable(m.cFile) AND THIS.IsDBF(m.cFile)
  2093.                     SELECT 0
  2094.                     USE (m.cFile) EXCLUSIVE
  2095.                     IF FCOUNT() = C_30DBCFLDS AND FIELD(4) == "OBJECTNAME"
  2096.                         *- okay -- it's a 3.0 DBC file
  2097.                         m.lIs30File = .T.
  2098.                     ENDIF
  2099.                     USE
  2100.                     SELECT (THIS.new30alias)
  2101.                 ENDIF
  2102.                 IF m.lIs30File
  2103.                     lOpenShared = .F.
  2104.                     THIS.WriteLog(SYS(2027,m.cFile),C_COMPILE_LOC)
  2105.                     IF DBUSED(m.cFile)
  2106.                         iCnt = ADATABASES(aDBC)
  2107.                         FOR i = 1 TO iCnt
  2108.                             IF SYS(2027,aDBC[i,2]) = SYS(2027,m.cFile)
  2109.                                 IF !ISEXCLUSIVE(JustStem(m.cFile))
  2110.                                     m.lOpenShared = .T.
  2111.                                     SET DATABASE TO (aDBC[i,1])
  2112.                                     CLOSE DATABASE
  2113.                                     OPEN DATABASE (SYS(2027,m.cFile)) EXCLUSIVE
  2114.                                 ENDIF
  2115.                                 EXIT
  2116.                             ENDIF
  2117.                         NEXT
  2118.                     ENDIF
  2119.                     COMPILE DATABASE (m.cFile)
  2120.                     IF m.lOpenShared
  2121.                         CLOSE DATABASE
  2122.                         OPEN DATABASE (SYS(2027,m.cFile)) SHARED
  2123.                     ENDIF
  2124.                 ENDIF
  2125.             ENDIF
  2126.         ENDSCAN
  2127.  
  2128.         SET DATABASE TO &cOldDataBase
  2129.         
  2130.     ENDPROC        && CompileAllDBC
  2131.  
  2132.  
  2133.     *----------------------------------
  2134.     PROCEDURE Destroy
  2135.     *----------------------------------
  2136.     ENDPROC
  2137.  
  2138. ENDDEFINE    && PJXConverterBase 
  2139.  
  2140.  
  2141. **********************************************
  2142. DEFINE CLASS PJXConverter AS PJXConverterBase
  2143. **********************************************
  2144.  
  2145.     platform = ""
  2146.     winobj = ""
  2147.     DIMENSION aMasterParms[1]
  2148.     DIMENSION a_s2files[1,3]
  2149.     DIMENSION a_s3files[1]
  2150.     DIMENSION a_scx[1]            && array of unique screens in this project
  2151.     lSet30Defaults = .F.        && if converting a 3.0 project, may need to set 3.0 defaults
  2152.  
  2153.  
  2154.     *------------------
  2155.     PROCEDURE Init    && PJXConverter
  2156.     *------------------
  2157.         PARAMETER aParms
  2158.         
  2159.         *- temp until array stuff fixed
  2160.         PRIVATE tmparr
  2161.         LOCAL m.cold, m.i, m.j, m.nlen, m.nct, m.cTmpPjxName,m.setid
  2162.  
  2163.         m.setid = 0 && in case PJX 3.0
  2164.  
  2165.         gOPJX = THIS
  2166.  
  2167.         SET ESCAPE ON
  2168.         ON ESCAPE DO EscHandler
  2169.  
  2170.         =ACOPY(aParms,THIS.aMasterParms)
  2171.  
  2172.         THIS.nTimeStamp    = THIS.TStamp()
  2173.         THIS.pjxName    = aParms[4]
  2174.         THIS.cBackDir    = aParms[1]
  2175.         THIS.lDevMode    = aParms[7]
  2176.         THIS.cCodeFile    = aParms[8]
  2177.         THIS.lLog        = aParms[9]
  2178.         THIS.cLogFile    = aParms[10]
  2179.         THIS.lBackup    = aParms[11]
  2180.         THIS.iPlatformCount    = aParms[12]
  2181.  
  2182.         THIS.cCurrentFile = THIS.pjxName
  2183.         THIS.cMemoExt = "PJT"
  2184.  
  2185.         IF THIS.lLog
  2186.             THIS.WriteLog(C_CONVLOG_LOC + THIS.cCurrentFile + " [" + TTOC(DATETIME()) + "]","")
  2187.             THIS.WriteLog(C_CONVVERS_LOC + C_CONVERSION_LOC,"")
  2188.             THIS.WriteLog("","")
  2189.         ENDIF
  2190.  
  2191.         *- make a working copy of the PJX file, in case of transporting, so if
  2192.         *- user cancels, original will still be available
  2193.         cTmpPjxName = ADDBS(JUSTPATH(THIS.pjxName)) + 'P' + LEFT(SYS(3),7) + ".PJX"
  2194.         COPY FILE (THIS.pjxName) TO (m.cTmpPjxName)
  2195.         IF FILE(FORCEEXT(THIS.pjxName,"PJT"))
  2196.             COPY FILE (FORCEEXT(THIS.pjxName,"PJT")) TO (FORCEEXT(m.cTmpPjxName,"PJT"))
  2197.         ENDIF
  2198.         THIS.pjxName = m.cTmpPjxName
  2199.  
  2200.         *- project PJX file
  2201.         THIS.pjx25Alias = THIS.OpenFile(THIS.pjxName)
  2202.         IF EMPTY(THIS.pjx25Alias)
  2203.             THIS.lHadError = .T.
  2204.             RETURN .F.
  2205.         ENDIF
  2206.  
  2207.         gOTherm.visible = .T.
  2208.  
  2209.         *- Check for proper file format
  2210.         DO CASE
  2211.             CASE FCOUNT() = C_PJX40FLDS AND FIELD(1) = "NAME"        
  2212.                 *- legal VFP4 PJX 
  2213.             CASE FCOUNT() = C_PJX30FLDS AND FIELD(1) = "NAME"
  2214.                 *- legal VFP3 PJX
  2215.                 THIS.lSet30Defaults = (THIS.iPlatformCount > 1)
  2216.                 THIS.iPlatformCount = 1
  2217.             CASE FCOUNT() = C_PJX25FLDS AND FIELD(1) = "NAME"
  2218.                 *- check for 2.5 PJX type
  2219.             CASE FCOUNT() = c_pjx20flds AND FIELD(1) = "NAME"
  2220.                 *- check for 2.0 PJX type - if so, call transporter first.
  2221.                 USE IN (THIS.pjx25Alias)
  2222.                 *-=MESSAGEBOX(E_HAS20FILE_LOC)
  2223.                 IF !THIS.Conv20PJX()
  2224.                     THIS.lHadError = .T.
  2225.                     RETURN
  2226.                 ENDIF
  2227.             OTHERWISE
  2228.                 USE IN (THIS.pjx25Alias)
  2229.                 THIS.lHadError=.T.
  2230.                 =MESSAGEBOX(E_INVALPJX_LOC)
  2231.                 RETURN
  2232.         ENDCASE
  2233.         
  2234.  
  2235.         THIS.cBackDir = AddBS(THIS.cBackDir)
  2236.  
  2237.         LOCATE FOR Type = "H"
  2238.         
  2239.         THIS.lDebug = debug
  2240.         THIS.lEncrypt = encrypt
  2241.         THIS.cDevInfo = devinfo
  2242.         THIS.highscxid = setid
  2243.         THIS.cHomeDir = ADDBS(JUSTPATH(THIS.pjxName))
  2244.  
  2245.         COUNT FOR type = 'S' AND !DELETED() TO THIS.nScreenSets
  2246.         THIS.nScreenCtr = 1
  2247.  
  2248.         THIS.BackFiles("name", "s|R|B|V|K", C_CONVERT3p_LOC)    && backup screen, report and label files to back dir
  2249.  
  2250.         IF gOMaster.lHadError OR THIS.lHadError
  2251.             THIS.Cleanup
  2252.             THIS.lHadError = .T.
  2253.             RETURN .F.
  2254.         ENDIF
  2255.  
  2256.         *- this cursor is for working with SPR code if devmode
  2257.         IF USED("_FOX3PJX")
  2258.             USE IN _FOX3PJX
  2259.         ENDIF
  2260.  
  2261.         CREATE CURSOR _FOX3PJX (sprmemo m)
  2262.         APPEND BLANK
  2263.  
  2264.         gOTherm.Update2((1 - N_THERM2X) * 100,C_PROJTASK1_LOC)        && update therm with next task
  2265.         
  2266.     ENDPROC    && PJXConverter:Init
  2267.  
  2268.     *------------------------------------
  2269.     PROCEDURE Cleanup        && PJXConverter
  2270.     *------------------------------------
  2271.         *- this proc is called by Error, and tries to put things back the way they were
  2272.         *- copy files in backdir to original location
  2273.  
  2274.         LOCAL i, cPJXname, cBackName, cTmpFname, cExt, nTables, cOldExact
  2275.         PRIVATE af, au
  2276.  
  2277.         cOldExact = SET("EXACT")
  2278.         SET EXACT OFF            && for ASCAN
  2279.  
  2280.         IF WEXIST("transdlg")    && just in case (jd 03/23/96)
  2281.             RELEASE WINDOW transdlg
  2282.         ENDIF
  2283.  
  2284.         m.cPJXname = ""
  2285.  
  2286.         IF USED(THIS.pjx25Alias)
  2287.             SELECT UPPER(name), type FROM DBF(THIS.pjx25Alias) ;
  2288.                 WHERE type $ C_SCREENSET + C_REPORT + C_LABEL AND !DELETED() ;
  2289.                 INTO ARRAY tmparr
  2290.  
  2291.             IF USED(THIS.new30alias)
  2292.                 m.cPJXname = FULLPATH(DBF(THIS.new30alias),THIS.cHomeDir)
  2293.             ENDIF
  2294.  
  2295.         ELSE
  2296.             _TALLY = 0
  2297.         ENDIF
  2298.  
  2299.         *- force deletion of any lingering temp screen or report files
  2300.         IF _TALLY > 0
  2301.             m.nTables = AUSED(au)
  2302.             FOR i = 1 TO m.nTables
  2303.                 IF LEFT(au[i,1],1) = "S" OR LEFT(au[i,1],1) = "F"
  2304.                     cTmpFname = DBF(au[i,1])
  2305.                     cExt = UPPER(JustExt(cTmpFname))
  2306.                     IF ASCAN(tmparr,UPPER(JustFName(cTmpFName))) > 0
  2307.                         *- oops -- it;s one of the real ones
  2308.                         LOOP
  2309.                     ENDIF
  2310.                     IF INLIST(cExt,C_SCXEXT,"FRX","LBX")
  2311.                         USE IN (au[i,1])
  2312.                         ERASE (cTmpFname)
  2313.                         ERASE FORCEEXT(cTmpFname,IIF(m.cExt = C_SCXEXT,C_SCTEXT,;
  2314.                             IIF(m.cExt = "FRX","FRT","LBT")))
  2315.                     ENDIF
  2316.                 ENDIF
  2317.             NEXT
  2318.         ENDIF
  2319.         
  2320.         CLOSE TABLES
  2321.  
  2322.         IF THIS.lBackUp
  2323.             FOR i = 1 TO _TALLY
  2324.                 *- Copy files from backup directory
  2325.                 m.cTmpFname = FULLPATH(ALLTRIM(IIF(AT(CHR(0),tmparr[m.i,1]) > 0,;
  2326.                     LEFT(tmparr[m.i,1],AT(CHR(0),tmparr[m.i,1])-1),tmparr[m.i,1])),THIS.cHomeDir)
  2327.                 m.cBackName = THIS.cBackDir + JUSTFNAME(STRTRAN(tmparr[m.i,1],C_NULL))
  2328.                 IF FILE(m.cBackName)   && is file there?
  2329.                     IF FILE(m.cTmpFname)
  2330.                         *- old file is there
  2331.                         *- try to get rid of it
  2332.                         DELETE FILE (m.cTmpFname)
  2333.                         IF FILE(m.cTmpFname)
  2334.                             *- still there -- maybe it is read-only, so skip
  2335.                             LOOP
  2336.                         ENDIF
  2337.                     ENDIF
  2338.                     COPY FILE (m.cBackName) TO (m.cTmpFname)
  2339.                     DO CASE
  2340.                         CASE tmparr[m.i,2] = 's' OR tmparr[m.i,2] = 'scx'
  2341.                             *- assume screen/form
  2342.                             IF FILE(FORCEEXT(m.cBackName,C_SCTEXT))
  2343.                                 COPY FILE (FORCEEXT(m.cBackName,C_SCTEXT)) TO (FORCEEXT(m.cTmpFname,C_SCTEXT))
  2344.                             ENDIF
  2345.                         CASE tmparr[m.i,2] = 'R' OR tmparr[m.i,2] = 'frx'
  2346.                             *- assume report form
  2347.                             IF FILE(FORCEEXT(m.cBackName,"FRT"))
  2348.                                 COPY FILE (FORCEEXT(m.cBackName,"FRT")) TO (FORCEEXT(m.cTmpFname,"FRT"))
  2349.                             ENDIF
  2350.                         CASE tmparr[m.i,2] $ 'B' OR tmparr[m.i,2] = 'lbx'
  2351.                             *- assume label
  2352.                             IF FILE(FORCEEXT(m.cBackName,"LBT"))
  2353.                                 COPY FILE (FORCEEXT(m.cBackName,"LBT")) TO (FORCEEXT(m.cTmpFname,"LBT"))
  2354.                             ENDIF
  2355.                     ENDCASE
  2356.                 ENDIF
  2357.             NEXT
  2358.  
  2359.             *-now, erase files in backup dir
  2360.             =ADIR(af,THIS.cBackDir + "*.*")
  2361.             IF TYPE("af") # 'U'
  2362.                 FOR i = 1 TO ALEN(af,1)
  2363.                     IF af[i,5] $ 'RD'
  2364.                         LOOP
  2365.                     ENDIF
  2366.                     DELETE FILE (THIS.cBackDir + af[i,1])
  2367.                 NEXT
  2368.                 RELEASE af
  2369.             ENDIF
  2370.             IF ADIR(af,THIS.cBackDir + "*.*") = 0
  2371.                 IF TYPE("af") = 'U'
  2372.                     RD (THIS.cBackDir)
  2373.                 ENDIF
  2374.             ENDIF
  2375.         ENDIF && THIS.lBackUp
  2376.  
  2377.         *- erase temp files
  2378.         IF FILE(m.cPJXname)
  2379.             DELETE FILE (m.cPJXname)
  2380.         ENDIF
  2381.         IF FILE(FORCEEXT(m.cPJXname,"PJT"))
  2382.             DELETE FILE (FORCEEXT(m.cPJXname,"PJT"))
  2383.         ENDIF
  2384.  
  2385.         IF FILE(THIS.PJXname)
  2386.             DELETE FILE (THIS.PJXname)
  2387.         ENDIF
  2388.         IF FILE(FORCEEXT(THIS.PJXname,"PJT"))
  2389.             DELETE FILE (FORCEEXT(THIS.PJXname,"PJT"))
  2390.         ENDIF
  2391.  
  2392.         SET EXACT &cOldExact
  2393.  
  2394.     ENDPROC    && PJXConverter:Cleanup
  2395.  
  2396.     *----------------------------------
  2397.     PROCEDURE Converter        && PJXConverter
  2398.     *----------------------------------
  2399.         *- convert PJX itself
  2400.         *- convert each of the objects in it
  2401.  
  2402.         PRIVATE i, z, oForm, cSaveArea
  2403.         LOCAL cOld, iWhichPlat, cExt1, cExt2
  2404.         DIMENSION aPlatforms[1]
  2405.  
  2406.         cOld = THIS.pjx25Alias
  2407.         SELECT (m.cOld)
  2408.  
  2409.         *- Get record count for thermometer
  2410.         THIS.nRecCount = RECC()
  2411.         THIS.nTmpCount = 1      && reset
  2412.  
  2413.         *- External preprocessor hook
  2414.           THIS.PreForm
  2415.  
  2416.         *- Create new PJX file here
  2417.         THIS.CreatePJX
  2418.  
  2419.         *- Add records from old PJX file
  2420.         SELECT (THIS.pjx25Alias)
  2421.  
  2422.         *- next, do all the screens
  2423.         FOR m.z = 1 TO THIS.highscxid    && will be 0 for 3.0
  2424.         
  2425.             *- Get screen set array to process screen sets
  2426.             THIS.lIsMain = .F.
  2427.             THIS.GetNextFset(m.z)
  2428.             
  2429.             *- Check to see if screen missing from project such as 
  2430.             *- when it is deleted since FoxPro uses next highest number.
  2431.             IF EMPTY(THIS.cOutFile)
  2432.                 LOOP
  2433.             ENDIF
  2434.  
  2435.             *- Call preprocessor external hook
  2436.             THIS.extproj
  2437.  
  2438.             aParms[12] = 1
  2439.  
  2440.             IF THIS.iPlatformCount > 1
  2441.                 *- convert multiple platforms in present
  2442.                 *- if multiple platforms, cycle through for each platform
  2443.                 DIMENSION aPlatforms[1]
  2444.                 aPlatforms[1] = ""
  2445.                 THIS.GetPlatformCount(THIS.a_s3files[1], @aPlatforms)
  2446.                 IF EMPTY(aPlatforms[1])
  2447.                     *- was unable to determine platforms
  2448.                     LOOP
  2449.                 ENDIF
  2450.                 IF ALEN(aPlatforms,1) > 1
  2451.                     IF ASCAN(aPlatforms,C_WINDOWS) > 0 AND ASCAN(aPlatforms,C_MAC) > 0
  2452.                         *- both platforms are there
  2453.                         aParms[12] = 2
  2454.                     ENDIF
  2455.                 ENDIF
  2456.             ELSE
  2457.                 aPlatforms[1] = THIS.GetPlatForm()
  2458.             ENDIF
  2459.  
  2460.             FOR m.iWhichPlat = 1 TO aParms[12]
  2461.  
  2462.                 *- Initialize form set object
  2463.                 aParms[13] = m.iWhichPlat
  2464.                 oForm = CREATEOBJ(THIS.scxConverterClass, @aParms, .F., .T.,.T.,.T.)    && no backup, 
  2465.                                                                                         && is a project, 
  2466.                                                                                         && show ext transpo dlog
  2467.                                                                                         && don;t compile (we do that all at once at the end)
  2468.  
  2469.                 IF TYPE("oForm") # "O"
  2470.                     *- object wasn't created (?)
  2471.                     THIS.lHadError = .T.
  2472.                 ELSE
  2473.                     IF oForm.lHadError
  2474.                         THIS.lHadError = .T.
  2475.                         *- try and close the file (jd 02/13/96)
  2476.                         IF USED(oForm.c25alias)
  2477.                             USE IN (oForm.c25alias)
  2478.                         ENDIF
  2479.                         RELEASE oForm            && dispose of object
  2480.                     ENDIF
  2481.                 ENDIF
  2482.                 
  2483.  
  2484.                 IF !THIS.lHadError
  2485.                     IF !oForm.lConverted
  2486.                         *- only convert the unconverted
  2487.                         oForm.Converter
  2488.                     ELSE
  2489.                         *- still need to know .SPR file location though
  2490.                         SELECT (THIS.pjx25Alias)
  2491.                         LOCATE FOR setid = m.z AND type = "S"
  2492.                         IF FOUND()
  2493.                             *- create an SPR file from the stored SPR code
  2494.                             THIS.cStubFile = FULLPATH(ALLTRIM(SUBSTR(outfile,1,AT(C_NULL,outfile)-1)),THIS.cHomeDir)
  2495.  
  2496.                             *- make sure this is a valid path
  2497.                             IF !IsDir(JUSTPATH(THIS.cStubFile))
  2498.                                 *- invalid path, so try and make a good one
  2499.                                 THIS.cStubFile = AddBS(THIS.cHomeDir) + JUSTFNAME(THIS.cStubFile)
  2500.                             ENDIF
  2501.  
  2502.                             SELECT (oForm.c25alias)
  2503.                             GO TOP
  2504.                             IF !EMPTY(user)
  2505.                                 COPY MEMO user TO (THIS.cStubFile)
  2506.                             ENDIF
  2507.                             THIS.WriteLog(THIS.cOutFile,C_FILECONV_LOC + C_CREATMSG_LOC)
  2508.                             IF USED(oForm.c25alias)
  2509.                                 USE IN (oForm.c25alias)
  2510.                             ENDIF
  2511.                         ELSE
  2512.                             *- error            
  2513.                             *- try and close the file (jd 02/13/96)
  2514.                             IF USED(oForm.c25alias)
  2515.                                 USE IN (oForm.c25alias)
  2516.                             ENDIF
  2517.                             THIS.lHadError = .T.
  2518.                             RELEASE oForm            && dispose of object
  2519.                             LOOP                    && continue converting
  2520.                         ENDIF
  2521.                     ENDIF
  2522.                 ELSE
  2523.                     *- reset this flag
  2524.                     THIS.lHadError = .F.
  2525.                 ENDIF && THIS.lHadError
  2526.  
  2527.             NEXT        && going through each platform
  2528.  
  2529.             *- get rid of temp files we created
  2530.             FOR m.i = 1 TO ALEN(THIS.a_s2files,1)
  2531.                 IF FILE(THIS.a_s2files[i,1])
  2532.                     DELETE FILE (THIS.a_s2files[i,1])
  2533.                 ENDIF
  2534.                 IF FILE(FORCEEXT((THIS.a_s2files[i,1]),C_SCTEXT))
  2535.                     DELETE FILE (FORCEEXT((THIS.a_s2files[i,1]),C_SCTEXT))
  2536.                 ENDIF
  2537.             NEXT
  2538.  
  2539.             *- add records to PJX file, even if not converted
  2540.             THIS.InsertSCX
  2541.  
  2542.             THIS.nScreenCtr = THIS.nScreenCtr + 1
  2543.  
  2544.         ENDFOR    && end of screen set loop
  2545.  
  2546.         gOTherm.Update2(N_THERM3X * 100,C_PROJTASK2_LOC)    && update project therm
  2547.  
  2548.         *- move other files to new project
  2549.         SELECT (THIS.pjx25Alias)
  2550.         SCAN FOR !DELETED()
  2551.             DO CASE
  2552.                 CASE type = C_SCREENSET
  2553.                     *- already handled above
  2554.                     LOOP
  2555.                 CASE type = C_SCREEN
  2556.                     *- already handled above
  2557.                     LOOP
  2558.                 CASE type = C_HEADER
  2559.                     *- already handled above
  2560.                     LOOP
  2561.                 CASE type $ C_VCXTYPE + C_SCXTYPE
  2562.                     *- we may need to set the 30 properties
  2563.                     IF THIS.lSet30Defaults
  2564.                         *- setup arrays with file names
  2565.                         *- dimension 1 = name of actual file that will be converted
  2566.                         *-           2 = arranged
  2567.                         *-           3 = original name of screen
  2568.  
  2569.                         DIMENSION THIS.a_s2files[1,3]
  2570.                         DIMENSION THIS.a_s3files[1]
  2571.  
  2572.                         THIS.a_s3files[1] = FULLPATH(ALLTRIM(;
  2573.                             IIF(AT(CHR(0),name) > 0,;
  2574.                                 SUBSTR(name,1,AT(CHR(0),name)-1),;
  2575.                                 name)),;
  2576.                             THIS.cHomeDir)
  2577.                         THIS.a_s2files[1,3] = JUSTFNAME(STRTRAN(name,C_NULL))
  2578.                         cext1 = JustExt(THIS.a_s2files[1,3])
  2579.                         cext2 = IIF(cext1 == C_VCXEXT, C_VCTEXT, C_SCTEXT)
  2580.                         THIS.a_s2files[1,1] = "S" + RIGHT(SYS(3),7) + '.' + m.cext1
  2581.                         IF THIS.lBackup
  2582.                             *- make sure the files are there
  2583.                             IF FILE(THIS.cBackDir + THIS.a_s2files[1,3]) AND FILE(FORCEEXT(THIS.cBackDir + THIS.a_s2files[1,3],m.cext2))
  2584.                                 COPY FILE (THIS.cBackDir + THIS.a_s2files[1,3]) TO (THIS.a_s2files[1,1])
  2585.                                 COPY FILE (FORCEEXT(THIS.cBackDir + THIS.a_s2files[1,3],m.cext2)) TO ;
  2586.                                     (FORCEEXT(THIS.a_s2files[1,1],m.cext2))
  2587.                             ELSE
  2588.                                 *- file not found
  2589.                                 THIS.WriteLog(E_FILE_LOC + THIS.a_s2files[1,3] + E_NOCONVERT1_LOC,"")
  2590.                                 THIS.cOutFile = ""
  2591.                                 LOOP
  2592.                             ENDIF
  2593.                         ELSE
  2594.                             IF !FILE(THIS.a_s3files[1]) OR !FILE(FORCEEXT(THIS.a_s3files[1],m.cext2))
  2595.                                 *- file not found
  2596.                                 THIS.WriteLog(E_FILE_LOC + THIS.a_s3files[1] + E_NOCONVERT1_LOC,"")
  2597.                                 THIS.cOutFile = ""
  2598.                                 LOOP
  2599.                             ENDIF
  2600.                             COPY FILE (THIS.a_s3files[1]) TO (THIS.a_s2files[1,1])
  2601.                             COPY FILE (FORCEEXT(THIS.a_s3files[1],m.cext2)) TO ;
  2602.                                 (FORCEEXT(THIS.a_s2files[1,1],m.cext2))
  2603.                         ENDIF
  2604.  
  2605.                         *- we set the 30 default values in the INIT, so throw object away when done
  2606.                         oForm = CREATEOBJ(THIS.scx30ConverterClass, @aParms, .F., .T.,.T.,.T.)    && no backup, 
  2607.                                                                                                 && is a project, 
  2608.                                                                                                 && show ext transpo dlog
  2609.                                                                                                 && don;t compile (we do that all at once at the end)
  2610.  
  2611.                         IF TYPE("oForm") # "O"
  2612.                             *- object wasn't created (?)
  2613.                             THIS.lHadError = .T.
  2614.                         ELSE
  2615.                             IF oForm.lHadError
  2616.                                 THIS.lHadError = .T.
  2617.                                 *- try and close the file
  2618.                                 IF USED(oForm.c25alias)
  2619.                                     USE IN (oForm.c25alias)
  2620.                                 ENDIF
  2621.                             ENDIF
  2622.  
  2623.                             oForm.Converter
  2624.  
  2625.                             oForm.oConvForm = .NULL.
  2626.  
  2627.                             RELEASE oForm            && dispose of object
  2628.                         ENDIF
  2629.  
  2630.                         
  2631.                         *- get rid of temp files we created
  2632.                         IF FILE(THIS.a_s2files[1,1])
  2633.                             COPY FILE (THIS.a_s2files[1,1]) TO (THIS.a_s3files[1])
  2634.                             DELETE FILE (THIS.a_s2files[1,1])
  2635.                         ENDIF
  2636.                         IF FILE(FORCEEXT((THIS.a_s2files[1,1]),m.cext2))
  2637.                             COPY FILE (FORCEEXT(THIS.a_s2files[1,1],m.cext2)) TO ;
  2638.                                 (FORCEEXT(THIS.a_s3files[1],m.cext2))
  2639.                             DELETE FILE (FORCEEXT((THIS.a_s2files[1,1]),m.cext2))
  2640.                         ENDIF
  2641.  
  2642.             
  2643.                     ENDIF
  2644.  
  2645.                     THIS.cOutFile = STRTRAN(EVAL(cOld + '.name'),C_NULL)
  2646.                     INSERT INTO (THIS.new30alias) ;
  2647.                         (name,mainprog,type,timestamp,homedir,exclude,key);
  2648.                         VALUES(EVAL(cOld + '.name'),;
  2649.                             EVAL(cOld + '.mainprog'),;
  2650.                             EVAL(cOld + '.type'),;
  2651.                             EVAL(cOld + '.timestamp'),;
  2652.                             EVAL(cOld + '.homedir'),;
  2653.                             EVAL(cOld + '.exclude'),;
  2654.                             UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  2655.                     THIS.p30to40
  2656.  
  2657.                 CASE type = C_REPORT OR type = C_LABEL
  2658.                     LOCAL m.cfrxext, m.cfrtext
  2659.                     m.cfrxext = IIF(type = C_REPORT,"FRX","LBX")
  2660.                     m.cfrtext = IIF(type = C_REPORT,"FRT","LBT")
  2661.                     *- Initialize report object
  2662.                     THIS.f2files = "F" + RIGHT(SYS(3),7) + '.' + m.cfrxext
  2663.                     THIS.f3files = FULLPATH(ALLTRIM(;
  2664.                         IIF(AT(CHR(0),name) > 0,;
  2665.                             SUBSTR(name,1,AT(CHR(0),name)-1),;
  2666.                             name)),;
  2667.                         THIS.cHomeDir)
  2668.                     IF !FILE(IIF(THIS.lBackUp,THIS.cBackDir + JUSTFNAME(THIS.f3files),THIS.f3files)) OR ;
  2669.                         !FILE(FORCEEXT(IIF(THIS.lBackUp,THIS.cBackDir + JUSTFNAME(THIS.f3files),THIS.f3files),m.cfrtext))
  2670.                         *- file not found
  2671.                         THIS.WriteLog(E_FILE_LOC + THIS.f3files + E_NOCONVERT1_LOC,"")
  2672.                         LOOP
  2673.                     ENDIF
  2674.                     COPY FILE (IIF(THIS.lBackUp,THIS.cBackDir + JUSTFNAME(THIS.f3files),THIS.f3files)) TO (THIS.f2files)
  2675.                     COPY FILE (FORCEEXT(IIF(THIS.lBackUp,THIS.cBackDir + JUSTFNAME(THIS.f3files),THIS.f3files),m.cfrtext)) TO ;
  2676.                         (FORCEEXT(THIS.f2files,m.cfrtext))
  2677.                     oForm = CREATEOBJ(THIS.frxConverterClass, @aParms, .F., .T., .T., .T.)
  2678.  
  2679.                     IF TYPE("oForm") # "O"
  2680.                         *- object wasn't created (?)
  2681.                         THIS.lHadError = .T.
  2682.                     ENDIF
  2683.  
  2684.                     IF !THIS.lHadError
  2685.                         IF !oForm.lHadError
  2686.                             IF !oForm.lConverted
  2687.                                 *- only convert the unconverted
  2688.                                 oForm.Converter
  2689.                             ELSE
  2690.                                 THIS.WriteLog(THIS.f3files,C_FILECONV_LOC + '.' + C_CRLF)
  2691.                                 IF USED(oForm.c25alias)
  2692.                                     USE IN (oForm.c25alias)
  2693.                                 ENDIF
  2694.                             ENDIF
  2695.                         ENDIF
  2696.                     ELSE
  2697.                         *- reset this flag
  2698.                         THIS.lHadError = .F.
  2699.                     ENDIF
  2700.  
  2701.                     *- erase temp files
  2702.                     IF FILE(THIS.f2files)
  2703.                         DELETE FILE (THIS.f2files)
  2704.                     ENDIF
  2705.                     IF FILE (FORCEEXT(THIS.f2files,m.cfrtext))
  2706.                         DELETE FILE (FORCEEXT(THIS.f2files,m.cfrtext))
  2707.                     ENDIF
  2708.  
  2709.                     INSERT INTO (THIS.new30alias) ;
  2710.                         (name,mainprog,type,timestamp,homedir,exclude,key);
  2711.                         VALUES(EVAL(cOld + '.name'),;
  2712.                             EVAL(cOld + '.mainprog'),;
  2713.                             EVAL(cOld + '.type'),;
  2714.                             EVAL(cOld + '.timestamp'),;
  2715.                             EVAL(cOld + '.homedir'),;
  2716.                             EVAL(cOld + '.exclude'),;
  2717.                             UPPER(LEFT(JUSTSTEM(THIS.f3files),LEN(key))))
  2718.                     THIS.p30to40
  2719.                     
  2720.                 CASE type = C_PRGTYPE
  2721.                     *- program -- check to make sure it isn;t a duplicate 
  2722.                     *- of an SPR already in the file
  2723.                     cSaveArea = SELECT()
  2724.                     THIS.cOutFile = STRTRAN(EVAL(cOld + '.name'),C_NULL)
  2725.                     SELECT (THIS.new30alias)
  2726.                     LOCATE FOR UPPER(JUSTFNAME(THIS.cOutFile)) $ UPPER(name)
  2727.                     IF FOUND()
  2728.                         *- .SPR file is already there, or it is a duplicate
  2729.                         *- log and continue
  2730.                         THIS.WriteLog(THIS.cOutFile,C_FILEFOUNDMSG_LOC)
  2731.                     ELSE
  2732.                         INSERT INTO (THIS.new30alias) ;
  2733.                             (name,mainprog,type,timestamp,homedir,exclude,key);
  2734.                             VALUES(EVAL(cOld + '.name'),;
  2735.                                 EVAL(cOld + '.mainprog'),;
  2736.                                 EVAL(cOld + '.type'),;
  2737.                                 EVAL(cOld + '.timestamp'),;
  2738.                                 EVAL(cOld + '.homedir'),;
  2739.                                 EVAL(cOld + '.exclude'),;
  2740.                                 UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  2741.                         THIS.p30to40
  2742.                         THIS.WriteLog(THIS.cOutFile,C_NOCONVMSG_LOC)
  2743.                     ENDIF
  2744.                     SELECT (m.cSaveArea)
  2745.                 OTHERWISE
  2746.                     THIS.cOutFile = STRTRAN(EVAL(cOld + '.name'),C_NULL)
  2747.                     INSERT INTO (THIS.new30alias) ;
  2748.                         (name,mainprog,type,timestamp,homedir,exclude,key);
  2749.                         VALUES(EVAL(cOld + '.name'),;
  2750.                             EVAL(cOld + '.mainprog'),;
  2751.                             EVAL(cOld + '.type'),;
  2752.                             EVAL(cOld + '.timestamp'),;
  2753.                             EVAL(cOld + '.homedir'),;
  2754.                             EVAL(cOld + '.exclude'),;
  2755.                             UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  2756.                     THIS.p30to40
  2757.                     THIS.WriteLog(THIS.cOutFile,C_NOCONVMSG_LOC)
  2758.             ENDCASE
  2759.         ENDSCAN
  2760.  
  2761.         SELECT (THIS.new30Alias)
  2762.         REPLACE TIMESTAMP WITH this.tstamp() + RECNO() ,;
  2763.             ID WITH timestamp FOR TYPE != 'H'
  2764.  
  2765.         *- compile the SCX files
  2766.         THIS.CompileAllScx
  2767.  
  2768.         *- compile the FRX files
  2769.         THIS.CompileAllFRX
  2770.  
  2771.         *- compile the DBC files
  2772.         THIS.CompileAllDBC
  2773.  
  2774.         *- Close project
  2775.         THIS.ClosePJX
  2776.  
  2777.         *- close up gOTherm
  2778.         gOTherm.Complete2
  2779.  
  2780.         gOPJX = .NULL.
  2781.  
  2782.         RETURN THIS.cCurrentFile
  2783.  
  2784.     ENDPROC    && PJXConverter:Converter
  2785.  
  2786.     *------------------
  2787.     PROCEDURE p30to40
  2788.     *------------------
  2789.     *- if it's a 30 pjx, copy USER and COMMENTS fields
  2790.         SELECT (this.new30Alias)
  2791.         IF TYPE(this.pjx25Alias+".Comments") # 'U'
  2792.             REPLACE Comments WITH ;
  2793.                 (EVAL(this.pjx25Alias+".Comments"))
  2794.         ENDIF
  2795.         IF TYPE(this.pjx25Alias+".User") # 'U'
  2796.             REPLACE User WITH ;
  2797.                 (EVAL(this.pjx25Alias+".User"))
  2798.         ENDIF
  2799.     ENDPROC
  2800.     
  2801.     *------------------
  2802.     PROCEDURE ExtProj
  2803.     *------------------
  2804.     *- this is an external hook to preprocess
  2805.     *- project object via subclassing
  2806.     ENDPROC
  2807.  
  2808.     *----------------------------------
  2809.     PROCEDURE InsertSCX            && PJXConverter
  2810.     *----------------------------------
  2811.         *- add appropriate record(s) to 3.0 PJX file
  2812.         PARAMETER lNoAddSPR
  2813.  
  2814.         LOCAL cFileName
  2815.  
  2816.         cFileName = SYS(2014,THIS.cOutFile,DBF(THIS.new30alias))
  2817.  
  2818.         INSERT INTO (THIS.new30alias) ;
  2819.             (name,timestamp,type,exclude,key);
  2820.             VALUES(;
  2821.                 cFileName + CHR(0),;
  2822.                 THIS.nTimeStamp,;
  2823.                 C_SCXTYPE,;
  2824.                 THIS.lExclude,;
  2825.                 UPPER(LEFT(JustFName(THIS.cOutFile),LEN(key))))
  2826.  
  2827.         IF THIS.iPlatformCount > 1 AND aParms[12] > 1
  2828.             *- converting more than one platform (i.e., also Mac) so add Mac form record
  2829.             m.cFileName = JustStem(cFileName) + C_MACEXT + "." + JustExt(cFileName)
  2830.             INSERT INTO (THIS.new30alias) ;
  2831.                 (name,timestamp,type,exclude,key);
  2832.                 VALUES(;
  2833.                     cFileName + CHR(0),;
  2834.                     THIS.nTimeStamp,;
  2835.                     C_SCXTYPE,;
  2836.                     THIS.lExclude,;
  2837.                     UPPER(LEFT(JustStem(THIS.cOutFile) + C_MACEXT + JustExt(THIS.cOutFile),LEN(key))))
  2838.         ENDIF
  2839.  
  2840.         IF !lNoAddSPR
  2841.             PJXConverterBase::InsertSCX
  2842.         ENDIF
  2843.  
  2844.     ENDPROC
  2845.  
  2846.     *------------------
  2847.     PROCEDURE Conv20PJX
  2848.     *------------------
  2849.         *- This converts a 2.0 project to a 2.5 one.
  2850.         *- transprt is built into this app
  2851.         LOCAL m.oldudfp
  2852.  
  2853.         gOTherm.SetTitle2(C_THERMMSG6_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  2854.         m.oldudfp = SET("UDFP")
  2855.         SET UDFP TO REFERENCE
  2856.         DO (gTransport) WITH THIS.pjxName,1,.F.,gAShowMe,m.gOTherm,THIS.cCurrentFile
  2857.         SET UDFP TO &oldudfp
  2858.         SET MESSAGE TO C_PROJTASK4_LOC
  2859.         gOTherm.SetTitle2(C_THERMMSG1_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  2860.         THIS.pjx25Alias = THIS.OpenFile(THIS.pjxName)
  2861.         IF FCOUNT() # C_PJX25FLDS OR FIELD(1) # "NAME"
  2862.             USE IN (THIS.pjx25Alias)
  2863.             THIS.lHadError = .T.
  2864.             RETURN .F.
  2865.         ENDIF
  2866.         RETURN .T.
  2867.     ENDPROC                && PJXConverter
  2868.  
  2869.     *------------------
  2870.     PROCEDURE ClosePJX    && PJXConverter
  2871.     *------------------
  2872.         m.cTmpFname = FULLPATH(THIS.cCurrentFile,THIS.cHomeDir)
  2873.         *m.cTmpFname = FULLPATH(DBF(THIS.pjx25Alias),THIS.cHomeDir)
  2874.         m.cBackName = IIF(!EMPTY(THIS.cBackDir),THIS.cBackDir,"") + JUSTFNAME(THIS.cCurrentFile)    && JUSTFNAME(DBF(THIS.pjx25Alias))
  2875.  
  2876.         IF USED("_FOX3PJX")
  2877.             IF THIS.lDevMode
  2878.                 COPY MEMO _FOX3PJX.sprmemo TO (THIS.cCodeFile)
  2879.                 *- add the devmode code file to the project
  2880.                 INSERT INTO (THIS.new30alias) ;
  2881.                     (name,mainprog,type,timestamp,homedir,exclude,key);
  2882.                     VALUES(THIS.cCodeFile,;
  2883.                         .F.,;
  2884.                         C_PRGTYPE,;
  2885.                         THIS.nTimeStamp,;
  2886.                         THIS.cHomeDir,;
  2887.                         .F.,;
  2888.                         UPPER(LEFT(JUSTSTEM(THIS.cCodeFile),LEN(key))))
  2889.             ENDIF
  2890.             USE IN _FOX3PJX
  2891.         ENDIF
  2892.  
  2893.         THIS.CloseFiles
  2894.  
  2895.         *- get rid of temp file
  2896.         IF FILE(THIS.pjxName)
  2897.             DELETE FILE (THIS.pjxName)
  2898.         ENDIF
  2899.         IF FILE(FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  2900.             DELETE FILE (FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  2901.         ENDIF
  2902.  
  2903.         *- Rename new FP3 project
  2904.         DELETE FILE (m.cTmpFname)
  2905.         DELETE FILE (FORCEEXT(m.cTmpFname,"PJT"))
  2906.  
  2907.         IF FILE(ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJX")
  2908.             RENAME (ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJX") TO (m.cTmpFname)
  2909.         ENDIF
  2910.         IF FILE(ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJT")
  2911.             RENAME (ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJT") TO (FORCEEXT(m.cTmpFname,"PJT"))
  2912.         ENDIF
  2913.  
  2914.     ENDPROC        &&   ClosePJX
  2915.  
  2916.     *---------------------
  2917.     PROCEDURE GetNextFset
  2918.     *---------------------
  2919.         PARAMETER pSetid
  2920.         PRIVATE tmparr,i 
  2921.         
  2922.         THIS.curscxid = m.pSetid    && get current screen ID number
  2923.                 
  2924.         *- Handle project PJX file
  2925.         SELECT (THIS.pjx25Alias)
  2926.         
  2927.         SELECT name,arranged,exclude FROM DBF(THIS.pjx25Alias) ;
  2928.             WHERE type = "s" AND setid = pSetid AND !DELETED() ;
  2929.             ORDER by scrnorder ;
  2930.             INTO ARRAY tmparr
  2931.  
  2932.         IF _TALLY = 0
  2933.             *- Screen is missing from set, so skip and go to next one.
  2934.             THIS.cOutFile = ""
  2935.             RETURN
  2936.         ENDIF
  2937.         
  2938.         *- setup arrays with file names
  2939.         *- dimension 1 = name of actual file that will be converted
  2940.         *-           2 = arranged
  2941.         *-           3 = original name of screen
  2942.         DIMENSION THIS.a_s2files[_TALLY,3]
  2943.         DIMENSION THIS.a_s3files[_TALLY]
  2944.  
  2945.         THIS.lExclude = tmparr[1,3]
  2946.  
  2947.         FOR i = 1 TO _TALLY
  2948.             THIS.a_s3files[m.i] = FULLPATH(ALLTRIM(;
  2949.                 IIF(AT(CHR(0),tmparr[m.i,1]) > 0,;
  2950.                     SUBSTR(tmparr[m.i,1],1,AT(CHR(0),tmparr[m.i,1])-1),;
  2951.                     tmparr[m.i,1])),;
  2952.                 THIS.cHomeDir)
  2953.             THIS.a_s2files[m.i,1] = "S" + RIGHT(SYS(3),7) + ".SCX"
  2954.             THIS.a_s2files[m.i,3] = JUSTFNAME(STRTRAN(tmparr[m.i,1],C_NULL))
  2955.             IF THIS.lBackup
  2956.                 *- make sure the files are there
  2957.                 IF FILE(THIS.cBackDir + THIS.a_s2files[m.i,3]) AND FILE(FORCEEXT(THIS.cBackDir + THIS.a_s2files[m.i,3],C_SCTEXT))
  2958.                     COPY FILE (THIS.cBackDir + THIS.a_s2files[m.i,3]) TO (THIS.a_s2files[m.i,1])
  2959.                     COPY FILE (FORCEEXT(THIS.cBackDir + THIS.a_s2files[m.i,3],C_SCTEXT)) TO ;
  2960.                         (FORCEEXT(THIS.a_s2files[m.i,1],C_SCTEXT))
  2961.                 ELSE
  2962.                     *- Screen is missing, so skip
  2963.                     THIS.cOutFile = ""
  2964.                     RETURN
  2965.                 ENDIF
  2966.             ELSE
  2967.                 IF !FILE(THIS.a_s3files[m.i]) OR !FILE(FORCEEXT(THIS.a_s3files[m.i],C_SCTEXT))
  2968.                     *- file not found
  2969.                     THIS.WriteLog(E_FILE_LOC + THIS.a_s3files[m.i] + E_NOCONVERT1_LOC,"")
  2970.                     THIS.cOutFile = ""
  2971.                     RETURN
  2972.                 ENDIF
  2973.                 COPY FILE (THIS.a_s3files[m.i]) TO (THIS.a_s2files[m.i,1])
  2974.                 COPY FILE (FORCEEXT(THIS.a_s3files[m.i],C_SCTEXT)) TO ;
  2975.                     (FORCEEXT(THIS.a_s2files[m.i,1],C_SCTEXT))
  2976.             ENDIF
  2977.             THIS.a_s2files[m.i,2] = tmparr[m.i,2]
  2978.         ENDFOR
  2979.  
  2980.         *- Get output file SPR name and screen set settings
  2981.         LOCATE FOR setid = m.pSetid AND type = "S"
  2982.         IF FOUND()
  2983.             THIS.cStubFile = FULLPATH(ALLTRIM(SUBSTR(outfile,1,AT(C_NULL,outfile)-1)),THIS.cHomeDir)
  2984.             *- make sure this is a valid path
  2985.             IF !IsDir(JUSTPATH(THIS.cStubFile))
  2986.                 *- invalid path, so try and make a good one
  2987.                 THIS.cStubFile = AddBS(THIS.cHomeDir) + JUSTFNAME(THIS.cStubFile)
  2988.             ENDIF
  2989.         ELSE
  2990.             THIS.cOutFile = ""
  2991.             RETURN            
  2992.         ENDIF
  2993.  
  2994.         THIS.cOutFile = THIS.a_s3files[1,1]
  2995.  
  2996.         *- also, remember the main
  2997.         THIS.lIsMain = mainprog
  2998.             
  2999.         *- populate settings array with Project options
  3000.         THIS.a_pjxsets[A_OPENFILES]  = openFiles    && open DBF files
  3001.         THIS.a_pjxsets[A_CLOSEFILES] = closeFiles    && close DBF files
  3002.         THIS.a_pjxsets[A_DEFWINDOWS] = defwinds        && define windows
  3003.         THIS.a_pjxsets[A_RELWINDOWS] = relwinds        && release windows
  3004.         THIS.a_pjxsets[A_READMODAL]  = IIF(!EMPTY(assocwinds),.F.,modal)        && READ MODAL
  3005.         THIS.a_pjxsets[A_GETBORDERS] = nologo        && border for GETs
  3006.         THIS.a_pjxsets[A_READCYCLE]  = readcycle    && READ CYCLE
  3007.         THIS.a_pjxsets[A_READNOLOCK] = nolock        && READ NOLOCK
  3008.          THIS.a_pjxsets[A_MULTIREADS] = multreads    && multiple READs
  3009.          THIS.a_pjxsets[A_ASSOCWINDS] = assocwinds    && associated windows
  3010.  
  3011.         IF !THIS.a_pjxsets[9]  AND ALEN(THIS.a_s3files) > 1        && multireads
  3012.             DIMENSION THIS.a_s3files[1]
  3013.         ENDIF
  3014.  
  3015.         gOTherm.Update2((THIS.nScreenCtr/(THIS.nScreenSets + 1) * N_THERM2X + (1 - N_THERM2X)) * 100)    && (1) account for jump start we gave when backing up
  3016.                 
  3017.     ENDPROC        &&   GetNextFset
  3018.  
  3019. ENDDEFINE        &&  PJXConvert 
  3020.  
  3021.  
  3022. **********************************************
  3023. DEFINE CLASS FPCConverter AS PJXConverterBase
  3024. **********************************************
  3025.     *- class for converting 2.6 Catalog Files (FPC files)
  3026.     *- simpler file structure than projects
  3027.     *- files are converted individually -- just as if selecting
  3028.     *- each one by one
  3029.  
  3030.     *------------------
  3031.     PROCEDURE Init
  3032.     *------------------
  3033.         PARAMETER aParms
  3034.  
  3035.         *- temp until array stuff fixed
  3036.         PRIVATE tmparr
  3037.         LOCAL m.nct
  3038.             
  3039.         gOPJX = THIS
  3040.  
  3041.         SET ESCAPE ON
  3042.         ON ESCAPE DO EscHandler
  3043.  
  3044.         THIS.isproj = .F.        && not really a project
  3045.  
  3046.         THIS.nTimeStamp    = THIS.TStamp()
  3047.         THIS.pjxName    = aParms[4]
  3048.         THIS.pjxVersion = aParms[3]
  3049.         THIS.cBackDir    = aParms[1]
  3050.         THIS.lDevMode    = aParms[7]
  3051.         THIS.cCodeFile    = aParms[8]
  3052.         THIS.lLog        = aParms[9]
  3053.         THIS.cLogFile    = aParms[10]
  3054.         THIS.lBackup    = aParms[11]
  3055.         THIS.iPlatformCount    = aParms[12]
  3056.  
  3057.         THIS.cCurrentFile = THIS.pjxName
  3058.         THIS.cMemoExt = "FCT"
  3059.  
  3060.         IF THIS.lLog
  3061.             THIS.WriteLog(C_CONVLOG_LOC + THIS.pjxName + " [" + TTOC(DATETIME()) + "]","")
  3062.             THIS.WriteLog(C_CONVVERS_LOC + C_CONVERSION_LOC,"")
  3063.             THIS.WriteLog("","")
  3064.         ENDIF
  3065.  
  3066.         *- make a working copy of the PJX file, in case of transporting, so if
  3067.         *- user cancels, original will still be available
  3068.         *- this is here for compatibility with PJXConverter
  3069.         cTmpPjxName = ADDBS(JUSTPATH(THIS.pjxName)) + 'P' + LEFT(SYS(3),7) + ".FPC"
  3070.         COPY FILE (THIS.pjxName) TO (m.cTmpPjxName)
  3071.         IF FILE(FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  3072.             COPY FILE (FORCEEXT(THIS.pjxName,THIS.cMemoExt)) TO (FORCEEXT(m.cTmpPjxName,THIS.cMemoExt))
  3073.         ENDIF
  3074.         THIS.pjxName = m.cTmpPjxName
  3075.  
  3076.         THIS.pjx25Alias = THIS.OpenFile(THIS.pjxName)
  3077.         IF EMPTY(THIS.pjx25Alias)
  3078.             THIS.lHadError = .T.
  3079.             RETURN
  3080.         ENDIF
  3081.  
  3082.         *- Check for proper file format
  3083.         IF !(FCOUNT() = C_FPCFLDS AND FIELD(8) = "FOX_FILE")
  3084.             USE IN (THIS.pjx25Alias)
  3085.             THIS.lHadError=.T.
  3086.             =MESSAGEBOX(E_INVALFPC_LOC)
  3087.             RETURN
  3088.         ENDIF
  3089.  
  3090.         *- Add records from old CAT file
  3091.         SELECT (THIS.pjx25Alias)
  3092.         COUNT FOR !DELETED() AND INLIST(type,C_FPCSCREENTYPE,C_FPCLABELTYPE,C_FPCREPORTTYPE) TO THIS.nScreenSets
  3093.         THIS.nScreenSets = THIS.nScreenSets + 2
  3094.         THIS.curscxid = 1
  3095.  
  3096.         gOTherm.Update2(0,C_PROJTASK5_LOC)
  3097.         
  3098.         gOTherm.visible = .T.
  3099.  
  3100.         THIS.cBackDir = ADDBS(THIS.cBackDir)
  3101.         THIS.cHomeDir = ADDBS(JUSTPATH(THIS.pjxName))
  3102.  
  3103.         THIS.BackFiles("path", "scx|frx|lbx", C_CONVERT3c_LOC)    && backup screen, report & label files to back dir
  3104.         IF gOMaster.lHadError OR THIS.lHadError
  3105.             THIS.Cleanup
  3106.             THIS.lHadError = .T.
  3107.             RETURN .F.
  3108.         ENDIF
  3109.  
  3110.         gOTherm.Update2((THIS.curscxid/(THIS.nScreenSets + 1)) * 100,C_PROJTASK5_LOC)        && update therm with next task
  3111.     
  3112.     ENDPROC        &&    FPCConverter:Init
  3113.  
  3114.     *----------------------------------
  3115.     PROCEDURE Converter        && FPCConverter
  3116.     *----------------------------------
  3117.         *- convert FPC itself
  3118.         *- convert each of the objects in it
  3119.  
  3120.         PRIVATE i, z, oForm, cOld, cTmpFile
  3121.         PRIVATE g_platforms
  3122.         PRIVATE aParms,oConvObject
  3123.         LOCAL    iWhichPlat
  3124.         PRIVATE aPlatforms
  3125.  
  3126.         cOld = THIS.pjx25Alias
  3127.  
  3128.         *- Get record count for Thermometer
  3129.  
  3130.         *- External preprocessor hook
  3131.           THIS.PreForm
  3132.  
  3133.         *- Create new PJX file here
  3134.         THIS.CreatePJX
  3135.  
  3136.         *- Add records from old PJX file
  3137.         SELECT (THIS.pjx25Alias)
  3138.  
  3139.         SCAN FOR !DELETED()
  3140.  
  3141.             DO CASE
  3142.                 CASE type = C_FPCCATTYPE
  3143.                     THIS.WriteLog(SYS(2027,EVAL(cOld + '.path')),C_CONVMSG_LOC)
  3144.                 CASE type = C_FPCSCREENTYPE
  3145.                     THIS.curscxid = THIS.curscxid + 1
  3146.  
  3147.                     IF THIS.nScreenSets > 0
  3148.                         gOTherm.Update2((THIS.curscxid/THIS.nScreenSets) * 100,C_PROJTASK1_LOC)
  3149.                     ENDIF
  3150.  
  3151.                     * needed for GENSCRN stuff
  3152.                     DIMENSION g_platforms[1]
  3153.                     g_platforms = ""
  3154.  
  3155.                     *- simulate call from _converter
  3156.                     DIMENSION aParms[13]
  3157.                     aParms[ 2] = C_SCREENTYPEPARM        && file type
  3158.                     aParms[ 3] = THIS.pjxVersion        && file version
  3159.                     aParms[ 4] = ALLT(SYS(2027,path))    && FP30 file name
  3160.                     aParms[ 5] = .T.                    && platform only
  3161.                     aParms[ 6] = .F.                    && special effect
  3162.                     aParms[ 7] = THIS.lDevMode            && developer mode
  3163.                     aParms[ 8] = THIS.cCodeFile            && code file if dev mode
  3164.                     aParms[ 9] = THIS.llog                && create log file?
  3165.                     aParms[10] = THIS.cLogFile            && logfile name
  3166.                     aParms[12] = THIS.iPlatformCount    && current platform only?
  3167.                     *- some other values are set below, in the FOR ... NEXT loop
  3168.  
  3169.                     THIS.cStubFile = FORCEEXT(aParms[4],C_SPREXT)
  3170.                     THIS.cOutFile = aParms[4]
  3171.  
  3172.                     IF THIS.iPlatformCount > 1
  3173.                         *- convert multiple platforms in present
  3174.                         *- if multiple platforms, cycle through for each platform
  3175.                         DIMENSION aPlatforms[1]
  3176.                         aPlatforms[1] = ""
  3177.                         THIS.GetPlatformCount(aParms[4], @aPlatforms)
  3178.                         IF EMPTY(aPlatforms[1])
  3179.                             *- was unable to determine platforms
  3180.                             LOOP
  3181.                         ENDIF
  3182.                         IF ALEN(aPlatforms,1) > 1
  3183.                             IF ASCAN(aPlatforms,C_WINDOWS) > 0 AND ASCAN(aPlatforms,C_MAC) > 0
  3184.                                 *- both platforms are there
  3185.                                 aParms[12] = 2
  3186.                             ENDIF
  3187.                         ENDIF
  3188.                     ELSE
  3189.                         aPlatforms[1] = THIS.GetPlatForm()
  3190.                     ENDIF
  3191.  
  3192.                     FOR m.iWhichPlat = 1 TO aParms[12]
  3193.  
  3194.                         aParms[ 1] = ""                        && backup dir (not used)
  3195.                         aParms[13] = m.iWhichPlat
  3196.  
  3197.                         oConvObject = CREATE(THIS.scxConverterClass, @aParms,.F.,.F.,.T.,.T.)    && no backup, 
  3198.                                                                                                 && not a project, 
  3199.                                                                                                 && show ext transpo dlog
  3200.                                                                                                 && don;t compile (we do that all at once at the end)
  3201.                         IF TYPE("oConvObject") # 'O'
  3202.                             *- object was not created
  3203.                             THIS.lHadError = .T.
  3204.                                 THIS.WriteLog(SYS(2027,THIS.cOutFile),C_NOTCONVMSG_LOC)
  3205.                         ENDIF
  3206.  
  3207.                         IF !THIS.lHadError AND !oConvObject.lHadError 
  3208.                             IF !oConvObject.lConverted 
  3209.                                 oConvObject.Converter
  3210.                             ELSE
  3211.                                 *- still need to know .SPR file location though
  3212.                                 SELECT (THIS.pjx25Alias)
  3213.                                 *- create an SPR file from the stored SPR code
  3214.                                 SELECT (oConvObject.c25alias)
  3215.                                 GO TOP
  3216.                                 IF !EMPTY(user)
  3217.                                     COPY MEMO user TO (THIS.cStubFile)
  3218.                                     THIS.WriteLog(SYS(2027,THIS.cOutFile),C_FILECONV_LOC + C_CREATMSG_LOC)
  3219.                                     IF USED(oConvObject.c25alias)
  3220.                                         USE IN (oConvObject.c25alias)
  3221.                                     ENDIF
  3222.                                     THIS.EndLog(THIS.cOutFile)
  3223.                                 ELSE
  3224.                                     *- error            
  3225.                                     THIS.lHadError = .T.
  3226.                                     RELEASE oConvObject            && dispose of object
  3227.                                     LOOP                        && continue converting
  3228.                                 ENDIF
  3229.                             ENDIF
  3230.                         ENDIF
  3231.  
  3232.                     NEXT        && going through each platform
  3233.  
  3234.  
  3235.                     *- add records to PJX file
  3236.                     THIS.InsertSCX
  3237.  
  3238.                     RELEASE oConvObject
  3239.  
  3240.                 CASE type = C_FPCREPORTTYPE OR ;
  3241.                     type = C_FPCLABELTYPE
  3242.                     *- Initialize report object
  3243.                     *- simulate call from _converter
  3244.                     THIS.curscxid = THIS.curscxid + 1
  3245.  
  3246.                     IF THIS.nScreenSets > 0
  3247.                         gOTherm.Update2((THIS.curscxid/THIS.nScreenSets) * 100,C_PROJTASK2_LOC)
  3248.                     ENDIF
  3249.  
  3250.                     DIMENSION aParms[13]
  3251.                     aParms[ 1] = ""                        && backup dir (not used)
  3252.                     aParms[ 2] = "REPORT"                && file type
  3253.                     aParms[ 3] = THIS.pjxVersion        && file version
  3254.                     aParms[ 4] = ALLT(SYS(2027,path))    && FP30 file name
  3255.                     aParms[ 5] = .T.                    && platform only
  3256.                     aParms[ 6] = .F.                    && special effect
  3257.                     aParms[ 7] = THIS.lDevMode            && developer mode
  3258.                     aParms[ 8] = THIS.cCodeFile            && code file if dev mode
  3259.                     aParms[ 9] = THIS.llog                && create log file?
  3260.                     aParms[10] = THIS.cLogFile            && logfile name
  3261.  
  3262.                     THIS.f3files = aParms[4]
  3263.                     THIS.f2files = IIF(THIS.lBackup,THIS.cBackDir,"") + JUSTFNAME(STRTRAN(path,C_NULL))
  3264.                     oForm = CREATEOBJ(THIS.frxConverterClass, @aParms, .F.,.F.,.T.,.T.)
  3265.  
  3266.                     IF TYPE("oForm") # "O"
  3267.                         *- object wasn't created (?)
  3268.                         THIS.lHadError = .T.
  3269.                     ENDIF
  3270.  
  3271.                     IF !THIS.lHadError
  3272.                         IF !oForm.lHadError AND !THIS.lHadError
  3273.                             IF !oForm.lConverted
  3274.                                 *- only convert the unconverted
  3275.                                 oForm.Converter
  3276.                             ELSE
  3277.                                 THIS.WriteLog(SYS(2027,THIS.f3files),C_FILECONV_LOC + '.' + C_CRLF)
  3278.                                 IF USED(oForm.c25alias)
  3279.                                     USE IN (oForm.c25alias)
  3280.                                 ENDIF
  3281.                             ENDIF
  3282.                         ENDIF
  3283.                     ELSE
  3284.                         *- reset this flag
  3285.                         THIS.lHadError = .F.
  3286.                     ENDIF
  3287.  
  3288.                     INSERT INTO (THIS.new30alias) ;
  3289.                         (name,mainprog,type,timestamp,homedir,exclude,comments,key);
  3290.                         VALUES(EVAL(cOld + '.File_name'),;
  3291.                             .F.,;
  3292.                             IIF(EVAL(cOld + '.type') = C_FPCLABELTYPE,C_LABEL,C_REPORT),;
  3293.                             THIS.nTimeStamp,;
  3294.                             JUSTPATH(EVAL(cOld + '.path')),;
  3295.                             .F.,;
  3296.                             EVAL(cOld + '.Title') + C_NULL,;
  3297.                             UPPER(LEFT(JUSTSTEM(EVAL(cOld + '.path')),LEN(key))))
  3298.  
  3299.  
  3300.                 OTHERWISE
  3301.                     PRIVATE cType
  3302.                     m.cTmpFile = EVAL(cOld + '.path')
  3303.                     m.cType = EVAL(cOld + '.type')
  3304.                     m.cType = IIF(m.cType = C_FPCDBFTYPE,"D",;
  3305.                               IIF(m.cType = C_FPCCSQUERYTYPE OR ;
  3306.                                     m.ctype = C_FPCUPQUERYTYPE OR ;
  3307.                                     m.ctype = C_FPCSQLQUERYTYPE,"P",;
  3308.                               IIF(m.cType = C_FPCREPORTTYPE,"R",;
  3309.                               IIF(m.cType = C_FPCLABELTYPE,"B",;
  3310.                               IIF(m.cType = C_FPCPRGTYPE,"P",;
  3311.                               IIF(m.cType = C_FPCAPPTYPE,"Z","x"))))))
  3312.                     INSERT INTO (THIS.new30alias) ;
  3313.                         (name,type,timestamp,exclude,comments,key);
  3314.                         VALUES(m.cTmpFile,;
  3315.                             m.cType,;
  3316.                             THIS.nTimeStamp,;
  3317.                             .F.,;
  3318.                             EVAL(cOld + '.Title') + C_NULL,;
  3319.                             UPPER(LEFT(JUSTSTEM(m.cTmpFile),LEN(key))))
  3320.                     THIS.WriteLog(SYS(2027,m.cTmpFile),C_NOCONVMSG_LOC)
  3321.             ENDCASE
  3322.         ENDSCAN
  3323.  
  3324.         *- compile the SCX files
  3325.         THIS.CompileAllScx
  3326.  
  3327.         *- compile the FRX files
  3328.         THIS.CompileAllFRX
  3329.  
  3330.         *- Close project
  3331.         THIS.ClosePJX
  3332.  
  3333.         *- close up gOTherm
  3334.         gOTherm.Complete2
  3335.  
  3336.         gOPJX = .NULL.
  3337.  
  3338.         RETURN THIS.cFull30PJXName
  3339.  
  3340.     ENDPROC        && FPCConverter:Converter
  3341.  
  3342.  
  3343.     *----------------------------------
  3344.     PROCEDURE InsertSCX            && FPCConverter
  3345.     *----------------------------------
  3346.         *- add appropriate record(s) to 3.0 PJX file
  3347.         LOCAL cFileName
  3348.  
  3349.         cFileName = SYS(2014,THIS.cOutFile,DBF(THIS.new30alias))
  3350.  
  3351.         INSERT INTO (THIS.new30alias) ;
  3352.             (name,timestamp,type,exclude,comments,key);
  3353.             VALUES(;
  3354.                 m.cFileName + CHR(0),;
  3355.                 THIS.nTimeStamp,;
  3356.                 C_SCXTYPE,;
  3357.                 THIS.lExclude,;
  3358.                 EVAL(cOld + '.Title') + C_NULL,;
  3359.                 UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  3360.  
  3361.         IF THIS.iPlatformCount > 1 AND aParms[12] > 1
  3362.             *- converting more than one platform (i.e., also Mac) so add Mac form record
  3363.             m.cFileName = JustStem(cFileName) + C_MACEXT + "." + JustExt(cFileName)
  3364.             INSERT INTO (THIS.new30alias) ;
  3365.                 (name,timestamp,type,exclude,comments,key);
  3366.                 VALUES(;
  3367.                     cFileName + CHR(0),;
  3368.                     THIS.nTimeStamp,;
  3369.                     C_SCXTYPE,;
  3370.                     THIS.lExclude,;
  3371.                     EVAL(cOld + '.Title') + C_NULL,;
  3372.                     UPPER(LEFT(JustStem(THIS.cOutFile) + C_MACEXT + JustExt(THIS.cOutFile),LEN(key))))
  3373.         ENDIF
  3374.  
  3375.         PJXConverterBase::InsertSCX
  3376.  
  3377.     ENDPROC        && FPCConverter:InsertSCX
  3378.  
  3379.  
  3380.     *------------------------------------
  3381.     PROCEDURE Cleanup                    && FPCConverter
  3382.     *------------------------------------
  3383.         *- this proc is called by Error, and tries to put things back the way they were
  3384.         *- for catalogs, the originals have the x2x type extension. They need to be renamed.
  3385.  
  3386.         IF USED(THIS.pjx25Alias)
  3387.             SELECT file_name, type FROM DBF(THIS.pjx25Alias) ;
  3388.                 WHERE type $ C_FPCSCREENTYPE + C_FPCREPORTTYPE + C_FPCLABELTYPE AND !DELETED() ;
  3389.                 INTO ARRAY tmparr
  3390.         ELSE
  3391.             _TALLY = 0
  3392.         ENDIF
  3393.  
  3394.         *- force deletion of any lingering temp screen or report files
  3395.         IF _TALLY > 0
  3396.             m.nTables = AUSED(au)
  3397.             FOR i = 1 TO m.nTables
  3398.                 IF LEFT(au[i,1],1) = "S" OR LEFT(au[i,1],1) = "F"
  3399.                     cTmpFname = DBF(au[i,1])
  3400.                     cExt = UPPER(JustExt(cTmpFname))
  3401.                     IF ASCAN(tmparr,UPPER(JustFName(cTmpFName))) > 0
  3402.                         *- oops -- it;s one of the real ones
  3403.                         LOOP
  3404.                     ENDIF
  3405.                     IF INLIST(cExt,C_SCXEXT,"FRX","LBX")
  3406.                         USE IN (au[i,1])
  3407.                         ERASE (cTmpFname)
  3408.                         ERASE FORCEEXT(cTmpFname,IIF(m.cExt = C_SCXEXT,C_SCTEXT,;
  3409.                             IIF(m.cExt = "FRX","FRT","LBT")))
  3410.                     ENDIF
  3411.                 ENDIF
  3412.             NEXT
  3413.         ENDIF
  3414.  
  3415.         CLOSE TABLES
  3416.         IF THIS.lBackUp
  3417.             FOR i = 1 TO _TALLY
  3418.                 m.cTmpFname = FULLPATH(ALLTRIM(IIF(AT(CHR(0),tmparr[m.i,1]) > 0,;
  3419.                     LEFT(tmparr[m.i,1],AT(CHR(0),tmparr[m.i,1])-1),tmparr[m.i,1])),THIS.cHomeDir)
  3420.                 IF FILE(m.cTmpFname)
  3421.                     DO CASE
  3422.                         CASE tmparr[m.i,1] = C_SCXTYPE
  3423.                             IF    FILE(m.cTmpFname) AND ;
  3424.                                 FILE(FORCEEXT(m.cTmpFname,C_SCTEXT)) AND ;
  3425.                                 FILE(FORCEEXT(m.cTmpFname,C_SCXBACKEXT)) AND ;
  3426.                                 FILE(FORCEEXT(m.cTmpFname,C_SCTBACKEXT))
  3427.                                 DELETE FILE (m.cTmpFname)
  3428.                                 DELETE FILE (FORCEEXT(m.cTmpFname,C_SCTEXT))
  3429.                                 RENAME (FORCEEXT(m.cTmpFname,C_SCXBACKEXT)) TO (m.cTmpFname)
  3430.                                 RENAME (FORCEEXT(m.cTmpFname,C_SCTBACKEXT)) TO (FORCEEXT(m.cTmpFname,C_SCTEXT))
  3431.                             ENDIF
  3432.                         CASE tmparr[m.i,1] = C_REPORT
  3433.                             IF    FILE(m.cTmpFname) AND ;
  3434.                                 FILE(FORCEEXT(m.cTmpFname,"LBT")) AND ;
  3435.                                 FILE(FORCEEXT(m.cTmpFname,C_LBXBACKEXT)) AND ;
  3436.                                 FILE(FORCEEXT(m.cTmpFname,C_LBTBACKEXT))
  3437.                                 DELETE FILE (m.cTmpFname)
  3438.                                 DELETE FILE (FORCEEXT(m.cTmpFname,"LBT"))
  3439.                                 RENAME (FORCEEXT(m.cTmpFname,C_LBXBACKEXT)) TO (m.cTmpFname)
  3440.                                 RENAME (FORCEEXT(m.cTmpFname,C_LBTBACKEXT)) TO (FORCEEXT(m.cTmpFname,"LBT"))
  3441.                             ENDIF
  3442.                         CASE tmparr[m.i,1] = C_LABEL
  3443.                             IF    FILE(m.cTmpFname) AND ;
  3444.                                 FILE(FORCEEXT(m.cTmpFname,"FRT")) AND ;
  3445.                                 FILE(FORCEEXT(m.cTmpFname,C_FRXBACKEXT)) AND ;
  3446.                                 FILE(FORCEEXT(m.cTmpFname,C_FRTBACKEXT))
  3447.                                 DELETE FILE (m.cTmpFname)
  3448.                                 DELETE FILE (FORCEEXT(m.cTmpFname,"FRT"))
  3449.                                 RENAME (FORCEEXT(m.cTmpFname,C_FRXBACKEXT)) TO (m.cTmpFname)
  3450.                                 RENAME (FORCEEXT(m.cTmpFname,C_FRTBACKEXT)) TO (FORCEEXT(m.cTmpFname,"FRT"))
  3451.                             ENDIF
  3452.                     ENDCASE
  3453.                 ENDIF && cTmpFname (new file) exists
  3454.             NEXT
  3455.  
  3456.             *-now, erase files in backup dir
  3457.             =ADIR(af,THIS.cBackDir + "*.*")
  3458.             IF TYPE("af") # 'U'
  3459.                 FOR i = 1 TO ALEN(af,1)
  3460.                     IF af[i,5] $ 'RD'
  3461.                         LOOP
  3462.                     ENDIF
  3463.                     DELETE FILE (THIS.cBackDir + af[i,1])
  3464.                 NEXT
  3465.                 RELEASE af
  3466.             ENDIF
  3467.             IF ADIR(af,THIS.cBackDir + "*.*") = 0
  3468.                 IF TYPE("af") = 'U'
  3469.                     RD (THIS.cBackDir)
  3470.                 ENDIF
  3471.             ENDIF
  3472.         ENDIF && THIS.lBackUp
  3473.  
  3474.         IF FILE(THIS.PJXname)
  3475.             DELETE FILE (THIS.PJXname)
  3476.         ENDIF
  3477.         IF FILE(FORCEEXT(THIS.PJXname,"PJT"))
  3478.             DELETE FILE (FORCEEXT(THIS.PJXname,"PJT"))
  3479.         ENDIF
  3480.         IF FILE(FORCEEXT(THIS.PJXname,"FCT"))
  3481.             DELETE FILE (FORCEEXT(THIS.PJXname,"FCT"))
  3482.         ENDIF
  3483.  
  3484.     ENDPROC                    && FPCConverter:Cleanup
  3485.  
  3486.     *------------------
  3487.     PROCEDURE ClosePJX        && FPCConverter
  3488.     *------------------
  3489.         m.cTmpFname = FULLPATH(THIS.cCurrentFile,THIS.cHomeDir)
  3490.     
  3491.         THIS.CloseFiles
  3492.  
  3493.         THIS.cFull30PJXName = FORCEEXT(m.cTmpFname,"PJX")
  3494.  
  3495.         *- get rid of temp file
  3496.         IF FILE(THIS.pjxName)
  3497.             DELETE FILE (THIS.pjxName)
  3498.         ENDIF
  3499.         IF FILE(FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  3500.             DELETE FILE (FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  3501.         ENDIF
  3502.  
  3503.         *- get rid of original -- back-up has been saved away...
  3504.         IF THIS.lBackUp
  3505.             IF FILE(THIS.cCurrentFile)
  3506.                 DELETE FILE (THIS.cCurrentFile)
  3507.             ENDIF
  3508.             IF FILE(FORCEEXT(THIS.cCurrentFile,THIS.cMemoExt))
  3509.                 DELETE FILE (FORCEEXT(THIS.cCurrentFile,THIS.cMemoExt))
  3510.             ENDIF
  3511.         ENDIF
  3512.  
  3513.         IF FILE(THIS.cFull30PJXName)
  3514.             DELETE FILE (THIS.cFull30PJXName)
  3515.         ENDIF
  3516.         RENAME (ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJX") TO (THIS.cFull30PJXName)
  3517.  
  3518.         IF FILE(FORCEEXT(m.cTmpFname,"PJT"))
  3519.             DELETE FILE (FORCEEXT(m.cTmpFname,"PJT"))
  3520.         ENDIF
  3521.         RENAME (ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJT") TO (FORCEEXT(m.cTmpFname,"PJT"))
  3522.  
  3523.     ENDPROC        && FPCConverter:ClosePJX
  3524.  
  3525. ENDDEFINE        &&  FPCConverter
  3526.  
  3527. **********************************************
  3528. DEFINE CLASS SCXSingleScreenConverter AS ConverterBase
  3529. **********************************************
  3530.  
  3531.     *- If someone wants to do their own converter:
  3532.     *- create their own object classes, 
  3533.     *- sub-class this class, 
  3534.     *- store their object class names in these variables
  3535.  
  3536.     formclass        = "fp25form"
  3537.     labelclass        = "fp25lbl"
  3538.     sayclass        = "fp25say"
  3539.     lineclass        = "fp25line"
  3540.     shapeclass        = "fp25shape"
  3541.     editclass        = "fp25edit"
  3542.     getclass        = "fp25get"
  3543.     spinclass        = "fp25spin"
  3544.     cboxclass        = "fp25cbox"
  3545.     listclass        = "fp25list"
  3546.     popupclass        = "fp25popup"
  3547.     pictclass        = "fp25pict"
  3548.     radioclass        = "fp25radio"
  3549.     *-btnclass        = "fp25btn"
  3550.     btnclass        = "fp25btngrp"
  3551.     btngclass        = "fp25btngrp"
  3552.     *-invclass        = "fp25invbtn"
  3553.     invclass        = "fp25invgrp"
  3554.     invgclass        = "fp25invgrp"
  3555.     oleclass        = "fp25ole"
  3556.     datanavclass    = "fpdatanav"                && data navigation object & cursor object
  3557.     datanavRelationClass = "fpdatanavRelation"    && data navigation relation object
  3558.     
  3559.     specialfx = .T.                                && add special fx? (i.e., make controls 3D?)
  3560.  
  3561.     oConvForm = .NULL.
  3562.  
  3563.     *- Object instance variables
  3564.     nObjCount = 0
  3565.     cStubFile = ""
  3566.     scxcount = 0
  3567.     timestamp = 0
  3568.     cNewScx = ""                && New SCX file name
  3569.     isMultiPlat = .F.
  3570.     curPlat = ""
  3571.     savedPlat = ""                && the platform we save may not be the one we are on (VFP Mac SCX's always have WINDOWS)
  3572.     platform = ""
  3573.     parentName = ""
  3574.     cParms = ""                    && parameter statement -- if any
  3575.     formnum =  1
  3576.     fp3prop    = ""                && properties
  3577.     fp3method = ""                && methods
  3578.     GetBorder = .T.
  3579.     itse_expr = ""
  3580.     read_expr = ""
  3581.     wclause_expr = ""
  3582.     cWnameExpr = ""
  3583.     noReadExpr = .F.
  3584.     noReadPlainExpr = .F.
  3585.     fontsub = ""
  3586.     lMultiReads = .F.
  3587.     cBackDir = ""
  3588.     lUserCall = .T.
  3589.     projcall = .F.
  3590.     lHasDataNavObj = .F.
  3591.     lIndirectWinName = .F.
  3592.     cIndirectWinName = ""
  3593.     cFormName =""
  3594.     nDNOCount = 0
  3595.     nDNORecNo = 0                && remember record # of DataEnvironment (nee DNO) record
  3596.     lConverted = .F.            && catch scx's in 3.0 format
  3597.     cReadShow = ""                && collects code for SAYs that need to be refreshed
  3598.     nFSetRecno = 0                && formset record number
  3599.     nFormRecno = 0                && form record number
  3600.     cHeaderID = "Screen"        && UniqueID for header 1 record
  3601.     cDefineWin = ""                && DEFINE WINDOW command
  3602.     lHasInvis = .F.                && flag for if has invisible buttons
  3603.     cProcs = ""                    && accumulate Cleanup procs from multiple screens in set
  3604.     lHasIDX    = .F.                && IDX files used in environment?
  3605.     cMainCurs = ""                && alias of main table
  3606.     cWinNames = ""                && accumulate list of window names, to prevent duplicates
  3607.     iFormSetCtr = 0                && counter for formsets
  3608.     cFormSetName = ""            && formset name
  3609.  
  3610.     lhasSys16 = .F.                && does SYS(16) appear in code?
  3611.     lHasReturn = .F.            && code returns a value
  3612.     lNoCompile = .F.            && flag to determine whether to compile right away, or later, in batch
  3613.  
  3614.     iPlatformCount = 1            && how many platforms do we need to deal with?
  3615.     iWhichPlat = 1                && which platform are we doing?
  3616.  
  3617.     *- Arrays
  3618.     DIMENSION a_plat[1]
  3619.     a_plat = ""
  3620.     DIMENSION a_reads[8]
  3621.     a_reads = ""
  3622.     DIMENSION a_scx2files[1,3]
  3623.     a_scx2files = ""
  3624.     DIMENSION a_scx2alias[1]
  3625.     a_scx2alias = ""
  3626.     DIMENSION a_scx3files[1]
  3627.     a_scx3files = ""
  3628.     DIMENSION a_scx3alias[1]
  3629.     a_scx3alias = ""
  3630.     DIMENSION a_pjxsets[10]
  3631.     a_pjxsets= ""
  3632.  
  3633.     DIMENSION a_tables[1]
  3634.     DIMENSION a_torder[1]
  3635.     a_tables = ""
  3636.     a_torder = ""
  3637.  
  3638.     *------------------------------------
  3639.     PROCEDURE Init                && SCXSingleScreenConverter
  3640.     *------------------------------------
  3641.         PARAMETER aParms, lBackup, lProjCall, lForceTransportDlog, lNoCompile
  3642.  
  3643.         LOCAL m.imaxThisTime, m.imaxOtherTime
  3644.  
  3645.         THIS.oConvForm = THIS
  3646.  
  3647.         THIS.projcall = lProjCall
  3648.  
  3649.         THIS.lBackup = m.lBackup
  3650.  
  3651.         THIS.lTransDlog = lForceTransportDlog
  3652.  
  3653.         THIS.lNoCompile = lNoCompile
  3654.  
  3655.         THIS.lDevMode = aParms[7]
  3656.         THIS.cCodeFile = aParms[8]
  3657.         THIS.llog = aParms[9]
  3658.         THIS.cLogFile = aParms[10]
  3659.         THIS.iPlatformCount = MAX(aParms[12],1)
  3660.         THIS.iWhichPlat = aParms[13]
  3661.         THIS.savedPlat = C_WINDOWS                && always WINDOWS on VFP Mac (jd 03/27/96)
  3662.  
  3663.         PRIVATE j
  3664.  
  3665.         DIMENSION a_pjxsets[10]
  3666.         a_pjxsets= ""
  3667.  
  3668.         *- populate settings array with default options
  3669.         THIS.a_pjxsets[A_OPENFILES]  = IIF(THIS.projcall,gOPJX.a_pjxsets[A_OPENFILES],.T.)    && open DBF files
  3670.         THIS.a_pjxsets[A_CLOSEFILES] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_CloseFiles],.T.)    && close DBF files
  3671.         THIS.a_pjxsets[A_DEFWINDOWS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_DEFWINDOWS],.T.)    && define windows
  3672.         THIS.a_pjxsets[A_RELWINDOWS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_RELWINDOWS],.T.)    && release windows
  3673.         THIS.a_pjxsets[A_READMODAL]  = IIF(THIS.projcall,gOPJX.a_pjxsets[A_READMODAL],.F.)    && READ MODAL
  3674.         THIS.a_pjxsets[A_GETBORDERS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_GETBORDERS],.T.)    && border for GETs
  3675.         THIS.a_pjxsets[A_READCYCLE]  = IIF(THIS.projcall,gOPJX.a_pjxsets[A_READCYCLE],.T.)    && READ CYCLE
  3676.         THIS.a_pjxsets[A_READNOLOCK] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_READNOLOCK],.F.)    && READ NOLOCK
  3677.          THIS.a_pjxsets[A_MULTIREADS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_MULTIREADS],.F.)    && multiple READs
  3678.          THIS.a_pjxsets[A_ASSOCWINDS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_ASSOCWINDS],"")    && associated windows
  3679.         THIS.lMultiReads = THIS.a_pjxsets[A_MULTIREADS]
  3680.  
  3681.         THIS.lAutoClose = THIS.a_pjxsets[A_CLOSEFILES]
  3682.  
  3683.         IF THIS.projcall                                        && called from project
  3684.             THIS.cBackDir = gOPJX.cBackDir                        && used only for project
  3685.             DIMENSION THIS.a_scx2files[ALEN(gOPJX.a_s2files,1),3]
  3686.             DIMENSION THIS.a_scx3files[ALEN(gOPJX.a_s3files,1)]
  3687.             =ACOPY(gOPJX.a_s2files,THIS.a_scx2files)
  3688.             =ACOPY(gOPJX.a_s3files,THIS.a_scx3files)            
  3689.             THIS.cStubFile = gOPJX.cStubFile
  3690.             THIS.cNewScx = THIS.a_scx3files[1]
  3691.             IF !THIS.lMultiReads
  3692.                 DIMENSION THIS.a_scx3files[1]
  3693.             ENDIF
  3694.             THIS.cCurrentFile = THIS.a_scx2files[1,3]
  3695.         ELSE
  3696.             IF EMPTY(aParms[1])
  3697.                 THIS.lUserCall = .F.    && assume called without output file
  3698.                 aParms[1] = ADDBS(JUSTPATH(aParms[4])) + LEFT(SYS(3),7) + ".SCX"
  3699.                 THIS.cNewScx = aParms[4]
  3700.             ELSE
  3701.                 THIS.cNewScx = aParms[1]
  3702.             ENDIF
  3703.             THIS.a_scx3files[1] = aParms[1]
  3704.             THIS.cStubFile = FORCEEXT(THIS.cNewScx,C_SPREXT)
  3705.             DIMENSION THIS.a_scx2files[1,3]
  3706.             THIS.a_scx2files[1,1] = aParms[4]
  3707.             THIS.a_scx2files[1,2] = ""
  3708.             THIS.a_scx2files[1,3] = aParms[4]
  3709.             THIS.cCurrentFile = THIS.a_scx2files[1,3]
  3710.             *- go ahead and make backup now, before we start
  3711.             *- if screen needs to be transported, the original is around
  3712.             IF THIS.lBackUp
  3713.                 *- copy old screen with S2X,S2T extensions. No need to backup .SCR files
  3714.                 IF FILE(THIS.a_scx2files[1]) AND UPPER(JUSTEXT(THIS.a_scx2files[1])) = C_SCXEXT
  3715.                     COPY FILE (THIS.a_scx2files[1]) TO (FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  3716.                 ENDIF
  3717.                 IF FILE(FORCEEXT(THIS.a_scx2files[1],C_SCTEXT))
  3718.                     COPY FILE (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT)) TO (FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  3719.                 ENDIF
  3720.                 *- backup has been done
  3721.                 THIS.lBackUp = .F.
  3722.             ENDIF
  3723.         ENDIF
  3724.  
  3725.         gOTherm.SetTitle(C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  3726.         gOTherm.Update(0,"")
  3727.         gOTherm.visible = .T.
  3728.  
  3729.         THIS.platform = THIS.GetPlatForm(THIS.iWhichPlat)
  3730.  
  3731.         THIS.WriteLog("","")                    && force a blank line
  3732.         THIS.BeginLog(SYS(2027,THIS.cNewScx) + IIF(THIS.platform == C_MAC AND THIS.iPlatformCount > 1, " " + C_MACLOGMSG_LOC,""))
  3733.  
  3734.         THIS.nTimeStamp = THIS.TStamp()
  3735.         THIS.scxcount = ALEN(THIS.a_scx2files,1)
  3736.  
  3737.         DIMENSION THIS.a_scx2alias[THIS.scxcount]
  3738.  
  3739.         FOR j = 1 TO THIS.scxcount
  3740.  
  3741.             IF !THIS.KnownFile(THIS.a_scx2files[m.j,1])
  3742.                 *- unknown file format -- error has already been written to the log
  3743.                 THIS.oConvForm = .NULL.
  3744.                 IF !THIS.projcall
  3745.                     *- attempt to remove backup files (jd 04/16/96)
  3746.                     THIS.EraseBackup
  3747.                 ENDIF
  3748.                 RETURN .F.
  3749.             ENDIF
  3750.  
  3751.             *- also check Read-Only status if project call (04/15/96 jd)
  3752.             IF THIS.projcall AND pReadOnly(THIS.cNewSCX)
  3753.                 THIS.WriteLog(JUSTFNAME(THIS.cNewSCX),TRIM(E_FILE_LOC) + E_NOCONVERT3_LOC)
  3754.                 RETURN .F.
  3755.             ENDIF
  3756.  
  3757.             *- now try to open SCX file -- returns alias
  3758.             THIS.a_scx2alias[m.j] = THIS.OpenFile(THIS.a_scx2files[m.j,1])
  3759.                 
  3760.             IF EMPTY(THIS.a_scx2alias[m.j])
  3761.                 *- error has been logged
  3762.                 THIS.oConvForm = .NULL.
  3763.                 IF !THIS.projcall
  3764.                     *- attempt to remove backup files (jd 04/16/96)
  3765.                     THIS.EraseBackup
  3766.                 ENDIF
  3767.                 RETURN .F.
  3768.             ENDIF
  3769.  
  3770.             IF j = 1
  3771.                 THIS.c25alias = THIS.a_scx2alias[m.j]
  3772.             ENDIF
  3773.  
  3774.             *- Check for file format
  3775.             DO CASE
  3776.                 CASE FCOUNT() = C_SCXFLDS AND FIELD(1) = "PLATFORM"
  3777.                     *- 2.5 SCX type
  3778.                     LOCATE FOR PLATFORM = THIS.platform
  3779.                     IF !FOUND()
  3780.                         *-  no platform objects for the current platform
  3781.                         IF !THIS.Conv20SCX(12)
  3782.                             THIS.lHadError = .T.
  3783.                             THIS.oConvForm = .NULL.
  3784.                             THIS.EraseBackup
  3785.                             RETURN
  3786.                         ENDIF
  3787.                     ELSE
  3788.                         *- check to see if any records are later than current platform records
  3789.                         *- if so, call transporter
  3790.                         CALCULATE MAX(timestamp) FOR platform = THIS.platform TO m.imaxThisTime
  3791.                         CALCULATE MAX(timestamp) FOR platform # THIS.platform TO m.imaxOtherTime
  3792.                         IF m.imaxOtherTime > m.imaxThisTime
  3793.                             IF !THIS.Conv20SCX(12)
  3794.                                 THIS.lHadError = .T.
  3795.                                 THIS.oConvForm = .NULL.
  3796.                                 THIS.EraseBackup
  3797.                                 RETURN
  3798.                             ENDIF
  3799.                         ENDIF
  3800.                     ENDIF
  3801.                 CASE FCOUNT() = C_20SCXFLDS AND FIELD(1) = "OBJTYPE"
  3802.                     *- 2.0 SCX type
  3803.                     *- Invoke Transporter
  3804.                     *- =MESSAGEBOX(E_HAS20FILE_LOC)
  3805.                     IF !THIS.Conv20SCX(2)
  3806.                         THIS.lHadError = .T.
  3807.                         THIS.oConvForm = .NULL.
  3808.                         THIS.EraseBackup
  3809.                         RETURN
  3810.                     ENDIF
  3811.                 CASE FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  3812.                     *- assume 3.0 format, screen was already converted
  3813.                     *- (this could be called while converting a 2.x Project
  3814.                     *- that contains scx's that have already been converted)
  3815.                     IF j = 1
  3816.                         *- some of the defaults for VFP 4.0 have changed. So if user
  3817.                         *- elected to retain the 3.0 behavior/defaults, we need to explicitly
  3818.                         *- write out those properties (05/14/96 jd)
  3819.                         *- this means that the checkbox is checked
  3820.                         IF !THIS.Set30Defaults()
  3821.                             THIS.lHadError = .T.
  3822.                             THIS.oConvForm = .NULL.
  3823.                             THIS.EraseBackup
  3824.                         ENDIF
  3825.                         THIS.lConverted = .T.    && only set this if main screen
  3826.                         RETURN
  3827.                     ELSE
  3828.                         *- screen is converted, but part of a screen set, so allow to continue
  3829.                     ENDIF
  3830.                 OTHERWISE
  3831.                     USE IN (THIS.a_scx2alias[m.j])
  3832.                     THIS.WriteLog(JUSTFNAME(THIS.a_scx2files[m.j,1]),TRIM(E_WRONGFMT_LOC) + E_NOCONVERT_LOC)
  3833.                     THIS.oConvForm = .NULL.
  3834.                     RETURN
  3835.             ENDCASE
  3836.         
  3837.         ENDFOR    && end of opening SCX files in set
  3838.         
  3839.         *- this cursor is for working with memo fields
  3840.         IF USED("_FOX3SPR")
  3841.           USE IN _FOX3SPR
  3842.         ENDIF
  3843.  
  3844.         CREATE CURSOR _FOX3SPR (sprmemo m, temp1 m, temp2 m, temp3 m, temp4 m,defines m, load m, code m)
  3845.         APPEND BLANK
  3846.         REPLACE _FOX3SPR.load WITH "PROCEDURE " + C_DELOAD_METH + C_CR, ;
  3847.             _FOX3SPR.code WITH C_CRLF + C_CODEHDR1_LOC + C_CODEHDR_LOC + THIS.a_scx2files[1,3] + C_CRLF + C_CODEHDR1_LOC + C_CRLF
  3848.  
  3849.         IF THIS.lDevMode AND THIS.projcall AND USED("_FOX3PJX")
  3850.             *- accumulate all of code in final screen
  3851.             REPLACE  _FOX3SPR.sprmemo WITH _FOX3PJX.sprmemo + C_CR
  3852.         ENDIF
  3853.  
  3854.         SELECT (THIS.c25alias)
  3855.  
  3856.     ENDPROC        &&  SCXSingleScreenConverter:Init
  3857.     
  3858.     *----------------------------------
  3859.     PROCEDURE Converter        && SCXSingleScreenConverter
  3860.     *----------------------------------
  3861.         PRIVATE i, j
  3862.         LOCAL oRec, nrec, cFormset
  3863.  
  3864.         *- Get platforms used in Screen Set
  3865.         *- returns total records to process for Thermometer
  3866.         THIS.nRecCount = THIS.ScanPlat(THIS.platform) * THIS.iPlatformCount        && accommodate doing multiple platforms
  3867.         THIS.nTmpCount = 1      && reset
  3868.  
  3869.         gOTherm.SetTitle(C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  3870.         gOTherm.Update(0)
  3871.  
  3872.         *- External preprocessor hook
  3873.           THIS.PreForm
  3874.  
  3875.         *- Create new SCX file(s) here
  3876.         *- Multiple files created if MultiReads option.
  3877.         THIS.CreateSCX
  3878.         THIS.new30alias = THIS.a_scx3alias[1]
  3879.  
  3880.         *- Add objects by platform
  3881.         FOR m.i = 1 TO 1        && ALEN(THIS.a_plat)
  3882.  
  3883.             *- Add environment info
  3884.             SELECT (THIS.c25alias)        && only check first file
  3885.  
  3886.             GO TOP
  3887.             IF environ
  3888.                 LOCATE FOR INLIST(objtype,2,3,4) AND platform = THIS.a_plat[m.i] 
  3889.                 IF FOUND()
  3890.                     THIS.AddSRecs(m.i,C_DNO)
  3891.                 ENDIF
  3892.             ENDIF
  3893.             
  3894.             *- check for indirect reference to window name (name expr)
  3895.             IF LEFT(name,1) = "("
  3896.                 *- indirect ref to window name
  3897.                 *- make up a munged name
  3898.                 m.ctmpname = ALLT(name)
  3899.                 THIS.cFormName = T_FORM + "1"
  3900.                 THIS.lIndirectWinName = .T.
  3901.                 THIS.cIndirectWinName = SUBS(m.ctmpname,2,LEN(m.ctmpname) - 2)
  3902.             ENDIF
  3903.  
  3904.             *- Create Screen Set object
  3905.             THIS.AddFSet(THIS.a_plat[m.i])
  3906.  
  3907.             gOTherm.Update(THIS.nTmpCount/THIS.nRecCount * 100)
  3908.  
  3909.             FOR m.j = 1 TO THIS.scxcount
  3910.  
  3911.                 *- Use separate files if Multi-Read option
  3912.                 IF THIS.lMultiReads
  3913.                     THIS.new30alias = THIS.a_scx3alias[m.j]
  3914.                 ENDIF
  3915.                 
  3916.                 *- Select screen to process in screen set
  3917.                 SELECT (THIS.a_scx2alias[m.j])
  3918.                 THIS.formnum = m.j
  3919.  
  3920.                 *- if this screen isn;t the main screen, it may already have been converted
  3921.                 *- so... just add the records to the main screen
  3922.                 IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  3923.                     *- this screen was already converted
  3924.                     LOCATE FOR class = T_FSET
  3925.                     m.cFormSet = objname
  3926.                     USE
  3927.                     SELECT (THIS.new30alias)
  3928.                     m.nRec = RECC()
  3929.                     APPEND FROM (THIS.cBackDir + THIS.a_scx2files[m.j,3]) FOR uniqueid # "Screen" AND uniqueid # "FONTINFO" AND LOWER(class) # "formset"
  3930.                     REPLACE ALL uniqueID WITH "~" + CHR(64 + j) FOR RECNO() > m.nrec
  3931.                     REPLACE ALL parent WITH STRTRAN(parent,m.cFormSet,THIS.cFormSetName)    && change formset to this formset
  3932.                     SELECT (THIS.c25alias)
  3933.                     LOOP
  3934.                 ENDIF
  3935.  
  3936.                 *- Add Screen objects
  3937.                 THIS.AddSRecs(m.i,C_CONTROLS)
  3938.                 IF THIS.lHadError    && RED00N4G
  3939.                     RETURN -1
  3940.                 ENDIF
  3941.             
  3942.                 *- collect procs for this screen
  3943.                 THIS.AddProcs1
  3944.  
  3945.                 IF m.j = 1 OR THIS.lMultiReads
  3946.                     *- Write FontInfo -- there is only a single record for 
  3947.                     *- FontInfo regardless of number of forms.
  3948.                     THIS.WriteFontSub()
  3949.                 ENDIF
  3950.  
  3951.                 IF m.j > 1 AND THIS.lMultiReads AND THIS.projcall
  3952.                     LOCAL m.cOldOutFile
  3953.                     m.cOldOutFile = goPJX.cOutFile
  3954.                     goPJX.cOutFile = THIS.a_scx3Files[j]
  3955.                     goPJX.InsertSCX(.T.)
  3956.                     goPJX.cOutFile = m.cOldOutFile
  3957.                 ENDIF
  3958.  
  3959.                ENDFOR  && end of screen loop
  3960.  
  3961.  
  3962.         ENDFOR    && end of platform loop
  3963.  
  3964.         *- Add stub file (SPR) statements
  3965.         SELECT (THIS.c25alias)
  3966.         THIS.AddParm
  3967.  
  3968.         *- Add Cleanup snippet procs/funcs code here for SPR file
  3969.         THIS.AddGenProcs
  3970.  
  3971.         *- add SAY refresh code into FormSet.ReadShow method
  3972.         THIS.UpdMethods
  3973.  
  3974.         *- External postprocessor hook
  3975.           THIS.PostForm
  3976.  
  3977.         *- Close screen files
  3978.         THIS.CloseFiles
  3979.  
  3980.         *- close up gOTherm
  3981.         IF THIS.iWhichPlat == THIS.iPlatformCount
  3982.             *- don;t stop thermometer unless we are really done...
  3983.             gOTherm.Complete
  3984.         ENDIF
  3985.  
  3986.         *- release the reference
  3987.         THIS.oConvForm = .NULL.
  3988.  
  3989.         *- write to log file
  3990.         THIS.EndLog(THIS.cNewScx + IIF(THIS.platform == C_MAC AND THIS.iPlatformCount > 1, " " + C_MACLOGMSG_LOC,""))
  3991.  
  3992.         RETURN THIS.a_scx2files[1,1]
  3993.  
  3994.     ENDPROC    && SCXSingleScreenConverter:Converter
  3995.  
  3996.     *------------------
  3997.     PROCEDURE EraseBackup            && SCXSingleScreenConverter
  3998.     *------------------
  3999.         IF FILE(FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  4000.             ERASE (FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  4001.         ENDIF
  4002.         IF FILE(FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  4003.             ERASE (FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  4004.         ENDIF
  4005.     ENDPROC
  4006.  
  4007.     *------------------
  4008.     PROCEDURE KnownFile            && SCXSingleScreenConverter
  4009.     *------------------
  4010.         *- verify that the file is a known format
  4011.         *- we only test for previous versions of FoxPro, .FMT files, and dBASE IV .scr files
  4012.         PARAMETER cFileName
  4013.  
  4014.         LOCAL oThis, cNewSCXName
  4015.         oThis = THIS
  4016.         cNewSCXName = m.cFileName
  4017.  
  4018.         *- does file exist?
  4019.         IF FILE(m.cFileName)
  4020.             *- can it be opened?
  4021.             IF Readable(m.cFileName)
  4022.                 *- is it a DBF?
  4023.                 IF !THIS.IsDBF(m.cFileName)
  4024.                     *- not a DBF, so try and migrate it
  4025.                     SET MESSAGE TO C_MIGRATEMSG_LOC
  4026.                     gOTherm.SetTitle(C_THERMMSG11_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  4027.                     IF !MigDB4(m.cFileName, @oThis)
  4028.                         THIS.WriteLog(JUSTFNAME(m.cFileName),E_NOMIG_LOC)
  4029.                         =MESSAGEBOX(E_WRONGFMT_LOC + " " + E_NOCONVERT_LOC)
  4030.                         THIS.lHadError=.T.
  4031.                         oThis = .NULL.
  4032.                         RETURN .F.
  4033.                     ELSE
  4034.                         *- go ahead and transport
  4035.                         IF FILE(FORCEEXT(m.cNewSCXName,C_SCXEXT)) AND FILE(FORCEEXT(m.cNewSCXName,C_SCTEXT))
  4036.                             *- assume migrated okay, so update names of files we are working with
  4037.                             THIS.a_scx2files[m.j,1] = FORCEEXT(m.cNewSCXName,C_SCXEXT)
  4038.                             THIS.cCurrentFile = THIS.a_scx2files[m.j,1]
  4039.                         ELSE
  4040.                             =MESSAGEBOX(E_NOMIG_LOC + " " + E_NOCONVERT_LOC)
  4041.                             THIS.lHadError=.T.
  4042.                             oThis = .NULL.
  4043.                             RETURN .F.
  4044.                         ENDIF
  4045.                         gOTherm.SetTitle(C_THERMMSG7_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  4046.                         gOTherm.Update(0,"")
  4047.                         LOCAL m.lOldScxShow
  4048.                         m.lOldScxShow = gAShowMe[N_TRANFILE_SCX,1]
  4049.                         gAShowMe[N_TRANFILE_SCX,1] = .F.
  4050.                         DO (gTransport) WITH THIS.cCurrentFile,12,.F.,gAShowMe, m.gOTherm,THIS.cCurrentFile
  4051.                         gAShowMe[N_TRANFILE_SCX,1] = m.lOldScxShow
  4052.                     ENDIF
  4053.                 ENDIF
  4054.             ENDIF
  4055.         ENDIF
  4056.         oThis = .NULL.
  4057.  
  4058.     ENDFUNC        && SCXSingleScreenConverter:KnownFile
  4059.  
  4060.     *------------------
  4061.     PROCEDURE CreateSCX            && SCXSingleScreenConverter
  4062.     *------------------
  4063.         PRIVATE m.cScxName,m.tmpalias,m.j
  4064.         *- Note: only create more than 1 new SCX table if 
  4065.         *- Multi-Read generate option is selected. Otherwise
  4066.         *- terminate at end of first loop.
  4067.         
  4068.         FOR m.j = 1 TO THIS.scxcount
  4069.             m.cScxName = THIS.a_scx3files[m.j]
  4070.             DIMENSION THIS.a_scx3alias[m.j]
  4071.  
  4072.             *- create new SCX file
  4073.             CREATE TABLE (m.cScxName) ;
  4074.                 (platform c(8),;
  4075.                 uniqueid c(10),;
  4076.                 timestamp n(10),;
  4077.                 class m,;
  4078.                 classloc m,;
  4079.                 baseclass m,;
  4080.                 objname m,;
  4081.                 parent m,;
  4082.                 properties m,;
  4083.                 protected m,;
  4084.                 methods m,;
  4085.                 objcode m,;
  4086.                 ole m,;
  4087.                 ole2 m,;
  4088.                 reserved1 m,;
  4089.                 reserved2 m,;
  4090.                 reserved3 m,;
  4091.                 reserved4 m,;
  4092.                 reserved5 m,;
  4093.                 reserved6 m,;
  4094.                 reserved7 m,;
  4095.                 reserved8 m,;
  4096.                 user m)
  4097.  
  4098.             m.tmpalias = ALIAS()
  4099.             THIS.a_scx3alias[m.j] = ALIAS()
  4100.  
  4101.             *- Add header comment record
  4102.             INSERT INTO (m.tmpalias) ;
  4103.                 (platform,uniqueid,reserved1);
  4104.                 VALUES ("COMMENT",THIS.cHeaderID,C_SCXVERSTAMP)
  4105.  
  4106.             IF !THIS.lMultiReads
  4107.                 EXIT
  4108.             ENDIF
  4109.         ENDFOR
  4110.  
  4111.     ENDPROC            && SCXSingleScreenConverter
  4112.     
  4113.     *------------------
  4114.     PROCEDURE Conv20SCX
  4115.     *------------------
  4116.     *- This converts a foreign scx to a 2.x current platform.
  4117.         PARAMETER m.scxtype
  4118.         *- m.scxtype = 12        && FP2.5 SCX format
  4119.         *- m.scxtype = 2        && FP2.0 SCX format
  4120.         LOCAL m.oldudfp
  4121.         LOCAL m.cOldMess
  4122.  
  4123.         USE IN (THIS.a_scx2alias[m.j])
  4124.         gOTherm.SetTitle(C_THERMMSG7_LOC + LOWER(PARTIALFNAME(THIS.a_scx2files[m.j,3],C_FILELEN)))
  4125.         m.oldudfp = SET("UDFP")
  4126.         SET UDFP TO REFERENCE
  4127.         m.cOldMess = SET("MESSAGE",1)
  4128.         DO (gTransport) WITH THIS.a_scx2files[m.j,1],m.scxtype,.F.,gAShowMe, m.gOTherm,THIS.a_scx2files[m.j,3],THIS.lTransDlog
  4129.         SET UDFP TO &oldudfp
  4130.         SET MESSAGE TO (cOldMess)
  4131.         THIS.a_scx2alias[m.j] = THIS.OpenFile(THIS.a_scx2files[m.j,1])
  4132.         THIS.c25alias = THIS.a_scx2alias[m.j]
  4133.         IF !EMPTY(THIS.a_scx2alias[m.j])
  4134.             IF FCOUNT() = C_SCXFLDS AND FIELD(1) = "PLATFORM"
  4135.                 LOCATE FOR Platform = THIS.Platform
  4136.                 IF FOUND()
  4137.                     RETURN .T.
  4138.                 ENDIF
  4139.             ENDIF
  4140.             USE IN (THIS.a_scx2alias[m.j])
  4141.         ENDIF
  4142.         THIS.lHadError=.T.
  4143.         RETURN .F.
  4144.     ENDPROC
  4145.  
  4146.     *------------------------------------
  4147.     PROCEDURE AddParm            && SCXSingleScreenConverter
  4148.     *------------------------------------
  4149.         PRIVATE j,cScxName
  4150.         LOCAL nParmCount, cParmCont, k, cParmCode, cParmA, npos
  4151.         LOCAL aTemp, cTmpText, cItem, nArryLen, cPubList, k, cDoForm
  4152.  
  4153.         cPubList = ""
  4154.  
  4155.         *- Base parameter statement on first SCX only in FP25.
  4156.         LOCATE FOR objtype = 1
  4157.         THIS.cParms = GetParam("setupcode")
  4158.         
  4159.         *- assume THIS.cParms was set in AddReads earlier
  4160.         IF !EMPTY(THIS.cParms)
  4161.             REPLACE _FOX3SPR.sprmemo WITH ;
  4162.                 C_PARM1_CMMT_LOC + ;
  4163.                 "PARAMETERS " + THIS.cParms + C_CRLF ADDITIVE
  4164.  
  4165.             *- need to add special code in case no parms passed, so 
  4166.             *- we don;t pass on default parms that shouldn;t be there
  4167.             m.nParmCount = OCCURS(",",THIS.cParms) + 1
  4168.             cParmCode = C_CRLF + ;
  4169.                         "LOCAL _aParm, _cparmstr, _nctr" + C_CRLF + ;
  4170.                         "DIMENSION _aParm[" + LTRIM(STR(nParmCount)) + "]" + C_CRLF
  4171.             *- assign parameter to an array, to build up a parameter clause to pass on
  4172.             m.npos = 1
  4173.             FOR m.k = 1 TO m.nParmCount
  4174.                 *- determine the parameter
  4175.                 IF m.k = m.nParmCount
  4176.                     cParmA = SUBS(THIS.cParms,npos)
  4177.                 ELSE
  4178.                     cParmA = SUBS(THIS.cParms,npos,AT(",",THIS.cParms,m.k) - npos)
  4179.                 ENDIF
  4180.                 m.cParmCode = m.cParmCode + ;
  4181.                         "_aParm[" + LTRIM(STR(m.k)) + "] = [" + ALLT(cParmA) + "]" + C_CRLF
  4182.                 m.npos = AT(",",THIS.cParms,m.k) + 1
  4183.             NEXT
  4184.  
  4185.             cParmCode = m.cParmCode + ;
  4186.                         C_CRLF + ;
  4187.                         "_cparmstr = []" + C_CRLF + ;
  4188.                         C_CRLF + ;
  4189.                         "IF PARAMETERS() > 0" + C_CRLF + ;
  4190.                         C_TAB + "_cparmstr = [WITH ]" + C_CRLF + ;
  4191.                         C_TAB + "_cparmstr = _cparmstr + _aParm[1]" + C_CRLF + ;
  4192.                         C_TAB + "FOR m._nctr = 2 TO PARAMETERS()" + C_CRLF + ;
  4193.                         C_TAB + C_TAB + "_cparmstr = _cparmstr + [,] + _aParm[m._nctr]" + C_CRLF + ;
  4194.                         C_TAB + "NEXT" + C_CRLF + ;
  4195.                         "ENDIF" + C_CRLF + C_CRLF
  4196.  
  4197.             REPLACE _FOX3SPR.SPRMEMO WITH cParmCode ADDITIVE
  4198.         ENDIF
  4199.  
  4200.         *- add in EXTERNAL lines
  4201.         IF !EMPTY(THIS.a_Dimes)
  4202.             m.nArryLen = ALEN(THIS.a_Dimes)
  4203.             FOR m.j = 1 TO m.nArryLen
  4204.                 *- expand array list (maybe multiple arrays were declared 
  4205.                 *- with one DIMENSION or DECLARE) (jd 03/11/96)
  4206.                 DECLARE a_Dimes2[1]
  4207.                 =GetArray(THIS.a_Dimes[j],@a_dimes2)
  4208.                 IF ALEN(a_dimes2,1) > 1
  4209.                     *- copy rest of array
  4210.                     THIS.a_Dimes[j] = a_dimes2[1]                                        && replace long item with just the first item
  4211.                     DIMENSION THIS.a_Dimes[ALEN(THIS.a_Dimes) + ALEN(a_dimes2,1) - 1]    && grow array
  4212.                     =ACOPY(a_dimes2, THIS.a_Dimes,2,-1,ALEN(THIS.a_Dimes) - ALEN(a_dimes2,1) + 2)    && 
  4213.                 ENDIF
  4214.             NEXT
  4215.             *- remove the array dimensions
  4216.             FOR m.j = 1 TO ALEN(THIS.a_Dimes)
  4217.                 THIS.a_Dimes[j] = StripParen(THIS.a_Dimes[j],'(',')')
  4218.                 THIS.a_Dimes[j] = StripParen(THIS.a_Dimes[j],'[',']')
  4219.             NEXT
  4220.             *- remove duplicates
  4221.             DECLARE aTemp[1]
  4222.             aTemp = ""
  4223.             m.nArryLen = 1
  4224.             FOR m.j = 1 TO ALEN(THIS.a_Dimes)
  4225.                 m.cTmpText = ALLT(THIS.a_Dimes[m.j])
  4226.                 IF ISALPHA(m.cTmpText) OR LEFT(m.cTmpText,1) == "_"
  4227.                     *- valid name (not a name expression)
  4228.                     m.cTmpText = ALLT(IIF("&" + "&" $ m.cTmpText,LEFT(m.cTmpText,AT("&" + "&",m.cTmpText) - 1), m.cTmpText))
  4229.                     m.cTmpText = ALLT(IIF(";" $ m.cTmpText,LEFT(m.cTmpText,AT(";",m.cTmpText) - 1), m.cTmpText))
  4230.                     DO WHILE !EMPTY(m.cTmpText)
  4231.                         IF "," $ m.cTmpText
  4232.                             m.cItem = LEFT(m.cTmpText,AT(",",m.cTmpText) - 1)
  4233.                             m.cTmpText = SUBS(m.cTmpText,AT(",",m.cTmpText) + 1)
  4234.                         ELSE
  4235.                             m.cItem = m.cTmpText
  4236.                             m.cTmpText = ""
  4237.                         ENDIF
  4238.                         IF !EMPTY(aTemp[1])
  4239.                             DIMENSION aTemp[m.nArryLen + 1]
  4240.                             m.nArryLen = m.nArryLen + 1
  4241.                         ENDIF
  4242.                         aTemp[m.nArryLen] = LOWER(ALLT(m.cItem))
  4243.                     ENDDO
  4244.                 ENDIF
  4245.             NEXT
  4246.  
  4247.             =ASORT(aTemp)
  4248.             m.cArrays = C_EXTERN_CMMT_LOC
  4249.             FOR m.j = 1 TO ALEN(aTemp)
  4250.                 IF m.j = 1 OR aTemp[m.j-1] != aTemp[m.j]
  4251.                     m.cArrays = m.cArrays + "EXTERNAL ARRAY " + aTemp[m.j] + C_CRLF
  4252.                 ENDIF
  4253.             NEXT
  4254.             REPLACE _FOX3SPR.SPRMEMO WITH m.cArrays + C_CRLF ADDITIVE
  4255.         ENDIF
  4256.  
  4257.         m.cScxName = THIS.cNewScx
  4258.         FOR m.j = 1 TO THIS.scxcount
  4259.             IF m.j # 1
  4260.                 m.cScxName = THIS.a_scx3files[m.j]
  4261.             ENDIF
  4262.             IF THIS.lHasReturn
  4263.                 REPLACE _FOX3SPR.SPRMEMO WITH C_RETVAL_CMMT_LOC + ;
  4264.                     "LOCAL _rval" + C_CRLF + C_CRLF ADDITIVE
  4265.             ENDIF
  4266.  
  4267.             IF THIS.lHasDataNavObj AND THIS.a_pjxsets[A_OPENFILES]
  4268.                 *- create PUBLIC variables for cursors, to hold record pointers
  4269.                 cPubList = C_GOTOVAR1_CMMT_LOC
  4270.                 FOR k = 1 TO ALEN(THIS.a_tables)
  4271.                     cCursVar = THIS.MakeVar(THIS.a_tables[k])
  4272.                     cPubList = m.cPubList + "PUBLIC " + m.cCursVar + C_CRLF
  4273.                 NEXT
  4274.                 REPLACE _FOX3SPR.SPRMEMO WITH ;
  4275.                     m.cPubList + C_CRLF ADDITIVE
  4276.             ENDIF
  4277.  
  4278.             IF !EMPTY(THIS.cParms)
  4279.                 cDoForm = [EXTERNAL PROC ] + JUSTFNAME(m.cScxName) + C_CRLF + C_CRLF + ;
  4280.                         IIF(THIS.iPlatformCount > 1,C_TAB,"") + [DO FORM "] + JUSTFNAME(m.cScxName) + [" NAME ] + SYS(2015) + [ LINKED ] + CHR(38) + "_cparmstr" + ;
  4281.                         IIF(THIS.noReadPlainExpr OR THIS.noReadExpr," NOREAD","") + ;
  4282.                         IIF(THIS.lHasReturn," TO m._rval" + C_CRLF + "RETURN m._rval" + C_CRLF,C_CRLF)
  4283.                    IF THIS.iPlatformCount > 1
  4284.                      *- only write out filename, not full path
  4285.                     REPLACE _FOX3SPR.SPRMEMO WITH ;
  4286.                         [IF _mac] + C_CRLF + ;
  4287.                         C_TAB + [EXTERNAL PROC ] + JUSTSTEM(m.cScxName) + C_MACEXT + "." + JUSTEXT(m.cScxName) + C_CRLF + C_CRLF + ;
  4288.                         C_TAB + [DO FORM "] + JUSTSTEM(m.cScxName) + C_MACEXT + "." + JUSTEXT(m.cScxName) + ;
  4289.                             [" NAME ] + SYS(2015) + [ LINKED ] + CHR(38) + "_cparmstr" + ;
  4290.                         IIF(THIS.noReadPlainExpr OR THIS.noReadExpr," NOREAD","") + ;
  4291.                         IIF(THIS.lHasReturn," TO m._rval" + C_CRLF + "RETURN m._rval" + C_CRLF,C_CRLF) + ;
  4292.                         [ELSE] + C_CRLF + ;
  4293.                         C_TAB + m.cDoForm + ;
  4294.                         [ENDIF] + C_CRLF ;
  4295.                         ADDITIVE
  4296.                 ELSE
  4297.                     REPLACE _FOX3SPR.SPRMEMO WITH m.cDoForm ADDITIVE
  4298.                 ENDIF
  4299.                ELSE
  4300.                    cDoForm = [EXTERNAL PROC ] + JUSTFNAME(m.cScxName) + C_CRLF + C_CRLF + ;
  4301.                         IIF(THIS.iPlatformCount > 1,C_TAB,"") + [DO FORM "] + JUSTFNAME(m.cScxName) + [" NAME ] + SYS(2015)+ [ LINKED ] + ;
  4302.                         IIF(THIS.noReadPlainExpr OR THIS.noReadExpr," NOREAD","") + ;
  4303.                         IIF(THIS.lHasReturn," TO m._rval" + C_CRLF + "RETURN m._rval" + C_CRLF,C_CRLF)
  4304.                   IF THIS.iPlatformCount > 1
  4305.                        *- only write out filename, not full path
  4306.                      REPLACE _FOX3SPR.SPRMEMO WITH ;
  4307.                         [IF _mac] + C_CRLF + ;
  4308.                         C_TAB + [EXTERNAL PROC ] + JUSTSTEM(m.cScxName) + C_MACEXT + "." + JUSTEXT(m.cScxName) + C_CRLF + C_CRLF + ;
  4309.                         C_TAB + [DO FORM "] + JUSTSTEM(m.cScxName) + C_MACEXT + "." + JUSTEXT(m.cScxName) + [" NAME ] + SYS(2015)+ [ LINKED ] + ;
  4310.                         IIF(THIS.noReadPlainExpr OR THIS.noReadExpr," NOREAD","") + ;
  4311.                         IIF(THIS.lHasReturn," TO m._rval" + C_CRLF + "RETURN m._rval" + C_CRLF,C_CRLF) + ;
  4312.                         [ELSE] + C_CRLF + ;
  4313.                         C_TAB + m.cDoForm + ;
  4314.                         [ENDIF] + C_CRLF ;
  4315.                         ADDITIVE
  4316.                 ELSE
  4317.                     REPLACE _FOX3SPR.SPRMEMO WITH m.cDoForm ADDITIVE
  4318.                 ENDIF
  4319.             ENDIF
  4320.  
  4321.             IF THIS.lHasDataNavObj AND THIS.a_pjxsets[A_OPENFILES]
  4322.                 *- add code to release public variables we created above
  4323.                 *cPubList = C_CRLF + C_GOTOVAR2_CMMT_LOC
  4324.                 *FOR k = 1 TO ALEN(THIS.a_tables)
  4325.                 *    cPubList = m.cPubList + "RELEASE " + THIS.MakeVar(THIS.a_tables[k]) + C_CRLF
  4326.                 *NEXT
  4327.                 *REPLACE _FOX3SPR.SPRMEMO WITH ;
  4328.                     m.cPubList + C_CRLF ADDITIVE
  4329.             ENDIF
  4330.  
  4331.             IF !THIS.lMultiReads
  4332.                 EXIT
  4333.             ENDIF
  4334.         ENDFOR
  4335.     ENDPROC        &&   AddParm
  4336.  
  4337.     *------------------
  4338.     PROCEDURE PostForm            && SCXSingleScreenConverter
  4339.     *------------------
  4340.         *- this is an external hook to postprocess
  4341.         *- form object
  4342.         
  4343.         *- make sure count of DNO items is recorded in DataNavigation
  4344.         *- object header record (in the Reserved2 field)
  4345.  
  4346.         LOCAL m.savearea, m.tempfile, cTemp, j
  4347.         m.savearea = SELECT()
  4348.  
  4349.         FOR j = 1 TO IIF(THIS.lMultiReads,THIS.scxCount,1)
  4350.             SELECT (THIS.a_scx3alias[j])
  4351.  
  4352.             IF THIS.nDNORecNo > 0 AND THIS.nDNOCount > 0
  4353.                 GO THIS.nDNORecNo
  4354.                 REPLACE reserved2 WITH LTRIM(STR(THIS.nDNOCount)),methods WITH IIF(THIS.lHasIDX,_FOX3SPR.load,methods)
  4355.             ENDIF
  4356.  
  4357.             *- record count of objects for each form in the SCX file
  4358.             LOCATE FOR class == C_FORMCLASS
  4359.  
  4360.             DO WHILE !EOF()
  4361.                 m.nFormRec1 = RECNO()                                            && remember form record #
  4362.                 SKIP                                                            && move past it
  4363.                 SCAN REST WHILE class # C_FORMCLASS AND !EMPTY(class)            && look for next form record, or fontinfo
  4364.                 ENDSCAN
  4365.                 m.nFormRec2 = RECNO()                                            && remember that record #
  4366.                 GO m.nformRec1                                                    && jump back to previous form record
  4367.                 REPLACE reserved2 WITH LTRIM(STR(m.nFormRec2 - m.nformRec1))    && store # of records
  4368.                 GO MIN(RECC(),m.nFormRec2)                                        && jump ahead to where we were...
  4369.                 IF !EOF()                                                        && and move past it
  4370.                     SKIP
  4371.                 ENDIF
  4372.             ENDDO    && going through file, tabulating #s of objects per form    && repeat
  4373.  
  4374.             *- sort on uniqueid
  4375.             IF THIS.lHasInvis
  4376.                 *- push all invisible buttons to end of file, so they will be created on top
  4377.                 *- pictures, since pictures will absorb mouse clicks in FP 3.0
  4378.  
  4379.                 *- create temporary file, and sort on uniqueID into it
  4380.                 REPLACE ALL uniqueID WITH "~Z" FOR uniqueID = "FONTINFO"
  4381.  
  4382.                 m.tempfile = ADDBS(JUSTPATH(THIS.a_scx3files[1])) + "S" + LEFT(SYS(3),7) +  "." + C_SCXEXT
  4383.                 SORT ON uniqueID TO (m.tempfile)
  4384.  
  4385.                 *- open the file, and change the unique ID for invisible buttons to a real uniqueID
  4386.                 SELECT 0
  4387.                 USE (m.tempfile)
  4388.                 REPLACE ALL uniqueid WITH SYS(2015) FOR "~A" $ uniqueid  OR '^' $ uniqueid
  4389.  
  4390.                 *- close the file, and replace the new SCX file with this modified one
  4391.                 USE
  4392.                 SELECT (THIS.a_scx3alias[j])
  4393.                 m.cTemp = DBF(THIS.a_scx3alias[j])
  4394.                 USE
  4395.                 DELETE FILE (m.cTemp)
  4396.                 DELETE FILE (FORCEEXT(m.cTemp,C_SCTEXT))
  4397.                 RENAME (m.tempfile) TO (m.cTemp)
  4398.                 RENAME (FORCEEXT(m.tempfile,C_SCTEXT)) TO (FORCEEXT(m.cTemp,C_SCTEXT))
  4399.  
  4400.                 *- reopen it
  4401.                 USE (m.cTemp)
  4402.             ENDIF
  4403.  
  4404.             *- and fix the FONTINFO record
  4405.             REPLACE ALL uniqueID WITH "FONTINFO" FOR "~Z" $ uniqueID
  4406.             REPLACE ALL uniqueID WITH SYS(2015) FOR "~" $ uniqueID
  4407.  
  4408.         NEXT
  4409.         SELECT (m.savearea)
  4410.  
  4411.     ENDPROC        && SCXSingleScreenConverter:PostForm            
  4412.  
  4413.     *------------------------------------
  4414.     PROCEDURE CloseFiles            && SCXSingleScreenConverter
  4415.     *------------------------------------
  4416.         PRIVATE i
  4417.         LOCAL cHFile, iCtr, cTmpFile
  4418.  
  4419.         IF USED("_FOX3SPR")
  4420.             SELECT (THIS.new30alias)
  4421.             GO TOP
  4422.             SELE _FOX3SPR
  4423.             IF !EMPTY(_FOX3SPR.defines)
  4424.                 *- write out #DEFINEs to new #INCLUDE file
  4425.                 cHFile = FORCEEXT(THIS.cStubFile,"h")
  4426.                 iCtr = 1
  4427.                 DO WHILE FILE(m.cHFile) AND m.iCtr <= 99
  4428.                     m.cHFile = FORCEEXT(THIS.cStubFile,"h" + RIGHT(STR(iCtr + 100),2))
  4429.                     m.iCtr = m.iCtr + 1
  4430.                 ENDDO
  4431.                 IF m.iCtr > 99
  4432.                     *- ?? very unlikely? go ahead and use original file
  4433.                     cHFile = FORCEEXT(THIS.cStubFile,"h")
  4434.                 ENDIF
  4435.                 REPLACE defines WITH C_CONV_CMMT_LOC + JustFName(m.cHFile) + C_CR + ;
  4436.                     C_H_CMMT_LOC + JustFName(THIS.cCurrentFile) + C_CR + C_CR + defines
  4437.                 COPY MEMO defines TO (m.cHFile)
  4438.                 *- remember the name of the #INCLUDE file
  4439.                 SELECT (THIS.new30alias)
  4440.                 REPLACE reserved8 WITH JUSTFNAME(m.cHFile)
  4441.                 *- add #INCLUDE to .SPR code
  4442.                 REPLACE _fox3spr.sprmemo WITH C_INCLUDE_CMMT_LOC + ;
  4443.                     "#INCLUDE " + JUSTFNAME(ALLT(reserved8)) + ;
  4444.                     C_CRLF + C_CRLF + _fox3spr.sprmemo
  4445.                 SELE _FOX3SPR
  4446.             ENDIF
  4447.             IF THIS.lDevMode
  4448.                 IF !EMPTY(_fox3spr.sprmemo)
  4449.                     REPLACE code WITH C_SEPARATOR + C_CODESRC_LOC + C_CRLF + _fox3spr.sprmemo ADDITIVE
  4450.                 ENDIF
  4451.                 IF !USED("_FOX3PJX")
  4452.                     *- write out code (it _FOX3PJX is used, it will be written out below)
  4453.                     COPY MEMO code TO (THIS.cCodeFile)
  4454.                 ENDIF
  4455.             ELSE 
  4456.                 COPY MEMO sprmemo TO (THIS.cStubFile)
  4457.             ENDIF
  4458.             *- remember SPR code, in case it needs to be spit out in the future
  4459.             SELECT (THIS.new30alias)
  4460.             REPLACE user WITH _fox3spr.sprmemo
  4461.             IF THIS.lDevMode AND THIS.projcall AND USED("_FOX3PJX")
  4462.                 REPLACE _FOX3PJX.sprmemo WITH _FOX3SPR.code
  4463.             ENDIF
  4464.  
  4465.             USE IN _FOX3SPR
  4466.         ENDIF
  4467.  
  4468.         FOR i = 1 TO ALEN(THIS.a_scx2alias)
  4469.             IF USED(THIS.a_scx2alias[m.i])
  4470.                 USE IN (THIS.a_scx2alias[m.i])
  4471.             ENDIF
  4472.         ENDFOR
  4473.  
  4474.         FOR m.i = 1 TO ALEN(THIS.a_scx3alias)
  4475.             IF USED(THIS.a_scx3alias[m.i])
  4476.                 USE IN (THIS.a_scx3alias[m.i])
  4477.             ENDIF
  4478.         ENDFOR
  4479.  
  4480.         *- if lUserCall = .T., means called via project
  4481.         *- if lUserCall = .F., means screen opened individually (also used for catalogs)
  4482.         IF THIS.lUserCall
  4483.             *- only thing we need to do with Project here is to change the
  4484.             *- name of the Mac form if converting all platforms and Mac
  4485.             *- platform is present... (12/16/95 jd)
  4486.             IF THIS.platform = C_MAC AND THIS.iPlatformCount > 1
  4487.                 m.cTmpFile = AddBS(JustPath(THIS.a_scx3files[1])) + ;
  4488.                     JustStem(THIS.a_scx3files[1]) + C_MACEXT + "." + C_SCXEXT
  4489.                 COPY FILE (THIS.a_scx3files[1]) TO (m.cTmpFile)
  4490.                 COPY FILE (FORCEEXT(THIS.a_scx3files[1],C_SCTEXT)) TO (FORCEEXT(m.cTmpFile,C_SCTEXT))
  4491.             ENDIF    
  4492.         ELSE
  4493.             IF THIS.lHadError
  4494.                 *- Delete temp files if we had an error
  4495.                 IF FILE(THIS.a_scx3files[1])
  4496.                     DELETE FILE (THIS.a_scx3files[1])
  4497.                     DELETE FILE FORCEEXT(THIS.a_scx3files[1],C_SCTEXT)
  4498.                 ENDIF
  4499.             ELSE
  4500.                 IF THIS.lBackUp
  4501.                     *- erase existing backup file if it;s there
  4502.                     THIS.EraseBackUp
  4503.  
  4504.                     *- Rename old screen with S2X,S2T extensions
  4505.                     *- unless converting multiple platforms, and this one is Mac (need to leave original around 
  4506.                     *-   for Windows conversion) so copy.
  4507.                     IF THIS.iPlatformCount > 1 AND THIS.platform = C_MAC
  4508.                         COPY FILE (THIS.a_scx2files[1]) TO (FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  4509.                         COPY FILE (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT)) TO (FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  4510.                     ELSE
  4511.                         RENAME (THIS.a_scx2files[1]) TO (FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  4512.                         RENAME (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT)) TO (FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  4513.                     ENDIF
  4514.                 ELSE
  4515.                     *- don;t delete if multi-platform and Mac, since we might need this later
  4516.                     IF !(THIS.platform = C_MAC AND THIS.iWhichPlat < THIS.iPlatformCount)
  4517.                         DELETE FILE (THIS.a_scx2files[1])
  4518.                         DELETE FILE (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT))
  4519.                     ENDIF
  4520.                 ENDIF
  4521.  
  4522.                 *- Rename new FP3 screen
  4523.                 IF THIS.iPlatformCount > 1 AND THIS.platform = C_MAC
  4524.                     *- converting more than one platform, and this one is Mac, so add _mac
  4525.                     *- extension to the file name
  4526.                     m.cTmpFile = (AddBS(JustPath(THIS.a_scx2files[1])) + ;
  4527.                         JustStem(THIS.a_scx2files[1]) + C_MACEXT + "." + C_SCXEXT)
  4528.                     IF FILE(m.cTmpFile)
  4529.                         *- erase it first
  4530.                         ERASE (m.cTmpFile)
  4531.                     ENDIF
  4532.                     RENAME (THIS.a_scx3files[1]) TO (m.cTmpFile)
  4533.                     IF FILE(FORCEEXT(m.cTmpFile,C_SCTEXT))
  4534.                         *- erase it first
  4535.                         ERASE (FORCEEXT(m.cTmpFile,C_SCTEXT))
  4536.                     ENDIF
  4537.                     RENAME (FORCEEXT(THIS.a_scx3files[1],C_SCTEXT)) TO (FORCEEXT(m.cTmpFile,C_SCTEXT))
  4538.                 ELSE
  4539.                     RENAME (THIS.a_scx3files[1]) TO (THIS.a_scx2files[1])
  4540.                     RENAME (FORCEEXT(THIS.a_scx3files[1],C_SCTEXT)) TO (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT))
  4541.                 ENDIF
  4542.  
  4543.                 *- Compile form
  4544.                 IF !THIS.lNoCompile
  4545.                     IF THIS.iPlatformCount > 1 AND THIS.platform = C_MAC
  4546.                         *- use proper name for Mac specific form
  4547.                         *- cTmpFile is set just above...
  4548.                         IF FILE(m.cTmpFile)
  4549.                             COMPILE FORM (m.cTmpFile)
  4550.                         ENDIF
  4551.                     ELSE
  4552.                         IF FILE(THIS.a_scx2files[1])
  4553.                             COMPILE FORM (THIS.a_scx2files[1])
  4554.                         ENDIF
  4555.                     ENDIF
  4556.                 ENDIF
  4557.  
  4558.             ENDIF
  4559.  
  4560.         ENDIF
  4561.  
  4562.     ENDPROC        &&   SCXSingleScreenConverter:CloseFiles
  4563.  
  4564.     *------------------------------------
  4565.     PROCEDURE Cleanup                && SCXSingleScreenConverter
  4566.     *------------------------------------
  4567.         *- this proc is called by Error, and tries to put things back the way they were
  4568.         *- if cleaning up from a crashed project conversion, the pjx cleanup will
  4569.         *- handle the screens
  4570.         LOCAL i
  4571.  
  4572.         IF !THIS.lUserCall 
  4573.             *- screen opened individually
  4574.             *- Delete temp files if we had an error
  4575.             CLOSE TABLES
  4576.             IF FILE(THIS.a_scx3files[1])
  4577.                 DELETE FILE (THIS.a_scx3files[1])
  4578.                 DELETE FILE (FORCEEXT(THIS.a_scx3files[1],C_SCTEXT))
  4579.             ENDIF
  4580.             IF !THIS.lBackUp
  4581.                 *- a backup could have already been made (e.g., a 2.0 file was being converted
  4582.                 *- restore old screen from S2X,S2T extensions
  4583.                 FOR i = 1 TO ALEN(THIS.a_scx2files,1)
  4584.                     IF    FILE(THIS.a_scx2files[i,1]) AND ;
  4585.                         FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCXBACKEXT)) AND ;
  4586.                         FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCTEXT)) AND ;
  4587.                         FILE((FORCEEXT(THIS.a_scx2files[i,1],C_SCTBACKEXT)))
  4588.                         *- all of the files are there to attempt this, so...
  4589.                         DELETE FILE (THIS.a_scx2files[i,1])
  4590.                         DELETE FILE (FORCEEXT(THIS.a_scx2files[i],C_SCTEXT))
  4591.                         IF !FILE(THIS.a_scx2files[i,1])
  4592.                             RENAME (FORCEEXT(THIS.a_scx2files[i,1],C_SCXBACKEXT)) TO (THIS.a_scx2files[i,1])
  4593.                         ENDIF
  4594.                         IF !FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCTEXT))
  4595.                             RENAME (FORCEEXT(THIS.a_scx2files[i,1],C_SCTBACKEXT)) TO (FORCEEXT(THIS.a_scx2files[i,1],C_SCTEXT))
  4596.                         ENDIF
  4597.                     ENDIF
  4598.                     *- under certain circumstances, these may be left around
  4599.                     IF FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCXBACKEXT))
  4600.                         DELETE FILE (FORCEEXT(THIS.a_scx2files[i,1],C_SCXBACKEXT))
  4601.                     ENDIF
  4602.                     IF FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCTBACKEXT))
  4603.                         DELETE FILE (FORCEEXT(THIS.a_scx2files[i,1],C_SCTBACKEXT))
  4604.                     ENDIF
  4605.                 NEXT
  4606.             ENDIF
  4607.         ENDIF
  4608.  
  4609.         THIS.oConvForm = .NULL.
  4610.  
  4611.     ENDPROC
  4612.  
  4613.     
  4614.     *---------------------------------------
  4615.     FUNCTION Set30Defaults            && SCXSingleScreenConverter
  4616.     *---------------------------------------
  4617.         *- set properties to VFP 3.0 defaults
  4618.         *- the following properties need to be set:
  4619.         *-        FontBold (default was bold in 3.0)
  4620.         *-        FontSize (default was 10 in 3.0)
  4621.         *-        ColorSource (default was 0 in 3.0)
  4622.         *-            Pages, pageframes  are set to 0
  4623.         *-            Forms are set to 5 (per allisonk 6/20/96)
  4624.         *- if the CLASSLOC field is not empty, that means the object has
  4625.         *- a parent, so we skip it -- it will pick up its behavior from one of
  4626.         *- its ancestors
  4627.  
  4628.         PRIVATE llUpdated, cProp
  4629.         LOCAL    cLine, cText, iRecc
  4630.  
  4631.         iRecc = RECC()
  4632.  
  4633.         SCAN FOR EMPTY(classloc)
  4634.  
  4635.             gOTherm.Update(RECNO()/iRecc * 100,C_PROJTASK6_LOC)        && update therm with next task
  4636.  
  4637.             llUpdated = .F.
  4638.             cProp = properties
  4639.  
  4640.             *- look for relevant properties in properties field
  4641.             *- if class is a container, look into the "contained" objects too
  4642.             IF INLIST(LOWER(baseclass), ;
  4643.                 "form","checkbox","combobox","commandbutton",;
  4644.                 "editbox","grid","header","label","listbox","page",;
  4645.                 "spinner","textbox")
  4646.                 IF !INLIST(LOWER(baseclass),"pageframe","formset")
  4647.                     *- check for, add FontBold and FontSize
  4648.                     THIS.Add40Property("FontBold",".T.","")
  4649.                     THIS.Add40Property("FontSize","10","")
  4650.                 ENDIF
  4651.             ENDIF
  4652.             
  4653.             IF INLIST(LOWER(baseclass), ;
  4654.                 "checkbox","combobox","commandbutton",;
  4655.                 "editbox","label","listbox","spinner",;
  4656.                 "shape","textbox","pageframe")
  4657.                 *- check for, add ColorSource
  4658.                 THIS.Add40Property("ColorSource","0","")
  4659.             ENDIF
  4660.  
  4661.             IF INLIST(LOWER(baseclass), ;
  4662.                 "commandgroup","optiongroup","grid","pageframe")
  4663.                 *- these are containers -- they will have sub-items (textboxes, 
  4664.                 *- optionbuttons, pages etc.) that will need to be checked
  4665.                 cText = m.cProp
  4666.                 FOR i = 1 TO MEMLINES(m.cProp)
  4667.                     cLine = MLINE(m.cText, ATCLINE(".name = ", m.cText))
  4668.                     cObject = LEFT(cLine, AT(".",cLine))
  4669.                     IF LOWER(baseclass) # "pageframe"
  4670.                         THIS.Add40Property("FontBold",".T.",cObject)
  4671.                         THIS.Add40Property("FontSize","10",cObject)
  4672.                     ENDIF
  4673.                     IF LOWER(baseclass) # "grid"
  4674.                         THIS.Add40Property("ColorSource","0",cObject)
  4675.                     ENDIF
  4676.                     cText = SUBS(cText,ATC(".name = ",cText) + 8)
  4677.                 NEXT
  4678.             ENDIF
  4679.             
  4680.             IF TRIM(LOWER(baseclass)) == "form"
  4681.                 *- check for, add ColorSource
  4682.                 THIS.Add40Property("ColorSource","5","")
  4683.             ENDIF
  4684.  
  4685.             IF m.llUpdated
  4686.                 REPLACE properties WITH m.cProp
  4687.             ENDIF
  4688.  
  4689.         ENDSCAN
  4690.  
  4691.         RETURN .T.
  4692.  
  4693.     ENDFUNC
  4694.     
  4695.     *---------------------------------------
  4696.     FUNCTION Add40Property            && SCXSingleScreenConverter
  4697.     *---------------------------------------
  4698.         PARAMETER lcProperty, lcValue, lcObject
  4699.  
  4700.         LOCAL iPos, lUseLF
  4701.         IF ATC(lcObject + lcProperty, m.cProp) == 0
  4702.             *- property is missing
  4703.             iPos = ATC(C_CRLF + m.lcObject + "name =",m.cProp)
  4704.             IF iPos == 0
  4705.                 lUseLF = .F.
  4706.                 iPos = ATC(C_CR + m.lcObject + "name =",m.cProp)
  4707.             ELSE
  4708.                 lUseLF = .T.
  4709.             ENDIF
  4710.             IF iPos # 0
  4711.                 m.cProp = LEFT(m.cProp,iPos - 1) + ;
  4712.                     IIF(m.lUseLF,C_CRLF,C_CR) + m.lcObject + lcProperty + " = " + lcValue + ;
  4713.                     SUBS(m.cProp,iPos)
  4714.                 llUpdated = .T.
  4715.             ENDIF
  4716.         ENDIF
  4717.     ENDFUNC
  4718.  
  4719.  
  4720.     *---------------------------------------
  4721.     PROCEDURE AddFontSub            && SCXSingleScreenConverter
  4722.     *---------------------------------------
  4723.         PRIVATE fontstr
  4724.         m.fontstr=ALLT(a_scx2fld[A_FONTFACE])+", "+ ;
  4725.             ALLT(STR(a_scx2fld[A_FONTSTYLE]))+", "+ ;
  4726.             ALLT(STR(a_scx2fld[A_FONTSIZE]))+", "+ ;
  4727.             ALLT(STR(a_scx2fld[A_HPOS]))+", "+ ;
  4728.             ALLT(STR(a_scx2fld[A_VPOS]))+", "+ ;
  4729.             ALLT(STR(a_scx2fld[A_HEIGHT]))+", "+ ;
  4730.             ALLT(STR(a_scx2fld[A_WIDTH]))+", "+ ;
  4731.             ALLT(STR(a_scx2fld[A_PENRED]))+", "+ ;
  4732.             ALLT(STR(a_scx2fld[A_PENGREEN]))+C_CRLF
  4733.         IF AT(m.fontstr,THIS.fontsub)=0
  4734.             THIS.fontsub = THIS.fontsub+m.fontstr
  4735.         ENDIF
  4736.     ENDPROC        &&   AddFontSub
  4737.     
  4738.     *---------------------------------------
  4739.     PROCEDURE WriteFontSub            && SCXSingleScreenConverter
  4740.     *---------------------------------------
  4741.           INSERT INTO (THIS.new30alias) ;
  4742.           (platform,uniqueid,properties) ;
  4743.           VALUES ("COMMENT","~Z",THIS.fontsub)
  4744.         THIS.fontsub = ""    &&reset
  4745.     ENDPROC        &&   WriteFontSub
  4746.     
  4747.     *------------------------------------
  4748.     PROCEDURE AddFSet            && SCXSingleScreenConverter
  4749.     *------------------------------------
  4750.         *-  Add the formset record here. We can use
  4751.         *-  "Formset1" name here since no 2.5 equivalent.
  4752.  
  4753.         PARAMETER getplat
  4754.         PRIVATE m.z,m.tmpstr,m.tmpcnt,m.j,lReadclause
  4755.         lReadclause = .F.
  4756.  
  4757.         THIS.curplat = m.getplat
  4758.  
  4759.         *- construct the formRef name
  4760.         THIS.iFormSetCtr = THIS.iFormSetCtr + 1
  4761.         THIS.cFormSetName = THIS.GetVarPrefix(T_FSET) + PROPER(LOWER(GoodName(JUSTSTEM(THIS.cCurrentFile)))) + LTRIM(STR(THIS.iFormSetCtr))
  4762.       
  4763.         *- reset arrays and all
  4764.         STORE "" TO THIS.a_reads
  4765.         THIS.nObjCount = 0
  4766.         THIS.fp3prop = ""        && properties
  4767.         THIS.fp3method = ""        && methods
  4768.  
  4769.         *- Add formset properties
  4770.       
  4771.         *- Add READ type here: Read - 2, Read Modal - 3
  4772.         IF THIS.lDevMode
  4773.             THIS.AddProp(M_READ,IIF(THIS.a_pjxsets[A_READMODAL],1,0))      
  4774.         ELSE
  4775.             THIS.AddProp(M_READ,IIF(THIS.a_pjxsets[A_READMODAL],3,2))      
  4776.         ENDIF
  4777.  
  4778.         *- Add READ CYCLE
  4779.           THIS.AddProp(M_READCYCLE,THIS.a_pjxsets[A_READCYCLE])      
  4780.       
  4781.         *- Add READ NOLOCK
  4782.           THIS.AddProp(M_READNOLOCK,!THIS.a_pjxsets[A_READNOLOCK])      
  4783.  
  4784.         *- GET Borders
  4785.           THIS.GetBorder = THIS.a_pjxsets[A_GetBorderS]
  4786.  
  4787.         *- Associated Windows
  4788.         IF !EMPTY(THIS.a_pjxsets[A_ASSOCWINDS])
  4789.             m.tmpstr = STRTRAN(THIS.a_pjxsets[A_ASSOCWINDS],CHR(13),',')
  4790.             THIS.AddProp(M_ASSOCWINDS,LEFT(m.tmpstr,LEN(m.tmpstr)-1))      
  4791.         ENDIF
  4792.  
  4793.         *- Accumulate READ stuff
  4794.         FOR m.j = 1 TO THIS.scxcount
  4795.  
  4796.             *- Select screen to process in screen set
  4797.             SELECT (THIS.a_scx2alias[m.j])
  4798.  
  4799.             *- already converted, so skip
  4800.             IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  4801.                 *- already converted, so skip this
  4802.                 LOOP
  4803.             ENDIF
  4804.  
  4805.             LOCATE FOR PLATFORM = THIS.curplat AND OBJTYPE = 1
  4806.             THIS.AddReads(m.j)
  4807.             
  4808.             *- RELEASE WINDOWS -- must be called after AddReads
  4809.             IF m.j = 1
  4810.                   THIS.AddProp(M_RELEASEWIND,THIS.a_pjxsets[A_RELWINDOWS])
  4811.             ENDIF
  4812.  
  4813.             *- Handle Multiple READ option
  4814.             IF THIS.lMultiReads
  4815.                 IF !EMPTY(THIS.read_expr)
  4816.                       THIS.ReadClause
  4817.                 ENDIF
  4818.  
  4819.                 *- Add Read snippets to Methods clause
  4820.                 THIS.WriteReads
  4821.                 
  4822.                 *- Add formset name
  4823.                 THIS.AddProp(M_NAME,THIS.cFormSetName)    && formset name
  4824.  
  4825.                 IF THIS.lDevMode
  4826.                     INSERT INTO (THIS.a_scx3alias[m.j]) ;
  4827.                       (platform,uniqueid,timestamp,;
  4828.                       class,baseclass,objname,properties) ;
  4829.                       VALUES (THIS.savedPlat,sys(2015),THIS.nTimeStamp,;
  4830.                       T_FSET,T_FSET,THIS.cFormSetName,THIS.fp3prop)
  4831.                     IF !EMPTY(THIS.fp3method)
  4832.                         REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.cFormSetName + C_CRLF + THIS.fp3method ADDITIVE
  4833.                     ENDIF
  4834.                 ELSE
  4835.                     INSERT INTO (THIS.a_scx3alias[m.j]) ;
  4836.                       (platform,uniqueid,timestamp,;
  4837.                       class,baseclass,objname,properties,methods) ;
  4838.                       VALUES (THIS.savedPlat,sys(2015),THIS.nTimeStamp,;
  4839.                       T_FSET,T_FSET,THIS.cFormSetName,THIS.fp3prop,THIS.fp3method)
  4840.                 ENDIF
  4841.  
  4842.                 IF m.j = 1
  4843.                     THIS.nFSetRecno = RECNO(THIS.a_scx3alias[1])
  4844.                 ENDIF
  4845.  
  4846.                 STORE "" TO THIS.a_reads
  4847.                 THIS.fp3method = ""            && methods
  4848.             ELSE
  4849.                 *- Check for #READCLAUSE
  4850.                 IF !EMPTY(THIS.read_expr) AND !m.lReadclause 
  4851.                     THIS.ReadClause
  4852.                     m.lReadclause= .T.
  4853.                 ENDIF
  4854.             ENDIF
  4855.         ENDFOR
  4856.  
  4857.         THIS.new30alias = THIS.a_scx3alias[1]
  4858.  
  4859.         IF !THIS.lMultiReads
  4860.             *- Add Read snippets to Methods clause
  4861.             THIS.WriteReads
  4862.  
  4863.             *- Add formset name
  4864.             THIS.AddProp(M_NAME,THIS.cFormSetName)    && default name
  4865.  
  4866.             IF THIS.lDevMode
  4867.                 *- put methods someplace else
  4868.                 INSERT INTO (THIS.new30alias) ;
  4869.                   (platform,uniqueid,timestamp,;
  4870.                   class,baseclass,objname,properties,reserved4) ;
  4871.                   VALUES (THIS.savedPlat,sys(2015),THIS.nTimeStamp,;
  4872.                   T_FSET,T_FSET,THIS.cFormSetName,THIS.fp3prop,;
  4873.                   IIF(!THIS.a_pjxsets[A_DEFWINDOWS],"NODEFINE",""))
  4874.                 IF !EMPTY(THIS.fp3method)
  4875.                     REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.cFormSetName + C_CRLF + THIS.fp3method ADDITIVE
  4876.                 ENDIF
  4877.             ELSE
  4878.                 INSERT INTO (THIS.new30alias) ;
  4879.                   (platform,uniqueid,timestamp,;
  4880.                   class,baseclass,objname,properties,methods,reserved4) ;
  4881.                   VALUES (THIS.savedPlat,sys(2015),THIS.nTimeStamp,;
  4882.                   T_FSET,T_FSET,THIS.cFormSetName,THIS.fp3prop,THIS.fp3method,;
  4883.                   IIF(!THIS.a_pjxsets[A_DEFWINDOWS],"NODEFINE",""))
  4884.             ENDIF
  4885.  
  4886.             THIS.nFSetRecno = RECNO(THIS.a_scx3alias[1])
  4887.  
  4888.         ENDIF
  4889.  
  4890.         THIS.parentName = THIS.cFormSetName
  4891.     
  4892.         *- Select 1st screen
  4893.         SELECT (THIS.c25alias)
  4894.         
  4895.     ENDPROC        && AddFSet
  4896.  
  4897.  
  4898.     *------------------------------------------------
  4899.     PROCEDURE ReadClause            && SCXSingleScreenConverter
  4900.     *------------------------------------------------
  4901.     *- ReadClause -- process if #READ
  4902.     PRIVATE tmpstr,tmpcnt 
  4903.  
  4904.     *- Add READ MOUSE
  4905.     IF ATC("NOMOUSE",THIS.read_expr) # 0
  4906.         THIS.AddProp(M_READNOMOUSE,C_TRUE)      
  4907.     ENDIF
  4908.  
  4909.     *- Add READ SAVE
  4910.     IF ATC("SAVE",THIS.read_expr) # 0
  4911.         THIS.AddProp(M_READSAVE,C_TRUE)      
  4912.     ENDIF
  4913.  
  4914.     *- Add READ TIMEOUT
  4915.     IF ATC("TIME",THIS.read_expr) # 0
  4916.         m.tmpstr = SUBSTR(THIS.read_expr,ATC("TIME",THIS.read_expr))
  4917.         THIS.AddProp(M_READTIME,VAL(SUBSTR(m.tmpstr ,ATC(" ",m.tmpstr))) * K_TIMEOUT_FACTOR)  
  4918.     ENDIF
  4919.   
  4920.     *- Add READ OBJECT
  4921.     IF ATC("OBJECT",THIS.read_expr) # 0
  4922.         m.tmpstr = SUBSTR(THIS.read_expr,ATC("OBJECT",THIS.read_expr))
  4923.         THIS.AddProp(M_READOBJ,VAL(SUBSTR(m.tmpstr ,ATC(" ",m.tmpstr))))  
  4924.     ENDIF
  4925.  
  4926.     *- Color Scheme
  4927.     IF ATC("COLORSCHEME",THIS.read_expr) # 0
  4928.         m.tmpcnt = 1
  4929.         DO WHILE UPPER(WORDNUM(THIS.read_expr,m.tmpcnt))#"COLORSCHEME"
  4930.             m.tmpcnt = m.tmpcnt+1
  4931.         ENDDO
  4932.         m.tmpstr = WORDNUM(THIS.read_expr,m.tmpcnt+1)
  4933.         THIS.AddProp(M_SCHEME,m.tmpstr)
  4934.     ENDIF
  4935.  
  4936.     ENDPROC        && SCXSingleScreenConverter:ReadClause
  4937.     
  4938.     *------------------------------------------------
  4939.     PROCEDURE WriteReads            && SCXSingleScreenConverter
  4940.     *------------------------------------------------
  4941.         *- This routine writes the Methods field to the
  4942.         *- new 3.0 SCX file for the Formset record at
  4943.         *- the end since it combines the snippets of
  4944.         *- 2.5 screens from screen sets. 
  4945.         
  4946.         *- if #NOREAD PLAIN, toss any snippets
  4947.         DO CASE
  4948.             CASE THIS.noReadExpr
  4949.                 THIS.AddMethods(M_WHEN,THIS.a_reads[4],1)
  4950.                 THIS.AddMethods(M_VALID,THIS.a_reads[5],1)
  4951.                 THIS.AddMethods(M_ACTIVATE,THIS.a_reads[7],1)
  4952.                 THIS.AddMethods(M_DEACTIVATE,THIS.a_reads[8],1)
  4953.             CASE !THIS.noReadPlainExpr
  4954.                 THIS.AddMethods(M_WHEN,THIS.a_reads[4],1)
  4955.                 THIS.AddMethods(M_VALID,THIS.a_reads[5],1)
  4956.                 THIS.AddMethods(M_ACTIVATE,THIS.a_reads[7],1)
  4957.                 THIS.AddMethods(M_DEACTIVATE,THIS.a_reads[8],1)
  4958.             OTHERWISE
  4959.                 THIS.cProcs = THIS.cProcs + THIS.a_reads[3]
  4960.         ENDCASE
  4961.         
  4962.     ENDPROC        && WriteReads
  4963.  
  4964.     *------------------------------------
  4965.     PROCEDURE AddReads            && SCXSingleScreenConverter
  4966.     *------------------------------------
  4967.         PARAMETER scrn_num
  4968.         *- This routine updates the Methods field in the
  4969.         *- new 3.0 SCX file. Since 2.5 screen sets combine
  4970.         *- these, we will combine here as well and update
  4971.         *- the formset record at the end.
  4972.  
  4973.         PRIVATE m.part1,m.part2,m.part2line,m.part2chr
  4974.         PRIVATE m.sect1,m.sect2,m.sect1line,m.sect2line,m.parmline 
  4975.         PRIVATE m.sect1chr,m.sect2chr,m.sect2start
  4976.         PRIVATE m.gendir,m.gendircount,savearea
  4977.         PRIVATE m.j
  4978.         LOCAL m.ctemptxt, ngendir
  4979.         LOCAL cDefine, cTmp, nCtr, cReplaceStr, cGenAction, cParmLine, nCtr, nLine
  4980.  
  4981.         STORE "" TO m.part1,m.part2,m.sect1,m.sect2    
  4982.         STORE 0 TO m.part2line,m.part2chr
  4983.         STORE 0 TO m.sect1line,m.sect2line,m.parmline
  4984.         STORE 0 TO m.sect1chr,m.sect2chr,m.sect2start
  4985.         STORE 1 TO m.gendircount
  4986.         STORE SELECT() TO m.savearea
  4987.         
  4988.         *- Get parameter statement here -- assume we always
  4989.         *- hit here at least once
  4990.         THIS.cParms = GetParam("setupcode")
  4991.  
  4992.         *- Preprocess here for screen directives
  4993.         *- Also remove (comment out) others
  4994.         
  4995.         REPLACE _FOX3SPR.temp1 WITH setupcode
  4996.  
  4997.         SELECT _FOX3SPR
  4998.         *- go ahead and strip out leading white space here, so MemoFind doesn;t need to do it each time
  4999.         *- temp4 will be a "cleaned-up" version of temp1, to aid in finding the right directives
  5000.         REPLACE temp4 WITH CleanWhite(temp1)
  5001.  
  5002.         *- alter references to SYS(16), because they will now be in a procedure
  5003.         IF "SYS(16" $ UPPER(_FOX3SPR.temp1)
  5004.             REPLACE _FOX3SPR.temp1 WITH STRTRAN(_FOX3SPR.temp1,"SYS(16","_SYS(16")
  5005.             REPLACE _FOX3SPR.temp1 WITH STRTRAN(_FOX3SPR.temp1,"sys(16","_sys(16")
  5006.             REPLACE _FOX3SPR.temp1 WITH STRTRAN(_FOX3SPR.temp1,"Sys(16","_Sys(16")
  5007.             THIS.lhasSys16 = .T.
  5008.         ENDIF
  5009.  
  5010.         DO WHILE .T.
  5011.             m.gendir = MemoFind("#","temp4",.T.,.F.,m.gendircount,.T.,.T.)
  5012.             DO CASE
  5013.                 CASE m.gendir = C_NULL
  5014.                     EXIT
  5015.                 CASE UPPER(LEFT(m.gendir,4)) = "DEFI"
  5016.                     *- accumulate
  5017.                     IF RIGHT(TRIM(m.gendir),1) = ";"
  5018.                         *- a continued #DEFINE, so take some special measures
  5019.                         m.cDefine = ""
  5020.                         m.ngendir = MemoFind("#","temp4",.T.,.T.,m.gendircount,.T.,.T.)
  5021.                         IF m.ngendir = 0
  5022.                             *- this should be an impossibility -- couldn;t find where it was
  5023.                             EXIT
  5024.                         ENDIF
  5025.                         gendir = MLINE(temp1,m.ngendir)
  5026.                         *- check for continued #DEFINES
  5027.                         m.nCtr = 1
  5028.                         DO WHILE .T.
  5029.                             m.cDefine = m.cDefine + m.gendir + C_CRLF
  5030.                             IF RIGHT(m.gendir,1) # ";"
  5031.                                 EXIT
  5032.                             ELSE
  5033.                                 m.gendir = MLINE(temp1,m.ngendir + m.nCtr)
  5034.                                 m.nCtr = m.nCtr + 1
  5035.                             ENDIF
  5036.                         ENDDO
  5037.                         REPLACE _FOX3SPR.defines WITH m.cDefine ADDITIVE
  5038.                     ELSE
  5039.                         REPLACE _FOX3SPR.defines WITH ;
  5040.                           "#" + m.gendir + C_CRLF ADDITIVE
  5041.                     ENDIF
  5042.                 CASE UPPER(LEFT(m.gendir,2)) = "IF" ;
  5043.                   OR UPPER(LEFT(m.gendir,4)) = "ELSE" ;
  5044.                   OR UPPER(LEFT(m.gendir,4)) = "ELIF" ;
  5045.                   OR UPPER(LEFT(m.gendir,5)) = "ENDIF"
  5046.                   *- should accumulate these in with the defines, plus leave them in the methods
  5047.                     REPLACE _FOX3SPR.defines WITH ;
  5048.                       "#" + m.gendir + C_CRLF ADDITIVE
  5049.                     m.gendircount = m.gendircount + 1
  5050.                     LOOP
  5051.                 CASE UPPER(LEFT(m.gendir,4)) = "INSE" ;
  5052.                   OR UPPER(LEFT(m.gendir,4)) = "SECT"
  5053.                     m.gendircount = m.gendircount + 1
  5054.                     LOOP
  5055.                 CASE UPPER(LEFT(m.gendir,4)) = "ITSE"
  5056.                     THIS.itse_expr = UPPER(MemoFind("#ITSE","temp4",.T.,.F.))
  5057.                 CASE UPPER(LEFT(m.gendir,4)) = "READ"
  5058.                     THIS.read_expr = m.gendir
  5059.                 CASE UPPER(LEFT(m.gendir,7)) = "WCLAUSE"
  5060.                     THIS.wclause_expr = m.gendir
  5061.                 CASE UPPER(LEFT(m.gendir,5)) = "WNAME"
  5062.                     THIS.cWnameExpr = UPPER(MemoFind("#WNAME","temp4",.T.,.F.))
  5063.                 CASE UPPER(LEFT(m.gendir,6)) = "NOREAD" AND ATC("PLAIN",m.gendir) # 0
  5064.                     THIS.a_pjxsets[A_DEFWINDOWS] = .F.
  5065.                     THIS.a_pjxsets[A_RELWINDOWS] = .F.
  5066.                     THIS.noReadPlainExpr = .T.
  5067.                 CASE UPPER(LEFT(m.gendir,6)) = "NOREAD"
  5068.                     THIS.a_pjxsets[A_RELWINDOWS] = .F.
  5069.                     THIS.noReadExpr = .T.
  5070.             ENDCASE
  5071.             *- Comment out directive
  5072.             m.cGenAction = IIF(" " $ ALLT(m.gendir), ;
  5073.                 SUBS(m.gendir, AT(" ",LTRIM(m.gendir)) + 1),"")
  5074.             IF LEFT(LTRIM(m.cGenAction),1) = "&" AND ;
  5075.                 IIF(LEN(m.cGenAction) > 1,SUBS(m.cGenAction,2,1)," ") # "&"
  5076.                 *- a macro expression -- can;t handle it
  5077.                 *- log it, and comment it in file 
  5078.                 THIS.WriteLog(THIS.cCurrentFile,E_MACROEXPR1_LOC)
  5079.                 m.cReplaceStr = C_MACRO_CMMT_LOC + '*'
  5080.             ELSE
  5081.                 m.cReplaceStr = '*'
  5082.             ENDIF
  5083.             *- Comment out directive
  5084.             _MLINE = 0
  5085.             nLine = MemoFind("#","temp4",.T.,.T.,m.gendircount,.F.,.T.)
  5086.             cTmp = MLINE(temp1,nLine - 1)                        && set _MLINE
  5087.             REPLACE temp1 WITH STUFF(temp1,_MLINE + IIF(nLine <= 1,0,2),0,m.cReplaceStr)
  5088.             cTmp = MLINE(temp4,nLine - 1)                        && set _MLINE
  5089.             REPLACE temp4 WITH STUFF(temp4,_MLINE + IIF(nLine <= 1,0,1),0,m.cReplaceStr)
  5090.         ENDDO
  5091.         
  5092.         *- Get SETUP snippet SECTION 1 location
  5093.         *- If parameter statement, then we must start at 1st
  5094.         *- line following. Note: only 1st screen parameter
  5095.         *- statement is used.
  5096.         m.sect1line =  GetFirstLine("temp1","SECT","1")
  5097.         m.sect1chr = _MLINE + 2 && add CRLF
  5098.         IF sect1line # 0
  5099.             m.parmline = GetFirstLine("temp1","PARM")
  5100.             IF m.parmline # 0    && has parameter
  5101.                 *- check for continued parameter line
  5102.                 m.nCtr = 0
  5103.                 DO WHILE .T.
  5104.                     cParmLine = MLINE(temp1,parmline + m.nCtr)
  5105.                     IF RIGHT(m.cParmLine,1) # ";"
  5106.                         EXIT
  5107.                     ELSE
  5108.                         m.nCtr = m.nCtr + 1
  5109.                     ENDIF
  5110.                 ENDDO
  5111.                 m.sect1chr = _MLINE + m.nCtr + 1
  5112.             ENDIF
  5113.         ENDIF
  5114.         
  5115.         *- Get SETUP snippet SECTION 2 location
  5116.         m.sect2line =  GetFirstLine("temp1","SECT","2")
  5117.         IF m.sect2line # 0
  5118.             m.sect2chr = _MLINE + 2 && add CRLF
  5119.             m.sect2start = m.sect2chr-LEN(MLINE(temp1,m.sect2line))-2
  5120.         ENDIF
  5121.         
  5122.         DO CASE
  5123.             CASE m.sect1line = 0 AND m.sect2line = 0 AND !EMPTY(temp1)
  5124.                 *- No #SECTION directives
  5125.                 m.sect2 = temp1
  5126.             CASE m.sect1line # 0 AND m.sect2line = 0 AND m.parmline # 0
  5127.                 *- Only #SECTION1 directive, with parameter
  5128.                 m.sect1 = SUBSTR(temp1,m.sect1chr)
  5129.             CASE m.sect1line # 0 AND m.sect2line = 0
  5130.                 *- Only #SECTION1 directive, without parameter
  5131.                 m.sect1 = SUBSTR(temp1,m.sect1chr)
  5132.             OTHERWISE
  5133.                 *- Has both #SECTION1 + #SECTION2 directives
  5134.                 m.sect1 = SUBSTR(temp1,m.sect1chr,sect2start-m.sect1chr)
  5135.                 m.sect2 = SUBSTR(temp1,m.sect2chr)
  5136.         ENDCASE
  5137.  
  5138.         SELECT (m.savearea)
  5139.  
  5140.         *- Get CLEANUP snippet stuff
  5141.         *- Check for duplicate procs in platforms
  5142.         m.part2line =  GetFirstLine("PROCCODE","PROC")
  5143.         IF m.part2line = 0    && no procedures
  5144.             m.part1 = ALLTRIM(proccode)
  5145.         ELSE
  5146.             m.part2chr = _MLINE - LEN(MLINE(PROCCODE,m.part2line)) - 2
  5147.             m.part1 = SUBSTR(proccode,1,m.part2chr)
  5148.         ENDIF
  5149.  
  5150.         IF !EMPTY(m.part1)
  5151.             *- alter references to SYS(16), because they will now be in a procedure
  5152.             IF "SYS(16" $ UPPER(m.part1)
  5153.                 m.part1 = STRTRAN(m.part1,"SYS(16","_SYS(16")
  5154.                 m.part1 = STRTRAN(m.part1,"sys(16","_sys(16")
  5155.                 m.part1 = STRTRAN(m.part1,"Sys(16","_Sys(16")
  5156.                 THIS.lhasSys16 = .T.
  5157.             ENDIF
  5158.  
  5159.             *- See if Cleanup code is returning a value
  5160.             REPLACE _FOX3SPR.temp1 WITH m.part1
  5161.             SELECT _FOX3SPR
  5162.             REPLACE temp4 WITH CleanWhite(temp1)
  5163.  
  5164.             m.nmaxretu = OCCURS('RETU',m.part1)
  5165.             FOR m.j = 1 TO m.nmaxretu
  5166.                 m.ctemptxt = UPPER(MemoFind("RETU","temp4",.F.,.F.,m.j,.T.,.T.))
  5167.                 IF !EMPTY(ALLT(m.ctemptxt))
  5168.                     *- There's a return statement in there -- does anything follow it?
  5169.                     IF    ' ' $ ALLT(m.ctemptxt) AND ;
  5170.                         (UPPER(LEFT(m.ctemptxt,1)) = "R" OR ;
  5171.                         UPPER(LEFT(m.ctemptxt,2)) = "RN")
  5172.                         m.ctemptxt = SUBS(m.ctemptxt,AT(' ',m.ctemptxt) + 1)
  5173.                     ENDIF
  5174.                     *- make sure it's not just a double-ampersand comment
  5175.                     IF !EMPTY(ALLT(m.ctemptxt)) AND LEFT(ALLT(m.ctemptxt),2) != '&' + '&'
  5176.                         THIS.lHasReturn = .T.
  5177.                         EXIT
  5178.                     ENDIF
  5179.                 ENDIF
  5180.             NEXT
  5181.  
  5182.         ENDIF
  5183.  
  5184.         SELECT (m.savearea)
  5185.  
  5186.         THIS.a_reads[1] = THIS.MergeMethods(THIS.a_reads[1],m.sect1,1,m.scrn_num)
  5187.         IF !EMPTY(THIS.cParms) AND (m.scrn_num = 1 OR THIS.lMultiReads) 
  5188.             THIS.a_reads[1] = "PARAMETERS " + THIS.cParms + C_CRLF + C_CRLF + THIS.a_reads[1] 
  5189.         ENDIF
  5190.         THIS.a_reads[2] = THIS.MergeMethods(THIS.a_reads[2],m.sect2,1,m.scrn_num)
  5191.  
  5192.         IF !THIS.noReadPlainExpr AND !THIS.noReadExpr AND EMPTY(THIS.a_reads[3])
  5193.             THIS.a_reads[3] = IIF(THIS.lDevMode,"",C_CLEANUP_CODE)
  5194.         ENDIF
  5195.  
  5196.         THIS.a_reads[3] = THIS.MergeMethods(THIS.a_reads[3],m.part1,1,m.scrn_num)
  5197.         THIS.a_reads[4] = THIS.MergeMethods(THIS.a_reads[4],when,whentype,m.scrn_num)
  5198.         THIS.a_reads[5] = THIS.MergeMethods(THIS.a_reads[5],valid,validtype,m.scrn_num)
  5199.         THIS.a_reads[6] = THIS.MergeMethods(THIS.a_reads[6],show,showtype,m.scrn_num)
  5200.         THIS.a_reads[7] = THIS.MergeMethods(THIS.a_reads[7],activate,activtype,m.scrn_num)
  5201.         THIS.a_reads[8] = THIS.MergeMethods(THIS.a_reads[8],deactivate,deacttype,m.scrn_num)
  5202.     ENDPROC        &&  SCXSingleScreenConverter:AddReads
  5203.  
  5204.     *--------------------------------------
  5205.     FUNCTION MergeMethods            && SCXSingleScreenConverter
  5206.     *--------------------------------------
  5207.     PARAMETER mergeCode,fp30fld,codetype,snum
  5208.     PRIVATE m.insfile, savearea
  5209.  
  5210.         m.savearea = SELECT()
  5211.         *- codetype = 0 -> Expression
  5212.         *- codetype = 1 -> Proc
  5213.         IF EMPTY(ALLT(m.fp30fld))
  5214.           RETURN m.mergeCode
  5215.         ENDIF
  5216.         
  5217.         IF m.codetype = 0        && expression
  5218.             m.fp30fld = "RETURN "+ m.fp30fld 
  5219.         ELSE                    && procedure
  5220.             *- check for #INSERT directives
  5221.             REPLACE _FOX3SPR.temp1 WITH m.fp30fld
  5222.             SELECT _FOX3SPR
  5223.             REPLACE _FOX3SPR.temp4 WITH CleanWhite(_FOX3SPR.temp1)
  5224.  
  5225.             *- move any other #DEFINEs over
  5226.             THIS.GetDefine("temp1")
  5227.  
  5228.             THIS.FindArry
  5229.  
  5230.             DO WHILE .T.
  5231.                 m.insfile = MemoFind("#INSE","temp4",.T.,.F.,.F.,.F.,.T.)
  5232.                 IF m.insfile = C_NULL
  5233.                     EXIT
  5234.                 ENDIF
  5235.  
  5236.                 IF TYPE('m.insfile') = 'C' AND !FILE(m.insfile)
  5237.                     *- look for insert file in same dir as file we;re converting
  5238.                     IF FILE(AddBS(JustPath(THIS.cCurrentFile)) + JustFName(m.insfile))
  5239.                         m.insfile = AddBS(JustPath(THIS.cCurrentFile)) + JustFName(m.insfile)
  5240.                     ENDIF
  5241.                 ENDIF
  5242.  
  5243.                 *- check for bad file
  5244.                 DO CASE
  5245.                     CASE TYPE('m.insfile') # 'C'
  5246.                         REPLACE temp2 WITH C_INSMESS3_LOC
  5247.                     CASE EMPTY(m.insfile) OR !FILE(m.insfile) 
  5248.                         REPLACE temp2 WITH C_INSMESS3_LOC + " - " + m.insfile
  5249.                     OTHERWISE    && all is OK
  5250.                         *- add file to temporary memo
  5251.                         APPEND MEMO temp2 FROM (m.insfile) OVERWRITE
  5252.  
  5253.                         *- go through #INSERT file, and if any #DEFINEs, move them
  5254.                         *- to the .h file
  5255.                         REPLACE temp2 WITH CleanWhite(temp2)
  5256.                         THIS.GetDefine("temp2")
  5257.  
  5258.                         REPLACE temp2 WITH C_INSMESS1_LOC + m.insfile + C_CR + ;
  5259.                             temp2 + C_CR + C_INSMESS2_LOC + C_CR
  5260.                 ENDCASE
  5261.               
  5262.                 *- replace directive with specified file
  5263.                 =MemoStuff("#INSE","temp1",temp2,.T.)
  5264.                 =MemoStuff("#INSE","temp4",temp2,.T.)
  5265.  
  5266.             ENDDO
  5267.  
  5268.             m.fp30fld = temp1    && set the contents to this field
  5269.             SELECT (m.savearea)
  5270.         ENDIF
  5271.         *- m.fp30fld = "#REGION " + ALLT(STR(m.snum)) + C_CRLF + m.fp30fld
  5272.         *- Merge method code
  5273.         RETURN IIF(EMPTY(m.MergeCode),m.fp30fld,m.MergeCode + C_CRLF + m.fp30fld)
  5274.     ENDFUNC        &&  MergeMethods
  5275.  
  5276.     *------------------------------------
  5277.     PROCEDURE GetDefine            && SCXSingleScreenConverter
  5278.     *------------------------------------
  5279.     *- grab the #DEFINEs, and move to the _Fox3SPR.Defines field
  5280.     *- assume cMemoFld (name of memo) is already cleaned of leading spaces/tabs
  5281.     PARAMETER cMemoFld
  5282.  
  5283.         LOCAL gendircount, ngendir, cDefine, gendir, nCtr, cTmp, nLine
  5284.  
  5285.         IF ('#' $ &cMemoFld)
  5286.             STORE 1 TO m.gendircount
  5287.             DO WHILE .T.
  5288.                 m.ngendir = MemoFind("#",cMemoFld,.T.,.T.,m.gendircount,.T.,.T.)
  5289.                 IF m.ngendir = 0
  5290.                     EXIT
  5291.                 ENDIF
  5292.                 *-m.gendir = MLINE(&cMemoFld,1,m.ngendir - 1)
  5293.                 m.gendir = ALLT(STRTRAN(MLINE(&cMemoFld,m.ngendir),CHR(9),' '))
  5294.                 m.cDefine = ""
  5295.                 DO CASE
  5296.                     CASE UPPER(LEFT(m.gendir,5)) = "#DEFI"
  5297.                         *- check for continued #DEFINES
  5298.                         m.nCtr = 1
  5299.                         DO WHILE .T.
  5300.                             m.cDefine = m.cDefine + C_CRLF + m.gendir
  5301.                             IF RIGHT(m.gendir,1) # ";"
  5302.                                 EXIT
  5303.                             ELSE
  5304.                                 m.gendir = MLINE(&cMemoFld,m.ngendir + m.nCtr)
  5305.                                 m.nCtr = m.nCtr + 1
  5306.                             ENDIF
  5307.                         ENDDO
  5308.                         *- accumulate
  5309.                         REPLACE _FOX3SPR.defines WITH m.cDefine ADDITIVE
  5310.                     OTHERWISE
  5311.                         m.gendircount = m.gendircount + 1
  5312.                         LOOP
  5313.                 ENDCASE
  5314.                 *- Comment out directive
  5315.                 _MLINE = 0
  5316.                 nLine = MemoFind("#",cMemoFld,.T.,.T.,m.gendircount,.F.,.T.)
  5317.                 cTmp = MLINE(&cMemoFld,m.nLine - 1)                        && set _MLINE
  5318.                 REPLACE (cMemoFld) WITH STUFF(&cMemoFld,_MLINE + IIF(m.nLine <= 1,0,1),0,'*')
  5319.             ENDDO
  5320.         ENDIF
  5321.     ENDPROC        && GetDefine
  5322.  
  5323.     *------------------------------------
  5324.     PROCEDURE ScanPlat            && SCXSingleScreenConverter
  5325.     *------------------------------------
  5326.         PARAMETER cplatonly
  5327.         *- get all platforms for all screens in set
  5328.  
  5329.         PRIVATE tmparr,tmp2arr,i,j,tmpcnt,totrecs
  5330.  
  5331.         m.tmpcnt = 0
  5332.         m.totrecs = 0
  5333.  
  5334.         DIMENSION tmparr[1]
  5335.         tmparr = ""
  5336.         
  5337.         *- get total records to process for thermometer
  5338.         FOR m.i = 1 TO THIS.scxcount
  5339.             SELECT (THIS.a_scx2alias[m.i])
  5340.  
  5341.             IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  5342.                 *- already converted, so skip this
  5343.                 LOOP
  5344.             ENDIF
  5345.  
  5346.             IF m.cplatonly # C_All
  5347.               COUNT TO m.tmpcnt ;
  5348.                   FOR !INLIST(objtype,10,20,23) ;
  5349.                   AND platform = m.cplatonly
  5350.               ELSE
  5351.               COUNT TO m.tmpcnt ;
  5352.                   FOR !INLIST(objtype,10,20,23) ;
  5353.                   AND INLIST(platform,C_DOS,C_WINDOWS,C_MAC,C_UNIX)
  5354.             ENDIF
  5355.             m.totrecs= m.totrecs + m.tmpcnt
  5356.         ENDFOR
  5357.  
  5358.         SELECT (THIS.c25alias)
  5359.         
  5360.         FOR i = 1 TO THIS.SCXCOUNT
  5361.             IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  5362.                 *- already converted, so skip this
  5363.                 LOOP
  5364.             ENDIF
  5365.  
  5366.               IF m.cplatonly # C_ALL
  5367.               DIMENSION tmparr[1]
  5368.               tmparr[1] = m.cplatonly
  5369.               EXIT
  5370.             ENDIF
  5371.               SELECT DISTINCT platform;
  5372.                 FROM DBF(THIS.a_scx2alias[m.i]);
  5373.                  WHERE INLIST(platform,C_DOS,C_WINDOWS,C_MAC,C_UNIX) ;
  5374.                   INTO ARRAY tmp2arr
  5375.               
  5376.             IF EMPTY(tmparr)
  5377.                 =ACOPY(tmp2arr,tmparr)
  5378.             ELSE
  5379.                 FOR j = 1 TO ALEN(tmp2arr)
  5380.                     IF ASCAN(tmparr,ALLT(tmp2arr[m.j])) = 0
  5381.                         DIMENSION tmparr[ALEN(tmparr)+1]
  5382.                         tmparr[ALEN(tmparr)]=ALLT(tmp2arr[m.j])
  5383.                     ENDIF
  5384.                 ENDFOR
  5385.             ENDIF
  5386.             IF ALEN(tmparr) = C_MAXPLATFORMS
  5387.                 EXIT
  5388.             ENDIF
  5389.         ENDFOR
  5390.         
  5391.         *- This is for GENSCRN stuff in conprocs
  5392.         =ACOPY(tmparr,g_platforms)
  5393.         =ACOPY(tmparr,THIS.a_plat)
  5394.  
  5395.         THIS.isMultiPlat = (ALEN(tmparr) > 1)
  5396.  
  5397.         RETURN m.totrecs        
  5398.     ENDPROC        &&  ScanPlat
  5399.  
  5400.     *----------------------
  5401.     PROCEDURE AddProcs1                && SCXSingleScreenConverter
  5402.     *----------------------
  5403.         PRIVATE m.saverec,m.part2line,m.part2,m.part2chr
  5404.         m.saverec = IIF(EOF(),1,RECNO())
  5405.  
  5406.          LOCATE FOR objtype = 1 AND platform = THIS.a_plat[1]
  5407.         m.part2line =  GetFirstLine("PROCCODE","PROC")
  5408.  
  5409.         IF m.part2line = 0    && no procedures
  5410.             GO m.saverec
  5411.             RETURN
  5412.         ELSE
  5413.             *- If it's the first line, don't subtract anything
  5414.             m.part2chr = _MLINE - LEN(MLINE(proccode,m.part2line)) - IIF(m.part2line > 1,2,0)
  5415.             m.part2 = C_CRLF + SUBSTR(proccode,m.part2chr)
  5416.         ENDIF
  5417.  
  5418.          THIS.cProcs = THIS.cProcs + m.part2 + C_CRLF
  5419.  
  5420.     ENDPROC        && AddProcs1
  5421.  
  5422.     *----------------------
  5423.     PROCEDURE AddGenProcs            && SCXSingleScreenConverter
  5424.     *----------------------
  5425.         PRIVATE m.saverec,m.part2line,m.part2,m.part2chr
  5426.         m.saverec = IIF(EOF(),1,RECNO())
  5427.  
  5428.         *- add accumulated procs
  5429.         IF !EMPTY(THIS.cProcs)
  5430.             REPLACE _FOX3SPR.sprmemo WITH ;
  5431.                 C_CRLF + C_PROCS_CMMT_LOC + ;
  5432.                 THIS.cProcs + C_CRLF + ;
  5433.                 C_PROCSEND_CMMT_LOC ADDITIVE
  5434.         ENDIF
  5435.  
  5436.         *- add in stuff from VALIDs
  5437.         IF !EMPTY(_FOX3SPR.temp3)
  5438.             REPLACE _FOX3SPR.sprmemo WITH ;
  5439.                 C_CRLF + C_CRLF + C_VALID_CMMT_LOC + ;
  5440.                 _FOX3SPR.temp3 + ;
  5441.                 C_VALIDEND_CMMT_LOC ADDITIVE
  5442.         ENDIF
  5443.  
  5444.         IF THIS.lHasSys16
  5445.             *- add special function to workaround fact that SYS(16)
  5446.             *- will return something new, now that methods are buried
  5447.             *- inside forms
  5448.             REPLACE _FOX3SPR.sprmemo WITH ;
  5449.                 C_CRLF + C_CRLF + C_SYS16_CMMT_LOC + ;
  5450.                 "PROCEDURE _Sys" + C_CRLF + ;
  5451.                 C_TAB + "PARAMETERS nCode, nDepth" + C_CRLF + ;
  5452.                 C_TAB + "IF PARAMETERS() = 1" + C_CRLF + ;
  5453.                 C_TAB2 + [RETURN IIF(LEFT(SYS(16),9) == "PROCEDURE" AND OCCURS(" ",SYS(16)) >= 2,SUBS(SYS(16),AT(" ",SYS(16),2) + 1),SYS(16))] +  C_CRLF + ;
  5454.                 C_TAB + "ELSE" + C_CRLF + ;
  5455.                 C_TAB2 + "RETURN SYS(16,nDepth)" + C_CRLF + ;
  5456.                 C_TAB + "ENDIF" + C_CRLF + ;
  5457.                 C_SYS16END_CMMT_LOC ADDITIVE
  5458.         ENDIF
  5459.  
  5460.         GO    m.saverec
  5461.  
  5462.     ENDPROC        &&  AddGenProcs
  5463.  
  5464.     *----------------------------------
  5465.     PROCEDURE AddSRecs            && SCXSingleScreenConverter
  5466.     *----------------------------------
  5467.         *- Add Screen objects
  5468.         PARAMETER platnum,cRecType
  5469.         
  5470.         *- cRecType = C_DNO        environment info
  5471.         *-          = C_CONTROL    control items
  5472.         
  5473.         PRIVATE oRec, a_scx2fld
  5474.         LOCAL nOldSize
  5475.  
  5476.         SCAN FOR platform = THIS.a_plat[m.platnum]
  5477.             *- skip odd records such as WIZARD record
  5478.             IF !INLIST(PLATFORM,C_DOS,C_WINDOWS,C_MAC,C_UNIX)
  5479.                 LOOP
  5480.             ENDIF
  5481.             *- 10 group items
  5482.             IF objtype = 10
  5483.                 LOOP
  5484.             ENDIF
  5485.             
  5486.             IF (m.cRecType # C_DNO AND INLIST(objtype,2,3,4)) OR;
  5487.                 m.cRecType = C_DNO AND !INLIST(objtype,2,3,4)
  5488.                 *- environment records have already been dealt with
  5489.                 LOOP
  5490.             ENDIF
  5491.             
  5492.             SCATTER MEMO TO a_scx2fld
  5493.             
  5494.             *- Add font substitution object
  5495.             IF objtype=23
  5496.                 THIS.AddFontSub()
  5497.                 LOOP    
  5498.             ENDIF
  5499.             
  5500.             *- get control type
  5501.             oRec = THIS.AddSCXObj(objtype)
  5502.  
  5503.             IF TYPE("oRec") # "O"
  5504.                 *- some sort of problem -- couldn't create the object - 
  5505.                 *- invalid or unknown object type?
  5506.                 LOOP
  5507.             ENDIF
  5508.  
  5509.             *- map main components of 2.5 control to 3.0
  5510.             oRec.MapIt
  5511.         
  5512.             *- write out record
  5513.             oRec.AddRec
  5514.  
  5515.             *- update status bar
  5516.             gOTherm.Update(THIS.nTmpCount/THIS.nRecCount * 100)
  5517.             THIS.nTmpCount = THIS.nTmpCount + 1
  5518.             
  5519.             *- check for error and terminate early
  5520.             IF THIS.lHadError
  5521.                 THIS.CloseFiles
  5522.                 CLEAR EVENTS
  5523.                   RETURN
  5524.             ENDIF
  5525.  
  5526.             *- move any array creation references to the screen;s list of arrays
  5527.             IF !EMPTY(oRec.a_Dimes)
  5528.                 m.noldSize = ALEN(THIS.a_Dimes)
  5529.                 DIMENSION THIS.a_Dimes[m.noldSize + ALEN(oRec.a_Dimes)]
  5530.                 =ACOPY(oRec.a_Dimes, THIS.a_Dimes, 1, ALEN(oRec.a_Dimes), m.noldsize + 1)
  5531.             ENDIF
  5532.  
  5533.             *- we're done with the object, so dispose of it
  5534.             RELEASE oRec
  5535.             
  5536.         ENDSCAN
  5537.     ENDPROC        &&  SCXSingleScreenConverter:AddSRecs
  5538.  
  5539.  
  5540.     *----------------------------------
  5541.     PROCEDURE AddSCXObj            && SCXSingleScreenConverter
  5542.     *----------------------------------
  5543.         PARAMETER m.nObjType
  5544.  
  5545.         PRIVATE ctrltype,tmpobj,objclass,oForm
  5546.         STORE "" TO m.ctrltype,m.objclassm
  5547.  
  5548.         oForm = THIS.oConvForm
  5549.  
  5550.         DO CASE
  5551.             CASE m.nObjType = 1                                            && screen
  5552.                 m.ctrltype = T_FORM
  5553.                 m.objclass = THIS.formclass
  5554.             CASE m.nObjType = 2                                            && table
  5555.                 m.ctrltype = T_DATANAV
  5556.                 m.objclass = THIS.datanavclass
  5557.             CASE m.nObjType = 3                                            && index
  5558.                 THIS.lHasIDX = .T.
  5559.                 *- wd be an index -- not sure how this is to be handled...
  5560.                 REPLACE _FOX3SPR.load WITH C_SETIDX_CMMT_LOC + ;
  5561.                     "SELECT " + TRIM(a_scx2fld[A_TAG2]) + C_CR + ;
  5562.                     "SET INDEX TO " + TRIM(a_scx2fld[A_NAME])  + C_CR + C_CR ADDITIVE
  5563.             CASE m.nObjType = 4                                            && relation
  5564.                 m.ctrltype = T_RELATION
  5565.                 m.objclass = THIS.datanavRelationclass
  5566.             CASE m.nObjType = 5                                            && label
  5567.                 m.ctrltype = T_LABEL
  5568.                 m.objclass = THIS.labelclass
  5569.             CASE m.nObjType = 6                                            && line
  5570.                 m.ctrltype = T_LINE
  5571.                 m.objclass = THIS.lineclass
  5572.             CASE m.nObjType = 7                                            && box
  5573.                 m.ctrltype = T_SHAPE
  5574.                 m.objclass = THIS.shapeclass
  5575.             CASE m.nObjType = 11                                            && list
  5576.                 m.ctrltype = T_LIST
  5577.                 m.objclass = THIS.listclass
  5578.             CASE m.nObjType = 12 AND OCCUR(";",a_scx2fld[A_PICTURE])=0        && single button
  5579.                 m.ctrltype = T_BTN
  5580.                 m.objclass = THIS.btnclass
  5581.             CASE m.nObjType = 12                                            && buttongroup
  5582.                 m.ctrltype = T_BTNGRP
  5583.                 m.objclass = THIS.btngclass
  5584.             CASE m.nObjType = 13                                            && radio
  5585.                 m.ctrltype = T_RADIOGRP
  5586.                 m.objclass = THIS.radioclass
  5587.             CASE m.nObjType = 14                                            && checkbox
  5588.                 m.ctrltype = T_CBOX
  5589.                 m.objclass = THIS.cboxclass
  5590.             CASE m.nObjType = 15 AND objcode = 0                            && say
  5591.                 m.ctrltype = T_SAY
  5592.                 m.objclass = THIS.sayclass
  5593.             CASE m.nObjType = 15 AND objcode = 1                            && get
  5594.                 m.ctrltype = T_GET
  5595.                 m.objclass = THIS.getclass
  5596.             CASE m.nObjType = 15 AND objcode = 2                            && edit
  5597.                 m.ctrltype = T_EDIT
  5598.                 m.objclass = THIS.editclass
  5599.             CASE m.nObjType = 16                                            && popup
  5600.                 m.ctrltype = T_POPUP
  5601.                 m.objclass = THIS.popupclass
  5602.             CASE m.nObjType = 17 AND ;
  5603.                 (style = 0 OR (" BITMAP" $ UPPER(name))) 
  5604.                 *- ("\" $ ALLT(name)) OR ('"' $ ALLT(name)) OR (":" $ ALLT(name)) OR ;
  5605.                 *- ('.' $ ALLT(name)) OR (' ' $ ALLT(name)))    && image
  5606.                 *- assume if filename or quoted expression, it's not a GENERAL field, so not OLE!
  5607.                 m.ctrltype = T_PICT
  5608.                 objclass = THIS.pictclass
  5609.             CASE m.nObjType = 17 AND style = 1                                && ole
  5610.                 m.ctrltype = T_OLE
  5611.                 objclass = THIS.oleclass
  5612.             CASE m.nObjType = 20 AND OCCUR(";",a_scx2fld[A_PICTURE]) = 0    && invisible button
  5613.                 m.ctrltype = T_INV
  5614.                 m.objclass = THIS.invclass
  5615.             CASE m.nObjType = 20                                            && inv buttongroup
  5616.                 m.ctrltype = T_INVGRP
  5617.                 m.objclass = THIS.invgclass
  5618.             CASE m.nObjType = 22                                            && spinner
  5619.                 m.ctrltype = T_SPIN
  5620.                 m.objclass = THIS.spinclass
  5621.         ENDCASE
  5622.         
  5623.         IF EMPTY(m.ctrltype)
  5624.             RETURN ""
  5625.         ELSE
  5626.             RETURN CREATEOBJ(m.objclass,m.ctrltype,@oForm)
  5627.         ENDIF
  5628.     ENDPROC        && AddSCXObj
  5629.  
  5630.     *------------------
  5631.     PROCEDURE UpdMethods            && SCXSingleScreenConverter
  5632.     *------------------
  5633.         *- update the Formset.Readshow method after all objects have been processed
  5634.  
  5635.         LOCAL cGoTo,cCursVar,k
  5636.         cGoTo = ""
  5637.  
  5638.         SELECT (THIS.a_scx3alias[1])
  5639.  
  5640.         IF THIS.nFSetRecno > 0 AND THIS.nFSetRecno <= RECC()
  5641.             
  5642.             GO THIS.nFSetRecno
  5643.  
  5644.             IF !THIS.noReadPlainExpr
  5645.                 THIS.AddMethods(M_SETUP1,;
  5646.                     IIF(!EMPTY(THIS.a_reads[1]),THIS.a_reads[1] + C_CRLF + C_CRLF, "") + ;
  5647.                     IIF(THIS.lDevMode,"",C_SETUP_CODE) + ;
  5648.                     IIF(THIS.lHasDataNavObj AND THIS.a_pjxsets[A_OPENFILES],C_OPENTAB_CMMT_LOC + C_DATANAVLOAD + ;
  5649.                         IIF(!EMPTY(THIS.cSetSkip),C_CRLF + THIS.cSetSkip,C_CRLF) + ;
  5650.                         C_GOTO1 + ;
  5651.                         C_CRLF,"") + ;
  5652.                     THIS.cDefineWin,1)        && add #SECTION2 stuff to FORM.LOAD
  5653.                 *- clear out setup var, so it isn;t added to more than one screen in set
  5654.                 THIS.a_reads[1] = ""
  5655.                 IF THIS.lHasDataNavObj AND THIS.a_pjxsets[A_OPENFILES]
  5656.                     *- code to remember the record pointer
  5657.                     cGoTo = C_GOTO2_CMMT_LOC
  5658.                     FOR k = 1 TO ALEN(THIS.a_tables)
  5659.                         cCursVar = THIS.MakeVar(THIS.a_tables[k])
  5660.                         cGoTo = cGoTo +  C_GOTO2A + THIS.a_tables[k] + ;
  5661.                             C_GOTO2 + THIS.a_tables[k] + C_CR + ;
  5662.                             C_TAB + cCursVar + C_GOTO3 + C_CR
  5663.                     NEXT
  5664.                     THIS.a_reads[3] = cGoTo + C_CR + THIS.a_reads[3]
  5665.                 ENDIF
  5666.                 THIS.AddMethods(M_CLEANUP,THIS.a_reads[3],1)
  5667.             ENDIF
  5668.         
  5669.             *- add in the refreshed SAYs after the READ SHOW stuff already there
  5670.             THIS.cReadShow = THIS.a_reads[6] + ;
  5671.                 IIF(!EMPTY(THIS.cReadShow),C_CRLF + C_SAYSCOMMENT_LOC + C_CRLF,"") + ;
  5672.                 THIS.cReadShow
  5673.             THIS.AddMethods(M_SHOW,THIS.CleanProc(THIS.cReadShow),1)
  5674.  
  5675.             IF THIS.lDevMode
  5676.                 REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.cFormSetName + C_CRLF + THIS.fp3method ADDITIVE
  5677.             ELSE
  5678.                 REPLACE methods WITH THIS.fp3method && + C_CRLF + C_CRLF + THIS.cReadShow
  5679.             ENDIF
  5680.  
  5681.         ENDIF
  5682.     ENDPROC
  5683.  
  5684.     *------------------
  5685.     PROCEDURE MakeVar            && SCXSingleScreenConverter
  5686.     *------------------
  5687.         PARAMETER cName
  5688.         RETURN C_GOTOVARPRE + PROPER(TRIM(cName)) + C_GOTOVAREXT
  5689.     ENDPROC
  5690.     *------------------
  5691.     FUNCTION CleanProc            && SCXSingleScreenConverter
  5692.     *------------------
  5693.         *- clean out any screen directives or other stuff from snippets 
  5694.         *- that will cause problems in VFP
  5695.  
  5696.         PARAMETER cSnippet
  5697.         PRIVATE m.gendircount,savearea
  5698.         LOCAL nLine, cTmp
  5699.  
  5700.         IF !('#' $ cSnippet)
  5701.             *- if no '#', no directives, so return
  5702.             RETURN m.cSnippet
  5703.         ENDIF
  5704.  
  5705.         STORE 1 TO m.gendircount
  5706.         STORE SELECT() TO m.savearea
  5707.  
  5708.         REPLACE _FOX3SPR.temp1 WITH m.cSnippet
  5709.         REPLACE _FOX3SPR.temp4 WITH CleanWhite(_FOX3SPR.temp1)
  5710.         SELECT _FOX3SPR
  5711.  
  5712.         DO WHILE .T.
  5713.             m.gendir = UPPER(MemoFind("#","temp4",.T.,.F.,m.gendircount,.T.,.T.))
  5714.             DO CASE
  5715.                 CASE m.gendir = C_NULL
  5716.                     EXIT
  5717.                 CASE LEFT(m.gendir,4) = "NAME"
  5718.                     *- all this to comment out this code
  5719.                 OTHERWISE
  5720.                     m.gendircount = m.gendircount + 1
  5721.                     LOOP
  5722.             ENDCASE
  5723.             *- Comment out directive
  5724.             *REPLACE temp1 with STUFF(temp1,MemoFind("#","temp4",.T.,0,m.gendircount,.F.,.T.),0,'*')
  5725.             _MLINE = 0
  5726.             nLine = MemoFind("#","temp4",.T.,.T.,m.gendircount,.F.,.T.)
  5727.             cTmp = MLINE(temp1,nLine - 1)                        && set _MLINE
  5728.             REPLACE temp1 WITH STUFF(temp1,_MLINE + IIF(nLine <= 1,0,2),0,'*')
  5729.             cTmp = MLINE(temp4,nLine - 1)                        && set _MLINE
  5730.             REPLACE temp4 WITH STUFF(temp4,_MLINE + IIF(nLine <= 1,0,1),0,'*')
  5731.  
  5732.         ENDDO
  5733.  
  5734.         SELECT (m.savearea)
  5735.  
  5736.         RETURN _FOX3SPR.temp1
  5737.  
  5738.     ENDFUNC
  5739.  
  5740. ENDDEFINE    && SCXSingleScreenConverter 
  5741.  
  5742.  
  5743.  
  5744. **********************************************
  5745. DEFINE CLASS SCX30Converter AS SCXSingleScreenConverter
  5746. **********************************************
  5747.  
  5748.     lSet30Defaults = .F.
  5749.  
  5750.     *------------------------------------
  5751.     PROCEDURE Init                && SCX30Converter
  5752.     *------------------------------------
  5753.         PARAMETER aParms, lBackup, lProjCall, lForceTransportDlog, lNoCompile
  5754.  
  5755.         LOCAL cExt1, cExt2, cbackext1 , cbackext2
  5756.  
  5757.         THIS.projcall = lProjCall
  5758.  
  5759.         THIS.lBackup = m.lBackup
  5760.  
  5761.         THIS.lNoCompile = lNoCompile
  5762.  
  5763.         THIS.lSet30Defaults = (aParms[12] > 1)                    && use the check box setting
  5764.         THIS.iPlatformCount = 1
  5765.  
  5766.         IF THIS.projcall                                        && called from project
  5767.             THIS.cBackDir = gOPJX.cBackDir                        && used only for project
  5768.             DIMENSION THIS.a_scx2files[ALEN(gOPJX.a_s2files,1),3]
  5769.             DIMENSION THIS.a_scx3files[1]
  5770.             =ACOPY(gOPJX.a_s2files,THIS.a_scx2files)
  5771.             =ACOPY(gOPJX.a_s3files,THIS.a_scx3files)            
  5772.             THIS.cNewScx = THIS.a_scx3files[1]
  5773.             THIS.cCurrentFile = THIS.a_scx2files[1,3]
  5774.         ELSE
  5775.             IF EMPTY(aParms[1])
  5776.                 THIS.lUserCall = .F.    && assume called without output file
  5777.                 aParms[1] = ADDBS(JUSTPATH(aParms[4])) + LEFT(SYS(3),7) + ".SCX"
  5778.                 THIS.cNewScx = aParms[4]
  5779.             ELSE
  5780.                 THIS.cNewScx = aParms[1]
  5781.             ENDIF
  5782.             DIMENSION THIS.a_scx2files[1,3]
  5783.             THIS.a_scx2files[1,1] = aParms[4]
  5784.             THIS.a_scx2files[1,2] = ""
  5785.             THIS.a_scx2files[1,3] = aParms[4]
  5786.             THIS.cCurrentFile = THIS.a_scx2files[1,3]
  5787.             *- go ahead and make backup now, before we start
  5788.             *- if screen needs to be transported, the original is around
  5789.             cext1 = JustExt(THIS.a_scx2files[1])
  5790.             cext2 = IIF(m.cext1 == C_VCXEXT, C_VCTEXT, C_SCTEXT)
  5791.             cbackext1 = IIF(m.cext1 == C_VCXEXT, C_VCXBACKEXT, C_SCXBACKEXT)
  5792.             cbackext2 = IIF(m.cext1 == C_VCXEXT, C_VCTBACKEXT, C_SCTBACKEXT) 
  5793.             THIS.a_scx3files[1] = FORCEEXT(aParms[1],m.cext1)
  5794.             *- copy old screen with S2X,S2T extensions. No need to backup .SCR files
  5795.             IF FILE(THIS.a_scx2files[1]) AND UPPER(JUSTEXT(THIS.a_scx2files[1])) = m.cext1
  5796.                 COPY FILE (THIS.a_scx2files[1]) TO (FORCEEXT(THIS.a_scx2files[1],m.cbackext1))
  5797.             ENDIF
  5798.             IF FILE(FORCEEXT(THIS.a_scx2files[1],m.cext2))
  5799.                 COPY FILE (FORCEEXT(THIS.a_scx2files[1],m.cext2)) TO (FORCEEXT(THIS.a_scx2files[1],m.cbackext2))
  5800.             ENDIF
  5801.             *- backup has been done
  5802.             THIS.lBackUp = .F.
  5803.         ENDIF
  5804.  
  5805.         IF THIS.lSet30Defaults
  5806.             gOTherm.SetTitle(C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  5807.             gOTherm.Update(0,"")
  5808.             gOTherm.visible = .T.
  5809.         ENDIF
  5810.  
  5811.         THIS.WriteLog("","")                    && force a blank line
  5812.         THIS.BeginLog(SYS(2027,THIS.cNewScx) )
  5813.  
  5814.         IF !THIS.KnownFile(THIS.a_scx2files[1,1])
  5815.             *- unknown file format -- error has already been written to the log
  5816.             THIS.oConvForm = .NULL.
  5817.             IF !THIS.projcall
  5818.                 *- attempt to remove backup files (jd 04/16/96)
  5819.                 THIS.EraseBackup
  5820.             ENDIF
  5821.             RETURN .F.
  5822.         ENDIF
  5823.  
  5824.         *- also check Read-Only status if project call (04/15/96 jd)
  5825.         IF THIS.projcall AND pReadOnly(THIS.cNewSCX)
  5826.             THIS.WriteLog(JUSTFNAME(THIS.cNewSCX),TRIM(E_FILE_LOC) + E_NOCONVERT3_LOC)
  5827.             RETURN .F.
  5828.         ENDIF
  5829.  
  5830.             *- now try to open SCX file -- returns alias
  5831.             THIS.a_scx2alias[1] = THIS.OpenFile(THIS.a_scx2files[1,1])
  5832.                 
  5833.             IF EMPTY(THIS.a_scx2alias[1])
  5834.                 *- error has been logged
  5835.                 THIS.oConvForm = .NULL.
  5836.                 IF !THIS.projcall
  5837.                     *- attempt to remove backup files (jd 04/16/96)
  5838.                     THIS.EraseBackup
  5839.                 ENDIF
  5840.                 RETURN .F.
  5841.             ENDIF
  5842.  
  5843.             THIS.c25alias = THIS.a_scx2alias[1]
  5844.  
  5845.             IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  5846.                 *- assume 3.0 format
  5847.                 RETURN .T.
  5848.             ELSE
  5849.                 *- error -- isn't a 3.0 SCX or VCX
  5850.                 USE IN (THIS.a_scx2alias[1])
  5851.                 THIS.WriteLog(JUSTFNAME(THIS.a_scx2files[1,1]),TRIM(E_WRONGFMT_LOC) + E_NOCONVERT_LOC)
  5852.                 THIS.oConvForm = .NULL.
  5853.                 RETURN .F.
  5854.             ENDIF
  5855.     ENDPROC
  5856.  
  5857.     *----------------------------------
  5858.     PROCEDURE Converter        && SCX30Converter
  5859.     *----------------------------------
  5860.         *- some of the defaults for VFP 4.0 have changed. So if user
  5861.         *- elected to retain the 3.0 behavior/defaults, we need to explicitly
  5862.         *- write out those properties (05/14/96 jd)
  5863.         *- this means that the checkbox is checked
  5864.         *- also need to fix colorsource property written out in a way that 4.0 can't handle
  5865.         REPLACE ALL properties WITH STRTRAN(properties,"ColorSource = 3","ColorSource = 5") ;
  5866.             FOR LOWER(baseclass) = "form"
  5867.         REPLACE ALL properties WITH STRTRAN(properties,"ColorSource = 3","ColorSource = 0") ;
  5868.             FOR LOWER(baseclass)= "line"
  5869.         IF THIS.lSet30Defaults
  5870.             THIS.Set30Defaults()
  5871.         ENDIF
  5872.         THIS.CloseFiles
  5873.         THIS.lConverted = .T.    && only set this if main screen
  5874.         RETURN
  5875.     ENDPROC
  5876.  
  5877.     *------------------------------------
  5878.     PROCEDURE CloseFiles            && SCX30Converter
  5879.     *------------------------------------
  5880.         PRIVATE i
  5881.         LOCAL cHFile, iCtr, cTmpFile, cExt1, cExt2, cbackext1 , cbackext2, cErrFile
  5882.  
  5883.         cext1 = JustExt(THIS.a_scx2files[1,3])
  5884.         cext2 = IIF(m.cext1 == C_VCXEXT, C_VCTEXT, C_SCTEXT)
  5885.         cbackext1 = IIF(m.cext1 == C_VCXEXT, C_VCXBACKEXT, C_SCXBACKEXT)
  5886.         cbackext2 = IIF(m.cext1 == C_VCXEXT, C_VCTBACKEXT, C_SCTBACKEXT) 
  5887.  
  5888.         FOR i = 1 TO ALEN(THIS.a_scx2alias)
  5889.             IF USED(THIS.a_scx2alias[m.i])
  5890.                 USE IN (THIS.a_scx2alias[m.i])
  5891.             ENDIF
  5892.         ENDFOR
  5893.  
  5894.         FOR m.i = 1 TO ALEN(THIS.a_scx3alias)
  5895.             IF USED(THIS.a_scx3alias[m.i])
  5896.                 USE IN (THIS.a_scx3alias[m.i])
  5897.             ENDIF
  5898.         ENDFOR
  5899.  
  5900.         *- if lUserCall = .T., means called via project
  5901.         *- if lUserCall = .F., means screen opened individually (also used for catalogs)
  5902.         IF !THIS.lUserCall
  5903.             IF THIS.lHadError
  5904.                 *- Delete temp files if we had an error
  5905.                 IF FILE(THIS.a_scx3files[1])
  5906.                     DELETE FILE (THIS.a_scx3files[1])
  5907.                     DELETE FILE FORCEEXT(THIS.a_scx3files[1],m.cext2)
  5908.                 ENDIF
  5909.             ELSE
  5910.                 *- Compile form
  5911.                 IF !THIS.lNoCompile
  5912.                     THIS.lLocalErr = .T.
  5913.                     IF THIS.iPlatformCount > 1 AND THIS.platform = C_MAC
  5914.                         *- use proper name for Mac specific form
  5915.                         *- converting more than one platform, and this one is Mac, so add _mac
  5916.                         *- extension to the file name
  5917.                         m.cTmpFile = (AddBS(JustPath(THIS.a_scx2files[1])) + ;
  5918.                             JustStem(THIS.a_scx2files[1]) + C_MACEXT + "." + C_SCXEXT)
  5919.                     ELSE
  5920.                         cTmpFile = THIS.a_scx2files[1]
  5921.                     ENDIF
  5922.                     cErrFile = AddBS(JustPath(m.cTmpFile)) + JustStem(m.cTmpFile) + ".ERR"
  5923.                     IF FILE(m.cErrFile)
  5924.                         ERASE (m.cErrFile)
  5925.                     ENDIF
  5926.                     IF FILE(m.cTmpFile)
  5927.                         COMPILE FORM (m.cTmpFile)
  5928.                     ENDIF
  5929.  
  5930.                     IF THIS.lHadLocErr OR FILE(m.cErrFile)
  5931.                         THIS.WriteLog(SYS(2027,THIS.cNewScx),E_NOINCLUDE_LOC)
  5932.                         =MESSAGEBOX(E_NOINCLUDE1_LOC + SYS(2027,THIS.cNewScx) + E_NOINCLUDE2_LOC)
  5933.                         THIS.lHadLocErr = .F.
  5934.                     ENDIF
  5935.                     THIS.lLocalErr = .F.
  5936.                 ENDIF
  5937.  
  5938.             ENDIF
  5939.  
  5940.         ENDIF
  5941.  
  5942.     ENDPROC        &&   SCX30Converter:CloseFiles
  5943.  
  5944. ENDDEFINE
  5945.  
  5946.  
  5947. **********************************************
  5948. DEFINE CLASS FRXConverter AS ConverterBase
  5949. **********************************************
  5950.     *- class to handle the conversion of 2.6 FRX files to 3.0 files
  5951.  
  5952.     datanavclass = "fpFRXdatanav"                        && data navigation object & cursor object
  5953.     datanavRelationClass = "fpFRXDataNavRelation"        && data navigation relation object
  5954.  
  5955.     oConvForm = .NULL.
  5956.     nObjCount = 0
  5957.     fp3prop    = ""                && properties
  5958.     nDNOCount = 0
  5959.     nDNORecNo = 0                && remember record # of DataEnvironment (nee DNO) record
  5960.     lConverted = .F.            && catch frx;s in 3.0 format
  5961.     lBackup = .F.                && backup files (as .S2X, .S2T)
  5962.     lHasDataNavObj = .F.
  5963.     projcall = .F.
  5964.     parentName = ""
  5965.     lHasInvis = .F.                && flag for if has invisible buttons
  5966.     lHasIDX    = .F.                && IDX files used in environment?
  5967.     lUserCall = .T.
  5968.     cBackDir = ""
  5969.     cNewFrx = ""                && New FRX file name
  5970.     cMainCurs = ""                && alias of main table
  5971.     lNoCompile = .F.            && flag to determine whether to compile right away, or later, in batch
  5972.  
  5973.     lNeedsDE = .T.                && need a DataEnvironment made? (transporter issue) (11/9/95 jd)
  5974.  
  5975.     cfrx2files = ""
  5976.     cfrx3files = ""
  5977.     cfrx3alias = ""
  5978.  
  5979.     DIMENSION a_scx3files[1]    && for compatibility with SCX converter
  5980.     DIMENSION a_pjxsets[10]        &&  "         "        "   "      ""
  5981.     a_pjxsets = .F.
  5982.  
  5983.     formnum = 1
  5984.  
  5985.     DIMENSION a_tables[1]        && used by datanav object
  5986.     DIMENSION a_torder[1]
  5987.     a_tables = ""
  5988.     a_torder = ""
  5989.  
  5990.     *------------------------------------
  5991.     PROCEDURE Init                && FRXConverter
  5992.     *------------------------------------
  5993.         PARAMETER aParms, lBackup, lProjCall, lForceTransportDlog, lNoCompile
  5994.  
  5995.         PRIVATE cNewFrxName, oThis
  5996.         LOCAL m.cnewext1, m.cnewext2, m.coldext1, m.coldext2
  5997.  
  5998.         THIS.oConvForm = THIS
  5999.         m.oThis = THIS
  6000.  
  6001.         THIS.projcall = lProjCall
  6002.  
  6003.         THIS.lBackup = m.lBackup
  6004.  
  6005.         THIS.lTransDlog = lForceTransportDlog
  6006.  
  6007.         THIS.lNoCompile = lNoCompile
  6008.  
  6009.         THIS.llog = aParms[9]
  6010.         THIS.cLogFile = aParms[10]
  6011.  
  6012.         THIS.lAutoOpen = .T.    && auto open tables for FRX files
  6013.         THIS.lAutoClose = .T.    && auto close tables for FRX files
  6014.         
  6015.         IF THIS.projcall                    && called from project
  6016.             THIS.cBackDir = gOPJX.cBackDir  && used only for project
  6017.             THIS.cFrx2files = gOPJX.f2files
  6018.             THIS.cFrx3files = gOPJX.f3files
  6019.             THIS.cNewFrx = THIS.cFrx3files
  6020.             THIS.cCurrentFile = THIS.cFrx3files
  6021.             IF JUSTEXT(THIS.cFrx2Files) = "LBX"
  6022.                 *- labels
  6023.                 m.coldext1 = "LBX"
  6024.                 m.coldext2 = "LBT"
  6025.                 m.cnewext1 = C_LBXBACKEXT
  6026.                 m.cnewext2 = C_LBTBACKEXT
  6027.             ELSE
  6028.                 *- reports
  6029.                 m.coldext1 = "FRX"
  6030.                 m.coldext2 = "FRT"
  6031.                 m.cnewext1 = C_FRXBACKEXT
  6032.                 m.cnewext2 = C_FRTBACKEXT
  6033.             ENDIF
  6034.         ELSE
  6035.             THIS.cNewFrx = aParms[1]
  6036.             IF EMPTY(aParms[1])
  6037.                 THIS.lUserCall = .F.    && assume called without output file
  6038.                 aParms[1] = ADDBS(JUSTPATH(aParms[4])) + "F" + RIGHT(SYS(3),7) + ".FRX"
  6039.                 THIS.cNewFrx = aParms[4]
  6040.             ENDIF
  6041.             THIS.cFrx3files = aParms[1]
  6042.             THIS.cFrx2files = aParms[4]
  6043.             THIS.cCurrentFile = THIS.cFrx2files
  6044.             IF JUSTEXT(THIS.cFrx2Files) = "LBX"
  6045.                 *- labels
  6046.                 m.coldext1 = "LBX"
  6047.                 m.coldext2 = "LBT"
  6048.                 m.cnewext1 = C_LBXBACKEXT
  6049.                 m.cnewext2 = C_LBTBACKEXT
  6050.             ELSE
  6051.                 *- reports
  6052.                 m.coldext1 = "FRX"
  6053.                 m.coldext2 = "FRT"
  6054.                 m.cnewext1 = C_FRXBACKEXT
  6055.                 m.cnewext2 = C_FRTBACKEXT
  6056.             ENDIF
  6057.             *- go ahead and make backup now, before we start
  6058.             *- this is if form needs to be transported, the original is around
  6059.             IF THIS.lBackUp
  6060.                 *- copy old form with F2X,F2T extensions
  6061.                 COPY FILE (THIS.cFrx2files) TO (FORCEEXT(THIS.cFrx2files,m.cnewext1))
  6062.                 IF FILE(FORCEEXT(THIS.cFrx2files,m.coldext2))
  6063.                     COPY FILE (FORCEEXT(THIS.cFrx2files,m.coldext2)) TO (FORCEEXT(THIS.cFrx2files,m.cnewext2))
  6064.                 ENDIF
  6065.                 *- backup has been done
  6066.                 THIS.lBackUp = .F.
  6067.             ENDIF
  6068.         ENDIF
  6069.  
  6070.  
  6071.         gOTherm.SetTitle(C_THERMMSG8_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  6072.         gOTherm.Update(0,"")
  6073.         gOTherm.visible = .T.
  6074.  
  6075.         THIS.WriteLog("","")
  6076.         THIS.BeginLog(SYS(2027,THIS.cCurrentFile))
  6077.  
  6078.         THIS.platform = THIS.GetPlatForm()
  6079.         THIS.nTimeStamp = THIS.TStamp()
  6080.  
  6081.         *- also check Read-Only status if project call (04/15/96 jd)
  6082.         IF THIS.projcall AND pReadOnly(THIS.cCurrentFile)
  6083.             THIS.WriteLog(JUSTFNAME(THIS.cCurrentFile),TRIM(E_FILE_LOC) + E_NOCONVERT3_LOC)
  6084.             THIS.lHadError=.T.
  6085.             oThis = .NULL.
  6086.             RETURN .F.
  6087.         ENDIF
  6088.  
  6089.         *- now try to open FRX file -- returns alias
  6090.         *- first -- may not be a DBF (old style .FRM report), or a 1.02 FRX file
  6091.         IF FILE(THIS.cFrx2Files)
  6092.             IF Readable(THIS.cFrx2Files)
  6093.                 IF !THIS.IsDBF(THIS.cFrx2Files)
  6094.                     *- not a DBF, so try and migrate it
  6095.                     m.cNewFrxName = ForceExt(SYS(2027,THIS.cFrx2Files),;
  6096.                         IIF(UPPER(JUSTEXT(THIS.cFrx2Files)) $ "LBL|LBX",'LBX','FRX'))
  6097.                     SET MESSAGE TO C_MIGRATEMSG_LOC
  6098.                     gOTherm.SetTitle(C_THERMMSG12_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  6099.                     IF !MigDB4(THIS.cFrx2Files, @oThis)
  6100.                         THIS.WriteLog(JUSTFNAME(THIS.cFrx2Files),E_NOMIG_LOC)
  6101.                         =MESSAGEBOX(E_WRONGFMT2_LOC + " " + E_NOCONVERT_LOC)
  6102.                         THIS.lHadError=.T.
  6103.                         oThis = .NULL.
  6104.                         RETURN .F.
  6105.                     ELSE
  6106.                         *- go ahead and transport
  6107.                         gOTherm.SetTitle(C_THERMMSG9_LOC + LOWER(PARTIALFNAME(THIS.cFrx2Files,C_FILELEN)))
  6108.                         gOTherm.Update(0,"")
  6109.                         LOCAL m.lOldFrxShow
  6110.                         m.lOldFrxShow = gAShowMe[N_TRANFILE_FRX,1]
  6111.                         gAShowMe[N_TRANFILE_FRX,1] = .F.
  6112.                         DO (gTransport) WITH m.cNewFrxName,13,.F.,gAShowMe, m.gOTherm,m.cNewFrxName
  6113.                         gAShowMe[N_TRANFILE_FRX,1] = m.lOldFrxShow
  6114.                         *- newly converted
  6115.                         THIS.cFrx2Files = m.cNewFrxName
  6116.                     ENDIF
  6117.                 ENDIF
  6118.             ENDIF
  6119.         ENDIF
  6120.  
  6121.         oThis = .NULL.
  6122.  
  6123.         THIS.c25alias = THIS.OpenFile(THIS.cFrx2Files)
  6124.         IF EMPTY(THIS.c25alias)
  6125.             *- error has been logged
  6126.             *- attempt to remove backup files (jd 04/16/96)
  6127.             THIS.EraseBackup
  6128.             RETURN .F.
  6129.         ENDIF
  6130.         
  6131.         *- Check for file format
  6132.         DO CASE
  6133.             CASE FCOUNT() = C_FRXFLDS AND FIELD(1) = "PLATFORM"
  6134.                 *- check for 2.5 FRX type and no platform objects
  6135.                 LOCATE FOR platform = THIS.platform
  6136.                 IF !FOUND()
  6137.                     *- =MESSAGEBOX(E_NOPLATOBJS_LOC)
  6138.                     IF !THIS.Conv20FRX(13)
  6139.                         THIS.lHadError = .T.
  6140.                         RETURN
  6141.                     ENDIF
  6142.                 ELSE
  6143.                     *- check to see if any records are later than Windows records
  6144.                     *- if so, call transporter
  6145.                     CALCULATE MAX(timestamp) FOR platform = THIS.platform TO m.imaxThisTime
  6146.                     CALCULATE MAX(timestamp) FOR platform # THIS.platform TO m.imaxOtherTime
  6147.                     IF m.imaxOtherTime > m.imaxThisTime
  6148.                         IF !THIS.Conv20FRX(13)
  6149.                             THIS.lHadError = .T.
  6150.                             RETURN
  6151.                         ENDIF
  6152.                     ENDIF
  6153.                 ENDIF
  6154.             CASE FCOUNT() = C_20FRXFLDS AND FIELD(1) = "OBJTYPE"
  6155.                 *- check for 2.0 FRX type
  6156.                 *- Invoke Transporter
  6157.                 IF !THIS.Conv20FRX(3)
  6158.                     THIS.lHadError = .T.
  6159.                     RETURN
  6160.                 ENDIF
  6161.             CASE FCOUNT() = C_30FRXFLDS AND FIELD(75) = "USER"
  6162.                 *- assume 3.0 format, report/label was already converted
  6163.                 *- (this could be called while converting a 2.x Project
  6164.                 *- that contains frx's that have already been converted)
  6165.                 *-
  6166.                 *- look to see if platform records exist for this platform
  6167.                 *- if not, we will need to transport (10/26/95 jd)
  6168.                 *-
  6169.                 LOCATE FOR platform = THIS.platform
  6170.                 IF !FOUND()
  6171.                     *- call transporter, as if it were a 2.5 file
  6172.                     THIS.Conv20FRX(13)
  6173.                     *- since no records existed from this platform, we will just use whatever
  6174.                     *- data environment stuff that was in original, and it has been transported over...
  6175.                     THIS.lNeedsDE = .F.
  6176.                     IF USED(THIS.c25alias)
  6177.                         USE IN (THIS.c25alias)
  6178.                     ENDIF
  6179.                     IF USED(THIS.cFRX3alias)
  6180.                         USE IN (THIS.cFRX3alias)
  6181.                     ENDIF
  6182.                     *- overwrite the old file with the new one
  6183.                     *- new one will be deleted later, in pjxconverter.converter
  6184.                     IF THIS.projcall
  6185.                         COPY FILE (THIS.cFRX2files) TO (FORCEEXT(THIS.cFRX3files,m.coldext1))
  6186.                         COPY FILE (FORCEEXT(THIS.cFRX2files,m.coldext2)) TO (FORCEEXT(THIS.cFRX3files,m.coldext2))
  6187.                     ENDIF
  6188.                 ELSE
  6189.                     *- check to see if any records are are later than Mac records (11/7/95 jd)
  6190.                     *-CALCULATE MAX(timestamp) FOR platform = THIS.platform TO m.imaxThisTime
  6191.                     *-CALCULATE MAX(timestamp) FOR platform # THIS.platform TO m.imaxOtherTime
  6192.  
  6193.                     *- only check header record (11/13/95 jd)
  6194.                     LOCATE FOR platform = THIS.platform AND objtype = N_OTHEADER
  6195.                     imaxThisTime = timestamp
  6196.                     LOCATE FOR platform # THIS.platform AND objtype = N_OTHEADER
  6197.                     imaxOtherTime = timestamp
  6198.  
  6199.                     IF m.imaxOtherTime > m.imaxThisTime
  6200.                         IF !THIS.Conv20FRX(13)
  6201.                             THIS.lHadError = .T.
  6202.                             RETURN
  6203.                         ENDIF
  6204.                     ENDIF
  6205.                     GO TOP
  6206.                     IF environ
  6207.                         *- has records for this platform, but check to see if there is an
  6208.                         *- environment but no DataEnvironment -- may need to make one
  6209.                         LOCATE FOR platform = THIS.platform AND objtype = N_FRX_DATAENV
  6210.                         THIS.lNeedsDE = !FOUND()
  6211.                     ENDIF
  6212.                 ENDIF
  6213.                 IF !THIS.lNeedsDE
  6214.                     THIS.lConverted = .T.
  6215.                     THIS.oConvForm = .NULL.
  6216.                     RETURN
  6217.                 ENDIF
  6218.             CASE FCOUNT() = C_20LBXFLDS AND FIELD(1) = "OBJTYPE"
  6219.                 *- assume a 2.0 LBX type
  6220.                 *- invoke transporter
  6221.                 IF !THIS.Conv20FRX(4)
  6222.                     THIS.lHadError = .T.
  6223.                     RETURN
  6224.                 ENDIF
  6225.             OTHERWISE
  6226.                 USE IN (THIS.c25alias)
  6227.                 THIS.lHadError = .T.
  6228.                 =MESSAGEBOX(E_WRONGFMT2_LOC)
  6229.                 RETURN
  6230.         ENDCASE
  6231.     
  6232.         
  6233.         *- this cursor is for working with memo fields
  6234.         IF USED("_FOX3SPR")
  6235.           USE IN _FOX3SPR
  6236.         ENDIF
  6237.  
  6238.         CREATE CURSOR _FOX3SPR (load m)
  6239.         APPEND BLANK
  6240.         SELECT (THIS.c25alias)
  6241.  
  6242.     ENDPROC        && FRXConverter:Init
  6243.  
  6244.     *----------------------------------
  6245.     PROCEDURE Converter        && FRXConverter
  6246.     *----------------------------------
  6247.         PRIVATE oRec, oForm, a_scx2fld
  6248.         LOCAL nRecCount, nCurRec, tempfile
  6249.  
  6250.         gOTherm.SetTitle(C_THERMMSG8_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  6251.         gOTherm.Update(0)
  6252.  
  6253.         *- External preprocessor hook
  6254.           THIS.PreForm
  6255.  
  6256.         *- Create new FRX file here, and move records from 2.6 over
  6257.         THIS.CreateFRX
  6258.         THIS.new30alias = THIS.cFrx3Alias
  6259.  
  6260.         gOTherm.Update(33)
  6261.  
  6262.         *- the only thing we need to do is create a data environment, and take the data from the
  6263.         *- old environment records, which we left at the top of the file...
  6264.         SELECT (THIS.new30alias)
  6265.         GO TOP
  6266.         IF environ AND THIS.lNeedsDE
  6267.             *- no need to bother with this, if no environ (right?)
  6268.  
  6269.             oForm = THIS.oConvForm
  6270.  
  6271.             COUNT FOR INLIST(objtype,2,3,4) TO THIS.nRecCount
  6272.             THIS.nTmpCount = 1      && reset
  6273.  
  6274.             LOCATE FOR objtype = 2
  6275.             SCAN WHILE INLIST(objtype,2,3,4)
  6276.                 oRec = .NULL.
  6277.                 SCATTER MEMO TO a_scx2fld
  6278.                 nCurRec = RECNO()
  6279.  
  6280.                 DO CASE
  6281.                     CASE objtype = 2
  6282.                         *- table/cursor
  6283.                         oRec = CREATEOBJ(THIS.dataNavClass,T_DATANAV,@oForm)
  6284.                         oRec.fp3objtype = N_FRX_CURSOR
  6285.                     CASE objtype = 4
  6286.                         *- relation
  6287.                         oRec = CREATEOBJ(THIS.datanavRelationclass,T_RELATION,@oForm)
  6288.                         oRec.fp3objtype = N_FRX_RELATION
  6289.                     CASE objtype = 3
  6290.                         *- index
  6291.                         REPLACE _FOX3SPR.load WITH "SELECT " + TRIM(tag) + C_CR + ;
  6292.                             "SET INDEX TO " + TRIM(name)  + C_CR + C_CR ADDITIVE
  6293.                         THIS.lHasIDX = .T.
  6294.                 ENDCASE
  6295.                 IF TYPE("oRec") == "O"
  6296.                     *- created the object 
  6297.                     *- map any values
  6298.                     oRec.MapIt
  6299.                 
  6300.                     *- write out record -- but use our own device to do that, since
  6301.                     *- the DE record was done for an SCX
  6302.                     oRec.AddRec
  6303.  
  6304.                     *- check for error and terminate early
  6305.                     IF THIS.lHadError
  6306.                         THIS.CloseFiles
  6307.                         CLEAR EVENTS
  6308.                           RETURN -1
  6309.                     ENDIF
  6310.                 ENDIF
  6311.  
  6312.                 RELEASE oRec
  6313.  
  6314.                 gOTherm.Update(THIS.nTmpCount/THIS.nRecCount * 57 + 33) && account for 33 already shown, + 10 to be added in closefiles!
  6315.  
  6316.                 *- return to the record we were on
  6317.                 GO nCurRec
  6318.  
  6319.             ENDSCAN
  6320.  
  6321.             *- add in LOAD method, if IDX files were present
  6322.             IF !EMPTY(THIS.cSetSkip)
  6323.                 *- add in SET SKIP code
  6324.                 REPLACE _FOX3SPR.load WITH THIS.cSetSkip ADDITIVE
  6325.             ENDIF
  6326.  
  6327.             *- add DESTROY method
  6328.             REPLACE _FOX3SPR.load WITH C_FRXDEDESTROY ADDITIVE
  6329.  
  6330.             IF BETWEEN(THIS.nDNORecNo,1,RECC())
  6331.                 *- may say there's an environment, but no environment records are in the FRX
  6332.                 GO THIS.nDNORecNo
  6333.                 REPLACE tag WITH C_DATANAVOPEN + _FOX3SPR.load
  6334.                 IF !THIS.lNoCompile
  6335.                     THIS.CompileFRX
  6336.                 ENDIF
  6337.  
  6338.                 *- sort on platform, so dataenvironment is with other records from this platform
  6339.                 m.tempfile = ADDBS(JUSTPATH(THIS.cfrx3files)) + "F" + LEFT(SYS(3),7) +  "." + "FRX"
  6340.                 SORT ON platform TO (m.tempfile)
  6341.                 *- close the file, and replace the new FRX file with this sorted one
  6342.                 SELECT (THIS.new30alias)
  6343.                 USE
  6344.                 DELETE FILE (THIS.cfrx3files)
  6345.                 DELETE FILE (FORCEEXT(THIS.cfrx3files,IIF(JUSTEXT(THIS.cfrx3files) = "LBX","LBT","FRT")))
  6346.                 RENAME (m.tempfile) TO (THIS.cfrx3files)
  6347.                 RENAME (FORCEEXT(m.tempfile,"FRT")) TO (FORCEEXT(THIS.cfrx3files,IIF(JUSTEXT(THIS.cfrx3files) = "LBX","LBT","FRT")))
  6348.  
  6349.                 *- reopen it
  6350.                 USE  (THIS.cfrx3files)
  6351.  
  6352.             ENDIF
  6353.  
  6354.             
  6355.             RELEASE oForm
  6356.  
  6357.         ENDIF && environ
  6358.  
  6359.         *- float and stretch are different properties in VFP. Explicitly set float if stretch
  6360.         REPLACE ALL float WITH .T. FOR stretch
  6361.  
  6362.         *- External postprocessor hook
  6363.           THIS.PostForm
  6364.  
  6365.         gOTherm.Update(90)
  6366.  
  6367.         *- Close FRX files
  6368.         THIS.CloseFiles
  6369.  
  6370.         gOTherm.Complete
  6371.  
  6372.         *- write out end to log
  6373.         THIS.EndLog(THIS.cCurrentFile)
  6374.  
  6375.         RETURN THIS.cFRX2files
  6376.  
  6377.     ENDPROC
  6378.  
  6379.     *------------------------------------
  6380.     PROCEDURE CloseFiles            && FRXConverter
  6381.     *------------------------------------
  6382.         PRIVATE i, m.cnewext1, m.cnewext2, m.coldext1, m.coldext2
  6383.  
  6384.         IF JUSTEXT(THIS.cFrx2Files) = "LBX"
  6385.             *- labels
  6386.             m.coldext1 = "LBX"
  6387.             m.coldext2 = "LBT"
  6388.             m.cnewext1 = C_LBXBACKEXT
  6389.             m.cnewext2 = C_LBTBACKEXT
  6390.         ELSE
  6391.             *- reports
  6392.             m.coldext1 = "FRX"
  6393.             m.coldext2 = "FRT"
  6394.             m.cnewext1 = C_FRXBACKEXT
  6395.             m.cnewext2 = C_FRTBACKEXT
  6396.         ENDIF
  6397.  
  6398.         IF USED("_FOX3SPR")
  6399.             *- may need to move index file code over
  6400.             USE IN _FOX3SPR
  6401.         ENDIF
  6402.         
  6403.         IF USED(THIS.c25alias)
  6404.             USE IN (THIS.c25alias)
  6405.         ENDIF
  6406.  
  6407.         IF USED(THIS.cFRX3alias)
  6408.             USE IN (THIS.cFRX3alias)
  6409.         ENDIF
  6410.  
  6411.         *- Compile forms
  6412.         IF .F. AND FILE(THIS.cFRX3files)
  6413.             COMPILE FORM (THIS.cFRX3files)
  6414.         ENDIF
  6415.  
  6416.         *- if lUserCall = .T., means called via project
  6417.         *- if lUserCall = .F., means report opened individually
  6418.         *- not used with project calls.
  6419.         IF !THIS.lUserCall
  6420.             IF THIS.lHadError
  6421.                 *- Delete temp files if we had an error
  6422.                 IF FILE(THIS.cFRX3files)
  6423.                     DELETE FILE (THIS.cFRX3files)
  6424.                     DELETE FILE (FORCEEXT(THIS.cFRX3files,m.coldext2))
  6425.                 ENDIF
  6426.             ELSE
  6427.                 IF THIS.lBackUp
  6428.                     *- erase existing backup file if it;s there
  6429.                     IF FILE(FORCEEXT(THIS.cFRX2files,m.cnewext1))
  6430.                         DELETE FILE (FORCEEXT(THIS.cFRX2files,m.cnewext1))
  6431.                     ENDIF
  6432.                     IF FILE(FORCEEXT(THIS.cFRX2files,m.cnewext2))
  6433.                         DELETE FILE (FORCEEXT(THIS.cFRX2files,m.cnewext2))
  6434.                     ENDIF
  6435.                     *- Rename old screen with F2X,F2T extensions
  6436.                     RENAME (THIS.cFRX2files) TO (FORCEEXT(THIS.cFRX2files,m.cnewext1))
  6437.                     RENAME (FORCEEXT(THIS.cFRX2files,m.coldext2)) TO (FORCEEXT(THIS.cFRX2files,m.cnewext2))
  6438.                 ELSE
  6439.                     DELETE FILE (THIS.cFRX2files)
  6440.                     DELETE FILE (FORCEEXT(THIS.cFRX2files,m.coldext2))
  6441.                 ENDIF
  6442.  
  6443.                 *- Rename new FP3 report 
  6444.                 RENAME (THIS.cFRX3files) TO (THIS.cFRX2files)
  6445.                 *- temp new file is always named as an FRX file, so force FRT extension
  6446.                 RENAME (FORCEEXT(THIS.cFRX3files,"FRT")) TO (FORCEEXT(THIS.cFRX2files,m.coldext2))
  6447.             ENDIF
  6448.         ENDIF
  6449.  
  6450.     ENDPROC        &&  CloseFiles
  6451.  
  6452.     *------------------
  6453.     PROCEDURE CreateFRX            && FRXConverter
  6454.     *------------------
  6455.         *- need to add just one field
  6456.  
  6457.         SELECT (THIS.c25alias)
  6458.         COPY TO (THIS.cFRX3Files)
  6459.  
  6460.         SELECT 0
  6461.         USE (THIS.cFRX3Files)
  6462.  
  6463.         *- add the new user field
  6464.         IF TYPE("user") == 'U'
  6465.             ALTER TABLE (THIS.cFRX3Files) ADD user m
  6466.  
  6467.             *- ALTER TABLE leaves some mess behind...
  6468.             IF FILE(FORCEEXT(THIS.cFRX3Files,"BAK"))
  6469.                 DELETE FILE (FORCEEXT(THIS.cFRX3Files,"BAK"))
  6470.             ENDIF
  6471.             IF FILE(FORCEEXT(THIS.cFRX3Files,"TBK"))
  6472.                 DELETE FILE (FORCEEXT(THIS.cFRX3Files,"TBK"))
  6473.             ENDIF
  6474.  
  6475.         ENDIF
  6476.  
  6477.         *- remember the alias
  6478.         THIS.cFrx3Alias  = ALIAS()
  6479.  
  6480.     ENDPROC
  6481.  
  6482.     *------------------
  6483.     PROCEDURE Conv20FRX
  6484.     *------------------
  6485.     *- This transports an frx file
  6486.  
  6487.         PARAMETER m.frxtype
  6488.         *- m.frxtype = 13    && FP2.5 FRX format
  6489.         *- m.frxtype = 3        && FP2.0 FRX format
  6490.         *- m.frxtype = 4        && FP2.0 LBX format
  6491.         LOCAL m.oldudfp
  6492.         LOCAL m.cOldMess
  6493.  
  6494.         USE IN (THIS.c25alias)
  6495.         gOTherm.SetTitle(C_THERMMSG9_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  6496.         m.oldudfp = SET("UDFP")
  6497.         SET UDFP TO REFERENCE
  6498.         m.cOldMess = SET("MESSAGE",1)
  6499.         DO (gTransport) WITH THIS.cFrx2files,m.frxtype,.F.,gAShowMe, m.gOTherm,THIS.cCurrentFile,THIS.lTransDlog
  6500.         SET UDFP TO &oldudfp
  6501.         SET MESSAGE TO (cOldMess)
  6502.         THIS.c25alias = THIS.OpenFile(THIS.cfrx2files)
  6503.         IF !EMPTY(THIS.c25alias)
  6504.             IF (FCOUNT() = C_FRXFLDS OR FCOUNT() = C_30FRXFLDS) AND FIELD(1) = "PLATFORM"        && may be 3.0 transport, so check for 2.x + 3.0 field counts (jd 11/13/95)
  6505.                 LOCATE FOR Platform = THIS.Platform
  6506.                 IF FOUND()
  6507.                     RETURN .T.
  6508.                 ENDIF
  6509.             ENDIF
  6510.             USE IN (THIS.c25alias)
  6511.         ENDIF
  6512.         THIS.lHadError=.T.
  6513.         RETURN .F.
  6514.     ENDPROC
  6515.  
  6516.  
  6517.     *------------------
  6518.     PROCEDURE PostForm
  6519.     *------------------
  6520.         REPLACE ALL uniqueid WITH SYS(2015) FOR uniqueid = "~A" OR uniqueid = '^'
  6521.         REPLACE ALL timestamp WITH THIS.nTimeStamp FOR platform = THIS.platform
  6522.     ENDPROC
  6523.  
  6524.     *------------------------------------
  6525.     PROCEDURE Cleanup                && FRXConverter
  6526.     *------------------------------------
  6527.         *- this proc is called by Error, and tries to put things back the way they were
  6528.         *- if cleaning up from a crashed project conversion, the pjx cleanup will
  6529.         *- handle the reports
  6530.         LOCAL i
  6531.  
  6532.         IF !THIS.lUserCall 
  6533.             *- report opened individually
  6534.             *- Delete temp files if we had an error
  6535.             CLOSE TABLES
  6536.             IF FILE(THIS.cFrx3files)
  6537.                 DELETE FILE (THIS.cFrx3files)
  6538.                 IF FILE(FORCEEXT(THIS.cFrx3files,IIF(JUSTEXT(THIS.cFrx3files) = "LBX","LBT","FRT")))
  6539.                     DELETE FILE (FORCEEXT(THIS.cFrx3files,IIF(JUSTEXT(THIS.cFrx3files) = "LBX","LBT","FRT")))
  6540.                 ENDIF
  6541.             ENDIF
  6542.             IF !THIS.lBackUp
  6543.                 *- a backup could have already been made (e.g., a 2.0 file was being converted)
  6544.                 *- restore old report/label from F2X,F2T extensions
  6545.                 IF    FILE(THIS.cFrx2files) AND ;
  6546.                     FILE(FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT)) AND ;
  6547.                     FILE(FORCEEXT(THIS.cFrx2files,"FRT")) AND ;
  6548.                     FILE(FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT))
  6549.                     *- all of the files are there to attempt this, so...
  6550.                     DELETE FILE (THIS.cFrx2files)
  6551.                     DELETE FILE (FORCEEXT(THIS.cFrx2files,"FRT"))
  6552.                     IF !FILE(THIS.cFrx2files)
  6553.                         RENAME (FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT)) TO (THIS.cFrx2files)
  6554.                     ENDIF
  6555.                     IF !FILE(FORCEEXT(THIS.cFrx2files,"FRT"))
  6556.                         RENAME (FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT)) TO (FORCEEXT(THIS.cFrx2files,"FRT"))
  6557.                     ENDIF
  6558.                 ENDIF
  6559.                 *- under certain circumstances, these may be left around
  6560.                 IF FILE(FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT))
  6561.                     DELETE FILE (FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT))
  6562.                 ENDIF
  6563.                 IF FILE(FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT))
  6564.                     DELETE FILE (FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT))
  6565.                 ENDIF
  6566.             ENDIF
  6567.         ENDIF
  6568.  
  6569.         THIS.oConvForm = .NULL.
  6570.  
  6571.     ENDPROC
  6572.  
  6573.     *------------------
  6574.     PROCEDURE EraseBackup            && FRXConverter
  6575.     *------------------
  6576.         *- get rid of backup files (jd 04/15/96)
  6577.         IF FILE(FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT))
  6578.             ERASE FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT)
  6579.         ENDIF
  6580.         IF FILE(FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT))
  6581.             ERASE FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT)
  6582.         ENDIF
  6583.  
  6584.     ENDPROC
  6585.  
  6586.  
  6587. ENDDEFINE        && FRXConverter
  6588.  
  6589.  
  6590. **********************************************
  6591. DEFINE CLASS fp25obj AS ConverterBase
  6592. **********************************************
  6593.     
  6594.     *- Properties corresponding to new SCX form fields
  6595.     fp3plat     = ""    && platform
  6596.     fp3saveplat = C_WINDOWS        && platform that is saved in SCX file (always WINDOWS on VFP Mac --jd 03/27/96)
  6597.     fp3id         = ""    && uniqueid
  6598.     fp3time     = 0        && timestamp
  6599.     fp3comment    = ""    && comment
  6600.     fp3class    = ""    && class
  6601.     fp3base        = ""    && baseclass
  6602.     fp3name     = ""    && objname
  6603.     fp3prop        = ""    && properties
  6604.     fp3method    = ""    && methods
  6605.     fp3parent    = ""    && parent
  6606.     fp3reserved1= ""    && reserved1
  6607.     fp3reserved2= ""    && reserved2
  6608.     fp3reserved6= ""    && reserved6
  6609.  
  6610.     *- Fontmetrics
  6611.     fp3font        = ""    && font face
  6612.     fp3fsize    = ""    && font size
  6613.     fp3fstyle    = ""    && font style
  6614.     fp3font1    = 1        && FONT(TM_HEIGHT)
  6615.     fp3font5    = 0        && FONT(TM_EXTERNALLEADING)
  6616.     fp3font6    = 1     && FONT(TM_AVECHARWIDTH)
  6617.  
  6618.     fp3fudge    = 0        && fudge factor for horizontal positioning
  6619.  
  6620.     *- Object Code 
  6621.     fp25OT = 0
  6622.     fp25OC = 0
  6623.     
  6624.     *- Object References
  6625.     formRef = ""
  6626.     
  6627.     *- Picture clause parts (ex. "@KJ XXXXX")
  6628.     *- ex. picword1 = @KJ  
  6629.     *-     picword2 = XXXXX
  6630.     
  6631.     picword1 = ""
  6632.     picword2 = ""
  6633.     picword3 = ""
  6634.     hasitse  = .F.
  6635.     
  6636.     iColorSource = I_DEFCOLORSOURCE
  6637.     
  6638.     *----------------------
  6639.     PROCEDURE Init            && fp25obj
  6640.     *----------------------
  6641.         PARAMETER parm1,parm2
  6642.         THIS.fp3class  = m.parm1            && class
  6643.         THIS.fp3base   = m.parm1            && baseclass
  6644.         THIS.formRef   = m.parm2            && form reference
  6645.         THIS.fp25OT    = a_scx2fld[A_ObjType]
  6646.         THIS.fp25OC    = a_scx2fld[A_ObjCode]
  6647.         THIS.fp3prop   = ""                    && properties
  6648.         THIS.fp3method = ""                    && methods
  6649.     ENDPROC
  6650.  
  6651.     *----------------------
  6652.     PROCEDURE MapIt
  6653.     *----------------------
  6654.         *- This is the main mapping program.
  6655.         *- It uses FP25OBJ base methods unless
  6656.         *- overridden by subclass method.
  6657.         THIS.PreMap
  6658.         THIS.AddBasic
  6659.         THIS.AddFont
  6660.         THIS.AddPos
  6661.         THIS.AddColor
  6662.         THIS.AddMain
  6663.         THIS.PostMap
  6664.         THIS.WriteName     && note Name property must be written last!
  6665.     ENDPROC
  6666.  
  6667.     *----------------------
  6668.     PROCEDURE AddMain
  6669.     *----------------------
  6670.     ENDPROC
  6671.     
  6672.     *----------------------
  6673.     PROCEDURE PreMap
  6674.     *----------------------
  6675.     ENDPROC
  6676.     
  6677.     *----------------------
  6678.     PROCEDURE PostMap
  6679.     *----------------------
  6680.     ENDPROC
  6681.  
  6682.     *----------------------
  6683.     FUNCTION FullBMP
  6684.     *----------------------
  6685.         *- returns fullpath of BMP
  6686.         PARAMETER bmpfpath
  6687.         RETURN bmpfpath
  6688.         
  6689.     ENDFUNC
  6690.  
  6691.     *----------------------
  6692.     FUNCTION GetPicPart
  6693.     *----------------------
  6694.         PARAMETER cPictStr
  6695.         *- picword1 (format)
  6696.         *- picword2 (inputmsk,bmp,caption)
  6697.         *- picword3 (misc #ITSE add-ons)
  6698.         
  6699.         PRIVATE spcloc,tmpstr,tmpcnt,tmpword,tmploc,tmpprestr
  6700.         IF EMPTY(ALLTRIM(m.cPictStr))
  6701.             RETURN
  6702.         ENDIF
  6703.         
  6704.         m.cPictStr = SUBS(m.cPictStr,2,LEN(m.cPictStr) - 2)    && EVAL(m.cPictStr)    && remove dbl quotes
  6705.         
  6706.         *- check for #ITSEXPRESSION
  6707.         IF !EMPTY(THIS.formRef.itse_expr) AND ;
  6708.             INLIST(a_scx2fld[A_ObjType],15,22) AND ;
  6709.             AT(THIS.formRef.itse_expr,m.cPictStr) # 0
  6710.             *- parse out GENSCRN tricks
  6711.             *- ex.   ~ [] NOMODIFY 
  6712.             *-       ~ [@!] COLOR ,N/N
  6713.             THIS.hasitse = .T.
  6714.             m.tmploc = AT(THIS.formRef.itse_expr,m.cPictStr)
  6715.             m.tmpstr = ALLT(SUBSTR(m.cPictStr,m.tmploc + 1))
  6716.             m.tmpprestr = LEFT(m.cPictStr,m.tmploc - 1)
  6717.             m.tmpcnt = 1
  6718.             DO WHILE .T.
  6719.                 tmpword = WORDNUM(m.tmpstr,m.tmpcnt)
  6720.                 DO CASE
  6721.                     CASE EMPTY(m.tmpword)
  6722.                         EXIT
  6723.                     CASE UPPER(m.tmpword) $ "NOMODIFY FONT STYLE COLOR SIZE"
  6724.                         THIS.picword3 = SUBSTR(m.tmpstr,AT(m.tmpword,m.tmpstr))
  6725.                         m.tmpstr = RTRIM(LEFT(m.tmpstr,AT(m.tmpword,m.tmpstr)-1))                 
  6726.                         EXIT
  6727.                 ENDCASE
  6728.                 m.tmpcnt = m.tmpcnt+1
  6729.             ENDDO
  6730.             IF EMPTY(m.tmpprestr)
  6731.                 m.cPictStr = m.tmpstr
  6732.             ENDIF
  6733.         ENDIF
  6734.         
  6735.         *- get location of space
  6736.         spcloc = ATC(" ",m.cPictStr)
  6737.         
  6738.         DO CASE
  6739.             CASE THIS.hasitse AND !EMPTY(m.tmpprestr)
  6740.                 THIS.picword1 = THIS.addquotes(ALLTRIM(m.tmpprestr))
  6741.                 THIS.picword2 = ALLTRIM(m.tmpstr)
  6742.             CASE THIS.hasitse AND AT("@",m.cPictStr)=0
  6743.                 THIS.picword2 = m.cPictStr
  6744.             CASE THIS.hasitse
  6745.                 THIS.picword1 = m.cPictStr
  6746.             CASE m.spcloc = 0 AND AT("@",m.cPictStr) # 0
  6747.                 THIS.picword1 = m.cPictStr
  6748.             CASE m.spcloc = 0
  6749.                 THIS.picword2 = m.cPictStr
  6750.             CASE AT("@",m.cPictStr) = 0
  6751.                 THIS.picword2 = m.cPictStr
  6752.             CASE EMPTY(SUBSTR(m.cPictStr,m.spcloc))
  6753.                 THIS.picword1 = m.cPictStr
  6754.             OTHERWISE
  6755.                 THIS.picword1 = LEFT(m.cPictStr,m.spcloc-1)
  6756.                 THIS.picword2 = ALLT(SUBSTR(m.cPictStr,m.spcloc+1))
  6757.         ENDCASE
  6758.         
  6759.         IF THIS.hasitse
  6760.             * special handling for #ITSEXPRESSION
  6761.             IF !EMPTY(THIS.picword1) AND EMPTY(m.tmpprestr) AND ;
  6762.                 LEFT(LTRIM(THIS.picword1),1) # "+"
  6763.                 THIS.picword1 = "+" + THIS.picword1
  6764.             ENDIF
  6765.             
  6766.             IF !EMPTY(THIS.picword2) AND ;
  6767.                 LEFT(LTRIM(THIS.picword2),1) # "+"
  6768.                 THIS.picword2 = "+" + THIS.picword2
  6769.             ENDIF        
  6770.         ENDIF
  6771.     ENDFUNC
  6772.     
  6773.     *----------------------
  6774.     PROCEDURE AddRec        && fp25obj
  6775.     *----------------------
  6776.         *- Add record to FORM file
  6777.         *- NOTE: This is overridden in some cases (e.g. fp25form)
  6778.         *- where different value needs to be inserted into reserved4 field
  6779.         IF THIS.formRef.lDevMode
  6780.             *- put methods someplace else
  6781.             INSERT INTO (THIS.formRef.new30alias) ;
  6782.              (platform,uniqueid,timestamp,;
  6783.               class,baseclass,objname,parent,properties,;
  6784.               user,reserved2);
  6785.              VALUES(THIS.fp3saveplat,THIS.fp3id,THIS.fp3time,;
  6786.               THIS.fp3class,THIS.fp3base,THIS.fp3name,;
  6787.               THIS.fp3parent,THIS.fp3prop,;
  6788.               THIS.fp3comment,;
  6789.               THIS.fp3reserved2)
  6790.             IF !EMPTY(THIS.fp3method)
  6791.                 REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.fp3name + C_CRLF + THIS.fp3method ADDITIVE
  6792.             ENDIF
  6793.         ELSE
  6794.             INSERT INTO (THIS.formRef.new30alias) ;
  6795.              (platform,uniqueid,timestamp,;
  6796.               class,baseclass,objname,parent,properties,;
  6797.               methods,user,reserved2);
  6798.              VALUES(THIS.fp3saveplat,THIS.fp3id,THIS.fp3time,;
  6799.               THIS.fp3class,THIS.fp3base,THIS.fp3name,;
  6800.               THIS.fp3parent,THIS.fp3prop,;
  6801.               THIS.fp3method,;
  6802.               THIS.fp3comment,;
  6803.               THIS.fp3reserved2)
  6804.         ENDIF
  6805.     ENDPROC
  6806.  
  6807.     *----------------------
  6808.     PROCEDURE AddBasic        && fp25obj
  6809.     *----------------------
  6810.         *- Update common fields
  6811.         THIS.fp3plat     = a_scx2fld[A_PLATFORM]         && platform
  6812.         THIS.fp3time     = THIS.formRef.nTimeStamp     && timestamp
  6813.         THIS.fp3comment    = a_scx2fld[A_COMMENT]        && comment
  6814.         THIS.fp3parent  = THIS.formRef.parentName
  6815.         THIS.fp3id         = "~A"                         && we'll sort on this field later
  6816.         THIS.formRef.lHasInvis = .T.
  6817.     ENDPROC
  6818.  
  6819.     *----------------------
  6820.     PROCEDURE AddName    && fp25obj
  6821.     *----------------------
  6822.         PARAMETER cAddname
  6823.         THIS.fp3name = m.cAddname
  6824.     ENDPROC
  6825.  
  6826.     *----------------------
  6827.     PROCEDURE WriteName    && fp25obj
  6828.     *----------------------
  6829.         THIS.AddProp(M_NAME,THIS.fp3name)
  6830.     ENDPROC
  6831.  
  6832.     *----------------------
  6833.     PROCEDURE AddFont    && fp25obj
  6834.     *----------------------
  6835.         PARAMETER m.nbtn
  6836.         
  6837.         *- check for non-GUI platform
  6838.         IF !INLIST(a_scx2fld[A_PLATFORM],C_MAC,C_WINDOWS)
  6839.             RETURN
  6840.         ENDIF
  6841.     
  6842.         THIS.fp3font  = ALLTRIM(a_scx2fld[A_FONTFACE])
  6843.         THIS.fp3fsize = a_scx2fld[A_FONTSIZE]
  6844.         THIS.fp3fstyle = THIS.GetStyle(a_scx2fld[A_FONTSTYLE])
  6845.         
  6846.         THIS.fp3font1 = FONT(1,THIS.fp3font,THIS.fp3fsize,THIS.fp3fstyle)
  6847.         THIS.fp3font5 = FONT(5,THIS.fp3font,THIS.fp3fsize,THIS.fp3fstyle)
  6848.         THIS.fp3font6 = FONT(6,THIS.fp3font,THIS.fp3fsize,THIS.fp3fstyle)
  6849.         
  6850.         THIS.nDeffont1 = THIS.formRef.nDeffont1     && default screen font1
  6851.         THIS.nDeffont5 = THIS.formRef.nDeffont5     && default screen font5
  6852.         THIS.nDeffont6 = THIS.formRef.nDeffont6     && default screen font6
  6853.  
  6854.         *- Add fontface and fontsize
  6855.         THIS.AddProp(M_FONTFACE,THIS.fp3font,m.nbtn)
  6856.         THIS.AddProp(M_FONTSIZE,THIS.fp3fsize,m.nbtn)
  6857.         
  6858.         *- Add font styles
  6859.         
  6860.         *- Bold is default on some so always add it
  6861.         THIS.AddProp(M_FONTBOLD,ATC("B",THIS.fp3fstyle) # 0,m.nbtn)
  6862.         
  6863.         *- Italic
  6864.         IF ATC("I",THIS.fp3fstyle) # 0 
  6865.             THIS.AddProp(M_FONTITAL,C_TRUE,m.nbtn)
  6866.         ENDIF
  6867.         
  6868.         *- Underline
  6869.         IF ATC("U",THIS.fp3fstyle) # 0 
  6870.             THIS.AddProp(M_FONTUNDER,C_TRUE,m.nbtn)
  6871.         ENDIF
  6872.  
  6873.         IF _mac
  6874.             *- these attributes only exist on the Mac (12/5/95 jd)
  6875.             IF ATC("O",THIS.fp3fstyle) # 0 
  6876.                 THIS.AddProp(M_FONTOUTLINE,C_TRUE,m.nbtn)
  6877.             ENDIF
  6878.  
  6879.             *- these attributes only exist on the Mac (12/5/95 jd)
  6880.             IF ATC("S",THIS.fp3fstyle) # 0 
  6881.                 THIS.AddProp(M_FONTSHADOW,C_TRUE,m.nbtn)
  6882.             ENDIF
  6883.  
  6884.             *- these attributes only exist on the Mac (12/5/95 jd)
  6885.             IF ATC("C",THIS.fp3fstyle) # 0 
  6886.                 THIS.AddProp(M_FONTCONDENSE,C_TRUE,m.nbtn)
  6887.             ENDIF
  6888.  
  6889.             *- these attributes only exist on the Mac (12/5/95 jd)
  6890.             IF ATC("E",THIS.fp3fstyle) # 0 
  6891.                 THIS.AddProp(M_FONTEXTEND,C_TRUE,m.nbtn)
  6892.             ENDIF
  6893.  
  6894.         ENDIF
  6895.  
  6896.     ENDPROC
  6897.     
  6898.     *----------------------
  6899.     PROCEDURE AddPos        && fp25obj
  6900.     *----------------------
  6901.         *- Add object positions in pixels (how FP3 stores it)
  6902.         *- VPOS,HPOS based on form font
  6903.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS] * (THIS.nDeffont1+THIS.nDeffont5))        
  6904.         THIS.AddProp(M_HPOS,(a_scx2fld[A_HPOS] - THIS.fp3fudge) * THIS.nDeffont6)
  6905.         
  6906.         *- HEIGHT,WIDTH based on object font
  6907.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6)
  6908.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  6909.             (THIS.fp3font1+THIS.fp3font5))
  6910.  
  6911.     ENDPROC
  6912.  
  6913.     *----------------------
  6914.     PROCEDURE AddColor    && fp25obj
  6915.     *----------------------
  6916.         *- Add colorstuff
  6917.         *- Add pen color
  6918.         PARAMETER m.btn
  6919.  
  6920.         THIS.AddProp(M_COLORSOURCE, THIS.iColorSource, m.btn)        && made colorsource value a property, so it is easier too override (jd 06/20/96)
  6921.  
  6922.         IF a_scx2fld[A_PENRED] # -1
  6923.             
  6924.             THIS.AddProp(M_PEN,ALLT(STR(a_scx2fld[A_PENRED])) + ;
  6925.                 "," + ALLT(STR(a_scx2fld[A_PENGREEN])) + ;
  6926.                 "," + ALLT(STR(a_scx2fld[A_PENBLUE])),m.btn)
  6927.  
  6928.         ENDIF
  6929.         
  6930.         *- Add fill color
  6931.         IF a_scx2fld[A_FILLRED] = -1
  6932.         ELSE                
  6933.             THIS.AddProp(M_BACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  6934.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  6935.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])),m.btn)
  6936.             THIS.AddProp(M_FILLCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  6937.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  6938.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])),m.btn)
  6939.             THIS.AddProp(M_DISBACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  6940.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  6941.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])),m.btn)
  6942.         ENDIF
  6943.     ENDPROC            && fp25obj
  6944.     
  6945.     *----------------------
  6946.     FUNCTION GetStyle    && fp25obj
  6947.     *----------------------
  6948.         *- Takes font style in SCX/FRX file and converts to
  6949.         *- font style code used by FONTMETRIC functions.
  6950.         PARAMETER iFntStyle
  6951.         LOCAL cFontStyle, i
  6952.         cFontStyle = "N"
  6953.         m.cStyleCodes = "BIUOSCE"   && bold (1), italic (2), underline (4), outline (8), 
  6954.                                     && shadow (16), condensed (32), extended (64)
  6955.  
  6956.         IF m.iFntStyle > 0
  6957.             *- has an attribute
  6958.             FOR i = 6 TO 0 STEP -1
  6959.                 IF m.iFntStyle >= 2^i
  6960.                     m.cFontStyle = m.cFontStyle + SUBSTR(m.cStyleCodes,i + 1,1)
  6961.                     m.iFntStyle = m.iFntStyle - 2^i
  6962.                 ENDIF
  6963.             NEXT 
  6964.         ENDIF
  6965.  
  6966.         RETURN m.cFontStyle
  6967.  
  6968.         *DO CASE
  6969.         *    CASE m.iFntStyle = 1        && BOLD
  6970.         *        RETURN 'B'
  6971.         *    CASE m.iFntStyle = 2        && ITALIC
  6972.         *        RETURN 'I'
  6973.         *    CASE m.iFntStyle = 3        && BOLD ITALIC
  6974.         *        RETURN 'BI'
  6975.         *    OTHERWISE                      && NORMAL
  6976.         *        RETURN 'N'
  6977.         *ENDCASE
  6978.     ENDFUNC 
  6979.     
  6980.     *----------------------
  6981.     FUNCTION GetNewName    && fp25obj
  6982.     *----------------------
  6983.         PARAMETER newobj
  6984.         PRIVATE cName
  6985.  
  6986.         cName = ALLT(a_scx2fld[A_NAME]) 
  6987.         *- use data source if available
  6988.         IF !EMPTY(cName)
  6989.             *- name could be an array element, so strip out
  6990.             m.cName = CHRTRANC(m.cName,",()[]","_")
  6991.             IF " " $ cName
  6992.                 *- space in name (e.g. "varname BITMAP") -- 
  6993.                 *- for now, take everything up to it
  6994.                 cName = LEFT(cName, AT(" ",cName) - 1)
  6995.                 IF ("\" $ cName) OR ("." $ cName) OR (":" $ cName)
  6996.                     *- assume is some kind of filename
  6997.                     *- strip off quotes if they are there
  6998.                     m.cName = JustStem(StripQuote(m.cname))
  6999.                 ENDIF
  7000.             ELSE
  7001.                 m.cName = IIF("->" $ cName,SUBSTR(cName,AT("->",cName) + 2),;
  7002.                         SUBSTR(cName,AT(".",cName) + 1))
  7003.             ENDIF
  7004.         ELSE
  7005.             m.cName = m.newobj
  7006.         ENDIF
  7007.         THIS.formRef.nObjCount = THIS.formRef.nObjCount + 1
  7008.         RETURN THIS.GetVarPrefix(m.newobj) + PROPER(ALLTRIM(m.cName)) + ALLTRIM(STR(THIS.formRef.nObjCount))
  7009.     ENDFUNC        &&  GetNewName
  7010.  
  7011.     *----------------------
  7012.     PROCEDURE AddFormat        && fp25obj
  7013.     *----------------------
  7014.         *- Add function codes - format
  7015.         DO CASE 
  7016.             CASE EMPTY(THIS.picword1)
  7017.                 *- skip
  7018.             CASE !THIS.hasitse
  7019.                 THIS.AddProp(M_FORMAT,THIS.addquotes(THIS.picword1))
  7020.             OTHERWISE
  7021.                 THIS.AddProp(M_FORMAT,THIS.picword1)
  7022.         ENDCASE
  7023.         
  7024.         *- Add picture codes - inputmask
  7025.         DO CASE
  7026.             CASE EMPTY(THIS.picword2)
  7027.             CASE !THIS.hasitse 
  7028.                 THIS.AddProp(M_INPUTMSK,THIS.addquotes(THIS.picword2))
  7029.             OTHERWISE
  7030.                 THIS.AddProp(M_INPUTMSK,THIS.picword2)
  7031.         ENDCASE
  7032.     ENDPROC        &&  AddFormat
  7033.     
  7034.     *----------------------
  7035.     PROCEDURE AddFX        && fp25obj
  7036.     *----------------------
  7037.         *- Add Special Effects
  7038.         *- support 3-D effects from FoxMac 2.6 (12/5/95 jd)
  7039.         PARAMETER btn
  7040.         IF a_scx2fld[A_PLATFORM] = C_MAC AND "3" $ THIS.picword1
  7041.             THIS.AddProp(M_SPECIAL,N_3D,m.btn)
  7042.         ELSE
  7043.             THIS.AddProp(M_SPECIAL,N_PLAIN,m.btn)
  7044.         ENDIF
  7045.     ENDPROC
  7046.  
  7047.     *----------------------
  7048.     PROCEDURE AddMode        && fp25obj
  7049.     *----------------------
  7050.         *- add the mode (opaque/transparent)
  7051.         *- if mode has to be converted, check for opaque w/ no fill pat
  7052.         PARAMETER lConvert,nMode,nFillPat,m.btn
  7053.         IF !lConvert
  7054.             THIS.AddProp(M_MODE,nMode,m.btn)
  7055.         ELSE
  7056.             *- reverse transparent/opaque value in 3.0
  7057.             THIS.AddProp(M_MODE,ABS(nMode - 1),m.btn)
  7058.         ENDIF
  7059.     ENDPROC
  7060.  
  7061.     *----------------------
  7062.     PROCEDURE Conv2Str
  7063.     *----------------------
  7064.         PARAMETER pstring
  7065.         DO CASE
  7066.         CASE TYPE(m.pstring) = "L"
  7067.             RETURN "IIF("+m.pstring+",'T','F')"
  7068.         CASE INLIST(TYPE(m.pstring),"N","F")
  7069.             RETURN "ALLTRIM(STR("+m.pstring+"))"
  7070.         CASE TYPE(m.pstring) = "D"
  7071.             RETURN "DTOS("+m.pstring+")"
  7072.         OTHERWISE      && don't index
  7073.             RETURN m.pstring
  7074.         ENDCASE
  7075.     ENDPROC
  7076.  
  7077. ENDDEFINE        &&  fp25obj 
  7078.  
  7079.  
  7080. ************************************
  7081. DEFINE CLASS fp25ctrl AS fp25obj
  7082. ************************************
  7083.         
  7084.     *----------------------
  7085.     PROCEDURE AddBasic        && fp25ctrl
  7086.     *----------------------
  7087.         fp25obj::AddBasic
  7088.         THIS.fp3id = "~B"        && we'll sort on this field later
  7089.     ENDPROC
  7090.  
  7091.     *----------------------
  7092.     PROCEDURE AddMain        && fp25ctrl
  7093.     *----------------------
  7094.         *- Now add control specific properties
  7095.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  7096.         
  7097.         *- add mode
  7098.         THIS.AddMode(L_CONVERT,a_scx2fld[A_MODE],a_scx2fld[A_FILLPAT])
  7099.  
  7100.         IF !THIS.formref.noReadPlainExpr OR (a_scx2fld[A_WHENTYPE] == 0)
  7101.             THIS.AddMethods(M_WHEN2,THIS.FormRef.CleanProc(a_scx2fld[A_WHEN]),a_scx2fld[A_WHENTYPE])
  7102.         ENDIF
  7103.         IF !THIS.formref.noReadPlainExpr OR (a_scx2fld[A_VALIDTYPE] == 0)
  7104.             THIS.AddMethods(M_VALID2,THIS.FormRef.CleanProc(a_scx2fld[A_VALID]),a_scx2fld[A_VALIDTYPE])
  7105.         ENDIF
  7106.         IF !THIS.formref.noReadPlainExpr OR (a_scx2fld[A_MESSTYPE] == 0)
  7107.             THIS.AddMethods(M_MESSAGE,a_scx2fld[A_MESSAGE],a_scx2fld[A_MESSTYPE])
  7108.         ENDIF
  7109.         IF !THIS.formref.noReadPlainExpr OR (a_scx2fld[A_ERRORTYPE] == 0)
  7110.             THIS.AddMethods(M_ERROR,a_scx2fld[A_ERROR],a_scx2fld[A_ERRORTYPE])
  7111.         ENDIF
  7112.         IF !THIS.formRef.lHasSys16
  7113.             THIS.formRef.lHasSys16 = ("SYS(16" $ UPPER(THIS.fp3method))
  7114.         ENDIF
  7115.  
  7116.         *- Get parts of Picture clause for use below
  7117.         THIS.GetPicPart(a_scx2fld[A_PICTURE])
  7118.  
  7119.         *- add releaseerase
  7120.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  7121.  
  7122.         *- DO specific action for control
  7123.         THIS.AddCtrl
  7124.  
  7125.         *- Add datasource (field, memvar, etc.)
  7126.         *- This has to be added after Value, RowSource etc,
  7127.         THIS.AddProp(M_DATASOURCE,ALLTRIM(a_scx2fld[A_NAME]))
  7128.  
  7129.         *- add 3D special effects
  7130.         THIS.AddFX
  7131.  
  7132.  
  7133.     ENDPROC    && AddMain
  7134.     
  7135.     *----------------------
  7136.     PROCEDURE AddCtrl        && fp25ctrl
  7137.     *----------------------
  7138.                 
  7139.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7140.  
  7141.     ENDPROC
  7142.     
  7143.     *----------------------
  7144.     PROCEDURE AddGroup        && fp25ctrl
  7145.     *----------------------
  7146.         PARAMETER btnname,invisbtn,optbtn
  7147.         
  7148.         PRIVATE i,capname,btn,vspc,hspc,lhaspicts,totbtns
  7149.         PRIVATE unitwid,unithgt,st_left,st_top,lishoriz
  7150.                 
  7151.         m.totbtns = OCCUR(";",a_scx2fld[A_PICTURE]) + 1
  7152.         m.lhaspicts = ATC("B",THIS.picword1) # 0
  7153.         m.lishoriz =  ATC("H",THIS.picword1) # 0
  7154.  
  7155.         *- VPOS,HPOS based on form font
  7156.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS] * (THIS.nDeffont1 + THIS.nDeffont5))        
  7157.         THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS] * THIS.nDeffont6)
  7158.  
  7159.         IF m.lishoriz  && horizontal buttons
  7160.             THIS.AddProp(M_WIDTH,((a_scx2fld[A_WIDTH]+a_scx2fld[A_SPACING]) * ;
  7161.                 m.totbtns*THIS.fp3font6)-(a_scx2fld[A_SPACING]*THIS.fp3font6))
  7162.             THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7163.                 (THIS.fp3font1+THIS.fp3font5))
  7164.             m.vspc = 0
  7165.             m.hspc = a_scx2fld[A_SPACING]*THIS.fp3font6
  7166.         ELSE
  7167.             THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6)
  7168.             THIS.AddProp(M_HEIGHT,((a_scx2fld[A_HEIGHT] + a_scx2fld[A_SPACING]) * ;
  7169.                 m.totbtns * (THIS.fp3font1 + THIS.fp3font5)) - ;
  7170.                 (a_scx2fld[A_SPACING] * (THIS.fp3font1 + THIS.fp3font5)))
  7171.             m.vspc = a_scx2fld[A_SPACING] * (THIS.fp3font1 + THIS.fp3font5)
  7172.             m.hspc = 0
  7173.         ENDIF
  7174.  
  7175.         IF m.btnName = "Option"
  7176.             THIS.AddMode(L_NOCONVERT,0)      && always transparent
  7177.         ELSE
  7178.             THIS.AddMode(L_NOCONVERT,0)      && always transparent
  7179.         ENDIF
  7180.  
  7181.         THIS.AddProp(M_BORDER,0)            && no auto-border around group
  7182.  
  7183.         THIS.AddProp(M_BUTTONS,m.totbtns)    && number of buttons
  7184.         
  7185.         m.unitwid = a_scx2fld[A_WIDTH] * THIS.fp3font6
  7186.         m.unithgt = a_scx2fld[A_HEIGHT] * (THIS.fp3font1 + THIS.fp3font5)
  7187.  
  7188.         *- buttons are offset from their container
  7189.         m.st_top = 0
  7190.         m.st_left = 0        
  7191.  
  7192.         *- Add name here - must be last
  7193.         THIS.AddProp(M_NAME,THIS.fp3name)
  7194.         
  7195.         *- Add specific buttons detail
  7196.         FOR i = 1 TO m.totbtns 
  7197.             m.btn = m.btnname + ALLTRIM(STR(m.i))
  7198.             DO CASE
  7199.                 CASE m.totbtns = 1    && single button
  7200.                     m.capname = THIS.picword2    
  7201.                 CASE m.i = 1
  7202.                     m.capname = LEFT(THIS.picword2,AT(";",THIS.picword2)-1)
  7203.                 CASE m.i = m.totbtns
  7204.                     m.capname = SUBSTR(THIS.picword2,RAT(";",THIS.picword2)+1)
  7205.                 OTHERWISE
  7206.                     m.pos1 = AT(";",THIS.picword2,m.i-1)+1
  7207.                     m.pos2 = AT(";",THIS.picword2,m.i)
  7208.                     m.capname = SUBSTR(THIS.picword2,m.pos1,m.pos2-m.pos1)                
  7209.             ENDCASE
  7210.             
  7211.             *- individual buttons have font attributes
  7212.             THIS.AddFont(m.btn)
  7213.  
  7214.             *- individual buttons need color props set
  7215.             THIS.AddColor(m.btn)
  7216.  
  7217.             *- make plain
  7218.             THIS.AddFX(m.btn)
  7219.             *- THIS.AddProp(M_SPECIAL,N_PLAIN,m.btn)
  7220.  
  7221.             DO CASE
  7222.                 CASE m.invisbtn            && invisible buttons
  7223.                     THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED],m.btn)
  7224.                     THIS.AddProp(M_STYLE,1,m.btn)
  7225.                 CASE m.lhaspicts         && picture buttons
  7226.                     THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED],m.btn)
  7227.                     THIS.AddProp(M_FPICTURE,THIS.FullBMP(m.capname),m.btn)
  7228.                     THIS.AddProp(M_CAPTION,[""],m.btn)
  7229.                     IF m.optbtn
  7230.                         THIS.AddProp(M_STYLE,1,m.btn)
  7231.                     ENDIF
  7232.                 OTHERWISE
  7233.                     IF "\\" $ m.capname
  7234.                         *- disabled, so strip out double backslash
  7235.                         m.capname = STRTRAN(m.capname,"\\")
  7236.                         THIS.AddProp(M_ENABLED,.F.,m.btn)
  7237.                     ELSE
  7238.                         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED],m.btn)
  7239.                     ENDIF
  7240.                     IF "\!" $ m.capname
  7241.                         *- default, so strip out and set property
  7242.                         m.capname = STRTRAN(m.capname,"\!")
  7243.                         THIS.AddProp(M_DEFAULT,.T.,m.btn)
  7244.                     ENDIF
  7245.                     IF "\?" $ m.capname
  7246.                         *- escape/cancel, so strip out and set property
  7247.                         m.capname = STRTRAN(m.capname,"\?")
  7248.                         THIS.AddProp(M_CANCEL,.T.,m.btn)
  7249.                     ENDIF
  7250.                     THIS.AddProp(M_CAPTION,THIS.addquotes(m.capname),m.btn)
  7251.             ENDCASE
  7252.             
  7253.  
  7254.             *- Add mode (Opaque,Trans), and other attributes peculiar to btnName
  7255.             IF m.btnName = "Option"
  7256.                 *-THIS.AddMode(L_NOCONVERT,0,a_scx2fld[A_FILLPAT],m.btn)      && always transparent
  7257.                 THIS.AddMode(L_CONVERT,a_scx2fld[A_MODE],a_scx2fld[A_FILLPAT],m.btn)
  7258.                 *- Also add value for specific button
  7259.                 IF THIS.iValue = i
  7260.                     THIS.AddProp(M_VALUE,1,m.btn)
  7261.                 ENDIF
  7262.             ELSE
  7263.                 THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]-1),a_scx2fld[A_FILLPAT],m.btn)
  7264.             ENDIF
  7265.  
  7266.  
  7267.             THIS.AddProp(M_HEIGHT,m.unithgt,m.btn)
  7268.             THIS.AddProp(M_WIDTH,m.unitwid,m.btn)
  7269.             
  7270.             IF m.lishoriz  &&horizontal buttons
  7271.                 THIS.AddProp(M_HPOS,m.st_left+;
  7272.                     ((m.hspc+m.unitwid)*(m.i-1)),m.btn)
  7273.                 THIS.AddProp(M_VPOS,m.st_top,m.btn)
  7274.             ELSE
  7275.                 THIS.AddProp(M_HPOS,m.st_left,m.btn)
  7276.                 THIS.AddProp(M_VPOS,m.st_top+;
  7277.                     ((m.vspc+m.unithgt)*(m.i-1)),m.btn)
  7278.             ENDIF
  7279.             
  7280.             IF ATC("T",THIS.picword1) # 0    && terminate read
  7281.                 THIS.AddProp(M_TERMINATEREAD,.T.,m.btn)
  7282.             ELSE
  7283.                 THIS.AddProp(M_TERMINATEREAD,.F.,m.btn)
  7284.             ENDIF
  7285.  
  7286.             *- add releaseerase
  7287.             THIS.AddProp(M_RELEASEERASE,C_FALSE,m.btn)
  7288.  
  7289.             THIS.AddProp(M_NAME,m.btn,m.btn)
  7290.  
  7291.         ENDFOR
  7292.     ENDPROC            && fp25ctrl:AddGroup
  7293.  
  7294.     *----------------------
  7295.     PROCEDURE AddBtn        && fp25ctrl
  7296.     *----------------------
  7297.         IF ATC("B",THIS.picword1) # 0    && pictures
  7298.             THIS.AddProp(M_FPICTURE,THIS.FullBMP(THIS.picword2))
  7299.             THIS.AddProp(M_CAPTION,[""])
  7300.         ELSE
  7301.             THIS.AddProp(M_CAPTION,THIS.addquotes(THIS.picword2))
  7302.         ENDIF
  7303.         
  7304.         IF ATC("T",THIS.picword1) # 0    && terminate read
  7305.             THIS.AddProp(M_TERMINATEREAD,.T.)
  7306.         ELSE
  7307.             THIS.AddProp(M_TERMINATEREAD,.F.)
  7308.         ENDIF
  7309.  
  7310.     ENDPROC    && AddBtn
  7311.     
  7312.     *----------------------
  7313.     PROCEDURE AddValue    && fp25ctrl
  7314.     *----------------------
  7315.         *- This routine sets Value property to DEFAULT 
  7316.         *- setting for a Textbox,Editbox or Spinner 
  7317.         *- control similar to GENDEFAULT in GENSCRN.
  7318.         
  7319.         PRIVATE ctempstr,cfillchar,cinitval
  7320.         
  7321.         m.cfillchar = a_scx2fld[A_FILLCHAR]
  7322.         m.cinitval = TRIM(a_scx2fld[A_INITIALVAL])
  7323.         
  7324.         IF EMPTY(m.cinitval) AND EMPTY(m.cfillchar)
  7325.                RETURN
  7326.         ENDIF
  7327.         
  7328.         IF EMPTY(m.cinitval)
  7329.             DO CASE
  7330.                 CASE m.cfillchar = "D"
  7331.                       m.ctempstr = {  /  /  }
  7332.                 CASE m.cfillchar = "C" OR fillchar = "M" OR fillchar = "G"
  7333.                     RETURN
  7334.                 CASE m.cfillchar = "L"
  7335.                     m.ctempstr = .F.
  7336.                 CASE m.cfillchar = "N"
  7337.                       m.ctempstr = 0
  7338.                 CASE m.cfillchar= "F"
  7339.                     m.ctempstr = 0.0
  7340.             ENDCASE
  7341.         ELSE
  7342.             *- this only occurs with a spinner
  7343.             m.ctempstr = m.cinitval
  7344.         ENDIF
  7345.         THIS.AddProp(M_VALUE,m.ctempstr)
  7346.     ENDPROC            && fp25ctrl:AddValue
  7347.  
  7348. ENDDEFINE        &&  fp25ctrl
  7349.  
  7350.  
  7351. ************************************
  7352. DEFINE CLASS fp25list AS fp25ctrl
  7353. ************************************
  7354.  
  7355.     *----------------------
  7356.     PROCEDURE AddCtrl    && fp25list    
  7357.     *----------------------
  7358.  
  7359.         THIS.AddProp(M_EXPR,THIS.addquotes(a_scx2fld[A_EXPR]))
  7360.  
  7361.         *- add style specific stuff
  7362.         DO CASE
  7363.             CASE a_scx2fld[A_STYLE] = 0        && array
  7364.                 THIS.AddMethods(M_RANGE2LO,a_scx2fld[A_RANGELO],a_scx2fld[A_LOTYPE],M_1STELEMENT)
  7365.                 THIS.AddMethods(M_RANGE2HI,a_scx2fld[A_RANGEHI],a_scx2fld[A_HITYPE],M_NUMELEMENTS)
  7366.                 THIS.AddProp(M_LSTYLE,5)
  7367.                 THIS.AddProp(M_VALUE,1)        && set a default value, just in case
  7368.             CASE a_scx2fld[A_STYLE] = 1        && popup
  7369.                 THIS.AddProp(M_LSTYLE,9)
  7370.                 THIS.AddProp(M_VALUE,1)        && set a default value, just in case
  7371.             CASE a_scx2fld[A_STYLE] = 2        && DBF structure
  7372.                 THIS.AddProp(M_LSTYLE,8)
  7373.                 THIS.AddProp(M_VALUE,[" "])    && set a default value, just in case
  7374.             CASE a_scx2fld[A_STYLE] = 3        && field
  7375.                 THIS.AddProp(M_LSTYLE,6)
  7376.                 THIS.AddProp(M_VALUE,[" "])    && set a default value, just in case
  7377.             CASE a_scx2fld[A_STYLE] = 4        && file skeleton
  7378.                 THIS.AddProp(M_LSTYLE,7)
  7379.                 THIS.AddProp(M_VALUE,[" "])    && set a default value, just in case
  7380.         ENDCASE
  7381.  
  7382.         IF ATC("T",THIS.picword1) # 0    && terminate read
  7383.             THIS.AddProp(M_TERMINATEREAD,.T.)
  7384.         ELSE
  7385.             THIS.AddProp(M_TERMINATEREAD,.F.)
  7386.         ENDIF
  7387.  
  7388.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7389.  
  7390.     ENDPROC
  7391.  
  7392.     *----------------------
  7393.     PROCEDURE AddPos    && fp25list
  7394.     *----------------------
  7395.         *- Lists need a ReadSize property, before top, left, height, width
  7396.         *- THIS.AddProp(M_READSIZE,.T.)
  7397.         THIS.fp3fudge = .2
  7398.         *- Add object positions in pixels (how FP3 stores it)
  7399.         *- VPOS,HPOS based on form font
  7400.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS] * (THIS.nDeffont1+THIS.nDeffont5))        
  7401.         THIS.AddProp(M_HPOS,(a_scx2fld[A_HPOS] - THIS.fp3fudge) * THIS.nDeffont6)
  7402.         
  7403.         *- HEIGHT,WIDTH based on object font
  7404.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6)
  7405.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7406.             (THIS.fp3font1+THIS.fp3font5) + 2)            && the extra 2 is for the border, which wasn't included in 2.6 listbox height
  7407.  
  7408.     ENDPROC
  7409.  
  7410.     *----------------------
  7411.     PROCEDURE AddColor    && fp25list
  7412.     *----------------------
  7413.         *- lists use different properties for colors
  7414.         *- Add colorstuff
  7415.         *- Add pen color
  7416.         PARAMETER m.btn
  7417.  
  7418.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  7419.  
  7420.         IF a_scx2fld[A_PENRED] # -1
  7421.  
  7422.             THIS.AddProp(M_ITEMFORECOLOR,ALLT(STR(a_scx2fld[A_PENRED]))+;
  7423.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  7424.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  7425.         ENDIF
  7426.         
  7427.         *- Add fill color
  7428.         IF a_scx2fld[A_FILLRED] = -1
  7429.         ELSE                
  7430.             THIS.AddProp(M_ITEMBACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  7431.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  7432.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  7433.             THIS.AddProp(M_DISITEMBACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  7434.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  7435.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  7436.         ENDIF
  7437.  
  7438.     ENDPROC
  7439.  
  7440. ENDDEFINE
  7441.  
  7442.  
  7443. ************************************
  7444. DEFINE CLASS fp25btn AS fp25ctrl
  7445. ************************************
  7446.  
  7447.     *----------------------
  7448.     PROCEDURE AddCtrl
  7449.     *----------------------
  7450.         THIS.AddBtn
  7451.         
  7452.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7453.  
  7454.     ENDPROC
  7455.  
  7456. ENDDEFINE
  7457.  
  7458.  
  7459. ************************************
  7460. DEFINE CLASS fp25cbox AS fp25ctrl
  7461. ************************************
  7462.  
  7463.     *----------------------
  7464.     PROCEDURE AddCtrl
  7465.     *----------------------
  7466.         THIS.AddBtn
  7467.         
  7468.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7469.  
  7470.         IF ATC("B",THIS.picword1) # 0    && pictures
  7471.             THIS.AddProp(M_STYLE,1)
  7472.         ELSE
  7473.             THIS.AddProp(M_STYLE,0)
  7474.         ENDIF
  7475.         
  7476.         THIS.AddProp(M_VALUE,a_scx2fld[A_INITIALNUM])
  7477.     ENDPROC
  7478.  
  7479. ENDDEFINE
  7480.  
  7481.  
  7482. ************************************
  7483. DEFINE CLASS fp25btngrp AS fp25ctrl
  7484. ************************************
  7485.     
  7486.     PROCEDURE AddPos
  7487.     ENDPROC
  7488.  
  7489.     PROCEDURE WriteName
  7490.     ENDPROC
  7491.     
  7492.     PROCEDURE AddCtrl
  7493.         THIS.AddGroup("Command")
  7494.     ENDPROC
  7495.  
  7496.     *----------------------
  7497.     PROCEDURE AddColor            && fp25btngrp
  7498.     *----------------------
  7499.         PARAMETER m.btn
  7500.  
  7501.         *- buttons are colorless things
  7502.  
  7503.         *- but they still need a colorsource
  7504.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  7505.  
  7506.     ENDPROC
  7507.  
  7508.  
  7509. ENDDEFINE
  7510.  
  7511.  
  7512. ***************************************
  7513. DEFINE CLASS fp25invgrp AS fp25ctrl
  7514. ***************************************
  7515.     
  7516.     PROCEDURE AddPos
  7517.     ENDPROC
  7518.  
  7519.     PROCEDURE WriteName
  7520.     ENDPROC
  7521.     
  7522.     PROCEDURE AddCtrl
  7523.         THIS.AddGroup("Command",.T.)
  7524.         THIS.AddProp(M_VALUE,0)                    && set the default value
  7525.     ENDPROC
  7526.  
  7527. ENDDEFINE
  7528.  
  7529.  
  7530. ***************************************
  7531. DEFINE CLASS fp25invbtn AS fp25ctrl
  7532. ***************************************
  7533.  
  7534.     *----------------------
  7535.     PROCEDURE AddCtrl
  7536.     *----------------------
  7537.         THIS.AddBtn
  7538.         
  7539.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7540.  
  7541.         THIS.AddProp(M_STYLE,1)
  7542.     ENDPROC
  7543.  
  7544. ENDDEFINE
  7545.  
  7546.  
  7547. ************************************
  7548. DEFINE CLASS fp25get AS fp25ctrl
  7549. ************************************
  7550.     *----------------------
  7551.     PROCEDURE AddMain        && fp25get
  7552.     *----------------------
  7553.  
  7554.         fp25ctrl::AddMain
  7555.  
  7556.         *- Add alignment
  7557.         DO CASE
  7558.             CASE ATC("B",THIS.picword1) # 0                && left - num type
  7559.                 THIS.AddProp(M_ALIGN,0)
  7560.             CASE ATC("J",THIS.picword1) # 0                && right - char type
  7561.                 THIS.AddProp(M_ALIGN,1)
  7562.             CASE ATC("I",THIS.picword1) # 0                && center - char type
  7563.                 THIS.AddProp(M_ALIGN,2)
  7564.             CASE INLIST(TYPE(a_scx2fld[A_EXPR]),"N")    && num, so make right just    
  7565.                 THIS.AddProp(M_ALIGN,1)
  7566.         ENDCASE
  7567.     
  7568.         IF !EMPTY(THIS.picword3)
  7569.             *- check for color, color scheme, size, etc.
  7570.         ENDIF        
  7571.  
  7572.     ENDPROC    && AddMain
  7573.  
  7574.     *----------------------
  7575.     PROCEDURE AddCtrl        && fp25get
  7576.     *----------------------
  7577.         THIS.AddFormat
  7578.         THIS.AddValue
  7579.         
  7580.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7581.  
  7582.         THIS.AddProp(M_MARGIN,0)    && new 3.0 prop
  7583.  
  7584.         THIS.AddMethods(M_RANGE2LO,a_scx2fld[A_RANGELO],a_scx2fld[A_LOTYPE])    && ,M_RANGELO)
  7585.         THIS.AddMethods(M_RANGE2HI,a_scx2fld[A_RANGEHI],a_scx2fld[A_HITYPE])    && ,M_RANGEHI)
  7586.         THIS.AddProp(M_PENPAT,IIF(THIS.formRef.GetBorder,1,0))
  7587.  
  7588.         *- check for any #ITSE expressions
  7589.  
  7590.         IF !EMPTY(THIS.picword3)
  7591.             *- additional checks
  7592.         ENDIF
  7593.     ENDPROC
  7594.     
  7595.     *----------------------
  7596.     PROCEDURE AddPos        && fp25get
  7597.     *----------------------
  7598.         *- Add object positions in pixels (how Taz stores it)
  7599.         *- FP2.5 added extra pixels for some reason
  7600.         *- VPOS = -1, HPOS = -2, WIDTH = 5,HEIGHT = 2
  7601.         *- VPOS,HPOS based on form font
  7602.         THIS.AddProp(M_VPOS, a_scx2fld[A_VPOS] * ;
  7603.             (THIS.nDeffont1 + THIS.nDeffont5) - 1)        
  7604.         THIS.AddProp(M_HPOS, a_scx2fld[A_HPOS] * THIS.nDeffont6 - 2)
  7605.         
  7606.         *- HEIGHT,WIDTH based on object font
  7607.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6 + 5)
  7608.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7609.                 (THIS.fp3font1+THIS.fp3font5) + 2)
  7610.     ENDPROC
  7611.  
  7612. ENDDEFINE && fp25get
  7613.  
  7614.  
  7615. ************************************
  7616. DEFINE CLASS fp25text AS fp25ctrl
  7617. ************************************
  7618.     *- superclass for textboxes and says
  7619.  
  7620.     *----------------------
  7621.     PROCEDURE AddMain        && fp25text
  7622.     *----------------------
  7623.  
  7624.         fp25ctrl::AddMain
  7625.  
  7626.         *- Add alignment
  7627.         DO CASE
  7628.             CASE ATC("B",THIS.picword1) # 0                && left - num type
  7629.                 THIS.AddProp(M_ALIGN,0)
  7630.             CASE ATC("J",THIS.picword1) # 0                && right - char type
  7631.                 THIS.AddProp(M_ALIGN,1)
  7632.             CASE ATC("I",THIS.picword1) # 0                && center - char type
  7633.                 THIS.AddProp(M_ALIGN,2)
  7634.             CASE INLIST(TYPE(a_scx2fld[A_EXPR]),"N")    && num, so make right just    
  7635.                 THIS.AddProp(M_ALIGN,1)
  7636.         ENDCASE
  7637.     
  7638.         IF !EMPTY(THIS.picword3)
  7639.             *- check for color, color scheme, size, etc.
  7640.         ENDIF        
  7641.  
  7642.     ENDPROC    && AddMain
  7643.  
  7644.     *----------------------
  7645.     PROCEDURE AddCtrl        && fp25text
  7646.     *----------------------
  7647.         THIS.AddFormat
  7648.         THIS.AddValue
  7649.  
  7650.         THIS.AddProp(M_MARGIN,0)    && new 3.0 prop
  7651.  
  7652.     ENDPROC
  7653.  
  7654.     *----------------------
  7655.     PROCEDURE AddPos        && fp25text
  7656.     *----------------------
  7657.         *- Add object positions in pixels (how Taz stores it)
  7658.         *- FP2.5 added extra pixels for some reason
  7659.         *- VPOS = -1, HPOS = -2, WIDTH = 2,HEIGHT = 2
  7660.         *- VPOS,HPOS based on form font
  7661.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS] * ;
  7662.             (THIS.nDeffont1 + THIS.nDeffont5)-1)        
  7663.         THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS] * THIS.nDeffont6-2)
  7664.         
  7665.         *- HEIGHT,WIDTH based on object font
  7666.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6+2)
  7667.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7668.                 (THIS.fp3font1 + THIS.fp3font5) + 2)
  7669.     ENDPROC
  7670.  
  7671.  
  7672. ENDDEFINE    && fp25text
  7673.  
  7674. ************************************
  7675. DEFINE CLASS fp25edit AS fp25text
  7676. ************************************
  7677.  
  7678.     *----------------------
  7679.     PROCEDURE AddCtrl
  7680.     *----------------------
  7681.         fp25text::AddCtrl
  7682.  
  7683.         IF !a_scx2fld[A_SCROLLBAR]
  7684.             THIS.AddProp(M_SCROLLBAR,0)
  7685.         ENDIF
  7686.         
  7687.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7688.  
  7689.         THIS.AddProp(M_TAB,a_scx2fld[A_TAB])
  7690.         *-THIS.AddProp(M_MAXLEN,a_scx2fld[A_INITIALNUM])
  7691.         *-THIS.AddProp(M_PENPAT,IIF(THIS.formRef.GetBorder,1,0))
  7692.         *- check if person has .T. NOMODIFY kludge
  7693.         IF  ATC(" NOMO",THIS.fp3method) # 0 OR ;
  7694.             ATC(" NOMO",THIS.picword3) # 0
  7695.             *- comment out NOMODIFY in methods. Leave alone in picture clause
  7696.             THIS.fp3method = STRTRAN(THIS.fp3method," NOMO"," &" + "& NOMO")
  7697.             THIS.AddProp(M_READONLY,C_TRUE)
  7698.         ENDIF
  7699.     ENDPROC
  7700.  
  7701.     *----------------------
  7702.     PROCEDURE AddValue    && fp25edit
  7703.     *----------------------
  7704.         *- This routine sets Value property to DEFAULT 
  7705.         *- Editbox. Overrides the fp25ctrl:AddValue
  7706.         *- 2.6 allowed a numeric type for the editbox, which is not allowed in 3.0
  7707.         
  7708.         RETURN
  7709.         
  7710.     ENDPROC            && fp25edit:AddValue
  7711.  
  7712. ENDDEFINE && fp25edit
  7713.  
  7714. ************************************
  7715. DEFINE CLASS fp25say AS fp25text
  7716. ************************************
  7717.     *- a read-only descendent of fp25text
  7718.  
  7719.     *----------------------
  7720.     PROCEDURE AddCtrl
  7721.     *----------------------
  7722.         fp25text::AddCtrl
  7723.  
  7724.         THIS.AddProp(M_STYLE,1)            && should set behavior like 2.6 SAY
  7725.         THIS.AddProp(M_READONLY,.T.)    && can't change it
  7726.         THIS.AddProp(M_TABSTOP,.F.)        && can't tab into it
  7727.         *-THIS.AddProp(M_ENABLED,.F.)        && disabled
  7728.  
  7729.         THIS.AddProp(M_PENPAT,0)        && no border
  7730.  
  7731.     ENDPROC
  7732.  
  7733.     *----------------------
  7734.     FUNCTION GetNewName    && fp25say
  7735.     *----------------------
  7736.         *- use as much of EXPR as possible
  7737.         PARAMETER newobj
  7738.         LOCAL cName
  7739.  
  7740.         m.cName = ALLT(StripQuote(ALLT(a_scx2fld[A_EXPR])))
  7741.         IF !EMPTY(m.cName)
  7742.             m.cName = LEFT(m.cName,MIN(LEN(m.cName),8))
  7743.             m.newobj = THIS.GetVarPrefix(newobj) + ALLT(PROPER(GoodName(m.cName)))
  7744.         ELSE
  7745.             m.newobj = THIS.GetVarPrefix(newobj) + PROPER(m.newobj)
  7746.         ENDIF
  7747.         THIS.formRef.nObjCount = THIS.formRef.nObjCount + 1
  7748.         RETURN ALLTRIM(m.newobj) + ALLTRIM(STR(THIS.formRef.nObjCount))
  7749.     ENDFUNC        &&  GetNewName
  7750.  
  7751.     *----------------------
  7752.     PROCEDURE AddColor    && fp25say
  7753.     *----------------------
  7754.         *- Add colorstuff
  7755.         *- Add pen color
  7756.         PARAMETER m.btn
  7757.  
  7758.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE)
  7759.  
  7760.         *- since SAYs are handled as disabled textboxes, make the disabled colors and
  7761.         *- the enabled colors the same as the 2.6 colors
  7762.         IF a_scx2fld[A_PENRED] = -1
  7763.         ELSE
  7764.             THIS.AddProp(M_DISFORECOLOR,ALLT(STR(a_scx2fld[A_PENRED]))+;
  7765.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  7766.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  7767.             THIS.AddProp(M_PEN,ALLT(STR(a_scx2fld[A_PENRED]))+;
  7768.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  7769.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  7770.         ENDIF
  7771.  
  7772.         IF a_scx2fld[A_FILLRED] = -1
  7773.         ELSE
  7774.             THIS.AddProp(M_BACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  7775.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  7776.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  7777.         ENDIF
  7778.  
  7779.     ENDPROC
  7780.  
  7781.     *----------------------
  7782.     PROCEDURE AddValue        && fp25say
  7783.     *----------------------
  7784.         LOCAL m.cExpr, m.cParent
  7785.  
  7786.         DO CASE
  7787.             CASE !EMPTY(a_scx2fld[A_EXPR]) AND ;
  7788.                 AT(LEFT(a_scx2fld[A_EXPR],1),["[']) # 0
  7789.                 m.cExpr = a_scx2fld[A_EXPR]
  7790.             CASE !INLIST(TYPE(a_scx2fld[A_EXPR]),"C","M","U","N")
  7791.                 m.cExpr = "(" + THIS.Conv2Str(a_scx2fld[A_EXPR]) + ")"
  7792.             OTHERWISE
  7793.                 m.cExpr = a_scx2fld[A_EXPR]
  7794.         ENDCASE
  7795.  
  7796.         THIS.AddProp(M_VALUE,m.cExpr)
  7797.  
  7798.         IF a_scx2fld[A_REFRESH]
  7799.             *- add to READSHOW method of formset
  7800.             IF THIS.FormRef.lIndirectWinName
  7801.                 *- need to slip in ref to the new, changed form name
  7802.                 m.cParent = "THISFORMSET." + CHR(38) + THIS.FormRef.cIndirectWinName + ".." + ;
  7803.                     SUBS(THIS.fp3parent,AT(".",THIS.fp3parent,2) + 1)
  7804.             ELSE
  7805.                 m.cParent = "THISFORMSET." + ;
  7806.                     SUBS(THIS.fp3parent,AT(".",THIS.fp3parent,1) + 1)
  7807.             ENDIF
  7808.  
  7809.             THIS.formRef.cReadShow = THIS.formRef.cReadShow + ;
  7810.                 m.cParent + "." + THIS.fp3name + ".Value = " + ;
  7811.                 m.cExpr + C_CRLF
  7812.         ENDIF
  7813.  
  7814.     ENDPROC
  7815.  
  7816. ENDDEFINE && fp25say
  7817.  
  7818. ************************************
  7819. DEFINE CLASS fp25option AS fp25ctrl
  7820. ************************************
  7821. *- this class allows both radios and popups to inherit this AddValue
  7822.  
  7823.     iValue = 0                && need to remember the value, so the individual option button value can be set
  7824.  
  7825.     *----------------------
  7826.     PROCEDURE AddValue
  7827.     *----------------------
  7828.         *- This routine sets Value property to DEFAULT 
  7829.         *- setting for a popup/combobox
  7830.         *- control similar to GENDEFAULT in GENSCRN.
  7831.         
  7832.         LOCAL ctempval,cinitval,ctemp2
  7833.         
  7834.         m.cinitval = ALLT(a_scx2fld[A_INITIALVAL])
  7835.         m.ctemp2 = SUBS(m.cinitval,2,LEN(m.cinitval) - 2)
  7836.         
  7837.         DO CASE
  7838.             CASE EMPTY(m.cinitval)
  7839.                 m.ctempval = 1
  7840.             CASE ALLT(STR(VAL(m.cinitval))) = m.cinitval
  7841.                 *- is a number
  7842.                 m.ctempval = VAL(m.cinitval)
  7843.             CASE THIS.fp25OC = 3
  7844.                 *- from array -- set to 1
  7845.                 m.ctempval = 1
  7846.             OTHERWISE
  7847.                 *- text -- do without the quotes
  7848.                 m.ctempval = m.cinitval
  7849.         ENDCASE
  7850.         
  7851.         THIS.AddProp(M_VALUE,m.ctempval)
  7852.         THIS.iValue = m.ctempval
  7853.  
  7854.     ENDPROC    && AddValue
  7855.  
  7856. ENDDEFINE    && fp25option
  7857.  
  7858.  
  7859. ************************************
  7860. DEFINE CLASS fp25radio AS fp25option
  7861. ************************************
  7862.     
  7863.     PROCEDURE AddPos
  7864.     ENDPROC
  7865.  
  7866.     PROCEDURE WriteName
  7867.     ENDPROC
  7868.  
  7869.     *----------------------
  7870.     PROCEDURE AddMain        && fp25radio
  7871.     *----------------------
  7872.  
  7873.         fp25option::AddMain
  7874.  
  7875.         THIS.AddGroup("Option",.F.,.T.)        && Add button groups AFTER ControlSource is set
  7876.  
  7877.     ENDPROC
  7878.  
  7879.  
  7880.     *----------------------
  7881.     PROCEDURE AddCtrl        && fp25radio
  7882.     *----------------------
  7883.         *- set initial value
  7884.         
  7885.         *- set group Enabled property to .T., and individual buttons to whatever
  7886.         THIS.AddProp(M_ENABLED,.T.)
  7887.  
  7888.         IF ATC("B",THIS.picword1) = 0    && text radios
  7889.             THIS.AddProp(M_VALUE,a_scx2fld[A_INITIALNUM])
  7890.             THIS.iValue = a_scx2fld[A_INITIALNUM]
  7891.         ENDIF
  7892.  
  7893.     ENDPROC
  7894.  
  7895.     *----------------------
  7896.     PROCEDURE AddMode        && fp25radio
  7897.     *----------------------
  7898.         *- add the mode (opaque/transparent)
  7899.         *- if mode has to be converted, check for opaque w/ no fill pat
  7900.         PARAMETER lConvert,nMode,nFillPat,m.btn
  7901.  
  7902.         IF a_scx2fld[A_FILLRED] = -1
  7903.             *- force transparent mode if auto color
  7904.             THIS.AddProp(M_MODE,N_TRANSPARENT,m.btn)
  7905.         ELSE
  7906.             fp25option::AddMode(lConvert,nMode,nFillPat,m.btn)
  7907.         ENDIF
  7908.     ENDPROC
  7909.  
  7910. ENDDEFINE    && fp25radio
  7911.  
  7912.  
  7913. ************************************
  7914. DEFINE CLASS fp25popup AS fp25option
  7915. ************************************
  7916.  
  7917.     *----------------------
  7918.     PROCEDURE AddCtrl
  7919.     *----------------------
  7920.         LOCAL cListSource
  7921.         
  7922.         THIS.AddProp(M_STYLE,2)
  7923.         
  7924.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7925.  
  7926.         *- combo box items must appear in the following order:
  7927.         *- rowSource, rowSourceType, value, dataSource
  7928.         IF THIS.fp25OC = 1  && list popups
  7929.             THIS.AddProp(M_1STELEMENT,a_scx2fld[A_INITIALNUM])
  7930.             m.cListSource = STRTRAN(STRTRAN(THIS.picword2,",","."),";",",")    && FP 3.0 delimits popups with commas,
  7931.             THIS.AddProp(M_EXPR,THIS.addquotes(m.cListSource))                && so attempt to preserve commas that are there
  7932.             THIS.AddProp(M_LSTYLE,1)                                        && Style = VALUE (1)
  7933.         ELSE                  && array popups
  7934.             THIS.AddMethods(M_RANGE2LO,a_scx2fld[A_RANGELO],a_scx2fld[A_LOTYPE],M_1STELEMENT)
  7935.             THIS.AddMethods(M_RANGE2HI,a_scx2fld[A_RANGEHI],a_scx2fld[A_HITYPE],M_NUMELEMENTS)
  7936.             THIS.AddProp(M_LSTYLE,5)
  7937.             THIS.AddProp(M_EXPR,THIS.addquotes(a_scx2fld[A_EXPR]))
  7938.         ENDIF
  7939.         
  7940.         THIS.AddValue
  7941.  
  7942.     ENDPROC
  7943.  
  7944. ENDDEFINE    && fp25popup
  7945.  
  7946. ************************************
  7947. DEFINE CLASS fp25spin AS fp25ctrl
  7948. ************************************
  7949.  
  7950.     PROCEDURE AddCtrl
  7951.         THIS.AddFormat
  7952.         THIS.AddValue
  7953.         
  7954.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7955.  
  7956.         THIS.AddProp(M_MARGIN,0)    && new 3.0 prop
  7957.  
  7958.         THIS.AddProp(M_ALIGN,1)        && force right align
  7959.  
  7960.         *- only add spinner high and low values if they have been set
  7961.         IF !EMPTY(a_scx2fld[A_TAG])
  7962.             THIS.AddProp(M_SPINLO,a_scx2fld[A_TAG])
  7963.         ENDIF
  7964.         IF !EMPTY(a_scx2fld[A_TAG2])
  7965.             THIS.AddProp(M_SPINHI,a_scx2fld[A_TAG2])
  7966.         ENDIF
  7967.  
  7968.         THIS.AddMethods(M_RANGE2LO,a_scx2fld[A_RANGELO],a_scx2fld[A_LOTYPE],M_KEYLO)
  7969.         THIS.AddMethods(M_RANGE2HI,a_scx2fld[A_RANGEHI],a_scx2fld[A_HITYPE],M_KEYHI)
  7970.     ENDPROC
  7971.  
  7972.     *----------------------
  7973.     PROCEDURE AddPos        && fp25spin
  7974.     *----------------------
  7975.         *- Add object positions in pixels (how FP3 stores it)
  7976.         *- VPOS,HPOS based on form font
  7977.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS]*(THIS.nDeffont1+THIS.nDeffont5))        
  7978.         THIS.AddProp(M_HPOS,(a_scx2fld[A_HPOS] - .6) * THIS.nDeffont6)
  7979.         
  7980.         *- HEIGHT,WIDTH based on object font
  7981.         *- Spinner needs extra 19 pixels width for spinner control
  7982.         *-               extra  6 pixels height
  7983.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6 + 19)
  7984.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7985.                 (THIS.fp3font1+THIS.fp3font5) + 7)
  7986.     ENDPROC
  7987.  
  7988.     *----------------------
  7989.     PROCEDURE AddValue    && fp25spin
  7990.     *----------------------
  7991.         *- This routine sets Value property to DEFAULT 
  7992.         
  7993.         LOCAL cinitval
  7994.  
  7995.         IF !EMPTY(a_scx2fld[A_INITIALVAL])
  7996.             IF INT(VAL(a_scx2fld[A_INITIALVAL])) <> VAL(a_scx2fld[A_INITIALVAL])
  7997.                 cinitval = ForceDec(a_scx2fld[A_INITIALVAL],;
  7998.                     LEN(a_scx2fld[A_INITIALVAL]) - AT('.',a_scx2fld[A_INITIALVAL]))
  7999.             ELSE
  8000.                 cinitval = ForceDec(a_scx2fld[A_INITIALVAL],3)
  8001.             ENDIF
  8002.         ELSE
  8003.             cinitval = "1.000"
  8004.         ENDIF
  8005.                 
  8006.         THIS.AddProp(M_SPININC,cinitval)
  8007.  
  8008.         DO CASE
  8009.             CASE !EMPTY(TAG)
  8010.                 m.cinitval = ForceDec(TRIM(a_scx2fld[A_TAG]),3)
  8011.                 THIS.AddProp(M_VALUE,m.cinitval)
  8012.             CASE !EMPTY(tag2)
  8013.                 m.cinitval = ForceDec(TRIM(a_scx2fld[A_TAG2]),3)
  8014.                 THIS.AddProp(M_VALUE,m.cinitval)
  8015.             CASE EMPTY(TRIM(initialval))
  8016.                 m.cinitval = "1"
  8017.                 THIS.AddProp(M_VALUE,m.cinitval)
  8018.             OTHERWISE
  8019.                fp25ctrl::AddValue
  8020.         ENDCASE
  8021.  
  8022.            RETURN
  8023.         
  8024. ENDDEFINE
  8025.  
  8026.  
  8027. ************************************
  8028. DEFINE CLASS fp25lbl AS fp25obj
  8029. ************************************
  8030. *- Text objects
  8031.     
  8032.     *----------------------
  8033.     PROCEDURE AddMain        && fp25lbl
  8034.     *----------------------
  8035.  
  8036.         *- Add label specific properties
  8037.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8038.  
  8039.         *- Get parts of Picture clause for use below
  8040.         THIS.GetPicPart(a_scx2fld[A_PICTURE])
  8041.  
  8042.         IF THIS.fp25OT = 15    && @..SAY
  8043.             DO CASE
  8044.                 CASE !EMPTY(a_scx2fld[A_EXPR]) AND ;
  8045.                     AT(LEFT(a_scx2fld[A_EXPR],1),["[']) # 0
  8046.                     THIS.AddProp(M_CAPTION,a_scx2fld[A_EXPR])
  8047.                 CASE !INLIST(TYPE(a_scx2fld[A_EXPR]),"C","M","U")
  8048.                     THIS.AddProp(M_CAPTION,THIS.Conv2Str(a_scx2fld[A_EXPR]))
  8049.                 OTHERWISE
  8050.                     THIS.AddProp(M_CAPTION,a_scx2fld[A_EXPR])
  8051.             ENDCASE
  8052.             
  8053.             THIS.picword2 = ""
  8054.             THIS.AddFormat
  8055.         ELSE
  8056.             THIS.AddProp(M_CAPTION,STRTRAN(a_scx2fld[A_EXPR],CHR(13),'" + CHR(13) + "'))
  8057.         ENDIF
  8058.  
  8059.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE)
  8060.  
  8061.         *- Add mode (Opaque,Trans)
  8062.         THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),1)    && labels have no fill
  8063.  
  8064.         *- Add alignment
  8065.         DO CASE
  8066.             CASE ATC("B",THIS.picword1) # 0    && left - num type
  8067.                 THIS.AddProp(M_ALIGN,0)
  8068.             CASE ATC("J",THIS.picword1) # 0    && right - char type
  8069.                 THIS.AddProp(M_ALIGN,1)
  8070.             CASE ATC("I",THIS.picword1) # 0    && center - char type
  8071.                 THIS.AddProp(M_ALIGN,2)
  8072.         ENDCASE
  8073.     
  8074.         IF !EMPTY(THIS.picword3)
  8075.             *- check for color, color scheme, size, etc.
  8076.         ENDIF        
  8077.  
  8078.         *- add releaseerase
  8079.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  8080.  
  8081.     ENDPROC    && AddMain
  8082.  
  8083.     *----------------------
  8084.     FUNCTION GetNewName    && fp25lbl
  8085.     *----------------------
  8086.         *- use as much of EXPR as possible
  8087.         PARAMETER newobj
  8088.         LOCAL cName
  8089.  
  8090.         m.cName = ALLT(StripQuote(ALLT(a_scx2fld[A_EXPR])))
  8091.         IF !EMPTY(m.cName)
  8092.             m.cName = LEFT(m.cName,MIN(LEN(m.cName),8))
  8093.             m.newobj = THIS.GetVarPrefix(m.newobj) + PROPER(GoodName(m.cName))
  8094.         ELSE
  8095.             m.newobj = THIS.GetVarPrefix(m.newobj) + PROPER(m.newobj)
  8096.         ENDIF
  8097.         THIS.formRef.nObjCount = THIS.formRef.nObjCount + 1
  8098.         RETURN ALLTRIM(m.newobj) + ALLTRIM(STR(THIS.formRef.nObjCount))
  8099.     ENDFUNC        &&  GetNewName
  8100.  
  8101.  
  8102. ENDDEFINE && fp25lbl
  8103.  
  8104.  
  8105. ************************************
  8106. DEFINE CLASS fp25shape AS fp25obj
  8107. ************************************
  8108.  
  8109.     *----------------------
  8110.     PROCEDURE AddBasic        && fp25shape
  8111.     *----------------------
  8112.         fp25obj::AddBasic
  8113.         THIS.fp3id = SYS(2015)        && we'll sort on this field later
  8114.     ENDPROC
  8115.  
  8116.  
  8117.     *- support 3-d from FoxMac 2.6 (12/5/95 jd)
  8118.     *----------------------
  8119.     PROCEDURE AddFX        && fp25shape
  8120.     *----------------------
  8121.         *- Add Special Effects
  8122.         PARAMETER btn
  8123.         IF a_scx2fld[A_PLATFORM] = C_MAC AND a_scx2fld[A_PENPAT] == 100 AND a_scx2fld[A_PENSIZE] == 2
  8124.             a_scx2fld[A_PENSIZE] = 1        && change this so new crame looks right
  8125.             THIS.AddProp(M_SPECIAL,N_3D)
  8126.         ELSE
  8127.             THIS.AddProp(M_SPECIAL,N_PLAIN)
  8128.         ENDIF
  8129.     ENDPROC
  8130.  
  8131.     *----------------------
  8132.     PROCEDURE AddMain        && fp25shape
  8133.     *----------------------
  8134.  
  8135.         LOCAL m.nFillPat
  8136.  
  8137.         *- Now add shape specific properties
  8138.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8139.         
  8140.         *- add 3-d if necessary -- do this right away, because it might
  8141.         *- change the PENSIZE value
  8142.         THIS.AddFx
  8143.  
  8144.         IF THIS.fp25OT = 7        && normal boxes
  8145.             DO CASE
  8146.                 CASE a_scx2fld[A_FILLPAT] = 0
  8147.                     m.nFillPat = 1
  8148.                 CASE a_scx2fld[A_FILLPAT] = 1
  8149.                     m.nFillPat = 0
  8150.                 CASE a_scx2fld[A_FILLPAT] = 4
  8151.                     m.nFillPat = 5
  8152.                 CASE a_scx2fld[A_FILLPAT] = 5
  8153.                     m.nFillPat = 4
  8154.                 OTHERWISE
  8155.                     m.nFillPat = a_scx2fld[A_FILLPAT]
  8156.             ENDCASE
  8157.  
  8158.             THIS.AddProp(M_FILLPAT,m.nFillPat)
  8159.             IF m.nFillPat = 1                && FillStyle 1 = transparent/none, 0 = opaque/solid
  8160.                 *- If FillPat is transparent, also set BackStyle to transparent
  8161.                 THIS.AddProp(M_MODE,0)        && BackStyle 0 = transparent/none, 1 = opaque/solid
  8162.             ELSE
  8163.                 *- Add mode (Opaque,Trans)
  8164.                 THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),a_scx2fld[A_FILLPAT])
  8165.             ENDIF
  8166.         ELSE
  8167.                 *- Add mode (Opaque,Trans)
  8168.                 THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),a_scx2fld[A_FILLPAT])
  8169.         ENDIF        
  8170.  
  8171.         *- Add rounded rectangle stuff
  8172.         IF    a_scx2fld[A_STYLE] >= 12
  8173.             *THIS.AddProp(M_SHAPE,4)
  8174.             THIS.AddProp(M_CURVE,a_scx2fld[A_STYLE])
  8175.         ENDIF
  8176.  
  8177.         *- Add pen width
  8178.         THIS.AddProp(M_PENSIZE,MAX(a_scx2fld[A_PENSIZE],1))
  8179.         
  8180.         *- Add pen pattern
  8181.         DO CASE
  8182.             CASE a_scx2fld[A_PENPAT] = 8    && solid
  8183.                 *- default of 8 in 2.6/1 in VFP, so no need to add
  8184.             CASE a_scx2fld[A_PENPAT] = 1    && dotted
  8185.                 THIS.AddProp(M_PENPAT,3)            
  8186.             CASE a_scx2fld[A_PENPAT] = 2    && dashed
  8187.                 THIS.AddProp(M_PENPAT,2)            
  8188.             CASE a_scx2fld[A_PENPAT] = 3    && dash dot
  8189.                 THIS.AddProp(M_PENPAT,4)            
  8190.             CASE a_scx2fld[A_PENPAT] = 4    && dash dot dot
  8191.                 THIS.AddProp(M_PENPAT,5)        
  8192.             CASE a_scx2fld[A_PENPAT] = 0    && "none"
  8193.                 THIS.AddProp(M_PENPAT,0)
  8194.         ENDCASE
  8195.  
  8196.         *- add ReleaseErase
  8197.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  8198.         
  8199.     ENDPROC
  8200.  
  8201.     *----------------------
  8202.     PROCEDURE AddFont
  8203.     *----------------------
  8204.     ENDPROC
  8205.     
  8206.     *----------------------
  8207.     PROCEDURE AddPos        && fp25shape
  8208.     *----------------------
  8209.         *- VPOS,HPOS based on form font
  8210.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))        
  8211.         THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS]*THIS.formRef.nDeffont6)
  8212.         DO CASE
  8213.             CASE THIS.fp25OT = 6        &&lines
  8214.                 IF a_scx2fld[A_STYLE] = 0 && vertical line
  8215.                     THIS.AddProp(M_WIDTH,0)
  8216.                     THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))
  8217.                 ELSE
  8218.                     THIS.AddProp(M_HEIGHT,0)
  8219.                     THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH]*THIS.formRef.nDeffont6)
  8220.                 ENDIF
  8221.             CASE THIS.fp25OT = 7        &&boxes
  8222.                 THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))
  8223.                 THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH]*THIS.formRef.nDeffont6)
  8224.         ENDCASE
  8225.     ENDPROC
  8226.  
  8227.     *----------------------
  8228.     PROCEDURE AddColor        && fp25shape
  8229.     *----------------------
  8230.         *- Add colorstuff
  8231.         *- Add pen color
  8232.         PARAMETER m.btn
  8233.  
  8234.         LOCAL lColorSource
  8235.  
  8236.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  8237.  
  8238.         IF a_scx2fld[A_PENRED] # -1
  8239.             THIS.AddProp(M_BORDERCOLOR,ALLT(STR(a_scx2fld[A_PENRED]))+;
  8240.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  8241.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  8242.         ENDIF
  8243.         
  8244.         *- Add fill color
  8245.         IF a_scx2fld[A_FILLRED] = -1
  8246.             RETURN
  8247.         ENDIF
  8248.                 
  8249.         THIS.AddProp(M_FILLCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  8250.             ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  8251.             ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  8252.         THIS.AddProp(M_BACKCOLOR,"255,255,255")
  8253.  
  8254.         *- set disabled color to be the same as the enabled color
  8255.         THIS.AddProp(M_DISFORECOLOR,ALLT(STR(a_scx2fld[A_PENRED])) + ;
  8256.             ","+ALLT(STR(a_scx2fld[A_PENGREEN])) + ;
  8257.             ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  8258.  
  8259.     ENDPROC
  8260.     
  8261. ENDDEFINE && fp25shape 
  8262.  
  8263. ************************************
  8264. DEFINE CLASS fp25line AS fp25shape
  8265. ************************************
  8266.     *- override AddColor
  8267.     *----------------------
  8268.     PROCEDURE AddColor
  8269.     *----------------------
  8270.         *- Add colorstuff
  8271.         *- Add pen color
  8272.         PARAMETER m.btn
  8273.  
  8274.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  8275.  
  8276.         IF a_scx2fld[A_PENRED] # -1
  8277.             THIS.AddProp(M_BORDERCOLOR,ALLT(STR(a_scx2fld[A_PENRED]))+;
  8278.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  8279.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  8280.         ENDIF
  8281.         
  8282.         *- Add fill color
  8283.         IF a_scx2fld[A_FILLRED] = -1
  8284.             RETURN
  8285.         ENDIF
  8286.                 
  8287.         THIS.AddProp(M_BACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  8288.             ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  8289.             ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  8290.  
  8291.     ENDPROC
  8292.  
  8293. ENDDEFINE && fp25line 
  8294.  
  8295. ************************************
  8296. DEFINE CLASS fp25pict AS fp25obj
  8297. ************************************
  8298.  
  8299.     *----------------------
  8300.     PROCEDURE AddBasic        && fp25pict
  8301.     *----------------------
  8302.         fp25obj::AddBasic
  8303.         THIS.fp3id = SYS(2015)        && we'll sort on this field later
  8304.     ENDPROC
  8305.  
  8306.     *----------------------
  8307.     PROCEDURE AddMain        && fp25pict
  8308.     *----------------------
  8309.     
  8310.         *- Now add form properties
  8311.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8312.         
  8313.         *- Add picture for BMP file
  8314.         IF a_scx2fld[A_STYLE] = 0
  8315.             *- source of picture is a file, stored in PICTURE field
  8316.             THIS.AddProp(M_FPICTURE,THIS.FullBMP(EVAL(a_scx2fld[A_PICTURE])))
  8317.         ELSE
  8318.             IF (" BITMAP" $ UPPER(a_scx2fld[A_NAME]))
  8319.             *-IF    ("\" $ ALLT(a_scx2fld[A_NAME])) OR ;
  8320.                 ("." $ ALLT(a_scx2fld[A_NAME])) OR ;
  8321.                 (":" $ ALLT(a_scx2fld[A_NAME])) OR ;
  8322.                 ('"' $ ALLT(a_scx2fld[A_NAME])) OR ;
  8323.                 (" " $ ALLT(a_scx2fld[A_NAME]))
  8324.                 *- assume is filename of form <filename><space>BITMAP
  8325.                 THIS.AddProp(M_FPICTURE,"(" + LEFT(ALLT(a_scx2fld[A_NAME]), AT(" ",ALLT(a_scx2fld[A_NAME])) - 1) + ")")
  8326.             ELSE
  8327.                 THIS.AddProp(M_FPICTURE,"(" + THIS.GetNewName(THIS.fp3class) + ")")
  8328.             ENDIF
  8329.         ENDIF
  8330.  
  8331.         *- Add mode (Opaque,Trans)
  8332.         THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),a_scx2fld[A_FILLPAT])
  8333.  
  8334.         *- add ReleaseErase
  8335.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  8336.                 
  8337.     ENDPROC
  8338.  
  8339.     *----------------------
  8340.     PROCEDURE AddPos        && fp25pict
  8341.     *----------------------
  8342.         *- Add stretch mode before height, width, etc.
  8343.         THIS.AddProp(M_STRETCH,a_scx2fld[A_BORDER])
  8344.  
  8345.         *- VPOS,HPOS based on form font
  8346.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))        
  8347.         THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS]*THIS.formRef.nDeffont6)
  8348.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))
  8349.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH]*THIS.formRef.nDeffont6)
  8350.     ENDPROC    
  8351.     
  8352.     *----------------------
  8353.     PROCEDURE AddFont
  8354.     *----------------------
  8355.     ENDPROC
  8356.     
  8357.     PROCEDURE AddColor
  8358.         PARAMETER m.btn
  8359.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  8360.     ENDPROC
  8361.  
  8362.  
  8363. ENDDEFINE && fp25pict
  8364.  
  8365. ************************************
  8366. DEFINE CLASS fp25ole AS fp25pict
  8367. ************************************
  8368.  
  8369.     *----------------------
  8370.     PROCEDURE AddMain        && fp25ole
  8371.     *----------------------
  8372.     
  8373.         *- Now add form properties
  8374.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8375.         
  8376.         *- Add mode (Opaque,Trans)
  8377.         THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),a_scx2fld[A_FILLPAT])
  8378.  
  8379.         *- add ReleaseErase
  8380.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  8381.  
  8382.         *- Add datasource (general field name)
  8383.         THIS.AddProp(M_DATASOURCE,ALLTRIM(a_scx2fld[A_NAME]))
  8384.  
  8385.         *- other specific actions for OLEBoundControls
  8386.         THIS.AddCtrl
  8387.  
  8388.     ENDPROC
  8389.     
  8390.     *----------------------
  8391.     PROCEDURE AddCtrl        && fp25ole
  8392.     *----------------------
  8393.         
  8394.         THIS.AddProp(M_ENABLED,.F.)
  8395.         THIS.AddProp(M_GROW,.F.)
  8396.         THIS.AddProp(M_AUTOACTIVATE,0)        && manual
  8397.  
  8398.     ENDPROC
  8399.  
  8400.  
  8401. ENDDEFINE    && fp25ole
  8402.  
  8403. ************************************
  8404. DEFINE CLASS fp25form AS fp25obj
  8405. ************************************
  8406.     *- Subclass for handling the form
  8407.  
  8408.     cWinName = ""
  8409.  
  8410.     *----------------------
  8411.     PROCEDURE Init        && fp25form
  8412.     *----------------------
  8413.         PARAMETER parm1,parm2
  8414.         fp25obj::Init(parm1,parm2)
  8415.         THIS.iColorSource = I_WINCPCOLORSOURCE        && use "5" (Windows CP) for colorsource for forms
  8416.     ENDPROC
  8417.     
  8418.     *----------------------
  8419.     PROCEDURE AddBasic        && fp25form
  8420.     *----------------------
  8421.         fp25obj::AddBasic
  8422.         THIS.fp3id = SYS(2015)        && we'll sort on this field later
  8423.     ENDPROC
  8424.  
  8425.     *----------------------------------
  8426.     PROCEDURE AddMain        && fp25form
  8427.     *----------------------------------
  8428.     
  8429.         PRIVATE m.tmpstr,m.tmpcnt
  8430.         LOCAL m.ctmpname, lZoom
  8431.  
  8432.         *- Now add form record
  8433.         *- get form name
  8434.         IF EMPTY(THIS.formRef.cWnameExpr)
  8435.             IF EMPTY(a_scx2fld[A_NAME])
  8436.                 THIS.cWinName = THIS.GetNewName(THIS.fp3class)
  8437.             ELSE                
  8438.                 IF LEFT(a_scx2fld[A_NAME],1) = "("
  8439.                     *- indirect ref to window name
  8440.                     *- cFormName has been created above, before formset
  8441.                     *- is created (at same time environment/DNO is handled)
  8442.                     THIS.cWinName = THIS.formRef.cFormName
  8443.                 ELSE
  8444.                     *- check to see if form name is already used
  8445.                     IF TRIM(a_scx2fld[A_NAME]) $ THIS.formRef.cWinNames
  8446.                         *- duplicate name, so use made up one
  8447.                         THIS.cWinName = THIS.GetNewName(THIS.fp3class)
  8448.                     ELSE
  8449.                         THIS.cWinName = TRIM(a_scx2fld[A_NAME])
  8450.                         THIS.formRef.cWinNames = THIS.formRef.cWinNames + "|" + THIS.cWinName    && add
  8451.                     ENDIF
  8452.                 ENDIF
  8453.             ENDIF
  8454.         ELSE
  8455.             IF EMPTY(a_scx2fld[A_NAME])
  8456.                 *- no name provided, so go ahead and use #WNAME directive value
  8457.                 THIS.cWinName = THIS.formRef.cWnameExpr
  8458.                 THIS.formRef.cWinNames = THIS.formRef.cWinNames + "|" + THIS.cWinName    && add
  8459.             ELSE
  8460.                 *- check to see if form name is already used
  8461.                 IF TRIM(a_scx2fld[A_NAME]) $ THIS.formRef.cWinNames
  8462.                     *- duplicate name, so use #WNAME one
  8463.                     THIS.cWinName = THIS.formRef.cWnameExpr
  8464.                     THIS.formRef.cWinNames = THIS.formRef.cWinNames + "|" + THIS.cWinName    && add
  8465.                 ELSE
  8466.                     IF THIS.formRef.cWnameExpr == "WZ_WIN"
  8467.                         *- assume this is a Wizard generated form, so use the #WNAME value (jd 7/15/96)
  8468.                         THIS.cWinName = THIS.formRef.cWnameExpr
  8469.                     ELSE
  8470.                         *- name and #WNAME directive value provided, and not Wizard -- use name
  8471.                         THIS.cWinName = TRIM(a_scx2fld[A_NAME])
  8472.                     ENDIF
  8473.                     THIS.formRef.cWinNames = THIS.formRef.cWinNames + "|" + THIS.cWinName    && add
  8474.                 ENDIF
  8475.             ENDIF
  8476.         ENDIF
  8477.         
  8478.         THIS.AddName(THIS.cWinName)
  8479.  
  8480.         *- adds form specific,window type properties
  8481.         *- window title (check for #itse)
  8482.         DO CASE
  8483.             CASE !EMPTY(THIS.formRef.itse_expr) AND SUBSTR(a_scx2fld[A_TAG],2,1) = THIS.formRef.itse_expr
  8484.                 THIS.AddProp(M_CAPTION,SUBSTR(a_scx2fld[A_TAG],3, RAT('"',a_scx2fld[A_TAG])-3))
  8485.             CASE !EMPTY(a_scx2fld[A_TAG])
  8486.                 THIS.AddProp(M_CAPTION,a_scx2fld[A_TAG])
  8487.             OTHERWISE
  8488.                 *- no title
  8489.                 THIS.AddProp(M_CAPTION,[""])
  8490.         ENDCASE
  8491.         
  8492.         IF !EMPTY(a_scx2fld[A_PICTURE])
  8493.             THIS.AddProp(M_FPICTURE,THIS.FullBMP(StripQuote(a_scx2fld[A_PICTURE]))) && wallpaper
  8494.         ENDIF
  8495.         IF !EMPTY(a_scx2fld[A_ORDER])
  8496.             THIS.AddProp(M_ICON,EVAL(a_scx2fld[A_ORDER])) &&icon
  8497.         ENDIF
  8498.         
  8499.         THIS.AddProp(M_BORDER,THIS.GetWBorder(a_scx2fld[A_BORDER]))
  8500.  
  8501.         IF INLIST(a_scx2fld[A_PLATFORM],C_DOS,C_UNIX)
  8502.             *- Add DOS footer (check for ITSE)
  8503.             DO CASE
  8504.                 CASE !EMPTY(THIS.formRef.itse_expr) AND SUBSTR(a_scx2fld[A_TAG2],2,1) = THIS.formRef.itse_expr
  8505.                     THIS.AddProp(M_TAGD,SUBSTR(a_scx2fld[A_TAG2],3, RAT('"',a_scx2fld[A_TAG2])-3))
  8506.                 CASE !EMPTY(a_scx2fld[A_TAG2])
  8507.                       THIS.AddProp(M_TAGD,a_scx2fld[A_TAG2])     
  8508.             ENDCASE
  8509.             *- Add shadow
  8510.             THIS.AddProp(M_SHADOW,a_scx2fld[A_SHADOW])
  8511.         ENDIF
  8512.                         
  8513.         *- Now check #WCLAUSE directive
  8514.         *- IN DESKTOP / IN SCREEN / IN WINDOW
  8515.         DO CASE
  8516.             CASE ATC("IN DESKTOP",THIS.formRef.wclause_expr) # 0
  8517.                 THIS.AddProp(M_DESKTOP,C_TRUE)
  8518.             CASE ATC("IN WINDOW",THIS.formRef.wclause_expr) # 0
  8519.                 m.tmpcnt = 1
  8520.                 DO WHILE UPPER(WORDNUM(THIS.formRef.wclause_expr,m.tmpcnt))#"WINDOW"
  8521.                     m.tmpcnt = m.tmpcnt+1
  8522.                 ENDDO
  8523.                 m.tmpstr = WORDNUM(THIS.formRef.wclause_expr,m.tmpcnt+1)
  8524.                 THIS.AddProp(M_WINDOW,m.tmpstr)
  8525.             CASE ATC("IN SCREEN",THIS.formRef.wclause_expr) # 0
  8526.                 THIS.AddProp(M_WINDOW,C_TRUE)
  8527.         ENDCASE
  8528.         
  8529.         *- GROW
  8530.         THIS.AddProp(M_GROW,ATC(" GROW",THIS.formRef.wclause_expr) # 0)
  8531.         
  8532.         *- ZOOM - Maximize
  8533.         m.lZoom = ATC(" ZOOM",THIS.formRef.wclause_expr) # 0
  8534.                 
  8535.         *- MDI
  8536.         THIS.AddProp(M_MDI,ATC(" MDI",THIS.formRef.wclause_expr) # 0)
  8537.  
  8538.         THIS.AddProp(M_MAXIMIZE,m.lZoom)
  8539.         THIS.AddProp(M_ZOOMBOX,m.lZoom)                    && for the Mac (jd 02.14.95)
  8540.         THIS.AddProp(M_FLOAT,a_scx2fld[A_FLOAT])
  8541.         THIS.AddProp(M_CLOSE,a_scx2fld[A_CLOSE])
  8542.         THIS.AddProp(M_MINIMIZE,a_scx2fld[A_MINIMIZE])
  8543.         IF (!a_scx2fld[A_FLOAT] AND !a_scx2fld[A_CLOSE] AND !a_scx2fld[A_MINIMIZE] AND !m.lZoom)
  8544.             THIS.AddProp(M_CONTROLBOX,.F.)
  8545.         ENDIF
  8546.             
  8547.         THIS.AddProp(M_HALF,a_scx2fld[A_TAB])
  8548.  
  8549.  
  8550.         *- Color Scheme
  8551.         IF ATC("COLORSCHEME",THIS.formRef.wclause_expr) # 0
  8552.             m.tmpcnt = 1
  8553.             DO WHILE UPPER(WORDNUM(THIS.formRef.wclause_expr,m.tmpcnt))#"COLORSCHEME"
  8554.                 m.tmpcnt = m.tmpcnt+1
  8555.             ENDDO
  8556.             m.tmpstr = WORDNUM(THIS.formRef.wclause_expr,m.tmpcnt+1)
  8557.             THIS.AddProp(M_SCHEME,m.tmpstr)
  8558.         ENDIF
  8559.             
  8560.         *- support indirect reference to file names
  8561.         IF THIS.FormRef.lIndirectWinName
  8562.             THIS.AddMethods(M_INIT,;
  8563.                 C_CRLF + ;
  8564.                 "THIS.Name = " + ;
  8565.                 THIS.FormRef.cIndirectWinName + ;
  8566.                 C_CRLF,1)
  8567.         ENDIF
  8568.  
  8569.         *- section 2 code goes into FORM.LOAD method
  8570.         IF !EMPTY(THIS.formRef.a_reads[2])
  8571.             THIS.AddMethods(M_SETUP2,THIS.formRef.a_reads[2],1)
  8572.             *- clear out setup var, so it isn;t added to more than one screen in set
  8573.             THIS.formRef.a_reads[2] = ""
  8574.         ENDIF
  8575.         IF !EMPTY(THIS.formRef.cMainCurs)
  8576.             THIS.AddMethods(M_FORMACTIVATE,"SELECT " + THIS.formRef.cMainCurs + C_CRLF,1)
  8577.         ENDIF
  8578.  
  8579.     ENDPROC
  8580.     
  8581.     *----------------------------------
  8582.     PROCEDURE Premap        && fp25form
  8583.     *----------------------------------
  8584.         *- We need to reset for screen sets
  8585.         THIS.formRef.parentName = THIS.formRef.cFormSetName
  8586.     ENDPROC
  8587.         
  8588.     *----------------------------------
  8589.     PROCEDURE Postmap        && fp25form
  8590.     *----------------------------------
  8591.  
  8592.         THIS.formRef.parentName = THIS.formRef.parentName + "." + THIS.fp3name
  8593.  
  8594.         *- get form fontmetrics for other records
  8595.         IF INLIST(a_scx2fld[A_PLATFORM],C_MAC,C_WINDOWS)
  8596.             THIS.formRef.nDeffont1 = THIS.fp3font1     && default screen font1
  8597.             THIS.formRef.nDeffont5 = THIS.fp3font5     && default screen font5
  8598.             THIS.formRef.nDeffont6 = THIS.fp3font6     && default screen font6
  8599.         ENDIF
  8600.         
  8601.         *- Need to get default screen color for transparent objects
  8602.         IF a_scx2fld[A_FILLRED] = -1
  8603.             THIS.formRef.cDefcolor = "255,255,255"
  8604.         ELSE
  8605.             THIS.formRef.cDefcolor = ALLT(STR(a_scx2fld[A_FILLRED]))+;
  8606.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  8607.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE]))
  8608.         ENDIF
  8609.         
  8610.         *- Add form record here so that
  8611.         *- PageFrame rec gets added automatically
  8612.         THIS.AddProp(M_NAME,THIS.fp3name)
  8613.         
  8614.         *- Add Form / PageFrame / FormPage record
  8615.         IF !THIS.FormRef.lDevMode
  8616.             THIS.AddRec
  8617.             THIS.AddPage()
  8618.         ENDIF
  8619.  
  8620.     ENDPROC
  8621.  
  8622.     *----------------------------------
  8623.     PROCEDURE WriteName
  8624.     *----------------------------------
  8625.     ENDPROC
  8626.     
  8627.     *----------------------------------
  8628.     PROCEDURE AddPage
  8629.     *----------------------------------
  8630.         *- Note: we add an invisible form page here
  8631.         *- to simulate the first READ level.
  8632.         THIS.fp3class = T_PAGE            && class
  8633.         THIS.fp3base = T_PAGE            && baseclass
  8634.         THIS.fp3prop = ""                && properties
  8635.         THIS.fp3method = ""                && methods
  8636.         THIS.AddBasic
  8637.         THIS.fp3comment    = a_scx2fld[A_COMMENT]         && comment
  8638.         THIS.fp3parent = THIS.formRef.parentName
  8639.         THIS.fp3name = C_PAGEFRAME
  8640.         THIS.AddProp(M_VPOS,0)
  8641.         THIS.AddProp(M_HPOS,0)
  8642.         THIS.AddProp(M_HEIGHT,30000)
  8643.         THIS.AddProp(M_WIDTH,30000)
  8644.         THIS.AddProp(M_FORMPAGES,1)
  8645.         THIS.AddProp(M_PENSIZE,0)    &&borderwidth
  8646.         THIS.AddProp(M_FORMTABS,C_FALSE)
  8647.         THIS.AddProp(M_ERASEPAGE,C_FALSE)
  8648.         THIS.AddProp(M_DRAWFRAME,C_FALSE)
  8649.         THIS.AddProp(M_NAME,C_PAGEFRAME)
  8650.         THIS.AddProp(C_DEFPAGE+"."+M_MODE,0)
  8651.         THIS.AddProp(C_DEFPAGE+"."+M_NAME,THIS.AddQuotes(C_DEFPAGE))
  8652.         
  8653.         THIS.formRef.parentName = THIS.formRef.parentName + ;
  8654.             "." + C_PAGEFRAME + "." + C_DEFPAGE
  8655.     ENDPROC
  8656.  
  8657.     *----------------------------------
  8658.     PROCEDURE AddPos        && fp25form
  8659.     *----------------------------------
  8660.         *- Add object positions in pixels (how Taz stores it)
  8661.         
  8662.         PRIVATE m.arrange,m.larrflag,m.lcentflag,m.nrow,m.ncol
  8663.         STORE "" TO m.arrange
  8664.         STORE .F. TO m.larrflag,m.lcentflag
  8665.         STORE 0 TO m.nrow,m.ncol
  8666.  
  8667.         THIS.nDeffont1 = THIS.fp3font1
  8668.         THIS.nDeffont5 = THIS.fp3font5
  8669.         THIS.nDeffont6 = THIS.fp3font6
  8670.  
  8671.         *- WIDTH based on object font
  8672.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6)
  8673.  
  8674.         *- HEIGHT based on object font
  8675.         *- Add title bar height for 3.0 style forms
  8676.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT]*;
  8677.           (THIS.fp3font1+THIS.fp3font5))
  8678.           
  8679.         *- check if we have arranged screen from project
  8680.         *- VPOS,HPOS based on form font
  8681.  
  8682.         m.arrange = THIS.formRef.a_scx2files[THIS.formRef.formnum,2]
  8683.         
  8684.         IF !EMPTY(m.arrange)
  8685.             =getarrange(m.arrange,ALLTRIM(a_scx2fld[A_PLATFORM]),@larrflag,@lcentflag,@nrow,@ncol,a_scx2fld[A_CENTER])
  8686.             IF m.larrflag AND !m.lcentflag
  8687.                 *- FoxPro 2.x used the current screen settings to calculate the row and col in foxels
  8688.                 THIS.AddProp(M_VPOS,m.nrow*FONT(1,WFONT(1,"screen"),WFONT(2,"screen"),WFONT(3,"screen"))) && (THIS.nDeffont1+THIS.nDeffont5)    
  8689.                 THIS.AddProp(M_HPOS,m.ncol*FONT(6,WFONT(1,"screen"),WFONT(2,"screen"),WFONT(3,"screen"))) &&    THIS.nDeffont6
  8690.             ENDIF
  8691.         ELSE
  8692.             *- most likely a screen by itself
  8693.             m.lcentflag = a_scx2fld[A_CENTER]
  8694.         ENDIF
  8695.         
  8696.         IF !m.larrflag 
  8697.           THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS]*(THIS.nDeffont1+THIS.nDeffont5))        
  8698.           THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS]*THIS.nDeffont6)
  8699.         ENDIF
  8700.         
  8701.         *- add Autocenter property
  8702.         THIS.AddProp(M_CENTER,m.lcentflag)
  8703.         
  8704.     ENDPROC    && AddPos
  8705.  
  8706.     *----------------------
  8707.     PROCEDURE AddRec        && fp25form
  8708.     *----------------------
  8709.         *- Add record to FORM file    
  8710.         *- Override base class method, since form record needs
  8711.         *- special key word in reserved4 field
  8712.         IF THIS.formRef.lDevMode
  8713.             *- put methods someplace else
  8714.             INSERT INTO (THIS.formRef.new30alias) ;
  8715.                 (platform,uniqueid,timestamp,;
  8716.                 class,baseclass,objname,parent,properties,;
  8717.                 user,reserved1,reserved4,reserved6);
  8718.             VALUES(THIS.fp3saveplat,THIS.fp3id,THIS.fp3time,;
  8719.                 THIS.fp3class,THIS.fp3base,THIS.fp3name,;
  8720.                 THIS.fp3parent,THIS.fp3prop,;
  8721.                 THIS.fp3comment,;
  8722.                 THIS.fp3reserved1,;
  8723.                 IIF(!THIS.formref.a_pjxsets[A_DEFWINDOWS] AND ;
  8724.                     THIS.fp3class = T_FORM,"NODEFINE",""),;
  8725.                     THIS.fp3reserved6)
  8726.             IF !EMPTY(THIS.fp3method)
  8727.                 REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.fp3name + C_CRLF + THIS.fp3method ADDITIVE
  8728.             ENDIF
  8729.         ELSE
  8730.             *- put methods someplace else
  8731.             INSERT INTO (THIS.formRef.new30alias) ;
  8732.                 (platform,uniqueid,timestamp,;
  8733.                 class,baseclass,objname,parent,properties,;
  8734.                 methods,user,reserved1,reserved4,reserved6);
  8735.             VALUES(THIS.fp3saveplat,THIS.fp3id,THIS.fp3time,;
  8736.                 THIS.fp3class,THIS.fp3base,THIS.fp3name,;
  8737.                 THIS.fp3parent,THIS.fp3prop,;
  8738.                 THIS.fp3method,;
  8739.                 THIS.fp3comment,;
  8740.                 THIS.fp3reserved1,;
  8741.                 IIF(!THIS.formref.a_pjxsets[A_DEFWINDOWS] AND ;
  8742.                     THIS.fp3class = T_FORM,"NODEFINE",""),;
  8743.                     THIS.fp3reserved6)
  8744.         ENDIF
  8745.     ENDPROC
  8746.  
  8747.     *----------------------------------
  8748.     FUNCTION GetWBorder
  8749.     *----------------------------------
  8750.         *- Note: FPW 2.x did not properly handle
  8751.         *- single and double border windows as in 3.0 
  8752.         
  8753.         PARAMETER wstyle
  8754.         DO CASE
  8755.             CASE m.wstyle = 0    && no border ???
  8756.                 RETURN 0
  8757.             CASE m.wstyle = 1    && single border
  8758.                 RETURN 1
  8759.             CASE m.wstyle = 2    && double border
  8760.                 RETURN 2
  8761.             CASE m.wstyle = 3    && panel border
  8762.                 RETURN 2
  8763.             CASE m.wstyle = 4    && system border
  8764.                 RETURN 2
  8765.         ENDCASE
  8766.     ENDFUNC
  8767.  
  8768.     
  8769.     *----------------------
  8770.     FUNCTION GetNewName    && fp25form
  8771.     *----------------------
  8772.         *- override fp25obj -- generate a unique form name
  8773.         PARAMETER newobj
  8774.  
  8775.         RETURN SYS(2015)
  8776.  
  8777.     ENDFUNC        && GetNewName
  8778.     
  8779.  
  8780. ENDDEFINE
  8781.  
  8782. ************************************
  8783. DEFINE CLASS fpdatanav AS fp25obj
  8784. ************************************
  8785.     
  8786.     cOldParentName = ""
  8787.     fp3objtype = 0
  8788.  
  8789.     *----------------------------------
  8790.     PROCEDURE Init            && fpdatanav
  8791.     *----------------------------------
  8792.         PARAMETER parm1,parm2
  8793.         
  8794.         fp25obj::Init(parm1,parm2)
  8795.         
  8796.         THIS.cOldParentName = THIS.formRef.parentName
  8797.         
  8798.         IF !THIS.formRef.lHasDataNavObj
  8799.             *- add a data nav object for this screen, and
  8800.             *- set flag so we don't come back here again
  8801.             THIS.formRef.parentName = ""
  8802.             THIS.fp3comment    = ""        && comment
  8803.             THIS.fp3objtype = N_FRX_DATAENV
  8804.             THIS.mapit
  8805.             THIS.addrec
  8806.             THIS.formRef.nDNORecNo = RECNO(THIS.formRef.new30alias)
  8807.             THIS.formRef.lHasDataNavObj = .T.
  8808.             THIS.ClearProp                && clear properties before continuing
  8809.         ENDIF
  8810.         *- set class values to "cursor"
  8811.         THIS.formRef.parentName = C_DEFDATANAV
  8812.         THIS.fp3class  = T_CURSOR            && class
  8813.         THIS.fp3base   = T_CURSOR            && baseclass
  8814.         RETURN
  8815.     ENDPROC
  8816.  
  8817.     *----------------------
  8818.     PROCEDURE AddBasic        && fpdatanav
  8819.     *----------------------
  8820.         fp25obj::AddBasic
  8821.         THIS.fp3id         = '^'                         && we'll sort on this field later -- goes after alpha, and before "_"
  8822.     ENDPROC
  8823.  
  8824.     *----------------------------------
  8825.     PROCEDURE MapIt
  8826.     *----------------------------------
  8827.     *- overwrite the MapIt procedure
  8828.         THIS.PreMap
  8829.         THIS.AddBasic
  8830.         THIS.AddMain
  8831.         THIS.PostMap
  8832.         THIS.WriteName     && note Name property must be written last!
  8833.         THIS.formRef.nDNOCount = THIS.formRef.nDNOCount + 1 
  8834.     ENDPROC
  8835.     
  8836.     *----------------------------------
  8837.     PROCEDURE AddMain        && fpdatanav
  8838.     *----------------------------------
  8839.  
  8840.         LOCAL nlen, cSaveArea, nCurrec
  8841.  
  8842.         *- Now add DE specific properties
  8843.         IF !THIS.formRef.lHasDataNavObj
  8844.             THIS.AddName(THIS.fp3class)
  8845.         ELSE
  8846.             THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8847.         ENDIF
  8848.         
  8849.         IF !THIS.formRef.lHasDataNavObj
  8850.             *- this is the data navigation container
  8851.             THIS.AddProp(M_AUTOLOADENV,THIS.formRef.lAutoOpen)
  8852.             THIS.AddProp(M_AUTOUNLOADENV,THIS.formRef.lAutoClose)
  8853.             STORE SELECT() TO m.savearea
  8854.             SELECT (THIS.formRef.c25alias)
  8855.             m.nCurrec = RECNO()
  8856.             LOCATE FOR objtype = 2 AND platform = THIS.formRef.platform
  8857.             SCAN WHILE objtype = 2 AND platform = THIS.formRef.platform
  8858.                 THIS.formRef.cMainCurs = IIF(EMPTY(THIS.formRef.cMainCurs) AND unique,ALLT(tag),THIS.formRef.cMainCurs)
  8859.             ENDSCAN
  8860.             IF m.nCurrec > RECC()
  8861.                 GO BOTTOM
  8862.                 SKIP
  8863.             ELSE
  8864.                 GO m.nCurrec
  8865.             ENDIF
  8866.             SELECT (m.savearea)
  8867.             THIS.AddProp(M_INITIALALIAS,THIS.formRef.cMainCurs)
  8868.         ELSE
  8869.             *- alias
  8870.             THIS.AddProp(M_ALIAS,a_scx2fld[A_TAG])
  8871.             
  8872.             *- cursor source
  8873.             THIS.AddProp(M_CURSORSRC,THIS.FullBMP(a_scx2fld[A_NAME]))
  8874.             
  8875.             *- order
  8876.             IF !EMPTY(ALLT(a_scx2fld[A_TAG2]))
  8877.                 THIS.AddProp(M_ORDER,a_scx2fld[A_TAG2])
  8878.             ENDIF
  8879.  
  8880.             *- remember index orders
  8881.             m.nlen = ALEN(THIS.formRef.a_tables)
  8882.             IF !(m.nlen = 1 AND EMPTY(THIS.formRef.a_tables[1]))
  8883.                 *- grow array
  8884.                 m.nlen = m.nlen + 1
  8885.                 DIMENSION THIS.formRef.a_tables[m.nlen]
  8886.                 DIMENSION THIS.formRef.a_torder[m.nlen]
  8887.             ENDIF
  8888.             THIS.formRef.a_tables[m.nlen] = ALLTRIM(a_scx2fld[A_TAG])
  8889.             THIS.formRef.a_torder[m.nlen] = ALLTRIM(a_scx2fld[A_TAG2])
  8890.  
  8891.             *- filter?
  8892.         
  8893.         ENDIF
  8894.                 
  8895.     ENDPROC        &&  fpdatanav:AddMain
  8896.  
  8897.     *----------------------------------
  8898.     FUNCTION GetNewName    && fp25datanav
  8899.     *----------------------------------
  8900.         PARAMETER newobj
  8901.         THIS.formRef.nObjCount = THIS.formRef.nObjCount + 1
  8902.         RETURN ALLTRIM(m.newobj) + ALLTRIM(STR(THIS.formRef.nObjCount))
  8903.     ENDFUNC && fp25datanav:GetNewName
  8904.  
  8905.     *----------------------------------
  8906.     PROCEDURE Destroy
  8907.     *----------------------------------
  8908.         *- reset remembered parentName
  8909.         THIS.formRef.parentName = THIS.cOldParentName
  8910.     ENDPROC
  8911. ENDDEFINE
  8912.  
  8913. ************************************
  8914. DEFINE CLASS fpFRXdatanav AS fpdatanav
  8915. ************************************
  8916.  
  8917.     *------------------
  8918.     PROCEDURE AddRec            && fpFRXdatanav
  8919.     *------------------
  8920.         THIS.fp3plat = THIS.GetPlatform()         && platform: NOTE -- forces to be current platform
  8921.  
  8922.         *- add a record to the 3.0 FRX file
  8923.         *- environ == private data session, always set it to .F.
  8924.         INSERT INTO (THIS.formRef.new30alias) ;
  8925.                 (platform,uniqueid,timestamp,objtype,name,expr,environ);
  8926.             VALUES(THIS.fp3plat,THIS.fp3id,THIS.fp3time,;
  8927.                 THIS.fp3objtype,THIS.fp3class,THIS.fp3prop,.F.)
  8928.  
  8929.     ENDPROC
  8930.  
  8931. ENDDEFINE
  8932.  
  8933. ************************************
  8934. DEFINE CLASS fpDataNavRelation AS fpdatanav
  8935. ************************************
  8936.  
  8937.     cAlias = ""
  8938.  
  8939.     *----------------------------------
  8940.     PROCEDURE Init
  8941.     *----------------------------------
  8942.         PARAMETER parm1,parm2
  8943.         
  8944.         fp25obj::Init(parm1,parm2)
  8945.             
  8946.         THIS.cOldParentName = THIS.formRef.parentName
  8947.         THIS.formRef.parentName = C_DEFDATANAV
  8948.     
  8949.     ENDPROC        &&  fpDataNavRelation::Init
  8950.     
  8951.     *----------------------------------
  8952.     PROCEDURE AddMain        && fpDataNavRelation
  8953.     *----------------------------------
  8954.  
  8955.         LOCAL npos, loldexact, nrec, m.savearea, nworkarea
  8956.  
  8957.         *- Now add relation properties
  8958.         IF !THIS.formRef.lHasDataNavObj
  8959.             THIS.AddName(THIS.fp3class)
  8960.         ELSE
  8961.             THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8962.         ENDIF
  8963.         
  8964.         *- parent alias
  8965.         THIS.AddProp(M_PARENTALIAS,a_scx2fld[A_TAG2])
  8966.         
  8967.         *- parent index expr
  8968.         THIS.AddProp(M_PARENTINDEXEXPR,a_scx2fld[A_EXPR])
  8969.         
  8970.         *- child alias
  8971.         THIS.AddProp(M_CHILDALIAS,a_scx2fld[A_TAG])
  8972.         
  8973.         *- child index expr
  8974.         m.loldexact = SET("EXACT")
  8975.         npos = ASCAN(THIS.formRef.a_tables,TRIM(a_scx2fld[A_TAG]))
  8976.         IF m.npos > 0
  8977.             THIS.AddProp(M_CHILDINDEXTAG,THIS.formRef.a_torder[m.npos])
  8978.         ENDIF
  8979.         SET EXACT &loldexact
  8980.  
  8981.         *- always set one-to-many
  8982.         *- remember this record
  8983.         m.savearea = SELECT()
  8984.         nWorkArea = a_scx2fld[A_OBJCODE]
  8985.         SELECT (THIS.formRef.c25alias)
  8986.         m.nrec = RECNO()
  8987.         LOCATE FOR objtype = 2 AND objcode = m.nWorkArea AND platform = THIS.formRef.platform AND !EMPTY(expr) AND !environ
  8988.         IF FOUND()
  8989.             *- THIS.AddProp(M_ONETOMANY,.T.)
  8990.             *- do it the hard way
  8991.             THIS.FormRef.cSetSkip = THIS.FormRef.cSetSkip + C_SELECT + LOWER(ALLT(tag)) + C_CR + ;
  8992.                 C_SETSKIP + LOWER(ALLT(expr)) + C_CR
  8993.             *- mark the record so we don;t hit it again -- this file is temporary, so we can touch it
  8994.             REPLACE environ WITH .T.
  8995.         ENDIF
  8996.         GOTO IIF(m.nrec > RECC(),RECC(),m.nrec)
  8997.         SELECT (m.savearea)
  8998.  
  8999.     ENDPROC        &&  fpDataNavRelation:AddMain
  9000.  
  9001. ENDDEFINE && fpDataNavRelation
  9002.  
  9003. ************************************
  9004. DEFINE CLASS fpFRXDataNavRelation AS fpDataNavRelation
  9005. ************************************
  9006.  
  9007.     *------------------
  9008.     PROCEDURE AddRec            && fpFRXDataNavRelation
  9009.     *------------------
  9010.         THIS.fp3plat = THIS.GetPlatform()         && platform: NOTE -- forces to be current platform
  9011.  
  9012.         *- add a record to the 3.0 FRX file
  9013.         *- environ == private data session, always set it to .F.
  9014.         INSERT INTO (THIS.formRef.new30alias) ;
  9015.                 (platform,uniqueid,timestamp,objtype,name,expr,environ);
  9016.             VALUES(THIS.fp3plat,THIS.fp3id,THIS.fp3time,;
  9017.                 THIS.fp3objtype,THIS.fp3class,THIS.fp3prop,.F.)
  9018.  
  9019.     ENDPROC
  9020.  
  9021. ENDDEFINE
  9022.  
  9023. *-
  9024. *- eof CONVERT.PRG
  9025. *-
  9026.