tslediter/designer/utslcodeeditor.tsf

8706 lines
304 KiB
Plaintext

unit UtslCodeEditor;
{
编辑器相关的代码20220217修改
}
interface
uses cstructurelib,tslvcl,UTslmemo,UTslSynMemo;
{
1. page标签
TPagees; TPageItem
2. TMemoPages ,TMemoPageItem
3. TEchoWnd
4. TFindResultWnd
5. FindStringWnd 查找框
5. TGotoLineWnd 跳转
}
function tdbgcallback(); //调试回调
function gettslexe();
type TPageItem=class //标签项
function Create(AOwner);
begin
FCaption := "";
FOwner := AOwner;
end
function Recycling();virtual;
begin
FBitmapA := nil;
FBitmapB := nil;
Tag := nil;
end
published
property Caption read FCaption write SetCaption;
property BitmapA read FBitmapA write SetBitmapA;
property BitmapB read FBitmapB write SetBitmapB;
tag;
Rect;
protected
function SetCaption(s);
begin
if s and ifstring(s)then
begin
FCaption := s;
if FOwner then FOwner.ItemCaptionChenged(self);
end
end
private
function SetBitmapA(Bmp);
begin
if FBitmapA <> Bmp then
begin
FBitmapA := Bmp;
if FOwner then FOwner.ItemBitmapAChenged(self);
end
end
function SetBitmapB(Bmp);
begin
if FBitmapB <> Bmp then
begin
FBitmapB := Bmp;
if FOwner then FOwner.ItemBitmapBChenged(self);
end
end
FBitmapB;
FBitmapA;
FCaption;
FOwner;
end
type TPage=class(TCustomControl) //标签
function Create(AOwner)
begin
Inherited;
FCloseBtn := false;
FPageItems := new TMyarrayB();
FMultiLine := 1;
FLineHeight := 16; //font.Height+6;
FLines := 0;
FItemIndex :=-1;
FWill_Drag := true;
font := array("height":16,"width":8,"escapement":0,"orientation":0,"weight":400,"italic":0,"underline":0,"strikeout":0,
"charset":0,"outprecision":0,"clipprecision":0,"quality":1,"pitchandfamily":1,"facename":"Courier New","color":0);
end
function GetPageRect(); //获得标签区域
begin
GetClientRect();
return FPageRect;
end
function PosInCurrentItemSection(xy); //点击部分
begin
if not FCurrentITem then return 0;
rc := FCurrentItem.Rect;
if not rc then return 0;
rc1 := rc;
rc1[2]:= rc1[0]+20;
if PointInrect(xy,rc1)then return 1;
rc1 := rc;
rc1[0]:= rc[2]-20;
if PointInrect(xy,rc1)then return 3;
if PointInRect(xy,rc)then return 2;
end
function DoControlAlign();override;
begin
CalcPageItemRect();
end
function CreateApageItem();virtual;
begin
return new TPageItem(self);
end
function itemcaptionchenged(it);
begin
if GetItemIndex(it)>= 0 then
begin
DoControlAlign();
InValidateRect(nil,false);
end
end
function ItemBitmapAChenged(it);
begin
if GetItemIndex(it)>= 0 then InValidateRect(it.Rect,false);
end
function ItemBitmapBChenged(it);
begin
if GetItemIndex(it)>= 0 then InValidateRect(it.Rect,false);
end
function FontChanged();override;
begin
FLineHeight := font.Height+6;
DoControlAlign();
end
function IncPaintLock();
begin
BeginUpdate();
end
function DecPaintLock();
begin
EndUpdate();
end
function DoEndUpDate();override;
begin
DoControlAlign();
inherited;
end
function GetClientRect();override;
begin
r := inherited;
FPageRect := R;
r[1]+= FLineHeight * FLines; //FLabelsheight;
FPageRect[3]:= r[1];
return r;
end
function Paint();override;
begin
dc := Canvas;
ps := PAINTSTRUCT().rcPaint;
//dc.Pen.Color := rgb(180,180,100);
dc.Pen.Color := rgb(250,250,250);
dc.Pen.Width := 1;
dc.font := font;
for i := 0 to FPageItems.Length()-1 do
begin
it := FPageitems[i];
rc := it.Rect;
if not rc then continue;
if Intersectrect(it.Rect,ps)then
begin
if FItemIndex=i then
begin
//dc.Brush.Color := rgb(244,205,205);
dc.Brush.Color := 0xFa901E;
end else
begin
dc.Brush.Color := rgb(238,238,228) //rgb(244,244,244);
end
dc.draw("roundrect",array(rc[0:1],rc[2:3],array(5,5)));
if it.BitmapB then
begin
rc1 := rc;
rc1[0]:= rc[2]-20;
rc1[2]-= 2;
rc1[1]+= 4;
rc1[3]-= 4;
dc.Stretchdraw(rc1,it.BitmapB);
end
if it.BitmapA then
begin
rc1 := rc;
rc1[2]:= rc1[0]+20;
rc1[0]+= 2;
rc1[2]-= 2;
rc1[1]+= 2;
rc1[3]-= 2;
dc.Stretchdraw(rc1,it.BitmapA);
end
rc[0]+= 20;
dc.DrawText(it.caption,rc,DT_nOPREFIX .| DT_LEFT .| DT_SINGLELINE .| DT_VCENTER);
end
end
if FCloseBtn and((FPageItems.Length()>0))then
begin
Closebmp();
rc := ClientRect;
FBmpClose.Draw(dc,rc[2]-25,3,SRCAND);
//rc := ClientRect;
//rc := array(rc[2]-25,1,rc[2]-1,19);
//dc.Stretchdraw(rc,FBmpClose);
end
end
function SetSel(it);
begin
idx := GetItemIndex(it);
if idx >= 0 and idx <> FItemIndex then
begin
ItemIndex := idx;
end
end
function CloseAllItem(it);
begin
FItemINdex :=-1;
FCurrentITem := nil;
saveit := nil;
for i,v in FPageItems.Data do
begin
if v=it then
begin
saveit := it;
continue;
end
end
FPageItems.Splice(0,FPageItems.Length());
if saveit then
begin
FItemINdex := 0;
FCurrentITem := it;
FPageItems.push(it);
end
//InValidateRect(nil,false);
DoControlAlign();
InValidateRect(nil,false);
end
function DeleteItemByIndex(idx);virtual;
begin
if idx >= 0 and idx<FPageItems.length()then
begin
if idx=FItemIndex then
begin
if CallSelChanging()then return;
end
FPageItems.Splice(idx,1);
CalcPageItemRect();
if idx=FItemIndex then
begin
FItemIndex :=-1;
FCurrentItem := nil;
ItemIndex := max(min(FPageItems.length()-1,idx),0);
if FItemINdex=-1 then
begin
CallSelChanged();
end
end
InValidateRect(nil,false);
end
end
function MouseDragDo(o,e); //移动拖拉
begin
if FIs_Draging then
begin
if GetItemIndexByPos(e.pos)=itemIndex then
begin
FNot_DragLive := true;
_wapi.ImageList_DragLeave(self.Handle);
end else
begin
nxy := clienttowindow(e.xpos,e.ypos);
if FNot_DragLive then
begin
_wapi.ImageList_DragEnter(self.Handle,nxy[0],nxy[1]);
FNot_DragLive := false;
end
_wapi.ImageList_DragMove(nxy[0],nxy[1]);
end
end
end
function MouseMove(o,e);override;
begin
MouseDragDo(o,e);
inherited;
end
function MouseDrageLeave(); //离开移动
begin
if FIs_Draging then
begin
FNot_DragLive := false;
_wapi.ImageList_DragLeave(self.Handle);
_wapi.ImageList_EndDrag();
FWill_Drag := true;
FIs_Draging := false;
_wapi.clipcursor(0);
end
end
function MouseUp(o,e);override;
begin
if e.button=mbLeft then
begin
if FIs_Draging then
begin
MouseDrageLeave();
idx := GetItemIndexByPos(e.pos);
IF idx >= 0 and FItemIndex <> idx then
begin
if FItemIndex<idx then
begin
for i := FItemIndex to idx-1 do
begin
FPageITems.SWap(i,i+1);
end
end else
begin
for i := FItemIndex downto idx+1 do
begin
FPageITems.SWap(i,i-1);
end
end
FItemIndex := idx;
DoControlAlign();
end
InvalidateRect(nil,false);
DecPaintLock();
end else
begin
if FCloseBtnClicked then //点击
begin
rc := ClientRect;
rc := array(rc[2]-25,1,rc[2]-1,19);
if PointInRect(e.pos,rc)then
begin
callDatafunction(FOnCloseClick,o,e);
end
end
end
end
return inherited;
end
function MouseDown(o,e);override;
begin
if e.button=mbMiddle then
begin
idx := GetItemIndexByPos(e.pos);
if idx>=0 then
begin
e._Tag := FPageitems[idx];
callDatafunction(fOnbmpbclick,o,e);
idx := GetItemIndex(FCurrentItem);
ItemIndex := idx;
return ;
end
end
if e.shiftdouble() then //处理新建
begin
idx := GetItemIndexByPos(e.pos);
if idx=-1 then
begin
callDatafunction(OnDblClick,o,e);
end
return ;
end
if e.button=mbLeft then
begin
cidx := posinitembmpb(e.pos);
if cidx>=0 then
begin
e._Tag := FPageitems[cidx];
callDatafunction(fOnbmpbclick,o,e);
idx := GetItemIndex(FCurrentItem);
ItemIndex := idx;
return ;
end
end
idx := GetItemIndexByPos(e.pos);
itemindex := idx;
FCloseBtnClicked := false;
if e.button=mbLeft and idx >= 0 then
begin
nxy := clienttowindow(e.xpos,e.ypos);
if FCanDraged and FWill_Drag then
begin
IncPaintLock();
FWill_Drag := false;
FIs_Draging := true;
CreateImageList();
_wapi.ImageList_BeginDrag(FDRageimglist,0,12,12);
FNot_DragLive := true;
//_wapi.ImageList_DragEnter(self.Handle,nxy[0],nxy[1]);
crect := GetPageRect();
ps := array(clienttoscreen(crect[0],crect[1]),clienttoscreen(crect[2],crect[3]));
_wapi.clipcursor(ps);
end
end else
begin
rc := ClientRect;
rc := array(rc[2]-25,1,rc[2]-1,19);
if PointInRect(e.pos,rc)then
begin
FCloseBtnClicked := true;
end
end
FCanDraged := true;
return inherited;
//if 3=PosInCurrentItemSection(e.pos) then FCurrentITem.Caption := datetimetostr(now());
end
FCanDraged; //修正提示导致修改后提示导致drage 体验问题
function PostInCloseRect(ps);
begin
rc := ClientRect;
rc := array(rc[2]-25,1,rc[2]-1,19);
return PointInRect(ps,rc);
end
function GetItemIndexByPos(xy);
begin
for i := 0 to FPageItems.Length()-1 do
begin
if PointInrect(xy,FPageItems[I].Rect)then return i;
end
return -1;
end
function posinitembmpb(xy);
begin
for i := 0 to FPageItems.Length()-1 do
begin
it := FPageItems[I];
if not it.BitmapB then continue ;
ri := it.Rect;
ri[0] := ri[2]-18;
ri[1]+=2;
ri[3]-=2;
ri[2]-=2;
if PointInrect(xy,ri)then return i;
end
return -1;
end
Function GetItemIndex(it);
begin
for i := 0 to FPageItems.length()-1 do
begin
if it=FPageitems[i]then
begin
return i;
end
end
return -1;
end
function Recycling();override;
begin
FPageItems.Splice(0,FPageItems.Length());
FOnSelChanged := nil;
FOnSelchanging := nil;
FCurrentItem := nil;
FItemIndex :=-1;
FOnCloseClick := nil;
fOnbmpbclick := nil;
inherited;
end
property CurrentItem read FCurrentItem;
property OnSelChanged read FOnSelChanged write FOnSelChanged;
property OnSelChanging read FOnSelChanging write FOnSelChanging;
property OnCloseClick read FOnCloseClick write FOnCloseClick;
property Onbmpbclick read FOnbmpbclick write fOnbmpbclick;
property MultiLine read FMultiLine write SetMultiLine;
property CloseBtn read FCloseBtn write SetCloseBtn;
property Lines read FLines;
property PageItems read FPageItems;
property ItemIndex read FItemIndex write SetItemIndex;
protected
function CallSelChanged();virtual;
begin
if not OnSelChanged then return false;
e := new tuieventbase();
callDatafunction(OnSelChanged,self(true),e);
end
function CallSelChanging();virtual;
begin
if not FOnSelchanging then return false;
e := new tuieventbase();
CallDatafunction(FOnSelchanging,self(true),e);
return e.skip;
end
function CalcPageItemRect();
begin
li := 0;
cw := Font.Width;
r := class(TCustomControl).ClientRect;
x := 0;
xct := 0;
for i := 0 to FPageitems.Length()-1 do
begin
it := FPageitems[i];
itwidth := length(it.Caption) * cw+40;
if xct>0 and(r[2]-(FCloseBtn?20:0))<x+itwidth then
begin
li++;
xct := 0;
x := 0;
end
it.Rect := array(x,li * FLineHeight,x+itwidth,(li+1) * FLineHeight);
x += itwidth;
xct++;
end
FLines := li+1;
//FPageRect := array(0,);
end
private
function CreateImageList();
begin
if not FDRageimglist then
begin
FImgs := new TCustomImageList(self);
FImgs.addbmp(MoveFileBmp());
FDRageimglist := FImgs.Handle;
end
end
FCloseBtnClicked; //点击
fOnbmpbclick;
FPageRect;
FIs_Draging;
FWill_Drag;
FNot_DragLive;
FDRageimglist;
FCloseBtn;
FBmpClose;
FPageItems;
FItemIndex;
FCurrentItem;
FMoveFileBmp;
function MoveFileBmp();
begin
if not FMoveFileBmp then
begin
FMoveFileBmp := new TBitmap();
s := "0502000000060400000074797065000203000000696D670006040000006461746
100022001000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000B549444154
5847ED93B10DC3201045D98231E859802D988211682929A1A3652E98E2223B582
1220DC28785C2979E849BFB4F982350851032853A8D404A09952DD0251063BC85
7A669780520A38E7430C0960B096C0E3BFA07E4823D433BB043058EB06F61A62D
025B0D71083B56E60AF21065D027B0D31F82F81631EA514186320840029E57C81
9CF379F6DE9FDF5AEBD2F6CE1481ABDC18539A3E4117B8CAADB5A5E53BE80207C
EB9D2D0A611B89B104299FE2B002F3C83B9B0E26C11600000000049454E44AE42
608200";
FMoveFileBmp.ReadVcon(HexformatStrToTsl(s));
end
return FMoveFileBmp;
end
function Closebmp();
begin
if not FBmpClose then
begin
FBmpClose := new TBitmap();
s := "0502000000060400000074797065000203000000696D670006040000006461746
100025601000089504E470D0A1A0A0000000D494844520000001C000000100806
00000005CF1FEF000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000EB49444154
484B63F88F03FC7DFCF0FFEF3327C9C6B8005E0BDF19A89285BFB637424DC1040
42DFC36B1FBFFD7E61A0C43D1F17B0BDDFF7FAE5DFEFFC1C789320B3F0679FEFF
73E7365E4BDF3B9881D57C9F3E09CCA7C84210865BDA5A0F1783E10F1E7628968
130C5168230CCD26F3D6D08B100370CCB40982A168230DCD2C9BD7036BA65204C
350B411866112ECB40983616DEBE497B0B9183F163A007381BD02C48B1C5D9072
F47AC96526C21CCB26FD326A2180CC21F5CAC302CA5C842B865FD9D7003D1F17B
5B63144B29B2105CB4B537A058800DBF37D7A14ED1460E26DB426CD50EB1183BF
8FF1F00B989BEC710621E4C0000000049454E44AE42608200";
FBmpClose.ReadVcon(HexformatStrToTsl(s));
end
return FBmpClose;
end
function SetCloseBtn(v);
begin
nv := v?true:false;
if nv <> FCloseBtn then
begin
FCloseBtn := nv;
DoControlAlign();
end
end
function SetItemIndex(idx);
begin
if idx >= 0 and idx<FPageItems.Length()and idx <> FItemIndex then
begin
if CallSelChanging()then return;
FItemIndex := idx;
FCurrentItem := FPageItems[idx];
InValidateRect(nil,false);
CallSelChanged();
end
end
FMultiLine;
FLineHeight;
FLines;
FOnSelChanged;
FOnCloseClick;
FOnSelchanging;
function SetMultiLine();
begin
end
end
type TEditerAuxiliary=class(TPage) //辅助窗口
function Create(AOwner);
begin
inherited;
Caption := "message:";
Ftimer := new TTimer(self);
Ftimer.Interval := 200;
Ftimer.Ontimer := thisfunction(BdownTimeOut);
Ftimer.Enabled := false;
//FEchoItem := CreateApageItem();
//FFileFindeItem := CreateApageItem();
OnSelChanged := thisfunction(OnSelChangedCall);
CloseBtn := true;
end
function WMNCLBUTTONDOWN(o,e):WM_NCLBUTTONDOWN;override;
begin
FIgnoreSize := true;
Ftimer.Enabled := true;
end
function BdownTimeOut(o,e);
begin
if(_wapi.GetAsyncKeyState(VK_LBUTTON).& 0xFF00)>0 then
begin
end else
begin
FIgnoreSize := false;
o.Enabled := false;
p := Parent;
if p then p.DoControlAlign();
end
end
{function MouseDown(o,e);override;
begin
if CloseBtn then
begin
rc := ClientRect;
rc := rc := array(rc[2]-25,1,rc[2]-1,19);
if PointInRect(e.pos,rc) then
begin
callDatafunction(FOnCloseClick,o,e);
end
end
inherited;
end }
//property OnCloseClick read FOnCloseClick write FOnCloseClick;
function DoControlAlign();override;
begin
if FIgnoreSize then
begin
end
inherited;
rc := ClientRect;
//单独处理linux的情况
{$ifdef linux}
rc[0]+= 2;
rc[2]-= 2;
rc[3]-= 2;
{$endif}
if CurrentItem then wnd := CurrentItem.Tag;
if wnd then wnd.SetBoundsRect(Rc);
end
function ShowPopUp();
begin
if not WSpOPUp then
begin
WSpOPUp := true;
Parent.DoControlAlign();
end
if not Visible then Visible := true;
end
function MouseDown(o,e);override;
begin
if e.shiftdouble()and e.button()=mbLeft then
begin
WSpOPUp := not WSpOPUp;
Parent.DoControlAlign();
if not WSpOPUp then
begin
_wapi.SetWindowPos(self.Handle,0,0,0,0,0,SWP_NOMOVE .| SWP_NOSIZE .| SWP_NOREDRAW .| SWP_NOSENDCHANGING);
end
end else
if GetItemIndexByPos(e.pos)>= 0 then
begin
inherited;
end else
if PostInCloseRect(e.pos)then
begin
//echo "------------\r\n";
inherited;
end else
begin
if WSpOPUp then _send_(WM_SYSCOMMAND,0xF012,0);
end
end
function Recycling();override;
begin
Ftimer := nil;
FEchoWnd := nil;
FFileFindWnd := nil;
FOnCloseClick := nil;
inherited;
//FOnCloseClick := nil;
end
function ShowByTag(tg); //显示
begin
its := Pageitems;
for i := 0 to its.Length()-1 do
begin
if its[i].tag=tg then
begin
ItemIndex := i;
//visible := true;
return;
end
end
end
function OnSelChangedCall(o,e);
begin
if not CurrentItem then Caption := "--";
rc := ClientRect;
its := PageItems;
for i := 0 to its.Length()-1 do
begin
it := its[i];
if CurrentItem=it then
begin
it.tag.SetboundsRect(rc);
it.tag.Visible := true;
caption := it.Tag.Caption;
end else
it.tag.Visible := false;
end
end
function AddWnd(wnd);
begin
if wnd is class(TWincontrol)then
begin
its := PageItems;
for i := 0 to its.Length()-1 do
begin
it := its[i];
if it.tag=wnd then return;
end
IncPaintLock();
it := CreateApAgeItem();
it.Caption := wnd.Caption;
it.tag := wnd;
wnd.visible := 0;
wnd.Parent := self;
PageItems.Push(it);
if PageItems.Length()=1 then
begin
itemIndex := 0;
end
DecPaintLock();
end
end
FEchoWnd;
FFileFindWnd;
FOnCloseClick;
private
Ftimer;
FIgnoreSize;
end
type TExecuteEditer=class(TCustomControl) //执行编辑器
Protected
Type TExecuteMemoComp=class(TSynCompletion)
function Create(AOwner);
begin
inherited;
IgnoreCase := false;
end
function PrepareCompletion(c);override; //获得数据
begin
//通过SetCompData 设置数据
if Not Memo then return;
d := array();
for i,v in array("FULL_CURRENT_PATH","CURRENT_DIRECTORY","SEARCH_PATH","TSL_EXE") do
begin
d[i,"caption"]:= v;
d[i,"value"]:= v;
d[i,"lvalue"]:= lowercase(v);
cl := length(v);
d[i,"clen"]:= cl;
d[i,"vlen"]:= cl;
end
SetCompData(d);
end
end
type TListBoxb=class(TListBOx)
function Create(AOwner);
begin
inherited;
end
function CheckListItem(it);override;
begin
return ifobj(it);
end
function GetItemText(i);override;
begin
it := GetItem(i);
if it then return it.FCaption;
return "";
end
function InsureItemVisible(idx); //移动当前的格子
begin
rc := GetIdxRect(idx);
c := ClientRect;
if rc[1]<c[1]then
begin
SetYpos(-1+GetYPos()+(rc[1]-c[1])/GetYScrollDelta());
end else
if rc[3]>c[3]then
begin
SetYpos(1+GetYPos()+(rc[3]-c[3]+1)/GetYScrollDelta());
end
end
function GetItemIndex();virtual;
begin
return inherited;
end
function SetItemIndex(idx);virtual;
begin
inherited;
FListBox.InsureItemVisible(idx);
end
end
type TComboBoxb=class(TCombobox)
function Create(AOwner);
begin
INherited;
end
function CreateAlist();override;
begin
return new TListBoxb(self);
end
end
type TCobItem=class
function Create(d);
begin
FCaption := "";
FExe := "";
if not ifarray(d)then return;
FCaption := d["caption"];
FExe := d["exe"];
end
FCaption;
FExe;
end
public
function showexeediter();
begin
FMemo.ExecuteCommand(FMemo.ecGotoXY,array(1,1));
FMemO.SetFocus();
show();
end
function Create(AOwner);
begin
inherited;
WSsYSMenu := true;
WsDlgModalFrame := true;
WsSizeBox := true;
WSpOPUp := true;
FItems := new TMyArrayB();
caption := "编辑 Execute.....";
SetBoundsRect(array(50,50,930,201));
FMemo := new TSynMemoNorm(self);
FMemo.OnKeyPress := function(o,e)
begin
if 13=e.charcode then
begin
e.skip := true;
doSaveCurrentName();
end
end
{FMemo.OnKeyDown := function(o,e)
begin
case e.charcode of
VK_DOWN:
begin
e.skip := true;
FChooser.ItemIndex += 1;
end
VK_UP:
begin
e.skip := true;
FChooser.ItemIndex -= 1;
end
end;
end}
FMemo.Border := true;
FMemo.parent := self;
FChooser := new TComboBoxb(self); //new TEditList(self);
FChooser.ReadOnly := false;
FChooser.parent := self;
FOkBtn := new TBtn(self);
FCancelBtn := new TBtn(self);
FEgnorBtn := new TBtn(self);
cp := new TExecuteMemoComp(self);
FMemo.Completion := cp;
cp.PrepareCompletion();
OnClose := function(o,e)
begin
e.skip := true;
o.visible := false;
end
FOkBtn.Caption := "保存/添加";
FCancelBtn.Caption := "删除当前";
FEgnorBtn.caption := "取消";
FOkBtn.parent := self;
FCancelBtn.parent := self;
FEgnorBtn.parent := self;
FMemo.parent := self;
FChooser.OnSelChanged := thisfunction(OnChooserChanged);
FCancelBtn.OnClick := thisfunction(DeleteCurrent);
FOkBtn.OnClick := thisfunction(doSaveCurrentName);
FEGnorBtn.OnClick := thisfunction(OnIgnore);
end
function Recycling();override;
begin
inherited;
FMemo := nil;
FChooser := nil;
FCancelBtn := nil;
FOkBtn := nil;
FEgnorBtn := nil;
Fonsaveclk := nil;
end
function DeleteCurrent();
begin
if length(FChooser.Items)<2 then return ;
FChooser.DeleteItem(FChooser.ItemIndex);
end
function DoControlAlign();override;
begin
if FMemo and FChooser and FCancelBtn and FOkBtn and FEgnorBtn then
begin
r := clientRect;
r1 := r;
r1[3]-= 30;
FMemo.SetBoundsRect(r1);
tp := r1[3]+2;
wd := 200;
x := 50;
FChooser.SetBoundsRect(array(x,tp,x+200,tp+26));
x += 200;
FCancelBtn.SetBoundsRect(array(x+20,tp,x+20+100,tp+26));
x += 120;
FOkBtn.SetBoundsRect(array(x+20,tp,x+100,tp+26));
x += 120;
FEgnorBtn.SetBoundsRect(array(x+20,tp,x+100,tp+26));
x += 120;
end
end
function OnIgnore();
begin
idx := FChooser.ItemIndex;
if idx >= 0 then
begin
it := FChooser.GetItem(idx);
FChooser.Editer.Text := it.FCaption;
FMemo.Text := it.FExe;
end
Visible := false;
end
function GetCurrentExuteparams(f);
begin
return ParserCommandLine(GetCurrentExuteString(f));
end
function getcurrentcommandline();
begin
idx := FChooser.ItemIndex;
if not(idx >= 0)then return "";
s := FChooser.GetItem(idx).fexe;
if not ifstring(s)then return "";
return s;
end
function GetCurrentExuteString(f); //获得当前的执行字符串
begin
if not ifstring(f)then return "";
if not fileexists("",f)then return "";
idx := FChooser.ItemIndex;
if not(idx >= 0)then return "";
s := FChooser.GetItem(idx).fexe;
if not ifstring(s)then return "";
s := replacetext(s,"$(FULL_CURRENT_PATH)",f);
dir := "";
sp := ioFileseparator();
for i := length(f)downto 1 do
begin
if f[i]=sp then
begin
dir := f[1:i-1];
break;
end
end
s := replacetext(s,"$(CURRENT_DIRECTORY)",dir);
s := replacetext(s,"$(SEARCH_PATH)",owner.getlibpathstr());
s := replacetext(s,"$(TSL_EXE)",gettslexe());
return s;
end
function doSaveCurrentName();
begin
Visible := false;
s := FChooser.Editer.Text;
its := FChooser.Items;
len := Length(its);
for i,v in its do
begin
if v.FCaption=s then
begin
v.FExe := FMemo.Text;
return callDatafunction( Fonsaveclk,self,self);
end
end
if cannotadd then return ;
FChooser.InsertItem(new TCobItem(array("caption":s,"exe":FMemo.Text)),0);
FChooser.ItemIndex := 0;
callDatafunction( Fonsaveclk,self,self);
end
function OnChooserChanged(o,e);
begin
idx := o.ItemIndex;
if idx >= 0 then
begin
it := O.GetItem(idx);
FMemo.Text := it.fexe;
end else
FMemo.Text := "";
FMemo.ClearUndo();
end
function GetData(); //获得数据
begin
r := array();
its := FChooser.Items;
if not(its)then return r;
r["itemindex"]:= FChooser.ItemIndex;
for i,v in its do
begin
r["items"][i]:= array("caption":v.FCaption,"exe":v.FExe);
end
return r;
end
function SetData(d); //设置数据
begin
if ifarray(d)then
begin
SetItems(d["items"]);
FChooser.ItemIndex := d["itemindex"];
end
end
property Items read FItems Write SetItems;
property onsaveclk read Fonsaveclk write Fonsaveclk;
property cannotadd read FCannotadd write FCannotadd;
private
FCannotadd;
Fonsaveclk;
FMemo;
FChooser;
FCancelBtn;
FOkBtn;
FItems;
FEgnorBtn;
private
function GetItemIndex();
begin
return FChooser.Items;
end
function SetItems(its); //设置信息
begin
vs := array();
for i,v in its do
begin
if ifarray(v)and ifstring(v["caption"])and ifstring(v["exe"])then
begin
vi := new TCobItem(v);
vs[length(vs)]:= vi;
end
end
FChooser.Items := vs;
end
end
type TEditList=class(TComboBox)
function Create(AOwner);override;
begin
inherited;
width := 280;
maxListItemShow := 30;
FMaxCoder := 20;
ReadONly := false;
Editer.OnKeyDown := function(o,e)
begin
case e.charcode of
VK_UP:
begin
ItemIndex -= 1;
e.skip := true;
end
VK_DOWN:
begin
ItemIndex += 1;
e.skip := true;
end
13:
begin
Calldatafunction(OnEnterUp,self(true),e);
e.skip := true;
end
VK_ESCAPE:
begin
oer := o.owner.owner;
if oer then oer.Visible := false;
end
ord("A"):
begin
if ssCtrl in e.Shiftstate()then
begin
e.skip := true;
o.SetSel(0,length(o.text));
end
end
end;
end
end
function Recycling();override;
begin
inherited;
FOnEnterUp := nil;
end
function Pushitem(s);
begin
if not ifstring(s)and s then return;
if s in Items then return 0;
insertItem(s,0);
if getItemCount()>FMaxCoder then
begin
deleteItem(FMaxCoder);
end
end
property OnEnterUp read FOnEnterUp write FOnEnterUp;
property MaxCoder read FMaxCoder write FMaxCoder;
private
FMaxCoder;
FOnEnterUp;
end
type TFindWnd=class(TPage)
type TFindBtn=class(TBtn)
function Create(AOwner);
begin
inherited;
left := 425;
width := 160;
height := 25;
end
end
type TFindCheck=class(TCheckBtn)
function Create(AOwner);
begin
inherited;
left := 25;
width := 160;
height := 25;
end
end
function CreateWndInfo(btn,sec); //触发
begin
r := GetInfo();
if sec then r["section"]:= sec;
r["btn"]:= btn;
end
function Create(AOwner);override;
begin
inherited;
OnClose := function(o,e)
begin
Parent.EndFind();
o.visible := false;
e.Skip := true;
end
WsDlgModalFrame := true;
Visible := false;
WsPopUp := true;
WsCaption := true;
WSsYSMenu := true;
//WsSizeBox := true;
caption := "查找";
SetBoundsRect(array(300,300,920,680));
IncPaintLock();
for i,v in array("查找","替换","文件查找") do
begin
it := CreateApageItem();
it.Caption := v;
PageItems.Push(it);
end
DecPaintLock();
lg := 30;
FEdit_Target := new TEditList(self);
FEdit_repace := new TEditList(self);
FEdit_Type := new TEditList(self);
FEdit_dir := new TEditList(self);
FDirChooser := new TFolderChooseADlg(self);
FEdit_dir_btn := new TBtn(self);
flabels := array();
for i,v in array("查找目标:"," 替换为:","文件类型:"," 目录:") do
begin
lb := new TLabel(self);
lb.TextAlign := AL9_CENTERRIGHT;
lb.caption := v;
lb.Top :=(i+1) * lg;
lb.Height := 25;
lb.Left := 20;
lb.Width := 120;
lb.Parent := self;
//lb.border := true;
flabels[i]:= lb;
end
FEdit_Target.left := 140;
FEdit_Target.top := lg;
FEdit_target.parent := self;
FEdit_target.Editer.OnKeyPress := thisfunction(EditerEnter);
FEdit_repace.left := 140;
FEdit_repace.top := lg+lg;
FEdit_repace.parent := self;
FEdit_type.left := 140;
FEdit_type.top := lg+lg+lg;
FEdit_type.Editer.Text := "*.tsf;*.tsl;";
FEdit_type.parent := self;
FEdit_dir.left := 140;
FEdit_dir.Width := FEdit_dir.Width-20;
FEdit_dir_btn.Caption := "..";
FEdit_dir_btn.top := lg+lg+lg+lg;
FEdit_dir_btn.Width := 18;
FEdit_dir_btn.left := 140+FEdit_dir.Width+2;
FEdit_dir_btn.height := 24;
FEdit_dir.top := lg+lg+lg+lg;
FEdit_dir.parent := self;
FEdit_dir_btn.OnClick := function(o,e)
begin
if FDirChooser.OpenDlg()then
begin
FEdit_dir.Editer.text := FDirChooser.Folder;
end
end
FBtn_Find := new TFindBtn(self);
FBtn_replace := new TFindBtn(self);
FBtn_Count := new TFindBtn(self); // 计数
FBtn_replaceall := new TFindBtn(self);
FBtn_Find.caption := "查找";
FBtn_replace.caption := "替换";
FBtn_Count.caption := "全部查找";
FBtn_replaceall.caption := "全部替换";
FBtn_Find.top := lg;
FBtn_Find.parent := self;
FBtn_replace.top := lg+lg;
FBtn_replace.parent := self;
FBtn_replaceall.top := lg+lg+lg;
FBtn_replaceall.parent := self;
FBtn_Find.OnClick := thisfunction(FindBtnClick);
FBtn_replace.OnClick := thisfunction(FindBtnClick);
FBtn_Count.OnClick := thisfunction(FindBtnClick);
FBtn_replaceall.OnClick := thisfunction(FindBtnClick);
FBtn_Count.top := lg+lg+lg+lg;
FBtn_Count.parent := self;
FDirChooser.parent := self;
FCheck_revers := new TFindCheck(self);
FCheck_wrap := new TFindCheck(self);
FCheck_case := new TFindCheck(self);
FCheck_cycle := new TFindCheck(self);
FCheck_reg := new TFindCheck(self);
FCheck_subdir := new TFindCheck(self);
FCheck_gt := new TFindCheck(self);
FCheck_subdir.checked := true;
FCheck_subdir.Left := 425;
FCheck_subdir.top := lg+lg+lg+lg;
FCheck_subdir.Caption := "包含子目录";
FCheck_revers.caption := "反向查找";
FCheck_revers.top := lg * 5;
FCheck_revers.parent := self;
FCheck_wrap.caption := "全词匹配";
FCheck_wrap.top := lg * 6;
FCheck_wrap.parent := self;
FEdit_dir_btn.parent := self;
FCheck_case.caption := "忽略大小写";
FCheck_case.Checked := true;
FCheck_case.top := lg * 7;
FCheck_case.parent := self;
FCheck_cycle.caption := "循环查找";
FCheck_cycle.Checked := true;
FCheck_cycle.top := lg * 8;
FCheck_cycle.parent := self;
FCheck_reg.caption := "正则匹配";
FCheck_reg.Enabled := false;
FCheck_reg.top := lg * 9;
FCheck_reg.parent := self;
FCheck_gt.caption := "\\t转义tab";
FCheck_gt.Checked := false;
FCheck_gt.top := lg * 9;
FCheck_gt.Left := FCheck_reg.width+FCheck_reg.Left+10;
FCheck_gt.parent := self;
FCheck_subdir.parent := self;
FCheck_reg.OnClick := function(o,e)
begin
FCheck_revers.Enabled := not(o.Checked);
FCheck_wrap.Enabled := not(o.Checked);
FCheck_case.Enabled := not(o.Checked);
end
FStatus := new TStatusBar(self);
//FStatus.Align := alNone;
FStatus.Items := array(("text":"","width":700));
FStatus.Parent := self;
OnSelChanged := thisfunction(DoSelChanged);
ItemIndex := 0;
//SetStatusText("查找");
end
function FindBtnClick(o,e);
begin
r := GetInfo();
r["btn"]:= o.Caption;
Owner.DoFind(r,self);
end
function EditErEnter(o,e);
begin
if e.CharCode=13 then
begin
e.skip := true;
r := GetInfo();
r["btn"]:= "查找";
OWner.DoFind(r,self);
end
end
function GetInfo();
begin
r := array();
r["section"]:= CurrentITem.Caption;
s := FEdit_target.Editer.Text;
if FCheck_gt.Checked then
begin
s := Replacestr(s,"\\t","\t");
end
r["target"]:= s;
s := FEdit_repace.Editer.Text;
if FCheck_gt.Checked then
begin
s := Replacestr(s,"\\t","\t");
end
r["replace"]:= s;
r["filetype"]:= FEdit_type.Editer.Text;
r["dir"]:= FEdit_dir.Editer.Text;
r["c_revers"]:= FCheck_revers.Checked;
r["c_cycle"]:= FCheck_cycle.Checked;
r["c_wrap"]:= FCheck_wrap.Checked;
r["c_case"]:= FCheck_case.Checked;
r["c_reg"]:= FCheck_reg.Checked;
r["c_dir"]:= FCheck_subdir.Checked;
return r;
end
function SetStatusText(s);
begin
if ifstring(s)then FStatus.SetItemText(s,0);
end
function OpenFind();
begin
ItemIndex := 0;
end
function OpenReplace();
begin
ItemIndex := 1;
end
function Show(f);override;
begin
it := Owner.GetCurrentEditer();
if it then
begin
s1 := it.SelText;
if s1 and length(s1)<20 and not(pos("\n",s1))then
begin
s := s1;
end else
s := it.CaretWords();
if s then SetFindText(s);
FEdit_target.Editer.SetFocus();
end
inherited;
end
Function SetFindText(s); //设置查找的字符串
begin
FEdit_target.Editer.Text := s;
FEdit_target.Editer.SetSel(0,length(s));
end
function SaveCurrentEditer(); //保存一下数据
begin
for i,v in array(FEdit_target,FEdit_dir,FEdit_type,FEdit_repace) do
begin
v.PushItem(v.Editer.Text);
end
//if e then e.PushItem(e.Editer.Text);
end
function DoSelChanged(o,e);
begin
if CurrentItem then Caption := CurrentItem.Caption;
case Caption of
"查找":
begin
for i := 1 to 3 do flabels[i].Visible := false;
FEdit_dir.visible := false;
FEdit_dir_btn.visible := false;
FEdit_type.visible := false;
FEdit_repace.visible := false;
FBtn_replace.visible := false;
FBtn_count.Visible := true;
FBtn_Replaceall.Visible := false;
FCheck_subdir.visible := false;
FCheck_Revers.visible := true;
FCheck_cycle.Visible := true;
end
"替换":
begin
flabels[1].Visible := true;
for i := 2 to 3 do flabels[i].Visible := false;
FEdit_dir.visible := false;
FEdit_dir_btn.visible := false;
FEdit_type.visible := false;
FEdit_repace.visible := true;
FBtn_replace.visible := true;
FBtn_count.Visible := false;
FBtn_Replaceall.Visible := true;
FCheck_subdir.visible := false;
FCheck_Revers.visible := false;
FCheck_cycle.Visible := true;
end
"文件查找":
begin
for i := 1 to 3 do flabels[i].Visible := true;
FEdit_dir.visible := true;
FEdit_dir_btn.Visible := true;
FEdit_type.visible := true;
FEdit_repace.visible := true;
FBtn_replace.visible := false;
FBtn_count.Visible := false;
FBtn_Replaceall.Visible := true;
FCheck_subdir.visible := true;
FCheck_Revers.visible := false;
FCheck_cycle.Visible := false;
end
end
end
function DoControlAlign();override;
begin
inherited;
if not FStatus then return;
rc := ClientRect;
rc[1]:= rc[3]-30;
FStatus.SetBoundsRect(rc);
end
function recycling();override;
begin
inherited;
FStatus := nil;
end
function GetHistory();
begin
r := array();
r["finds"]:= FEdit_Target.Items;
r["repalces"]:= FEdit_repace.Items;
r["dirs"]:= FEdit_dir.items;
r["findfiletyps"] := FEdit_Type.items;
return r;
end
function SetHistory(d);
begin
if not ifarray(d)then return;
fds := d["finds"];
if ifarray(fds)then
begin
FEdit_Target.Items := fds;
end
rps := d["repalces"];
if ifarray(rps)then
begin
FEdit_repace.Items := rps;
end
dirs := d["dirs"];
if ifarray(dirs)then
begin
FEdit_dir.items := dirs;
end
dirs := d["findfiletyps"];
if ifarray(dirs)then
begin
FEdit_Type.items := dirs;
end
end
private
FStatus;
FDirChooser;
//查找
FEdit_Target;
FEdit_repace;
FEdit_type;
FEdit_dir;
FEdit_dir_btn;
FBtn_Find;
FBtn_replace;
FBtn_Replaceall;
FBtn_Count; // 计数
flabels;
FCheck_revers;
FCheck_wrap;
FCheck_case;
FCheck_cycle;
FCheck_reg;
FCheck_subdir;
FCheck_gt;
end
type TListPages=class(TListBox)
function Create(AOwner);override;
begin
inherited;
Visible := false;
WsPopUp := true;
end
function PaintIdx(idx,rc_,cvs);override;
begin
{**
@explan(说明)绘制项 %%
@param(item)(TCustomListItem) 项 %%
@param(rc)(array) 绘制区域%%
@param(cvs)(tcanvas) 画布 %%
**}
inherited;
if idx=getCurrentSelection()then
begin
rc := rc_;
rc[2:3]-= 1;
cvs.pen.Color := rgb(30,144,255);
cvs.draw("Polyline",array(rc[0:1],(rc[2],rc[1]),(rc[2],rc[3]),(rc[0],rc[3]),rc[0:1]));
end
end
function MouseUp(o,e);override;
begin
inherited;
visible := false;
end
function SetData(d);override;
begin
if not ifarray(d)then return;
height := ItemHeight * (1+min(15,length(d)));
x := 10;
for i,v in d do
begin
x := max(x,length(v));
end
width := font.Width * (x+3);
inherited;
end
function InsureItemVisible(idx); //移动当前的格子
begin
rc := GetIdxRect(idx);
c := ClientRect;
if rc[1]<c[1]then
begin
SetYpos(-1+GetYPos()+(rc[1]-c[1])/GetYScrollDelta());
end else
if rc[3]>c[3]then
begin
SetYpos(1+GetYPos()+(rc[3]-c[3]+1)/GetYScrollDelta());
end
end
function GetSelFileName;
begin
r := GetItem(getCurrentSelection());
if pos("*",r)then
begin
return r[2:];
end
return r;
end
function IncIndex(f);
begin
if ifnil(f)then f :=-1;
idx := getCurrentSelection();
ct := ItemCount;
nidx := idx-f;
if idx=ct-1 then nidx := 0;
else if idx=-1 then nidx := 1;
SetCurrentSelection(nidx);
InsureItemVisible(nidx);
end
end
type tagCOMPOSITIONFORM=class(tslcstructureobj)
private
static SSTRUCT;
class function getstruct()
begin
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
("dwstyle","int",4),
("ptcurrentpos","intptr",0),
("rcarea","int[4]",array(0,0,0,0))),nil,nil,1);
return SSTRUCT;
end
public
function create()
begin
inherited create(getstruct(),ptr);
FPonter := new TCPoint();
_setvalue_("ptcurrentpos",FPonter._getptr_());
end
property dwstyle index "dwstyle" read _getvalue_ write _setvalue_;
property ptcurrentpos read FPonter;
property rcarea index "rcarea" read _getvalue_ write _setvalue_;
private
FPonter;
end
type TFTSLScriptMemo=class(TSYNmemoNorm)
function Create(AOwner);override;
begin
inherited;
WsDlgModalFrame := true;
FChangedFlag := false;
FChangedLock := false;
Lineinterval := 3;
FCOMPOSITIONFORM := new tagCOMPOSITIONFORM(nil);
font := array("height":18,"width":9,"escapement":0,"orientation":0,"weight":400,"italic":0,"underline":0,"strikeout":0,
"charset":0,"outprecision":0,"clipprecision":0,"quality":1,"pitchandfamily":1,"facename":"Courier New","color":0);
//134
//font := array("facename":"Courier New");
end
function DoCaretPosChanged();override;
begin
if HandleAllocated()then calldatafunction(FOnCaretChanged,self(true),new tuieventbase(0,0,0,0));
//echo tostn(self.CaretXY);
end
function WMIMESTARTCOMPOSITION(o,e):WM_IME_STARTCOMPOSITION;virtual;
begin
ime := ImmGetContext(self.Handle);
FCOMPOSITIONFORM.ptcurrentpos.cx := 200;
FCOMPOSITIONFORM.ptcurrentpos.cy := 200;
ImmSetCompositionWindow(ime,FCOMPOSITIONFORM._getptr_());
ImmReleaseContext(self.Handle,ime);
end
{$ifdef linux}
function ImmReleaseContext();
begin
end;
function ImmGetContext();
begin
end;
function ImmSetCompositionWindow();
begin
end;
function ImmSetStatusWindowPos();
begin
end;
{$else}
function ImmReleaseContext(h:pointer;ime:pointer):integer;stdcall;external "Imm32.dll" name "ImmReleaseContext";
function ImmGetContext(h:pointer):pointer;stdcall;external "Imm32.dll" name "ImmGetContext";
function ImmSetCompositionWindow(h:pointer;s:pointer):integer;stdcall;external "Imm32.dll" name "ImmSetCompositionWindow";
function ImmSetStatusWindowPos(h:pointer;s:pointer):integer;stdcall;external "Imm32.dll" name "ImmSetStatusWindowPos";
{$endif}
function InvalidateLines(FirstLine,LastLine:integer);override;
begin
//return inherited;
if not HandleAllocated()then return;
if HighLighter is class(TTslSynHighLighter)then
begin
fy :=(FirstLine-TopLine) * TextHeight;
r := ClientRect;
if fy<r[1]then return;
if fy>r[3]then return;
r[0]:= GutterWidth;
r[1]:= max(0,fy);
InvalidateRect(r,false);
end else
return inherited;
end
function MouseUp(o,e);override;
begin
inherited;
end
function InsertChars(s);override;
begin
if(s="\r\n")then
begin
y := CaretY;
x := CaretX;
sl := Lines.GetStringByIndex(y-1);
if ifstring(sl)and sl then
begin
ins := "";
for i := 1 to x-1 do
begin
si := sl[i];
if si="\t" or si=" " then
begin
ins += si;
end else
break;
end
if ins then
begin
return inherited InsertChars(s+ins);
end
end
end
return inherited;
end
function KeyUp(o,e);override;
begin
e.Result := 1;
if Calldatafunction(FQuckKeys,self,e)then return;
inherited;
end
function ContextMenu(o,e);override;
begin
inherited;
e.skip := true;
end
function SwitchMarkLine(L); //此处处理断点问题
begin
if not(L >= 0)then
begin
L := self.CaretY-1;
end
it := Lines[L];
if it then
begin
it.FMarked := not(it.FMarked);
r := ClientRect;
r[2]:= GutterWidth()-1;
InValidateRect(r,false);
if _Tag then _Tag.markline(L,it.FMarked);
end
end
function KeyDown(o,e);override;
begin
e.Result := 0;
qc := Calldatafunction(FQuckKeys,self,e);
if qc then return;
if e.CharCode=VK_F5 then
begin
L := self.CaretY-1;
SwitchMarkLine(L);
return;
end
if e.CharCode=VK_F2 and(ssCtrl in e.shiftState())then
begin
L := self.CaretY-1;
SwitchMarkLine(L);
return;
end
if not(ssCtrl in e.shiftstate())and not(ssShift in e.shiftstate())then
begin
if e.CharCode=VK_F2 then
begin
y := CaretY-1;
len := Lines.length();
for i := y+1 to len+y-1 do
begin
idx :=(i+len)mod len;
it := Lines[idx];
if it and it.FMarked then
begin
return ExecuteCommand(ecGotoXY,array(idx+1,1));
end
end
return;
end
end
inherited;
end
function WMSYSKEYUP(o,e):WM_SYSKEYUP;override;
begin
e.Result := 1;
if CallDatafunction(FQuckKeys,self,e)then return;
inherited;
end
Function WMSYSKEYDOWN(o,e):WM_SYSKEYDOWN;override;
begin
e.Result := 0;
if CallDatafunction(FQuckKeys,self,e)then return;
inherited;
end
function WMSETFOCUS(o,e):WM_SETFOCUS;override;
begin
inherited;
CallDataFunction(FOnTextSetFocus,self(true),e);
end
function DoTextChanged(p);override;
begin
n := Lines.Length();
ccnt := GutterCharCnt;
nccnt := max(integer(n~10)+3,4);
if ccnt <> nccnt then
begin
GutterCharCnt := nccnt;
end
inherited;
SetChangeFlag(true);
end
function Recycling();override;
begin
FQuckKeys := nil;
FOnTextChanged := nil;
FOnTextSetFocus := nil;
FPageItem := nil;
FOnCaretChanged := nil;
inherited;
end
published
property OnCaretChanged read FOnCaretChanged write FOnCaretChanged;
property PageItem read FPageItem write FPageItem;
property OnTextChanged read FOnTextChanged write FOnTextChanged; //文本改变
property QuckKeys read FQuckKeys write FQuckKeys; //快捷键
property ChangedFlag read FChangedFlag write SetChangeFlag;
property ChangedLock read FChangedLock write FChangedLock;
property OnTextSetFocus read FOnTextSetFocus write FOnTextSetFocus;
private
function SetChangeFlag(v);
begin
nv := v?true:false;
if nv <> FChangedFlag then
begin
FChangedFlag := nv;
if FChangedLock then return;
calldatafunction(OnTextChanged,self(true),nv);
end
end
FPageItem;
FChangedLock;
FChangedFlag;
FOnTextChanged;
FOnTextSetFocus;
FQuckKeys;
FCOMPOSITIONFORM;
FOnCaretChanged;
end
type TPageEditerItem=class(TPageItem)
FPageOrderId; //序号有调用者使用
FEditer; //编辑器
FSynType;
FInitCompletion;
FDebuger;
fisnewfile;
function create(AOwner);override;
begin
inherited;
FSynType := "";
FEnCode := "ANSI";
FGetInfoText := "";
FLastVersion := "";
FEditer := new TFTSLScriptMemo(AOwner);
FEditer.Visible := false;
FEditer._Tag := self;
end
function Recycling();override;
begin
FDebuger := nil;
inherited;
FEditer.Recycling();
FEditer := nil;
end
function markline(l,f); //标记被调用
begin
if FDebuger then
begin
if f then
begin
FDebuger.addbreak(self,l);
end else
begin
FDebuger.removebreak(self,l);
end
end
end
function ScriptPathIs(v);
begin
return filenameIsTheSame(v,FScriptPath);
end
published
property ScriptPath read FScriptPath write SetScriptPath; //文件名
property OrigScriptPath read FOrgScriptPath;
property TslSynText read FTslSynText write FTslSynText;
property LastText read FLastVersion; //最新的版本
property EnCode read FEnCode;
RepreComple;
FISstm;
///////////////////设计器相关//////////////////////////////////////
public
function Addfiled(fld); //添加成员变量
begin
if not FTslParser then return 0;
if not(fld and ifstring(fld))then return;
nfld := lowercase(fld);
nt := str2array(nfld,":");
nfld := nt[0];
nfldt := nt[1];
d := GetClassInfo();
if not(d and ifarray(d))then return 0;
for i,v in d["filed"] do
begin
if v["name"]=nfld then return 1;
end
crec := GetCreateFunctionRec(d);
if crec then
begin
p := crec[0];
if ifarray(p)then
begin
FEditer.ExecuteCommand(FEditer.ecGotoXY,p);
FEditer.ExecuteCommand(FEditer.ecString,fld+";\r\n ");
end
end
end
function GetCreateFunctionRec(d); //获得插入函数为位置
begin
fi := d["funcsinfo"];
for i,v in fi do
begin
if v["name"]="create" then
begin
return GetInfoRowCol(v);
end
end
return 0;
end
function Delfiled(fld,nn); //删除成员变量
begin
if not FTslParser then return 0;
if not(fld and ifstring(fld))then return;
if not ifstring(nn)then nn := "";
nfld := lowercase(fld);
d := GetClassInfo();
if not(d and ifarray(d))then return 0;
for i,v in d["filed"] do
begin
if v["name"]=nfld then
begin
frec := GetInfoRowCol2(v);
if ifarray(frec[0])and ifarray(frec[1])then
begin
FEditer.ExecuteCommand(FEditer.ecGotoXY,frec[0]);
FEditer.ExecuteCommand(FEditer.ecSelGotoXY,frec[1]);
FEditer.SelText := nn?(nn+";"):"";
end
end
end
end
function GoToFunction(fn);
begin
if not(ifstring(fn))then return false;
nfld := lowercase(fn);
d := GetClassInfo();
if not ifarray(d)then return 0;
for i,v in d["funcsinfo"] do
begin
if v["name"]=nfld then
begin
crec := GetInfoRowCol(v);
if ifarray(crec)and ifarray(crec[0])then
begin
FEditer.ExecuteCommand(FEditer.ecGotoXY,crec[0]);
end
return true;
end
end
end
function AddFunction(fn,finfo); //添加函数
begin
if not FTslParser then return 0;
if not(ifstring(fn)and fn and ifstring(finfo))then return 0;
nfld := lowercase(fn);
d := GetClassInfo();
if not ifarray(d)then return 0;
for i,v in d["funcsinfo"] do
begin
if v["name"]=nfld then
begin
crec := GetInfoRowCol(v);
if ifarray(crec)and ifarray(crec[0])then
begin
FEditer.ExecuteCommand(FEditer.ecGotoXY,crec[0]);
end
return true;
end
end
crec := GetCreateFunctionRec(d);
if crec then
begin
p := crec[1];
if ifarray(p)then
begin
FEditer.ExecuteCommand(FEditer.ecGotoXY,p);
FEditer.ExecuteCommand(FEditer.ecString,"\r\n"+finfo+"\r\n ");
end
end
return true;
end
function GetLastLoadTime(); //最新时间
begin
return FLastFileTime;
end
function ReGetLastLoadTime(); //重新获得时间
begin
fi := FileList("",FScriptPath);
FLastFileTime := fi[0,"Time"];
return FLastFileTime;
end
function PrePareSave(); //准备保存
begin
if not FEditer.ChangedFlag then
begin
if RepreComple then itemPareCompletion();
return false;
end
if FEditer.ReadOnly then
begin
if RepreComple then itemPareCompletion();
return false;
end
t := FEditer.Text;
if FLastVersion=t then
begin
FEditer.ChangedFlag := false;
if RepreComple then itemPareCompletion();
return false;
end
FLastVersion := t;
itemPareCompletion();
//FEditer.PrePareCompletion(t); //准备自动完成
FEditer.ChangedFlag := false;
return true;
end
function itemPareCompletion();
begin
t := caption;
cp := FEditer.Completion;
if cp then cp.PrePareCompletion(t);
RepreComple := false;
end
function IsTextUTF8(str)
begin
{utf8规则
单字节: 0xxxxxxx
二字节 110xxxxx 10xxxxxx
三字节 1110xxxx 10xxxxxx 10xxxxxx
四字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
五字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
刘字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
}
// 0 为ansi 编码,1 为utf8编码 -1 不能确定什么编码
nBytes := 0; //UFT8可用1-6个字节编码,ASCII用一个字节
DY := 0;
chr := "";
bAllAscii := TRUE; //如果全部都是ASCII, 说明不是UTF-8
for i := 1 to length(str) do
begin
chr := ord(str[i]);
if((chr .& 0x80)<> 0)then
begin // 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码,但用一个字节存,最高位标记为0,o0xxxxxxx
bAllAscii := FALSE;
end
if(nBytes=0)then //如果不是ASCII码,应该是多字节符,计算字节数
begin
if(chr >= 0x80)then
begin
if(chr >= 0xFC and chr <= 0xFD)then nBytes := 6;
else if(chr >= 0xF8)then nBytes := 5;
else if(chr >= 0xF0)then nBytes := 4;
else if(chr >= 0xE0)then nBytes := 3;
else if(chr >= 0xC0)then nBytes := 2;
else return 0;
DY := MAX(nBytes,DY);
nBytes--;
end
end else //多字节符的非首字节,应为 10xxxxxx
begin
if((chr .& 0xC0)<> 0x80)then return-1;
nBytes--;
end
end;
if(nBytes>0)then //违返规则
return-1;
if(bAllAscii)then //如果全部都是ASCII, 说明不是UTF-8
return 0;
//return 1;
return DY>2;
end
function ToUnicode_big();
begin
if FEnCode="UCS2-big" then return;
FEnCode := "UCS2-big";
FEditer.ChangedFlag := true;
FLastVersion := "";
end
function ToUniocode_little();
begin
if FEnCode="UCS2-little" then return;
FEnCode := "UCS2-little";
FEditer.ChangedFlag := true;
FLastVersion := "";
end
function ToUTF8();
begin
if FEnCode="UTF8" then return;
FEnCode := "UTF8";
FEditer.ChangedFlag := true;
FLastVersion := "";
return;
end
function ToUTF8BOM();
begin
if FEnCode="UTF8 BOM" then return;
FEditer.ChangedFlag := true;
FEnCode := "UTF8 BOM";
FLastversion := "";
end
function ToANSI();
begin
if FEnCode="ANSI" then return;
FEditer.ChangedFlag := true;
FEnCode := "ANSI";
FLastversion := "";
end
function CurrentCodeIsUtf8();
begin
if FEnCode="ANSI" then
begin
s := FEditer.Text;
try
s := UTF8toansi(s);
FEditer.Text := s;
FEnCode := "UTF8";
except
end
end
end
function CurrentCodeIsAnsi();
begin
if FEnCode="UTF8" then
begin
FEnCode := "ANSI";
end
end
function SetLoadScript(s); //保存文件
begin
if not ifstring(s)then return;
strcode := 0;
FEnCode := "ANSI";
if(length(s)>= 2)and ord(s[1])=0xFE and ord(s[2])=0xFF then //ucs2-big
begin
strcode := 2;
FEnCode := "UCS2-big"; //要转换
if length(s)=2 then s := "";
else
begin
s1 := "";
setlength(s1,length(s)-2);
for i := 3 to length(s)-1 step 2 do
begin
s1[i-2]:= s[i+1];
s1[i-1]:= s[i];
end
s := unicodetomultibyte(s1,936);
end
end else
if(length(s)>= 2)and ord(s[1])=0xFF and ord(s[2])=0xFE then //ucs2-little
begin
strcode := 4;
FEnCode := "UCS2-little";
if length(s)=2 then s := "";
else
begin
s := unicodetomultibyte(s[3:],936);
end
end else
if(length(s)>= 3)and ord(s[1])=0xEF and ord(s[2])=0xBB and ord(s[3])=0xBF then
begin
FEnCode := "UTF8 BOM";
if length(s)=3 then s := "";
else s := utf8toansi(s[4:]);
strcode := 1;
end
if(0=strcode)then
begin
if IsTextUTF8(s)=1 then
begin
FEnCode := "UTF8";
strcode := 1;
s := utf8toansi(s);
end
end
FLastVersion := s;
FEditer.Text := s;
FEditer.ExecuteCommand(FEditer.ecGotoXY,array(1,1));
FEditer.ClearUndo();
FEditer.ChangedFlag := false;
if not FTslSynText then return;
if not(s)then return;
r := tsl_tokenizeex_2_(s,1);
cs := r["class"];
if ifarray(cs)and cs[0]then
begin
lcs1 := lowercase(cs[0]);
if lcs1 in array("tdcreateform","tdcreatepanel")then
begin
try
if not FTslParser then FTslParser := new unit(UDesignerProject).tslparser(); #! end
except
end;
return; //返回
end
end
FTslParser := nil;
end
function GetClassInfo(); //获得信息
begin
if not FTslParser then return array();
txt := FEditer.Text;
if txt <> FGetInfoText then
begin
FGetInfoText := txt;
FTslParser.Script := txt;
FGetInfoChace := FTslParser.GetClassInfo(1);
end
return FGetInfoChace;
end
private
FEnCode;
FLastFileTime;
FTslSynText;
function GetInfoRowCol(v); //获得行列
begin
rs := PosToRowCol(FGetInfoText,array(v["startpos"]-1,v["endpos"]));
return rs;
end
function GetInfoRowCol2(v); //获得行列结尾
begin
rs := PosToRowCol(FGetInfoText,array(v["beg"]-1,v["end"]));
return rs;
end
function PosToRowCol(s,ps); //位置换算
begin
r := array();
idx := 0;
pi := ps[idx];
ri := ci := 1;
for i := 1 to length(s) do
begin
vi := s[i];
if vi="\n" then
begin
ri++;
ci := 1;
end else
ci++;
if i=pi then
begin
r[idx]:= array(ri,ci);
idx++;
pi := ps[idx];
end
end
return r;
end
FTslParser; //
FGetInfoChace; //class 信息
FGetInfoText; //文本
FLastVersion; //脚本
FScriptPath; //路径
FOrgScriptPath; //原始路径
function SetScriptPath(v);
begin
sp := ioFileseparator();
if ifstring(v)then
begin
for i := length(v)downto 1 do
begin
if v[i]=sp then
begin
Caption := v[i+1:];
break;
end
if v[i]="." then
begin
if lowercase(v[i:])in array(".tsl",".tsf")then FTslSynText := true;
end
end
FScriptPath := v;
FOrgScriptPath := v;
FEditer.Caption := v;
end
end
end
type TPageEditer=class(TPage) //多页编辑
function Create(AOwner);override;
begin
inherited;
end
function MouseUp(o,e);override;
begin
inherited;
if e.button()=mbRight then
begin
return CallDatafunction(FPageItemOnRClick,self,e);
end
end
function CallSelChanged();override;
begin
it := Currentitem;
if it then
begin
it.FEditer.SetBoundsRect(self.ClientRect);
it.FEditer.Visible := true;
it.FEditer.SetFocus();
end
inherited;
end
function CallSelChanging();override;
begin
inherited;
it := CurrentItem;
if it and it.FEditer then it.FEditer.Visible := false;
end
function Recycling();override;
begin
inherited;
FCliper := nil;
FMenu := nil;
FPageItemOnRClick := nil;
end
function DoControlAlign();override;
begin
inherited;
it := CurrentItem;
if it then
begin
it.FEditer.SetBoundsRect(self.ClientRect);
end
end
property PageItemOnRClick read FPageItemOnRClick write FPageItemOnRClick;
private
FPageItemOnRClick;
end
type TTslChmHelp=class
function SearchWord(s);
begin
if not s then return;
pm := format('%s::/%s.htm',FTSLinterpPath+FChmName,s); //>mainwin
HtmlHelpA(GetDesktopWindow(),pm,0,nil);
return;
end
function ShowTslLangChm();
begin
return HtmlHelpA(GetDesktopWindow(),FTSLinterpPath+FChmName,0,nil);
end
function Create();
begin
FChmName := "help\\LANGUAGEGUIDE.CHM";
FTSLinterpPath := "";
n := pluginpath();
for i := length(n)-1 downto 3 do
begin
if n[i]="\\" then
begin
FTSLinterpPath := n[1:i];
break;
end
end
end
property ChmName read FChmName write FChmName;
private
FTSLinterpPath;
FHanle;
FChmName;
end
type TEditerEchoWnd=class(TSynMemoNorm) //
function Create(AOwner);override;
begin
inherited;
FDoLockTime := 0;
FIsLocked := false;
height := 250;
ReadOnly := true;
WsSizeBox := true;
WsSysMenu := true;
OnClose := function(o,e)
begin
o.visible := false;
e.skip := true;
end
m := new TPopUpMenu(self);
m1 := new TMenu(self);
m1.Caption := "清空";
m1.parent := m;
{m2 := new TMenu(self);
m2.Caption := "选中字符高亮";
m2.Checked := false;
m2.OnClick := function(o,e)begin
o.Checked := not(o.Checked);
self.HighLighter := (o.Checked) ?F_Highlighter :false;
end
m2.Parent := m;}
PopUpMenu := m;
m1.OnClick := function(o,e)
begin
ClearAll();
AppendString("ctrl+z 停止;ctrl+c 复制选择\r\n");
end;
FProcess := new TCreateProcessA();
FProcess.BufSize := 1024 * 5;
FProcess.OnEcho := thisfunction(TEchoToString);
AppendString("ctrl+z 停止;ctrl+c 复制选择\r\n");
F_Highlighter := new TSynHighLighter(self);
//Highlighter := new TSynHighLighter(self);
end
function TEchoToString(o,s);
begin
//t := now();
{if (t-FDoLockTime)>(0.3E-5) then
begin
FDoLockTime := t;
if FIsLocked then
begin
FIsLocked := false;
DecPaintLock();
end else
begin
FIsLocked := true;
IncPaintLock();
end
end }
AppendString(s);
//Visible := true;
return true;
end
function Exec(exe,cmd,h);
begin
//AppendString(format('"%s" %s\r\n',exe,cmd));
self.HighLighter := nil;
AppendString(format('%s %s\r\n',exe,cmd));
//EndExe();
r := FProcess.CreateProcessWaitRead(exe,cmd,h);
AppendString(format("\r\n执行结束:endcode:%d\r\n",r));
{if FIsLocked then
begin
FIsLocked := false;
DecPaintLock();
end }
self.HighLighter := F_Highlighter;
h := 0;
return r;
end
function Exeing();
begin
return FProcess.LastExeHandle;
end
function EndExe();
begin
if FProcess.LastExeHandle then
begin
r := 1;
SysTerminate(r,FProcess.LastExeHandle);
end
end
function KeyDown(o,e);override;
begin
if ssCtrl in e.shiftstate then
begin
case e.charcode of
ord("Z"):
begin
EndExe();
return;
end
ord("C"):
begin
ExecuteCommand(ecCopy);
return;
end
end
end
inherited;
end
function AppendString(s);
begin
if not(ifstring(s)and s)then return;
ct := Lines.Length();
if ct>0 then
begin
ExecuteCommand(ecGoToXY,array(ct,1));
ExecuteCommand(ecLineEnd);
ExecuteCommand(ecString,s);
end
end
FExeHandle;
FProcess;
FIsLocked;
FDoLockTime;
F_Highlighter;
end
type TTslDebug=class(TCustomControl)
private //成员变量
FRuningfile; //执行脚本文件名
FRuningItem; //执行的pageitem
FCurrentgotoitem; //当前运行到的pageitem
FDebughandle; //调试的句柄
FDebugExe; //调试功能的exe
FConnectchannel; //调试的 通道
FDebugaddr; //地址
FDebugport; //调试的端口
FDebugUsr; //用户名
FDebugPwd; //密码
FDebugtsfs; //当前工程对应的tsf文件
FBtns;
FAttchedid;
FDebugtype;
fdbgselwnd;
FRemoteWait; //远程调试等待
FValewnd;
FCmdHistory;
FCmdHistoryid;
FCmdHistorycount;
////////////////////
Fdbgssybs;
Fdbgsybs;
Fdbgstack;
fdefaultdbger; //编辑器的调试器
type tdbgwnd=class(TPanel)
uses tslvcl;
function Create(AOwner);
begin
inherited;
WsDlgModalFrame := false;
p1 := new TPairSplitter(self);
p1.Position := 310;
p2 := new TPairSplitter(self);
p2.Position := 310;
sd1 := new TPairSplitterSide(self);
sd2 := new TPairSplitterSide(self);
sd3 := new TPairSplitterSide(self);
sd3 := new TPairSplitterSide(self);
sd4 := new TPairSplitterSide(self);
p1.Align := alClient;
sd1.WsDlgModalFrame := false;
sd2.WsDlgModalFrame := false;
sd3.WsDlgModalFrame := false;
sd4.WsDlgModalFrame := false;
p1.WsDlgModalFrame := false;
p2.WsDlgModalFrame := false;
p1.parent := self;
sd1.parent := p1;
sd1.Border := false;
sd2.parent := p1;
p2.Align := alClient;
p2.parent := sd2;
sd3.parent := p2;
sd4.parent := p2;
sd4.Border := false;
fside1 := sd1;
fside2 := sd3;
fside3 := sd4;
end
function addwnds(stk,vlist,cmd,cmdshow);
begin
stk.Align := alClient;
stk.parent := fside1;
vlist.Align := alClient;
vlist.parent := fside2;
cmd.Align := alBottom;
cmd.parent := fside3;
cmdshow.Align := alClient;
cmdshow.parent := fside3;
end
function Recycling();override;
begin
inherited;
fside1 := nil;
fside2 := nil;
fside3 := nil;
end
fside1;
fside2;
fside3;
end
function cmdkeyup(o,e);
begin
case e.charcode of
VK_UP:
begin
//return ;
if FCmdHistoryid <= 0 then return o.text := "";
FCmdHistoryid--;
txt := FCmdHistory[FCmdHistoryid];
if ifstring(txt)and txt then o.text := txt;
end
VK_DOWN:
begin
if FCmdHistoryid >= Length(FCmdHistory)then return o.text := "";
FCmdHistoryid++;
txt := FCmdHistory[FCmdHistoryid];
if ifstring(txt)and txt then o.text := txt;
end
13:
begin
//return ExecuteCommand("docmd");
txt := trim(o.Text);
if txt then
begin
if length(FCmdHistory)>FCmdHistorycount then
begin
for i := 0 to FCmdHistorycount-1 do
begin
FCmdHistory[i]:= FCmdHistory[i+1];
end
end
FCmdHistory[length(FCmdHistory)]:= txt;
FCmdHistoryid := length(FCmdHistory);
ExecuteCommand("docmd");
end
e.skip := true;
end
end
end
function getvalewnd(cp);
begin
if not FValewnd then
begin
FValewnd := new TTSLDataGrid(self);
FValewnd.Visible := false;
FValewnd.Caption := "Value";
FValewnd.left := owner.left+100;
FValewnd.Width := 600;
FValewnd.Height := 500;
FValewnd.WSpOPUp := true;
FValewnd.WSsYSMenu := true;
FValewnd.WsSizeBox := true;
FValewnd.Parent := self;
FValewnd.OnClose := function(o,e)
begin
o.Visible := false;
o.TSLdata := array();
end
end
if ifstring(cp)then FValewnd.Caption := cp;
return FValewnd;
end
function deletefuncacheini();
begin
plg := pluginpath();
{$ifdef linux}
sp := "/";
{$else}
sp := "\\";
{$endif}
for i := length(plg)-1 downto 1 do
begin
if plg[i]=sp then
begin
fn := plg[1:i]+"FunCache.ini";
r := filedelete("",fn);
return r;
end
end
end
public
function addbtns(btns); //添加菜单
begin
FBtns := btns;
for i,v in Fbtns do
begin
v.onClick := thisfunction(Dbgtooldo);
if v.Caption="添加/删除断点F5" then continue;
v.Visible := false;
end
end
function DbgNextLine(); //下一行
begin
ExecuteCommand("dbgstepover");
end
function serwnd_cclk(o,e); //取消
begin
FRemoteWait := false;
cancelremotedbg(o,e,"取消调试");
return;
end
function serwnd_oclk(o,e); //远程连接按钮
begin
d := fdbgselwnd.GetData();
addr := d["addr"];
port := d["port"];
if not(addr and port)then return MessageboxA("远程服务器信息不全","提示",0,self.Handle);
port := StrToIntDef(port,443);
usr := d["usr"];
pwd := d["pwd"];
//连接判断
if checkconnected()then
begin
disconnectserver();
end
if FDebugtype="remotewait" then //远程等待
begin
FDebugaddr := addr;
FDebugport := port;
FDebugUsr := usr;
FDebugPwd := pwd;
FRemoteWait := true;
fdbgselwnd.Visible := false;
return _send_(WM_USER,0,0,1);
end
if 0 <> connectserver(addr,port)then return MessageboxA("远程服务器连接失败","提示",0,self.Handle);
if(usr and pwd)and 0 <> dbglogin(usr,pwd)then
begin
return MessageboxA("登陆用户失败","提示",0,self.Handle);
end
ExecuteCommand("dbgcreatechannel"); //构造channel
if FConnectchannel then
begin
dbglist(FConnectchannel);
end
end
function dbg_clk(o,e);
begin
file := o.getstartfilename(d);
item := nil;
if file=0 then //不存在脚本
begin
if 1 <> MessageboxA("没找到本地对应的tsl\r\n是否继续调试","提示",1,self.Handle)then
begin
return serwnd_cclk();
end
end else
begin
item := owner.OpenAndGotoFileByName(file,1);
end
o.Visible := false;
FRuningItem := item;
FCurrentgotoitem := item;
parsercurrentitem(item);
FAttchedid := d;
dbgattach(FConnectchannel,d["id"]);
//echo tostn(d);
end
function Debugremote(flg);
begin
{$ifdef linux}
return MessageboxA("linux目前不支持调试","提示",0,self.Handle);
{$endif}
if FRemoteWait then
begin
if flg then
begin
if 1=MessageboxA("远程调试等待中...\r\n点击确定停止等待..","提示",1,self.Handle)then
begin
FRemoteWait := false;
disconnectserver();
end
return;
end else
begin
return MessageboxA("远程调试等待中...","提示",0,self.Handle);
end
end else
begin
//if flg then return ;
if FConnectchannel then
begin
return MessageboxA("正在调试中...","提示",0,self.Handle);
end
end
if not fdbgselwnd then
begin
fdbgselwnd := new tdbgselwnd(self);
fdbgselwnd.Parent := self;
fdbgselwnd.FHistoryDir := owner.FHistoryDir;
fdbgselwnd.loaddata();
fdbgselwnd.OnClose := thisfunction(serwnd_cclk);
fdbgselwnd.save_clk := thisfunction(serwnd_oclk);
fdbgselwnd.cancel_clk := thisfunction(serwnd_cclk);
fdbgselwnd.dbg_clk := thisfunction(dbg_clk);
end
fdbgselwnd.setlist();
if flg then
begin
FDebugtype := "remotewait";
fdbgselwnd.setattachwait(true);
end else
begin
FDebugtype := "remote";
fdbgselwnd.setattachwait(false);
end
fdbgselwnd.show();
return;
end
function Debuglocal(item); //调试脚本
begin
{$ifdef linux}
return MessageboxA("linux目前不支持调试","提示",0,self.Handle);
{$endif}
if not item then return 0;
if FConnectchannel then return MessageboxA("正在调试中","提示",0,self.Handle);
if FRemoteWait then return MessageboxA("远程调试等待中...","提示",0,self.Handle);
FDebugtype := "local";
if checkconnected()then disconnectserver(); //断开连接
FAttchedid := 0;
FDebugport := randomfrom(1 -> 600)+20000;
FDebugaddr := '127.0.0.1';
FRuningItem := item;
FCurrentgotoitem := item;
dirs := owner.getlibpathstr();
parsercurrentitem(item);
fio := ioFileseparator();
FDebugUsr := 0;
FDebugPwd := 0;
deletefuncacheini();
getdebuger(pms);
exestr := format('"%s" "%s" -DEBUGSERVER -DEBUGLOGIN 0 -WAITATTACH -DEBUGPORT %d -libpath "%s" ',FDebugExe,FRuningfile,FDebugport,dirs);
exestr += pms;
FDebughandle := sysexec(FDebugExe,exestr,nil,0,rcode,0);
if FDebughandle then
begin
ExecuteCommand("dbgcreatechannel");
ExecuteCommand("showeval","调试程序:"+FDebugExe);
if FConnectchannel then
begin
dbgattachwait(FConnectchannel);
end
end
end
function wmuser(o,e):WM_USER;virtual;
begin
if FRemoteWait and not(checkconnected())then
begin
if(0 <> connectserver(FDebugaddr,FDebugport))then
begin
FRemoteWait := false;
messageboxa("连接服务器失败","错误",0,self);
return;
//sleep(100);
//_send_(WM_USER,0,0,1);
end else
begin
FRemoteWait := false;
FConnectchannel := dbgcreatechannel();
setgdbcallback();
if(FDebugUsr and FDebugPwd)and(0 <>(lgg := dbglogin(FDebugUsr,FDebugPwd)))then
begin
messageboxa("登陆失败\r\n用户名或者密码错误","登陆失败",0,self);
return disconnectserver();
end
dbgattachwait(FConnectchannel);
FBtns["终止"].Visible := true;
end
end
end
function Create(AOwner);
begin
inherited;
FCmdHistory := array();
FCmdHistoryid := 0;
FCmdHistorycount := 10;
FDebugExe := "";
Caption := "tsl debug ...";
{fimgelist := new tcontrolimagelist(self);
fimgelist.Width := 24;
fimgelist.height := 24;
fimgelist.DrawBimpFirst := true;
FToolbar := new TToolBar(self);
FToolbar.Visible := false;
idx := 0;
for i,v in dbugicos() do //工具条
begin
bmp := new TBitmap();
bmp.ReadVcon(HexformatStrToTsl( v));
fimgelist.addbmp(bmp);
iti := new TToolButton(self);
iti.OnClick := thisfunction(Dbgtooldo);
iti.Caption := i;
iti.imageid := idx;
iti.Parent := FToolbar;
idx++;
end
FToolbar.ImageList := fimgelist;
FToolbar.Parent := self;
}
dbwnd := new tdbgwnd(self);
dbwnd.Align := alClient;
dbwnd.Parent := self;
FStackList := new TListView(self); // new TListBox(self); //new tmemo(self);//
FStackList.ItemHeight := 23;
FStackList.Columns := array(("text":"line","width":40),
("text":"function","width":250) //,("text":"type","width":70)
);
//FStackList.ReadOnly := true;
//FStackList.Width := 300;
FStackList.Border := true;
//FStackList.Align := alLeft;
//FStackList.Parent := self;
FVaraiblesList := new TGroupGridA(self);
FVaraiblesList.Border := false;
FVaraiblesList.ItemHeight := 23;
FVaraiblesList.Columns := array(("text":"name","width":95),
("text":"value","width":135),
("text":"type","width":50)
);
FCommandtext := new TEdit(self);
//FCommandtext.Border := true;
FCommandtext.placeholder := "命令输入框";
FCommandtext.Height := 23;
//FCommandtext.Align := alBottom;
//FCommandtext.Parent := self;
FCommandtext.onkeyup := thisfunction(cmdkeyup);
FShowText := new tmemo(self);
FShowText.ReadOnly := true;
FShowText.Border := true;
//FShowText.Align := alClient;
//FShowText.Parent := self;
pmenu := new TPopUpMenu(self);
cmu := new TMenu(self);
cmu.OnClick := function(o,e)
begin
FShowText.Text := "";
end;
cmu.Caption := "清除";
cmu.Parent := pmenu;
FShowText.PopUpMenu := pmenu;
dbwnd.addwnds(FStackList,FVaraiblesList,FCommandtext,FShowText);
ExecuteCommand("clearall");
getdefaultdbger();
end
function addbreak(item,idx,n); //添加断点
begin
if not FConnectchannel then return;
parseriteminfo(item,idx,n,usr);
if n then
begin
//echo "\r\n====add:",usr,"====",n,"===",idx;
dbgsetbreak(FConnectchannel,usr,n,idx+1);
end
end
function removebreak(item,idx); //移除断点
begin
if not FConnectchannel then return;
parseriteminfo(item,idx,n,usr);
if n then
begin
//echo "\r\n====remove:",usr,"====",n,"===",idx;
dbgunsetbreak(FConnectchannel,usr,n,idx+1);
end
end
function Dbgtooldo(o,e)
begin
cp := o.Caption;
case cp of
"调试运行":
begin
//echo "调试运行";
it := Owner.GetCurrentItem(); //Owner.GetAllPageItems();
Debuglocal(it);
end
"添加/删除断点F5":
begin
it := Owner.GetCurrentItem();
if it then
begin
it.FEditer.SwitchMarkLine();
end
end
"暂停":
begin
ExecuteCommand("dbgpause");
end
"进入":
begin
ExecuteCommand("dbgstep")
end
"单步":
begin
//dbgstep();
end
"下一行(F8)":
begin
ExecuteCommand("dbgstepover");
end
"跳出":
begin
ExecuteCommand("dbgstepout");
end
"继续":
begin
toolbtnState("继续");
if FCurrentgotoitem and FCurrentgotoitem.FEditer then FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",nil);
ExecuteCommand("dbgrun");
end
"终止":
begin
ExecuteCommand("dbgreset");
end
"单步":
begin
end
"刷新符号表":
begin
ExecuteCommand("dbggetallvalue");
end
"刷新当前符号":
begin
ExecuteCommand("dbggetcurrentnode");
end
"清除文本框":
begin
FShowText.Text := "";
end
end;
end
function dbgeventcall(d); //回调
begin
global g_tsldbgcallback_handle;
if not ifarray(d)then return;
if d["channel"]<> FConnectchannel then return;
recvtype := d["recvtype"];
if recvtype=0 then
begin
FRemoteWait := 0;
ExecuteCommand("showeval","调试结束");
if FConnectchannel then dbgdeletechannel(FConnectchannel);
FConnectchannel := 0;
g_tsldbgcallback_handle := nil;
if FCurrentgotoitem and FCurrentgotoitem.FEditer then FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",nil);
FDebughandle := 0;
toolbtnState("停止");
return;
end
//echo "\r\nrectype",format("0x%x",recvtype);
if 0x0401=recvtype then
begin
owner.echoAppendString(d["errmsg"]);
return;
end
if recvtype <> 0x402 then
begin
return;
end
case magicgetarray(d,array("result","CmdType"))of
"attachlist":
begin
r := magicgetarray(d,array("result","CmdData"));
r ::
begin
if mcol="createtm" then
begin
mcell := datetimetostr(mcell);
end
end
return fdbgselwnd.setlist(r);
//return echo tostn(r);
end
"attachwaitok","attachok": // 连接,默认
begin
debuginitok();
FVaraiblesList.SetNodeData(array());
FStackList.DeleteAllItems();
//dbgeval(FConnectchannel,getobjtransfunc());
return;
end
"DebugInfo": //调试信息
begin
if "dbgdetach"=remotewaitinit(d)then return;
toolbtnState("暂停");
stk := magicgetarray(d,array("result","CmdData","CallStack")); //深度
sybs := magicgetarray(d,array("result","CmdData","SymbolInfo")); //符号
ssybs := magicgetarray(d,array("result","CmdData","EnvInfo")); //系统参数
{if (ssybs = Fdbgssybs) and (sybs = Fdbgsybs) and (stk=Fdbgstack) then //值没变
begin
return ;
end }
if(ssybs <> Fdbgssybs)or(sybs <> Fdbgsybs)then
begin
FVaraiblesList.SetNodeData(array());
ddd := formatsysvlist(ssybs,nil);
FVaraiblesList.SetNodeData(ddd,true);
Fdbgssybs := ssybs;
ddd := formatvlist(sybs);
FVaraiblesList.SetNodeData(ddd,true);
Fdbgsybs := sybs;
end
if stk <> Fdbgstack then
begin
FStackList.DeleteAllItems();
FStackList.appendItems(stk[:,array("LINE","NAME","USER")]);
//FStackList.text := array2str(stks,"\r\n");
Fdbgstack := stk;
end
if ifarray(stk)then
begin
FVaraiblesList.celldbclk := thisfunction(vdbclk);
FVaraiblesList.celledit := thisfunction(vdoedit);
FVaraiblesList.Showarray := thisfunction(vdoshowarray);
FStackList.OnDblClick := thisfunction(stkdbclk);
it := opengoto(stk[0]);
//if not it then return;
if it and it <> FCurrentgotoitem then
begin
if FCurrentgotoitem and FCurrentgotoitem.FEditer then
begin
FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",nil);
end
FCurrentgotoitem := it;
end
if FCurrentgotoitem then
begin
FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",stk[0,"LINE"]-1);
end
end
return;
end
"detached":
begin
if FConnectchannel then
begin
dbgdeletechannel(FConnectchannel);
FConnectchannel := 0;
g_tsldbgcallback_handle := nil;
FAttchedid := 0;
end
FRemoteWait := 0;
if FCurrentgotoitem and FCurrentgotoitem.FEditer then FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",nil);
ExecuteCommand("showeval","调试结束");
toolbtnState("停止");
return;
end
"DebugSysParamValue":
begin
CmdTypeAux := magicgetarray(d,array("result","CmdTypeAux"));
ev := magicgetarray(d,array("result","CmdData"));
cp := magicgetarray(d,array("result","CmdParam"));
len :=-1;
if ifnumber(CmdTypeAux)and(CmdTypeAux .& 0x80000000)then
begin
len := _shr((int(CmdTypeAux).& 0xFFF0),4);
end
//echo "\r\n***",len," ",cp," ",tostn(ev);
if(cp="#DebugEval")or(cp="#Error")then
begin
return showevaldata(nil,ev);
end
if ifarray(ev)then
begin
ddd := formatsysvlist(array(cp:ev),len);
FVaraiblesList.SetNodeData(ddd,true);
for i,v in ev do
begin
if ifstring(i)then
begin
ncp := tostn(i);
ncp := replacetext(ncp,".","\\o");
ncp := cp+".["+ncp+"]";
end else
begin
ncp := cp+".["+tostn(i)+"]";
end
magicsetarray(d,array("result","CmdParam"),ncp);
magicsetarray(d,array("result","CmdData"),v);
dbgeventcall(d);
end
return;
end else
begin
ddd := formatsysvlist(array(cp:ev),len);
FVaraiblesList.SetNodeData(ddd,true);
end
end
"DebugValue":
begin
cp := magicgetarray(d,array("result","CmdParam"));
ev := magicgetarray(d,array("result","CmdData"));
if(cp="#DebugEval")or(cp="#Error")then
begin
return showevaldata(nil,ev);
end
if ifarray(ev)then
begin
//showevaldata(cp,ev);
ddd := formatvlist(array(cp:ev));
FVaraiblesList.SetNodeData(ddd,true);
for i,v in ev do
begin
if ifstring(i)then
begin
ncp := tostn(i);
ncp := replacetext(ncp,".","\\o");
ncp := cp+".["+ncp+"]";
end else
begin
ncp := cp+".["+tostn(i)+"]";
end
magicsetarray(d,array("result","CmdParam"),ncp);
magicsetarray(d,array("result","CmdData"),v);
dbgeventcall(d);
end
return;
end else
begin
ddd := formatvlist(array(cp:ev));
FVaraiblesList.SetNodeData(ddd,true);
end
end
"noattachederror":
begin
return disconnectserver();
FRemoteWait := 0;
ExecuteCommand("showeval","noattachederror");
d["recvtype"]:= 0; //退出
dbgeventcall(d);
return;
end else
begin
//echo tostn(d);
end
end
return;
end
function showevaldata(cp_,ev);
begin
cp := cp_;
if cp then
begin
if parseregexpr("\\(\\w+\\)\\.",cp,"r", function(a)
begin
return "";
end
,s)=1 then
begin
cp := s;
end
end
if ev and ifarray(ev)then
begin
fwnd := getvalewnd(cp);
fwnd.TSLdata := ev;
fwnd.Show();
end else
begin
if cp then FShowText.Text += ">>"+cp+"\r\n";
ExecuteCommand("showeval",ev);
end
end
function ExecuteCommand(cmd,p);
begin
case cmd of
"dbgstate":
begin
if ifnil(p)then return FdebugState;
end
"execommand":
begin
case p of
"#127":
begin
FShowText.Text := "";
end
end;
end
"docmd":
begin
s := FCommandtext.Text;
if not s then return;
FCommandtext.Text := "";
if s="#cls" then return ExecuteCommand("execommand",s);
FShowText.Text += ">>"+s+"\r\n";
ExecuteCommand("dbgeval",s);
end
"clearall": //清除所有
begin
//FStackList.items := array();
//FStackList.text := "";
FStackList.DeleteAllItems();
FVaraiblesList.SetNodeData(array());
if p then
begin
FShowText.Text := "";
FCommandtext.Text := "";
end
end
"showeval":
begin
FShowText.Text += "ans="+tostn(p)+"\r\n";
FShowText.ExecuteCommand(FShowText.ecGotoXY,array(100000,1));
end
"dbgcreatechannel":
begin
if not FConnectchannel then
begin
idx := 0;
if not checkconnected()then
begin
while(FDebugtype="local")and(0 <> connectserver(FDebugaddr,FDebugport)) do
begin
sleep(100);
idx++;
if idx>20 then
begin
return ExecuteCommand("debugconnecterr");
end;
end
end
FConnectchannel := dbgcreatechannel();
setgdbcallback();
end
end
"dbggetallvalue":
begin
if FConnectchannel then
begin
dbggetallvalue(FConnectchannel);
end
end
"dbggetcurrentnode":
begin
FVaraiblesList.getcurrentnodedata();
end
"dbgreset": //停止
begin
if FConnectchannel then
begin
if FDebughandle then
begin
return SysTerminate(-1,FDebughandle);
end
if FAttchedid then
begin
//echo "\r\n终止";
return dbgdetach(FConnectchannel);
end else
begin
if FDebugtype="remotewait" then //远程,断开连接
begin
return disconnectserver();
end
return dbgdetach(FConnectchannel);
//return dbgreset(FConnectchannel);
end
end
end
"dbgrun": //运行
begin
if FConnectchannel then dbgrun(FConnectchannel);
end
"dbgstep":
begin
if FConnectchannel then dbgstep(FConnectchannel);
end
"dbgpause": //暂停
begin
if FConnectchannel then dbgpause(FConnectchannel);
end
"dbgstepover": //下一行
begin
if FConnectchannel then dbgstepover(FConnectchannel);
end
"dbgstepout": //跳出函数
begin
if FConnectchannel then dbgstepout(FConnectchannel);
end
"dbgeval": //执行
begin
if FConnectchannel and p and ifstring(p)then
begin
getvalewnd("ans");
dbgeval(FConnectchannel,p);
end
end
end
end
function Recycling();override;
begin
global g_tsldbgcallback_handle;
stopdebug();
inherited;
FStackList := nil;
FVaraiblesList := nil;
FToolbar := nil;
FCommandtext := nil;
FShowText := nil;
fimgelist := nil;
FBtns := nil;
g_tsldbgcallback_handle := nil;
fdbgselwnd := nil;
end
private
function getdefaultdbger();
begin
fdefaultdbger := gettslexe();
end
function getdebuger(pms); //获得调试程序
begin
p := static pluginpath();
FDebugExe := inireadstring("",p+"localediter.ini","debug","debuger","");
pms := " ";
//if FDebugExe="1" then //默认获取参数
// begin
ps := owner.getexecuteparams(FRuningfile);
if ps then
begin
psi := ps[0];
if fileexists("",psi)then
begin
cmdexe := psi;
end else
begin
if FDebugExe="1" then
ExecuteCommand("showeval","当前指定的执行程序不存在!!");
end
psi := ps[1];
if psi and fileexists("",psi)then
begin
end else
begin
pms += " "+tostn(psi);
end
idx := 2;
while idx<length(ps) do
begin
psi := ps[idx];
if lowercase(psi)="-libpath" then
begin
idx += 2;
continue;
end
pms += " "+tostn(psi);
idx++;
end
end
//end
if(FDebugExe="1")and cmdexe then
begin
FDebugExe := cmdexe;
ExecuteCommand("showeval","<当前执行程序(F9)做调试器>");
end else
if fileexists("",FDebugExe)then
begin
ExecuteCommand("showeval","<用配置文件给定的调试器>");
end else
begin
FDebugExe := fdefaultdbger;
ExecuteCommand("showeval","<用编辑器自带的调试器b:>");
end
end
function remotedbugok();
begin
if FAttchedid then
begin
ExecuteCommand("showeval","远程启动脚本:"+FAttchedid["info"]);
end
end
function remotewaitinit(d);
begin
if FDebugtype <> "remotewait" then return;
if FAttchedid then return;
FAttchedid := magicgetarray(d,array("result","CmdData","StartInfo"));
file := fdbgselwnd.getstartfilename(FAttchedid);
item := nil;
if file=0 then //不存在脚本
begin
if 1 <> MessageboxA("没找到本地对应的tsl\r\n是否继续调试","提示",1,self.Handle)then
begin
dbgdetach(FConnectchannel);
return "dbgdetach";
//return serwnd_cclk();
end
end else
begin
item := owner.OpenAndGotoFileByName(file,1);
end
FRuningItem := item;
FCurrentgotoitem := item;
parsercurrentitem(item);
setbrks(); //设置断点
remotedbugok();
end
function debuginitok();
begin
if FDebugtype <> "remotewait" then setbrks(); //设置断点
//showbtns(); //显示按钮
ExecuteCommand("showeval","开始调试");
//toolbtnState("暂停");
remotedbugok();
return;
end
function opengoto(v);
begin
cn := v["NAME"];
cnn := "";
for ii := 1 to length(cn) do
begin
if cn[ii]in array(".",":")then
begin
cn := cnn;
break;
end
cnn += cn[ii];
end
f := FDebugtsfs[lowercase(cn)];
if not f then
begin
return ExecuteCommand("showeval","找不到代码:"+cn);
end
it := owner.OpenAndGotoFileByName(f,v["LINE"]);
return it;
end
function cancelremotedbg(o,e,s);
begin
fdbgselwnd.Visible := false;
if e then e.skip := true;
if FConnectchannel then dbgdeletechannel(FConnectchannel);
FConnectchannel := 0;
ExecuteCommand("showeval",ifstring(s)?s:"取消远程调试...");
end
function stkdbclk(o,e);
begin
//echo "\r\n",o.SelectedId;
id := o.SelectedId;
if id >= 0 then
begin
d := o.GetItem(id);
if d then
begin
return opengoto(d);
end
end
end
function vdoshowarray(d);
begin
//echo tostn(d);
try
gp := d[3];
if(gp[length(gp)]="+")and parseregexpr("\\+$",gp,"r", function(a)
begin
return "";
end
,sgp)=1 then
begin
gp := "sysparams:"+sgp;
end
showevaldata(gp,d[1]["value"]);
except
end;
end
function vdoedit(d,s);
begin
if not FConnectchannel then return;
gp := d[1][3];
try
v := eval(&s);
except
v := nil;
end
if(gp[length(gp)]="+")and parseregexpr("\\+$",gp,"r", function(a)
begin
return "";
end
,sgp)=1 then
begin
dbgsetvalue(FConnectchannel,sgp,d[1][5],v);
sleep(20);
dbggetvalue(FConnectchannel,sgp,d[1][5]);
end else
begin
//echo "\r\nset: ",gp," ",v;
dbgsetvalue(FConnectchannel,gp,0,v);
sleep(20);
dbggetvalue(FConnectchannel,gp,0);
end
end
function vdbclk(o,e);
begin
if not FConnectchannel then return;
if(e[0]=1)and(e[1][2]="*")then
begin
gp := e[1][3];
if gp="sysparams+" then return;
if(gp[length(gp)]="+")and parseregexpr("\\+$",gp,"r", function(a)
begin
return "";
end
,sgp)=1 then
begin
dbggetvalue(FConnectchannel,sgp,e[1][5]);
end else
begin
dbggetvalue(FConnectchannel,gp,0);
end
end
end
function parsercurrentitem(item); //修正本地函数
begin
FDebugtsfs := class(TTSLCompletion).getdirtsfs();
if item then
begin
FRuningfile := item.OrigScriptPath; // %% E:\TSUIGROUP\script\tgdb.tsl%%;
FDebugtsfs["__main__"]:= FRuningfile;
ls := item.FEditer.lines;
d := tsl_tokenizeex_2_(item.FEditer.Text,0xffff);
for i,v in d["blcks"] do
begin
s := ls.GetStringByIndex(v["mbeg"]-1);
ctls := 0;
case v["mtype"]of //函数
11:
begin
ctls := "function\\s+(\\w+)\\(";
end
3:
begin
ctls := "type\\s+(\\w+)\\s*=\\s*class" //类
end
end;
if s and ctls and(parseregexpr(ctls,s,"si",m,mp,ml)=1)then
begin
n := lowercase(m[0,1]);
FDebugtsfs[n]:= FRuningfile;
end
end
end
end
function toolbtnState(flg);
begin
case flg of
"启动","暂停":
begin
showbtns();
FBtns["暂停"].Visible := false;
FBtns["刷新符号表"].Visible := true;
FBtns["刷新当前符号"].Visible := true;
end
"继续":
begin
//运行
FBtns["继续"].Visible := false;
FBtns["进入"].Visible := false;
FBtns["跳出"].Visible := false;
FBtns["下一行(F8)"].Visible := false;
//FBtns["单步"].Visible := false;
FBtns["终止"].Visible := false;
FBtns["暂停"].Visible := true;
FBtns["刷新符号表"].Visible := false;
FBtns["刷新当前符号"].Visible := false;
end
"停止":
begin
hiddenbtns();
end
end
end
function showbtns(); //显示
begin
for i,v in FBtns do
begin
V.Visible := true;
end
//FToolbar.Visible := true;
end
function hiddenbtns(); //隐藏
begin
for i,v in FBtns do
begin
if v.Caption="添加/删除断点F5" then continue;
v.Visible := false;
end
//FToolbar.Visible := false;
end
function stopdebug(); //结束进程
begin
if FDebughandle then
begin
SysTerminate(-1,FDebughandle);
FDebughandle := 0;
end
end
function parseriteminfo(item,idx,n,usr);
begin
if item=FRuningItem then
begin
usr := "local";
n := "__main__";
end else
begin
usr := "system";
end
if not n then
begin
n := getscriptname(item.OrigScriptPath);
end
end
function getscriptname(nn);
begin
fio := ioFileseparator();
n := "";
for i := Length(nn)-1 downto 1 do
begin
if fio=nn[i]then
begin
n := nn[i+1:];
idx := pos(".",n);
if idx then
begin
n := lowercase(n[1:idx-1]);
end
break;
end
end
return n;
end
function setbrks(); //初次添加断点
begin
its := owner.GetAllPageItems().data;
for i,v in FDebugtsfs do
begin
delii :=-1;
for ii,vv in its do
begin
ifok := vv.ScriptPathIs(v);
if ifok then
begin
delii := ii;
lines := vv.FEditer.Lines;
for idx := 0 to Lines.Length()-1 do
begin
if Lines[idx].FMarked then addbreak(vv,idx,i);
end
break;
end
end
if delii <> 0 then
begin
reindex(its,array(delii:nil));
end
end
if FRuningItem then
begin
lines := FRuningItem.FEditer.Lines;
for idx := 0 to Lines.Length()-1 do
begin
if Lines[idx].FMarked then addbreak(FRuningItem,idx,"__main__");
end
end
end
function setgdbcallback(); //设置回调
begin
global g_tsldbgcallback_handle;
g_tsldbgcallback_handle := thisfunction(dbgeventcall);
dbgsetcallback(FConnectchannel,"return unit(UtslCodeEditor).tdbgcallback();");
end
function formatvlist(d);
begin
r := array();
ncs := array();
{
ddd := array();
for i,v in dd do
begin
ddd[i]["id"] := v["n"];
ddd[i]["data"] := array(v["c"],v["v"],v["t"],v["n"]);
ddd[i]["pid"] := v["p"];
end
}
idx := 0;
for i,v in d do
begin
ri := parservname(i,v);
for j,vj in ri do
begin
id := vj["n"];
if ncs[id]then continue;
ncs[id]:= true;
r[idx]["id"]:= id;
vjt := vj["t"];
vjv := vj["v"];
if vjt="*" then
begin
vval := array("value":vjv,"font":("color":0xff0000));
end else
if ifarray(vjv)then
begin
vval := array("value":vjv,"font":("color":0));
end else
if ifstring(vjt)and(vjt <> "nil")then
begin
vval := array("value":tostn(vjv),"font":("color":0));
end else
begin
vval := array("value":"","font":("color":0));
end
r[idx]["data"]:= array(vj["c"],vval,vj["t"],vj["n"],id);
r[idx]["pid"]:= vj["p"];
r[idx]["nnp"]:= vj["nnp"];
idx++;
end
end
return r;
end
function formatsysvlist(d,len);
begin
r := array();
ncs := array();
idx := 0;
for i,v in d do
begin
ri := parsersysname(i,v,len);
for j,vj in ri do
begin
id := vj["n"];
if ncs[id]then continue;
ncs[id]:= true;
r[idx]["id"]:= id;
vjt := vj["t"];
vjv := vj["v"];
if vjt="*" then
begin
vval := array("value":vjv,"font":("color":0xff0000));
end else
if ifarray(vjv)then
begin
vval := array("value":vjv,"font":("color":0));
end else
if ifstring(vjt)and(vjt <> "nil")then
begin
vval := array("value":tostn(vjv),"font":("color":0));
end else
begin
vval := array("value":"","font":("color":0));
end
r[idx]["data"]:= array(vj["c"],vval,vjt,vj["n"],id,vj["len"]);
r[idx]["pid"]:= vj["p"];
r[idx]["nnp"]:= vj["nnp"];
idx++;
end
end
return r;
end
function gettypename(ev);
begin
case datatype(ev)of
0:t := "int"; //处理长整型的问题
20:t := "int64";
24:t := "lstr";
1:t := "double";
2:t := "str";
5:t := "array";
else t := "nil";
end;
return t;
end
function parsersysname(ostring,ev,nlen);
begin
len := length("*TSL_UNComplete*");
ucp := false;
if pos("*TSL_UNComplete*",ostring)=1 then
begin
ucp := true;
if Length(ostring)=len then //空串
begin
nstr := "";
return array();
end else
nstr := ostring[len+1:];
end else
nstr := ostring;
r := array();
if ucp then t := "*";
else t := gettypename(ev);
nid := "";
r[0]:= array("n":"sysparams+",
"c":array("font":("color":0x0000ff,"italic":1),"value":"sysparams")
);
if nlen >= 0 then
begin
nnl := 0x80000000+_shl(nlen,4)+1;
cn := "";
if nlen=0 then
begin
r[1]:= array("n":"+",
"c":tostn(""),
"len":nnl,
"p":"sysparams+"
);
end else
begin
cn := nstr[1:nlen];
r[1]:= array("n":cn+"+",
"c":cn,
"len":nnl,
"p":"sysparams+"
);
if nlen<length(nstr)then
begin
nstr := nstr[nlen+1:];
end else
nstr := "";
end
dd := str2array(nstr,".");
dd[0]:= cn;
ldd := length(dd)-1;
for i,v in dd do
begin
cl := 0x0000ff;
nid += v;
if(i=0)then
begin
vi := tostn(v);
end else
begin
vi := v;
//cl := 0xff0000;
end
if 1=parseregexpr("^\\(\\w+\\)$",vi,"i",p11,p111,p1111)then
begin
np := 1;
cl := 0x008080;
end else
np := 0;
r[i+1]:= array("c":array("font":("color":cl),"value":vi),"i":false,"n":nid+"+","p":r[i]["n"],"len":nnl,"nnp":np);
if i<ldd then nid += ".";
end
r[i+1]["t"]:= t;
r[i+1]["v"]:= ev;
end else
begin
nnl := 0x80000000+_shl(length(nstr),4)+1;
r[1]:= array("n":nstr+"+",
"c":("font":("color":0x0000ff),"value":tostn(nstr)),
"t":t,
"v":ev,
"len":nnl,
"p":"sysparams+"
);
end
return r;
end
function parservname(ostring,ev);
begin
len := length("*TSL_UNComplete*");
ucp := false;
if pos("*TSL_UNComplete*",ostring)=1 then
begin
ucp := true;
nstr := ostring[len+1:];
end else
nstr := ostring;
len := length(nstr);
r := array();
if ucp then t := "*";
else
begin
t := gettypename(ev);
end
nid := "";
dd := str2array(nstr,".");
ldd := length(dd)-1;
for i,v in dd do
begin
cl := 0;
nid += v;
if 1=parseregexpr("^\\(\\w+\\)$",v,"i",p11,p111,p1111)then
begin
np := 1;
cl := 0x008080;
end else
np := 0;
r[i]:= array("c":("value":v,"font":("color":cl)),"i":false,"n":nid,"p":r[i-1]["n"],"nnp":np);
if i<ldd then nid += ".";
end
r[i]["n"]:= nstr;
r[i]["t"]:= t;
r[i]["v"]:= ev;
return r;
end
function getobjtransfunc();
begin
return %%
function _show_dbg_obj(o_,ct,mus);
begin
r := array();
if ifarray(o_) then
begin
for i,v in o_ do
begin
r[i] := _show_dbg_obj(v,ct,mus);
end
return r;
end else
if not ifobj(o_) then return o_;
if not ifarray(mus) then mus := array();
if o_ in mus then return "<object>";
o := o_;
obk := o;
try
stk := array();
idx :=0;
while idx<(ct>0?ct:3) do
begin
mus[length(mus)] := o;
d := o.classinfo();
stk[idx,0] := o;
stk[idx,1] := d;
inh := d["inherited"];
if not inh then break;
o := findclass(inh[0],o);
idx++;
end
for idx := length(stk)-1 downto 0 do
begin
o:=stk[idx,0];
for i,v in stk[idx,1,"properties"] do
begin
n := v["name"];
if v["read"] and (v["access"] in array(0,1)) then
begin
r[n] := 0;
end else
begin
reindex(r,array(n:nil));
end
end
for i,v in stk[idx,1,"members"] do
begin
n := v["name"];
if v["access"] in array(0,1) then
begin
r[n] := 0;
end else
begin
reindex(r,array(n:nil));
end
end
end
rs := mrows(r,1) ;
for i := length(rs)-1 downto 0 do
begin
v := rs[i];
nv := invoke(obk,v);
if datatype(nv)=7 then r[v] := "<function>";
else if ifarray(nv) then r[v] := _show_dbg_obj(nv,ct,mus);
else if ifobj(nv) then r[v] := _show_dbg_obj(nv,ct,mus);
else r[v] := _show_dbg_obj(nv,ct,mus);
end
except
return r;
end;
return r;
end
%%;
end
FStackList;
FVaraiblesList;
FToolbar;
FCommandtext;
FShowText;
fimgelist;
end
type TFindListWnd=class(TListBox) //查找的地方
function Create(AOwner);
begin
inherited;
end
function CheckListItem(s);override;
begin
return ifarray(s);
end
function GetItemText(i);override;
begin
it := GetItem(i);
if it then r := it["caption"];
if not ifstring(r)then return "";
return r;
end
Published
private
end
type TGoToLineWnd=class(TVCForm) //跳转
function Create(AOwner);override;
begin
inherited;
wssizebox := false;
minmaxbox := false;
WsDlgModalFrame := true;
width := 300;
height := 80;
caption := "转到..";
FLabel := new TLabel(self);
FLabel.SetBoundsRect(array(3,10,70,35));
FEdit := new TEdit(self);
FEdit.SetBoundsRect(array(75,10,200,35));
FBtn := new TBtn(self);
FBtn.SetBoundsRect(array(210,10,280,35));
FLabel.Caption := "目标位置:";
FBtn.Caption := "定位";
FLabel.parent := self;
FEdit.parent := self;
FEdit.OnKeyPress := function(o,e)
begin
if e.CharCode=13 then
begin
e.skip := true;
GotoTextInteger();
end
end
OnClose := function(o,e)
begin
o.visible := false;
e.skip := true;
end
FBtn.parent := self;
FBtn.OnClick := function(o,e)
begin
GotoTextInteger();
end
end
function DoControlAlign();override;
begin
end
function ShowGoto();
begin
show();
FEdit.SetFocus();
FEdit.Text := "";
end
private
function GotoTextInteger();
begin
id := FEdit.Text;
id := StrToIntDef(id,0);
if id>0 then
begin
it := Owner.GetCurrentItem();
Visible := false;
Owner.OpenAndGotoFileByName(it.ScriptPath,id);
//it.SetFocus();
//return ;
it := Owner.GetCurrentEditer();
if not it then return;
//it.ExecuteCommand(it.ecGotoXY,array(id,1));
//Visible := false;
it.SetFocus();
end
end
FEdit;
FBtn;
end
type TTslCodeMap=class(TTreeView) //tsl代码地图
function Create(AOwner);
begin
inherited;
caption := "代码树:支持[左/右/上/下/enter]键";
width := 400;
height := 800;
WsPopUp := true;
WsSysMenu := true;
WsSizeBox := true;
OnClose := function(o,e)
begin
o.visible := false;
e.skip := true;
if not FTreeEditer then return;
FTreeEditer.SetFocus();
end
OnActivate := function(o,e)
begin
if not e.wparam then CodeMapLive(o,e);
{o.Visible := false;
if not FTreeEditer then return;
FTreeEditer.SetFocus();}
end
onKeyPress := thisfunction(CodeMapLive);
//OnDblClick := thisfunction(SynNodeSelected);
OnSelChanged := thisfunction(SynNodeSelected);
end
function CodeMapLive(o,e);
begin
o.Visible := false;
if not FTreeEditer then return;
FTreeEditer.SetFocus();
end
function SynNodeSelected(o,e);
begin
//双击
if not FTreeEditer then return;
nd := CurrentNode;
line := nd._tag;
if line>0 then
begin
FTreeEditer.ExecuteCommand(FTreeEditer.ecGoToXY,array(line,1));
end
end
function hasFocus();override;
begin
return true;
end
function ShowMap();
begin
FTreeEditer := nil;
it := Owner.GetCurrentItem();
if not it then return;
//caption := "codemap:"+it.ScriptPath;
FTreeEditer := it.FEditer;
s := FTreeEditer.Text;
if FString <> s then
begin
FString := s;
LoadString(s,FTreeEditer.CaretY);
end else
GoToTheNode(FTreeEditer.CaretY);
end
function Recycling();override;
begin
inherited;
FTempNodes := nil; //节点
FEditer := nil;
FString := nil;
FTreeEditer := nil;
end
private
function LoadString(s,line);
begin
{ 代码块快类型
#define Block_TypeClass 1
#define Block_Function 2
#define Block_Statements 4
#define Block_If 8
#define Block_Else 16
#define Block_SubCase 32
#define Block_Goto_Label 64
#define Block_Empty_Begin_End 128
#define Block_Try 256
#define Block_NeedSql 512
#define Block_UnitStruct 1024
}
if s then r := tsl_tokenizeex_2_(s,1+2+4+8+16+32+256+1024+2048+4096);
else r := array();
RootNode.RecyclingChildren();
FTempNodes := array();
ScriptDelBlocks(r["blcks"],str2array(s,"\r\n"),self.RootNode,0);
GoToTheNode(line);
end
function GoToTheNode(line);
begin
nd := FTempNodes[0];
for i,v in FTempNodes do
begin
if v._tag <= line then
begin
nd := v;
end else
if v._tag >= Line then
begin
SetSel(nd);
break;
end
end
Show();
if _wapi.GetFocus()<> Handle then
begin
SetFocus();
end
end
function ScriptDelBlocks(blcks,strs,Node,ct);
begin
if not blcks then return;
for i,v in blcks do
begin
if v["mtype"]<> 1 then
begin
cnd := CreateTreeNode();
cnd.Caption := trim(strs[v["mbeg"]-1]);
cnd._tag := v["mbeg"];
FTempNodes[length(FTempNodes)]:= cnd;
cnd.parent := node;
end
if not cnd then cnd := node;
ScriptDelBlocks(v["msub"],strs,cnd,ct+1);
end
end
FTempNodes; //节点
FString; //字符串
FTreeEditer; //编辑框
end
type TEditer=class(TCustomcontrol) //包括工具栏,状态栏,输出,查找
function Create(AOwner);override;
begin
inherited;
FOpenHistory := new TMyarrayb();
FFistShows := array();
FSynHCS := New TMyArrayA();
//构造部件
FLastDispathTime := now();
FTslexe := gettslexe() ;//SysExecName();
FTabChar := " ";
FTabWidth := 4;
FCurrentItemCode := array();
FGoBackA := new TMyarrayB();
FGoBackB := new TMyarrayB();
FToolbar := new TToolBar(self); //工具栏
FStatus := new TStatusBar(self); //状态栏
FInfoShowWnd := new TEditerAuxiliary(self);
FPageEditer := new TPageEditer(self);
//FPageEditer.CloseBtn := true;
FPageEditer.Onbmpbclick := function(o,e)
begin
it := e._Tag;
if not it then return ;
if JudgeItemState(it)then return;
if it.FEditer.ChangedFlag then
begin
mr := MessageboxA(format("是否保存:%s",it.OrigScriptPath),"提示",3,self);
if mr=IDYES then
begin
SavePageItem(it);
end else
if mr=IDCANCEL then
begin
return;
end
end
DeletePageItem(it);
o.CallSelChanged();
end
FPageEditer.OnCloseClick := function(o,e)
begin
it := GetCurrentItem();
if not it then return ;
if JudgeItemState(it)then return;
if it.FEditer.ChangedFlag then
begin
mr := MessageboxA(format("是否保存:%s",it.OrigScriptPath),"提示",3,self);
if mr=IDYES then
begin
SavePageItem(it);
end else
if mr=IDCANCEL then
begin
return;
end
end
DeletePageItem(it);
end;
FFindWnd := new TFindWnd(self); //查找
FGotoLineWnd := new TGoToLineWnd(self); //共同
FListPages := new TListPages(self); //tab 跳转页面
FEchoWnd := new TEditerEchoWnd(self);
FEchoWnd.font := array("height":16,"width":8,"escapement":0,"orientation":0,"weight":400,"italic":0,"underline":0,"strikeout":0,
"charset":0,"outprecision":0,"clipprecision":0,"quality":1,"pitchandfamily":1,"facename":"Courier New","color":0);
FTslDebug := new TTslDebug(self);
FFindListWnd := new TFindListWnd(self);
FCodeMap := new TTslCodeMap(self);
FFileopen := new TOpenFileADlg(self);
FFileSave := new TSavefileADlg(self);
FFileopen.WndOwner := self;
FFileSave.WndOwner := self;
//初始部件
//////////////////////////////////////
FEchoWnd.Border := true;
FEchoWnd.WsSysMenu := false;
FEchoWnd.WsSizeBox := false;
FEchoWnd.Caption := "echo...";
FFindListWnd.Caption := "find....";
FFindListWnd.OnDblClick := thisfunction(FindListChoosed);
FGotoLineWnd.Visible := false;
/////////////////////////
FCodeMap.visible := false;
FFindWnd.Visible := false;
FFileSave.Filter := array("any":"*.*","tsl文件":"*.tsl;*.tsf");
FFileSave.Caption := "另存为";
FFileopen.Filter := array("any":"*.*","tsl文件":"*.tsl;*.tsf");
FPageEditer.OnSelChanged := thisfunction(PageItemSelChanged);
////////
FListPages.Visible := false;
////////////////////////////
FPageMenu := new TPopUpMenu(self);
for i,v in array("关闭","关闭其他标签","复制文件名","复制文件全名","重新加载","打开目录","另存为") do
begin
mi := new TMenu(self);
mi.Caption := v;
mi.Parent := FPageMenu;
mi.OnClick := thisfunction(PageMenuClick);
end
FExecuteEditer := new TExecuteEditer(self);
FExecuteEditer.visible := false;
////////////
FPageEditer.PageItemOnRClick := thisfunction(PageItemOnRClick);
FImages := new TControlImageList(self);
FImages.Width := 22;
FImages.Height := 22;
bmp := new TBitmap();
imgs := GetEditIcons();
id := 0;
FToolbtns := array();
dbgbtns := array();
for i,v in imgs do
begin
bmp.Readvcon(HexFormatStrToTsl(v));
FImages.addbmp(bmp);
bt := new TToolButton(self);
FToolbtns[i]:= bt;
bt.OnClick := thisfunction(ToolClick);
bt.Caption := i;
bt.imageid := id;
id++;
BT.parent := FToolbar;
if i in array("添加/删除断点F5","暂停","继续","进入","跳出","单步","下一行(F8)","终止","刷新符号表","刷新当前符号")then
begin
dbgbtns[i]:= bt;
end
end
FImages.DrawBimpFirst := true;
FTslDebug.addbtns(dbgbtns);
FToolbar.ImageList := FImages;
FInfoShowWnd.Visible := false;
//FInfoShowWnd.WsSysMenu := true;
FInfoShowWnd.WSsizebox := true;
FInfoShowWnd.height := 200;
//FInfoShowWnd.OnSize := thisfunction(DoControlAlign);
FInfoShowWnd.OnCloseClick := function(o,e)
begin
o.visible := false;
e.skip := true;
DoControlAlign();
end
/////////////////////
FStatus.Items := array(("text":"","width":0.85),("text":"","width":0.16));
/////////////////////////////////////////
//FInfoShowWnd.Caption := "信息:";
////构造节点////////////////////////////////////////////////////
FToolBar.Parent := self;
FStatus.Parent := self;
FInfoShowWnd.Parent := self;
FPageEditer.Parent := self;
FCodeMap.parent := self;
FGotoLineWnd.Parent := self;
FFindWnd.parent := self;
FFileopen.parent := self;
FFileSave.parent := self;
FListPages.parent := self;
FExecuteEditer.parent := self;
//FEchoWnd
FInfoShowWnd.AddWnd(FEchoWnd);
FInfoShowWnd.AddWnd(FFindListWnd);
FInfoShowWnd.AddWnd(FTslDebug);
FTempPageItem := new TPageEditerItem(FPageEditer);
/////////////
FSynClasses["txt"]:= array(class(TSynHighLighter),class(TSynCompletion),";txt;");
FSynClasses["tsl"]:= array(class(TTslSynHighLighter),class(TTslCompletion),";tsl;tsf;pas;stm;");
FSynClasses["json"]:= array(class(TJsonSynHighLighter),class(TSynCompletion),";json;");
FSynClasses["ini"]:= array(class(TINISynHigLighter),class(TSynCompletion),";ini;");
FSynClasses["bat"]:= array(class(TBatSynHigLighter),class(TSynCompletion),";bat;cmd;");
FSynClasses["None"]:= array(nil,nil,"");
//FSynClasses["tsf"] := FSynClasses["tsl"];
FTslChmHelp := new TTslChmHelp();
FCodeFormatInfo := array("wordct":80,"charct":200,"syn":true,"sel":false,"arraytype":0);
FPageEditer.OnDblClick := function(o,e)
begin
CreateAFile();
end
end
function PopUpAuxiliary();
begin
FInfoShowWnd.ShowPopUp();
end
function ClearPageItemMark(it);
begin
if not it then it := GetCurrentItem();
if not it then return;
ed := it.FEditer;
ls := ed.Lines;
canval := false;
for i := 0 to ls.length()-1 do
begin
li := ls[i];
if li.FMarked then
begin
li.FMarked := false;
canval := true;
end
end
if canval then ed.InValidateRect(nil,false);
end
function GetAllPageItems();
begin
return FPageEditer.PageItems;
end
function SaveFileByName(n);
begin
for i,v in FPageEditer.PageItems.Data do
begin
if v.ScriptPathIs(n)then
begin
return SavePageItem(v);
end
end
end
function GetAllPagesInfo();
begin
r := array();
its := FPageEditer.PageItems;
for i := 0 to its.Length()-1 do
begin
it := its[i];
r["pages"][i]["filename"]:= it.OrigScriptPath;
edt := it.FEditer;
r["pages"][i]["r"]:= edt.TopLine; //edt.CaretY;
ls := edt.Lines;
f2s := array();
for j := 0 to ls.Length()-1 do
begin
if ls[j].FMarked then f2s[j]:= true;
end
r["pages"][i]["f2"]:= f2s;
r["pages"][i]["isnewfile"]:= it.fisnewfile;
end
it := GetCurrentItem();
if it then
begin
r["currentpage"]:= array(it.OrigScriptPath,it.FEditer.TopLine);
end
//FPageEditer.DoControlAlign();
return r;
end
function CloseScriptByFileName(n);
begin
for i,v in FPageEditer.PageItems.Data do
begin
if v.ScriptPathIs(n)then
begin
return DeletePageItem(v);
end
end
end
function CloseAllPageItems(it);
begin
its := FPageEditer.PageItems;
tits := its.Data;
FPageEditer.CloseAllItem(it);
for i,v in tits do
begin
if v=it then
begin
cit := it;
continue;
end
v.Recycling();
end
if cit then cit.FEditer.ReCreateCaret();
end
function SaveAllPageItems(); //保存所有
begin
its := FPageEditer.PageItems;
for i,v in its.Data do
begin
JudgeItemState(v);
end
its := FPageEditer.PageItems;
for i := 0 to its.Length()-1 do
begin
SavePageItem(its[i]);
end
end
function WMUSER(o,e):WM_USER;override;
begin
inherited;
if e.wparam=101 and e.lparam=102 then
begin
self.Enabled := true;
end
end
function EndFind();
begin
FIsFinding := false;
_send_(WM_USER,101,102,1);
end
function DoFind(d,o);
begin
if FIsFinding then return;
o.SetStatusText("查找.....");
o.SaveCurrentEditer();
self.Enabled := false;
FIsFinding := true;
if not(d["c_reg"])then
begin
if(d["section"]="查找")and(d["btn"]="全部查找")then
begin
FFindListWnd.Clean();
ShowFindWnd();
FindAllInCurrent(d,o,nil,ct);
o.SetStatusText(format("查找到 %d处",ct));
return EndFind();
end else
if(d["section"]in array("查找","替换"))and(d["btn"]="查找")then
begin
FindInCurrent(d,o);
return EndFind();
end else
if(d["section"]in array("替换"))and(d["btn"]="替换")then
begin
if d["replace"]<> d["target"]then FindInCurrent(d,o,nil,1);
return EndFind();
end else
if(d["section"]in array("替换"))and(d["btn"]="全部替换")then
begin
if d["replace"]<> d["target"]then
begin
FFindListWnd.Clean();
ShowFindWnd();
ReplaceAllInCurrent(d,o,nil,idx);
o.SetStatusText(format("替换 %d处",idx));
end
return EndFind();
end else
if(d["section"]in array("文件查找"))and(d["btn"]="全部替换")then
begin
FFindListWnd.Clean();
ShowFindWnd();
FindInFiles(d,o,true,ct);
o.SetStatusText(format("总共替换 %d处",ct));
return EndFind();
end else
if(d["section"]in array("文件查找"))and(d["btn"]="查找")then
begin
FFindListWnd.Clean();
ShowFindWnd();
FindInFiles(d,o,false,ct);
o.SetStatusText(format("总共查找 %d处",ct));
return EndFind();
end
end
o.SetStatusText("功能开发中....");
EndFind();
end
function DebugPageItem(it,h);
begin
if not it then return;
showdbugwnd();
FTslDebug.Debuglocal(it);
end
function Debugremote(it);
begin
showdbugwnd();
FTslDebug.Debugremote(it);
end
function DbgNextLine();
begin
FTslDebug.DbgNextLine(); //FDebuger
end
function ExecutePageItem(it,h);
begin
if not it then return;
ShowEchoWnd();
//exe :=(FTslExe and ifstring(FTslExe))?FTslExe:SysExecName();
if FEchoWnd.Exeing()then FEchoWnd.Endexe();
s := FExecuteEditer.GetCurrentExuteString(it.Scriptpath);
// echo s,"\r\n";
FEchoWnd.Exec(s,"",h);
//FEchoWnd.Exec(exe,format('"%s" -libpath "%s"',it.ScriptPath,getdirfromfile(it.ScriptPath)),h);
end
{function ExecutePageItemWithCmd(it);
begin
s := FExecuteEditer.GetCurrentExuteString(it.Scriptpath);
hd := "d:\\test\\execmd.cmd";
//RewriteString(hd,s);
_wapi.WinExec("cmd.exe",1);
//_wapi.WinExec("",1);
//SysExec("","cmd.exe /c " + s,nil,false,c,nil);
//echo "===\r\n";
end }
function SavePageItem(it,f);
begin
if not it then return -1;
if f or it.PrePareSave()then
begin
it.FEditer.ChangedFlag := false;
s := it.LastText;
case it.EnCode of
"UTF8":
begin
s := AnsiToutf8(it.LastText);
end
"UTF8 BOM":
begin
//0xEF, 0xBB, 0xBF
s := " ";
s[1]:= 0xEF;
s[2]:= 0xBB;
s[3]:= 0xBF;
s += AnsiToutf8(it.LastText);
//ECHO "SAVE UTFB-BOM\r\n";
end
"UCS2-little":
begin
s := " ";
s[1]:= 0xFF;
s[2]:= 0xFE;
s += multibytetounicode(it.LastText,936);
end
"UCS2-big":
begin
s2 := " ";
s2[1]:= 0xFF;
s2[2]:= 0xFE;
s2 += multibytetounicode(it.LastText,936);
s := "";
setlength(s,length(s2));
for i := 1 to length(s2)-1 step 2 do
begin
s[i]:= s2[i+1];
s[i+1]:= s2[i];
end
end
end;
fp := it.OrigScriptPath;
if it.FISstm then
begin
try
v := eval(&s);
//s := tostm(v);
r := exportfile(ftstream(),"",fp,v);
it.ReGetLastLoadTime();
return r;
except
end
end
r := ReWriteString(fp,s);
it.ReGetLastLoadTime();
return r;
end
return 1;
end
function ShowFindWnd();
begin
FInfoShowWnd.ShowByTag(FFindListWnd);
ShowLogWnd(true);
end
function showdbugwnd();
begin
FInfoShowWnd.ShowByTag(FTslDebug);
ShowLogWnd(true);
end
function ShowEchoWnd();
begin
FInfoShowWnd.ShowByTag(FEchoWnd);
ShowLogWnd(true);
end
function SwitchLogWnd();
begin
FInfoShowWnd.Visible := not(FInfoShowWnd.Visible);
DoControlAlign();
end
function SetFindHistroy(d);
begin
FFindWnd.SetHistory(d);
end
function GetFindHistory();
begin
return FFindWnd.GetHistory();
end
function ShowLogWnd(flg);
begin
n :=(ifnil(flg)or flg)?true:false;
if n=FInfoShowWnd.Visible then return;
FInfoShowWnd.Visible := n;
DoControlAlign();
end
function JudgeItemState(it); //状态处理
begin
lt := it.GetLastLoadTime();
nlt := it.ReGetLastLoadTime();
if not lt then return;
if nlt <> lt then
begin
FPageEditer.FCanDraged := false;
FPageEditer.MouseDrageLeave(); //此处不知为什么会报错
if not nlt then //已经删除
begin
if Messageboxa("文件已经被删除,依然保存请按确定","提示",1,self)=IDOK then
begin
CreateDirWithFileName(it.OrigScriptPath); //新建
SavePageItem(it,true);
end else
begin
DeletepageItem(it); //删除
return true;
end
end else //被其他程序修改
begin
if Messageboxa(format("%s\r\n被其他程序修改是否重新加载",it.ScriptPath),"提示",1,self)=IDOK then
begin
LoadFromFile(it,true);
end else
begin
it.FEditer.ChangedFlag := true;
end
end
end
end
function PageItemTextChanged(o,flg);
begin
its := FPageEditer.Pageitems;
cit := GetCurrentItem();
for i := 0 to its.Length()-1 do
begin
it := Its[i];
if it.FEditer=o then
begin
if cit=it then
begin
if it.fisnewfile then Caption := (flg?"*":"")+" new ";
else
Caption :=(flg?"*":"")+it.OrigScriptPath;
end
callDatafunction(OnPageEditerChanged,it,flg);
it.BitmapA := flg?GetNeedSaveBmp():GetNneedSaveBmp();
return;
end
end
end
function DeletePageItem(it);
begin
idx := FPageEditer.GetItemIndex(it);
if idx >= 0 then
begin
//f := it.OrigScriptPath;
FPageEditer.DeleteItemByIndex(idx);
it.Recycling();
it := GetCurrentItem();
if it then it.FEditer.ReCreateCaret();
//if it.fisnewfile then filedelete("",f);
end
end
function PageItemSelChanged(o,e);virtual;
begin
it := GetCurrentItem();
if not it then return;
//if JudgeItemState(it) then return ;
FCurrentItemCode[length(FCurrentItemCode)]:= it;
if it.fisnewfile then
begin
Caption :=(it.FEditer.ChangedFlag?"*":"")+" new ";
end
else
begin
Caption :=(it.FEditer.ChangedFlag?"*":"")+it.OrigScriptPath;
end
CallDatafunction(FOnPageItemSelChanged,self(true),it);
cp := it.FEditer.Completion;
if cp and it.FInitCompletion then
begin
it.FInitCompletion := false;
cp.PrePareCompletion(it.Caption);
end
EditerCaretChanged(it.FEditer,nil);
end
function PageMenuClick(o,e);
begin
it := GetCurrentItem();
if not it then return;
case o.Caption of
"关闭":
begin
if it.fisnewfile then //单独处理新建关闭
begin
f := it.OrigScriptPath;
DeletePageItem(it);
if fileexists("",f) then filedelete("",f);
return ;
end
if JudgeItemState(it)then return;
if it.FEditer.ChangedFlag then
begin
mr := MessageboxA(format("是否保存:%s",it.OrigScriptPath),"提示",3,self);
if mr=IDYES then
begin
if SavePageItem(it)=0 then
begin
it.FEditer.ChangedFlag := true;
return 0;
end
end else
if mr=IDCANCEL then
begin
return;
end
end
DeletePageItem(it);
end
"关闭其他标签":
begin
Cit := it;
its := GetAllPageItems();
for i := 0 to its.Length()-1 do
begin
it := its[i];
if it.FEditer.ChangedFlag then
begin
r := MessageBoxA("存在未保存的文件,是否保存!","提示",3,self);
if r=IDYES then
begin
SaveAllPageItems();
break;
end else
if r=IDCANCEL then
begin
return;
end else
begin
end
break;
end
end
CloseAllPageItems(Cit);
end
"另存为":
begin
if JudgeItemState(it)then return;
//FFileopen.OverwritePrompt := true;
if FFileSave.OpenDlg()then
begin
fn := FFileSave.FileName;
dfn := it.ScriptPath;
CreateDirWithFileName(fn);
//echo format('FileCopy("","%s","","%s",false)',dfn,fn);
ret := FileCopy("",dfn,"",fn,false);
if ret then
begin
it.ScriptPath := fn;
if SavePageItem(it)=0 then
begin
it.FEditer.ChangedFlag := true;
end
if it.fisnewfile then
begin
FileDelete("",dfn);
it.fisnewfile := false;
end
end
end
//FFileopen.OverwritePrompt := false;
end
"重新加载":
begin
LoadFromFile(it,true);
end
"复制文件全名":
begin
if not FCliper then FCliper := new TClipBoard(self);
FCliper.text := it.OrigScriptPath;
end
"复制文件名":
begin
if not FCliper then FCliper := new TClipBoard(self);
FCliper.text := it.Caption;
end
"打开目录":
begin
p := it.ScriptPath;
if FileExists("",p)then
begin
for i := length(p)downto 3 do
begin
if p[i]="\\" then
begin
p := p[1:i];
break;
end
end
//_wapi.WinExec('cmd.exe /C start "" "'+p,1);
_wapi.openresourcemanager(p);
end
end
"采用cmd执行":
begin
//ExecutePageItemWithCmd(it);
end
end
end
function PageItemOnRClick(o,e);
begin
if FPageEditer.GetItemIndexByPos(e.pos)>= 0 then o.PopUpMenu := FPageMenu;
else o.PoPupMenu := nil;
end
function PageEditerMenuClick(o,e);
begin
if pos("复制",o.caption)=1 then
begin
it := GetCurrentItem();
if it then
begin
ed := it.FEditer;
if ed then
begin
ed.ExecuteCommand(ed.ecCopy);
end
//it.FEditer.ReadOnly := not(o.Checked);
end
return;
end else
if pos("粘贴",o.caption)=1 then
begin
it := GetCurrentItem();
if it then
begin
ed := it.FEditer;
if ed then
begin
ed.ExecuteCommand(ed.ecPaste);
end
//it.FEditer.ReadOnly := not(o.Checked);
end
return;
end else
if pos("剪切",o.caption)=1 then
begin
it := GetCurrentItem();
if it then
begin
ed := it.FEditer;
if ed then
begin
ed.ExecuteCommand(ed.ecCut);
end
//it.FEditer.ReadOnly := not(o.Checked);
end
return;
end else
if pos("定位",o.caption)=1 then
begin
InitShowWndPos(FGotoLineWnd,"g",200,200);
FGotoLineWnd.ShowGoto();
return;
end else
if pos("查看",o.caption)=1 then
begin
cs := o.Caption;
if length(cs)<6 then return;
s :=(o.Caption)[6:];
GetCurrentEditer().Tryjump(s);
return;
end else
if pos("只读",o.caption)=1 then
begin
it := GetCurrentItem();
if it then
begin
it.FEditer.ReadOnly := not(o.Checked);
end
return;
end else
if pos("执行",o.Caption)=1 then
begin
it := GetCurrentItem();
ExecutePageItem(it);
return;
end else
if pos("停止",o.Caption)=1 then
begin
if FEchoWnd.Exeing()then FEchoWnd.EndExe();
return;
end else
if o.Caption = "转换为大写" then
begin
upperorlowercase(1);
end else
if o.Caption = "转换为小写" then
begin
upperorlowercase(0);
end else
if o.Caption = "删除尾空白" then
begin
seltrimright();
end
end
function PageEditerOnRClick(o,e);
begin
o.popupMenu := nil;
if not FPageEditerMenu then
begin
FPageEditerMenu := new TPopUpMenu(self);
FPageEditerMenus := array();
for i,v in array("查看","复制(C)","粘贴(V)","剪切(X)","定位(G)","只读","转换为大写","转换为小写","删除尾空白","执行(F9)","停止执行") do
begin
it := new TMenu(self);
it.Caption := v;
it.parent := FPageEditerMenu;
FPageEditerMenus[v]:= it;
it.OnClick := thisfunction(PageEditerMenuClick);
end
end
rd := FPageEditerMenus["只读"];
if rd then
begin
zd := GetCurrentItem().FEditer.Readonly;
rd.Checked := zd;
it := FPageEditerMenus["粘贴(V)"];
if it then it.Enabled := not zd;
it := FPageEditerMenus["剪切(X)"];
if it then it.Enabled := not zd;
end
rd := FPageEditerMenus["查看"];
if rd then
begin
mtic;
it := GetCurrentEditer();
s := it.CanJump();
if s then
begin
rd.Caption := "查看:"+s;
rd.Enabled := true;
end else
begin
rd.Caption := "查看";
rd.Enabled := false;
end
end
ex := FEchoWnd.Exeing()?true:false;
rd := FPageEditerMenus["执行(F9)"];
if rd then rd.Enabled := not ex;
rd := FPageEditerMenus["停止执行"];
if rd then rd.Enabled := ex;
rd := FPageEditerMenus["执行"];
if rd then
begin
end
o.popupMenu := FPageEditerMenu;
//MessageBoxA("MESSAGErclick","tis",0);
end
function createparams(p);override;
begin
inherited;
P.ExStyle := P.ExStyle .| WS_EX_ACCEPTFILES;
end
{$ifdef linux}
function DragQueryFileA();
{$else}
function DragQueryFileA(hDrop:pointer;iFile:integer;lpszFile:string;cch:integer):integer;stdcall;external "Shell32.dll" name "DragQueryFileA";
{$endif}
function WMDROPFILES(o,e):WM_DROPFILES;
begin
dn := "";
opends := array();
for i := 1 to DragQueryFileA(e.wparam,0xFFFFFFFF,"",0) do
begin
len := DragQueryFileA(e.wparam,i-1,nil,0);
if len>0 then
begin
setlength(dn,len+10);
if DragQueryFileA(e.wparam,i-1,dn,len+1)>0 then
begin
opends[length(opends)]:= dn[1:len];
end
end
end
for i,v in opends do
begin
arr := FileList("",v);
if not(pos("D",arr[0,"Attr"]))then OpenAndGotoFileByName(v);
end
end
function GetOpendPageItemByFileName(n);
begin
its := FPageEditer.PageItems;
for i := 0 to its.Length()-1 do
begin
it := its[i];
if it.ScriptPathIs(n)then return it;
end
end
function EditerCaretChanged(o,e);
begin
if GetCurrentEditer()=o then
begin
FStatus.setitemtext(format("col:%d | %s",o.CaretX,o.PageItem.EnCode),1);
end
end
function OpenScriptByFileName(n);
begin
if not ifstring(n)then return false;
it := GetOpendPageItemByFileName(n);
if it then return it;
fl := FileList("",n);
if not(length(fl)=1)then return false;
nn := fl[0,"FileName"];
if(POS("d",fl[0,"Attr"]))then return false;
it := new TPageEditerItem(FPageEditer);
it.FDebuger := FTslDebug;
it.FEditer.OnCaretChanged := thisfunction(EditerCaretChanged);
it.FEditer.Parent := FPageEditer;
it.FEditer.TabChar := FTabChar;
it.FEditer.PageItem := it;
it.FEditer.QuckKeys := Thisfunction(EditerQuckKeys);
it.FEditer.OnTextSetFocus := function(o,e)
begin
//echo "\r\n",o.PageItem.Scriptpath;
JudgeItemState(o.PageItem);
end
FPageEditer.PageItems.push(it);
nn1 := n;
nn1[(length(n)-length(nn)+1):]:= nn;
//echo nn1,"==",n,"\r\n";
it.ScriptPath := nn1;
it.BitmapA := GetNneedSaveBmp();
it.BitmapB := Closebmp();
LoadFromFile(it,true);
for i,v in FReadDirs do
begin
if not ifstring(v)then continue;
if pos(v,n)=1 then
begin
it.FEditer.ReadOnly := true;
break;
end
end
//DoControlAlign();
if it then
begin
SetHistoryFiles(n);
it.FEditer.OnRclick := thisfunction(PageEditerOnRClick);
it.FEditer.OnTextChanged := thisfunction(PageITEMtextChanged);
end
return it;
end
function GetHistoryFiles();
begin
return FOpenHistory.Data;
end
function SetHistoryFiles(v);
begin
if ifarray(v)then
begin
for i,vi in v do
begin
SetHistoryFiles(vi);
end
return;
end
if ifstring(v)and v then
begin
fcadd := true;
for i,vi in FOpenHistory.Data do
begin
if filenameIsTheSame(v,vi)then
begin
fcadd := false;
break;
end
end
if fcadd then
begin
FOpenHistory.Push(v);
if FOpenHistory.Length()>30 then FOpenHistory.shift();
end
end
end
function ShowHistoryWnd();
begin
if not FHistoryWnd then
begin
FHistoryWnd := new TMouseMoveList(self);
FHistoryWnd.Visible := false;
FHistoryWnd.WSpOPUp := true;
FHistoryWnd.Parent := self;
FHistoryWnd.Caption := "打开历史....";
FHistoryWnd.WSsysMenu := true;
FHistoryWnd.WsSizeBox := true;
FHistoryWnd.Width := 400;
FHistoryWnd.Height := 600;
{FHistoryClearMenuPop := new TPopUpMenu(self);
FHistoryClearMenu := new TMenu(self);
FHistoryClearMenu.Caption := "清空历史记录";
FHistoryClearMenu.Parent := FHistoryClearMenuPop;
FHistoryWnd.PopUpMenu := FHistoryClearMenu;
FHistoryClearMenu.OnClick := function(o,e)begin
FHistoryWnd.SetData(array());
FOpenHistory.Splices(0,FOpenHistory.Length());
end }
FHistoryWnd.OnClose := function(o,e)
begin
o.EndModal();
o.Visible := false;
e.skip := true;
end
FHistoryWnd.OnClick := function(o,e)
begin
idx := o.getCurrentSelection();
if idx >= 0 then
begin
n := o.GetItem(idx);
o.EndModal();
O.Visible := false;
OpenAndGotoFileByName(n);
end
end
end
if FOpenHistory.Length()>0 then
begin
FHistoryWnd.SetData(FOpenHistory.Data);
InitShowWndPos(FHistoryWnd,"history",100,100);
FHistoryWnd.ShowModal();
end
end
function OpenAndGoLineByName(n,L);
begin
it := OpenScriptByFileName(n);
if it then
begin
if l>0 then
begin
ed := it.FEditer;
ed.ExecuteCommand(ed.ecGoToXY,array(L,1));
end
end
return it;
end
function OpenAndGotoFileByName(n,L);
begin
bit := GetCurrentItem();
if bit then
begin
if not((ifnil(L)or(L=bit.FEditer.CaretY))and(filenameIsTheSame(n,bit.ScriptPath)))then
begin
bit := array("file":bit.OrigScriptPath,"line":bit.FEditer.CaretY);
if FRebackFlag then FGoBackB.Push(bit);
else FGoBackA.Push(bit);
end
end
it := OpenAndGoLineByName(n,L);
if it then FPageEditer.SetSel(it);
return it;
end
function CommetCurrentSel(); //注释选择
begin
it := GetCurrentEditer();
if it then
begin
if it.ReadOnly then return;
bg := it.BlockBegin;
ed := it.BlockEnd;
if bg and ed and ed[0]<> bg[0]then
begin
it.ExecuteCommand(it.ecTab,"//");
end else
begin
it.ExecuteCommand(it.ecLineStart);
it.ExecuteCommand(it.ecString,"//");
end
end
end
function UnCommentCurrentSel(); //取消注释
begin
it := GetCurrentEditer();
if it then
begin
if it.ReadOnly then return;
bg := it.BlockBegin;
ed := it.BlockEnd;
if bg and ed and bg[0]<> ed[0]then
begin
it.ExecuteCommand(it.ecShifttab,array("//"));
end else
begin
s := it.LineText;
if pos("//",s)=1 then
begin
it.ExecuteCommand(it.ecLineStart);
it.ExecuteCommand(it.ecSelLineEnd);
if length(s)>= 3 then it.ExecuteCommand(it.ecString,s[3:]);
else it.ExecuteCommand(it.ecString,"");
end
end
end
end
function UnDoCurrentEditer();
begin
it := GetCurrentEditer();
if it then
begin
if it.ReadOnly then return;
self.Enabled := false;
it.ExecuteCommand(it.ecUndo);
self.Enabled := true;
if it.ChangedFlag then
begin
cit := GetCurrentItem();
if it.Text=cit.LastText then //
begin
it.ChangedFlag := false;
end
end
end
end
function ToolClick(o,e); //
begin
case o.caption of
"打开文件":
begin
OpenAFile();
//FPages.OpenAFile();
end
"新建":
begin
CreateAFile();
//FPages.CreateAFile();
end
"保存全部":
begin
return SaveAllPageItems();
end
"保存":
begin
it := GetCurrentItem();
if SavePageItem(it)=0 then
begin
it.FEditer.ChangedFlag := true;
end
end
"取消注释":
begin
UnCommentCurrentSel();
end
"注释":
begin
CommetCurrentSel();
end
"快捷键说明":
begin
s := "";
s += "ctrl+o 打开\r\n";
s += "ctrl+N 新建\r\n";
s += "ctrl+s 保存\r\n";
s += "ctrl+F 查找窗口\r\n";
s += "ctrl+R 替换窗口\r\n";
s += "ctrl+a 全选\r\n";
s += "ctrl+c 拷贝选择\r\n";
s += "ctrl+D 复制被插入当前行\r\n";
s += "ctrl+v 粘贴\r\n";
s += "ctrl+x 剪切选择\r\n";
s += "ctrl+G 定位到行\r\n";
s += "ctrl+L|Y 删除当前行\r\n";
s += "tab | shift+tab 多行选中时缩进\r\n";
s += "ctrl+/ 注释当前选择\r\n";
s += "ctrl+\\ 取消当前注释\r\n";
s += "ctrl+U 反撤销\r\n";
s += "ctrl+z 撤销\r\n";
s += "ctrl+tab 切换标签\r\n";
s += "F2 跳转到下一个断点行\r\n";
s += "F5 添加删除断点\r\n";
s += "Alt+F5 将选中字符串转换为大写\r\n";
s += "ctl+F5 将选中字符串转换为小写\r\n";
s += "F3 正向搜索先前搜索的字符\r\n";
s += "ctrl+F3 反向搜索先前搜索的字符\r\n";
s += "ctrl+tab 切换标签页\r\n";
s += "F9 执行当前页的代码\r\n";
s += "ctrl+F9 打开执行代码编辑器\r\n";
s += "F7 显示隐藏日志窗口\r\n";
s += "F1 对于tsl语言查找当前光标所在位置的帮助\r\n";
s += "alt+m 弹出tsl代码地图\r\n";
messageboxa(s,"快捷键说明",0,self);
end
"撤销":
begin
UnDoCurrentEditer();
end
"反撤销":
begin
it := GetCurrentEditer();
if it then
begin
if it.ReadOnly then return;
self.Enabled := false;
it.ExecuteCommand(it.ecRedo);
self.Enabled := true;
end
end
"tsl语法检查":
begin
it := GetCurrentEditer();
if it then
begin
if not CheckTslCode(it.Text,err)then
begin
Messageboxa(err,"提示",0,self);
end else
messageboxa("符合tsl语法","提示",0,self);
end
end
"tsl代码格式化":
begin
it := GetCurrentEditer();
if it then
begin
if 1 <> MessageboxA("将格式化代码!!","提示",1,self.Handle)then return;
if it.ReadOnly then return;
//sel := FCodeFormatInfo["sel"];
syn := FCodeFormatInfo["syn"];
arraytype := FCodeFormatInfo["arraytype"];
cftype :=(FCodeFormatInfo["cmt"]=1);
arraytype :=(arraytype in array(0,1,3))?arraytype:1;
sel := true;
sel2 := false;
if sel then
begin
s := it.SelText;
if s then sel2 := true;
end
if not s then
begin
s := it.Text;
end
if not s then return;
if syn then
begin
if not CheckTslCode(s,err)then
begin
return Messageboxa(err,"提示-tsl语法错误",0,self);
end
end
try
Enabled := false;
fs := UNIT(UTslCodeFormat).FormatTsl(s,FTabWidth,wordct,charct,arraytype,cftype);
if fs <> s then
begin
if sel and sel2 then
begin
it.SelText := fs;
end else
begin
it.Text := fs;
it.ExecuteCommand(it.ecGotoXY,array(1,1));
end
end
finally
Enabled := true;
end;
end
end
"查找":
begin
FFindWnd.Show();
end
"前进":
begin
GoToReBack();
end
"后退":
begin
GoToBack();
end
"代码地图(alt+m)":
begin
InitShowWndPos(FCodeMap,"cm",250,100);
FCodeMap.ShowMap();
end
end
end
function GetCurrentItem();
begin
return FPageEditer.CurrentItem;
end
function GetCurrentEditer();
begin
it := GetCurrentItem();
if it then return it.FEditer;
end
function DoControlAlign();override; // 对齐
begin
if not(FPageEditer and FPageEditer.parent=self)then return;
rr := ClientRect;
r := rr;
th := FToolbar.CalcHeightFixWidth(rr[2]-rr[0]);
//FToolbar.Height := th;
r[3]:= r[0]+th;
FToolBar.SetBoundsRect(r);
r := rr;
r[1]:= r[3]-FStatus.Height;
FStatus.SetBoundsRect(r);
rr := rr;
rr[1]:= FToolbar.Height+1;
rr[3]:= rr[3]-FStatus.Height-1;
{if ffolderdlg and ffolderdlg.Visible then
begin
r := rr;
fwd := min(ffolderdlg.Width,integer(r[2] * 0.6));
r[2] := r[0]+fwd;
rr[0] := r[2]+1;
ffolderdlg.SetBoundsRect(r);
end }
if FInfoShowWnd.Visible and not(FInfoShowWnd.WSpOPUp)then
begin
r := rr;
r[1]:= r[3]-min(FInfoShowWnd.Height,integer(r[3] * 0.6));
rr[3]:= r[1]-1;
{fwd := min(FInfoShowWnd.Width,integer(r[2] * 0.6)); //右侧
r[0] := r[2]-fwd;
rr[2] := r[0]-1;}
FInfoShowWnd.SetBoundsRect(r);
end
FPageEditer.SetBoundsRect(rr);
end
function CreateAFile(); //构造文件
begin
if FTslCacheDir then
begin
idx := 0;
while true do
begin
idx++;
fn := FTslCacheDir+"newfile"+ioFileseparator()+"new"+inttostr(idx);
if fileexists("",fn) then continue;
r := ReWriteString(fn,"");
if r=1 then
begin
it := OpenAndGotoFileByName(fn);
it.fisnewfile := true;
end
return ;
end
end
FFileopen.Caption := "新建文件--输入文件名点击打开";
FFileopen.Multiselected := false;
it := GetCurrentItem();
if it then
begin
s := it.ScriptPath;
sp := ioFileseparator();
for i := length(s)downto 2 do
begin
if s[i]=sp then
begin
FFileopen.initialDir := s[1:i-1];
break;
end
end
end
if FFileopen.Opendlg()then
begin
exen := FFileopen.FileName;
if FileExists("",exen)then
begin
r := true;
end else
r := ReWriteString(exen,""); //exportfile(ftstream(),"",exen,"//createBytsl");
if r=1 then OpenAndGotoFileByName(exen);
end
end
function OpenAFile(); //打开文件
begin
FFileopen.Caption := "打开文件";
FFileopen.Multiselected := true;
it := GetCurrentItem();
if it then
begin
if not it.fisnewfile then
begin
s := it.ScriptPath;
sp := ioFileseparator();
for i := length(s)downto 3 do
begin
if s[i]=sp then
begin
FFileopen.initialDir := s[1:i-1];
break;
end
end
end
end
if FFileopen.Opendlg()then
begin
rs := FFileopen.getResults();
//echo tostn(rs);
lenrs := length(rs);
for i,v in rs do
begin
if lenrs=1 and not(FileList("",v))then
begin
if MessageboxA("文件不存在,点击确定新建.点击取消退出","提示",1)=IDOK then
begin
ReWriteString(v,"");
end
end
OpenAndGotoFileByName(v,1);
end
end
end
function GoToBack();
begin
FRebackFlag := true;
it := FGoBackA.Pop();
if it then OpenAndGotoFileByName(it["file"],it["line"]);
FRebackFlag := false;
end
function GoToReBack();
begin
it := FGoBackB.Pop();
if it then OpenAndGotoFileByName(it["file"],it["line"]);
end
function seltrimright();
begin
ed := GetCurrentEditer();
IF not ed then return;
//ed.Lines.SetValueByIndex
b := ed.BlockBegin;
e1 := ed.BlockEnd;
try
if b and e1 then
begin
ed.IncPaintLock();
for i := b[0] to e1[0] do
begin
s1 := ed.Lines.GetValueByIndex(i-1).FStr;
s := trimright(s1);
if s1=s then continue;
ed.Lines.SetValueByIndex(i-1,s);
end
ed.ExecuteCommand(ed.ecGoToXY,b);
ed.ExecuteCommand(ed.ecSelGotoXY,e1);
ed.DecPaintLock();
end else
begin
s1 := ed.LineText;
s := trimright(s1);
if s1<>s then ed.LineText :=s;
end
except
end;
end
function upperorlowercase(f);
begin
ed := GetCurrentEditer();
IF not ed then return;
s := ed.SelText;
if s then
begin
b := ed.BlockBegin;
e1 := ed.BlockEnd;
ed.SelText := f?uppercase(s):lowercase(s);
ed.ExecuteCommand(ed.ecGoToXY,b);
ed.ExecuteCommand(ed.ecSelGotoXY,e1);
end
end
function EditerQuckKeys(o,e);virtual; //快捷键
begin
if e.Result=0 and(ssAlt in e.shiftstate)then
begin
case e.charcode of
VK_F5: //大写
begin
upperorlowercase(1);
e.skip := true;
return true;
end
ord("M"):
begin
InitShowWndPos(FCodeMap,"cm",250,100);
FCodeMap.ShowMap();
e.skip := true;
return true;
end
end
end
if ssCtrl in e.ShiftState then
begin
if e.Result=0 then //down
begin
case e.CharCode of
220,191:
begin
if e.CharCode=220 then UnCommentCurrentSel();
else CommetCurrentSel();
e.skip := true;
return true;
end
VK_F5: //小写
begin
upperorlowercase(0);
return true;
end
ord("D"):
begin
ed := GetCurrentEditer();
if not ed then return;
if ed.ReadOnly then return;
//xy := ed.CaretY;
ed.ExecuteCommand(ed.ecLineEnd,nil);
S := ed.LineText;
ed.ExecuteCommand(ed.ecString,"\r\n"+s);
return;
end
ord("R"):
begin
InitShowWndPos(FFindWnd,"fr",200,150);
FFindWnd.oPENreplace();
FFindWnd.Show();
return true;
end
ord("E"):
begin
ed := GetCurrentEditer();
IF not ed then return;
s := ed.CaretWords();
if s then ed.Tryjump(s);
return true;
end
ord("F"):
begin
InitShowWndPos(FFindWnd,"fr",200,150);
FFindWnd.OpenFind();
FFindWnd.Show();
return true;
end
ord("G"):
begin
InitShowWndPos(FGotoLineWnd,"g",200,200);
FGotoLineWnd.ShowGoto();
return true;
end
ord("O"):
begin
OpenAfile();
return true;
end
ord("N"):
begin
CreateAfile();
return true;
end
ord("Z"):
begin
UnDoCurrentEditer();
return true;
end
ord("S"):
begin
it := GetCurrentItem();
if 0=SavePageItem(it)then
begin
it.FEditer.ChangedFlag := true;
end
return true;
end
end
end else //up
begin
case e.CharCode of
VK_TAB:
begin
TabChecking(ssShift in e.ShiftState);
return true;
end
VK_F3:
begin
d := FFindWnd.GetINfo();
d["section"]:= "查找";
d["btn"]:= "查找";
d["c_revers"]:= 1;
DoFind(d,FFindWnd);
return true;
end
end
end
end
if e.Result=1 then
begin
case e.CharCode of
17:
begin
if e.Result then
begin
TabCheckChanged();
end
end
VK_F7:
begin
SwitchLogWnd();
return true;
end
VK_F8:
begin
DbgNextLine();
return true;
end
VK_F9:
begin
if ssctrl in e.ShiftState()then
begin
ShowExeEditer();
return true;
end
ExecutePageItem(GetCurrentItem());
return true;
end
VK_F3:
begin
d := FFindWnd.GetINfo();
d["section"]:= "查找";
d["btn"]:= "查找";
d["c_revers"]:= 0;
DoFind(d,FFindWnd);
return true;
end
VK_F1:
begin
it := GetCurrentItem();
if it.FSynType="tsl" then
begin
ed := it.FEditer;
IF not ed then return;
s := ed.CaretWords();
if s then FTslChmHelp.SearchWord(s);
end
return true;
end
end;
end
end
function ShowTslLangChm();
begin
FTslChmHelp.ShowTslLangChm();
end
function InitShowWndPos(wnd,n,ix,iy); //计算初始位置
begin
if not FFistShows[n]then
begin
FFistShows[n]:= true;
xy := Clienttoscreen(ix,iy);
wnd.left := xy[0];
wnd.top := xy[1];
end
end
function SetPageItemSyn(it,n);
begin
if not it then return;
if not ifstring(n)then return;
if it.FSynType=n then return;
hc := GetFreeSynObjectByName(n);
if hc then
begin
cp := hc[1];
it.FEditer.IncPaintLock();
it.FEditer.HighLighter := hc[0];
it.FEditer.Completion := hc[1];
it.FEditer.DecPaintLock();
cp.OnJumpChoosed := function(cmp,d);
begin
f := d["file"];
nf :=(f?(cmp.GetFileFullPath(f)):GetCurrentItem().OrigScriptPath);
//echo "\r\n",nf,"===",d["line"];
OpenAndGotoFileByName(nf,d["line"]);
end
cit := GetCurrentItem();
if cit=it then
begin
it.FInitCompletion := false;
cp.PrePareCompletion(it.Caption);
end else
begin
it.FInitCompletion := true;
end
it.FSynType := n;
end else
begin
it.FEditer.IncPaintLock();
it.FEditer.HighLighter := nil;
it.FEditer.Completion := nil;
it.FEditer.DecPaintLock();
it.FSynType := n;
end
end
function Recycling();override;
begin
inherited;
FSynHCS := nil;
FCurrentItemCode := array();
FPageEditer := nil;
FToolbar := nil;
FStatus := nil;
FInfoShowWnd := nil;
FPageMenu := nil;
FPageEditerMenu := nil;
FPageEditerMenus := array();
FOnPageEditerChanged := nil;
fOnPageItemSelChanged := nil;
FListPages := nil;
FCodeMap := nil;
FEchoWnd := nil;
FFindListWnd := nil;
FTempPageItem := nil;
FExecuteEditer := nil;
FTslDebug := nil;
end
function GetSynTypeNames();
begin
return FSynClasses.IndexNames();
end
function SetCodeFormatInfo(d);
begin
if ifarray(d)then FCodeFormatInfo := d;
else return FCodeFormatInfo;
end
function getexecuteparams(f); //获得当前的执行参数
begin
return FExecuteEditer.GetCurrentExuteparams(f);
end
function ShowExeEditer(flg);
begin
if ifnil(flg)or flg then
begin
InitShowWndPos(FExecuteEditer,"exe",200,200);
FExecuteEditer.showexeediter();
end else
begin
FExecuteEditer.Visible := false;
end
end
function getlibpathstr();
begin
dirs := "";
fio := ioFileseparator();
for i,v in FTslSearchDir do
begin
if ifstring(v)then
begin
if v[length(v)]=fio then
begin
dirs += v;
end else
begin
dirs += v;
dirs += fio;
end
end
dirs += ";";
end
return dirs;
end
function echoAppendString(s);
begin
FEchoWnd.AppendString(s);
end
published //property 位置
FHistoryDir;
property OnPageEditerChanged read FOnPageEditerChanged write FOnPageEditerChanged;
property OnPageItemSelChanged read FOnPageItemSelChanged write FOnPageItemSelChanged;
property TslSearchDir read FTslSearchDir write SetTslSearchDir;
property TslCacheDir read FTslCacheDir write SetTslCacheDir;
property TabWidth read FTabWidth write SetTabWidth;
property TabChar read FTabChar;
property Tslexe read FTslExe write FTslExe;
property ReadOnlyDirs read FReadDirs write FReadDirs;
protected
class function Sinit();override;
begin
inherited;
if not FSynClasses then FSynClasses := new TMyArrayA();
end
class function GetSynTypeByFileType(ft);
begin
if not string(ft)then return "txt";
nft := lowercase(ft);
for i,v in FSynClasses.IndexNames() do
begin
dv := FSynClasses[v];
dvf := dv[2];
if ifstring(dvf)then
begin
if pos(";"+nft+";",dvf)then
begin
return v;
end
end
end
return "None";
end
class function RegSynType(n,h,c,files);
begin
if ifstring(n)and(h is class(TSynhighLighter))and(c is TSynCompletion)then
begin
FSynClasses[n]:= array(h,c,files);
end
end
class function UnRegSynType(n,h,c);
begin
if ifstring(n)then
begin
FSynClasses.DeleteIndex(n);
end
end
{
r["section"] := CurrentITem.Caption;
r["target"]:= FEdit_target.Editer.Text;
r["replace"]:= FEdit_repace.Editer.Text;
r["filetype"] := FEdit_type.Editer.Text;
r["dir"] := FEdit_dir.Editer.Text;
r["c_revers"]:=FCheck_revers.Checked;
r["c_cycle"]:= FCheck_cycle.Checked;
r["c_wrap"] := FCheck_wrap.Checked;
r["c_case"] := FCheck_case.Checked;
r["c_reg"] := FCheck_reg.Checked;
r["c_dir"] := FCheck_subdir.Checked;
}
function ReplaceAllInCurrent(data,fo,it,idx);
begin
data["c_revers"]:= 0;
data["c_cycle"]:= 0;
if not it then it := GetCurrentItem();
if not it then return;
ed := it.FEditer;
if not ed then return;
idx := 0;
try
ed.IncPaintLock();
ed.ExecuteCommand(ed.ecGotoXY,array(1,1));
cidx := 0;
while FindInCurrent(data,fo,it,1)=0 do
begin
if idx=0 then
begin
FFindListWnd.AppendItem(array("caption":format("replace:%s in file:%s",data["target"],it.OrigScriptPath)));
end
if idx>0 then
begin
ed.MergeLastUndo();
end
idx++;
L := ed.CaretY;
if cidx=L then continue;
cidx := L;
scap := format(" %d:(第%d行) ",idx,L)+trim(ed.LineText);
FFindListWnd.AppendItem(array("caption":scap,"file":it.OrigScriptPath,"line":L));
end
finally
ed.DecPaintLock();
end
//fo.SetStatusText(format("共替换:%d 处",idx));
end
function FindInFiles(d,o,rep,ct);
begin
fs := GetFilesFormSearchInfo(d);
ct := 0;
for i,v in fs do
begin
if not FIsFinding then break;
o.SetStatusText("查找文件:"+i);
it := GetOpendPageItemByFileName(i);
if not it then
begin
FTempPageItem.ScriptPath := i;
LoadFromFile(FTempPageItem,false);
it := FTempPageItem;
end
if rep then
begin
ReplaceAllInCurrent(d,o,it,idx);
SavePageItem(it);
end else
begin
FindAllInCurrent(d,o,it,idx);
end
ct += idx;
end
end
function FindInCurrent(data,fo,it,rep);
begin
if not it then it := GetCurrentItem();
if not it then return-2;
ed := it.FEditer;
if not ed then return-2;
cy := ed.CaretY;
cx := ed.CaretX;
wordwrap := data["c_wrap"];
fs := data["target"];
if not(fs and ifstring(fs))then
begin
fo.SetStatusText("查找内容为空!");
return-2;
end
stringiswrapword := isCaseWords(fs);
if data["c_case"]then fs := lowercase(fs);
rstring := data["replace"];
lfs := length(fs);
L := ed.Lines;
ct := L.length();
if data["c_revers"]then
begin
for i := cy-1 downto cy-ct do
begin
ridx := i;
if data["c_cycle"]then
begin
ridx :=(ridx<0)?(ridx+ct):ridx;
end
if ridx<0 then
begin
fo.SetStatusText("到达顶部");
return-2;
end
s := L.GetStringByIndex(ridx);
ls := length(s);
while cx-lfs+1>1 do
begin
if not FIsFinding then return-2;
TryDispatch();
subs := s[cx-lfs:cx-1];
if data["c_case"]then subs := lowercase(subs);
if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了
begin
ed.ExecuteCommand(ed.ecGotoXY,array(ridx+1,cx));
ed.ExecuteCommand(ed.ecSelGotoXY,array(ridx+1,cx-lfs));
if rep then
begin
ed.SelText := rstring;
end
fo.SetStatusText(format("位置: %d %d",ridx+1,cx-lfs));
return 0;
end
cx--;
end
tidx := ridx-1;
if data["c_cycle"]then
begin
tidx += ct;
tidx := tidx mod ct;
end else
begin
if tidx<0 then
begin
fo.SetStatusText("到达顶部");
return-2;
end
end
s := L.GetStringByIndex(tidx);
cx := length(s)+1;
end
fo.SetStatusText("到达顶部");
return-2;
end
for i := 0 to ct do
begin
ridx := i+cy-1;
if data["c_cycle"]then
begin
ridx := ridx mod ct;
end
if ridx >= ct then
begin
fo.SetStatusText("到达底部");
return-2;
end
s := L.GetStringByIndex(ridx);
ls := length(s);
while cx+lfs-1 <= ls do
begin
if not FIsFinding then return-2;
//GetAndDispatchMessageA();
TryDispatch();
subs := s[cx:cx+lfs-1];
if data["c_case"]then subs := lowercase(subs);
if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了
begin
ed.ExecuteCommand(ed.ecGotoXY,array(ridx+1,cx));
ed.ExecuteCommand(ed.ecSelGotoXY,array(ridx+1,cx+lfs));
if rep then
begin
ed.SelText := rstring;
end
fo.SetStatusText(format("位置: %d %d",ridx+1,cx));
return 0;
end
//没找到
cx++;
end
cx := 1;
end
fo.SetStatusText("到达底部");
return-2;
end
function FindListChoosed(o,e);
begin
it := o.GetItem(o.GetCurrentSelection());
if ifarray(it)then
begin
f := it["file"];
l := it["line"];
if ifstring(f)and l >= 0 then
begin
OpenAndGotoFileByName(f,l);
end
end
end
function TryDispatch();
begin
{$ifdef linux}
return;
{$endif}
t := now();
if(t-FLastDispathTime)>0.25e-5 then
begin
FLastDispathTime := t;
GetAndDispatchMessageA();
end
end
function FindAllInCurrent(data,fo,it,rt);
begin
rt := 0;
if not it then it := GetCurrentItem();
if not it then return;
ed := it.FEditer;
if not ed then return;
wordwrap := data["c_wrap"];
fs := data["target"];
if not(fs and ifstring(fs))then return fo.SetStatusText("找到 0 处");
if data["c_case"]then fs := lowercase(fs);
stringiswrapword := isCaseWords(fs);
lfs := length(fs);
L := ed.Lines;
ct := L.length();
cidx := 0;
for i := 0 to ct-1 do
begin
s := L.GetStringByIndex(i);
ls := length(s);
cx := 1;
while cx+lfs-1 <= ls do
begin
if not FIsFinding then return rt;
//GetAndDispatchMessageA();
TryDispatch();
subs := s[cx:cx+lfs-1];
if data["c_case"]then subs := lowercase(subs);
//((stringiswrapword .& 2) and (IsWordsChar(s,cx-1,ls)) ( (stringiswrapword .& 1) and IsWordsChar(s,cx+lfs,ls)) )
if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了
begin
if rt=0 then FFindListWnd.AppendItem(array("caption":format("find:%s in file:%s",fs,it.OrigScriptPath),"file":it.OrigScriptPath,"line":1));
cx += lfs;
rt++;
if cidx=i+1 then continue;
cidx := i+1;
scap := format(" %d:(第%d行) ",rt,i+1)+trim(s);
FFindListWnd.AppendItem(array("caption":scap,"file":it.OrigScriptPath,"line":i+1));
continue;
end
//没找到
cx++;
end
end
return rt;
end
function isCaseWords(s); //判断全词匹配
begin
if ifstring(s)and s then
begin
len := length(s);
if len=1 then return IsWordsChar(s,1,1);
return IsWordsChar(s,1,1).|(2 * IsWordsChar(s,len,len));
end
end
function IsWordsChar(s,idx,len);
begin
if not(len>0)then len := length(s);
if idx>len then return true;
if idx<1 then return true;
ivi := ord(s[idx]);
if(ivi<48)or(ivi>57 and ivi<65)or(ivi>90 and ivi<95)or(ivi>95 and ivi<97)or(ivi>122 and ivi <= 127)then return true;
end
function TabCheckChanged();
begin
if not FListPages.Visible then return;
FListPages.Visible := false;
n := FListPages.GetSelFileName;
OpenAndGotoFileByName(n);
end
function TabChecking(f);
begin
its := FPageEditer.PageItems;
if not(its.Length()>1)then return FCurrentItemCode := array();
if FListPages.Visible then
begin
FListPages.IncIndex((f>0)?1:(-1));
end else
begin //初始化
bit := GetCurrentItem();
for i := 0 to its.Length()-1 do
begin
it := its[i];
it.FPageOrderId := 0;
end
idx := 1;
for i := length(FCurrentItemCode)-1 downto 0 do
begin
it := FCurrentItemCode[i];
if it.FPageOrderId<1 then it.FPageOrderId := idx++;
end
sr := array();
for i := 0 to its.Length()-1 do
begin
it := its[i];
sv := it.OrigScriptPath;
if it.FEditer.ChangedFlag then sv := "*"+sv;
sr[i,0]:= sv;
sr[i,1]:= it.FPageOrderId;
sr[i,2]:= it;
if it.FPageOrderId=0 then
begin
it.FPageOrderId := idx++;
end
end
sit := sselect[0]from sr order by[1]asc end;
FCurrentItemCode := sselect[2]from sr order by[1]desc end;
FListPages.SetData(sit);
FListPages.IncIndex(-1);
xy := ClientToScreen(100,100);
FListPages.Top := xy[1];
FListPages.Left := xy[0];
//FListPages.SetBoundsRect(array(xy[0],xy[1],xy[0]+600,xy[1]+600));
//FListPages.Visible := true;
FListPages.Show(SW_SHOWNOACTIVATE);
//bit.FEditer.SetFocus();
end
end
function GetFreeSynObjectByName(n);
begin
if not ifstring(n)then return;
lns := FSynHCS[n];
if not lns then
begin
lns := new TMyARRayB();
FSynHCS[n]:= lns;
end
for i := 0 to lns.length()-1 do
begin
vi := lns[i];
if not(vi[0].Memo)then return vi;
end
hc := CreateASynObject(n,self);
if hc then
begin
lns.Push(hc);
return hc;
end
end
public
FExecuteEditer;
private
class function CreateASynObject(n,ow);
begin
c := FSynClasses[n];
//if not c then c := FSynClasses["txt"];
if c then
begin
if ifobj(c[0])and ifobj(c[1])then return array(CreateObject(c[0],ow),CreateObject(c[1],ow));
end
end
static FSynClasses;
FCodeFormatInfo;
FTslChmHelp;
FFistShows;
FSynHCS;
FLastDispathTime;
FIsFinding;
FOnPageEditerChanged;
FPageEditerMenu;
FPageEditerMenus;
fOnPageItemSelChanged;
FReadDirs;
FCurrentItemCode;
FGoBackA; // := new TMyarrayB();
FGoBackB; // := new TMyarrayB();
FRebackFlag;
FPageEditer;
FToolbar;
FStatus;
FInfoShowWnd;
FCodeMap;
FListPages;
FFindWnd;
FFindListWnd;
FEchoWnd;
FGotoLineWnd;
FFileopen;
FFileSave;
FPageMenu;
//图标
FNeedSaveBmp;
FNotNeedSaveBmp;
FBmpClose;
FTabWidth;
FTabChar;
FTslexe;
FTslSearchDir;
FTslCacheDir;
FTempPageItem;
FOpenHistory;
FHistoryWnd;
FTslDebug;
private
function GetFilesFormSearchInfo(d);
begin
r := array();
dir := d["dir"];
if not dir then return r;
ft := d["filetype"];
if ft then
begin
ft := str2array(ft,";");
end
if not ft then ft := array("*");
FindFiles(dir,ft,d["c_dir"],r);
return r;
end
function FindFiles(dir,ft,sub,ret);
begin
dir_ := dir;
sp := ioFileseparator();
if not(dir_[length(dir_)]=sp)then dir_ += sp;
if sub then
begin
dirs := FileList("",dir_+"*");
for i,v in dirs do
begin
TryDispatch();
if not FIsFinding then return;
fn := v["FileName"];
if(pos("D",v["Attr"]))and not(fn in array(".",".."))then
begin
FindFiles(dir_+fn,ft,sub,ret);
end
end
end
for i,v in ft do
begin
vi := trim(v);
if not vi then continue;
fs := FileList("",dir_+vi);
for j,vj in fs do
begin
if(POS("D",vj["Attr"]))then continue;
ret[dir_+vj["FileName"]]:= true;
end
end
end
function SetTslCacheDir(d);
begin
if FTslCacheDir=d then return;
if ifstring(d)then
begin
FTslCacheDir := d;
class(TTSLCompletion).SetCacheDir(d);
end
end
function SetTslSearchDir(d);
begin
if FTslSearchDir=d then return;
if ifarray(d)then
begin
FTslSearchDir := d;
class(TTSLCompletion).SetFindDirs(d);
its := GetAllPageItems();
for i := 0 to its.Length()-1 do
begin
it := its[i];
it.RepreComple := true;
end
end
end
function SetTabWidth(n);
begin
if not(n >= 0)then return;
nn := integer(n);
if nn >= 0 and nn <> FTabWidth then
begin
FTabWidth := nn;
if nn=0 then FTabChar := "\t";
else
begin
FTabChar := "";
for i := 1 to nn do
begin
FTabChar += " ";
end
end
its := FPageEditer.PageITems;
for i := 0 to its.Length()-1 do its[i].FEditer.TabChar := FTabChar;
end
end
function getdirfromfile(p);
begin
r := "";
if not ifstring(p)then return r;
sp := ioFileseparator();
for i := length(p)downto 1 do
begin
if p[i]=sp then return p[1:i];
end
return r;
end
function LoadFromFile(it,ifinit);
begin
p := it.ScriptPath;
sz := filesize("",p);
if readFile(rwRaw(),"",p,0,sz,s)then
begin
it.ReGetLastLoadTime();
if lowercase(p[length(p)-3:length(p)])=".stm" then
begin
try
if s then
begin
v := stm(s);
s := tostn(v);
end
it.FEditer.ReadOnly := true;
it.FISstm := true;
except
end
end
edt := it.FEditer;
tl := edt.TopLine;
cxy := edt.CaretXY;
it.SetLoadScript(s);
if ifinit then
begin
InitScriptHighLighter(it);
edt.TopLine := tl;
edt.ExecuteCommand(edt.ecGotoXY,cxy);
end
end else
begin
//MessageBoxA(s,"提示",0,self);
it.ReGetLastLoadTime();
it.SetLoadScript(s);
it.FEditer.ReadOnly := true; //设置为自读
end
end
function InitScriptHighLighter(it);
begin
p := it.ScriptPath;
for i := length(p)downto 3 do
begin
if p[i]="." then
begin
synt := GetSynTypeByFileType(p[i+1:]);
return SetPageItemSyn(it,synt);
end
end
end
function GetNNeedSaveBmp();
begin
if not FNOTneedSaveBmp then
begin
s := "0502000000060400000074797065000203000000696D670006040000006461746
100027701000089504E470D0A1A0A0000000D4948445200000030000000300806
0000005702F987000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000010C49444154
6843ED9AC1AA83500C05FBFFBFE84E45117521A21B955B023790B6E73D5B29490
A199876D148CFACDB5B5DD7A9288A9FB1AAAA741C47626EE8C8BBEBBAE6F92701
C3309889F6B06F07C8436DD01E360234407BD808D000ED61234003B4878D000DD
01E360234407BD808D000ED61234003B4878D000DD01E360234407BD88F02AC44
7B58FA9CF937C0AB11606D04581B01D64680B59702BE0D8D40DFF38E11F00D222
0732960DFF7D434CD8BD334E58B73CC03D08D4940DBB6F0E85989AB007AE9BA0E
1E4A25EE0288B30889CB00A2EF7BF80029711B40FC1521711D40A01F9A25EE038
8711C1F1E9258069465F9F85F89FCFE11DBB6A5799E5F5C96255FE87129C0133F
1E90D21D478EF0B86077F81A0000000049454E44AE42608200";
FNOTneedSaveBmp := new TBitmap();
FNOTneedSaveBmp.ReadVcon(HexFormatStrToTsl(s));
end
return FNOTneedSaveBmp;
end
function Closebmp();
begin
if not FBmpClose then
begin
FBmpClose := new TBitmap();
s := "0502000000060400000074797065000203000000696D670006040000006461746
100025601000089504E470D0A1A0A0000000D494844520000001C000000100806
00000005CF1FEF000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000EB49444154
484B63F88F03FC7DFCF0FFEF3327C9C6B8005E0BDF19A89285BFB637424DC1040
42DFC36B1FBFFD7E61A0C43D1F17B0BDDFF7FAE5DFEFFC1C789320B3F0679FEFF
73E7365E4BDF3B9881D57C9F3E09CCA7C84210865BDA5A0F1783E10F1E7628968
130C5168230CCD26F3D6D08B100370CCB40982A168230DCD2C9BD7036BA65204C
350B411866112ECB40983616DEBE497B0B9183F163A007381BD02C48B1C5D9072
F47AC96526C21CCB26FD326A2180CC21F5CAC302CA5C842B865FD9D7003D1F17B
5B63144B29B2105CB4B537A058800DBF37D7A14ED1460E26DB426CD50EB1183BF
8FF1F00B989BEC710621E4C0000000049454E44AE42608200";
FBmpClose.ReadVcon(HexformatStrToTsl(s));
end
return FBmpClose;
end
function GetNeedSaveBmp();
begin
if not FNeedSaveBmp then
begin
s := "0502000000060400000074797065000203000000696D670006040000006461746
10002A701000089504E470D0A1A0A0000000D4948445200000030000000300806
0000005702F987000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000013C49444154
6843ED8FBB4A43511045F32F7E908D95BDAD551A6DAC6C6CB4110276368282852
00ADAD908B6E94212141F49A110BC820FC2918133307A3737C925CC4C6016AC34
9993ECD5E8AF1EA4F6D2E6C2D85B69A5F1C757621AE8C8BBC56D37CF9F1030DCB
B3613ED61A70E9087DAA03D6C046880F6B011A001DAC3468006680F1B011AA03D
6C046880F6B011A001DAC3468006680F1B011AA03D6C046880F6B033055889F6B
0F43D5319E0D508B03602AC8D006B23C0DA5A01F38646A0FF99C60898071190A9
15F0F35AA4FBB5C3926FC777F96232E601E8C624E061FD081EFD57E22A803E1E9
B27F0502A7117403C6D9CC26356E2328078DE3A830F4889DB00E265FB1C3E92B8
0E20063B97A54712F701C470F7EACF2389654077793F8D8BCFFC2B1501557C0F4
66974D12EF97ED3C9177AD40AF0C48207A4F40B898CCDD8EC600A800000000049
454E44AE42608200";
FNeedSaveBmp := new TBitmap();
FNeedSaveBmp.ReadVcon(HexFormatStrToTsl(s));
end
return FNeedSaveBmp;
end
end
implementation
type tdbgselwnd=class(tdcreateform)
uses tslvcl;
label1:tlabel;
furl:tedit;
label2:tlabel;
fport:tedit;
label3:tlabel;
fusr:tedit;
label4:tlabel;
label5:tlabel;
fpwd:tpassword;
fdir:tedit;
fdiag:tfolderchooseadlg;
flist:tlistview;
fcbtn:tbtn;
flogout:tbtn;
flogin:tbtn;
fdbg:tbtn;
cancel_clk;
save_clk;
dbg_clk;
fhistorydir;
function Create(AOwner);override; //构造
begin
inherited;
Visible := false;
Loader.LoadFromTfmScript(self,getinfo());
flist.Columns := array(
("text":"ID号","width":150),
("text":"信息","width":300),
("text":"创建时间","width":100)
);
flogout.top := 140;
flogout.OnClick := function(o,e)
begin
calldatafunction(cancel_clk,self,e);
end
flogin.OnClick := function(o,e)
begin
if fhistorydir and ifstring(fhistorydir)then
begin
Fremotepath := fhistorydir+"remoteinfo.tsm";
d := getdata();
Exportfile(ftstream(),"",Fremotepath,d);
end
calldatafunction(save_clk,self,e);
end
fdbg.onclick := function(o,e)
begin
calldatafunction(dbg_clk,self,e);
end
setlist();
end
function setattachwait(flg); //设置登陆样式
begin
if flg then
begin
Height := 210;
end else
begin
Height := 550;
end
end
function loaddata(); //导入数据
begin
if fhistorydir and ifstring(fhistorydir)then
begin
Fremotepath := fhistorydir+"remoteinfo.tsm";
if fileexists("",Fremotepath)and(1=importfile(ftstream(),"",Fremotepath,d))then
begin
setdata(d);
end
end
end
function getdata();
begin
r := array();
r["addr"]:= furl.text;
r["port"]:= fport.text;
r["usr"]:= fusr.text;
r["pwd"]:= fpwd.text;
r["dir"]:= fdir.text;
return r;
end
function tserlogersimplewnd1_close(o;e);virtual;
begin
e.skip := true;
end
function Recycling();override; //回收变量
begin
inherited;
ci := self.classinfo(); //将成员变量赋值为nil避免循环引用
for i,v in ci["members"] do
begin
if v["static"]then continue;
invoke(self,v["name"],nil);
end
end
function getdir();
begin
if fdiag.ChooseDlg()then
begin
fdir.text := fdiag.Folder;
end
end
function setlist(d);
begin
FList.DeleteAllItems();
fdbg.Enabled := false;
if d and ifarray(d)then
begin
FList.appendItems(d);
FList.SelectedId := 0;
fdbg.Enabled := true;
end
end
function getstartfilename(sv);
begin
dirt := fdir.Text;
if not sv then sv := FList.SelectedValue;
if dirt and sv then
begin
if sv then
begin
fs := sv["info"];
if fs then
begin
for i := length(fs)-1 downto 1 do
begin
if fs[i]in array("\\","/")then
begin
fs := fs[i+1:];
break;
end
end
return gettruefile(dirt,fs,ioFileseparator());
end
end
end
end
private
function getinfo();
begin
return %%
object tserlogersimplewnd1:tserlogersimplewnd
caption="远程调试"
color=0xFFFFFF
top=100
height=550
minmaxbox=false
onclose=tserlogersimplewnd1_close
width=580
wsdlgmodalframe=true
wssizebox=false
object label1:tlabel
left=4
top=3
width=80
height=25
caption="服务器地址"
end
object furl:tedit
height=25
left=88
tabstop=true
top=3
width=204
end
object label2:tlabel
left=296
top=3
width=34
height=25
caption="端口"
end
object fport:tedit
height=25
left=333
tabstop=true
top=3
width=62
end
object label3:tlabel
left=2
top=38
width=80
height=25
caption=" 用户名"
end
object fusr:tedit
height=25
left=88
tabstop=true
top=38
width=300
end
object label4:tlabel
left=2
top=72
width=80
height=25
caption=" 密 码"
end
object label5:tlabel
left=2
top=100
width=80
height=25
caption=" 脚本目录"
end
object fpwd:tpassword
height=25
left=88
tabstop=true
top=72
width=300
end
object fdir:tedit
height=25
left=88
tabstop=true
top=100
width=300
end
object fcbtn:tbtn
caption="..."
height=25
left=390
tabstop=true
top=100
width=22
onclick=getdir
end
object flogout:tbtn
an1chors=[akright akbottom]
caption="取消"
height=23ff
left=375
tabstop=true
top=480
width=74
end
object fdbg:tbtn
an1chors=[akright akbottom]
caption="调试"
height=23
left=470
tabstop=true
top=480
width=74
end
object flogin:tbtn
caption="连接"
height=23
left=470
tabstop=true
top=140
width=74
end
object flist:tlistview
anch1ors=[akTop akright akLeft akBottom]
height=290
left=2
top=180
width=560
end
object fdiag:tfolderchooseadlg
caption="执行目录"
end
end
%%;
end
private
function setdata(d);
begin
if not ifarray(d)then return;
furl.text := d["addr"];
fport.text := d["port"];
fusr.text := d["usr"];
fpwd.text := d["pwd"];
fdir.text := d["dir"];
end
function gettruefile(dir,n,fio);
begin
if dir and ifstring(dir)then
begin
rfile := dir+fio+n;
if fileexists("",rfile)then return rfile;
for i,v in FileList("",dir+fio+"*") do
begin
fn := v["FileName"];
if pos("D",v["Attr"])and not(fn in array(".",".."))then
begin
rfile := gettruefile(dir+fio+fn,n,fio);
if rfile then return rfile;
end
end
end
end
end
function tdbgcallback();
begin
global g_tsldbgcallback_handle;
if g_tsldbgcallback_handle then call(g_tsldbgcallback_handle,sysparams);
end
function filenameIsTheSame(p1,p2);
begin
if not(ifstring(p1)and ifstring(p2))then return 0;
if p1=p2 then return 1;
{$ifdef linux}
{$else}
return lowercase(p1)=lowercase(p2);
{$endif}
end
type TMouseMoveList=class(TListBox)
function Create(AOwner);override;
begin
inherited;
FCurrentIndex :=-1;
end
function MouseMove(o,e);override;
begin
inherited;
idx := GetIdxByYpos(e.ypos);
if FCurrentIndex <> idx then
begin
FCurrentIndex := idx;
InValidateRect(nil,false);
end
end
function getItemText(i);override;
begin
r := inherited;
return " "+r;
end
function PaintIdx(idx,rc_,cvs);virtual;
begin
{**
@explan(说明)绘制项 %%
@param(item)(TCustomListItem) 项 %%
@param(rc)(array) 绘制区域%%
@param(cvs)(tcanvas) 画布 %%
**}
inherited;
if idx=FCurrentIndex then
begin
rc := rc_;
rc[2:3]-= 1;
cvs.pen.Color := rgb(30,144,255);
cvs.draw("Polyline",array(rc[0:1],(rc[2],rc[1]),(rc[2],rc[3]),(rc[0],rc[3]),rc[0:1]));
end
end
private
FCurrentIndex;
end
type TTSLDataGrid=class(TDrawGrid)
{**
@explan(说明)TSL数组和对象展示 %%
**}
private
static FHGS;
ftext;
FCols;
Fdata;
FMRWD;
FGridControl;
FRows;
FShowTwo;
FCControls;
FColumnWidth;
FRowHeader;
FControlIndex;
FStringAlign;
FNumberAlign;
FDefAlign;
FCanedit;
function showstring(f);
begin
if ifarray(Fdata)then
begin
gettxtobj();
ftext.text := "";
if f then
begin
ftext.HighLighter := FHGS[1]; //FHGS[1];
ftext.Caption := "json";
ftext.text := ejsonformat(Fdata);
end else
begin
ftext.HighLighter := FHGS[0];
ftext.Caption := "原串....";
ftext.text := tostn(Fdata);
end
ftext.show();
end
end
function getdata(i,j,cp,indexs);
begin
{**
@explan(说明) 获取数据
**}
if j=0 and FRowHeader then return FRows[i];
r := FRows[i];
if FCols and FShowTwo then
begin
if FRowHeader then c := FCols[j-1];
else c := FCols[j];
d := FData[r][c];
if cp then cp := "["+tostn(r)+"]";
if cp then cp += "["+tostn(c)+"]";
if indexs then indexs := array(r,c);
end else
begin
d := FData[FRows[i]];
if cp then
begin
cs := r;
if ifstring(cs)then cs := replacetext(cs,".","\\o");
cp := "["+tostn(cs)+"]";
end
if indexs then indexs := array(r);
end
return d;
end
function SetStringAlign(v);
begin
if v <> FStringAlign then
begin
FStringAlign := v;
InvalidateRect(nil,true);
end
end
function SetNumberAlign(v);
begin
if v <> FNumberAlign then
begin
FNumberAlign := v;
InvalidateRect(nil,true);
end
end
function SetdefAlign(v);
begin
if v <> FDefAlign then
begin
FDefAlign := v;
InvalidateRect(nil,true);
end
end
function GetTSLData();
begin
return FData;
end
function StrToNumber(s);
begin
if pos(".",s)then
begin
return StrToFloatDef(s,0);
end else
begin
return StrToIntDef(s,0);
end
end
function SetRowHeader(v);
begin
nv := v?true:false;
if FRowHeader <> nv then
begin
FRowHeader := nv;
FD := FData;
SetData(array());
SetData(FD);
end
end
function SetTwoD(v);
begin
//if parent is class(TTSLDataGrid)then exit;
nv := v?true:false;
if nv <> FShowTwo then
begin
if FCanedit and nv then return; //编辑情况
FD := FData;
SetData(array());
FShowTwo := nv;
SetData(FD);
end
end
function setdatap();
begin
if not Fdata then exit;
FCols := nil;
FRows := mrows(Fdata,1);
FCL := mcols(Fdata,1);
allFCL := true;
if FShowTwo then
begin
for i,v in FData do
begin
if not ifarray(v)then
begin
allFCL := false;
break;
end
end
end
fcs := array();
wd := 150;
for i,v in FRows do
begin
if ifstring(v)then
begin
wd := max(wd,length(v) * 9);
if wd>200 then break;
end
end
if RowHeader then
begin
fcs[0]:= array("text":" ","width":min(200,wd));
end
if FCL and allFCL and FShowTwo then
begin
FCols := FCl;
for i,v in FCols do
begin
fcs[length(fcs)]:= array("text":ifstring(v)?v:inttostr(v),"width":FMRWD);
end
end else
begin
fcs[length(fcs)]:= array("text":" ","width":ColumnWidth>20?ColumnWidth:150);
end
Columns := fcs;
ItemCount := length(FRows);
end
function gettxtobj();
begin
if not ftext then
begin
FText := new TFTSLScriptMemo(self); //tmemo(self);
//ftext.HighLighter := FHGS[0];
ftext.readonly := true;
ftext.left := left+20;
ftext.top := top+20;
ftext.width := 500;
ftext.height := 400;
ftext.wspopup := true;
FText.WsSysMenu := true;
ftext.WsSizeBox := true;
FText.onclose := function(o,e)
begin
e.skip := true;
o.visible := false;
end
FText.parent := self;
end
return ftext;
end
function SetData(data,f);
begin
if Fdata=data then return;
DeleteAllColumns();
if ftext then ftext.Visible := false;
for i,v in mrows(FCControls,1) do
begin
obj := FCControls[v];
obj.TSLdata := nil;
obj.Visible := false;
obj.Parent := nil;
end
FCControls := array();
FData := data;
setdatap();
end
function itemishow(r,r2);
begin
return r[2]<r2[0]or r[0]>r2[2];
end
function getdtobject();
begin
global Fdtobjects;
if not ifarray(Fdtobjects)then Fdtobjects := array();
for i,v in Fdtobjects do
begin
p := v.Parent;
if not p then
begin
return v;
end
end
o := new TTSlDataGrid(initializeapplication());
o.ControlIndexs(idexs);
o.height := 500;
o.width := 500;
o.Twodimensional := Twodimensional;
o.Visible := false;
o.wspopup := true;
o.WsSysMenu := true;
o.WsSizeBox := true;
o.onclose := thisfunction(ShowDataClose);
Fdtobjects[length(Fdtobjects)]:= o;
return o;
end
function getitemcontrol(d,p,i,j,tp,cp,idexs);
begin
idx := format("%d*%d",i,j);
o := FCControls[idx];
if tp="grid" then
begin
if not o then
begin
o := getdtobject();
o.parent := self;
FCControls[idx]:= o;
end
//o.Twodimensional := Twodimensional;
if o.wspopup then p := ClientToScreen(p[0],p[1]);
o.left := p[0]-20;
o.top := p[1]-20;
o.caption := caption+"."+cp;
o.TSLdata := d;
o.show();
end
end
public
function create(AOwner);override;
begin
inherited;
if not fhgs then
begin
FHGS := array();
FHGS[0]:= new TTslSynHighLighter(initializeapplication());
FHGS[1]:= new TJsonSynHighLighter(initializeapplication());
end
GridLine := true;
FCControls := array();
FRowHeader := true;
FixedColumns := 1;
itemheight := 25;
caption := "";
FMRWD := 150;
FShowTwo := false;
OndblClick := thisfunction(GridCellDblClick);
FNumberAlign := AL9_CENTERRIGHT;
FStringAlign := AL9_CENTERLEFT;
FDefAlign := AL9_CENTER;
mu := new TPopupmenu(self);
for i,v in array("一维","二维","原串","json") do
begin
mi := new TMenu(self);
mi.parent := mu;
mi.caption := v;
mi.OnClick := function(o,e)
begin
case o.caption of
"一维":
begin
Twodimensional := false;
end
"二维":
begin
if FCanedit then return;
Twodimensional := true;
end
"原串":
begin
showstring();
end
"json":
begin
showstring(1);
end
end
end
end
PopupMenu := mu;
end
function DoDrawSubItem(o,e);override;
begin
inherited;
if e.skip then exit;
dc := e.canvas;
i := e.itemid;
j := e.subitemid;
d := getdata(i,j);
src := e.SubItemRect;
if j=0 and FRowHeader then
begin
//_wapi.DrawFrameControl(dc.Handle,src,DFC_BUTTON,DFCS_BUTTONPUSH);
dc.Draw("framecontrol",array(src[0:1],src[2:3]),DFC_BUTTON,DFCS_BUTTONPUSH);
end
ds := "";
dc.font.color := 0;
if ifarray(d)then
begin
ds := format("<Array[%d]>",length(d));
//dc.drawtext(ds,src);
class(TLabel).CanvasDrawAlignText(dc,src,ds,FDefAlign);
end else
if ifstring(d)then
begin
ds := d;
//dc.drawtext(ds,src);
class(TLabel).CanvasDrawAlignText(dc,src,ds,FStringAlign);
end else
begin
ds := tostn(d);
if d<0 then dc.font.color := rgb(200,0,0);
if ifnumber(d)and j>0 then
begin
//dc.drawtext(ds,src,DT_RIGHT);
class(TLabel).CanvasDrawAlignText(dc,src,ds,FNumberAlign);
end else
begin
//dc.drawtext(ds,src);
if not ifnil(d)then class(TLabel).CanvasDrawAlignText(dc,src,ds,FStringAlign);
end
end
end
function GridCellDblClick(o,e);virtual;
begin
cp := 1;
cl := e.isubitem;
if cl<1 and FRowHeader then exit;
indexs := 1;
d := getdata(e.iitem,cl,cp,indexs);
p := e.ptaction;
if ifarray(d)then
begin
if d then getitemcontrol(d,p,e.iitem,cl,"grid",cp,indexs);
end else
begin
gettxtobj();
ftext.caption := Caption+"."+cp;
FText.text := tostn(d);
FText.show();
end
end
function ShowDataClose(o,e);
begin
o.show(false);
o.TSLdata := array();
e.skip := true;
end
function Recycling();override;
begin
inherited;
ftext := nil;
FCols := nil;
Fdata := nil;
FControls := array();
end
function ControlIndexs(dx);
begin
{**
@ignore(忽略) %%
**}
if dx then FControlIndex := dx;
return FControlIndex;
end
property Twodimensional:bool read FShowTwo write SetTwoD;
property TSLdata:variable read GetTSLData write SetData;
property ColumnWidth:integer read FColumnWidth write FColumnWidth;
property RowHeader:bool read FRowHeader write SetRowHeader;
property StringAlign:AlignStyle9 read FStringAlign write SetStringAlign;
property NumberAlign:AlignStyle9 read FNumberAlign write SetNumberAlign;
property DefAlign:AlignStyle9 read FDefAlign write SetdefAlign;
{**
@param(Twodimensional)(BOOL) 是否二维强制二维展示 %%
@param(TSLdata)(array) tsl数据 %%
**}
end
type TGroupGridA=class(TDrawGrid)
{**
@explan(说明)带层级功能的表格 %%
**}
{**
@expample(范例)
FGrid := new TGroupGridA(self);
FGrid.border := true;
FGrid.OddLineBKColor := 0xFF0000; //奇数行背景色
FGrid.EvenLineBKColor := 0x00FF00;//偶数行背景色
cls := array(("text":"a","width":300),("text":"b","width":30)); //设置标题
FGrid.Columns := cls;
d := array(
("id":1,"data":("福哥",true)),
("id":2,"data":("a",false)),
("id":3,"pid":1,"data":(("value":"a","type":"string","font":("color":rgb(200,0,0))),true)),
("id":4,"pid":1,"data":("a",false)),
("id":5,"pid":3,"data":("a",false))
);
FGrid.SetNodeData(d); //设置数据
//获得数据使用 FGrid.GetNodeData();
**}
uses tslvcl;
function Create(AOwner);override;
begin
inherited;
GridLine := true;
FOddLineBKColor := 0xFAF3F1;
FEvenLineBKColor := 0xFFFFFF;
FNodeManger := new TGroupManger();
GridLine := true;
FNodes := array();
FCellediter := new tedit(self);
FCellediter.Visible := false;
FCellediter.Parent := self;
FCellediter.onkeyup := thisfunction(doeditcell);
FCellediter.onKillFocus := function(o,e)
begin
o.Visible := false;
end
//inherited SetColumns(array(("text":"","width":25)));
end
function doeditcell(o,e);
begin
//echo "\r\nkey up:",e.charcode;
case e.charcode of
13:
begin
e.skip := true;
o.Visible := false;
callDatafunction(FCelledit,o._Tag,o.text);
end
end;
end
function SetNodeData(d,ncls); //设置数据
begin
FCellediter.Visible := false;
if not ncls then
begin
FCurrentNode_a := nil;
FNodeManger.RootNode.RecyclingChildren();
FNodeData := array();
FNodeIds := array();
end
for i,v in d do
begin
id := v["id"];
nd := FNodeData[id];
if nd then
begin
for j,vj in v["data"] do
begin
nd[j]:= vj;
end
continue;
end
pid := v["pid"];
nd := CreateNode();
nd.FNodeid := id;
nd.FNNNODE := V["nnp"];
nd.Expanded := false;
pnd := FNodeData[pid];
for j,vj in v["data"] do
begin
nd[j]:= vj;
end
if not(pnd)then AppendNode(nd);
else AppendNode(nd,pnd);
FNodeData[id]:= nd;
FNodeIds[id]:= pid;
end
UpdateWindow();
InValidateRect(nil,false);
end
function GetNodeData(); //获得数据
begin
r := array();
ri := 0;
for i,v in FNodeData do
begin
r[ri,"id"]:= i;
r[ri,"pid"]:= FNodeIds[i];
r[ri,"data"]:= v.FData;
ri++;
end
return r;
end
function getcurrentnodedata();
begin
if FCurrentNode_a then
begin
d := FCurrentNode_a.Fdata;
if d[3]="sysparams+" then return;
d[2]:= "*";
FNodeManger.getcdnodes(FCurrentNode_a,r);
reindex(FNodeData,r);
reindex(FNodeIds,r);
FCurrentNode_a.RecyclingChildren();
FCurrentNode_a.Expanded := false;
calldatafunction(FCelldbclk,self,array(1,d,FCurrentNode_a));
end
end
function MouseDown(o,e);override;
begin
//
inherited;
if e.shiftdouble()then
begin
r := HitTestItem(e.xpos,e.ypos);
if r[0]>= 0 and r[1]=1 then
begin
nd := FNodes[r[0]];
d := nd.Fdata;
if d[2]in array("str","int","lstr","double","nil","int64")then
begin
try
rc := o.GetSubItemRect(r[0],r[1]);
FCellediter.SetBoundsRect(rc);
try
FCellediter.Text := d[1]["value"];
except
FCellediter.Text := "";
end;
FCellediter._Tag := array(r[1],d,nd);
FCellediter.show();
FCellediter.SetFocus();
except
end;
return;
end else
if d[2]="array" then
begin
calldatafunction(FShowarray,d);
return;
end
calldatafunction(FCelldbclk,o,array(r[1],d,nd));
end
end
FCellediter.Visible := false;
end
function MouseUp(o,e);override; //展开折叠点击
begin
inherited;
r := HitTestItem(e.xpos+5,e.ypos);
if r[0]>= 0 then
begin
nd := FNodes[r[0]];
if FCurrentNode_a <> nd then
begin
FCurrentNode_a := nd;
InValidateRect(nil,false);
end
if r[1]=0 then
begin
if nd and nd.NodeCount>0 then
begin
if nd.Expanded then nd.UnExpand();
else nd.Expand();
UpDateWindow();
end
return;
end
v := nd[r[1]];
if ifarray(v)then
begin
if v["type"]="link" then
begin
return CallMessgeFunction(OnLinkCellClik,o,v);
end
end
end
end
function AppendNode(nd,pnd); //在父节点中追加节点
begin
if not(pnd is class(TNode))then _pnd := FNodeManger.RootNode;
else _pnd := pnd;
_pnd.AppendNode(nd);
end
function InsertNode(nd,idx,pnd); //插入节点
begin
if not(pnd is class(TNode))then _pnd := FNodeManger.RootNode;
else _pnd := pnd;
_pnd.InsertNode(nd,idx);
end
function CreateNode(); //构造节点
begin
return FNodeManger.CreateNode();
end
function InsertNodes(nds,idx,pnd); //批量添加节点
begin
if not(pnd is class(TNode))then _pnd := FNodeManger.RootNode;
else _pnd := pnd;
_pnd.InsertNodes(nds,idx);
end
function GetNodeByIndex(idx); //通过序号获得节点,必须update后
begin
return FNodes[idx];
end
function UpDateWindow(); //update节点
begin
//更新窗口
FNodes := FNodeManger.ListNodes();
ItemCount := length(FNodes);
end
function DoDrawItem(o,e);override; //绘制单元格
begin
inherited;
j := e.Subitemid;
i := e.itemid;
DObject := FNodes[i];
if not DObject then return;
dc := e.canvas;
e.rcitem := rec;
rec := e.SubItemRect;
wd := 4;
if FCurrentNode_a=DObject then
begin
dc.Brush.Color := 0xffce87;
end else
begin
if i mod 2 then
begin
dc.Brush.Color := FOddLineBKColor; // FOddLineBKColor := 0xFAF3F1;
end else
dc.Brush.Color := FEvenLineBKColor; // FEvenLineBKColor := 0xFFFFFF;
end
dc.FillRect(rec);
dc.pen.color := 0xa8a8a8;
//dc.pen.style := PS_DASHDOT;
dc.pen.width := 2;
dc.moveto(array(rec[2],rec[1]));
dc.LineTo(array(rec[2],rec[3]));
if j=0 then
begin
cj :=-1;
pd := DObject.Parent;
while pd do
begin
if not(pd.FNNNODE)then cj++;
pd := pd.Parent;
end
wd := cj * 20+4;
if DObject.NodeCount>0 then
begin
if DObject.Expanded then bmp := FBmpExpand;
else bmp := FBmpUnexpand;
bmp.Draw(dc,rec[0]+wd+1,rec[1]+10,SRCAND);
//dc.stretchdraw(array(rec[0]+2+wd,rec[1]+2,rec[0]+15+wd,rec[1]+15),bmp);
end
//rec[0]+=wd+4+18;
rec[0]+= wd+16;
end
if j >= 0 and DObject then
begin
rec[0]+= 4;
v := DObject[j];
if ifstring(v)then
begin
//if j=0 and v="sysparams" then dc.font.color := 0x0000ff;
//else dc.font.color := 0;
dc.DrawText(v,rec,DT_SINGLELINE .| DT_VCENTER);
end else
begin
if ifarray(v)then
begin
val := v["value"];
typ := v["type"];
ft := v["font"];
rebk := false;
if ifarray(ft)and ft then
begin
bf := dc.font.fontinfo();
dc.font.setvalues(ft);
rebk := true;
end
if typ="link" then
begin
udl := dc.font.underline;
fcl := dc.Font.Color;
dc.font.underline := true;
dc.Font.Color := rgb(0,0,254);
end
if ifstring(val)then
begin
dc.drawtext(val,rec,DT_SINGLELINE .| DT_VCENTER .| DT_NOPREFIX);
end else
if ifarray(val)then
begin
dc.drawtext(format("ARRAY<[%d]>",Length(val)),rec,DT_SINGLELINE .| DT_VCENTER .| DT_NOPREFIX);
end
//还原
if rebk then
begin
dc.font.SetValues(bf);
end else
if typ="link" then
begin
dc.font.underline := udl;
dc.Font.Color := fcl;
end
end else
begin
if not ifnil(v)then dc.drawtext(tostn(v),rec,DT_SINGLELINE .| DT_VCENTER .| DT_NOPREFIX);
end
end
end
end
function Recycling();override;
begin
inherited;
FCurrentNode_a := nil;
FCelldbclk := nil;
FShowarray := nil;
FCelledit := nil;
FOnLinkCellClik := nil;
FBoolColumns := nil;
FOddLineBKColor := nil;
FEvenLineBKColor := nil;
FNodeData := nil;
FNodeIds := nil;
FCellediter := nil;
end
published //属性
property OddLineBKColor read FOddLineBKColor write FOddLineBKColor;
property EvenLineBKColor read FEvenLineBKColor write FEvenLineBKColor;
property BoolColumns read FBoolColumns write FBoolColumns;
property OnLinkCellClik read FOnLinkCellClik write FOnLinkCellClik;
property celldbclk read FCelldbclk write FCelldbclk;
property celledit read FCellEdit write FCelledit;
property Showarray read FShowarray write FShowarray;
private
function GetChildAllChecked(nd,j,ck);
begin
nck := not(ck);
for i := 0 to nd.NodeCount-1 do
begin
cnd := nd.GetNodeByIndex(i);
if ifobj(cnd)then
begin
if cnd.NodeCount=0 then
begin
if cnd[j]=nck then return 0;
end
if 0=GetChildAllChecked(cnd,j,ck)then return 0;
end
end
return 1;
end
function CheckAllChild(nd,j,ck);
begin
for i := 0 to nd.NodeCount-1 do
begin
cnd := nd.GetNodeByIndex(i);
if ifobj(cnd)then
begin
vi := nd[j];
if vi=0 or vi=1 then cnd[j]:= ck;
CheckAllChild(cnd,j,ck);
end
end
end
FBoolColumns;
FOddLineBKColor;
FEvenLineBKColor;
FNodeData;
FNodeIds;
FOnLinkCellClik;
FCelldbclk;
FCelledit;
FShowarray;
FCellediter;
protected
type TGroupNode=class(TNode) //groupgrid节点
uses tslvcl;
function Create();
begin
inherited;
FData := array();
end
function Operator[](idx);
begin
return FData[idx];
end
function Operator[1](idx,val);
begin
return FData[idx]:= val;
end
FNodeid;
FNNNODE;
//private
FData;
end
type TGroupManger=class(TNodeManger) //group节点管理
function Create();
begin
inherited;
end
function CreateNode();override;
begin
return new TGroupNode();
end
end
class function Sinit();override;
begin
inherited;
GetSJPng();
end
private
FCurrentNode_a;
FNodes;
FNodeManger;
static FBmpExpand;
static FBmpUnexpand;
class function GetSJPng();
begin
if not FBmpExpand then
begin
FBmpExpand := new TBitmap();
FBmpExpand.readvcon(HexFormatStrToTsl("0502000000060400000074797065000203000000696D670006040000006461746
10002C700000089504E470D0A1A0A0000000D494844520000000A0000000A0806
0000008D32CFBD000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000005C49444154
285363F84F24204DE1EA7DF8F1ABF740851FBFFEFF9FD9F3FF7F443D6E7CF53ED
4C41B0FFFFF8F6FC1AEE8D005900A24379EBA86A968D729A82410A07866F76984
A2CD47A1825080E16B9807D00186425C804885FFFF030081696EBEB08C861D000
0000049454E44AE42608200"));
end
if not FBmpUnexpand then
begin
FBmpUnexpand := new TBitmap();
FBmpUnexpand.readvcon(HexFormatStrToTsl("0502000000060400000074797065000203000000696D670006040000006461746
10002BF00000089504E470D0A1A0A0000000D494844520000000A0000000A0806
0000008D32CFBD000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000005449444154
285363F88F0672FAFEFF3F7A09CA4102180A23EA2178DF39A80014E05408C23B4
E40058100AF4210DE7404224E502108AFDE474D852045208057214C1108E05488
AC08043014164DC654F4FFFFFFFF0022DF66E2EA30F3BB0000000049454E44AE4
2608200"));
end
end
end
type TNodeManger=class //节点树管理
uses tslvcl;
function Create();
begin
FRootNode := CreateNode();
end
function CreateNode();virtual;
begin
return new TNode();
end
function ListNodes();virtual;
begin
r := array();
GetExpandedNodes(FRootNode,r,0);
return r;
end
function GetNodeByListIndex(id);virtual;
begin
return GetExpandedNodeById(FRootNode,0,id);
end
function getcdnodes(nd,r);
begin
if not ifarray(r)then r := array();
for i := 0 to nd.NodeCount-1 do
begin
cnd := nd.GetNodeByIndex(i);
r[cnd.FNodeid]:= nil;
getcdnodes(cnd,r);
end
end
Property RootNode read FRootNode;
Private
function GetExpandedNodes(nd,r,ct);
begin
for i := 0 to nd.NodeCount-1 do
begin
cnd := nd.GetNodeByIndex(i);
r[ct++]:= cnd;
if cnd.NodeCount>0 and cnd.Expanded then GetExpandedNodes(cnd,r,ct);
end
end
function GetExpandedNodeById(nd,ct,id);
begin
for i := 0 to nd.NodeCount-1 do
begin
cnd := nd.GetNodeByIndex(i);
if ct=id then return cnd;
ct++;
if cnd.NodeCount>0 and cnd.Expanded then
begin
r := GetExpandedNodeById(cnd,ct,id);
if r then return r;
end
end
end
private
FRootNode;
end
function getdebugicons();
begin
r := array();
r["调试运行"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100021003000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000002A549444154
484BAD958952DA501486592ACAA652A4E2C6BE18A22202A540DDA6639FABCB540
58D200AA22C21019EAF8FF0F704AE89B59A9982DFCC9924E4DEF3DD73C84D0C60
7CED7238E96CB2ABB743157C11E314511C53BC25AAE044A2E4BD108EC4200EBB0
1F6EBF46815C8611CCB945CF2E340F461BFBBC1EE4C872A381E0470D8A7C4FD75
14A555E4452FF22D2FBB3B39AAE068E8C7FE601D85FE0AF2D2077CEC2D21DB762
37BBFC4464C862A38186EE0F380920F3CC8C8EF91E92D22DD5944AAB580BD3B17
1BF5FFA882FDE11A0AC36564FB6EA4E505A47A4EECB41D483ED8B1DDA0E3ED3C1
BF92FBF396E14CFCF15544171B88ADCD083ECC08594E4C0B668C5567B167C93A2
318BC48D157CD5C146BFCCD3C48FA802A53DB901ADBE3F8F64CF06BE330BAEFD0
EF1A609F1BA199BB5197095396C09AF4B7405C5A177D49E3D995A23CE21D19941
ECDE8448C38048CD8068D584A8402281AA29BF2CD115140624905DD895ECE0BBB
4FA0733227794FCDA80B06040F0928E17242A5355E7566C979C6CA686BE405E46
5A2281E800DFB62046AD89DE8C93874A2438A5E319C5B911B1730B36CF6C6CA68
6AEE093444F50CF8564DB8EC403B5A76142A8AA250FFE64F18BAA3A35B3597FA3
2B50766EA64B15B49C48DC5910AD1B11BE52563C4E1CF83E0EE5FC35F42BE890A
0E5C64E93047512DC90807A1EA0D58F927F1B871EFA15D07B27D37423D97082AB
CD21563523541EB74411F874922B891F933F3D57D02AB85F41A64102DAB1FCB50
D316106E1B2712CF8A1BF723DD499B90609EA1EECD616C05FD910BFB4205232D3
1F6C642326436BD1ED1AB2B565EC565CA3DDCA95ADA3C7715A5441A1B6814CD58
BD4951B5B17F3E04A7676673AB40AAA3EE42AAB480B1E242F267F3D3F47ABA0EA
474E5843E672FAAFD8535441B112445EF0B1ABB702F803D2475555757FB6FA000
0000049454E44AE42608200";
return r;
end
function GetEditIcons();
begin
r := array();
r["打开文件"]:= "0502000000060400000074797065000203000000696D670006040000006461746
10002DB02000089504E470D0A1A0A0000000D4948445200000026000000200806
0000007E640AB3000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000027049444154
5847ED97DF4B537114C0EFDF104410414808D54B62504F113D590FBDF86A083E0
4820FD10F028320EAA51E7ACD880C451DA8A5A258334B1333FAF51211856E7777
D3DAE62CE6E6D674DB3D9D73EEF56EB77D37B6D5BE97A00F1C3676B7EFF9F03DE
7FB63CAB43F011D3361383DB652760C2DC6A0D6280D7D9A3079A9D8716709FCB1
2D7388DAA050124A562EB7DE7D67B1F995A4F9496DF82F5629158B3D0F2458ACD
A689B0AC2C3C5B8395A712A168B6D66E1DAAB08FFA69AA07CADEEA0395A712A16
FB53CACDF76F8A851219B8F976ADAAA045220ACA77A8CF277CB61D6A74ABB4D88
9E1000FE44414157BAA6DF0177A3EADF3D6202B86F1B82B2976793EC25F904DE7
4B23AF502CA3EBD0D8AF712965D334B20CC787026231B7666CA25446997C8CA46
067D7125CC159138A5D9A5B75A48CBD38119477528D178A6D6674D8DFA3C2499C
52D99C9B0DB35834952D147BECCBAD4699A4B33A1C1BF45B7D5D2076FE85612D9
B37C19F9C97FA8BB089A5B08C7BEF7BA179DCDE7332E8FA10B5FA8BB0894D789D
292371763AC4B9A9BF089B58FBB3102E570FBF97C93A5EA50E0F68D0F428B7E02
CB1445AE73DE4CC936FE62379CC2E2779B6AE2E18FD455862639E383F1CF82CBF
8CB7DFFFB0F5176189D1AD921ADF095AB04ABBEEE6FA8B60B153B899D22BF5986
C8278E73BD8EBC3C9B16FE82C76D4E567B1512CA76C26556327B8FE7ACDFCC480
C5F675AB70008F2127B88142E4E0C613271F16A3B88007B713344F7C853DF73CB
6FE222CB129BCB1CAC68B77FBBA6EF149A3D43F5061371AD7E18AAC5960F2EDA0
1D203F6852E8CFCBEF28AE2F3138E2D2C403FE8DC89312895D9C0B43326D2F230
0C02FA1DC4D3F567030CC0000000049454E44AE42608200";
r["保存全部"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100025302000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000001E849444154
5847ED974D4B42411486EF7FE9EFB40A8268518B68578B9605EDA25D50B4A88C2
40C8A5A5408B5882430C122888220B2FC46F2A696A9842935F91EEF19A68B9479
3F16D50B0766CE9999F771D0EB3D9A3054BDD545767A5F447B16C455D7842381B
3E1012F16013CCC055A6E7032F4D9C326402DFB2C93A991755139898A78FFB25C
84B995E00F873331CF8C6F4B3F786BF7537BD28CA50258950AC04A0EFB28076FE
DAE7B9E26A0635901C09EC4D0AA281FDDD0BC1540C117A61CBC350CEC0430EF6D
05002FF6FDBD003086FE1E40D17F29729EA03CCF7500B32C03206F253A028031E
7ED0AF536BF05803293BB446D47E02C556D0138A97F808E005037AFF92A67CEAB
42EDC700BC4E15FFC45471CE5680F271446E78DA3937B22E02A44637E8252231E
815B13E8F917509E0AD5AA77A29702DF499031ABFBFD4A8C60F2C55B60314FD17
B25E398DD138BF12A29A2B00E9C6F5F31A8EF880976AAD0038670B405D2F512DB
7D4FC7B45608CDC6BB220CDF8918B39DF00E7F0A66D56DB0085B5301D520E468C
4CE317D11823875ADE1B92460806507396009CD227006EC5DC0478DC3A234F786
BE8D53041C7E29662BD8BE4096F0D8D2226083C6CD034E0369C089C9D1EDB947E
F0A6E694BFCD6E063C21D99EA35144AFC6AD9A1381B3E101AFA684F80055B3808
F56B6A2590000000049454E44AE42608200";
r["保存"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100022702000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000001BC49444154
5847ED97CD2E035114C7EF4AB045B011ED0295D06D173E1296880891B0A88588F
00E3C000F6021165D88442CBD869022AA3A65CC0C8BAA36165A334D8FFEAF7B5B
7442FA35ABF927279973EE9C737E776E663287514196A191B1BE48515F1B457A9
A1A6AE8A1AFCDD387728BD6C4D03C36DC657B73232D36D4C937CEB07304B49559
B29E0DCA84CFB81F1F1B20538DD7C5500B3551DB7AD2490BCE70DFD85822261F3
B16A022C0A49FFB952A6F59A4AFCE91693C8A08F15A1200C2CEE1477DEDC47001
93AA15207B73C9F3D3C7211129078064DFBA03C8FCD4E1BE88380C90BD3AE7F9E
9A303117118209F79A758C0C38F42AA2280ECF505F7EFC77D2252BBE45B80DA52
B26F19402E99A0486F3345BDAD646A0F225ABDF01A463C2DBC662E9514D13F002
02D38CD63CA683FA5427BF4767A5295215719E9E3B5F09DF92ED9D716C0D4557E
8E72AD565302DE1FDF0548AED90240388AC4CE16A90B13A44E05AAB3426E62779
B72AF2FA26A49FF02345A2E800BE002B8002E800BE00214017E0F264EA838980C
7610C3A00807E3921310682E7FF98CCD65629852312822E0A4DDF9BBF9864BE37
96150C4AC6677733D0D3DB0F3AFA74DF409837977A59FB64D730000000049454E
44AE42608200";
r["取消注释"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100022001000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000B549444154
5847ED95C109C5200C40FF4E4EE15D07D0832B787142F1EC0C2EE03925FC2A9F9
2160A7EE3C10739546DF220113FC0CC16D8026B0AD45A21A5343430270529E09C
0321C4D0C09C146B0AB0B76026EB0B78EF2184707E8DE751008BB721C23EFE035
2A094024AA95EDC180331C63E5039E7F3E497B6FE14AF86504AD98BDF45039353
FBD778750DD905B0055AEBFEB3B5766E0B1A6C43F80BEB359CC19A02EC8F11FB7
3CC2EC0DE82996C812DC02C0070005765629339C9EFE60000000049454E44AE42
608200";
r["注释"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100021201000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000A749444154
5847ED94410A80201045BB9377F20A6EBD9757F03A82BB8909021333B56F1AF8E
0D3A2181F8CFD8D06B30496C09C02CE39B2D642C333532405A4942484808667A6
985360F80ABEE41F02C6986387FC445324105E26B444D125D45A6725C26FEF02E
F81538287A7DEC781F740578170058C52EA32ACFB0A42BCF7D9C3DFF228C0F0A1
437FC39ECC2910F70022F01EA80DBC076AD3DC03A834F7406F96C012182C40B40
319335F36295E4B140000000049454E44AE42608200";
r["撤销"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100022A03000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000002BF49444154
5847BD974B681341188073F289F80005116C6BA10F15D48B56A8AF832858A8288
8F460412A420F05A9079182E2C1E20391422B88A055F060050F2282482D689552
2A5AA14DB24D9A3449D39A36469B64934DB2BFFB4FA6D34C36AF26BBFBC17FC8F
E9BFFFF6676323B314101486E2744C67ED24FDA925720F47500849A8D602E5B09
A12FFDF4AA76E414C0E6D6EA0D60DEBE824468F013CD68475681F0D067106A37B
1E6735D9D34A32D1905B8E6CAD4FB9F74D18CF6A80454CD9F76D38C3E7002E9CD
FFF43EA219FD60025CF38AD51078D54B33FA4204D29BFF7DFD82245359F8F80E7
E775E2F2870C1E200A2360BFD76764CAAE66F5ED2D412F1791F98CB5725EF5966
D88FEE26EB4896A2B41A8FC9D5DCC86E7634D667BC518EC5C0717C1F5778B9613
B540DE1916FB4E212A644380453E74FB01B5D171A408E88349D422241B664C969
CF1BE2F72108F43D0777CB19B0EE58C36A5B2AD7A96698AC8182258A202A8C73B
5F13107073ED02C1540F49480781C663ADA586DEBAE2D109B769314B70F1089A6
93FA48C832785A9B586DEFD54BE4322780C862583789B87F0EAC3B37276B2B8F4
29A9A540B207A4AF8EEDF6475FD8F1F661640D2D784FBE269F24B2895C8F82F56
13079955004997107F0CD34C6990038E52CF565F955B0041096F7B0B9901AD1E8
3FD700D11B054ADCF2FA00713FBCB8880B067ABF102388B8BBB236EEF860B04FB
DF93E618D36DCDC60B782E9F6302FFDEF6192B101E1E24272D6C2EECDD0689E08
2710231DF2C4C1C2867A3F73FEB21D70D11C093D1E4915AD6DC79F69872C69048
4E578178C00FBE07B7D8C68361AFAB24B3B1082780070EDC9FE77BEE151FDD776
1F6C615B2CD5A2BD6B2C6188E868310F37A68B7249C007770D030F0EF9DEF4E07
79C9A5C309CC5C6BCD58A0A85056BBF3549D7242BEAD1A752AFC1A50DE7691B15
11047474A0AC9E500391AA1457301F01FDA4F2FDFE8B101E70000000049454E44
AE42608200";
r["反撤销"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100028202000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000021749444154
584763F83FC060D401A30E1875004D1DF06ED684FF6F2677FCFFFFE70F540413D
0D401B73485FFDF9063FBFF28DCEDFFEFD72FA1A2A880A60EB8A9C403760008DF
3690FEFFF5C83EA80C02D0CD01207C4B89EBFFEBBEA6FFFFFFFE85AAA0B30360F
8496AF0FFBF9F3E80D5E075C0D7A3FBFFBFA8C8FAFFD0DBE2FF1D53B9FF7774C5
49C2D82C87E16779F1603BB03AE0F7B327C084E38A5523B5F0D3AC28B05D180EF
879EFF6FFBB26726045F71C75FF7F58B9E0FFEF17CFFEFFFFF70FAA8278802B0A
1E4579FCFFF3F635580D8A03FE7DFFF6FF9E830E58D1F3A2E4FFFF7EFD84CA900
7301C20CFFEFF557B154AB980E280B733FB202E8C70C75B78100B50B2A1BEE4FF
2FFB7740651000C501F7ED35C18A7F5CBF0C15A10CDCD610049BF7C0D7EAFFAF2
70FA1A2A800EE805F4F1F8115DF7731808A500E4079FE556BC5FF7F3F7F404530
01DC01DFCE1C033BE0496A0854843E00EE80EF174E431C90140015A10F803BE0C
F9B57E0547AD74289AC2C472E404984A0C4020A852F87F64045680F501CF069E3
4AB0034065C1DFCF1FA1A2B405280E00D5524F62BDC18E78E86F0B2E92690D501
D00047F3FBEFFFFC0CF1AEC08503E7E599BFFFFF3EE2DFFBF5F3A4B3206A52B42
00C30120F0EFC7F7FF2F9B4BFFDF54E6053B845C0C2AFDFEFDFE0535153BC0EA0
018F8FDEAC5FFF74B66FD7F5E96F1FF496200B8122105BF6AAB849A841BE07500
3DC0A80306D801FFFF03006C2FCBC409CD25D50000000049454E44AE42608200";
r["tsl语法检查"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100020204000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000039749444154
5847AD97F94B545114C7FB5FFA2DA41FDAC8A00CCA225A7EA9205A208A8222081
222FA413335CD25358D448BCC32CA16111754D250C9164D2575F66677369D71C6
D91A47E734E7BEFB5E6FF4CD7B6FC6F9C0859973BFE7DCEFBB73EF7D7736419AA
C8622E0EB99266D35B44CA3A993B281D09405EC0F7A40BDAF1C6636DF254DB3BF
021CE5BD109AB652957C641958F185C0F36E0C8C175F708362335D69212D2176F
515783BA620B6BC42B3C51135101C3382BDA80BD47BCAB801D4D965E0ACF90C51
E712550144ED3E7054F681725B11A7D31CA80267553F849576AA12669D81154F1
03CAD3FC078E139570C1B3EE9D2A08AAA92836BC270EE5962EEF556F076FD0688
51118F040373F91DA0DC55C225E2D3BAEA07613518A10AF9E0ACD88BBB61764B3
E574F7BB886CC1E1FCE80F5F6074E68BEF61A823F0DB467E3E0ACE84F3570F56D
859DB4876780ED4C075FEF0C18CE3641E0FB1F1A1106FB710CD4B26CD8406054C
74D333EA918193780FB5E955D4AF2F06C9022A30622C605D01EAA2639D63B1F69
549C8C19882EF8417F9A5954E6F8168B45A2B4479C8C18C0C18C979A9942F1FDC
E3F90A4C8880157ED00D1E98E3E86C54F1364BFCB45D4806A37B398A49E088B68
0F3EE20C133327EAC9A123B50BFC032AA2B7DC7C4B233C03FA934F496770DC482
3E204BEEAC0F1B01774C7EA12CCAC3DE9F878DB27194D451F8DF00CA02BEC4451
AAB8EA0649AE3AA71CC2AAE42F1F77F328D1B9E3EF1A16CE00BA927A0221E61B8
7491E1E46FE112D8D0A83B551EB1F52D308CF4070D24C3A75C7EB68441A77CB37
92836DB17D824693A3D9CB5C62F036C5C21940B4476A89203C3B4723C9F1B48D7
383CF370DD368727081A2D674F9258D30241860A748EA67C0773B3BB8A354FA08
46D89BD342D3088D302418082B6CA0D85A088AAC02D159C07D8CC5AC79EF69441
C76B6943B4BC8187C120C20F30D4344CCDFAB6B8998DCB2176BD413004D2E736E
A091B5AC338018CE3357AA5477841096BC3652CB16BF6D09216800A79F5DB178F
4A68BBDA49BD4D09F69A491F5081A40961D3EB216B0C05CFC758BDFE5825ACCC1
5CE58E621A1526A90116754E0529A4CDAD066F77FC662B016A508B39982B85A40
1C47CE30D2988CD7EBF1322160FEDF90FC6B08FD5618E1C641940F0CAC516C763
D77AAB0D82BF4CA4E167F65EA8C8BA07CECA7E9A258D6C0308BE01F9B3C16FCAE
DC5602BE880BF6A0755CB2325032C38DDAE275FC881840DFF37C6C2E9FD434ECB
40E600F8077525AC9F3D612B2D0000000049454E44AE42608200";
r["tsl代码格式化"]:= "0502000000060400000074797065000203000000696D670006040000006461746
10002E601000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000017B49444154
484BCD96CD2B04611CC7FD390E8E5C1D957273578E0E2E4AED897FC045EBA58D1
4DBA675D8C8A64424D12E566B6D1B4931C94611C9719E9FF93EBF999E31EF333B
C9A77E87797E2F9F79E6ADE92293A90341DD593D561C3F0AB3DB1F29687F916CA
83E89483152E2404FF936582205684271542CC1E239F7151AFE928E0460A9C6BD
0B67DE928E0560B5CEFDD98A7B462A02B07EED2D492C185873D76FDDF09CB9AA9
22712945A5C3F54E09D380339CC0489040067E9351C918A2088FF2FC0E539D5D4
8D74D29160A349345C0CAE8D2CC85FF14DB33398D7A9D8E435E4F0FC3B0915E42
E04F5E6749AD81574FF6E2E1AD49E897AE6551D72A8E9336A972F952850603D7E
56819D4963D8CC897B1DB5E899AD702E74078D17A2F11D215FA46DF373FCFACD8
DDAA73C9420879AB1B2A07A5B89430516B804993D2EC4376674530D01997D4177
6FE6818DC8023BFD2B828E1E7E0BFC882D40DE6A8842A21DC4E1EF05DA875A4C2
3300B3F12400AC0F42127D208FC0231443F28BE427F9C549A270000000049454E
44AE42608200";
r["查找"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100021B03000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000002B049444154
5847E597CB6B13511487FD5F5CB8115C09EE74A12E4437D58D2B455011DC88822
86215AD8A2DA1A550954A7D9582A4565B4DB56A158D4A11ADD6BE93B44D62D264
92A6499C344D3331C79CE39921D3492693718C0B3FB884FBE33E3EEECCBD77B20
6FE31550B48C20F488F06203D16845C2CC5A9792A0A64A6C310BAE880D93DD761
6CED694D99D8701EBCFB6F41F8CA5358F12E702FE3E80A084DCF6162FD399AC87
BE036241E7D858C5B809F6206A4A808A2D305D1F6B710386E2FB4AB87A94D9720
76E703F736465901FFD12E9A187F97867D9C9667E9E31C7876B52AB2462929202
F6FB27F9413E3044ED895FE46D008A0BDD1CEE548BDF7D01842F34B4ECAA312C0
E7871DC397FB3931CF42C73B1A0BDF1B3D14017C83F1259AA96BE3E4CFF11DBC0
B737BDBB9561A452074E10919E3F25985383845638A4E37275A1481E9CD8DB4D7
AD06572170F201D7B490406A68864CF1C0B19AE88D37E0DA66E39A161248F48D9
080996D5789B8FD138D9D5FCE72A28604A2379DD4480A2529B412F1D5EFF76079
32C4891A1290B74C3618A7D04A6401BC534A4102B8F4D828D1ABBF67CD808F607
CDD19C84B394ED49040C6132181F9B3BD145A49A4ED357876B6724D0B0920B3BB
AF8167470BD7AC037798DE91AC08445A06691516BB3F73521B14815C220DEEC27
EC503A9962802C862E710AD42F0540F277F1F950062C5758CDB1A8B113402080A
60A9F664942222CCD7F729FDABFE1E28A6DA4FB2F8C32FE0DA6AA33EA106077C3
F76DF9044590104F7B07B7B330D84178AFFF03D101A0720F17804928E6F20D85E
80AF90B9B634511BEFBE0EFA3694C15BB09284AE0092CFE620DE330CFE239D345
87199DCD800BE4305A9C204C98171EEA1060F373D898A02AB91FF98ACF8629C54
061F094AE059B39AAA05CC12BEFAACE44AD44C00C1C951A2989A0A94E27F1700F
805D0F3420D05EDA5310000000049454E44AE42608200";
r["后退"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100027501000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000010A49444154
5847EDD3218B84501405E0FD8B16AB60325A15C162325A0C2641D0603319AC822
641EC62B2984C8270969179CBCC70C75D771FCAC23B708A70BD1F3CEE072E8E00
088000FC5F405DD7304D13711CDFBFFC2E8701E338C2F77D4892B4F5544096655
055F56BF96980A66960DBF6D3E25300D3342108027231AB65591BE2481FF31690
E739344D2397FEB56DDBDEB71080AEEBE0380E39C8AB6F0161189203BC4B02E67
9866118E400EFEE3E4151145014851CE4D55DC02DCBB2208A22729847BF05B0F4
7D0FD775C99FB052679824C96E1FB30B6029CB12BAAE9380D7BB3E9A1F016E59D
715699A4296E56B002CC330C0F3BCEB002C55556D677B19805704400004E06200
F00985F34928814F15230000000049454E44AE42608200";
r["前进"]:= "0502000000060400000074797065000203000000696D670006040000006461746
10002E501000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000017A49444154
5847C5963D4BC3501486F33B440DE220520D3AA888ABAB8A28A26DA9F5A355549
42EAE4E8E8E6ECE4EFE011737870E8E82AB38EB0FB8E7B6C79EF6857EA569D2DC
9B3CE585F4DE03EF43C897C331D9A0031C8D466C8129B5C05B94C3BFE81811185
3B3BC4D79AC44C3988064870A580D8F5101C92E15B1130EE302923D3AC2EE70AC
0848F6E90413C158139064A984A9C1581590E4A98C497F9CF75A95E3649880A44
0E7A8EBC7918165B51E2BBD857E39D417A8ECA62990548A7489DA36890A488EE9
0AD52D1217909CEA6BD4A7242029D14DBA02923255D213985073E99D0157CD37C
B85C4055CF250DD2251015779AC1ABF4E121390D3FE5BFF436D9BA680DFE3B533
2B149CDEB2DE4C362EB86FFE416537D65F4672B57FD6BF50D78FD5D7F1B8CA70B
5FE81497FAC0ABCD6DE3035182B021EADF1B37EC14430C605326A951FF5137687
635460462DF1BD7EC04E388C094CAB45BED577580D8F1101B9D5CE74052BD1302
290D3C15FBE41C416D8A42C8E4681F91F06F7DA0A168403F80000000049454E44
AE42608200";
r["快捷键说明"]:= "0502000000060400000074797065000203000000696D670006040000006461746
10002C601000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000015B49444154
5847ED96314B03411085ADFC019616F676292D2DD2091616B63682A545B0B4505
BD1D2DA562C03762155AAD4225148F49010541051C1588CBCF1DEB91956B9856C
C2E13D781C6F7676E7BBBDE66664CA2A014A800CE0A37329FD9D2DB95BAF46F56
0775BDEDBAD746A0AF0D66ACAD5C2ECC4DC599C9397FAF90FC0EDDA72B6D8AF6D
CAC3D17E6E3F1E1FE436FA3907B79101B038D8AB6931A69ECF4E7F070021844FE
2DA57B3B63D36BBB55C00ACB1114FD6B0EE5E27F731C390DD031507000D34E466
0230739FDB637310404C0503B86F61330E83DD9AEDB10A06E01A0C61233301987
928336C553C000E816DF6D9F658A1160400B90786D827D4830150674F5EFFF532
582F1E00368478AC00E39417E0BA32AF45FC0B0C939E2EC4D2D3C9A1CE4A36563
52B0006F3162665DEB602BC362EA4B7B2E46D8CE16EB5A2C32105A086DD1BFD46
31FD799FA4D3BE3502300D9500FF1D40E40B036C6466EFBB13F70000000049454
E44AE42608200";
r["代码地图(alt+m)"]:= "0502000000060400000074797065000203000000696D670006040000006461746
10002A405000089504E470D0A1A0A0000000D4948445200000020000000200806
000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000053949444154
5847C5577D4C95551847304021958FED22134190217B5F750C192226384030705
302455D3304FF409BB32205755CBED2A2D41495BBA29CAC81F63186D4D614E707
96C628FE486B4BD104CBC972E2951C9AECD7F31CCF7BE1CAB978B1B97EDB6FEFD
D79CE739EDF39CF739EF7BD2EF89FE1B4804B972EA1B6B616797979A8A8A8C099
3367A4E5BFE1A902FAFBFB317DFA74F8F8F8206BC912588A8B51919D8DE52929F
01A3F1EADADAD72E6B3614401E7CF9F87C964C2E7F5F5B85F5E0EEBA245766C9B
370F73838361369BA5C7E831A2006F6F6F0C5CBF6E0B7868D62C644F9E8CB2F07
0B4C6C5D9C6E7F8FAE2D4A953D26B747028203A3A1ACDCDCDF87BDD3AFCB26001
5C5C5C7078F66CDC2A2D45C7CE9D707375457158984D04DB9F050EBD7C6957FD7
575B6C57F4B4810A73114251B36E0939933C59C147F7F946565498BF3500AB871
E30602030371BFA4041DF3E7232B20008F2E5E94D6417474746075529210F04D4
C0CA2283DA38552404B4B0B121313D1B772254EC7C66213ED5285BB77EFE2E5E4
6421E02ACDF7F5F09016E7E13005E154687D6BD6A093164E0E0A92A3F6686A6AC
2A6820221605764245684864A8BF3702860ECD8B1E8AAAC148BE7D155ABADAA92
9641B8B9B9E19CC522E6E44E998286DC5C69711E0E05A4A5A5A1913A1E2FCE7C8
36E00DFF7C6C64654575763C28409E204EE519AD89EE4E78787274E486FE7E150
405B5B1BBCC68DB309607653D57F4727F12B5DCF07478FE2DEAA5562BC6AC60CA
CA6A21DE8EA92DECEC3A100467A7A3A8ED0D51A2A42C5A924B43127477A8D0E23
0AE0174E0C15972AA8C11A5D47F4C489F8E7EC59E9353A8C2880111515852F972
D530667A652033A9C9121678F1EC3049452ABD5340D4B972E457E7E3E32333391
4005A80ACEBB8F9D34090F8F1F17DD9253B670E14258AD56B11617726A6A2A62A
99744444420801A9AA7A7A76872C6BBC34E406F6FAF6840AF1DBE89B995D76DF4
D333B0272E759880006A3CFBE317DBCD359873A41B71F464AAECC6BBC34EC0B16
3C7F0E6B672686FFF6EC7D0579BE0EAEA66179C77BF96EE7E51DE67C3E66BDBAE
41AFBE327C7C0859C0C53FFBED05141616A2E8D3166825D786D13FBE00DB631EF
77DA6BFBB3B1AD25643DB71157A5527F4DD574450BDE632B47768EC7D1AA3DFFA
41228FEF21F2D8CE4E841534C3332012753FF4DA0B888F8FC7E27DDD4A01330A7
F8487879708CEAFE1726AD5AFAFFF0ADA76B23F417D3FED5EB1864153CA56F8C5
E6C2FA60C05E40DFC301E845EA23630666EC40CAB44878D2B7C0B7991B957398F
A3E12B0596D637A4F4B44489645C4B413F0F1F777940E06F9085DC68C111F2639
EB4F2AE77060FD834EB54D728CDB0B48A8FC59C414027A7A7A44F5675AFE503A1
8E49C9A92B6A02187AEAAC22EC8C75C71556D9374F7094141C3CD4101EDEDEDE2
45137F90F2C7C5B48B8A8576218A860BEC3D492E26CB65A4ECBE209E23D228C00
344AA09E14BA989283B07AFD018D45EB83328A0A6A6065FFC6455AAB5B18C76F5
949D695BE89468034A9B64F02B87E017BD16576E3F782C80BB1677BE151F8D7CF
C7CB5B4AD74BC2A9B4133D9E95A2A6D92A68422042DD92D82335CEAE99BDF6C2E
C5AC62B583C1A7151693EFB8A80185CDA0ABC78B8879EBA40C4F02B2E95FCEC67
20BF40F29477B65AE38679C3BCE21E792734AF5C01D4E33D30E2BA9D1BC4B35C1
75C27EEC738048CD4608E079FCE4B4D15C8D84895AA2DA72F70FC6E6AF6FC9F02
480BFFD7D4C53956A0D8A8515E34F9205ABC60D86E41C112D78EFE9DB32BC2C42
6DCE4BC2F0BCE9E11F8ED0E507F057DF23119C616B443DD647A2373F6FDA03F81
751AD08E04A61DA310000000049454E44AE42608200";
return r union dbugicos();
end
function dbugicos();
begin
r := array();
r["添加/删除断点F5"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100022B01000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000C049444154
484B63F84F6330022CB0769FF85F58A98A280C528B0EF05A1095BAE8FFCEBD37A
03CC200A416A40719E0B500E42A5201BA1EFA5AB076D3C5FFF6DE93C16179E4F8
5DEA5B6064DFFDFFF6DDD7501E0D7C802E396A01088C5A800148B2A073E2DEFF3
9A56BFE6FD87A99280C52DB31610F543704E0B500040E1CB9FD3F2967195118A4
161D10B4801000F9121FA0AF0520C5DA961D58BD8F0DFB45CEFE7FEFC11BA86EE
C00C50210F8F0F13BD608C48689011816501B0C750BFEFF070066B64F1FB7C689
CB0000000049454E44AE42608200";
r["暂停"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100022401000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000B949444154
484BED8FBB0AC2401045AD2CC4CA0FB0D0CA5E1B7F401B3F3C820A29825A98F8C
A0F988744E2C459278F6598ADB450F6C06DE6C23D4C0BBECC1F0B1EE105B2E3E1
9D934FD79AAA7B258F6E74E58882FDA807DB7EBBCA3389A90148374BAD0B16536
A38A2A03980C9E3881A8064EDB05E4214EC061D6DC024F067636A3856A062052A
56C0B0821251D01CC098041809F98361571B300982F9841A8E28B87BAE1AC2A4E
E8AAE356587C9AE67BA7244C1A7F875014001DF29EF2FFBC3E1B1000000004945
4E44AE42608200";
r["继续"]:= "0502000000060400000074797065000203000000696D670006040000006461746
10002E201000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000017749444154
484BAD95CB2E035118C73D835BB4112511D61E80A7B0747900AFC003D892A84E1
B246CEC24166A8145C3A60B21128BCE8CA6F4128AD665A42EF93B47BF3363B43A
9D73E697FC33E93933DFAFFDE6CB690788C5F43DB4F30A7D0A0E5B90BAB1108AE
9984916706B7DD2AA3A2E4124AEA3279A41E74A06CBA70FB4A3864B3098307E8A
F3441226C636B338BAB6E80E39DC82B82310E16D9BDD2F4AB7CD53C0A3D2B6B60
422036CDF6FDB7C0944FC4C9B9480C769DB2355688EB440A4DEB62B1CE65EA992
1B6581482866603AD9386D81097844DBCCCA3B550D5AB0AA63FEF88E2AD609443
0C44E8089ED1CD2A537AAE6A024E863DFB88B5DA367FF4F92B420ACE998DA2B22
5B75FADD0CDF827ECDC0C8BA891DFD999E6C8D6FC1C249194FB52F7ACA9BB6046
176348CB39798CAFB3FBADD825FFF0722DD6CB6973C8E8356FC119876613E1D93
BB795C946B74871C0D82DEA88EE135135B9755DA51C316F0711BDD3031775042E
1E58356D5B1051CFE2B8205F806770EAF93F6C525FA0000000049454E44AE4260
8200";
r["进入"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100028401000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000011949444154
484BB5954B0AC2301086BD9E3771E3C643780B578AA2A0541405A122EE558A4F7
C811B372E4410DF1219496B8393F4B7EA0759740AF36566DA2422FE8C2248778E
62B5BDCB2795F6F2F25C9FE209287934B513B1D29E95D03B5AD9DE494630940A9
2CD835692E99E3C49C139CB68306F334025C53E56093B6454620D832B6105042A
A98ECD83D70A0854529FE8254601814A1A53BE5D8102C224713F6F5AF6FCBD124
840A095B416AA041610AE245EDECBC80BBFC4595F6534A42051310B669B9B8CFE
A845FE39846A11DA7F7B1662C8E8CE1B53FE5F300AD0E4B589FEC8D00AD0B6544
6FCCE5D58019ADC1A8438ECD0E4C53E762728023479DEC16F354F805E99B96FAE
4C9270C909FA527427A60976C8BF43880799B976B3940BD8ED0000000049454E4
4AE42608200";
r["跳出"]:= "0502000000060400000074797065000203000000696D670006040000006461746
10002ED01000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000018249444154
484BCD933B4BC3601486FD0F3A3938D841872E0A0AD2C1C141271727577111A48
30E855625A09680507410844E2E2A88508428B45EF082850A2254F1822288E0CF
3872EC39C9C9E5FB92140B3EF041F39E93F7214DDB062DE67F09CCF513D8DEADD
15534220BA66677A0BD3BFB7BF2850AA5E14412C8723E86794C533DA102598E9F
E5F5C28A455B6AB4026F3923F38C714869304A81AA9C91F3B95C89523F8182B07
246EEA5330794BAF109A29633727F667E9F520797206E3923EF9B4EEF51DAC016
E09F48575EB2EA901ADD80B1892D7878FAA6D4414A16F347940A01FEAE75E57C3
39EC19102DCD7BF68EAC092CDE215258A972CF196F3E91F5E83DBBB4FDA52A315
78CBF15A66C92113AAB50FDA0E4629082A67E4AC6760152E6FDE68E22750A02B6
7E44EA26F194E2F5E69E2C6278852CEC8DDAEA401E5B3679A38B80471CA19794F
67EF1258E5479A34B00595F397D8E58C947424B2705D7DA789108C4F169B2A67A
404BB185B80561CE093340B7E3DB21CF1BDE4BFA6C502801FF275D8DB8771B6A3
0000000049454E44AE42608200";
{r["单步"] := "0502000000060400000074797065000203000000696D670006040000006461746
100025701000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000EC49444154
484BC5D5CD09C240108661EBB003CBB0801460035E723087282A117F886024A0A
0276F962558893B616565844427BB331B832F783003DF83E46047B7DCFF819BBE
EB0B5CF19B3C2B60C6FB2AD0DD474F0F21C2A7B26A81F2F8FBE383587F41561C2
B800FE27C079B62DF087102A604B6DE080B304D60E985B0015304733122024C21
8C45881830E5707A8D72102FE073FC05A81F01D478A862BC7E2702A8F111CCF04
AC706A8F1181678AD8F0550E35358E3D59E13A0C61348F1EACE0A50E32BC8F0CA
CB0A046A50194F21C70B3F2B50FE4FD8C1019FCA72BE0383E4C519BFC973024D6
B19D0FA0973865C3E24DD42ED0000000049454E44AE42608200";}
r["下一行(F8)"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100025E01000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000000F349444154
484BED93CD0A015118865D835BB0B37509EEC2CE6DB8105694B29C859548766E4
0ACFC6450148A1AA349C3A7777E0E66CE9C9F290BE5A96F31DF999EA74E9D0C7D
997F400A0B5C6E77AA8D4E3458DBC1261D8EFBA0C6E44CFBABEB7DB340D1D850B
63AF3A6DCDB055B3DDA738BF2CD25F3F457B61F30A6165B86A31B813CEA28B44C
3F303E3AB1438C6A8427C7943ADBD71541C6FB4916499263BA66704521BA11911
C67E0230054232A72100B005944550EB801208AF0F698A81C24068048161D9E1C
08034025922407D200D0BD96779402801791C9817200548607CAD517DE0B55910
3AD401AFE0129BF1E207A02B9FA383F9BCBB70F0000000049454E44AE42608200
";
r["终止"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100026602000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA864000001FB49444154
484BED94596B145114847DC8BEAF6423FBBE424296FFFF3F444386CC609C314EA
2AD498629EBEBE92B361C8982C197141C98BEC3AD3A5DA74EBFD10BE355E059FC
1F81F6D999F46B9D9E4AC7C7D2D191B4BFAF2757B6B7A7A6ABE1AAF9B9727050D
C2E237E03482F2E3A757EDE793E39E908ECEE4A9B9B7A747DDDD8D0EDD6966EB6
B755D9D9292E97F16702E90D0E0F2593696D4DAD951565CBCB6AAEAEEAA39FABE
BEBC5E5327E2F007122A77BC8E91EA2A525696E4EDFE7E775B7B0A0FAE2A2AA16
8B100B409ABC4FD6D86BAC913B9789DB53537A74DDCDCCA8313BABAACF22C402D
80171B205727B9D93BB6399B83D36A607D7FDF8B81A9393AA4D4F1797CB8805E8
984AB6D0B9BDCEC9211A1D556B6848DF5CF7C3C3AA8F8CA83631515C2E231670E
C7262068AE7A9F3825CFDFD7AEAEB53D6DBABE6C080EA16AA5A24422840CEF3AE
9D8E7CA0F86B5B1279CBE40F3D3DFAD2DDAD4F16B9B1C8F5DF08B044E49C28921
6068AE7D842E790675D5DFA6C8186AB66D18AFF8B100AB0A12C1139278AA48581
E27966323A4FE41FFC06D73EBB1A1C2C6E97110AB0FE6C284B44CE89226961A07
88E2D3FC95D573E7BEFFF2284027C5B587F36942522E74491B430503CC796BC73
FFBEF4D93BE6132014E0C3C5B785F567435922724E14490B03C5F34B774DE790B
F75031142817F89578167F1C202D20F98CF9591BE2EF7850000000049454E44AE
42608200";
r["刷新符号表"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100027702000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000020C49444154
484BC596DD4B145118C6FBEBBA13C12B6FBAE8224C414A08BA116BD584C050171
752D02093B6442D2F84CA34B520D35CBFC036493445CAAC50776D5D9DF771DEF3
313B677766F6EBA21F3C3767E73CCF9CF39EF3CE5E42996CEF03D7C2845B7DA44
64C0203D2E7C0EE0110FB068C2F1086DE1396364DA3CE1784CB8D96D0444C0DBA
F00D189F275C699713BD74B5C342FB70C69C551B21A4D2E60BE404ECFC025A9E9
A138BD1E05440006F49436FE9E6ACAA7B16BEDB75D118010F46CB33D7EAB0EBA2
71020626A5F9F56E0B8FDF5A58DF31977A74024C2E93D8F7EAFBDEC66E2D6CC87
94E4043AF4C3E4CAA81003E7E81A7A95BFC928C08F89B80335008AD51FFADAC6A
B5C4EF7C3F181130B3666E473EF8526943DEAEBB8384E88CBC23E933F590C2287
2A1FCF80361B6F75B0D0450524031FCFF80AD9F843731C2A7787175D2E40424FE
01EF5608E131428D7D277431FDBAA51FF35FE5F34E001FD31B3D19C36CF5BF2E2
CE0E4541E63DD2E44009B7B99BAB5B6259E0F64D16EEBF50F65173E55C755046C
EC0115216F63AD8A10A1E909E1F92C612E2E8FA9D6C807C2ED4799BBF1EA7366B
5CE16E95E54AEBA5E9A1DC10948A581BA88F7A44275C75E61364E0033B592BF89
F9697A5599646104306DCFCC89BCE49B76A7AD6C36C759B5F631E60E1CDF55933
DC80970173CBBC31EDBDF84ED7D59D8644A0DE62127806163FE2BA25B6EE90017
13C9EE8D2E4822C60000000049454E44AE42608200";
r["刷新当前符号"]:= "0502000000060400000074797065000203000000696D670006040000006461746
100027802000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000020D49444154
484BB594DD2BA74114C7F7EF70A914529262BD5C798B645F5A2552EE5C4872837
2B1524A6D5C59C566A98D52ECC55228B4ED850B3724424A5A89B8D9B597CFBC1C
7D4F679EE691C76EC37E6AFACD3933BFF93E73E63BF382FE3309815DBB4F8BF61
B4DE8695AB7DF25FB34628151F39132A29C442B5655321A0E0B1CDAE378D1CF66
96CEE827B5EA768E87F4084F0C8505E6CC022F76BF2CF9513995A81A89C260812
F669E05F0E53E9DBA87B2A32289C260814B7BC502288B0F726DBA43A230E243C6
D7624194A5570F701FED5FDC8439701E1C0827FAC402E0AB59A6DCE8252FDCAEB
B69D9ACC9483A709AFB18D7E04847420038BBD6AA46C9A40387612E4A8BF38303
9D089C095205D046F498641F060E43497D502EFC17CE04A9020366987FDFA936D
AB17B329A24332AE0B3F3C14EF03F9C09481500AB6683AAD55B8E1B54330DEA0F
B465B669D12CD1A499A14AF5269EEB7017D499E35101704B7F68CC7CA20AF59AF
37E2B53B5BC0BF4E13C940B7DFF89F9AB800FC40EEC119DD853C910EFE8956AA1
2C55C86772FF694908F836456D7FD16F1909271670170D027E7FD3FC901961B0C
0B9BDE005BB741F271DC8F5E8F71285C102D37241AEE986930E1C5C5E542A5118
2C80370402B8893E285179542751182C80070A0268F02F76827221EED6FD3C319
4F890FD27C2B57AD524A3E1C402000F14DE907133452B765DB24F2321F0FC10DD
0144332BF870524ED00000000049454E44AE42608200";
return r;
end
function ejsonformat(d,tbw,ct);
begin
//d:天软数据
//tbw : 字符串,tab 宽度
//ct 递归深度,忽略
case datatype(d)of
0,20:return inttostr(d);
1:return floattostr(d);
2:return tostn(d);
8,10,11,12:return "null";
end;
if not(ct>0)then ct := 0;
if not ifstring(tbw)then tbw := " ";
tbstr := "";
tbstra := "";
for i := 0 to ct do
begin
tbstr += tbw;
if i>0 then tbstra += tbw
end
if ifarray(d)then
begin
if not d then return "[]";
idx := 0;
for i,v in d do
begin
if idx <> i then
begin
fobj := true;
break;
end
idx++;
end
if fobj then
begin
r := "{";
for i,v in d do
begin
if ifstring(i)then ii := tostn(i);
else ii := tostn(tostn(i));
r += "\r\n"+tbstr+ii+":";
if ifarray(v)and v then
begin
r += "\r\n"+tbstr;
end
r += ejsonformat(v,tbw,ct+1)+",";
end
lr := length(r);
r[lr:]:= "\r\n"+tbstra+"}";
end else
begin
r := "[";
for i,v in d do
begin
r += "\r\n"+(tbstr)+ejsonformat(v,tbw,ct+1)+",";
end
lr := length(r);
r[lr:]:= "\r\n"+tbstra+"]";
end
return r;
end else
if ifobj(d)then
begin
try
//return "{}";
//此处可以遍历对象信息
objtoarray(d,dinfo);
for i,v in mrows(dinfo,1) do
begin
nv := invoke(d,v);
if ifobj(nv)then nv := nil; //避免死循环
dinfo[v]:= nv;
end
return ejsonformat(dinfo,tbw,ct);
except
return "{}";
end
end else
return "null";
end
function objtoarray(o,r);
begin
d := o.classinfo();
if not ifarray(r)then r := array();
for i,v in d["inherited"] do
begin
objtoarray(findclass(v,o),r);
end
for i,v in d["members"] do
begin
n := v["name"];
if v["access"]in array(0,1)then
begin
r[n]:= 0;
end else
begin
reindex(r,array(n:nil));
end
end
for i,v in d["properties"] do
begin
n := v["name"];
if v["read"]and(v["access"]in array(0,1))then
begin
r[n]:= 0;
end else
begin
reindex(r,array(n:nil));
end
end
end
function ReWriteString(fn,d);
begin
if not ifstring(d)then return 0;
als := "";
len := length(d);
if FileExists(als,fn)and(filesize(als,fn)>len)then
begin
lfn := FileList(als,fn); //修正文件名变小写的问题
if lfn then
begin
nfn := lfn[0,"FileName"];
if nfn then
begin
for i := length(fn)downto 1 do
begin
if fn[i]="\\" then
begin
fn := fn[1:i]+nfn;
break;
end
end
end
end
FileDelete(als,fn);
end else
begin
CreateDirWithFileName(fn);
end
spos := 0;
return writefile(rwraw(),als,fn,spos,len,d);
end
function gettslexe();
begin
return static gettslexefullpath();
end
function gettslexefullpath();
begin
plg := pluginpath();
sp := ioFileseparator();
for i:= length(plg)-1 downto 1 do
begin
if plg[i]=sp then
begin
if sp="/" then
begin
return plg[1:i]+"TSL";
end else
begin
return plg[1:i]+"tsl.exe";
end
end
end
return "";
end
{$ifdef linux}
function HtmlHelpA()
begin
return 0;
end
function GetDesktopWindow()
begin
return 0;
end
{$else}
function HtmlHelpA(hwndCaller:pointer;pszFile:string;uCommand:integer;dwData:pointer):pointer;stdcall;external "HHCTRL.OCX" name "HtmlHelpA";
function GetDesktopWindow():pointer;stdcall;external "User32.dll" name "GetDesktopWindow";
{$endif}
end.