Metropoli BBS
VIEWER: nflag.pps MODE: TEXT (ASCII)
;
; Patched for use with Blackcat Viewer 2.0. 
; Patched for use with Blackcat Nuker 0.80 and up.
;
;
;******************************************************************************
;  FLAG.PPE version 3.0 released on 12/18/93 by David W. Terry
;
; FLAG.PPE is a replacement for PCBoard's internal "more?" prompt, gives
; PCBoard v15.1 the easiest-to-use system for flagging and viewing files of
; any BBS around.  It gives callers the ability to point and shoot when
; flagging or viewing files.
;
; NOTE:  Please DO NOT DISTRIBUTE modified source code without prior permission
; or without meeting the requirements set forth in FLAG.DOC.
;******************************************************************************

' check to see if caller has ANSI capabilities and, if not, display the old
' prompt and exit - let PCBoard handle the input.

;***********************************************************************


;*** BlackCAT NUKER ADDITION START 
string nukecfg, nukefile, dirnr
nukecfg = ppepath() + "flagnuke.cfg"
if (!exist(nukecfg)) then
	freshline
	println "Error: Flag.ppe is setup to use NUKE.PPE but cannot"
	println "find FLAGNUKE.CFG, please contact sysop"
	end
endif
nukefile = readline(nukecfg, 1) + "\work\bcnk" + string(curconf()) +"."+ string(pcbnode())
;*** BlackCAT NUKER ADDITION END 

IF (! ANSION()) THEN
  DISPFILE PPEPATH()+"FLAGOLD",LANG
  END
ENDIF

BOOLEAN exitflag       ' Flag to determine when we should exit
BOOLEAN rip            ' Flag to indicate RIPscrip is in use

STRING  text           ' The text that the caller types
STRING  key            ' Keystroke text

STRING  BS             ' An ASCII backspace character
STRING  BS2            ' An ASCII backspace character
STRING  CR             ' An ASCII carriage return character
STRING  ESC            ' An ASCII esc character

BYTE    len            ' Length of the text the caller has typed
BYTE    oldy           ' Last row position of cursor
BYTE    newy           ' New row position of cursor

STRING  filenames(23)  ' The names of the files found on the screen
STRING  filename       ' The name of the file that is being processed
STRING  fileimage      ' Includes the color codes for restoration of text

;***********************************************************************

; Initializations

BS     = CHR(8)   ' Backspace Key
BS2    = CHR(127) ' Alternate Backspace Key
CR     = CHR(13)  ' Carriage Return
ESC    = CHR(27)  ' ESC character
len    = 0        ' Initialize to 0 bytes in the input buffer
text   = ""       ' Initialize to an empty input buffer

;***********************************************************************

; Main Program

                             ' in case the last invocation of flag.ppe saved
RESTSCRN                     ' the screen, restore it now

CLREOL                       ' clear the line for input
GOSUB displayprompt          ' display the new prompt
GOSUB scanforfiles           ' build filenames array

' While the user hasn't exited, get keystrokes and act on them.
' Exiting will occur when the caller presses ENTER.

WHILE (!exitflag) DO

  key = INKEY()  ' Get a keypress from the user

  if (key <> "") THEN  ' If the user pressed a key, then let's process it

    ' If it is the FIRST keystroke, signified by the buffer having 0 bytes
    ' in it, then check to see if it is a SPACE.  If so, then we'll go into
    ' MARK mode.  If not, then we'll process the keystrokes the same way that
    ' PCBoard would .. gathering them up into a buffer.  Once the ENTER key
    ' is pressed, we'll exit out and stuff PCBoard's keyboard buffer with the
    ' keystrokes that were collected.

    IF (len = 0 & key = " ") THEN
      oldy = GETY()
      newy = 0

      PRINT CR
      CLREOL
      PRINT ESC+"[s"  ' save the current cursor position

      ' Let the caller know what he can do while in MARK mode
      DISPFILE PPEPATH()+"FLAGBAR",GRAPH+LANG

      ' Move the cursor back to the first column
      PRINT CR

      ' Find the first filename on the screen.
      GOSUB findfile

      ' If a filename was found, then findfile highlighted it.  Now wait for
      ' another keystroke to see if the user whats to mark this one, or move
      ' on to another one, or exit out.  Marking is done by pressing ENTER,
      ' moving to another file is done by pressing SPACE, viewing the file is
      ' done by pressing "V", and exiting is done by pressing ESC.

      IF (filename <> "") THEN

        ;*** BlackCAT NUKER PATCH START 
        WHILE (key != ESC & key != CR & UPPER(key) != "V" & upper(key) != "N") DO
        ;*** BlackCAT NUKER PATCH END 
          key = INKEY()

          ' If the key pressed was a SPACE then the user has decided to skip
          ' over that file.  So unhighlight it, then try to find another
          ' file.  If a file is found, we'll stay in this loop.  If one is
          ' not found, then we'll restore the original prompt and go back to
          ' waiting for keystrokes in case the caller wants to start over
          ' (marking files) or wants to manually (F)lag them instead.

          IF (key = " ") THEN
            GOSUB unhighlight
            GOSUB findfile
            IF (filename = "") THEN
              GOSUB restorecursor
              GOSUB displayprompt
              GOTO  bottom
            ENDIF
          ENDIF
        ENDWHILE

        ' If we've gotten this far, then ESC, CR or V was pressed.  We'll
        ' unhighlight the file, restore the prompt and then, if CR was pressed,
        ' meaning the user wished to MARK that file, then will stuff PCBoard's
        ' keyboard buffer with a FLAG command and the name of the file to flag.
        ' If V was pressed, then we'll instead stuff the buffer with a command
        ' to VIEW the file.

        GOSUB unhighlight
        GOSUB restorecursor

        IF (key = CR) THEN
          KBDSTUFF "F "+filename+CR
          END
        ELSEIF (UPPER(key) = "V") THEN
          ' save the screen into PCBoard's memory so that we can restore it
          ' when FLAG.PPE is called up again, then issue the view command
          SAVESCRN
	  ; blackcat viewer
          ;KBDSTUFF "V "+filename+CR
          KBDSTUFF "F "+ CR + "/VIEW" + CR + filename + CR
	  ;blackcat viewer
          END

        ;*** MAFIA NUKER ADDITION START 
        ELSEIF (UPPER(key) = "N") THEN
	  savescrn
	  fclose -1
	  if (upper(readline(nukefile, 1)) <> u_name()) then
	       delete nukefile
	       fappend 1, nukefile, O_WR, S_DN
	       fputln 1, u_name() 
	  else
	       fappend 1, nukefile, O_WR, S_DN
	  endif
	  dirnr = string(pcbmac("@DIRNUM@"))
          ; oops, assume upload dir, there's nothing we can do
	  if (dirnr == "") then 
	      dirnr = string(pcbmac("@NUMDIR@"))
	  endif
	  if (filename <> "") fputln 1, filename + " " + dirnr
	  fclose 1
	  println "@X0CFile targetted for nuking...."
	  delay 20
	  restscrn
        ;*** MAFIA NUKER ADDITION END 
        ENDIF
      ELSE
        GOSUB restorecursor
      ENDIF

      GOSUB displayprompt
      CONTINUE

    ELSEIF (key == BS | key == BS2) THEN

      ' If the caller pressed backspace or delete, then delete the character
      ' to the left, and remove it from the input buffer.  Of course, if the
      ' caller hasn't typed anything yet, or if the caller has already
      ' backspaced everything out, signified by the len being 0 (meaning there
      ' are 0 bytes in the buffer), then we'll just loop back around waiting
      ' for more keystrokes

      IF (len > 0) THEN
        PRINT BS+" "
        len  = len - 1
        text = LEFT(text,len)
      ELSE
        CONTINUE
      ENDIF

    ELSEIF (key == CR) THEN

      ' If it's a carriage return then set the flag to exit
      exitflag = TRUE

    ELSEIF (LEN(key) > 1 | key < " ") THEN

      ' Special keys, such as UP, DOWN, etc, return multi-letter values such
      ' as "UP" and "DOWN" when the INKEY() function is called.  Since we just
      ' want to ignore special characters, we'll use the CONTINUE statement to
      ' jump back to the top of the loop
      '
      ' We also want to avoid displaying "control characters" so anything
      ' less than a SPACE should also be skipped.

      CONTINUE

    ELSEIF ((len = 0) & ((key = "?") | (UPPER(key) = "H"))) THEN

      ' If the user typed "?" or "H" then we want to display a help file.
      ' First we'll save the current screen, then display the help file, and
      ' then restore the saved screen after the caller has read the help file.

      SAVESCRN
      NEWLINE
      DISPFILE PPEPATH()+"FLAGHLP",GRAPH+LANG
      NEWLINE
      WAIT
      RESTSCRN
      CONTINUE

    ELSEIF ((key >= " ") & (len < 80)) THEN

      ' Here we are just gathering up keystrokes and putting them into an
      ' input buffer.  As long as the keystrokes are greater than or equal to
      ' a SPACE we'll just add them in until a limit of 80 characters is
      ' reached.  PCBoard won't let you type more than 80 characters at that
      ' prompt anyway so we might as well keep the same limit.

      text = text + key
      len  = len + 1

    ENDIF

    PRINT key    ' Print any keystrokes the caller types
  ENDIF

:bottom
ENDWHILE

' If we've gotten this far, then the caller has pressed ENTER so we'll stuff
' whatever the caller has typed into PCBoard's input buffer and let PCBoard
' process the request.
'
' But first, if the command begins with V then it may be a view files command.
' Verify that assumption by checking to see if the user typed "V" and pressed
' ENTER (check length equal to 1) or if the user typed "V filename" (check
' for length greater than or equal to 3 for "F f")

text = RTRIM(text," ")

IF (UPPER(LEFT(text,1)) = "V") THEN
  IF (LEN(text) = 1) THEN
    CLREOL
    filename = ""
    ; blackcat viewer start
    ;PROMPTSTR 240,filename,12,MASK_FILE(),FIELDLEN
    inputstr "@X07Filename to view (enter=none)", filename, 7, 12, mask_file(), fieldlen
    ;blackcat viewer end
    filename = RTRIM(filename," ");
    IF (LEN(filename) = 0) THEN
      CLREOL
      KBDSTUFF CR
      END
    ENDIF
    NEWLINE

    ' the lines below could be used to specify a different "default extension"
    ' for archive files in different conferences - uncomment and adapt as
    ' necessary to suit your needs
    '
    ' IF (INSTR(filename,".") = 0) THEN
    '   IF (CURCONF() = 30) THEN
    '     filename = filename + ".ARJ"
    '   ELSEIF (CURCONF() = 50) THEN
    '     filename = filename + ".ZOO"
    '   ENDIF
    ' ENDIF

    ; blackcat viewer start
    ;text = "V "+filename
    text = "V "+ CR + filename
    ; blackcat viewer end
    ' save the screen to PCBoard's memory so that the next invocation of
    ' FLAG.PPE will restore the screen
    SAVESCRN
  ELSEIF (LEN(text) >= 3) THEN
    ' save the screen to PCBoard's memory so that the next invocation of
    ' FLAG.PPE will restore the screen
    CLREOL

    ' the lines below could be used to specify a different "default extension"
    ' for archive files in different conferences - uncomment and adapt as
    ' necessary to suit your needs
    '
    ' IF (INSTR(filename,".") = 0) THEN
    '   IF (CURCONF() = 30) THEN
    '     text = text + ".ARJ"
    '   ELSEIF (CURCONF() = 50) THEN
    '     text = text + ".ZOO"
    '   ENDIF
    ' ENDIF

    SAVESCRN
    ; blackcat viewer start
    text = "F " + CR + "/VIEW" + CR + mid(text, 2, len(text) - 1)
    ; blackcat viewer end
  ELSE
    KBDSTUFF CR
    END
  ENDIF
ENDIF

KBDSTUFF text+CR
END


;***********************************************************************
'
' This subroutine restores the cursor position.  It does this using an ANSI
' command that simply restores a previously saved cursor position.  In
' addition, we'll clear the line before returning.

:restorecursor
PRINT ESC+"[u"
CLREOL
RETURN


;***********************************************************************
'
' This is a subroutine that displays the new prompt and then sets the color to
' the default for input.

:displayprompt
DISPFILE PPEPATH()+"FLAGNEW",LANG
DEFCOLOR
RETURN


;***********************************************************************
'
' This is a subroutine that checks the filenames() array to locate the next
' file on screen.  If RIPscrip is used, then special commands (which are
' passed via a mouse-click from the caller's terminal, are used to identify
' which file is desired.
'
' If a valid filename is found, it is stored in a variable called filename.
' Also, it calls another subroutine to highlight the filename on the screen.

:findfile
IF (rip) THEN
  newy = 0
  key = ""
  WHILE (newy = 0) DO
    key = INKEY()      ' watch for the next character
    newy = ASC(key)
    IF (newy >= 129 & newy <= 151) THEN
      newy = newy - 128
      IF (filenames(newy) <> "") THEN
        GOSUB highlight
        filename = filenames(newy)
        RETURN
      ELSE
        newy = 0
      ENDIF
    ENDIF
  ENDWHILE
ELSE
  WHILE (newy < oldy) DO
    newy = newy + 1
    IF (filenames(newy) <> "") THEN
      GOSUB highlight
      filename = filenames(newy)
      RETURN
    ENDIF
  ENDWHILE
ENDIF

' no valid filename was found, return with an empty filename
filename = ""
RETURN


;***********************************************************************
'
' This is a subroutine that highlights the filename moving the cursor to the
' correct line and then changing the color to black on white and printing the
' filename.  Prior to highlighting the filename, it saves a color image of the
' filename so that, when it comes time to unhighlight the file, the image can
' be restored.

:highlight
' move the cursor back to where it started, at the bottom, and then move
' it up to the appropriate line on the screen.
PRINT ESC+"[u"+ESC+"["+STRING(oldy-newy)+"A"

' get the file image (text & attributes) for later restoration
fileimage = SCRTEXT(1,newy,13,TRUE)

' then highlight the filename and return
COLOR @X70
PRINT filenames(newy)+CR
RETURN


;***********************************************************************
'
' This is a subroutine that unhighlights the filename by printing the file
' image, which includes color codes as well as the filename.

:unhighlight
PRINT fileimage+CR
RETURN


;***********************************************************************
'
' This subroutine scans the screen at startup to see and fills an array called
' filenames() with the names of all files found on screen.  If RIPscrip is in
' use, it will also send out RIPscrip commands to define the location of the
' filenames on screen so that the caller can use a mouse to point and click.

:scanforfiles
IF (GRAFMODE() = "R") THEN
  rip = TRUE
ENDIF

' NOTE:  This loop is unnecessary because PPL automatically initializes
'        all array elements to 0 or blank
'
' FOR newy=1 TO 23
'   filenames(newy) = ""   ' initialize the array elements
' NEXT

newy = 1
WHILE (newy > 0) DO
  ' get a filename off the screen ... if a filename is found, the filename
  ' variable will be updated, if no more filenames are found, newy will be
  ' set to 0.
  SCRFILE newy, filename

  IF (newy <> 0) THEN
    ' store the filename that was found into an array
    filenames(newy) = filename

    ' If in RIPscrip mode, define the mouse region where the filename is
    ' located.  The coordinates are defined in X,Y coordinates of 0,newy and
    ' 13,newy+1.  The X coordinate (0 to 13) defines the length of the name.
    ' The Y coordinate (newy to newy+1) defines the height of the name.
    ' An 8x8 font is assumed.  The CHR(newy+128) is a "command" that we will
    ' be using to communicate back to FLAG.PPE the position of the file being
    ' selected via mouse click.
    IF (rip) THEN
      MOUSEREG 0,1,newy,13,newy+1,8,8,TRUE,FALSE," "+CHR(newy+128)
    ENDIF
    INC newy
  ENDIF
ENDWHILE

' finish up the mouse region definitions
IF (rip) THEN
  MPRINT "!|#|#|#"+CR+chr(10)
ENDIF
RETURN

;***********************************************************************
[ RETURN TO DIRECTORY ]