fptools.pas 44 KB

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