fpc/ide/fptools.pas
pierre 209acc0251 * Reset AbortTool before each run
git-svn-id: trunk@14063 -
2009-11-05 00:45:19 +00:00

1666 lines
45 KiB
ObjectPascal

{
This file is part of the Free Pascal Integrated Development Environment
Copyright (c) 1998 by Berczi Gabor
Tool support for the IDE
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{$I globdir.inc}
unit FPTools;
interface
uses Objects,Drivers,Views,Dialogs,Validate,
BrowCol,
WEditor,WViews,
FPViews;
const
MsgFilterSign = 'BI#PIP#OK'#0;
type
TCaptureTarget = (capNone,capMessageWindow,capEditWindow,capNoSwap);
PTool = ^TTool;
TTool = object(TObject)
constructor Init(const ATitle, AProgramPath, ACommandLine: string; AHotKey: word);
function GetTitle: string; virtual;
procedure GetParams(var ATitle, AProgramPath, ACommandLine: string; var AHotKey: word); virtual;
procedure SetParams(const ATitle, AProgramPath, ACommandLine: string; const AHotKey: word); virtual;
destructor Done; virtual;
private
Title : PString;
ProgramPath : PString;
CommandLine : PString;
HotKey : word;
end;
PToolCollection = ^TToolCollection;
TToolCollection = object(TCollection)
function At(Index: sw_Integer): PTool;
end;
PToolListBox = ^TToolListBox;
TToolListBox = object(TAdvancedListBox)
function GetText(Item,MaxLen: Sw_Integer): String; virtual;
end;
PToolParamValidator = ^TToolParamValidator;
TToolParamValidator = object(TValidator)
function IsValid(const S: string): Boolean; virtual;
procedure Error; virtual;
private
ErrorPos: integer;
end;
PToolItemDialog = ^TToolItemDialog;
TToolItemDialog = object(TCenterDialog)
constructor Init(ATool: PTool);
function Execute: Word; virtual;
private
Tool : PTool;
TitleIL : PEditorInputLine;
ProgramIL: PEditorInputLine;
ParamIL : PEditorInputLine;
HotKeyRB : PRadioButtons;
end;
PToolsDialog = ^TToolsDialog;
TToolsDialog = object(TCenterDialog)
constructor Init;
function Execute: Word; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
private
ToolsLB : PToolListBox;
procedure Add;
procedure Edit;
procedure Delete;
end;
PToolMessage = ^TToolMessage;
TToolMessage = object(TMessageItem)
constructor Init(AModule: PString; ALine: string; ARow, ACol: sw_integer);
function GetText(MaxLen: Sw_integer): string; virtual;
end;
PToolMessageListBox = ^TToolMessageListBox;
TToolMessageListBox = object(TMessageListBox)
procedure NewList(AList: PCollection); virtual;
procedure Clear; virtual;
procedure Update; virtual;
function GetPalette: PPalette; virtual;
constructor Load(var S: TStream);
procedure Store(var S: TStream);
destructor Done; virtual;
end;
PMessagesWindow = ^TMessagesWindow;
TMessagesWindow = object(TFPWindow)
constructor Init;
procedure Update; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
function GetPalette: PPalette; virtual;
constructor Load(var S: TStream);
procedure Store(var S: TStream);
destructor Done; virtual;
procedure FocusItem(i : sw_integer);
procedure SizeLimits(var Min, Max: TPoint); virtual;
private
MsgLB : PToolMessageListBox;
end;
procedure InitTools;
function GetToolCount: sw_integer;
function GetToolName(Idx: sw_integer): string;
function AddTool(Title, ProgramPath, Params: string; HotKey: word): sw_integer;
procedure GetToolParams(Idx: sw_integer; var Title, ProgramPath, Params: string; var HotKey: word);
procedure SetToolParams(Idx: sw_integer; Title, ProgramPath, Params: string; HotKey: word);
procedure DoneTools;
function GetHotKeyName(Key: word): string;
function ParseToolParams(var Params: string; CheckOnly: boolean): integer;
procedure InitToolProcessing;
function ProcessMessageFile(const MsgFileName: string): boolean;
procedure AddToolCommand(Command: string);
procedure AddToolMessage(ModuleName, Text: string; Row, Col: longint);
procedure ClearToolMessages;
procedure DoneToolMessages;
procedure UpdateToolMessages;
procedure InitToolTempFiles;
procedure DoneToolTempFiles;
const
ToolFilter : string[128] = '';
ToolOutput : string[128] = '';
CaptureToolTo : TCaptureTarget = capNone;
ToolMessages : PCollection = nil;
ToolModuleNames: PStoreCollection = nil;
MessagesWindow : PMessagesWindow = nil;
LastToolMessageFocused : PToolMessage = nil;
LongestTool : sw_integer = 0;
procedure RegisterFPTools;
{$ifdef DEBUG}
Procedure FpToolsDebugMessage(AFileName, AText : string; ALine, APos : string;nrline,nrpos:sw_word);
{$endif DEBUG}
implementation
uses Dos,
FVConsts,
App,MsgBox,
WConsts,WUtils,WINI,
FPConst,FPVars,FPUtils;
{$ifndef NOOBJREG}
const
RToolMessageListBox: TStreamRec = (
ObjType: 1600;
VmtLink: Ofs(TypeOf(TToolMessageListBox)^);
Load: @TToolMessageListBox.Load;
Store: @TToolMessageListBox.Store
);
RMessagesWindow: TStreamRec = (
ObjType: 1601;
VmtLink: Ofs(TypeOf(TMessagesWindow)^);
Load: @TMessagesWindow.Load;
Store: @TMessagesWindow.Store
);
{$endif}
{$ifdef useresstrings}
resourcestring
{$else}
const
{$endif}
dialog_tools = 'Tools';
dialog_modifynewtool = 'Modify/New Tool';
dialog_programarguments = 'Program Arguments';
dialog_messages = 'Messages';
msg_errorparsingparametersatpos = ^C'Error parsing parameters line at line position %d.';
msg_cantinstallmoretools = ^C'Can''t install more tools...';
msg_requiredparametermissingin = 'Required parameter missing in [%s]';
msg_requiredpropertymissingin = 'Required property missing in [%s]';
msg_unknowntypein = 'Unknown type in [%s]';
msg_propertymissingin = '%s property missing in [%s]';
msg_invaliditemsin = 'Invalid number of items in [%s]';
label_tools_programtitles = '~P~rogram titles';
label_toolprop_title = '~T~itle';
label_toolprop_programpath = 'Program ~p~ath';
label_toolprop_commandline = 'Command ~l~ine';
label_enterprogramargument = '~E~nter program argument';
{ standard button texts }
button_OK = 'O~K~';
button_Cancel = 'Cancel';
button_New = '~N~ew';
button_Edit = '~E~dit';
button_Delete = '~D~elete';
type
THotKeyDef = record
Name : string[12];
KeyCode : word;
end;
const
HotKeys : array[0..11] of THotKeyDef =
( (Name : '~U~nassigned' ; KeyCode : kbNoKey ),
(Name : 'Shift+F~2~' ; KeyCode : kbShiftF2 ),
(Name : 'Shift+F~3~' ; KeyCode : kbShiftF3 ),
(Name : 'Shift+F~4~' ; KeyCode : kbShiftF4 ),
(Name : 'Shift+F~5~' ; KeyCode : kbShiftF5 ),
(Name : 'Shift+F~6~' ; KeyCode : kbShiftF6 ),
(Name : 'Shift+F~7~' ; KeyCode : kbShiftF7 ),
(Name : 'Shift+F~8~' ; KeyCode : kbShiftF8 ),
(Name : 'Shift+F~9~' ; KeyCode : kbShiftF9 ),
(Name : 'Shift+F1~0~' ; KeyCode : kbShiftF10),
(Name : 'Shift+F1~1~' ; KeyCode : kbShiftF11),
(Name : 'Shift+~F~12' ; KeyCode : kbShiftF12));
Tools : PToolCollection = nil;
AbortTool : boolean = false;
ToolTempFiles: PUnsortedStringCollection = nil;
function GetHotKeyCount: integer;
begin
GetHotKeyCount:=ord(High(HotKeys))-ord(Low(HotKeys))+1;
end;
function GetHotKeyNameByIdx(Idx: integer): string;
begin
GetHotKeyNameByIdx:=HotKeys[Idx].Name;
end;
function HotKeyToIdx(Key: word): integer;
var Count,I: integer;
Found: boolean;
begin
Count:=GetHotKeyCount; Found:=false;
I:=0;
while (I<Count) and (Found=false) do
begin
Found:=HotKeys[I].KeyCode=Key;
if Found=false then
Inc(I);
end;
if Found=false then I:=-1;
HotKeyToIdx:=I;
end;
function IdxToHotKey(Idx: integer): word;
var Count: integer;
Key: word;
begin
Count:=GetHotKeyCount;
if (0<=Idx) and (Idx<Count) then
Key:=HotKeys[Idx].KeyCode
else
Key:=kbNoKey;
IdxToHotKey:=Key;
end;
function GetHotKeyName(Key: word): string;
var Idx: integer;
S: string;
begin
Idx:=HotKeyToIdx(Key);
if Idx=0 then S:='' else
if Idx=-1 then S:='???' else
S:=GetHotKeyNameByIdx(Idx);
GetHotKeyName:=S;
end;
function WriteToolMessagesToFile(FileName: string): boolean;
var OK: boolean;
f: text;
M: PToolMessage;
I: sw_integer;
begin
I:=0;
Assign(f,FileName);
{$I-}
Rewrite(f);
OK:=EatIO=0;
if Assigned(ToolMessages) then
while OK and (I<ToolMessages^.Count) do
begin
M:=ToolMessages^.At(I);
writeln(f,GetStr(M^.Module)+#0+GetStr(M^.Text)+#0+IntToStr(M^.Row)+#0+IntToStr(M^.Col));
Inc(I);
OK:=EatIO=0;
end;
Close(f);
EatIO;
{$I+}
WriteToolMessagesToFile:=OK;
end;
constructor TTool.Init(const ATitle, AProgramPath, ACommandLine: string; AHotKey: word);
begin
inherited Init;
SetParams(ATitle,AProgramPath,ACommandLine,AHotKey);
end;
function TTool.GetTitle: string;
begin
GetTitle:=KillTilde(GetStr(Title));
end;
procedure TTool.GetParams(var ATitle, AProgramPath, ACommandLine: string; var AHotKey: word);
begin
ATitle:=GetStr(Title); AProgramPath:=GetStr(ProgramPath);
ACommandLine:=GetStr(CommandLine);
AHotKey:=HotKey;
end;
procedure TTool.SetParams(const ATitle, AProgramPath, ACommandLine: string; const AHotKey: word);
begin
if Title<>nil then DisposeStr(Title); Title:=nil;
if ProgramPath<>nil then DisposeStr(ProgramPath); ProgramPath:=nil;
if CommandLine<>nil then DisposeStr(CommandLine); CommandLine:=nil;
Title:=NewStr(ATitle); ProgramPath:=NewStr(AProgramPath);
CommandLine:=NewStr(ACommandLine);
HotKey:=AHotKey;
end;
destructor TTool.Done;
begin
inherited Done;
if Title<>nil then DisposeStr(Title);
if ProgramPath<>nil then DisposeStr(ProgramPath);
if CommandLine<>nil then DisposeStr(CommandLine);
end;
function TToolCollection.At(Index: sw_Integer): PTool;
begin
At:=inherited At(Index);
end;
function TToolListBox.GetText(Item,MaxLen: sw_integer): String;
var S: string;
P: PTool;
begin
P:=List^.At(Item);
S:=P^.GetTitle;
GetText:=copy(S,1,MaxLen);
end;
procedure InitTools;
begin
if Tools<>nil then DoneTools;
New(Tools, Init(10,20));
end;
function GetToolCount: sw_integer;
var Count: integer;
begin
if Tools=nil then Count:=0 else
Count:=Tools^.Count;
GetToolCount:=Count;
end;
function GetToolName(Idx: sw_integer): string;
var S1,S2: string;
W: word;
begin
GetToolParams(Idx,S1,S2,S2,W);
GetToolName:=KillTilde(S1);
end;
function AddTool(Title, ProgramPath, Params: string; HotKey: word): sw_integer;
var P: PTool;
begin
if Tools=nil then InitTools;
New(P, Init(Title,ProgramPath,Params,HotKey));
Tools^.Insert(P);
AddTool:=Tools^.IndexOf(P);
end;
procedure GetToolParams(Idx: sw_integer; var Title, ProgramPath, Params: string; var HotKey: word);
var P: PTool;
begin
P:=Tools^.At(Idx);
P^.GetParams(Title,ProgramPath,Params,HotKey);
end;
procedure SetToolParams(Idx: sw_integer; Title, ProgramPath, Params: string; HotKey: word);
var P: PTool;
begin
P:=Tools^.At(Idx);
P^.GetParams(Title,ProgramPath,Params,HotKey);
end;
procedure DoneTools;
begin
if Tools<>nil then Dispose(Tools, Done); Tools:=nil;
end;
procedure TToolParamValidator.Error;
begin
MsgParms[1].Long:=ErrorPos;
ErrorBox(msg_errorparsingparametersatpos,@MsgParms);
end;
function TToolParamValidator.IsValid(const S: string): Boolean;
var P: string;
begin
P:=S;
ErrorPos:=ParseToolParams(P,true);
IsValid:=ErrorPos=0;
end;
constructor TToolItemDialog.Init(ATool: PTool);
var R,R2,R3: TRect;
Items: PSItem;
I,KeyCount: sw_integer;
begin
KeyCount:=GetHotKeyCount;
R.Assign(0,0,60,Max(3+KeyCount,12));
inherited Init(R,dialog_modifynewtool);
Tool:=ATool;
GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
New(TitleIL, Init(R, 128)); Insert(TitleIL);
R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_toolprop_title, TitleIL)));
R.Move(0,3);
New(ProgramIL, Init(R, 128)); Insert(ProgramIL);
R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_toolprop_programpath, ProgramIL)));
R.Move(0,3);
New(ParamIL, Init(R, 128)); Insert(ParamIL);
ParamIL^.SetValidator(New(PToolParamValidator, Init));
R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_toolprop_commandline, ParamIL)));
R.Copy(R3); Inc(R.A.X,38); R.B.Y:=R.A.Y+KeyCount;
Items:=nil;
for I:=KeyCount-1 downto 0 do
Items:=NewSItem(GetHotKeyNameByIdx(I), Items);
New(HotKeyRB, Init(R, Items));
Insert(HotKeyRB);
InsertButtons(@Self);
TitleIL^.Select;
end;
function TToolItemDialog.Execute: Word;
var R: word;
S1,S2,S3: string;
W: word;
L: longint;
begin
Tool^.GetParams(S1,S2,S3,W);
TitleIL^.SetData(S1); ProgramIL^.SetData(S2); ParamIL^.SetData(S3);
L:=HotKeyToIdx(W); if L=-1 then L:=255;
HotKeyRB^.SetData(L);
R:=inherited Execute;
if R=cmOK then
begin
TitleIL^.GetData(S1); ProgramIL^.GetData(S2); ParamIL^.GetData(S3);
HotKeyRB^.GetData(L); W:=IdxToHotKey(L);
Tool^.SetParams(S1,S2,S3,W);
end;
Execute:=R;
end;
constructor TToolsDialog.Init;
var R,R2,R3: TRect;
SB: PScrollBar;
begin
R.Assign(0,0,46,16);
inherited Init(R,dialog_tools);
HelpCtx:=hcTools;
GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R3.Copy(R); Dec(R.B.X,12);
R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
New(SB, Init(R2)); Insert(SB);
New(ToolsLB, Init(R,1,SB));
Insert(ToolsLB);
R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
Insert(New(PLabel, Init(R2, label_tools_programtitles, ToolsLB)));
R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
Insert(New(PButton, Init(R, button_OK, cmOK, bfNormal)));
R.Move(0,2);
Insert(New(PButton, Init(R, button_Edit, cmEditItem, bfDefault)));
R.Move(0,2);
Insert(New(PButton, Init(R, button_New, cmAddItem, bfNormal)));
R.Move(0,2);
Insert(New(PButton, Init(R, button_Delete, cmDeleteItem, bfNormal)));
R.Move(0,2);
Insert(New(PButton, Init(R, button_Cancel, cmCancel, bfNormal)));
SelectNext(false);
end;
procedure TToolsDialog.HandleEvent(var Event: TEvent);
var DontClear: boolean;
begin
case Event.What of
evKeyDown :
begin
DontClear:=false;
case Event.KeyCode of
kbIns :
Message(@Self,evCommand,cmAddItem,nil);
kbDel :
Message(@Self,evCommand,cmDeleteItem,nil);
else DontClear:=true;
end;
if DontClear=false then ClearEvent(Event);
end;
evBroadcast :
case Event.Command of
cmListItemSelected :
if Event.InfoPtr=pointer(ToolsLB) then
Message(@Self,evCommand,cmEditItem,nil);
end;
evCommand :
begin
DontClear:=false;
case Event.Command of
cmAddItem : Add;
cmDeleteItem : Delete;
cmEditItem : Edit;
else DontClear:=true;
end;
if DontClear=false then ClearEvent(Event);
end;
end;
inherited HandleEvent(Event);
end;
function TToolsDialog.Execute: Word;
var R: word;
C: PToolCollection;
I: integer;
S1,S2,S3: string;
W: word;
begin
New(C, Init(10,20));
if Tools<>nil then
for I:=0 to Tools^.Count-1 do
begin
Tools^.At(I)^.GetParams(S1,S2,S3,W);
C^.Insert(New(PTool, Init(S1,S2,S3,W)));
end;
ToolsLB^.NewList(C);
R:=inherited Execute;
if R=cmOK then
begin
if Tools<>nil then Dispose(Tools, Done);
Tools:=C;
Message(Application,evBroadcast,cmUpdateTools,nil);
end
else
Dispose(C, Done);
Execute:=R;
end;
procedure TToolsDialog.Add;
var P: PTool;
IC: boolean;
S1,S2,S3: string;
W: word;
begin
if ToolsLB^.Range>=MaxToolCount then
begin InformationBox(msg_cantinstallmoretools,nil); Exit; end;
IC:=ToolsLB^.Range=0;
if IC=false then
begin
P:=ToolsLB^.List^.At(ToolsLB^.Focused);
P^.GetParams(S1,S2,S3,W);
end
else
begin
S1:=''; S2:=''; S3:=''; W:=0;
end;
New(P, Init(S1,S2,S3,W));
if Application^.ExecuteDialog(New(PToolItemDialog, Init(P)), nil)=cmOK then
begin
ToolsLB^.List^.Insert(P);
ToolsLB^.SetRange(ToolsLB^.List^.Count);
ReDraw;
end
else
Dispose(P, Done);
end;
procedure TToolsDialog.Edit;
var P: PTool;
begin
if ToolsLB^.Range=0 then Exit;
P:=ToolsLB^.List^.At(ToolsLB^.Focused);
Application^.ExecuteDialog(New(PToolItemDialog, Init(P)), nil);
ReDraw;
end;
procedure TToolsDialog.Delete;
begin
if ToolsLB^.Range=0 then Exit;
ToolsLB^.List^.AtFree(ToolsLB^.Focused);
ToolsLB^.SetRange(ToolsLB^.List^.Count);
ReDraw;
end;
(*procedure ReplaceStr(var S: string; const What,NewS: string);
var I : integer;
begin
repeat
I:=Pos(What,S);
if I>0 then
begin
Delete(S,I,length(What));
Insert(NewS,S,I);
end;
until I=0;
end;
procedure ReplaceStrI(var S: string; What: string; const NewS: string);
var I : integer;
UpcaseS: string;
begin
UpcaseS:=UpcaseStr(S); What:=UpcaseStr(What);
repeat
I:=Pos(What,UpcaseS);
if I>0 then
begin
Delete(S,I,length(What));
Insert(NewS,S,I);
end;
until I=0;
end;*)
function GetCoordEntry(F: PINIFile; Section, Entry: string; var P: TPoint): boolean;
var OK: boolean;
S: string;
Px: integer;
begin
S:=F^.GetEntry(Section,Entry,'');
S:=Trim(S);
OK:=(S<>'') and (S[1]='(') and (S[length(S)]=')');
if OK then S:=copy(S,2,length(S)-2);
Px:=Pos(',',S);
OK:=OK and (Px>0);
if OK then P.X:=StrToInt(copy(S,1,Px-1));
OK:=OK and (LastStrToIntResult=0);
if OK then P.Y:=StrToInt(copy(S,Px+1,High(S)));
OK:=OK and (LastStrToIntResult=0);
GetCoordEntry:=OK;
end;
function ExecutePromptDialog(const FileName: string; var Params: string): boolean;
const
MaxViews = 20;
MaxViewNameLen = 40;
MaxValueLen = 80;
secMain = 'MAIN';
{ Main section entries }
tmeTitle = 'TITLE';
tmeCommandLine = 'COMMANDLINE';
tmeSize = 'SIZE';
tmeDefaultView = 'DEFAULT';
{ View section entries }
tieType = 'TYPE';
tieOrigin = 'ORIGIN';
tieSize = 'SIZE';
{*} tieDefault = 'DEFAULT';
tieValue = 'VALUE';
{ Additional CheckBox view section entries }
tieName = 'NAME';
tieOnParm = 'ON';
tieOffParm = 'OFF';
{ Additional CheckBox view section entries }
tieItem = 'ITEM';
tieParam = 'PARAM';
{ Additional InputLine view section entries }
tieMaxLen = 'MAXLEN';
{ Additional Label view section entries }
tieLink = 'LINK';
tieText = 'TEXT';
{ Additional Memo view section entries }
tieFileName = 'FILENAME';
{ View types }
vtCheckBox = 1;
vtRadioButton = 2;
vtInputLine = 3;
vtMemo = 4;
vtLabel = 127;
vtsCheckBox = 'CHECKBOX';
vtsRadioButton = 'RADIOBUTTON';
vtsInputLine = 'INPUTLINE';
vtsLabel = 'LABEL';
vtsMemo = 'MEMO';
var Title : string;
DSize : TPoint;
CmdLine : string;
ViewCount : Sw_integer;
ViewNames : array[0..MaxViews-1] of string[MaxViewNameLen];
ViewTypes : array[0..MaxViews-1] of byte;
ViewBounds : array[0..MaxViews-1] of TRect;
ViewPtrs : array[0..MaxViews-1] of PView;
ViewValues : array[0..MaxViews-1] of string[MaxValueLen];
ViewItemCount: array[0..MaxViews-1] of sw_integer;
function BuildPromptDialogInfo(F: PINIFile): boolean;
var
OK: boolean;
_IS: PINISection;
procedure ProcessSection(Sec: PINISection);
var P1,P2: TPoint;
Typ: string;
Count: sw_integer;
begin
if (OK=false) or
( (UpcaseStr(Sec^.GetName)=secMain) or
(UpcaseStr(Sec^.GetName)=UpcaseStr(MainSectionName)) ) then
Exit;
ViewItemCount[ViewCount]:=0;
OK:=(Sec^.SearchEntry(tieType)<>nil) and
(Sec^.SearchEntry(tieOrigin)<>nil) and
(Sec^.SearchEntry(tieSize)<>nil);
if OK=false then
begin ErrorBox(FormatStrStr(msg_requiredparametermissingin,Sec^.GetName),nil); Exit; end;
Typ:=UpcaseStr(Trim(F^.GetEntry(Sec^.GetName,tieType,'')));
if Typ=vtsCheckBox then ViewTypes[ViewCount]:=vtCheckBox else
if Typ=vtsRadioButton then ViewTypes[ViewCount]:=vtRadioButton else
if Typ=vtsInputLine then ViewTypes[ViewCount]:=vtInputLine else
if Typ=vtsLabel then ViewTypes[ViewCount]:=vtLabel else
if Typ=vtsMemo then ViewTypes[ViewCount]:=vtMemo else
begin OK:=false; ErrorBox(FormatStrStr(msg_unknowntypein,Sec^.GetName),nil); Exit; end;
ViewNames[ViewCount]:=Sec^.GetName;
GetCoordEntry(F,Sec^.GetName,tieOrigin,P1);
GetCoordEntry(F,Sec^.GetName,tieSize,P2);
ViewBounds[ViewCount].Assign(P1.X,P1.Y,P1.X+P2.X,P1.Y+P2.Y);
{ allow conversion of $EDNAME for instance in
default values PM }
Typ:=F^.GetEntry(Sec^.GetName,tieValue,'');
ParseToolParams(Typ,true);
ViewValues[ViewCount]:=Typ;
case ViewTypes[ViewCount] of
vtLabel :
begin
OK:=OK and (Sec^.SearchEntry(tieLink)<>nil) and
(Sec^.SearchEntry(tieText)<>nil);
if OK=false then
begin ErrorBox(FormatStrStr(msg_requiredpropertymissingin,Sec^.GetName),nil); Exit; end;
end;
vtInputLine : ;
vtMemo : ;
vtCheckBox :
begin
OK:=OK and (Sec^.SearchEntry(tieName)<>nil);
if Typ='' then
Typ:=tieOffParm;
if F^.GetEntry(Sec^.GetName,tieDefault,'')<>'' then
begin
Typ:=F^.GetEntry(Sec^.GetName,tieDefault,'');
end;
Typ:=UpcaseStr(Trim(Typ));
if Typ=tieOnParm then
Typ:='1'
else if Typ=tieOffParm then
Typ:='0'
else if (Typ<>'0') and (Typ<>'1') then
Ok:=false;
ViewValues[ViewCount]:=Typ;
if OK=false then
begin ErrorBox(FormatStrStr2(msg_propertymissingin,tieName,Sec^.GetName),nil); Exit; end;
end;
vtRadioButton:
begin
Count:=0;
while Sec^.SearchEntry(tieItem+IntToStr(Count+1))<>nil do
Inc(Count);
ViewItemCount[ViewCount]:=Count;
OK:=Count>0;
if OK=false then
begin ErrorBox(FormatStrStr(msg_invaliditemsin,Sec^.GetName),nil); Exit; end;
end;
end;
if OK then Inc(ViewCount);
end;
begin
BuildPromptDialogInfo:=false;
_IS:=F^.SearchSection(secMain);
OK:=_IS<>nil;
if OK then OK:=(_IS^.SearchEntry(tmeTitle)<>nil) and
(_IS^.SearchEntry(tmeSize)<>nil) and
(_IS^.SearchEntry(tmeCommandLine)<>nil);
if OK then
begin
Title:=F^.GetEntry(secMain,tmeTitle,'');
OK:=OK and GetCoordEntry(F,secMain,tmeSize,DSize);
CmdLine:=F^.GetEntry(secMain,tmeCommandLine,'');
OK:=OK and (CmdLine<>'');
end;
if OK=false then
begin ErrorBox(FormatStrStr(msg_requiredpropertymissingin,_IS^.GetName),nil); Exit; end;
if OK then
begin
ViewCount:=0;
F^.ForEachSection(@ProcessSection);
end;
BuildPromptDialogInfo:=OK;
end;
function SearchViewByName(Name: string): integer;
var I,Idx: Sw_integer;
begin
Idx:=-1; Name:=UpcaseStr(Name);
for I:=0 to ViewCount-1 do
if UpcaseStr(ViewNames[I])=Name then
begin
Idx:=I;
Break;
end;
SearchViewByName:=Idx;
end;
function GetParamValueStr(F: PINIFile; Idx: integer): string;
var S: string;
Entry: string[20];
begin
S:='???';
case ViewTypes[Idx] of
vtLabel :
S:='';
vtMemo :
begin
S:=F^.GetEntry(ViewNames[Idx],tieFileName,'');
if S='' then S:=GenTempFileName;
ToolTempFiles^.InsertStr(S);
if PFPMemo(ViewPtrs[Idx])^.SaveToFile(S)=false then
ErrorBox(FormatStrStr(msg_errorsavingfile,S),nil);
end;
vtInputLine :
S:=PInputLine(ViewPtrs[Idx])^.Data^;
vtCheckBox :
with PCheckBoxes(ViewPtrs[Idx])^ do
begin
if Mark(0) then Entry:=tieOnParm else Entry:=tieOffParm;
S:=F^.GetEntry(ViewNames[Idx],Entry,'');
end;
vtRadioButton :
with PRadioButtons(ViewPtrs[Idx])^ do
begin
Entry:=tieParam+IntToStr(Value+1);
S:=F^.GetEntry(ViewNames[Idx],Entry,'');
end;
end;
GetParamValueStr:=S;
end;
function ExtractPromptDialogParams(F: PINIFile; var Params: string): boolean;
function ReplacePart(StartP,EndP: integer; const S: string): integer;
begin
Params:=copy(Params,1,StartP-1)+S+copy(Params,EndP+1,255);
ReplacePart:=length(S)-(EndP-StartP+1);
end;
var OptName: string;
OK: boolean;
C: char;
OptStart: integer;
InOpt: boolean;
I,Idx: integer;
S: string;
begin
Params:=CmdLine;
I:=1; InOpt:=false; OK:=true;
while OK and (I<=length(Params)) do
begin
C:=Params[I];
if C='%' then
begin
InOpt:=not InOpt;
if InOpt then
begin
OptName:='';
OptStart:=I;
end
else
begin
OptName:=UpcaseStr(OptName);
Idx:=SearchViewByName(OptName);
OK:=Idx<>-1;
if OK then
begin
S:=GetParamValueStr(F,Idx);
if (S='') and (Params[I+1]=' ') then Inc(I);
I:=I+ReplacePart(OptStart,I,S);
end;
end;
end
else
if InOpt then
OptName:=OptName+C;
Inc(I);
end;
ExtractPromptDialogParams:=OK;
end;
function ExecPromptDialog(F: PINIFile): boolean;
var R: TRect;
PromptDialog: PCenterDialog;
Re: integer;
OK: boolean;
I,J,MaxLen: integer;
Memo: PFPMemo;
IL: PEditorInputLine;
CB: PCheckBoxes;
RB: PRadioButtons;
LV: PLabel;
SI: PSItem;
S: string;
P: PView;
begin
OK:=true;
R.Assign(0,0,DSize.X,DSize.Y);
New(PromptDialog, Init(R, Title));
with PromptDialog^ do
begin
for I:=0 to ViewCount-1 do
begin
case ViewTypes[I] of
vtLabel :
begin
S:=F^.GetEntry(ViewNames[I],tieLink,'');
J:=SearchViewByName(S);
if J=-1 then P:=nil else
P:=ViewPtrs[J];
S:=F^.GetEntry(ViewNames[I],tieText,'');
New(LV, Init(ViewBounds[I], S, P));
ViewPtrs[I]:=LV;
end;
vtInputLine :
begin
MaxLen:=F^.GetIntEntry(ViewNames[I],tieMaxLen,80);
New(IL, Init(ViewBounds[I], MaxLen));
IL^.Data^:=ViewValues[I];
ViewPtrs[I]:=IL;
end;
vtMemo :
begin
{ MaxLen:=F^.GetIntEntry(ViewNames[I],tieMaxLen,80);}
New(Memo, Init(ViewBounds[I],nil,nil,nil));
if ViewValues[I]<>'' then
begin
Memo^.AddLine(ViewValues[I]);
Memo^.TextEnd;
end;
ViewPtrs[I]:=Memo;
end;
vtCheckBox :
begin
New(CB, Init(ViewBounds[I],
NewSItem(
F^.GetEntry(ViewNames[I],tieName,''),
nil)));
if StrToInt(ViewValues[I])=1 then
CB^.Press(0);
ViewPtrs[I]:=CB;
end;
vtRadioButton :
begin
SI:=nil;
for J:=ViewItemCount[I] downto 1 do
SI:=NewSItem(F^.GetEntry(ViewNames[I],tieItem+IntToStr(J),''),SI);
New(RB, Init(ViewBounds[I], SI));
RB^.Press(StrToInt(ViewValues[I]));
ViewPtrs[I]:=RB;
end;
end;
Insert(ViewPtrs[I]);
end;
end;
InsertButtons(PromptDialog);
S:=F^.GetEntry(secMain,tmeDefaultView,'');
if S<>'' then
begin
S:=UpcaseStr(S);
I:=0;
while (I<ViewCount) and (UpcaseStr(ViewNames[I])<>S) do
Inc(I);
if UpcaseStr(ViewNames[I])=S then
ViewPtrs[I]^.Select;
end;
Re:=Desktop^.ExecView(PromptDialog);
OK:=OK and (Re=cmOK);
AbortTool:=(Re<>cmOK);
if OK then OK:=ExtractPromptDialogParams(F,Params);
if PromptDialog<>nil then Dispose(PromptDialog, Done);
ExecPromptDialog:=OK;
end;
var OK: boolean;
F: PINIFile;
Fn : string;
begin
Fn:=LocateFile(FileName);
if Fn='' then
Fn:=FileName;
if not ExistsFile(Fn) then
ErrorBox('Can''t read '+Fn,nil)
else
begin
New(F, Init(Fn));
OK:=F<>nil;
if OK then
begin
OK:=BuildPromptDialogInfo(F);
if OK then
OK:=ExecPromptDialog(F);
end;
if F<>nil then Dispose(F, Done);
end;
ExecutePromptDialog:=OK;
end;
function ParseToolParams(var Params: string; CheckOnly: boolean): integer;
var Err: integer;
W: PSourceWindow;
procedure ParseParams(Pass: sw_integer);
var I: sw_integer;
function IsAlpha(Ch: char): boolean;
begin
IsAlpha:=(Upcase(Ch) in['A'..'Z','_','$']);
end;
function ReplacePart(StartP,EndP: integer; const S: string): integer;
begin
Params:=copy(Params,1,StartP-1)+S+copy(Params,EndP+1,255);
ReplacePart:=length(S)-(EndP-StartP+1);
end;
function Consume(Ch: char): boolean;
var OK: boolean;
begin
OK:=Params[I]=Ch;
if OK then Inc(I);
Consume:=OK;
end;
function ReadTill(var S: string; C: char): boolean;
var Found: boolean;
begin
Found:=false; S:='';
while (I<=length(Params)) and (Found=false) do
begin
Found:=Params[I]=C;
if Found=false then
begin
S:=S+Params[I];
Inc(I);
end;
end;
ReadTill:=Found;
end;
var C,PrevC: char;
WordS: string;
LastWordStart: sw_integer;
L: longint;
S: string;
D: DirStr; N: NameStr; E: ExtStr;
begin
I:=1; WordS:=''; LastWordStart:=I; PrevC:=' ';
while (I<=length(Params)+1) and (Err=0) do
begin
if I<=length(Params) then C:=Params[I];
if (I<=length(Params)) and IsAlpha(C) then
begin
if (I=1) or (IsAlpha(PrevC)=false) then
begin WordS:=''; LastWordStart:=I; end;
{ if IsAlpha(C) then ForceConcat:=false;}
WordS:=WordS+C;
end
else
begin
WordS:=UpcaseStr(Trim(WordS));
if WordS<>'' then
if (WordS='$CAP') then
begin
if (Pass=0) then
if (Params[I]=' ') and (I<=High(Params)) then Params[I]:='_';
end else
if (WordS='$CAP_MSG') then
begin
if (Pass=2) then
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
I:=I+ReplacePart(LastWordStart,I-1,'')-1;
ToolFilter:=S;
CaptureToolTo:=capMessageWindow;
end;
end else
if (WordS='$CAP_EDIT') then
begin
if (Pass=3) then
begin
if Consume('(')=false then
I:=I+ReplacePart(LastWordStart,I-1,'')-1
else if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
I:=I+ReplacePart(LastWordStart,I-1,'')-1;
ToolOutput:=S;
end;
CaptureToolTo:=capEditWindow;
end;
end else
if (WordS='$COL') then
begin
if (Pass=1) then
begin
if W=nil then L:=0 else
L:=W^.Editor^.CurPos.X+1;
I:=I+ReplacePart(LastWordStart,I-1,IntToStr(L))-1;
end;
end else
if (WordS='$CONFIG') then
begin
if (Pass=1) then
I:=I+ReplacePart(LastWordStart,I-1,IniFileName)-1;
end else
if (WordS='$DIR') then
begin
if (Pass=2) then
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
FSplit(S,D,N,E);
L:=Pos(':',D);if L>0 then Delete(D,1,L);
I:=I+ReplacePart(LastWordStart,I-1,D)-1;
end;
end else
if (WordS='$DRIVE') then
begin
if (Pass=2) then
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
FSplit(S,D,N,E);
L:=Pos(':',D);
D:=copy(D,1,L);
I:=I+ReplacePart(LastWordStart,I-1,D)-1;
end;
end else
if (WordS='$EDNAME') then
begin
if (Pass=1) then
begin
if W=nil then S:='' else
S:=W^.Editor^.FileName;
I:=I+ReplacePart(LastWordStart,I-1,S)-1;
end;
end else
if (WordS='$EXENAME') then
begin
if (Pass=1) then
I:=I+ReplacePart(LastWordStart,I-1,EXEFile)-1;
end else
if (WordS='$EXT') then
begin
if (Pass=2) then
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
FSplit(S,D,N,E); E:=copy(E,2,High(E));
I:=I+ReplacePart(LastWordStart,I-1,E)-1;
end;
end else
if (WordS='$LINE') then
begin
if (Pass=1) then
begin
if W=nil then L:=0 else
L:=W^.Editor^.CurPos.Y+1;
I:=I+ReplacePart(LastWordStart,I-1,IntToStr(L))-1;
end;
end else
if (WordS='$NAME') then
begin
if (Pass=2) then
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
FSplit(S,D,N,E);
I:=I+ReplacePart(LastWordStart,I-1,N)-1;
end;
end else
if (WordS='$NAMEEXT') then
begin
if (Pass=2) then
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
FSplit(S,D,N,E);
I:=I+ReplacePart(LastWordStart,I-1,N+E)-1;
end;
end else
if (WordS='$NOSWAP') then
begin
if (Pass=1) then
begin
I:=I+ReplacePart(LastWordStart,I-1,'')-1;
CaptureToolTo:=capNoSwap;
end;
end else
if (WordS='$DRIVE') then
begin
if (Pass=2) then
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
FSplit(S,D,N,E);
L:=Pos(':',D); if L=0 then L:=-1;
D:=copy(D,1,L+1);
I:=I+ReplacePart(LastWordStart,I-1,D)-1;
end;
end else
if (WordS='$PROMPT') then
begin
if (Pass=3) then
if Params[I]='(' then
begin
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
if S='' then Err:=I-1 else
if CheckOnly=false then
if ExecutePromptDialog(S,S)=false then
Err:=I
else
I:=I+ReplacePart(LastWordStart,I-1,S)-1;
end;
end
else { just prompt for parms }
begin
I:=I+ReplacePart(LastWordStart,I-1,'')-1;
if CheckOnly=false then
begin
S:=copy(Params,I+1,High(Params));
if InputBox(dialog_programarguments, label_enterprogramargument,
S,High(Params)-I+1)=cmOK then
begin
ReplacePart(LastWordStart,255,S);
I:=255;
end
else
Err:=-1;
end;
end;
end else
if (WordS='$SAVE') then
begin
if (Pass=0) then
if (Params[I]=' ') and (I<=High(Params)) then Params[I]:='_';
end else
if (WordS='$SAVE_ALL') then
begin
if (Pass=2) then
begin
I:=I+ReplacePart(LastWordStart,I-1,'')-1;
Message(Application,evCommand,cmSaveAll,nil);
end;
end else
if (WordS='$SAVE_CUR') then
begin
if (Pass=2) then
begin
I:=I+ReplacePart(LastWordStart,I-1,'')-1;
Message(W,evCommand,cmSave,nil);
end;
end else
if (WordS='$SAVE_PROMPT') then
begin
if (Pass=2) then
begin
I:=I+ReplacePart(LastWordStart,I-1,'')-1;
if W<>nil then
if W^.Editor^.SaveAsk(true)=false then
Err:=-1;
end;
end else
if (WordS='$WRITEMSG') then
begin
if (Pass=2) then
if Consume('(')=false then Err:=I else
if ReadTill(S,')')=false then Err:=I else
begin
Consume(')');
I:=I+ReplacePart(LastWordStart,I-1,'')-1;
if CheckOnly=false then
WriteToolMessagesToFile(S);
end;
end else
if copy(WordS,1,1)='$' then
Err:=LastWordStart;
WordS:='';
end;
PrevC:=C;
Inc(I);
end;
end;
var Pass: sw_integer;
begin
W:=FirstEditorWindow;
Err:=0;
AbortTool:=false;
for Pass:=0 to 3 do
begin
ParseParams(Pass);
if Err<>0 then Break;
end;
if AbortTool then Err:=-1;
ParseToolParams:=Err;
end;
procedure InitToolProcessing;
begin
AbortTool:=false;
CaptureToolTo:=capNone;
ToolFilter:='';
ToolOutput:='';
end;
function ProcessMessageFile(const MsgFileName: string): boolean;
var OK,Done: boolean;
S: PBufStream;
C: char;
Sign: array[1..10] of char;
InFileName,InReference: boolean;
AddChar: boolean;
FileName,Line: string;
Row,Col: longint;
procedure AddLine;
begin
Row:=ord(Line[1])+ord(Line[2]) shl 8;
Col:=ord(Line[3])+ord(Line[4]) shl 8;
AddToolMessage(FileName,copy(Line,5,High(Line)),Row,Col);
end;
begin
New(S, Init(MsgFileName, stOpenRead, 4096));
OK:=(S<>nil) and (S^.Status=stOK);
if OK then S^.Read(Sign,SizeOf(Sign));
OK:=OK and (Sign=MsgFilterSign);
Done:=false;
InFileName:=false;
InReference:=false;
FileName:='';
Line:='';
while OK and (Done=false) do
begin
S^.Read(C,SizeOf(C));
OK:=(S^.Status=stOK);
AddChar:=false;
if OK then
case C of
#0 : if InFileName then
begin InFileName:=false end else
if InReference then
begin
if (length(Line)>4) then
begin
AddLine;
InReference:=false;
end
else
AddChar:=true;
end else
begin InFileName:=true; FileName:=''; end;
#1 : if InReference then AddChar:=true else
begin InReference:=true; Line:=''; end;
#127 : if InReference then AddChar:=true else
Done:=true;
else AddChar:=true;
end;
if AddChar then
if InFileName then
FileName:=FileName+C else
if InReference then
Line:=Line+C;
end;
if S<>nil then Dispose(S, Done);
ProcessMessageFile:=OK;
end;
procedure InitToolTempFiles;
begin
if not Assigned(ToolTempFiles) then
New(ToolTempFiles, Init(10,10));
end;
procedure DoneToolTempFiles;
procedure DeleteIt(P: PString);
begin
DeleteFile(GetStr(P));
end;
begin
if not Assigned(ToolTempFiles) then Exit;
{$ifndef DEBUG}
ToolTempFiles^.ForEach(@DeleteIt);
{$endif ndef DEBUG}
Dispose(ToolTempFiles, Done);
ToolTempFiles:=nil;
end;
constructor TToolMessage.Init(AModule: PString; ALine: string; ARow, ACol: sw_integer);
begin
inherited Init(0,ALine,AModule,ARow,ACol);
if LongestTool<Length(Aline)+Length(GetStr(AModule))+4 then
LongestTool:=Length(Aline)+Length(GetStr(AModule))+4;
end;
function TToolMessage.GetText(MaxLen: Sw_integer): string;
var S: string;
begin
if Module=nil then
S:=GetStr(Text)
else
S:=NameAndExtOf(GetModuleName)+
'('+IntToStr(Row)+'): '+GetStr(Text);
GetText:=copy(S,1,MaxLen);
end;
procedure AddToolCommand(Command: string);
begin
AddToolMessage('',Command,0,0);
LastToolMessageFocused:=ToolMessages^.At(ToolMessages^.Count-1);
end;
procedure AddToolMessage(ModuleName, Text: string; Row, Col: longint);
var MN: PString;
begin
if ToolMessages=nil then
New(ToolMessages, Init(500,1000));
if ToolModuleNames=nil then
New(ToolModuleNames, Init(50,100));
MN:=ToolModuleNames^.Add(ModuleName);
ToolMessages^.Insert(New(PToolMessage, Init(MN,Text,Row,Col)));
end;
procedure ClearToolMessages;
begin
If assigned(ToolMessages) then
ToolMessages^.FreeAll;
If assigned(ToolModuleNames) then
ToolModuleNames^.FreeAll;
LastToolMessageFocused:=nil;
LongestTool:=0;
end;
procedure DoneToolMessages;
begin
If assigned(ToolMessages) then
begin
Dispose(ToolMessages,Done);
ToolMessages:=nil;
end;
If assigned(ToolModuleNames) then
begin
Dispose(ToolModuleNames,Done);
ToolModuleNames:=nil;
end;
LastToolMessageFocused:=nil;
LongestTool:=0;
end;
procedure UpdateToolMessages;
begin
if Assigned(MessagesWindow) then
MessagesWindow^.Update;
end;
procedure TToolMessageListBox.Update;
var P: PMessageItem;
Idx: integer;
begin
P:=LastToolMessageFocused;
NewList(ToolMessages);
if assigned(HScrollBar) then
HScrollbar^.SetRange(0,LongestTool);
if (Range>0) and (P<>nil) then
begin
Idx:=List^.IndexOf(P);
if Idx>=0 then
begin
FocusItem(Idx);
DrawView;
end;
end;
DrawView;
end;
procedure TToolMessageListBox.NewList(AList: PCollection);
begin
if (List=ToolMessages) or (ToolMessages=nil) then
begin List:=nil; SetRange(0); end;
inherited NewList(AList);
end;
procedure TToolMessageListBox.Clear;
begin
ClearToolMessages;
Update;
Message(Application,evBroadcast,cmClearLineHighlights,@Self);
end;
function TToolMessageListBox.GetPalette: PPalette;
const
P: string[length(CBrowserListBox)] = CBrowserListBox;
begin
GetPalette:=@P;
end;
constructor TToolMessageListBox.Load(var S: TStream);
begin
inherited Load(S);
end;
procedure TToolMessageListBox.Store(var S: TStream);
var OL: PCollection;
begin
OL:=List;
New(List, Init(1,1));
inherited Store(S);
Dispose(List, Done);
List:=OL;
end;
destructor TToolMessageListBox.Done;
begin
HScrollBar:=nil; VScrollBar:=nil;
if List=ToolMessages then begin List:=nil; SetRange(0); end;
inherited Done;
end;
constructor TMessagesWindow.Init;
var R: TRect;
HSB,VSB: PScrollBar;
begin
Desktop^.GetExtent(R); R.A.Y:=R.B.Y-7;
inherited Init(R,dialog_messages,SearchFreeWindowNo);
HelpCtx:=hcMessagesWindow;
HSB:=StandardScrollBar(sbHorizontal+sbHandleKeyboard); Insert(HSB);
VSB:=StandardScrollBar(sbVertical+sbHandleKeyboard); Insert(VSB);
VSB^.SetStep(R.B.Y-R.A.Y-2,1);
HSB^.SetStep(R.B.X-R.A.X-2,1);
GetExtent(R); R.Grow(-1,-1);
New(MsgLB, Init(R, HSB, VSB));
Insert(MsgLB);
Update;
MessagesWindow:=@Self;
end;
procedure TMessagesWindow.Update;
begin
MsgLB^.Update;
end;
procedure TMessagesWindow.FocusItem(i : sw_integer);
begin
MsgLB^.FocusItem(i);
end;
procedure TMessagesWindow.HandleEvent(var Event: TEvent);
begin
case Event.What of
evBroadcast :
case Event.Command of
cmListFocusChanged :
if Event.InfoPtr=MsgLB then
begin
LastToolMessageFocused:=MsgLB^.List^.At(MsgLB^.Focused);
Message(Application,evBroadcast,cmClearLineHighlights,@Self);
end;
end;
end;
inherited HandleEvent(Event);
end;
procedure TMessagesWindow.SizeLimits(var Min, Max: TPoint);
begin
inherited SizeLimits(Min,Max);
Min.X:=20;
Min.Y:=4;
end;
function TMessagesWindow.GetPalette: PPalette;
const S: string[length(CBrowserWindow)] = CBrowserWindow;
begin
GetPalette:=@S;
end;
constructor TMessagesWindow.Load(var S: TStream);
begin
inherited Load(S);
GetSubViewPtr(S,MsgLB);
Update;
MessagesWindow:=@Self;
end;
procedure TMessagesWindow.Store(var S: TStream);
begin
inherited Store(S);
PutSubViewPtr(S,MsgLB);
end;
destructor TMessagesWindow.Done;
begin
MessagesWindow:=nil;
inherited Done;
end;
procedure RegisterFPTools;
begin
{$ifndef NOOBJREG}
RegisterType(RToolMessageListBox);
RegisterType(RMessagesWindow);
{$endif}
end;
{$ifdef DEBUG}
Procedure FpToolsDebugMessage(AFileName, AText : string; ALine, APos :string ;nrline,nrpos:sw_word);
begin
AddToolMessage(AFileName,AText,nrline,nrPos);
UpdateToolMessages;
end;
begin
DebugMessageS:=@FpToolsDebugMessage;
{$endif DEBUG}
END.