home *** CD-ROM | disk | FTP | other *** search
- *
- * StatWin v2.5
- *
- * Original STAWIN.PRG by Jim Schaffner
- *
- * This version, STATWIN.PRG, with modifications by Cai Campbell
- * (Compuserve ID 72622,1771)
- *
- * Displays a status bar across the screen when performing a long
- * running task, such as indexing or reporting. This is a Clipper 5
- * version of the Foxpro STATWIN function, originally written by
- * Duane Keeling of Keeling Consulting.
- *
- * To use this, first call StatInit() with the desired top/left
- * coordinates of the display "window". Coordinates are optional.
- * Then call StatWin() from within your processing loop, passing
- * the total to be processed, and the current process count. There
- * are optional parameters for a display message, a logical for
- * displaying estimated completion time, window color, percentage bar
- * "template" color, and percentage bar "fill" color.
- *
- * Here's an example:
- *
- * StatInit()
- * DO WHILE .NOT. EOF()
- * StatWin ( LASTREC(), RECNO(), "Percent processed:", .T. )
- * SKIP
- * END DO
- * StatExit()
- *
- * If you fail to call StatExit(), you will get some strange display results
- * after the process is finished.
- *
- * Compile with /a/m/n.
- *
- * Enjoy!
- *
-
- // "borrowed" from Clipper 5.2 COMMON.CH (allows compile in 5.01)
-
- #xcommand DEFAULT <v1> TO <x1> [, <vn> TO <xn> ] ;
- => ;
- IF <v1> == NIL ; <v1> := <x1> ; END ;
- [; IF <vn> == NIL ; <vn> := <xn> ; END ]
-
-
- #include "setcurs.ch"
- #include "box.ch"
-
- MEMVAR nStatCounter, cStatMsg
-
- // Static variables:
-
- // ?Sav??? -> save video attributes, screen, etc.
- // nTop ... nRight -> screen coordinates for display
- // lFirst -> denotes first pass through routine
- // cEstMessage -> "estimated time left" message
- // lWinSize -> logical for window size, defaults to .F., small window
-
- STATIC cSavWin,cSavClr,nSavCsr
- STATIC nSavRow,nSavCol
- STATIC nTop,nLeft,nBottom,nRight
- STATIC lFirst
- STATIC cEstMessage := "Hours Left: "
- STATIC lWinSize
-
- *
- * StatInit() - initialize the status display
- *
-
- FUNCTION StatInit ( nT, nL, lSize )
-
- PUBLIC nStatCounter := 0 // Public variables needed for keeping track of
- PUBLIC cStatMsg // "internal" processes, and allowing for
- // dynamic Status Window header changes.
-
- nTop := IF ( nT == NIL, 0, nT )
- lFirst := .T.
-
- IF lSize == NIL
- lWinSize := .F.
- ELSE
- lWinSize := lSize
- END IF
-
- IF nTop > MAXROW() - 5
- nTop := MAXROW() - 5
- END IF
-
- nLeft := IF ( nL == NIL, 0, nL )
-
- IF nLeft > MAXCOL() - IF ( lWinSize, 54, 29 )
- nLeft := MAXCOL() - IF ( lWinSize, 54, 29 )
- END IF
-
- nRight := nLeft + IF ( lWinSize, 53, 28 )
- nBottom := nTop + 4
-
- cSavWin := SAVESCREEN ( nTop, nLeft, nBottom+1, nRight+1 )
-
- cSavClr := SETCOLOR()
- nSavCsr := SETCURSOR()
- nSavRow := ROW()
- nSavCol := COL()
-
- SETCURSOR(SC_NONE)
-
- RETURN NIL
-
- *
- * StatWin() - display the status bar
- *
-
- FUNCTION StatWin ( nTotal,; // Size of data being processed
- nCurrent,; // Current position in data
- cStatMsg,; // Header message for window
- lEstimate,; // If true, display estimated time left
- cMenuColor,; // Color of menu
- cBeforeColor,; // Color of percentage bar template
- cBarColor ) // Color of percentage bar, filling template
-
- LOCAL nWidth, nBlock, nBlocks, nEst, nPct
- LOCAL nBtm, nPctPos, c1stQuarter, c2ndQuarter, c3rdQuarter , cHalf, cFull
-
- STATIC nStart
-
- nStatCounter += 1 // Counter for "internal" processes
-
- // Characters for both the "long" and "short" percent bar.
-
- c1stQuarter := CHR ( 176 ) // ░
- c2ndQuarter := CHR ( 177 ) // ▒
- c3rdQuarter := CHR ( 178 ) // ▓
- cHalf := CHR ( 221 ) // ▌
- cFull := CHR ( 219 ) // █
-
- DEFAULT cStatMsg to "" // Default to NULL display message
- DEFAULT lEstimate to .F. // Default to NO estimating
- DEFAULT cBeforeColor to "B/B" // Default bar template color Blue
- DEFAULT cBarColor to "GR+/B" // Default bar color Yellow on Blue
- DEFAULT cMenuColor to "B/W" // Default color to Blue on White
-
- nWidth := IF ( lWinSize, 50, 25 )
-
- nPct := IF ( nTotal > 0, ROUND ( ( nCurrent * 100 ) / nTotal, 0 ), 100 )
-
- // This will prevent screen overrun and percentages > 100
- nPct := IF ( nPct > 100, 100, nPct )
-
- IF .NOT. ( cStatMsg == "" )
- IF LEN ( cStatMsg ) > IF ( lWinSize, 46, 20 )
- cStatMsg := LEFT ( cStatMsg, IF ( lWinSize, 46, 20 ) )
- END IF
- nPctPos := nLeft + IF ( lWinSize, 24, 12 ) + LEN ( cStatMsg ) / 2 + 1
- ELSE
- nPctPos := nLeft + IF ( lWinSize, 24, 12 )
- END IF
-
- IF lFirst
-
- IF .NOT. lEstimate // If not displaying estimated time
- nBtm := nBottom - 1 // decrease the size of the display.
- ELSE
- nBtm := nBottom
- nStart := SECONDS()
- cEstMessage := "Hours Left: "
- END IF
-
- SETCOLOR ( "B/N" ) // Draw Shadow
- @ (nTop + 1), (nLeft + 1) CLEAR TO (nBtm + 1), (nRight + 1)
- SETCOLOR ( cMenuColor )
- @ nTop, nLeft, nBtm, nRight BOX B_DOUBLE_SINGLE + SPACE(1)
- SETCOLOR ( cBeforeColor )
- @ nTop + 2, nLeft + 2 SAY REPLICATE ( cFull, nWidth )
- SETCOLOR ( cMenuColor )
-
- IF .NOT. empty(cStatMsg) // If we have a message then
- @ nTop+1, nLeft + ( IF ( lWinSize, 52, 26 ) - LEN ( cStatMsg ) ) / 2 SAY cStatMsg
- END IF
-
- lFirst := .F.
-
- ELSE
-
- IF lEstimate
- ShowTimeLeft ( nPct, nStart )
- END IF
-
- END IF
-
- nBlock := INT ( 100 / nWidth )
-
- nBlocks := INT ( nPct / nBlock ) // How many blocks do I need?
-
- @ nTop+1, nPctPos SAY STR ( nPct, 3 ) + "%" // Display percentage
-
- SETCOLOR ( cBarColor )
- IF lWinSize
- DO CASE
- CASE nPct / 2 # INT ( nPct / 2 ) // Add a 1/2 block if needed
- @ nTop + 2, nLeft + 2 SAY REPLICATE ( cFull, nBlocks ) + cHalf
- OTHERWISE // and display the bar...
- @ nTop + 2, nLeft + 2 SAY REPLICATE ( cFull, nBlocks )
- END CASE
- ELSE
- DO CASE
- CASE nPct % 4 == 1 // Add a 1/4 block if needed
- @ nTop + 2, nLeft + 2 SAY REPLICATE ( cFull, nBlocks ) + c1stQuarter
- CASE nPct % 4 == 2 // Add a 1/2 block if needed
- @ nTop + 2, nLeft + 2 SAY REPLICATE ( cFull, nBlocks ) + c2ndQuarter
- CASE nPct % 4 == 3 // Add a 3/4 block if needed
- @ nTop + 2, nLeft + 2 SAY REPLICATE ( cFull, nBlocks ) + c3rdQuarter
- OTHERWISE // and display the bar...
- @ nTop + 2, nLeft + 2 SAY REPLICATE ( cFull, nBlocks )
- END CASE
- END IF
- SETCOLOR ( cMenuColor )
-
- RETURN " "
-
- *
- * Calculate method in which to display time left then display it.
- *
-
- PROCEDURE ShowTimeLeft ( nPercent, nBegin )
-
- LOCAL nUnits
-
- nUnits := ( ( SECONDS() - nBegin ) * 100 ) / nPercent
- nUnits := ROUND ( nUnits - nUnits * nPercent * .01, 2 )
-
- IF cEstMessage == "Hours Left: " .AND. nUnits < 3600
- cEstMessage := "Minutes Left:"
- END IF
- IF cEstMessage == "Minutes Left:" .AND. nUnits < 60
- cEstMessage := "Seconds Left:"
- END IF
- IF cEstMessage == "Seconds Left:" .AND. nUnits >= 60
- cEstMessage := "Minutes Left:"
- END IF
-
- DO CASE
- CASE cEstMessage == "Hours Left: "
- nUnits /= 3600
- CASE cEstMessage == "Minutes Left:"
- nUnits /= 60
- END CASE
-
- // Display estimated units left. Maximum display = 999.99
-
- @ nTop + 3, nLeft + IF ( lWinSize, 16, 4 ) SAY cEstMessage
- @ nTop+3, nLeft + IF ( lWinSize, 32, 20 ) SAY PADR ( LTRIM ( STR ( nUnits ) ), 6 )
-
- RETURN
-
- *
- * StatExit() - exit from the status display & restore attributes
- *
-
- FUNCTION StatExit()
-
- RESTSCREEN ( nTop, nLeft, nBottom + 1, nRight + 1, cSavWin )
-
- SETCOLOR ( cSavClr )
- SETCURSOR ( nSavCsr )
- SETPOS ( nSavRow, nSavCol )
-
- cSavWin := ""
-
- RETURN NIL
-