返回
{***************************************************************}
{*** FVision Unit Version1.0 ***}
{*** 蓝蚂蚁工作室 ***}
{***************************************************************}
{*** 编辑器单元 ***}
{***************************************************************}
{$O+,F+,X+,I-}
Unit FEdit;
Interface
Uses
Dos,FXmsDrv,Graph,FGraph,FView,FWrite,FTool,
FMouse,FEvent,FDialog,FControl,FExtDrv;
Const
edHScroll = $0001;
edVScroll = $0002;
edViewerPos = $0004;
edProgress = $0008;
edBroad = $0010;
edUseXms = $0020;
Const
edTxtColor :Byte=$9E;
edSigColor :Byte=$F1;
edMakColor :Byte=$04;
Const
fiSearch = $01;
fiReplace = $02;
Type
PInsStatus=^TInsStatus;
TInsStatus=Object(TView)
Constructor Init;
Procedure Paint;virtual;
Procedure UpDate;virtual;
end;
PViewerPos=^TViewerPos;
TViewerPos=object(TView)
PosX,PosY:Integer;
ModifyFlag:Boolean;
Constructor Init(X,Y,PX,PY:Integer);
Procedure Paint;virtual;
Procedure Draw;virtual;
Procedure Modify(M:Boolean;PX,PY:Integer);
end;
ViewLine=record
Str:StringStrLong;
Col:ColType;
end;
ViewType=array[1..1]of ViewLine;
PLineItem = ^TLineItem;
TLineItem = record
Next : PLineItem;
Str : Stringstrlong;
end;
PViewer = ^TViewer;
TViewer = object(TView)
Style:Word;
HScrollBar: PScrollBar;
VScrollBar: PScrollBar;
ViewPos: PViewerPos;
Progress: PProgressBar;
Head:PLineItem;
View:^ViewType;
XmsHandle:Word;
Width,Height,LineNum,OldLineNum,
StaLine,TotLine:Integer;
Pos,Mark:TPoint;
TColor,SColor,MColor:Byte;
FileName:PathStr;
ModifyFlag,CtrlkFlag,ReplaceFlag:Boolean;
SPos,EPos:TPoint;
CurPos,EndPos,CurMark:Integer;
FindMode:Byte;
Constructor Init(R:TRect;St:Word);
Destructor Done;virtual;
Procedure InsertScroll(H,V:PScrollBar);
Procedure DeleteScroll;
Procedure MoveTo(X,Y:Integer);virtual;
Procedure ChangeBroad(X,Y:Integer);virtual;
Procedure Paint;virtual;
Procedure Draw;virtual;
Procedure DrawLine(Num:Integer);virtual;
Procedure DrawMark;
Procedure SetView;virtual;
Procedure SetViewLine(Num:Integer);virtual;
Procedure SetViewColor(Num:Integer);virtual;
Procedure SetScroll;
Function MoveMark(Shift:Boolean;X,Y:Integer):Boolean;
Function MoveView(Shift,Chk:Boolean;X,Y:Integer):Boolean;
Procedure HandleMouse(var Event:TEvent);
Procedure HandleEvent(var Event:TEvent);virtual;
Procedure InitBuf;
Procedure InitLine;
Procedure FreeBuf;
Procedure FreeLine;
Function InsertLine(Num:Integer;Str:string):Boolean;
Function DeleteLine(Num:Integer):Boolean;
Function Insert(Str:string):Boolean;
Function GetLine(Num:Integer):string;
Procedure ModifyLine(Num:Integer;Str:string);
Procedure DeleteBlock;
Procedure LoadFromXms;
Procedure StoreToXms;
Procedure LoadFromFile(Name:PathStr);
Procedure ConvTab(var S:string);
Procedure SaveFile;
Procedure SaveToFile(Name:PathStr);
Procedure ProCtrlKB;
Procedure ProCtrlKK;
Function ProShift(Shift:Boolean;X,Y:Integer):Boolean;
Procedure CopyToClip(var P:PViewer);
Procedure PasteFromClip(var P:PViewer);
Function MsgDlg(T,S:string;Sty:Word):Boolean;
Function RunView(V:PView;Event:TEvent):Boolean;
Function Search(Mode:Byte):Boolean;
Function Find(Mode:Byte):Boolean;
Function SearchAgain:Boolean;
Procedure ReplaceAll;
end;
PEditor = ^TEditor;
TEditor = object(TViewer)
CanEdit:Boolean;
Constructor Init(R:TRect;St:Word);
Procedure CloseSelf;virtual;
Procedure HandleEvent(var Event:TEvent);virtual;
Procedure ProChar(Ch:Char);
Procedure ProEnter;
Procedure ProDel;
Procedure ProBackSpace;
Procedure ProCtrlKC;
Procedure ProCtrlKV;
Procedure ProPaste;
Procedure ProCut;
end;
PFileViewer=^TFileViewer;
TFileViewer=object(TWindow)
Viewer:PViewer;
Constructor Init(R:TRect;Name:string);
Procedure LoadFromFile(Name:PathStr);
end;
PFileEditor=^TFileEditor;
TFileEditor=object(TWindow)
Editor:PEditor;
Constructor Init(R:TRect;Name:string);
Procedure SaveToFile(Name:PathStr);
Procedure SaveFile;
Procedure LoadFromFile(Name:PathStr);
end;
var
InsStatus:PInsStatus;
Function FindWin:PWindow;
Function ReplaceWin:PWindow;
Function GotoLineWin(var L:Integer):PWindow;
Function SetupEditEnv:PWindow;
Function SetEditColor:PWindow;
Implementation
Const
NormalXmsSize = 300;
MaxLine = 30000;
BufLine = 500;
MaxBufLine = 800;
Const
fiForward = $01;
fiBackward = $02;
fiCursor = $01;
fiEntire = $02;
FindStr :string='';
ReplaceStr :string='';
fiSensitive :Boolean=False;
fiWholeWord :Boolean=False;
fiScope :Boolean=False;
fiPrompt :Boolean=True;
fiDirection :Byte=$01;
fiOrigin :Byte=$01;
HangTailFlag :Boolean=False;
BackFile :Boolean=True;
AutoIndent :Boolean=True;
DelTailSpace :Boolean=True;
ConvertTab :Boolean=True;
InsertMode :Boolean=True;
OldInsertMode:Boolean=False;
Const
WordChars: set of Char=['0'..'9', 'A'..'Z', '_', 'a'..'z',#$A1..#$F4];
InsStr:array [False..True] of string[4]=('改写','插入');
ClipViewer:PViewer=nil;
Constructor TInsStatus.Init;
begin
Inherited Init;
AssignRect(Broad,GetMaxx-49,GetMaxy-22,GetMaxx,GetMaxy);
InsertMode:=(GetShiftState and kbInsState)<>0;
OldInsertMode:=InsertMode;
end;
Procedure TInsStatus.Paint;
begin
HideMouse;
SignBroad(Broad.a.x,Broad.a.y,Broad.b.x,Broad.b.y,1);
SignBroad(Broad.a.x+4,Broad.a.y+2,Broad.b.x-4,Broad.b.y-2,0);
WritecMap(Broad.a.x+9,Broad.a.y+3,InsStr[InsertMode],0,10);
ShowMouse;
end;
Procedure TInsStatus.UpDate;
begin
InsertMode:=(GetShiftState and kbInsState)<>0;
if InsertMode<>OldInsertMode then
begin
Paint;
OldInsertMode:=InsertMode;
end;
end;
Constructor TViewerPos.Init;
begin
Inherited Init;
Size.X:=90;
Size.Y:=17;
MoveTo(X,Y);
PosX:=PX;
PosY:=PY;
end;
Procedure TViewerPos.Paint;
begin
HideMouse;
SignBroadc(Broad.A.X,Broad.A.Y,Broad.B.X,Broad.B.Y,0,$0A);
Draw;
end;
Procedure TViewerPos.Draw;
var
Str:string[12];
begin
HideMouse;
Str:=IntStr(PosX);
InsSpaceFront(Str,5);
Str:=Str+':'+IntStr(PosY);
InsSpace(Str,10);
if ModifyFlag then Str[10]:='*';
Writec16(Origin.X div 8 +1,Origin.Y+1,Str,$A4);
ShowMouse;
end;
Procedure TViewerPos.Modify;
begin
if (PX=PosX)and(PY=PosY)and(ModifyFlag=M) then Exit;
PosX:=PX;
PosY:=PY;
ModifyFlag:=M;
Draw;
end;
Constructor TViewer.Init;
var
T:TRect;
begin
Inherited Init;
GrowMode:=gfGrowHiX or gfGrowHiY;
Style:=St;
Size.X:=R.b.x*8;
Size.Y:=R.b.y*16;
HScrollBar:=nil;
VScrollBar:=nil;
ViewPos:=nil;
XmsHandle:=0;
Progress:=New(PProgressBar,Init(R.A.X,R.A.Y+Size.Y+2,90,17,pbBroad+pbSaveBack));
if (Style and edViewerPos)<>0 then
ViewPos:=New(PViewerPos,Init(R.A.X,R.A.Y+Size.Y+2,1,1));
if (Style and edViewerPos)<>0 then
AssignRect(T,R.a.x+100,R.a.y+Size.Y+2,Size.X-100,15)
else
AssignRect(T,R.a.x,R.a.y+Size.Y+2,Size.X,15);
if ((Style and edHScroll)<>0) and (HScrollBar=nil) then
HScrollBar:=New(PScrollBar,Init(sbHor,T,0));
AssignRect(T,R.a.x+Size.X+2,R.a.y,15,Size.Y);
if ((Style and edVScroll)<>0) and (VScrollBar=nil) then
VScrollBar:=New(PScrollBar,Init(sbVer,T,0));
MoveTo(R.a.x,R.a.y);
Width:=R.b.x;
Height:=R.b.y;
GetMem(View,SizeOf(ViewType)*Height);
FileName:='';
TColor:=edTxtColor;
SColor:=edSigColor;
MColor:=edMakColor;
InitBuf;
ModifyFlag:=False;
CtrlkFlag:=False;
CurPos:=1;
EndPos:=0;
FindMode:=fiSearch;
end;
Destructor TViewer.Done;
begin
FreeBuf;
FreeMem(View,SizeOf(ViewType)*Height);
DeleteScroll;
if ViewPos<>nil then Dispose(ViewPos,Done);
Dispose(Progress,Done);
Inherited Done;
end;
Procedure TViewer.InsertScroll;
begin
DeleteScroll;
HScrollBar:=H;
VScrollBar:=V;
end;
Procedure TViewer.DeleteScroll;
begin
if HScrollBar<>nil then Dispose(HScrollBar,Done);
if VScrollBar<>nil then Dispose(VScrollBar,Done);
HScrollBar:=nil;
VScrollBar:=nil;
end;
Procedure TViewer.MoveTo;
begin
X:=X div 8 *8;
Inherited MoveTo(X,Y);
if HScrollBar<>nil then
begin
if (Style and edViewerPos)<>0 then
HScrollBar^.MoveTo(X+100,Y+Size.Y+2)
else
HScrollBar^.MoveTo(X,Y+Size.Y+2);
end;
if VScrollBar<>nil then VScrollBar^.MoveTo(X+Size.X+2,Y);
if ViewPos<>nil then ViewPos^.MoveTo(X,Y+Size.Y+2);
Progress^.MoveTo(X,Y+Size.Y+2);
end;
Procedure TViewer.ChangeBroad;
var
TW,TH:Integer;
begin
Inherited ChangeBroad(X,Y);
if (Size.X=Width*8)and(Size.Y=Height*16) then Exit;
FreeMem(View,SizeOf(ViewType)*Height);
TW:=Width;TH:=Height;
Width:=Size.X div 8;
Height:=Size.Y div 16;
Size.X:=Width*8;
Size.Y:=Height*16;
if HScrollBar<>nil then HScrollBar^.ChangeBroad((Width-TW)*8,(Height-TH)*16);
if VScrollBar<>nil then VScrollBar^.ChangeBroad((Width-TW)*8,(Height-TH)*16);
MoveTo(Origin.X,Origin.Y);
GetMem(View,SizeOf(ViewType)*Height);
if Mark.X>Width then Mark.X:=Width;
if Mark.Y>Height then Mark.Y:=Height;
end;
Procedure TViewer.Paint;
begin
HideMouse;
if (Style and edBroad)<>0 then
SignBroad(Broad.A.X-1,Broad.A.Y-1,Broad.B.X,Broad.B.Y,0);
if HScrollBar<>nil then HScrollBar^.Paint;
if VScrollBar<>nil then VScrollBar^.Paint;
if ViewPos<>nil then ViewPos^.Paint;
HideMouse;
Draw;
end;
Procedure TViewer.Draw;
var
Str:string;
i:Integer;
begin
SetView;
if MouIn(Broad) then HideMouse;
for i:=1 to Height do
begin
Str:=View^[i].Str;
if HangTailFlag then
begin
View^[i].Col[Length(Str)+1]:=$97;
if Pos.Y+i<LineNum then
Str:=Str+#17
else if Pos.Y+i=LineNum then
Str:=Str+#10;
end;
InsSpace(Str,StrLong);
CWrite16(Origin.X div 8,Origin.Y+(i-1)*16,Pos.x+1,Width,Str,View^[i].Col);
end;
DrawMark;
SetScroll;
ShowMouse;
ClearKbBuf;
end;
Procedure TViewer.DrawLine;
var
Str:string;
begin
SetViewLine(Num);
HideMouse;
Str:=View^[Num].Str;
if HangTailFlag then
begin
View^[Num].Col[Length(Str)+1]:=$97;
if Pos.Y+Num<LineNum then
Str:=Str+#17
else if Pos.Y+Num=LineNum then
Str:=Str+#10;
end;
InsSpace(Str,StrLong);
CWrite16(Origin.X div 8,Origin.Y+(Num-1)*16,Pos.x+1,Width,Str,View^[Num].Col);
if Mark.Y=Num then DrawMark;
if ViewPos<>nil then
ViewPos^.Modify(ModifyFlag,StaLine+Pos.Y+Mark.Y,Pos.X+Mark.X);
ShowMouse;
end;
Procedure TViewer.DrawMark;
begin
HideMouse;
SetWriteMode(1);
SetColor(MColor);
SetLineStyle(0,0,1);
PutPixel(0,0,0);
Line(Origin.X+(Mark.X-1)*8,Origin.Y+Mark.Y*16-2,
Origin.X+Mark.X*8-1,Origin.Y+Mark.Y*16-2);
Line(Origin.X+(Mark.X-1)*8,Origin.Y+Mark.Y*16-1,
Origin.X+Mark.X*8-1,Origin.Y+Mark.Y*16-1);
SetWriteMode(0);
ShowMouse;
end;
Procedure TViewer.SetView;
var
Temp:PLineItem;
i:Integer;
begin
Temp:=Head;
for i:=1 to Pos.y do
Temp:=Temp^.Next;
for i:=1 to Height do
begin
if Temp=nil then
View^[i].Str:=''
else
begin
View^[i].Str:=Temp^.Str;
Temp:=Temp^.Next;
end;
SetViewColor(i);
end;
end;
Procedure TViewer.SetViewLine;
var
Temp:PLineItem;
i:Integer;
begin
Temp:=Head;
for i:=1 to Pos.y+Num-1 do
if Temp<>nil then
Temp:=Temp^.Next;
if Temp=nil then
View^[Num].Str:=''
else
View^[Num].Str:=Temp^.Str;
SetViewColor(Num);
end;
Procedure TViewer.SetViewColor;
var
Temp1,Temp2:Integer;
begin
FillChar(View^[Num].Col[1],StrLong,TColor);
if (Pos.Y+Num<SPos.Y)or(Pos.Y+Num>EPos.Y) then Exit;
if Pos.Y+Num>SPos.Y then
Temp1:=1
else
Temp1:=SPos.X;
if Pos.Y+Num<EPos.Y then
Temp2:=StrLong+1
else if EPos.X<=Length(View^[Num].Str) then
Temp2:=EPos.X
else
Temp2:=Length(View^[Num].Str)+1;
Dec(Temp2,Temp1);
if Temp2<0 then Temp2:=0;
FillChar(View^[Num].Col[Temp1],Temp2,SColor);
end;
Procedure TViewer.SetScroll;
begin
if HScrollBar<>nil then
HScrollBar^.NewPos(Pos.X/(StrLong-Width));
if VScrollBar<>nil then
begin
if TotLine>Height then
VScrollBar^.NewPos((StaLine+Pos.Y)/(TotLine-Height))
else VScrollBar^.NewPos(0);
end;
if ViewPos<>nil then
ViewPos^.Modify(ModifyFlag,StaLine+Pos.Y+Mark.Y,Pos.X+Mark.X);
end;
Function TViewer.MoveMark;
var
TempY1,TempY2:Integer;
begin
MoveMark:=False;
if (X=Mark.X) and (Y=Mark.Y) then Exit;
if (X<1)or(X>Width)or(Y<1)or(Y>Height) then Exit;
MoveMark:=True;
DrawMark;
TempY1:=SPos.Y;
TempY2:=EPos.Y;
if ProShift(Shift,Pos.X+X,Pos.Y+Y) then
begin
Mark.X:=X;
if (Mark.Y=Y)and(TempY1=SPos.Y)and(TempY2=EPos.Y) then
DrawLine(Mark.Y)
else begin
Mark.Y:=Y;
Draw;
end;
end else
begin
Mark.X:=X;
Mark.Y:=Y;
DrawMark;
end;
if ViewPos<>nil then
ViewPos^.Modify(ModifyFlag,StaLine+Pos.Y+Mark.Y,Pos.X+Mark.X);
end;
Function TViewer.MoveView;
var
TPos,TMark:TPoint;
Temp:Integer;
begin
MoveView:=False;
TPos:=Pos;
TMark:=Mark;
if (Y<0)and(StaLine>0) then
begin
StoreToXms;
Temp:=BufLine div 2 -Y;
if StaLine<Temp then Temp:=StaLine;
Dec(StaLine,Temp);
LoadFromXms;
Pos:=TPos;Mark:=TMark;
Dec(Pos.Y,Temp);
Inc(Y,Temp);
end else
if (Y>LineNum-Height)and(StaLine+LineNum<TotLine) then
begin
if Y+StaLine>=TotLine then Y:=TotLine-StaLine-1;
StoreToXms;
Temp:=Y-LineNum+Height+BufLine div 2;
if TotLine-StaLine<Temp then Temp:=TotLine-StaLine;
Inc(StaLine,Temp);
LoadFromXms;
Pos:=TPos;Mark:=TMark;
Inc(Pos.Y,Temp);
Dec(Y,Temp);
end else
if LineNum>MaxBufLine then
begin
StoreToXms;
Temp:=Y-BufLine div 2;
if StaLine+Temp<0 then Temp:=-StaLine;
Inc(StaLine,Temp);
LoadFromXms;
Pos:=TPos;Mark:=TMark;
Dec(Pos.Y,Temp);
Dec(Y,Temp);
end;
if Chk then
begin
if (X=Pos.X) and (Y=Pos.Y) then Exit;
if (X<0) or (Y<0) or (X>StrLong-Width) then Exit;
if (LineNum>=Height)and(Y>LineNum-Height)and(Y>Pos.Y) then Exit;
if (LineNum<Height)and(Y<>0)and(Y>Pos.Y) then Exit;
ProShift(Shift,X+Mark.X,Y+Mark.Y);
end;
Pos.X:=X;
Pos.Y:=Y;
Draw;
MoveView:=True;
end;
Procedure TViewer.HandleMouse;
begin
repeat
ClearEvent(Event);
GetEvent(Event);
if (Event.Buttons=mbLeftButton) and
((Event.What=evMouseMove) or (Event.What=evMouseAuto)) then
begin
if IsIn(Event.Where,Broad) then
MoveMark(True,(Event.Where.X-Broad.A.X) div 8+1,(Event.Where.Y-Broad.A.Y) div 16+1)
else if Event.Where.Y<Broad.A.Y then
begin
if not MoveMark(True,Mark.X,Mark.Y-1) then
MoveView(True,True,Pos.X,Pos.Y-1);
end else if Event.Where.Y>Broad.B.Y then
begin
if not MoveMark(True,Mark.X,Mark.Y+1) then
MoveView(True,True,Pos.X,Pos.Y+1);
end else if Event.Where.X<Broad.A.X then
begin
if not MoveMark(True,Mark.X-1,Mark.Y) then
MoveView(True,True,Pos.X-1,Pos.Y);
end else if Event.Where.X>Broad.B.X then
begin
if not MoveMark(True,Mark.X+1,Mark.Y) then
MoveView(True,True,Pos.X+1,Pos.Y);
end;
end;
until (Event.What=evMouseUp);
end;
Procedure TViewer.HandleEvent;
begin
if HScrollBar<>nil then HScrollBar^.HandleEvent(Event);
if VScrollBar<>nil then VScrollBar^.HandleEvent(Event);
case Event.What of
evCommand:if (not (Event.Command in [cmGotoLine,cmSearch,cmSearchAgain]))
and (Event.InfoPtr<>HScrollBar) and (Event.InfoPtr<>VScrollBar)
and (Event.Index<>HScrollBar) and (Event.Index<>VScrollBar) then
Exit
else
case Event.Command of
cmLeft: if not MoveMark(False,Mark.X-1,Mark.Y) then
MoveView(False,True,Pos.X-1,Pos.Y);
cmRight:if not MoveMark(False,Mark.X+1,Mark.Y) then
MoveView(False,True,Pos.X+1,Pos.Y);
cmUp: if not MoveMark(False,Mark.X,Mark.Y-1) then
MoveView(False,True,Pos.X,Pos.Y-1);
cmDown: if not MoveMark(False,Mark.X,Mark.Y+1) then
MoveView(False,True,Pos.X,Pos.Y+1);
cmInterHor:MoveView(False,True,Round(Event.InfoReal*(StrLong-Width)),Pos.Y);
cmInterVer:MoveView(False,True,Pos.X,Round(Event.InfoReal*(TotLine-Height))-StaLine);
cmHome:begin
MoveMark(False,1,Mark.Y);
MoveView(False,True,0,Pos.Y);
end;
cmEnd: if not MoveMark(False,Length(View^[Mark.y].Str)+1,Mark.Y) then
begin
MoveMark(False,Width,Mark.Y);
if Length(View^[Mark.y].Str)=StrLong then
MoveView(False,True,StrLong-Width,Pos.Y)
else
MoveView(False,True,Length(View^[Mark.y].Str)-Width+1,Pos.Y);
end;
cmPgUp:if not MoveView(False,True,Pos.X,Pos.Y-Height+1) then
MoveView(False,True,Pos.X,0);
cmPgDn:if not MoveView(False,True,Pos.X,Pos.Y+Height-1) then
MoveView(False,True,Pos.X,LineNum-Height);
cmCtrlPgUp:begin
MoveMark(False,1,1);
MoveView(False,True,0,-StaLine);
end;
cmCtrlPgDn:begin
MoveView(False,True,Pos.X,TotLine-StaLine-Height);
if Mark.Y<Height then
MoveMark(False,Mark.X,LineNum-Pos.Y);
end;
cmGotoLine:begin
MoveView(False,True,Pos.X,Integer(Event.InfoPtr^)-StaLine-1);
MoveMark(False,Mark.X,1);
end;
cmSearch:if RunView(FindWin,Event) then Find(fiSearch);
cmSearchAgain:SearchAgain;
else Exit;
end;
evKeyDown:case Event.KeyCode of
kbCtrlK:if not CtrlkFlag then
CtrlkFlag:=True
else
ProCtrlKK;
kbCtrlH:if CtrlkFlag then
begin
EPos:=SPos;
CtrlkFlag:=False;
Draw;
end;
kbCtrlB:if CtrlkFlag then ProCtrlKB;
else Exit;
end;
evMouseDown:if (Event.Buttons=mbLeftButton) and IsIn(Event.Where,Broad) then
begin
if MoveMark(False,(Event.Where.X-Broad.A.X) div 8+1,(Event.Where.Y-Broad.A.Y) div 16+1) then
begin
SPos.X:=Pos.X+Mark.X;
SPos.Y:=Pos.Y+Mark.Y;
EPos:=SPos;
MoveView(False,False,Pos.X,Pos.Y);
end;
end else Exit;
evMouseMove:if (Event.Buttons=mbLeftButton) and IsIn(Event.Where,Broad) then
HandleMouse(Event)
else Exit;
else Exit;
end;
ClearEvent(Event);
end;
Procedure TViewer.InitBuf;
begin
InitLine;
XmsHandle:=0;
StaLine:=0;
TotLine:=0;
end;
Procedure TViewer.InitLine;
begin
Head:=nil;
LineNum:=0;
OldLineNum:=0;
Pos.X:=0;
Pos.Y:=0;
Mark.X:=1;
Mark.Y:=1;
SPos.X:=1;
SPos.Y:=1;
EPos.X:=1;
EPos.Y:=1;
end;
Procedure TViewer.FreeBuf;
begin
if XmsHandle<>0 then
FreeXms(XmsHandle);
FreeLine;
InitBuf;
end;
Procedure TViewer.FreeLine;
var
Temp:PLineItem;
begin
if Head=nil then Exit;
Temp:=Head;
while Temp<>nil do
begin
Head:=Temp^.Next;
Dispose(Temp);
Temp:=Head;
end;
InitLine;
end;
Function TViewer.InsertLine;
var
Temp,Temp1,Temp2:PLineItem;
i:Integer;
begin
InsertLine:=False;
if (Num>1)and(Num>LineNum) then Exit;
New(Temp);
if Temp=nil then Exit;
InsertLine:=True;
Temp^.Str:=Str;
Temp^.Next:=nil;
Inc(LineNum);
Inc(TotLine);
if Head=nil then
begin
Head:=Temp;
Exit;
end;
if Num=0 then
begin
Temp^.Next:=Head;
Head:=Temp;
Exit;
end;
Temp1:=Head;
for i:=1 to Num-1 do
if Temp1<>nil then
Temp1:=Temp1^.Next;
Temp2:=Temp1^.Next;
Temp1^.Next:=Temp;
Temp^.Next:=Temp2;
ModifyFlag:=True;
end;
Function TViewer.DeleteLine;
var
Temp,Temp1:PLineItem;
i:Integer;
begin
DeleteLine:=True;
if (Head=nil)or(Num>LineNum) then Exit;
DeleteLine:=True;
Dec(LineNum);
Dec(TotLine);
Temp:=Head;
if Num=1 then
begin
Head:=Head^.Next;
Dispose(Temp);
Exit;
end;
for i:=1 to Num-2 do
Temp:=Temp^.Next;
Temp1:=Temp^.Next;
Temp^.Next:=Temp1^.Next;
Dispose(Temp1);
ModifyFlag:=True;
end;
Function TViewer.Insert;
begin
Insert:=InsertLine(LineNum,Str);
end;
Function TViewer.GetLine;
var
Temp:PLineItem;
i:Integer;
begin
GetLine:='';
if (Head=nil)or(Num>LineNum) then Exit;
Temp:=Head;
for i:=1 to Num-1 do
if Temp<>nil then
Temp:=Temp^.Next;
if Temp<>nil then
GetLine:=Temp^.Str;
end;
Procedure TViewer.ModifyLine;
var
Temp:PLineItem;
i:Integer;
begin
if (Head=nil)or(Num>LineNum) then Exit;
Temp:=Head;
for i:=1 to Num-1 do
Temp:=Temp^.Next;
Temp^.Str:=Str;
ModifyFlag:=True;
end;
Procedure TViewer.DeleteBlock;
var
Str1,Str2:string;
i:Integer;
begin
if (SPos.Y>EPos.Y) or ((SPos.Y=EPos.Y)and(SPos.X>=EPos.X)) then Exit;
Str1:=GetLine(SPos.Y);
Str1:=System.Copy(Str1,1,SPos.X-1);
Str2:=GetLine(EPos.Y);
System.Delete(Str2,1,EPos.X-1);
Str1:=Str1+Str2;
for i:=SPos.Y to EPos.Y do
DeleteLine(SPos.Y);
InsertLine(SPos.Y-1,Str1);
EPos:=SPos;
if (SPos.Y>Pos.Y)and(SPos.Y<=Pos.Y+Height) then
Mark.Y:=SPos.Y-Pos.Y
else begin
Pos.Y:=SPos.Y - Height div 2;
if Pos.Y<0 then Pos.Y:=0;
Mark.Y:=SPos.Y-Pos.Y;
end;
Mark.X:=SPos.X-Pos.X;
if Mark.X<1 then
begin
Pos.X:=0;
Mark.X:=SPos.X;
if Mark.X>Width then Mark.X:=1;
end else
if Mark.X>Width then Mark.X:=1;
MoveView(False,False,Pos.X,Pos.Y);
CtrlkFlag:=False;
end;
Procedure TViewer.LoadFromXms;
var
Str:string;
i,Num,TempTot:Integer;
TempModify:Boolean;
begin
if XmsHandle=0 then Exit;
Num:=BufLine;
if TotLine-StaLine<BufLine then
Num:=TotLine-StaLine;
TempModify:=ModifyFlag;
TempTot:=TotLine;
FreeLine;
for i:=1 to Num do
begin
MoveXms(@Str[0],0,Pointer(Longint(StaLine+i-1)*Longint(StrLong+1)),XmsHandle,StrLong+1);
Insert(Str);
end;
TotLine:=TempTot;
OldLineNum:=LineNum;
ModifyFlag:=TempModify;
end;
Procedure TViewer.StoreToXms;
var
Str:string;
i:Integer;
begin
if (XmsHandle=0)or(Head=nil) then Exit;
if OldLineNum>LineNum then
MoveXms(Pointer(Longint(StaLine+LineNum)*Longint(StrLong+1)),XmsHandle,
Pointer(Longint(StaLine+OldLineNum)*Longint(StrLong+1)),XmsHandle,
Longint(TotLine-StaLine-LineNum)*Longint(StrLong+1))
else if OldLineNum<LineNum then
for i:=TotLine-1 downto StaLine+LineNum do
MoveXms(Pointer(Longint(i)*Longint(StrLong+1)),XmsHandle,
Pointer(Longint(i-LineNum+OldLineNum)*Longint(StrLong+1)),XmsHandle,StrLong+1);
for i:=1 to LineNum do
begin
Str:=GetLine(i);
MoveXms(Pointer(Longint(StaLine+i-1)*Longint(StrLong+1)),XmsHandle,@Str[0],0,StrLong+1);
end;
end;
Procedure TViewer.LoadFromFile;
var
Fp1:File;
Fp:Text;
Str,St:string;
i,Result,XSize:Integer;
NoErr:Boolean;
begin
if not Exist_Fi(Name) then Exit;
Result:=IOResult;
Assign(Fp1,Name);
Reset(Fp1,1);
XSize:=FileSize(Fp1) div 350;
Result:=IOResult;
Assign(Fp,Name);
Reset(Fp);
NoErr:=True;
if IOResult<>0 then NoErr:=False;
Inc(XSize,NormalXmsSize);
if GetXmsSize<XSize then Exit;
FreeBuf;
if (Style and edUseXms)<>0 then
XmsHandle:=MallocXms(XSize);
if (Style and edProgress)<>0 then
begin
Progress^.Loc:=0;
Progress^.Paint;
end;
while (not Eof(Fp)) and NoErr and (TotLine<MaxLine) do
begin
Readln(Fp,Str);
St:='';
for i:=1 to Length(Str) do
if Str[i]=#9 then
InsSpace(St,Length(St)+8-(Length(St) mod 8))
else
St:=St+Str[i];
if (Style and edUseXms)<>0 then
begin
MoveXms(Pointer(Longint(TotLine)*Longint(StrLong+1)),XmsHandle,@St[0],0,StrLong+1);
Inc(TotLine);
end else
NoErr:=Insert(Copy(St,1,StrLong));
if (Style and edProgress)<>0 then
Progress^.Modify(TotLine/8/(XSize-NormalXmsSize+1));
end;
Close(Fp);
FileName:=Name;
LoadFromXms;
ModifyFlag:=False;
if (Style and edProgress)<>0 then Progress^.Hide;
end;
Procedure TViewer.ConvTab;
var
Po:Integer;
begin
while System.Pos(' ',S)>0 do
begin
Po:=System.Pos(' ',S);
System.Delete(S,Po,7);
S[Po]:=#9;
end;
end;
Procedure TViewer.SaveFile;
begin
SaveToFile(FileName);
end;
Procedure TViewer.SaveToFile;
var
Fp:Text;
Temp:PLineItem;
Str:string;
i,Result:Integer;
begin
if Name='' then Exit;
if BackFile then
ReNameFile(Name,Ch_Name(Name,'BAK'));
Result:=IOResult;
Assign(Fp,Name);
ReWrite(Fp);
if IOResult<>0 then Exit;
StoreToXms;
if (Style and edProgress)<>0 then
begin
Progress^.Loc:=0;
Progress^.Paint;
end;
if XmsHandle<>0 then
begin
for i:=0 to TotLine-1 do
begin
MoveXms(@Str[0],0,Pointer(Longint(i)*Longint(StrLong+1)),XmsHandle,StrLong+1);
if ConvertTab then ConvTab(Str);
Writeln(Fp,Str);
if (Style and edProgress)<>0 then
Progress^.Modify((i+1)/TotLine);
end;
end else
begin
i:=0;
Temp:=Head;
while Temp<>nil do
begin
Str:=Temp^.Str;
if DelTailSpace then DelSpaceTail(Str);
if ConvertTab then ConvTab(Str);
Writeln(Fp,Str);
Temp:=Temp^.Next;
Inc(i);
if (Style and edProgress)<>0 then
Progress^.Modify(i/LineNum);
end;
end;
Close(Fp);
FileName:=Name;
ModifyFlag:=False;
if (Style and edProgress)<>0 then Progress^.Hide;
end;
Procedure TViewer.ProCtrlKB;
begin
SPos.X:=Pos.X+Mark.X;
SPos.Y:=Pos.Y+Mark.Y;
Draw;
CtrlkFlag:=False;
end;
Procedure TViewer.ProCtrlKK;
begin
EPos.X:=Pos.X+Mark.X;
EPos.Y:=Pos.Y+Mark.Y;
Draw;
CtrlkFlag:=False;
end;
Function TViewer.ProShift;
var
TempX,TempY:Integer;
begin
ProShift:=False;
if (not Shift) and (not ShiftPush) then Exit;
if Y>LineNum then Y:=LineNum;
TempX:=Pos.X+Mark.X;
TempY:=Pos.Y+Mark.Y;
if TempY>LineNum then TempY:=LineNum;
if (SPos.X=TempX)and(SPos.Y=TempY) then
begin
SPos.X:=X;
SPos.Y:=Y;
end else
if (EPos.X=TempX)and(EPos.Y=TempY) then
begin
EPos.X:=X;
EPos.Y:=Y;
end else
begin
SPos.X:=X;
SPos.Y:=Y;
EPos.X:=TempX;
EPos.Y:=TempY;
end;
if (SPos.Y>EPos.Y) or ((SPos.Y=EPos.Y)and(SPos.X>EPos.X)) then
begin
SwapInt(SPos.X,EPos.X);
SwapInt(SPos.Y,EPos.Y);
end;
ProShift:=True;
end;
Procedure TViewer.CopyToClip;
var
R:TRect;
Str1,Str2:string;
i:Integer;
begin
if (SPos.Y>EPos.Y) or ((SPos.Y=EPos.Y)and(SPos.X>=EPos.X)) then Exit;
AssignRect(R,0,0,0,0);
if P=nil then P:=New(PViewer,Init(R,0));
P^.FreeLine;
Str1:=GetLine(SPos.Y);
System.Delete(Str1,1,SPos.X-1);
Str2:=GetLine(EPos.Y);
Str2:=System.Copy(Str2,1,EPos.X-1);
if SPos.Y=EPos.Y then
P^.Insert(System.Copy(Str1,1,EPos.X-SPos.X))
else
for i:=SPos.Y to EPos.Y do
begin
if i=SPos.Y then
P^.Insert(Str1)
else if i=EPos.Y then
P^.Insert(Str2)
else
P^.Insert(GetLine(i));
end;
end;
Procedure TViewer.PasteFromClip;
var
Str1,Str2:string;
i:Integer;
begin
if (P=nil)or(P^.LineNum=0) then Exit;
if Pos.Y+Mark.Y>LineNum then
begin
for i:=LineNum+1 to Pos.Y+Mark.Y do
Insert('');
end;
Str1:=GetLine(Pos.Y+Mark.Y);
Str1:=System.Copy(Str1,1,Pos.X+Mark.X-1);
InsSpace(Str1,Pos.X+Mark.X-1);
Str2:=GetLine(Pos.Y+Mark.Y);
System.Delete(Str2,1,Pos.X+Mark.X-1);
if P^.LineNum=1 then
ModifyLine(Pos.Y+Mark.Y,Str1+P^.GetLine(1)+Str2)
else
for i:=1 to P^.LineNum do
begin
if i=1 then
ModifyLine(Pos.Y+Mark.Y,Str1+P^.GetLine(i))
else if i=P^.LineNum then
InsertLine(Pos.Y+Mark.Y+i-2,P^.GetLine(i)+Str2)
else
InsertLine(Pos.Y+Mark.Y+i-2,P^.GetLine(i));
end;
SPos.X:=Pos.X+Mark.X;
SPos.Y:=Pos.Y+Mark.Y;
EPos.Y:=SPos.Y+P^.LineNum-1;
if SPos.Y=EPos.Y then
EPos.X:=SPos.X+Length(P^.GetLine(1))
else
EPos.X:=Length(P^.GetLine(P^.LineNum))+1;
end;
Function TViewer.MsgDlg;
var
Dlg:PMsgDialog;
begin
Dlg:=New(PMsgDialog,Init(T,S,Sty));
Dlg^.Owner:=@Self;
Dlg^.Paint;
Dlg^.Run(Event);
Dispose(Dlg,Done);
MsgDlg:=(Event.Command=cmYes) or (Event.Command=cmOk);
ReplaceFlag:=True;
if Event.Command=cmCancel then
ReplaceFlag:=False;
end;
Function TViewer.RunView;
begin
RunView:=False;
V^.Owner:=@Self;
V^.Paint;
V^.Run(Event);
Dispose(V,Done);
if (Event.Command<>cmOk) and (Event.Command<>cmYes) then Exit;
RunView:=True;
ReplaceFlag:=False;
if Event.Command=cmYes then
ReplaceFlag:=True;
end;
Function TViewer.Search;
var
i,P,Dlt:Integer;
Str,Str1:string;
Dlg:PMsgDialog;
begin
Search:=False;
i:=CurPos;
repeat
if CtrlBreakHit then Exit;
MoveXms(@Str[0],0,Pointer(Longint(i-1)*Longint(StrLong+1)),XmsHandle,StrLong+1);
Str1:=Str;
System.Delete(Str,1,CurMark);
if fiSensitive then
P:=System.Pos(FindStr,Str)
else
P:=System.Pos(Upcases(FindStr),Upcases(Str));
if P<>0 then
begin
if (not fiWholeWord) or
not (((P>1) and (Str[P-1] in WordChars)) or
((P+System.Length(FindStr)<=System.Length(Str)) and
(Str[P+System.Length(FindStr)] in WordChars))) then
begin
Search:=True;
CurPos:=i;
Dlt:=Height div 2;
if TotLine-CurPos<=Dlt then Dlt:=TotLine-CurPos+1;
if CurPos<Dlt then Dlt:=CurPos;
if (CurPos-StaLine-Pos.Y<1)or(CurPos-StaLine-Pos.Y>Height) then
MoveView(False,True,Pos.X,CurPos-StaLine-Dlt);
SPos.X:=CurMark+P;SPos.Y:=CurPos-StaLine;
EPos.X:=CurMark+P+Length(FindStr);EPos.Y:=SPos.Y;
Pos.X:=0;
if CurMark+P+Length(FindStr)>Width then
Pos.X:=CurMark+P+Length(FindStr)-Width;
Mark.X:=SPos.X-Pos.X;
if Mark.X<1 then Mark.X:=1;
Mark.Y:=CurPos-StaLine-Pos.Y;
MoveView(False,False,Pos.X,Pos.Y);
if Mode=fiReplace then
begin
if fiPrompt and (not MsgDlg('替换字串',' 是否替换此字串? ',
mbYesNo+mbQuestion)) then
begin
Inc(CurMark,P+Length(FindStr)-1);
if not ReplaceFlag then
CtrlBreakHit:=True;
Exit;
end;
System.Delete(Str1,CurMark+P,System.Length(FindStr));
System.Insert(ReplaceStr,Str1,CurMark+P);
ModifyLine(Pos.Y+Mark.Y,Str1);
DrawLine(Mark.Y);
end;
Inc(CurMark,P+Length(FindStr)-1);
Exit;
end;
end;
CurMark:=0;
case fiDirection of
fiForward:Inc(i);
fiBackWard:Dec(i);
end;
until ((fiDirection=fiForward)and(i>=EndPos)) or
((fiDirection=fiBackward)and(i<=EndPos));
end;
Function TViewer.Find;
begin
Find:=False;
if (TotLine=0) or (FindStr='') then Exit;
StoreToXms;
case fiOrigin of
fiCursor:begin CurPos:=StaLine+Pos.Y+Mark.Y;CurMark:=Pos.X+Mark.X-1; end;
fiEntire:begin CurPos:=1;CurMark:=0; end;
end;
EndPos:=TotLine;
if fiScope then
begin
CurPos:=StaLine+SPos.Y;
EndPos:=StaLine+EPos.Y;
end;
if CurPos>EndPos then Exit;
if fiDirection=fiBackward then SwapInt(CurPos,EndPos);
Find:=Search(Mode);
FindMode:=Mode;
end;
Function TViewer.SearchAgain;
begin
SearchAgain:=False;
if (TotLine=0) or (FindStr='') then Exit;
if ((fiDirection=fiForward)and(CurPos>EndPos)) or
((fiDirection=fiBackward)and(CurPos<EndPos)) then Exit;
if Search(FindMode) then
SearchAgain:=True
else
MsgDlg('错误','已无可匹配字串!',mbOkOnly+mbInformation);
end;
Procedure TViewer.ReplaceAll;
begin
Find(fiReplace);
while (not CtrlBreakHit) and SearchAgain do;
StoreToXms;
CtrlBreakHit:=False;
end;
Constructor TEditor.Init;
begin
Inherited Init(R,St);
CanEdit:=True;
end;
Procedure TEditor.CloseSelf;
var
P:PView;
begin
if ModifyFlag then
begin
P:=New(PMsgDialog,Init('保存文件',
'文件"'+FileName+'"已改动'+#13',是否要保存?',mbYesNo));
P^.Owner:=@Self;
P^.Paint;
P^.Run(Event);
Dispose(P,Done);
if Event.Command=cmYes then
SaveFile
else if Event.Command=cmCancel then
SureToCloseWin:=False;
end;
end;
Procedure TEditor.HandleEvent;
begin
Inherited HandleEvent(Event);
if not CanEdit then Exit;
case Event.What of
evCommand:case Event.Command of
cmCopy:CopyToClip(ClipViewer);
cmPaste:ProPaste;
cmClear:DeleteBlock;
cmCut:ProCut;
cmReplace:if RunView(ReplaceWin,Event) then
begin
if ReplaceFlag then
ReplaceAll
else
Find(fiReplace);
end;
else Exit;
end;
evKeyDown:if Event.CMark then
begin
ProChar(Char(Hi(Event.KeyCode)));
ProChar(Char(Lo(Event.KeyCode)));
end else
case Event.KeyCode of
kbEnter:begin
ProEnter;
Event.What:=evCommand;
Event.Command:=cmEnterPress;
Exit;
end;
kbDel:ProDel;
kbBack:ProBackSpace;
kbCtrlC:if CtrlkFlag then ProCtrlKC;
kbCtrlV:if CtrlkFlag then ProCtrlKV;
kbCtrlY:if not CtrlkFlag then
begin
if DeleteLine(Pos.Y+Mark.Y) then
begin
Mark.X:=1;
MoveView(False,False,0,Pos.Y);
end;
end else
DeleteBlock;
else case Event.CharCode of
#32..#255:ProChar(Event.CharCode);
else Exit;
end;
end;
else Exit;
end;
ClearEvent(Event);
end;
Procedure TEditor.ProChar;
var
Str:string;
Dlt:Integer;
i:Integer;
begin
if Pos.X+Mark.X>=StrLong then Exit;
if Pos.Y+Mark.Y>LineNum then
begin
for i:=LineNum+1 to Pos.Y+Mark.Y do
Insert('');
end;
Str:=GetLine(Pos.Y+Mark.Y);
if Length(Str)>=StrLong then Exit;
if Pos.X+Mark.X>Length(Str) then
begin
InsSpace(Str,Pos.X+Mark.X-1);
Str:=Str+Ch;
end else
begin
if InsertMode then
System.Insert(Ch,Str,Pos.X+Mark.X)
else
Str[Pos.X+Mark.X]:=Ch;
end;
ModifyLine(Pos.Y+Mark.Y,Str);
if Mark.X=Width then
begin
Dlt:=10;
if StrLong-Width-Pos.X<Dlt then
Dlt:=StrLong-Width-Pos.X;
Dec(Mark.X,Dlt-1);
MoveView(False,True,Pos.X+Dlt,Pos.Y);
end else
begin
Inc(Mark.X);
DrawLine(Mark.Y);
end;
end;
Procedure TEditor.ProEnter;
var
Str,Str1:string;
TempPos:TPoint;
i:Integer;
begin
if Pos.Y+Mark.Y>LineNum then
begin
for i:=LineNum+1 to Pos.Y+Mark.Y do
Insert('');
Exit;
end;
Str:=GetLine(Pos.Y+Mark.Y);
Str1:=Copy(Str,Pos.X+Mark.X,Length(Str)-Pos.X-Mark.X+1);
if AutoIndent then
begin
i:=0;
while (i<Length(Str)) and (Str[i+1]=' ') do Inc(i);
InsSpaceFront(Str1,i+Length(Str1));
end;
ModifyLine(Pos.Y+Mark.Y,Copy(Str,1,Pos.X+Mark.X-1));
InsertLine(Pos.Y+Mark.Y,Str1);
TempPos.X:=0;
TempPos.Y:=Pos.Y;
if i>=Width then TempPos.X:=i-Width+10;
if Mark.Y=Height then TempPos.Y:=Pos.Y+1;
Mark.X:=i+1-TempPos.X;
Inc(Mark.Y);
if Mark.Y>Height then Mark.Y:=Height;
MoveView(False,False,TempPos.X,TempPos.Y);
end;
Procedure TEditor.ProDel;
var
Str,Str1:string;
begin
if Pos.Y+Mark.Y>LineNum then Exit;
Str:=GetLine(Pos.Y+Mark.Y);
if Pos.X+Mark.X<=Length(Str) then
begin
System.Delete(Str,Pos.x+Mark.X,1);
ModifyLine(Pos.Y+Mark.Y,Str);
DrawLine(Mark.Y);
end else
if Pos.Y+Mark.Y<LineNum then
begin
Str1:=GetLine(Pos.Y+Mark.Y+1);
InsSpace(Str,Pos.X+Mark.X-1);
Str:=Str+Str1;
ModifyLine(Pos.Y+Mark.Y,Str);
DeleteLine(Pos.Y+Mark.Y+1);
MoveView(False,False,Pos.X,Pos.Y);
end;
end;
Procedure TEditor.ProBackSpace;
var
Str,Str1:string;
Temp:Integer;
begin
if Pos.Y+Mark.Y>LineNum then Exit;
Str:=GetLine(Pos.Y+Mark.Y);
if Pos.X+Mark.X>Length(Str)+1 then
begin
if not MoveMark(False,Mark.X-1,Mark.Y) then
MoveView(False,True,Pos.X-1,Pos.Y);
Exit;
end else
if Pos.X+Mark.X>1 then
begin
System.Delete(Str,Pos.X+Mark.X-1,1);
ModifyLine(Pos.Y+Mark.Y,Str);
if Mark.X>1 then
begin
Dec(Mark.X);
DrawLine(Mark.Y);
end else
begin
Temp:=Pos.X-10;
if Temp<0 then Temp:=0;
Mark.X:=Pos.X+Mark.X-Temp-1;
MoveView(False,True,Temp,Pos.Y);
end;
end else
if Pos.Y+Mark.Y>1 then
begin
Str1:=GetLine(Pos.Y+Mark.Y-1);
Temp:=Length(Str1);
Str1:=Str1+Str;
ModifyLine(Pos.Y+Mark.Y-1,Str1);
DeleteLine(Pos.Y+Mark.Y);
if Mark.Y>1 then
Dec(Mark.Y)
else
Dec(Pos.Y);
if Temp<Width then
Pos.X:=0
else
Pos.X:=Temp-Width+1;
Mark.X:=Temp-Pos.X+1;
MoveView(False,False,Pos.X,Pos.Y);
end;
end;
Procedure TEditor.ProCtrlKC;
begin
CopyToClip(ClipViewer);
PasteFromClip(ClipViewer);
MoveView(False,False,Pos.X,Pos.Y);
CtrlkFlag:=False;
end;
Procedure TEditor.ProCtrlKV;
begin
CopyToClip(ClipViewer);
DeleteBlock;
PasteFromClip(ClipViewer);
MoveView(False,False,Pos.X,Pos.Y);
CtrlkFlag:=False;
end;
Procedure TEditor.ProPaste;
begin
PasteFromClip(ClipViewer);
MoveView(False,False,Pos.X,Pos.Y);
end;
Procedure TEditor.ProCut;
begin
CopyToClip(ClipViewer);
DeleteBlock;
end;
Constructor TFileViewer.Init;
var
T:TRect;
begin
R.A.X:=R.A.X div 8 * 8;
T.A:=R.A;
T.B.X:=T.A.X+R.B.X*8+31;
T.B.Y:=T.A.Y+R.B.Y*16+53;
Inherited Init(T,Name,True);
Option:=Option or opAligen8 or opResize;
GrowDlt.X:=8;
GrowDlt.Y:=16;
Inc(R.A.X,8);
Inc(R.A.Y,29);
Viewer:=New(PViewer,Init(R,edHScroll+edVScroll+edBroad
+edViewerPos+edProgress+edUseXms));
Viewer^.LoadFromFile(Name);
Insert(Viewer);
end;
Procedure TFileViewer.LoadFromFile;
begin
if not Exist_Fi(Name) then Exit;
ModifyTitle(Name);
Viewer^.LoadFromFile(Name);
ModifyTitle(Viewer^.FileName);
Viewer^.Draw;
end;
Constructor TFileEditor.Init;
var
T:TRect;
begin
R.A.X:=R.A.X div 8 * 8;
T.A:=R.A;
T.B.X:=T.A.X+R.B.X*8+31;
T.B.Y:=T.A.Y+R.B.Y*16+53;
Inherited Init(T,Name,True);
Option:=Option or opAligen8 or opResize;
GrowDlt.X:=8;
GrowDlt.Y:=16;
Inc(R.A.X,8);
Inc(R.A.Y,29);
Editor:=New(PEditor,Init(R,edHScroll+edVScroll+edBroad
+edViewerPos+edProgress+edUseXms));
Editor^.LoadFromFile(Name);
Insert(Editor);
end;
Procedure TFileEditor.SaveToFile;
begin
Editor^.SaveToFile(Name);
ModifyTitle(Editor^.FileName);
end;
Procedure TFileEditor.SaveFile;
begin
Editor^.SaveFile;
end;
Procedure TFileEditor.LoadFromFile;
begin
if not Exist_Fi(Name) then Exit;
ModifyTitle(Name);
Editor^.LoadFromFile(Name);
ModifyTitle(Editor^.FileName);
Editor^.Draw;
end;
{----------------------------------------------}
Function FindWin:PWindow;
var
R:TRect;
P:PWindow;
Inp:PInput;
Chk:PCheckBox;
Rad:PRadioButton;
begin
AssignRect(R, 0, 0, 350, 180);
P:=New(PWindow,Init(R,'查找字符串',True));
P^.Insert(New(PStaticText,Init(stNormal,20,30,'待查字串:',0)));
Inp:=New(PInput,init(100,30,FindStr,28,ipBroad));
P^.Insert(Inp);
Chk:=New(PCheckBox,Init(20,60,160,140,'设置:'));
Chk^.Insert('分辨大小写',fiSensitive);
Chk^.Insert('整个字串匹配',fiWholeword);
Chk^.Insert('查找选择区',fiScope);
P^.Insert(Chk);
Rad:=New(PRadioButton,Init(170,60,330,95,'方向:',fiDirection));
Rad^.Insert('顺序');
Rad^.Insert('倒序');
P^.Insert(Rad);
Rad:=New(PRadioButton,Init(170,105,330,140,'起点:',fiOrigin));
Rad^.Insert('光标');
Rad^.Insert('文件头');
P^.Insert(Rad);
P^.Insert(New(PButton,Init(130 ,150,190,170,'确定',kbAlto,cmOk)));
P^.Insert(New(PButton,Init(200 ,150,260,170,'放弃',kbAltc,cmCancel)));
P^.Insert(New(PButton,Init(270 ,150,330,170,'帮助',kbF1,cmHelp)));
P^.Next;
P^.Next;
P^.Center;
FindWin:=P;
end;
Function ReplaceWin:PWindow;
var
R:TRect;
P:PWindow;
Inp:PInput;
Chk:PCheckBox;
Rad:PRadioButton;
begin
AssignRect(R, 0, 0, 350, 215);
P:=New(PWindow,Init(R,'替换字符串',True));
P^.Insert(New(PStaticText,Init(stNormal,20,30,'原字串:',0)));
Inp:=New(PInput,init(90,30,FindStr,30,ipBroad));
P^.Insert(Inp);
P^.Insert(New(PStaticText,Init(stNormal,20,55,'新字串:',0)));
Inp:=New(PInput,init(90,55,ReplaceStr,30,ipBroad));
P^.Insert(Inp);
Chk:=New(PCheckBox,Init(20,85,160,175,'设置:'));
Chk^.Insert('分辨大小写',fiSensitive);
Chk^.Insert('整个字串匹配',fiWholeword);
Chk^.Insert('替换时提示',fiPrompt);
Chk^.Insert('查找选择区',fiScope);
P^.Insert(Chk);
Rad:=New(PRadioButton,Init(170,85,330,120,'方向:',fiDirection));
Rad^.Insert('顺序');
Rad^.Insert('倒序');
P^.Insert(Rad);
Rad:=New(PRadioButton,Init(170,140,330,175,'起点:',fiOrigin));
Rad^.Insert('光标');
Rad^.Insert('文件头');
P^.Insert(Rad);
P^.Insert(New(PButton,Init(30 ,185,120,205,'替换全部',kbAltA,cmYes)));
P^.Insert(New(PButton,Init(130 ,185,190,205,'确定',kbAltO,cmOk)));
P^.Insert(New(PButton,Init(200 ,185,260,205,'放弃',kbAltC,cmCancel)));
P^.Insert(New(PButton,Init(270 ,185,330,205,'帮助',kbF1,cmHelp)));
P^.Next;
P^.Next;
P^.Center;
ReplaceWin:=P;
end;
Function GotoLineWin(var L:Integer):PWindow;
var
R:TRect;
P:PWindow;
begin
AssignRect(R, 0, 0, 260, 100);
P:=New(PWindow,Init(R,'跳转至特定行',True));
P^.Insert(New(PStaticText,Init(stNormal,20,45,'行号:',4)));
P^.Insert(New(PDigInput,Init(65,45,@L,12,ipBroad+ipDigital,dtInteger)));
P^.Insert(New(PButton,Init(180, 40,240, 60,'确定',kbAltO,cmOk)));
P^.Insert(New(PButton,Init(180, 70,240, 90,'放弃',kbAltC,cmCancel)));
P^.Next;
P^.Next;
P^.Center;
GotoLineWin:=P;
end;
Function SetupEditEnv:PWindow;
var
R:TRect;
P:PWindow;
Q:PCheckBox;
begin
AssignRect(R,0,0,340,180);
P:=New(PWindow,Init(R,'设置编辑器环境',True));
Q:=New(PCheckBox,Init(20,40,320,110,'编辑器选项:'));
Q^.Insert('创建后备文件',BackFile);
Q^.Insert('自动缩进模式',AutoIndent);
Q^.Insert('删除行尾空格',DelTailSpace);
Q^.Insert('显示行尾标志',HangTailFlag);
Q^.Insert('生成制表符',ConvertTab);
P^.Insert(Q);
P^.Insert(New(PButton,Init(120,140,180,160,'确定',0,cmOk)));
P^.Insert(New(PButton,Init(190,140,250,160,'放弃',0,cmCancel)));
P^.Insert(New(PButton,Init(260,140,320,160,'帮助',kbF1,cmHelp)));
P^.Next;
P^.Center;
SetupEditEnv:=P;
end;
Function SetEditColor:PWindow;
var
P:PSetColorWin;
begin
P:=New(PSetColorWin,Init('设置颜色',10));
P^.InsertColor('正常文字颜色',edTxtColor,scFront+scBack);
P^.InsertColor('选择文字颜色',edSigColor,scFront+scBack);
P^.InsertColor('光标颜色',edMakColor,scFront);
SetEditColor:=P;
end;
end.