REBOL [ Title: "Flash log viewer" Purpose: {Get a list of text files in a selected directory, and then show them in a scrolling text area.} ] ;; [---------------------------------------------------------------------------] ;; [ It is a common practice to have a program log its activity in a text ] ;; [ file for later debugging. This is a simple program to obtain the names ] ;; [ of all the text files in a given folder, display the names, the then ] ;; [ display the contents of the file when the name is selected. ] ;; [ The folder name is hard-coded because the expected use of this program ] ;; [ would be to make a quick-viewer of all text files in a known location, ] ;; [ and asking for the file location would be an extra step. ] ;; [---------------------------------------------------------------------------] ;; [---------------------------------------------------------------------------] ;; [ We work on one folder of scripts. The folder name is hard-coded. ] ;; [---------------------------------------------------------------------------] DEFAULT-DIR: %/C/ change-dir DEFAULT-DIR ;; [---------------------------------------------------------------------------] ;; [ This is a function we can use to get a true-false answer to the question ] ;; [ of whether or not a particular file is a kind of file we might want to ] ;; [ view. ] ;; [---------------------------------------------------------------------------] LOG-FILE?: func ["Returns true if file is an script" file] [ find [%.txt %.TXT] find/last file "." ] ;; [---------------------------------------------------------------------------] ;; [ This function builds a list of log files in the current directory. ] ;; [ We have this operation in a function because we could want to use it ] ;; [ more than once, because we have a button that will refresh the list ] ;; [ of files. We might want to refresh the list if a new file appears. ] ;; [---------------------------------------------------------------------------] BUILD-FILE-LIST: does [ FILES: copy [] FILES: read %. while [not tail? FILES] [ either LOG-FILE? first FILES [FILES: next FILES][remove FILES] ] FILES: head FILES if empty? FILES [ inform layout [backdrop 140.0.0 text bold "No trace files found"] quit ] ] ;; [---------------------------------------------------------------------------] ;; [ This function is executed for the "Quit" button. ] ;; [---------------------------------------------------------------------------] QUIT-BUTTON: does [ quit ] ;; [---------------------------------------------------------------------------] ;; [ This function is executed for the "Debug" button. ] ;; [ It halts the script at a command prompt so we can use the "probe" ] ;; [ command to investigate problems. The "do-events" command can reactivate ] ;; [ the window. ] ;; [---------------------------------------------------------------------------] DEBUG-BUTTON: does [ halt ] ;; [---------------------------------------------------------------------------] ;; [ This function is executed when a file name is selected from the list ] ;; [ of file names. It reads the selected file and displays it in the text ] ;; [ area. ] ;; [---------------------------------------------------------------------------] CURRENT-FILE: none FILE-TEXT: "" FILE-LINECOUNT: 0 NEW-TEXT: "" SHOW-FILE: does [ CURRENT-FILE: to-file MAIN-LIST/picked if not exists? CURRENT-FILE [ alert rejoin ["You deleted " to-string CURRENT-FILE] exit ] FILE-TEXT: copy "" FILE-TEXT: read CURRENT-FILE MAIN-FILE/text: FILE-TEXT MAIN-FILE/line-list: none MAIN-FILE/para/scroll/y: 0 MAIN-FILE/user-data: second size-text MAIN-FILE MAIN-SCROLLER/data: 0 MAIN-SCROLLER/redrag MAIN-FILE/size/y / MAIN-FILE/user-data show MAIN-FILE show MAIN-SCROLLER MAIN-FILENAME/text: to-string CURRENT-FILE MAIN-CHARACTERS/text: to-string length? FILE-TEXT show MAIN-FILENAME show MAIN-CHARACTERS FILE-LINES: copy [] FILE-LINES: read/lines CURRENT-FILE FILE-LINECOUNT: length? read/lines CURRENT-FILE MAIN-LINES/text: to-string FILE-LINECOUNT show MAIN-LINES ] ;; [---------------------------------------------------------------------------] ;; [ This function is called whenever the scroller is moved. ] ;; [ The text area and the scroller are passed to this function. ] ;; [---------------------------------------------------------------------------] SCROLL-AREA: func [TXT BAR] [ ;; -- The program will crash if we try to scroll before data is present. if CURRENT-FILE [ TXT/para/scroll/y: negate BAR/data * (max 0 TXT/user-data - TXT/size/y) show TXT ] ] ;; [---------------------------------------------------------------------------] ;; [ This function is executed for the "Refresh" button. ] ;; [ It re-reads the list of file names in the current directory and ] ;; [ rebuilds the file name list in the main window. ] ;; [---------------------------------------------------------------------------] REFRESH-BUTTON: does [ BUILD-FILE-LIST MAIN-LIST/data: FILES show MAIN-LIST ] ;; [---------------------------------------------------------------------------] ;; [ Begin. ] ;; [ Build the list of files before we create the main window because ] ;; [ that list of file names is the data for the list in the main window. ] ;; [---------------------------------------------------------------------------] BUILD-FILE-LIST ;; [---------------------------------------------------------------------------] ;; [ Build and display the main window. ] ;; [---------------------------------------------------------------------------] MAIN-WINDOW: layout [ across MAIN-LIST: text-list 300x700 data FILES [SHOW-FILE] MAIN-FILE: area 800x700 font [name: font-fixed] MAIN-SCROLLER: scroller 24x700 [SCROLL-AREA MAIN-FILE MAIN-SCROLLER] return text "Current file: " MAIN-FILENAME: text 200 text "Lines: " MAIN-LINES: text 40 text "Characters: " MAIN-CHARACTERS: text 40 return button "Quit" [QUIT-BUTTON] button "Debug" [DEBUG-BUTTON] button "Refresh" [REFRESH-BUTTON] ] view center-face MAIN-WINDOW