fptools.pas 45 KB

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