fptools.pas 44 KB

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