fptools.pas 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Tool support for the IDE
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$I globdir.inc}
  12. unit FPTools;
  13. interface
  14. uses Objects,Drivers,Views,Dialogs,Validate,
  15. BrowCol,
  16. WEditor,WViews,
  17. FPViews;
  18. const
  19. MsgFilterSign = 'BI#PIP#OK'#0;
  20. type
  21. TCaptureTarget = (capNone,capMessageWindow,capEditWindow,capNoSwap);
  22. PTool = ^TTool;
  23. TTool = object(TObject)
  24. constructor Init(const ATitle, AProgramPath, ACommandLine: string; AHotKey: word);
  25. function GetTitle: string; virtual;
  26. procedure GetParams(var ATitle, AProgramPath, ACommandLine: string; var AHotKey: word); virtual;
  27. procedure SetParams(const ATitle, AProgramPath, ACommandLine: string; const AHotKey: word); virtual;
  28. destructor Done; virtual;
  29. private
  30. Title : PString;
  31. ProgramPath : PString;
  32. CommandLine : PString;
  33. HotKey : word;
  34. end;
  35. PToolCollection = ^TToolCollection;
  36. TToolCollection = object(TCollection)
  37. function At(Index: sw_Integer): PTool;
  38. end;
  39. PToolListBox = ^TToolListBox;
  40. TToolListBox = object(TAdvancedListBox)
  41. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  42. end;
  43. PToolParamValidator = ^TToolParamValidator;
  44. TToolParamValidator = object(TValidator)
  45. function IsValid(const S: string): Boolean; virtual;
  46. procedure Error; virtual;
  47. private
  48. ErrorPos: integer;
  49. end;
  50. PToolItemDialog = ^TToolItemDialog;
  51. TToolItemDialog = object(TCenterDialog)
  52. constructor Init(ATool: PTool);
  53. function Execute: Word; virtual;
  54. private
  55. Tool : PTool;
  56. TitleIL : PEditorInputLine;
  57. ProgramIL: PEditorInputLine;
  58. ParamIL : PEditorInputLine;
  59. HotKeyRB : PRadioButtons;
  60. end;
  61. PToolsDialog = ^TToolsDialog;
  62. TToolsDialog = object(TCenterDialog)
  63. constructor Init;
  64. function Execute: Word; virtual;
  65. procedure HandleEvent(var Event: TEvent); virtual;
  66. private
  67. ToolsLB : PToolListBox;
  68. procedure Add;
  69. procedure Edit;
  70. procedure Delete;
  71. end;
  72. PToolMessage = ^TToolMessage;
  73. TToolMessage = object(TMessageItem)
  74. constructor Init(AModule: PString; ALine: string; ARow, ACol: sw_integer);
  75. function GetText(MaxLen: Sw_integer): string; virtual;
  76. end;
  77. PToolMessageListBox = ^TToolMessageListBox;
  78. TToolMessageListBox = object(TMessageListBox)
  79. procedure NewList(AList: PCollection); virtual;
  80. procedure Clear; virtual;
  81. procedure Update; virtual;
  82. function GetPalette: PPalette; virtual;
  83. constructor Load(var S: TStream);
  84. procedure Store(var S: TStream);
  85. destructor Done; virtual;
  86. end;
  87. PMessagesWindow = ^TMessagesWindow;
  88. TMessagesWindow = object(TFPWindow)
  89. constructor Init;
  90. procedure Update; virtual;
  91. procedure HandleEvent(var Event: TEvent); virtual;
  92. function GetPalette: PPalette; virtual;
  93. constructor Load(var S: TStream);
  94. procedure Store(var S: TStream);
  95. destructor Done; virtual;
  96. procedure FocusItem(i : sw_integer);
  97. procedure SizeLimits(var Min, Max: TPoint); virtual;
  98. private
  99. MsgLB : PToolMessageListBox;
  100. end;
  101. procedure InitTools;
  102. function GetToolCount: sw_integer;
  103. function GetToolName(Idx: sw_integer): string;
  104. function AddTool(Title, ProgramPath, Params: string; HotKey: word): sw_integer;
  105. procedure GetToolParams(Idx: sw_integer; var Title, ProgramPath, Params: string; var HotKey: word);
  106. procedure SetToolParams(Idx: sw_integer; Title, ProgramPath, Params: string; HotKey: word);
  107. procedure DoneTools;
  108. function GetHotKeyName(Key: word): string;
  109. function ParseToolParams(var Params: string; CheckOnly: boolean): integer;
  110. procedure InitToolProcessing;
  111. function ProcessMessageFile(const MsgFileName: string): boolean;
  112. procedure AddToolCommand(Command: string);
  113. procedure AddToolMessage(ModuleName, Text: string; Row, Col: longint);
  114. procedure ClearToolMessages;
  115. procedure DoneToolMessages;
  116. procedure UpdateToolMessages;
  117. procedure InitToolTempFiles;
  118. procedure DoneToolTempFiles;
  119. const
  120. ToolFilter : string[128] = '';
  121. ToolOutput : string[128] = '';
  122. CaptureToolTo : TCaptureTarget = capNone;
  123. ToolMessages : PCollection = nil;
  124. ToolModuleNames: PStoreCollection = nil;
  125. MessagesWindow : PMessagesWindow = nil;
  126. LastToolMessageFocused : PToolMessage = nil;
  127. LongestTool : sw_integer = 0;
  128. procedure RegisterFPTools;
  129. {$ifdef DEBUG}
  130. Procedure FpToolsDebugMessage(AFileName, AText : string; ALine, APos : string;nrline,nrpos:sw_word);
  131. {$endif DEBUG}
  132. implementation
  133. uses Dos,
  134. FVConsts,
  135. App,MsgBox,
  136. WConsts,WUtils,WINI,
  137. FPConst,FPVars,FPUtils;
  138. {$ifndef NOOBJREG}
  139. const
  140. RToolMessageListBox: TStreamRec = (
  141. ObjType: 1600;
  142. VmtLink: Ofs(TypeOf(TToolMessageListBox)^);
  143. Load: @TToolMessageListBox.Load;
  144. Store: @TToolMessageListBox.Store
  145. );
  146. RMessagesWindow: TStreamRec = (
  147. ObjType: 1601;
  148. VmtLink: Ofs(TypeOf(TMessagesWindow)^);
  149. Load: @TMessagesWindow.Load;
  150. Store: @TMessagesWindow.Store
  151. );
  152. {$endif}
  153. {$ifdef useresstrings}
  154. resourcestring
  155. {$else}
  156. const
  157. {$endif}
  158. dialog_tools = 'Tools';
  159. dialog_modifynewtool = 'Modify/New Tool';
  160. dialog_programarguments = 'Program Arguments';
  161. dialog_messages = 'Messages';
  162. msg_errorparsingparametersatpos = ^C'Error parsing parameters line at line position %d.';
  163. msg_cantinstallmoretools = ^C'Can''t install more tools...';
  164. msg_requiredparametermissingin = 'Required parameter missing in [%s]';
  165. msg_requiredpropertymissingin = 'Required property missing in [%s]';
  166. msg_unknowntypein = 'Unknown type in [%s]';
  167. msg_propertymissingin = '%s property missing in [%s]';
  168. msg_invaliditemsin = 'Invalid number of items in [%s]';
  169. label_tools_programtitles = '~P~rogram titles';
  170. label_toolprop_title = '~T~itle';
  171. label_toolprop_programpath = 'Program ~p~ath';
  172. label_toolprop_commandline = 'Command ~l~ine';
  173. label_enterprogramargument = '~E~nter program argument';
  174. { standard button texts }
  175. button_OK = 'O~K~';
  176. button_Cancel = 'Cancel';
  177. button_New = '~N~ew';
  178. button_Edit = '~E~dit';
  179. button_Delete = '~D~elete';
  180. type
  181. THotKeyDef = record
  182. Name : string[12];
  183. KeyCode : word;
  184. end;
  185. const
  186. HotKeys : array[0..11] of THotKeyDef =
  187. ( (Name : '~U~nassigned' ; KeyCode : kbNoKey ),
  188. (Name : 'Shift+F~2~' ; KeyCode : kbShiftF2 ),
  189. (Name : 'Shift+F~3~' ; KeyCode : kbShiftF3 ),
  190. (Name : 'Shift+F~4~' ; KeyCode : kbShiftF4 ),
  191. (Name : 'Shift+F~5~' ; KeyCode : kbShiftF5 ),
  192. (Name : 'Shift+F~6~' ; KeyCode : kbShiftF6 ),
  193. (Name : 'Shift+F~7~' ; KeyCode : kbShiftF7 ),
  194. (Name : 'Shift+F~8~' ; KeyCode : kbShiftF8 ),
  195. (Name : 'Shift+F~9~' ; KeyCode : kbShiftF9 ),
  196. (Name : 'Shift+F1~0~' ; KeyCode : kbShiftF10),
  197. (Name : 'Shift+F1~1~' ; KeyCode : kbShiftF11),
  198. (Name : 'Shift+~F~12' ; KeyCode : kbShiftF12));
  199. Tools : PToolCollection = nil;
  200. AbortTool : boolean = false;
  201. ToolTempFiles: PUnsortedStringCollection = nil;
  202. function GetHotKeyCount: integer;
  203. begin
  204. GetHotKeyCount:=ord(High(HotKeys))-ord(Low(HotKeys))+1;
  205. end;
  206. function GetHotKeyNameByIdx(Idx: integer): string;
  207. begin
  208. GetHotKeyNameByIdx:=HotKeys[Idx].Name;
  209. end;
  210. function HotKeyToIdx(Key: word): integer;
  211. var Count,I: integer;
  212. Found: boolean;
  213. begin
  214. Count:=GetHotKeyCount; Found:=false;
  215. I:=0;
  216. while (I<Count) and (Found=false) do
  217. begin
  218. Found:=HotKeys[I].KeyCode=Key;
  219. if Found=false then
  220. Inc(I);
  221. end;
  222. if Found=false then I:=-1;
  223. HotKeyToIdx:=I;
  224. end;
  225. function IdxToHotKey(Idx: integer): word;
  226. var Count: integer;
  227. Key: word;
  228. begin
  229. Count:=GetHotKeyCount;
  230. if (0<=Idx) and (Idx<Count) then
  231. Key:=HotKeys[Idx].KeyCode
  232. else
  233. Key:=kbNoKey;
  234. IdxToHotKey:=Key;
  235. end;
  236. function GetHotKeyName(Key: word): string;
  237. var Idx: integer;
  238. S: string;
  239. begin
  240. Idx:=HotKeyToIdx(Key);
  241. if Idx=0 then S:='' else
  242. if Idx=-1 then S:='???' else
  243. S:=GetHotKeyNameByIdx(Idx);
  244. GetHotKeyName:=S;
  245. end;
  246. function WriteToolMessagesToFile(FileName: string): boolean;
  247. var OK: boolean;
  248. f: text;
  249. M: PToolMessage;
  250. I: sw_integer;
  251. begin
  252. I:=0;
  253. Assign(f,FileName);
  254. {$I-}
  255. Rewrite(f);
  256. OK:=EatIO=0;
  257. if Assigned(ToolMessages) then
  258. while OK and (I<ToolMessages^.Count) do
  259. begin
  260. M:=ToolMessages^.At(I);
  261. writeln(f,GetStr(M^.Module)+#0+GetStr(M^.Text)+#0+IntToStr(M^.Row)+#0+IntToStr(M^.Col));
  262. Inc(I);
  263. OK:=EatIO=0;
  264. end;
  265. Close(f);
  266. EatIO;
  267. {$I+}
  268. WriteToolMessagesToFile:=OK;
  269. end;
  270. constructor TTool.Init(const ATitle, AProgramPath, ACommandLine: string; AHotKey: word);
  271. begin
  272. inherited Init;
  273. SetParams(ATitle,AProgramPath,ACommandLine,AHotKey);
  274. end;
  275. function TTool.GetTitle: string;
  276. begin
  277. GetTitle:=KillTilde(GetStr(Title));
  278. end;
  279. procedure TTool.GetParams(var ATitle, AProgramPath, ACommandLine: string; var AHotKey: word);
  280. begin
  281. ATitle:=GetStr(Title); AProgramPath:=GetStr(ProgramPath);
  282. ACommandLine:=GetStr(CommandLine);
  283. AHotKey:=HotKey;
  284. end;
  285. procedure TTool.SetParams(const ATitle, AProgramPath, ACommandLine: string; const AHotKey: word);
  286. begin
  287. if Title<>nil then DisposeStr(Title); Title:=nil;
  288. if ProgramPath<>nil then DisposeStr(ProgramPath); ProgramPath:=nil;
  289. if CommandLine<>nil then DisposeStr(CommandLine); CommandLine:=nil;
  290. Title:=NewStr(ATitle); ProgramPath:=NewStr(AProgramPath);
  291. CommandLine:=NewStr(ACommandLine);
  292. HotKey:=AHotKey;
  293. end;
  294. destructor TTool.Done;
  295. begin
  296. inherited Done;
  297. if Title<>nil then DisposeStr(Title);
  298. if ProgramPath<>nil then DisposeStr(ProgramPath);
  299. if CommandLine<>nil then DisposeStr(CommandLine);
  300. end;
  301. function TToolCollection.At(Index: sw_Integer): PTool;
  302. begin
  303. At:=inherited At(Index);
  304. end;
  305. function TToolListBox.GetText(Item,MaxLen: sw_integer): String;
  306. var S: string;
  307. P: PTool;
  308. begin
  309. P:=List^.At(Item);
  310. S:=P^.GetTitle;
  311. GetText:=copy(S,1,MaxLen);
  312. end;
  313. procedure InitTools;
  314. begin
  315. if Tools<>nil then DoneTools;
  316. New(Tools, Init(10,20));
  317. end;
  318. function GetToolCount: sw_integer;
  319. var Count: integer;
  320. begin
  321. if Tools=nil then Count:=0 else
  322. Count:=Tools^.Count;
  323. GetToolCount:=Count;
  324. end;
  325. function GetToolName(Idx: sw_integer): string;
  326. var S1,S2: string;
  327. W: word;
  328. begin
  329. GetToolParams(Idx,S1,S2,S2,W);
  330. GetToolName:=KillTilde(S1);
  331. end;
  332. function AddTool(Title, ProgramPath, Params: string; HotKey: word): sw_integer;
  333. var P: PTool;
  334. begin
  335. if Tools=nil then InitTools;
  336. New(P, Init(Title,ProgramPath,Params,HotKey));
  337. Tools^.Insert(P);
  338. AddTool:=Tools^.IndexOf(P);
  339. end;
  340. procedure GetToolParams(Idx: sw_integer; var Title, ProgramPath, Params: string; var HotKey: word);
  341. var P: PTool;
  342. begin
  343. P:=Tools^.At(Idx);
  344. P^.GetParams(Title,ProgramPath,Params,HotKey);
  345. end;
  346. procedure SetToolParams(Idx: sw_integer; Title, ProgramPath, Params: string; HotKey: word);
  347. var P: PTool;
  348. begin
  349. P:=Tools^.At(Idx);
  350. P^.GetParams(Title,ProgramPath,Params,HotKey);
  351. end;
  352. procedure DoneTools;
  353. begin
  354. if Tools<>nil then Dispose(Tools, Done); Tools:=nil;
  355. end;
  356. procedure TToolParamValidator.Error;
  357. begin
  358. MsgParms[1].Long:=ErrorPos;
  359. ErrorBox(msg_errorparsingparametersatpos,@MsgParms);
  360. end;
  361. function TToolParamValidator.IsValid(const S: string): Boolean;
  362. var P: string;
  363. begin
  364. P:=S;
  365. ErrorPos:=ParseToolParams(P,true);
  366. IsValid:=ErrorPos=0;
  367. end;
  368. constructor TToolItemDialog.Init(ATool: PTool);
  369. var R,R2,R3: TRect;
  370. Items: PSItem;
  371. I,KeyCount: sw_integer;
  372. begin
  373. KeyCount:=GetHotKeyCount;
  374. R.Assign(0,0,60,Max(3+KeyCount,12));
  375. inherited Init(R,dialog_modifynewtool);
  376. Tool:=ATool;
  377. GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
  378. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
  379. New(TitleIL, Init(R, 128)); Insert(TitleIL);
  380. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_toolprop_title, TitleIL)));
  381. R.Move(0,3);
  382. New(ProgramIL, Init(R, 128)); Insert(ProgramIL);
  383. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_toolprop_programpath, ProgramIL)));
  384. R.Move(0,3);
  385. New(ParamIL, Init(R, 128)); Insert(ParamIL);
  386. ParamIL^.SetValidator(New(PToolParamValidator, Init));
  387. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_toolprop_commandline, ParamIL)));
  388. R.Copy(R3); Inc(R.A.X,38); R.B.Y:=R.A.Y+KeyCount;
  389. Items:=nil;
  390. for I:=KeyCount-1 downto 0 do
  391. Items:=NewSItem(GetHotKeyNameByIdx(I), Items);
  392. New(HotKeyRB, Init(R, Items));
  393. Insert(HotKeyRB);
  394. InsertButtons(@Self);
  395. TitleIL^.Select;
  396. end;
  397. function TToolItemDialog.Execute: Word;
  398. var R: word;
  399. S1,S2,S3: string;
  400. W: word;
  401. L: longint;
  402. begin
  403. Tool^.GetParams(S1,S2,S3,W);
  404. TitleIL^.SetData(S1); ProgramIL^.SetData(S2); ParamIL^.SetData(S3);
  405. L:=HotKeyToIdx(W); if L=-1 then L:=255;
  406. HotKeyRB^.SetData(L);
  407. R:=inherited Execute;
  408. if R=cmOK then
  409. begin
  410. TitleIL^.GetData(S1); ProgramIL^.GetData(S2); ParamIL^.GetData(S3);
  411. HotKeyRB^.GetData(L); W:=IdxToHotKey(L);
  412. Tool^.SetParams(S1,S2,S3,W);
  413. end;
  414. Execute:=R;
  415. end;
  416. constructor TToolsDialog.Init;
  417. var R,R2,R3: TRect;
  418. SB: PScrollBar;
  419. begin
  420. R.Assign(0,0,46,16);
  421. inherited Init(R,dialog_tools);
  422. HelpCtx:=hcTools;
  423. GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R3.Copy(R); Dec(R.B.X,12);
  424. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  425. New(SB, Init(R2)); Insert(SB);
  426. New(ToolsLB, Init(R,1,SB));
  427. Insert(ToolsLB);
  428. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
  429. Insert(New(PLabel, Init(R2, label_tools_programtitles, ToolsLB)));
  430. R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
  431. Insert(New(PButton, Init(R, button_OK, cmOK, bfNormal)));
  432. R.Move(0,2);
  433. Insert(New(PButton, Init(R, button_Edit, cmEditItem, bfDefault)));
  434. R.Move(0,2);
  435. Insert(New(PButton, Init(R, button_New, cmAddItem, bfNormal)));
  436. R.Move(0,2);
  437. Insert(New(PButton, Init(R, button_Delete, cmDeleteItem, bfNormal)));
  438. R.Move(0,2);
  439. Insert(New(PButton, Init(R, button_Cancel, cmCancel, bfNormal)));
  440. SelectNext(false);
  441. end;
  442. procedure TToolsDialog.HandleEvent(var Event: TEvent);
  443. var DontClear: boolean;
  444. begin
  445. case Event.What of
  446. evKeyDown :
  447. begin
  448. DontClear:=false;
  449. case Event.KeyCode of
  450. kbIns :
  451. Message(@Self,evCommand,cmAddItem,nil);
  452. kbDel :
  453. Message(@Self,evCommand,cmDeleteItem,nil);
  454. else DontClear:=true;
  455. end;
  456. if DontClear=false then ClearEvent(Event);
  457. end;
  458. evBroadcast :
  459. case Event.Command of
  460. cmListItemSelected :
  461. if Event.InfoPtr=pointer(ToolsLB) then
  462. Message(@Self,evCommand,cmEditItem,nil);
  463. end;
  464. evCommand :
  465. begin
  466. DontClear:=false;
  467. case Event.Command of
  468. cmAddItem : Add;
  469. cmDeleteItem : Delete;
  470. cmEditItem : Edit;
  471. else DontClear:=true;
  472. end;
  473. if DontClear=false then ClearEvent(Event);
  474. end;
  475. end;
  476. inherited HandleEvent(Event);
  477. end;
  478. function TToolsDialog.Execute: Word;
  479. var R: word;
  480. C: PToolCollection;
  481. I: integer;
  482. S1,S2,S3: string;
  483. W: word;
  484. begin
  485. New(C, Init(10,20));
  486. if Tools<>nil then
  487. for I:=0 to Tools^.Count-1 do
  488. begin
  489. Tools^.At(I)^.GetParams(S1,S2,S3,W);
  490. C^.Insert(New(PTool, Init(S1,S2,S3,W)));
  491. end;
  492. ToolsLB^.NewList(C);
  493. R:=inherited Execute;
  494. if R=cmOK then
  495. begin
  496. if Tools<>nil then Dispose(Tools, Done);
  497. Tools:=C;
  498. Message(Application,evBroadcast,cmUpdateTools,nil);
  499. end
  500. else
  501. Dispose(C, Done);
  502. Execute:=R;
  503. end;
  504. procedure TToolsDialog.Add;
  505. var P: PTool;
  506. IC: boolean;
  507. S1,S2,S3: string;
  508. W: word;
  509. begin
  510. if ToolsLB^.Range>=MaxToolCount then
  511. begin InformationBox(msg_cantinstallmoretools,nil); Exit; end;
  512. IC:=ToolsLB^.Range=0;
  513. if IC=false then
  514. begin
  515. P:=ToolsLB^.List^.At(ToolsLB^.Focused);
  516. P^.GetParams(S1,S2,S3,W);
  517. end
  518. else
  519. begin
  520. S1:=''; S2:=''; S3:=''; W:=0;
  521. end;
  522. New(P, Init(S1,S2,S3,W));
  523. if Application^.ExecuteDialog(New(PToolItemDialog, Init(P)), nil)=cmOK then
  524. begin
  525. ToolsLB^.List^.Insert(P);
  526. ToolsLB^.SetRange(ToolsLB^.List^.Count);
  527. ReDraw;
  528. end
  529. else
  530. Dispose(P, Done);
  531. end;
  532. procedure TToolsDialog.Edit;
  533. var P: PTool;
  534. begin
  535. if ToolsLB^.Range=0 then Exit;
  536. P:=ToolsLB^.List^.At(ToolsLB^.Focused);
  537. Application^.ExecuteDialog(New(PToolItemDialog, Init(P)), nil);
  538. ReDraw;
  539. end;
  540. procedure TToolsDialog.Delete;
  541. begin
  542. if ToolsLB^.Range=0 then Exit;
  543. ToolsLB^.List^.AtFree(ToolsLB^.Focused);
  544. ToolsLB^.SetRange(ToolsLB^.List^.Count);
  545. ReDraw;
  546. end;
  547. (*procedure ReplaceStr(var S: string; const What,NewS: string);
  548. var I : integer;
  549. begin
  550. repeat
  551. I:=Pos(What,S);
  552. if I>0 then
  553. begin
  554. Delete(S,I,length(What));
  555. Insert(NewS,S,I);
  556. end;
  557. until I=0;
  558. end;
  559. procedure ReplaceStrI(var S: string; What: string; const NewS: string);
  560. var I : integer;
  561. UpcaseS: string;
  562. begin
  563. UpcaseS:=UpcaseStr(S); What:=UpcaseStr(What);
  564. repeat
  565. I:=Pos(What,UpcaseS);
  566. if I>0 then
  567. begin
  568. Delete(S,I,length(What));
  569. Insert(NewS,S,I);
  570. end;
  571. until I=0;
  572. end;*)
  573. function GetCoordEntry(F: PINIFile; Section, Entry: string; var P: TPoint): boolean;
  574. var OK: boolean;
  575. S: string;
  576. Px: integer;
  577. begin
  578. S:=F^.GetEntry(Section,Entry,'');
  579. S:=Trim(S);
  580. OK:=(S<>'') and (S[1]='(') and (S[length(S)]=')');
  581. if OK then S:=copy(S,2,length(S)-2);
  582. Px:=Pos(',',S);
  583. OK:=OK and (Px>0);
  584. if OK then P.X:=StrToInt(copy(S,1,Px-1));
  585. OK:=OK and (LastStrToIntResult=0);
  586. if OK then P.Y:=StrToInt(copy(S,Px+1,High(S)));
  587. OK:=OK and (LastStrToIntResult=0);
  588. GetCoordEntry:=OK;
  589. end;
  590. function ExecutePromptDialog(const FileName: string; var Params: string): boolean;
  591. const
  592. MaxViews = 20;
  593. MaxViewNameLen = 40;
  594. MaxValueLen = 80;
  595. secMain = 'MAIN';
  596. { Main section entries }
  597. tmeTitle = 'TITLE';
  598. tmeCommandLine = 'COMMANDLINE';
  599. tmeSize = 'SIZE';
  600. tmeDefaultView = 'DEFAULT';
  601. { View section entries }
  602. tieType = 'TYPE';
  603. tieOrigin = 'ORIGIN';
  604. tieSize = 'SIZE';
  605. {*} tieDefault = 'DEFAULT';
  606. tieValue = 'VALUE';
  607. { Additional CheckBox view section entries }
  608. tieName = 'NAME';
  609. tieOnParm = 'ON';
  610. tieOffParm = 'OFF';
  611. { Additional CheckBox view section entries }
  612. tieItem = 'ITEM';
  613. tieParam = 'PARAM';
  614. { Additional InputLine view section entries }
  615. tieMaxLen = 'MAXLEN';
  616. { Additional Label view section entries }
  617. tieLink = 'LINK';
  618. tieText = 'TEXT';
  619. { Additional Memo view section entries }
  620. tieFileName = 'FILENAME';
  621. { View types }
  622. vtCheckBox = 1;
  623. vtRadioButton = 2;
  624. vtInputLine = 3;
  625. vtMemo = 4;
  626. vtLabel = 127;
  627. vtsCheckBox = 'CHECKBOX';
  628. vtsRadioButton = 'RADIOBUTTON';
  629. vtsInputLine = 'INPUTLINE';
  630. vtsLabel = 'LABEL';
  631. vtsMemo = 'MEMO';
  632. var Title : string;
  633. DSize : TPoint;
  634. CmdLine : string;
  635. ViewCount : Sw_integer;
  636. ViewNames : array[0..MaxViews-1] of string[MaxViewNameLen];
  637. ViewTypes : array[0..MaxViews-1] of byte;
  638. ViewBounds : array[0..MaxViews-1] of TRect;
  639. ViewPtrs : array[0..MaxViews-1] of PView;
  640. ViewValues : array[0..MaxViews-1] of string[MaxValueLen];
  641. ViewItemCount: array[0..MaxViews-1] of sw_integer;
  642. function BuildPromptDialogInfo(F: PINIFile): boolean;
  643. var
  644. OK: boolean;
  645. _IS: PINISection;
  646. procedure ProcessSection(Sec: PINISection);
  647. var P1,P2: TPoint;
  648. Typ: string;
  649. Count: sw_integer;
  650. begin
  651. if (OK=false) or
  652. ( (UpcaseStr(Sec^.GetName)=secMain) or
  653. (UpcaseStr(Sec^.GetName)=UpcaseStr(MainSectionName)) ) then
  654. Exit;
  655. ViewItemCount[ViewCount]:=0;
  656. OK:=(Sec^.SearchEntry(tieType)<>nil) and
  657. (Sec^.SearchEntry(tieOrigin)<>nil) and
  658. (Sec^.SearchEntry(tieSize)<>nil);
  659. if OK=false then
  660. begin ErrorBox(FormatStrStr(msg_requiredparametermissingin,Sec^.GetName),nil); Exit; end;
  661. Typ:=UpcaseStr(Trim(F^.GetEntry(Sec^.GetName,tieType,'')));
  662. if Typ=vtsCheckBox then ViewTypes[ViewCount]:=vtCheckBox else
  663. if Typ=vtsRadioButton then ViewTypes[ViewCount]:=vtRadioButton else
  664. if Typ=vtsInputLine then ViewTypes[ViewCount]:=vtInputLine else
  665. if Typ=vtsLabel then ViewTypes[ViewCount]:=vtLabel else
  666. if Typ=vtsMemo then ViewTypes[ViewCount]:=vtMemo else
  667. begin OK:=false; ErrorBox(FormatStrStr(msg_unknowntypein,Sec^.GetName),nil); Exit; end;
  668. ViewNames[ViewCount]:=Sec^.GetName;
  669. GetCoordEntry(F,Sec^.GetName,tieOrigin,P1);
  670. GetCoordEntry(F,Sec^.GetName,tieSize,P2);
  671. ViewBounds[ViewCount].Assign(P1.X,P1.Y,P1.X+P2.X,P1.Y+P2.Y);
  672. { allow conversion of $EDNAME for instance in
  673. default values PM }
  674. Typ:=F^.GetEntry(Sec^.GetName,tieValue,'');
  675. ParseToolParams(Typ,true);
  676. ViewValues[ViewCount]:=Typ;
  677. case ViewTypes[ViewCount] of
  678. vtLabel :
  679. begin
  680. OK:=OK and (Sec^.SearchEntry(tieLink)<>nil) and
  681. (Sec^.SearchEntry(tieText)<>nil);
  682. if OK=false then
  683. begin ErrorBox(FormatStrStr(msg_requiredpropertymissingin,Sec^.GetName),nil); Exit; end;
  684. end;
  685. vtInputLine : ;
  686. vtMemo : ;
  687. vtCheckBox :
  688. begin
  689. OK:=OK and (Sec^.SearchEntry(tieName)<>nil);
  690. if Typ='' then
  691. Typ:=tieOffParm;
  692. if F^.GetEntry(Sec^.GetName,tieDefault,'')<>'' then
  693. begin
  694. Typ:=F^.GetEntry(Sec^.GetName,tieDefault,'');
  695. end;
  696. Typ:=UpcaseStr(Trim(Typ));
  697. if Typ=tieOnParm then
  698. Typ:='1'
  699. else if Typ=tieOffParm then
  700. Typ:='0'
  701. else if (Typ<>'0') and (Typ<>'1') then
  702. Ok:=false;
  703. ViewValues[ViewCount]:=Typ;
  704. if OK=false then
  705. begin ErrorBox(FormatStrStr2(msg_propertymissingin,tieName,Sec^.GetName),nil); Exit; end;
  706. end;
  707. vtRadioButton:
  708. begin
  709. Count:=0;
  710. while Sec^.SearchEntry(tieItem+IntToStr(Count+1))<>nil do
  711. Inc(Count);
  712. ViewItemCount[ViewCount]:=Count;
  713. OK:=Count>0;
  714. if OK=false then
  715. begin ErrorBox(FormatStrStr(msg_invaliditemsin,Sec^.GetName),nil); Exit; end;
  716. end;
  717. end;
  718. if OK then Inc(ViewCount);
  719. end;
  720. begin
  721. BuildPromptDialogInfo:=false;
  722. _IS:=F^.SearchSection(secMain);
  723. OK:=_IS<>nil;
  724. if OK then OK:=(_IS^.SearchEntry(tmeTitle)<>nil) and
  725. (_IS^.SearchEntry(tmeSize)<>nil) and
  726. (_IS^.SearchEntry(tmeCommandLine)<>nil);
  727. if OK then
  728. begin
  729. Title:=F^.GetEntry(secMain,tmeTitle,'');
  730. OK:=OK and GetCoordEntry(F,secMain,tmeSize,DSize);
  731. CmdLine:=F^.GetEntry(secMain,tmeCommandLine,'');
  732. OK:=OK and (CmdLine<>'');
  733. end;
  734. if OK=false then
  735. begin ErrorBox(FormatStrStr(msg_requiredpropertymissingin,_IS^.GetName),nil); Exit; end;
  736. if OK then
  737. begin
  738. ViewCount:=0;
  739. F^.ForEachSection(@ProcessSection);
  740. end;
  741. BuildPromptDialogInfo:=OK;
  742. end;
  743. function SearchViewByName(Name: string): integer;
  744. var I,Idx: Sw_integer;
  745. begin
  746. Idx:=-1; Name:=UpcaseStr(Name);
  747. for I:=0 to ViewCount-1 do
  748. if UpcaseStr(ViewNames[I])=Name then
  749. begin
  750. Idx:=I;
  751. Break;
  752. end;
  753. SearchViewByName:=Idx;
  754. end;
  755. function GetParamValueStr(F: PINIFile; Idx: integer): string;
  756. var S: string;
  757. Entry: string[20];
  758. begin
  759. S:='???';
  760. case ViewTypes[Idx] of
  761. vtLabel :
  762. S:='';
  763. vtMemo :
  764. begin
  765. S:=F^.GetEntry(ViewNames[Idx],tieFileName,'');
  766. if S='' then S:=GenTempFileName;
  767. ToolTempFiles^.InsertStr(S);
  768. if PFPMemo(ViewPtrs[Idx])^.SaveToFile(S)=false then
  769. ErrorBox(FormatStrStr(msg_errorsavingfile,S),nil);
  770. end;
  771. vtInputLine :
  772. S:=PInputLine(ViewPtrs[Idx])^.Data^;
  773. vtCheckBox :
  774. with PCheckBoxes(ViewPtrs[Idx])^ do
  775. begin
  776. if Mark(0) then Entry:=tieOnParm else Entry:=tieOffParm;
  777. S:=F^.GetEntry(ViewNames[Idx],Entry,'');
  778. end;
  779. vtRadioButton :
  780. with PRadioButtons(ViewPtrs[Idx])^ do
  781. begin
  782. Entry:=tieParam+IntToStr(Value+1);
  783. S:=F^.GetEntry(ViewNames[Idx],Entry,'');
  784. end;
  785. end;
  786. GetParamValueStr:=S;
  787. end;
  788. function ExtractPromptDialogParams(F: PINIFile; var Params: string): boolean;
  789. function ReplacePart(StartP,EndP: integer; const S: string): integer;
  790. begin
  791. Params:=copy(Params,1,StartP-1)+S+copy(Params,EndP+1,255);
  792. ReplacePart:=length(S)-(EndP-StartP+1);
  793. end;
  794. var OptName: string;
  795. OK: boolean;
  796. C: char;
  797. OptStart: integer;
  798. InOpt: boolean;
  799. I,Idx: integer;
  800. S: string;
  801. begin
  802. Params:=CmdLine;
  803. I:=1; InOpt:=false; OK:=true;
  804. while OK and (I<=length(Params)) do
  805. begin
  806. C:=Params[I];
  807. if C='%' then
  808. begin
  809. InOpt:=not InOpt;
  810. if InOpt then
  811. begin
  812. OptName:='';
  813. OptStart:=I;
  814. end
  815. else
  816. begin
  817. OptName:=UpcaseStr(OptName);
  818. Idx:=SearchViewByName(OptName);
  819. OK:=Idx<>-1;
  820. if OK then
  821. begin
  822. S:=GetParamValueStr(F,Idx);
  823. if (S='') and (Params[I+1]=' ') then Inc(I);
  824. I:=I+ReplacePart(OptStart,I,S);
  825. end;
  826. end;
  827. end
  828. else
  829. if InOpt then
  830. OptName:=OptName+C;
  831. Inc(I);
  832. end;
  833. ExtractPromptDialogParams:=OK;
  834. end;
  835. function ExecPromptDialog(F: PINIFile): boolean;
  836. var R: TRect;
  837. PromptDialog: PCenterDialog;
  838. Re: integer;
  839. OK: boolean;
  840. I,J,MaxLen: integer;
  841. Memo: PFPMemo;
  842. IL: PEditorInputLine;
  843. CB: PCheckBoxes;
  844. RB: PRadioButtons;
  845. LV: PLabel;
  846. SI: PSItem;
  847. S: string;
  848. P: PView;
  849. begin
  850. OK:=true;
  851. R.Assign(0,0,DSize.X,DSize.Y);
  852. New(PromptDialog, Init(R, Title));
  853. with PromptDialog^ do
  854. begin
  855. for I:=0 to ViewCount-1 do
  856. begin
  857. case ViewTypes[I] of
  858. vtLabel :
  859. begin
  860. S:=F^.GetEntry(ViewNames[I],tieLink,'');
  861. J:=SearchViewByName(S);
  862. if J=-1 then P:=nil else
  863. P:=ViewPtrs[J];
  864. S:=F^.GetEntry(ViewNames[I],tieText,'');
  865. New(LV, Init(ViewBounds[I], S, P));
  866. ViewPtrs[I]:=LV;
  867. end;
  868. vtInputLine :
  869. begin
  870. MaxLen:=F^.GetIntEntry(ViewNames[I],tieMaxLen,80);
  871. New(IL, Init(ViewBounds[I], MaxLen));
  872. IL^.Data^:=ViewValues[I];
  873. ViewPtrs[I]:=IL;
  874. end;
  875. vtMemo :
  876. begin
  877. { MaxLen:=F^.GetIntEntry(ViewNames[I],tieMaxLen,80);}
  878. New(Memo, Init(ViewBounds[I],nil,nil,nil));
  879. if ViewValues[I]<>'' then
  880. begin
  881. Memo^.AddLine(ViewValues[I]);
  882. Memo^.TextEnd;
  883. end;
  884. ViewPtrs[I]:=Memo;
  885. end;
  886. vtCheckBox :
  887. begin
  888. New(CB, Init(ViewBounds[I],
  889. NewSItem(
  890. F^.GetEntry(ViewNames[I],tieName,''),
  891. nil)));
  892. if StrToInt(ViewValues[I])=1 then
  893. CB^.Press(0);
  894. ViewPtrs[I]:=CB;
  895. end;
  896. vtRadioButton :
  897. begin
  898. SI:=nil;
  899. for J:=ViewItemCount[I] downto 1 do
  900. SI:=NewSItem(F^.GetEntry(ViewNames[I],tieItem+IntToStr(J),''),SI);
  901. New(RB, Init(ViewBounds[I], SI));
  902. RB^.Press(StrToInt(ViewValues[I]));
  903. ViewPtrs[I]:=RB;
  904. end;
  905. end;
  906. Insert(ViewPtrs[I]);
  907. end;
  908. end;
  909. InsertButtons(PromptDialog);
  910. S:=F^.GetEntry(secMain,tmeDefaultView,'');
  911. if S<>'' then
  912. begin
  913. S:=UpcaseStr(S);
  914. I:=0;
  915. while (I<ViewCount) and (UpcaseStr(ViewNames[I])<>S) do
  916. Inc(I);
  917. if UpcaseStr(ViewNames[I])=S then
  918. ViewPtrs[I]^.Select;
  919. end;
  920. Re:=Desktop^.ExecView(PromptDialog);
  921. OK:=OK and (Re=cmOK);
  922. AbortTool:=(Re<>cmOK);
  923. if OK then OK:=ExtractPromptDialogParams(F,Params);
  924. if PromptDialog<>nil then Dispose(PromptDialog, Done);
  925. ExecPromptDialog:=OK;
  926. end;
  927. var OK: boolean;
  928. F: PINIFile;
  929. Fn : string;
  930. begin
  931. Fn:=LocateFile(FileName);
  932. if Fn='' then
  933. Fn:=FileName;
  934. if not ExistsFile(Fn) then
  935. ErrorBox('Can''t read '+Fn,nil)
  936. else
  937. begin
  938. New(F, Init(Fn));
  939. OK:=F<>nil;
  940. if OK then
  941. begin
  942. OK:=BuildPromptDialogInfo(F);
  943. if OK then
  944. OK:=ExecPromptDialog(F);
  945. end;
  946. if F<>nil then Dispose(F, Done);
  947. end;
  948. ExecutePromptDialog:=OK;
  949. end;
  950. function ParseToolParams(var Params: string; CheckOnly: boolean): integer;
  951. var Err: integer;
  952. W: PSourceWindow;
  953. procedure ParseParams(Pass: sw_integer);
  954. var I: sw_integer;
  955. function IsAlpha(Ch: char): boolean;
  956. begin
  957. IsAlpha:=(Upcase(Ch) in['A'..'Z','_','$']);
  958. end;
  959. function ReplacePart(StartP,EndP: integer; const S: string): integer;
  960. begin
  961. Params:=copy(Params,1,StartP-1)+S+copy(Params,EndP+1,255);
  962. ReplacePart:=length(S)-(EndP-StartP+1);
  963. end;
  964. function Consume(Ch: char): boolean;
  965. var OK: boolean;
  966. begin
  967. OK:=Params[I]=Ch;
  968. if OK then Inc(I);
  969. Consume:=OK;
  970. end;
  971. function ReadTill(var S: string; C: char): boolean;
  972. var Found: boolean;
  973. begin
  974. Found:=false; S:='';
  975. while (I<=length(Params)) and (Found=false) do
  976. begin
  977. Found:=Params[I]=C;
  978. if Found=false then
  979. begin
  980. S:=S+Params[I];
  981. Inc(I);
  982. end;
  983. end;
  984. ReadTill:=Found;
  985. end;
  986. var C,PrevC: char;
  987. WordS: string;
  988. LastWordStart: sw_integer;
  989. L: longint;
  990. S: string;
  991. D: DirStr; N: NameStr; E: ExtStr;
  992. begin
  993. I:=1; WordS:=''; LastWordStart:=I; PrevC:=' ';
  994. while (I<=length(Params)+1) and (Err=0) do
  995. begin
  996. if I<=length(Params) then C:=Params[I];
  997. if (I<=length(Params)) and IsAlpha(C) then
  998. begin
  999. if (I=1) or (IsAlpha(PrevC)=false) then
  1000. begin WordS:=''; LastWordStart:=I; end;
  1001. { if IsAlpha(C) then ForceConcat:=false;}
  1002. WordS:=WordS+C;
  1003. end
  1004. else
  1005. begin
  1006. WordS:=UpcaseStr(Trim(WordS));
  1007. if WordS<>'' then
  1008. if (WordS='$CAP') then
  1009. begin
  1010. if (Pass=0) then
  1011. if (Params[I]=' ') and (I<=High(Params)) then Params[I]:='_';
  1012. end else
  1013. if (WordS='$CAP_MSG') then
  1014. begin
  1015. if (Pass=2) then
  1016. if Consume('(')=false then Err:=I else
  1017. if ReadTill(S,')')=false then Err:=I else
  1018. begin
  1019. Consume(')');
  1020. I:=I+ReplacePart(LastWordStart,I-1,'')-1;
  1021. ToolFilter:=S;
  1022. CaptureToolTo:=capMessageWindow;
  1023. end;
  1024. end else
  1025. if (WordS='$CAP_EDIT') then
  1026. begin
  1027. if (Pass=3) then
  1028. begin
  1029. if Consume('(')=false then
  1030. I:=I+ReplacePart(LastWordStart,I-1,'')-1
  1031. else if ReadTill(S,')')=false then Err:=I else
  1032. begin
  1033. Consume(')');
  1034. I:=I+ReplacePart(LastWordStart,I-1,'')-1;
  1035. ToolOutput:=S;
  1036. end;
  1037. CaptureToolTo:=capEditWindow;
  1038. end;
  1039. end else
  1040. if (WordS='$COL') then
  1041. begin
  1042. if (Pass=1) then
  1043. begin
  1044. if W=nil then L:=0 else
  1045. L:=W^.Editor^.CurPos.X+1;
  1046. I:=I+ReplacePart(LastWordStart,I-1,IntToStr(L))-1;
  1047. end;
  1048. end else
  1049. if (WordS='$CONFIG') then
  1050. begin
  1051. if (Pass=1) then
  1052. I:=I+ReplacePart(LastWordStart,I-1,IniFileName)-1;
  1053. end else
  1054. if (WordS='$DIR') then
  1055. begin
  1056. if (Pass=2) then
  1057. if Consume('(')=false then Err:=I else
  1058. if ReadTill(S,')')=false then Err:=I else
  1059. begin
  1060. Consume(')');
  1061. FSplit(S,D,N,E);
  1062. L:=Pos(':',D);if L>0 then Delete(D,1,L);
  1063. I:=I+ReplacePart(LastWordStart,I-1,D)-1;
  1064. end;
  1065. end else
  1066. if (WordS='$DRIVE') then
  1067. begin
  1068. if (Pass=2) then
  1069. if Consume('(')=false then Err:=I else
  1070. if ReadTill(S,')')=false then Err:=I else
  1071. begin
  1072. Consume(')');
  1073. FSplit(S,D,N,E);
  1074. L:=Pos(':',D);
  1075. D:=copy(D,1,L);
  1076. I:=I+ReplacePart(LastWordStart,I-1,D)-1;
  1077. end;
  1078. end else
  1079. if (WordS='$EDNAME') then
  1080. begin
  1081. if (Pass=1) then
  1082. begin
  1083. if W=nil then S:='' else
  1084. S:=W^.Editor^.FileName;
  1085. I:=I+ReplacePart(LastWordStart,I-1,S)-1;
  1086. end;
  1087. end else
  1088. if (WordS='$EXENAME') then
  1089. begin
  1090. if (Pass=1) then
  1091. I:=I+ReplacePart(LastWordStart,I-1,EXEFile)-1;
  1092. end else
  1093. if (WordS='$EXT') then
  1094. begin
  1095. if (Pass=2) then
  1096. if Consume('(')=false then Err:=I else
  1097. if ReadTill(S,')')=false then Err:=I else
  1098. begin
  1099. Consume(')');
  1100. FSplit(S,D,N,E); E:=copy(E,2,High(E));
  1101. I:=I+ReplacePart(LastWordStart,I-1,E)-1;
  1102. end;
  1103. end else
  1104. if (WordS='$LINE') then
  1105. begin
  1106. if (Pass=1) then
  1107. begin
  1108. if W=nil then L:=0 else
  1109. L:=W^.Editor^.CurPos.Y+1;
  1110. I:=I+ReplacePart(LastWordStart,I-1,IntToStr(L))-1;
  1111. end;
  1112. end else
  1113. if (WordS='$NAME') then
  1114. begin
  1115. if (Pass=2) then
  1116. if Consume('(')=false then Err:=I else
  1117. if ReadTill(S,')')=false then Err:=I else
  1118. begin
  1119. Consume(')');
  1120. FSplit(S,D,N,E);
  1121. I:=I+ReplacePart(LastWordStart,I-1,N)-1;
  1122. end;
  1123. end else
  1124. if (WordS='$NAMEEXT') then
  1125. begin
  1126. if (Pass=2) then
  1127. if Consume('(')=false then Err:=I else
  1128. if ReadTill(S,')')=false then Err:=I else
  1129. begin
  1130. Consume(')');
  1131. FSplit(S,D,N,E);
  1132. I:=I+ReplacePart(LastWordStart,I-1,N+E)-1;
  1133. end;
  1134. end else
  1135. if (WordS='$NOSWAP') then
  1136. begin
  1137. if (Pass=1) then
  1138. begin
  1139. I:=I+ReplacePart(LastWordStart,I-1,'')-1;
  1140. CaptureToolTo:=capNoSwap;
  1141. end;
  1142. end else
  1143. if (WordS='$DRIVE') then
  1144. begin
  1145. if (Pass=2) then
  1146. if Consume('(')=false then Err:=I else
  1147. if ReadTill(S,')')=false then Err:=I else
  1148. begin
  1149. Consume(')');
  1150. FSplit(S,D,N,E);
  1151. L:=Pos(':',D); if L=0 then L:=-1;
  1152. D:=copy(D,1,L+1);
  1153. I:=I+ReplacePart(LastWordStart,I-1,D)-1;
  1154. end;
  1155. end else
  1156. if (WordS='$PROMPT') then
  1157. begin
  1158. if (Pass=3) then
  1159. if Params[I]='(' then
  1160. begin
  1161. if Consume('(')=false then Err:=I else
  1162. if ReadTill(S,')')=false then Err:=I else
  1163. begin
  1164. Consume(')');
  1165. if S='' then Err:=I-1 else
  1166. if CheckOnly=false then
  1167. if ExecutePromptDialog(S,S)=false then
  1168. Err:=I
  1169. else
  1170. I:=I+ReplacePart(LastWordStart,I-1,S)-1;
  1171. end;
  1172. end
  1173. else { just prompt for parms }
  1174. begin
  1175. I:=I+ReplacePart(LastWordStart,I-1,'')-1;
  1176. if CheckOnly=false then
  1177. begin
  1178. S:=copy(Params,I+1,High(Params));
  1179. if InputBox(dialog_programarguments, label_enterprogramargument,
  1180. S,High(Params)-I+1)=cmOK then
  1181. begin
  1182. ReplacePart(LastWordStart,255,S);
  1183. I:=255;
  1184. end
  1185. else
  1186. Err:=-1;
  1187. end;
  1188. end;
  1189. end else
  1190. if (WordS='$SAVE') then
  1191. begin
  1192. if (Pass=0) then
  1193. if (Params[I]=' ') and (I<=High(Params)) then Params[I]:='_';
  1194. end else
  1195. if (WordS='$SAVE_ALL') then
  1196. begin
  1197. if (Pass=2) then
  1198. begin
  1199. I:=I+ReplacePart(LastWordStart,I-1,'')-1;
  1200. Message(Application,evCommand,cmSaveAll,nil);
  1201. end;
  1202. end else
  1203. if (WordS='$SAVE_CUR') then
  1204. begin
  1205. if (Pass=2) then
  1206. begin
  1207. I:=I+ReplacePart(LastWordStart,I-1,'')-1;
  1208. Message(W,evCommand,cmSave,nil);
  1209. end;
  1210. end else
  1211. if (WordS='$SAVE_PROMPT') then
  1212. begin
  1213. if (Pass=2) then
  1214. begin
  1215. I:=I+ReplacePart(LastWordStart,I-1,'')-1;
  1216. if W<>nil then
  1217. if W^.Editor^.SaveAsk(true)=false then
  1218. Err:=-1;
  1219. end;
  1220. end else
  1221. if (WordS='$WRITEMSG') then
  1222. begin
  1223. if (Pass=2) then
  1224. if Consume('(')=false then Err:=I else
  1225. if ReadTill(S,')')=false then Err:=I else
  1226. begin
  1227. Consume(')');
  1228. I:=I+ReplacePart(LastWordStart,I-1,'')-1;
  1229. if CheckOnly=false then
  1230. WriteToolMessagesToFile(S);
  1231. end;
  1232. end else
  1233. if copy(WordS,1,1)='$' then
  1234. Err:=LastWordStart;
  1235. WordS:='';
  1236. end;
  1237. PrevC:=C;
  1238. Inc(I);
  1239. end;
  1240. end;
  1241. var Pass: sw_integer;
  1242. begin
  1243. W:=FirstEditorWindow;
  1244. Err:=0;
  1245. for Pass:=0 to 3 do
  1246. begin
  1247. ParseParams(Pass);
  1248. if Err<>0 then Break;
  1249. end;
  1250. if AbortTool then Err:=-1;
  1251. ParseToolParams:=Err;
  1252. end;
  1253. procedure InitToolProcessing;
  1254. begin
  1255. AbortTool:=false;
  1256. CaptureToolTo:=capNone;
  1257. ToolFilter:='';
  1258. ToolOutput:='';
  1259. end;
  1260. function ProcessMessageFile(const MsgFileName: string): boolean;
  1261. var OK,Done: boolean;
  1262. S: PBufStream;
  1263. C: char;
  1264. Sign: array[1..10] of char;
  1265. InFileName,InReference: boolean;
  1266. AddChar: boolean;
  1267. FileName,Line: string;
  1268. Row,Col: longint;
  1269. procedure AddLine;
  1270. begin
  1271. Row:=ord(Line[1])+ord(Line[2]) shl 8;
  1272. Col:=ord(Line[3])+ord(Line[4]) shl 8;
  1273. AddToolMessage(FileName,copy(Line,5,High(Line)),Row,Col);
  1274. end;
  1275. begin
  1276. New(S, Init(MsgFileName, stOpenRead, 4096));
  1277. OK:=(S<>nil) and (S^.Status=stOK);
  1278. if OK then S^.Read(Sign,SizeOf(Sign));
  1279. OK:=OK and (Sign=MsgFilterSign);
  1280. Done:=false;
  1281. InFileName:=false;
  1282. InReference:=false;
  1283. FileName:='';
  1284. Line:='';
  1285. while OK and (Done=false) do
  1286. begin
  1287. S^.Read(C,SizeOf(C));
  1288. OK:=(S^.Status=stOK);
  1289. AddChar:=false;
  1290. if OK then
  1291. case C of
  1292. #0 : if InFileName then
  1293. begin InFileName:=false end else
  1294. if InReference then
  1295. begin
  1296. if (length(Line)>4) then
  1297. begin
  1298. AddLine;
  1299. InReference:=false;
  1300. end
  1301. else
  1302. AddChar:=true;
  1303. end else
  1304. begin InFileName:=true; FileName:=''; end;
  1305. #1 : if InReference then AddChar:=true else
  1306. begin InReference:=true; Line:=''; end;
  1307. #127 : if InReference then AddChar:=true else
  1308. Done:=true;
  1309. else AddChar:=true;
  1310. end;
  1311. if AddChar then
  1312. if InFileName then
  1313. FileName:=FileName+C else
  1314. if InReference then
  1315. Line:=Line+C;
  1316. end;
  1317. if S<>nil then Dispose(S, Done);
  1318. ProcessMessageFile:=OK;
  1319. end;
  1320. procedure InitToolTempFiles;
  1321. begin
  1322. if not Assigned(ToolTempFiles) then
  1323. New(ToolTempFiles, Init(10,10));
  1324. end;
  1325. procedure DoneToolTempFiles;
  1326. procedure DeleteIt(P: PString);
  1327. begin
  1328. DeleteFile(GetStr(P));
  1329. end;
  1330. begin
  1331. if not Assigned(ToolTempFiles) then Exit;
  1332. {$ifndef DEBUG}
  1333. ToolTempFiles^.ForEach(@DeleteIt);
  1334. {$endif ndef DEBUG}
  1335. Dispose(ToolTempFiles, Done);
  1336. ToolTempFiles:=nil;
  1337. end;
  1338. constructor TToolMessage.Init(AModule: PString; ALine: string; ARow, ACol: sw_integer);
  1339. begin
  1340. inherited Init(0,ALine,AModule,ARow,ACol);
  1341. if LongestTool<Length(Aline)+Length(GetStr(AModule))+4 then
  1342. LongestTool:=Length(Aline)+Length(GetStr(AModule))+4;
  1343. end;
  1344. function TToolMessage.GetText(MaxLen: Sw_integer): string;
  1345. var S: string;
  1346. begin
  1347. if Module=nil then
  1348. S:=GetStr(Text)
  1349. else
  1350. S:=NameAndExtOf(GetModuleName)+
  1351. '('+IntToStr(Row)+'): '+GetStr(Text);
  1352. GetText:=copy(S,1,MaxLen);
  1353. end;
  1354. procedure AddToolCommand(Command: string);
  1355. begin
  1356. AddToolMessage('',Command,0,0);
  1357. LastToolMessageFocused:=ToolMessages^.At(ToolMessages^.Count-1);
  1358. end;
  1359. procedure AddToolMessage(ModuleName, Text: string; Row, Col: longint);
  1360. var MN: PString;
  1361. begin
  1362. if ToolMessages=nil then
  1363. New(ToolMessages, Init(500,1000));
  1364. if ToolModuleNames=nil then
  1365. New(ToolModuleNames, Init(50,100));
  1366. MN:=ToolModuleNames^.Add(ModuleName);
  1367. ToolMessages^.Insert(New(PToolMessage, Init(MN,Text,Row,Col)));
  1368. end;
  1369. procedure ClearToolMessages;
  1370. begin
  1371. If assigned(ToolMessages) then
  1372. ToolMessages^.FreeAll;
  1373. If assigned(ToolModuleNames) then
  1374. ToolModuleNames^.FreeAll;
  1375. LastToolMessageFocused:=nil;
  1376. LongestTool:=0;
  1377. end;
  1378. procedure DoneToolMessages;
  1379. begin
  1380. If assigned(ToolMessages) then
  1381. begin
  1382. Dispose(ToolMessages,Done);
  1383. ToolMessages:=nil;
  1384. end;
  1385. If assigned(ToolModuleNames) then
  1386. begin
  1387. Dispose(ToolModuleNames,Done);
  1388. ToolModuleNames:=nil;
  1389. end;
  1390. LastToolMessageFocused:=nil;
  1391. LongestTool:=0;
  1392. end;
  1393. procedure UpdateToolMessages;
  1394. begin
  1395. if Assigned(MessagesWindow) then
  1396. MessagesWindow^.Update;
  1397. end;
  1398. procedure TToolMessageListBox.Update;
  1399. var P: PMessageItem;
  1400. Idx: integer;
  1401. begin
  1402. P:=LastToolMessageFocused;
  1403. NewList(ToolMessages);
  1404. if assigned(HScrollBar) then
  1405. HScrollbar^.SetRange(0,LongestTool);
  1406. if (Range>0) and (P<>nil) then
  1407. begin
  1408. Idx:=List^.IndexOf(P);
  1409. if Idx>=0 then
  1410. begin
  1411. FocusItem(Idx);
  1412. DrawView;
  1413. end;
  1414. end;
  1415. DrawView;
  1416. end;
  1417. procedure TToolMessageListBox.NewList(AList: PCollection);
  1418. begin
  1419. if (List=ToolMessages) or (ToolMessages=nil) then
  1420. begin List:=nil; SetRange(0); end;
  1421. inherited NewList(AList);
  1422. end;
  1423. procedure TToolMessageListBox.Clear;
  1424. begin
  1425. ClearToolMessages;
  1426. Update;
  1427. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  1428. end;
  1429. function TToolMessageListBox.GetPalette: PPalette;
  1430. const
  1431. P: string[length(CBrowserListBox)] = CBrowserListBox;
  1432. begin
  1433. GetPalette:=@P;
  1434. end;
  1435. constructor TToolMessageListBox.Load(var S: TStream);
  1436. begin
  1437. inherited Load(S);
  1438. end;
  1439. procedure TToolMessageListBox.Store(var S: TStream);
  1440. var OL: PCollection;
  1441. begin
  1442. OL:=List;
  1443. New(List, Init(1,1));
  1444. inherited Store(S);
  1445. Dispose(List, Done);
  1446. List:=OL;
  1447. end;
  1448. destructor TToolMessageListBox.Done;
  1449. begin
  1450. HScrollBar:=nil; VScrollBar:=nil;
  1451. if List=ToolMessages then begin List:=nil; SetRange(0); end;
  1452. inherited Done;
  1453. end;
  1454. constructor TMessagesWindow.Init;
  1455. var R: TRect;
  1456. HSB,VSB: PScrollBar;
  1457. begin
  1458. Desktop^.GetExtent(R); R.A.Y:=R.B.Y-7;
  1459. inherited Init(R,dialog_messages,SearchFreeWindowNo);
  1460. HelpCtx:=hcMessagesWindow;
  1461. HSB:=StandardScrollBar(sbHorizontal+sbHandleKeyboard); Insert(HSB);
  1462. VSB:=StandardScrollBar(sbVertical+sbHandleKeyboard); Insert(VSB);
  1463. VSB^.SetStep(R.B.Y-R.A.Y-2,1);
  1464. HSB^.SetStep(R.B.X-R.A.X-2,1);
  1465. GetExtent(R); R.Grow(-1,-1);
  1466. New(MsgLB, Init(R, HSB, VSB));
  1467. Insert(MsgLB);
  1468. Update;
  1469. MessagesWindow:=@Self;
  1470. end;
  1471. procedure TMessagesWindow.Update;
  1472. begin
  1473. MsgLB^.Update;
  1474. end;
  1475. procedure TMessagesWindow.FocusItem(i : sw_integer);
  1476. begin
  1477. MsgLB^.FocusItem(i);
  1478. end;
  1479. procedure TMessagesWindow.HandleEvent(var Event: TEvent);
  1480. begin
  1481. case Event.What of
  1482. evBroadcast :
  1483. case Event.Command of
  1484. cmListFocusChanged :
  1485. if Event.InfoPtr=MsgLB then
  1486. begin
  1487. LastToolMessageFocused:=MsgLB^.List^.At(MsgLB^.Focused);
  1488. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  1489. end;
  1490. end;
  1491. end;
  1492. inherited HandleEvent(Event);
  1493. end;
  1494. procedure TMessagesWindow.SizeLimits(var Min, Max: TPoint);
  1495. begin
  1496. inherited SizeLimits(Min,Max);
  1497. Min.X:=20;
  1498. Min.Y:=4;
  1499. end;
  1500. function TMessagesWindow.GetPalette: PPalette;
  1501. const S: string[length(CBrowserWindow)] = CBrowserWindow;
  1502. begin
  1503. GetPalette:=@S;
  1504. end;
  1505. constructor TMessagesWindow.Load(var S: TStream);
  1506. begin
  1507. inherited Load(S);
  1508. GetSubViewPtr(S,MsgLB);
  1509. Update;
  1510. MessagesWindow:=@Self;
  1511. end;
  1512. procedure TMessagesWindow.Store(var S: TStream);
  1513. begin
  1514. inherited Store(S);
  1515. PutSubViewPtr(S,MsgLB);
  1516. end;
  1517. destructor TMessagesWindow.Done;
  1518. begin
  1519. MessagesWindow:=nil;
  1520. inherited Done;
  1521. end;
  1522. procedure RegisterFPTools;
  1523. begin
  1524. {$ifndef NOOBJREG}
  1525. RegisterType(RToolMessageListBox);
  1526. RegisterType(RMessagesWindow);
  1527. {$endif}
  1528. end;
  1529. {$ifdef DEBUG}
  1530. Procedure FpToolsDebugMessage(AFileName, AText : string; ALine, APos :string ;nrline,nrpos:sw_word);
  1531. begin
  1532. AddToolMessage(AFileName,AText,nrline,nrPos);
  1533. UpdateToolMessages;
  1534. end;
  1535. begin
  1536. DebugMessageS:=@FpToolsDebugMessage;
  1537. {$endif DEBUG}
  1538. END.