[Back to TEXTFILE SWAG index] [Back to Main SWAG index] [Original]
{
From: Daniel Perrenoud <dperren@msswiss.kla.com>
As promised, here is the PASCAL program able to walk through a text file of
any size. It is ready to compile and contains a short example explaining how
to use the routines. The instructions are included in the source itself. If
you like it, feel free to add this file to the next release of the SWAG
libraries. I will keep working on new features and bug fixes for this
program. Let me know if you are interested on receiving the future releases.
[[ FILEBRWS.PAS : 2886 in FILEBRWS.PAS ]]
Best regards, Daniel
{
**************************************************************************
* *
* File Browser Package V1.0 by Daniel Perrenoud *
* ~~~~~~~~~~~~~~~~~~~~~~~~~ *
* o Released to the Public domain, feel free to use and copy *
* this program without any restriction. *
* o Please credit me if your program uses these routines. *
* o Your comments are welcome. You can contact me on *
* e-mail: d_perren@kla.com *
* *
* or by post: *
* *
* Daniel Perrenoud *
* Mont-Pugin 8 *
* CH-2400 Le Locle *
* SWITZERLAND *
* *
* !!! Please compile me with range checking turned OFF !!! *
* *
* *
**************************************************************************
This set of routine makes possible to display and walk through a text file
of any length. The content of the currently selected line as well as the
selected line number are available in global variables. The text file is
diplayed in a window fully parametrable by the user (position, size,
color). For better performance, use File Browser together with a disk
caching program like MS-DOS SmartDrive.
Six functions and procedures are available for File Browser control:
---> Procedure InitFB(FN:str255;WUX,WUY,WLX,WLY,BC,FC,SBC,SFC:Word)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InitFB initialises the File Browser and displays the first screen
of the file. The first line is selected.
Parameters: FN: Path and file name to display (MS-DOS format)
WUX,WUY: Upper left corner of the window
WLX,WLY: Lower right corner of the window
BC: Background color of normal text
FC: Foreground color of normal text
SBC: Background color of selected line
SFC: Foreground color of selected line
---> Function UpArrow:Boolean
~~~~~~~~~~~~~~~~~~~~~~~~
UpArrow tries to select the previous line. It returns FALSE if the
previous line is not selectable because the top line is already
selected.
---> Function DnArrow:Boolean
~~~~~~~~~~~~~~~~~~~~~~~~
DnArrow tries to select the next line. It returns FALSE if the
next line is not selectable because the bottom line is already
selected.
---> Function PgUp:Boolean
~~~~~~~~~~~~~~~~~~~~~
PgUp tries to display the previous screen of text. If the top line
is reached before one complete screen has scrolled, PgUp returns
FALSE and only the possible number of lines is scrolled.
---> Function PgDn:Boolean
~~~~~~~~~~~~~~~~~~~~~
PgDn tries to display the next screen of text. If the bottom line
is reached before one complete screen has scrolled, PgDn returns
FALSE and only the possible number of lines is scrolled.
---> Procedure CloseFB
~~~~~~~~~~~~~~~~~
CloseFB stops File Browser activity. It must be used when FB is
no longer used in order to close the open files.
The status of File Browser can be read through two variables:
---> SelAbsInd:Longint
~~~~~~~~~~~~~~~~~
Selected line number. SelAbsInd=0 if the first line is selected.
---> Image[SelCirInd]:Str255
~~~~~~~~~~~~~~~~~~~~~~~
Text of selected line. The CR or LF charaters have been removed.
This file is ready to be compiled by TP4.0 or better. A short example is
included, showing how FB works.
CAUTION: FB routines change the window attributs by using the PASCAL
WINDOW procedure.
Future extensions:
~~~~~~~~~~~~~~~~~~
o Left and right scrolling to display long lines
o Direct access to a specific line number
o Find text module
o Tag-untag line handling
o Mouse support
o Speed improvement by writing some ASM modules.
o A decent error handling!
Let me know if you have other ideas ( e-mail: d_perren@kla.com )
}
program FileBrws;
uses DOS,CRT;
type Str255=String[255];
const NbRec= 255;
FrontCst= 0;
BackCst= 1;
CRcst= $0D;
LFcst= $0A;
var FileBrowse: array[0..2] of File;
CurLine,Packet: array[0..2] of Str255;
Image: array[0..25] of Str255;
PacketInd,Numread: array[0..2] of Word;
FirstCirInd,ScrInd,SelCirInd: Word;
MaxLine,VWUX,VWUY,VWLX,VWLY: Word;
ColListBG,ColListFG,ColSListBG,ColSListFG:Word;
Ch,TmpChar: Char;
EndFile,EOP,Again,Dummy,ExtKey: Boolean;
FileName: Str255;
FilLinNum: Array[0..2] of Longint;
SelAbsInd: Longint;
Function WaitKey:Char;
var WK: Char;
begin
ExtKey:=FALSE;
repeat
until keypressed;
WK:=ReadKey;
if WK=#0 then
begin
ExtKey:=TRUE;
WK:=ReadKey;
end;
WaitKey:=WK
end;
Procedure Initialize;
begin
assign(FileBrowse[0],FileName);
assign(FileBrowse[1],FileName);
assign(FileBrowse[2],FileName);
reset(FileBrowse[0],1);
reset(FileBrowse[1],1);
reset(FileBrowse[2],1);
window(VWUX,VWUY,VWLX+1,VWLY);
ClrScr;
end;
Procedure CloseFB;
begin
close(FileBrowse[0]);
close(FileBrowse[1]);
close(FileBrowse[2]);
end;
Procedure ReadPrevPacket(FN:integer);
begin
seek(FileBrowse[FN],(FilePos(FileBrowse[FN])-Numread[FN]-NbRec));
blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
Packet[FN][0]:=chr(Numread[FN]);
PacketInd[FN]:=NbRec;
end;
Function ReadNextLine(FN:integer):Boolean;
var EOP: Boolean;
CurLinInd: Word;
begin
ReadNextLine:=FALSE;
if (EndFile=FALSE) or (FN=BackCst) then
begin
CurLinInd:=1;
repeat
repeat
TmpChar:=Packet[FN][PacketInd[FN]];
CurLine[FN][CurLinInd]:=TmpChar;
inc(CurLinInd);
inc(PacketInd[FN]);
EOP:=(PacketInd[FN]>Length(Packet[FN]))
until ((ord(TmpChar)=CRcst) OR (EOP));
if EOP then
if Numread[FN]<>NbRec then
EndFile:=TRUE
else
begin
blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
Packet[FN][0]:=chr(Numread[FN]);
PacketInd[FN]:=1;
end;
until ((ord(TmpChar)=CRcst) or (EndFile));
ReadNextLine:=TRUE;
inc(FilLinNum[FN]);
CurLine[FN][0]:=chr(CurLinInd-1);
end;
end;
Procedure Read1stLine(FN:integer);
var CurLinInd: Word;
EOP: Boolean;
begin
EndFile:=FALSE;
reset(FileBrowse[FN],1);
blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
Packet[FN][0]:=chr(Numread[FN]);
PacketInd[FN]:=1;
CurLinInd:=1;
repeat
repeat
TmpChar:=Packet[FN][PacketInd[FN]];
CurLine[FN][CurLinInd]:=TmpChar;
inc(CurLinInd);
inc(PacketInd[FN]);
EOP:=(PacketInd[FN]>Length(Packet[FN]))
until ((ord(TmpChar)=CRcst) OR (EOP));
if EOP then
if Numread[FN]<>NbRec then
EndFile:=TRUE
else
begin
blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
Packet[FN][0]:=chr(Numread[FN]);
PacketInd[FN]:=1;
end;
until ((ord(TmpChar)=CRcst) or (EndFile));
CurLine[FN][0]:=chr(CurLinInd-1);
FilLinNum[FN]:=0;
end;
Function ReadPrevLine(FN:integer):Boolean;
var Dummy: Boolean;
CurLinInd: Word;
i: Integer;
begin
CurLinInd:=1;
ReadPrevLine:=FALSE;
if FilLinNum[FN]>0 then
begin
if PacketInd[FN]>1 then
dec(PacketInd[FN])
else
ReadPrevPacket(FN);
TmpChar:=' ';
for i:=1 to 2 do
begin
while (ord(TmpChar)<>CRcst) and ((FilLinNum[FN]<>0) or
(PacketInd[FN]<>1)) do
begin
if PacketInd[FN]>1 then
dec(PacketInd[FN])
else
ReadPrevPacket(FN);
TmpChar:=Packet[FN][PacketInd[FN]];
end;
TmpChar:=' ';
dec(FilLinNum[FN]);
EndFile:=FALSE;
end;
if FilLinNum[FN]<>-1 then
inc(PacketInd[FN]);
if PacketInd[FN]>Length(Packet[FN]) then
begin
blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
Packet[FN][0]:=chr(Numread[FN]);
PacketInd[FN]:=1;
end;
Dummy:=ReadNextLine(FN);
ReadPrevLine:=TRUE;
end;
end;
Function CleanString(ALine:str255):str255;
var i,j: Integer;
begin
j:=1;
i:=1;
repeat
if (ord(ALine[i])<>CRcst) and (ord(ALine[i])<>LFcst) then
begin
CleanString[j]:=ALine[i];
inc(j);
end;
inc(i);
until (i>ord(ALine[0])) or (j>VWLX-VWUX+1);
CleanString[0]:=chr(j-1);
end;
Procedure DispSelLine;
begin
TextBackground(ColSListBG);
TextColor(ColSListFG);
GotoXY(1,ScrInd+1);
write(Image[SelCirInd]);
end;
Procedure UndispSelLine;
begin
TextBackground(ColListBG);
TextColor(ColListFG);
GotoXY(1,ScrInd+1);
write(Image[SelCirInd]);
end;
Function IncMod(i:Word):Word;
begin
IncMod:=(i+1) mod MaxLine;
end;
Function DecMod(i:Word):Word;
begin
DecMod:=(i+MaxLine-1) mod MaxLine;
end;
Procedure RefreshScreen;
var CleanLine: Str255;
i,j: Word;
begin
i:=FirstCirInd;
j:=1;
TextBackground(ColListBG);
TextColor(ColListFG);
ClrScr;
repeat
GotoXY(1,j);
write(Image[i]);
i:=IncMod(i);
inc(j);
until i=FirstCirInd;
DispSelLine;
end;
Procedure FirstScreen;
var CleanLine: Str255;
i: Integer;
LineOK: Boolean;
begin
FirstCirInd:=0;
Read1stLine(FrontCst);
CleanLine:=CleanString(CurLine[FrontCst]);
Image[FirstCirInd]:=CleanLine;
TextBackground(ColListBG);
TextColor(ColListFG);
GotoXY(1,FirstCirInd+1);
write(CleanLine);
FirstCirInd:=IncMod(FirstCirInd);
repeat
LineOK:=ReadNextLine(FrontCst);
CleanLine:=CleanString(CurLine[FrontCst]);
Image[FirstCirInd]:=CleanLine;
GotoXY(1,FirstCirInd+1);
write(CleanLine);
FirstCirInd:=IncMod(FirstCirInd);
until (FirstCirInd=0) or (LineOK=FALSE);
Read1stLine(BackCst);
SelCirInd:=0;
SelAbsInd:=0;
ScrInd:=0;
DispSelLine;
end;
Function ScrollUp:Boolean;
var IsScrolled: Boolean;
Dummy: Boolean;
CleanLine: Str255;
begin
IsScrolled:=ReadNextLine(FrontCst);
if IsScrolled then
begin
CleanLine:=CleanString(CurLine[FrontCst]);
Image[FirstCirInd]:=CleanLine;
FirstCirInd:=IncMod(FirstCirInd);
TextBackground(ColListBG);
TextColor(ColListFG);
GotoXY(1,1);
DelLine;
GotoXY(1,MaxLine);
write(CleanLine);
Dummy:=ReadNextLine(BackCst);
end;
ScrollUp:=IsScrolled;
end;
Function ScrollDn:Boolean;
var IsScrolled: Boolean;
Dummy: Boolean;
CleanLine: Str255;
begin
IsScrolled:=ReadPrevLine(BackCst);
if IsScrolled then
begin
CleanLine:=CleanString(CurLine[BackCst]);
FirstCirInd:=DecMod(FirstCirInd);
Image[FirstCirInd]:=CleanLine;
TextBackground(ColListBG);
TextColor(ColListFG);
GotoXY(1,1);
InsLine;
GotoXY(1,1);
write(CleanLine);
Dummy:=ReadPrevLine(FrontCst);
end;
ScrollDn:=IsScrolled;
end;
Function DnArrow:Boolean;
Var Success: Boolean;
begin
window(VWUX,VWUY,VWLX+1,VWLY);
UndispSelLine;
Success:=TRUE;
If IncMod(SelCirInd)=FirstCirInd then
begin
Success:=ScrollUp;
If Success then
begin
SelCirInd:=IncMod(SelCirInd);
inc(SelAbsInd);
end
else;
end
else
begin
SelCirInd:=IncMod(SelCirInd);
inc(SelAbsInd);
inc(ScrInd);
end;
DnArrow:=Success;
DispSelLine;
end;
Function UpArrow:Boolean;
Var Success: Boolean;
begin
window(VWUX,VWUY,VWLX+1,VWLY);
UndispSelLine;
Success:=TRUE;
If SelCirInd=FirstCirInd then
begin
Success:=ScrollDn;
If Success then
begin
SelCirInd:=DecMod(SelCirInd);
Dec(SelAbsInd);
end
else;
end
else
begin
SelCirInd:=DecMod(SelCirInd);
dec(SelAbsInd);
dec(ScrInd);
end;
UpArrow:=Success;
DispSelLine;
end;
Function PgUp:Boolean;
Var Complete,Dummy: Boolean;
i: Word;
CleanLine: Str255;
begin
window(VWUX,VWUY,VWLX+1,VWLY);
i:=MaxLine;
repeat
Complete:=ReadPrevLine(BackCst);
If Complete then
begin
CleanLine:=CleanString(CurLine[BackCst]);
FirstCirInd:=DecMod(FirstCirInd);
Image[FirstCirInd]:=CleanLine;
SelCirInd:=DecMod(SelCirInd);
Dec(SelAbsInd);
Dec(i);
Dummy:=ReadPrevLine(FrontCst);
end;
until (i=0) or (Complete=FALSE);
RefreshScreen;
end;
Function PgDn:Boolean;
Var Complete,Dummy: Boolean;
i: Word;
CleanLine: Str255;
begin
window(VWUX,VWUY,VWLX+1,VWLY);
i:=MaxLine;
repeat
Complete:=ReadNextLine(FrontCst);
If Complete then
begin
CleanLine:=CleanString(CurLine[FrontCst]);
Image[FirstCirInd]:=CleanLine;
FirstCirInd:=IncMod(FirstCirInd);
SelCirInd:=IncMod(SelCirInd);
inc(SelAbsInd);
Dec(i);
Dummy:=ReadNextLine(BackCst);
end;
until (i=0) or (Complete=FALSE);
RefreshScreen;
end;
Procedure InitFB(FN:str255;WUX,WUY,WLX,WLY,BC,FC,SBC,SFC:Word);
begin
FileName:=FN;
ColListBG:=BC;
ColListFG:=FC;
ColSListBG:=SBC;
ColSListFG:=SFC;
VWUX:=WUX;
VWUY:=WUY;
VWLX:=WLX;
VWLY:=WLY;
MaxLine:=1+WLY-WUY;
Initialize;
FirstScreen;
end;
{------------------- END OF FILE BROWSER MODULE ---------------------------}
{
The following program shows a way to use the File Browser. It displays
its own source code (!!) and handles the arrows and PgUp PgDn keys.
The current line number and current line content are displayed on the
bottom line.
Be sure to place THIS source code (filebrws.pas) in the directory from
which you run this program!
Press q to quit.
}
begin
ClrScr;
InitFB('filebrws.pas',1,1,70,20,Black,LightGray,LightGray,Black);
repeat
Ch:=WaitKey;
if ExtKey then
begin
if Ch=#80 then Dummy:=DnArrow;
if Ch=#72 then Dummy:=UpArrow;
if Ch=#73 then Dummy:=PgUp;
if Ch=#81 then Dummy:=PgDn;
window(1,25,80,25);
TextBackground(ColListBG);
TextColor(ColListFG);
write(SelAbsInd);
write(':');
write(Image[SelCirInd]);
end;
until (ExtKey=FALSE) and (Ch='q');
CloseFB;
end.
[Back to TEXTFILE SWAG index] [Back to Main SWAG index] [Original]