1 {
2 ***************************************************************************
3 * *
4 * This source is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This code is distributed in the hope that it will be useful, but *
10 * WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * General Public License for more details. *
13 * *
14 * A copy of the GNU General Public License is available on the World *
15 * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
16 * obtain it by writing to the Free Software Foundation, *
17 * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
18 * *
19 ***************************************************************************
20
21 Author: Mattias Gaertner
22
23 Abstract:
24 Defines the TExternalToolOptions which stores the settings of a single
25 external tool. (= Programfilename and parameters)
26 All TExternalToolOptions are stored in a TExternalToolList
27 (see exttooldialog.pas).
28 And this unit provides TExternalToolOptionDlg which is a dialog for editing
29 a single external tool.
30 }
31 unit ExtToolEditDlg;
32
33 {$mode objfpc}
34 {$H+}
35
36 {$I ide.inc}
37
38 interface
39
40 uses
41 {$IFDEF IDE_MEM_CHECK}
42 MemCheck,
43 {$ENDIF}
44 Classes, SysUtils, contnrs,
45 // LCL
46 LCLType, Controls, Forms, StdCtrls, Dialogs, LCLProc, ButtonPanel, EditBtn,
47 // LazUtils
48 FileUtil, LazFileUtils, LazUTF8, LazConfigStorage,
49 // Codetools
50 FileProcs,
51 // IdeIntf
52 IDEExternToolIntf, IDEHelpIntf, PropEdits, IDEDialogs, IDECommands, IDEUtils,
53 // IDE
54 TransferMacros, LazarusIDEStrConsts, EnvironmentOpts, KeyMapping;
55
56 const
57 ExternalToolOptionsVersion = 3;
58 // 3: changed ScanOutputForFPCMessages to parser SubToolFPC
59 // changed ScanOutputForMakeMessages to parser SubToolMake
60 type
61
62 { TExternalUserTool - the options of an external tool in the IDE menu Tools }
63
64 TExternalUserTool = class(TComponent)
65 private
66 FChangeStamp: integer;
67 fCmdLineParams: string;
68 FEnvironmentOverrides: TStringList;
69 fFilename: string;
70 FHideWindow: boolean;
71 FKey: word;
72 FParsers: TStrings;
73 FShift: TShiftState;
74 FShowConsole: boolean;
75 fTitle: string;
76 fWorkingDirectory: string;
77 fSavedChangeStamp: integer;
GetHasParsernull78 function GetHasParser(aName: string): boolean;
GetModifiednull79 function GetModified: boolean;
80 procedure SetChangeStamp(AValue: integer);
81 procedure SetCmdLineParams(AValue: string);
82 procedure SetEnvironmentOverrides(AValue: TStringList);
83 procedure SetFilename(AValue: string);
84 procedure SetHasParser(aName: string; AValue: boolean);
85 procedure SetHideWindow(AValue: boolean);
86 procedure SetModified(AValue: boolean);
87 procedure SetParsers(AValue: TStrings);
88 procedure SetShowConsole(AValue: boolean);
89 procedure SetTitle(AValue: string);
90 procedure SetWorkingDirectory(AValue: string);
91 public
92 constructor Create(AOwner: TComponent); override;
93 destructor Destroy; override;
94 procedure Clear;
Equalsnull95 function Equals(Obj: TObject): boolean; override;
96 procedure Assign(Source: TPersistent); override;
Loadnull97 function Load(Config: TConfigStorage; CfgVersion: integer): TModalResult; virtual;
Savenull98 function Save(Config: TConfigStorage): TModalResult; virtual;
99 procedure IncreaseChangeStamp; inline;
100 property CmdLineParams: string read fCmdLineParams write SetCmdLineParams;
101 property Filename: string read fFilename write SetFilename;
102 property Title: string read fTitle write SetTitle;
103 property WorkingDirectory: string read fWorkingDirectory write SetWorkingDirectory;
104 property EnvironmentOverrides: TStringList read FEnvironmentOverrides write SetEnvironmentOverrides;
105 property Parsers: TStrings read FParsers write SetParsers;
106 property HasParser[aName: string]: boolean read GetHasParser write SetHasParser;
107 property ShowConsole: boolean read FShowConsole write SetShowConsole;
108 property HideWindow: boolean read FHideWindow write SetHideWindow;
109 property Modified: boolean read GetModified write SetModified;
110 property ChangeStamp: integer read FChangeStamp write SetChangeStamp;
111 public
112 // these properties are saved in the keymappings, not in the config
113 property Key: word read FKey write FKey;
114 property Shift: TShiftState read FShift write FShift;
115 end;
116
117 { TExternalUserTools }
118
119 TExternalUserTools = class(TBaseExternalUserTools)
120 private
121 fItems: TObjectList; // list of TExternalUserTool
GetItemsnull122 function GetItems(Index: integer): TExternalUserTool; inline;
123 public
124 constructor Create; override;
125 destructor Destroy; override;
126 procedure Clear; inline;
Equalsnull127 function Equals(Obj: TObject): boolean; override;
128 procedure Assign(Src: TExternalUserTools);
Countnull129 function Count: integer; inline;
130 property Items[Index: integer]: TExternalUserTool read GetItems; default;
131 procedure Add(Item: TExternalUserTool);
132 procedure Insert(Index: integer; Item: TExternalUserTool);
133 procedure Delete(Index: integer);
134 procedure Move(CurIndex, NewIndex: integer);
135 // run
Runnull136 function Run(Index: integer; {%H-}ShowAbort: boolean): TModalResult;
137 // load/save
Loadnull138 function Load(Config: TConfigStorage): TModalResult;
Loadnull139 function Load(Config: TConfigStorage; const Path: string): TModalResult; override;
Savenull140 function Save(Config: TConfigStorage): TModalResult;
Savenull141 function Save(Config: TConfigStorage; const Path: string): TModalResult; override;
142 procedure LoadShortCuts(KeyCommandRelationList: TKeyCommandRelationList);
143 procedure SaveShortCuts(KeyCommandRelationList: TKeyCommandRelationList);
144 end;
145
146 var
147 ExternalUserTools: TExternalUserTools = nil;
148
149 type
150 { TExternalToolOptionDlg - the editor dialog for a single external tool }
151
152 TExternalToolOptionDlg = class(TForm)
153 ButtonPanel: TButtonPanel;
154 FileNameEdit: TFileNameEdit;
155 FilenameLabel: TLabel;
156 HideWindowCheckBox: TCheckBox;
157 KeyGroupBox: TGroupBox;
158 MacrosGroupbox: TGroupbox;
159 MacrosInsertButton: TButton;
160 MacrosListbox: TListbox;
161 MemoParameters: TMemo;
162 OptionsGroupBox: TGroupBox;
163 ParametersLabel: TLabel;
164 ScannersButton: TButton;
165 ScanOutputForFPCMessagesCheckBox: TCheckBox;
166 ScanOutputForMakeMessagesCheckBox: TCheckBox;
167 ShowConsoleCheckBox: TCheckBox;
168 TitleEdit: TEdit;
169 TitleLabel: TLabel;
170 WorkingDirEdit: TDirectoryEdit;
171 WorkingDirLabel: TLabel;
172 procedure FormCreate(Sender: TObject);
173 procedure FormDestroy(Sender: TObject);
174 procedure HelpButtonClick(Sender: TObject);
175 procedure MacrosInsertButtonClick(Sender: TObject);
176 procedure MacrosListboxClick(Sender: TObject);
177 procedure MacrosListboxDblClick(Sender: TObject);
178 procedure OKButtonClick(Sender: TObject);
179 procedure ShowConsoleCheckBoxChange(Sender: TObject);
180 private
181 fAllKeys: TKeyCommandRelationList;
182 fOptions: TExternalUserTool;
183 fTransferMacros: TTransferMacroList;
184 fScanners: TStrings;
185 fKeyBox: TShortCutGrabBox;
186 procedure FillMacroList;
KeyConflictsnull187 function KeyConflicts(Key:word; Shift:TShiftState): TModalResult;
188 procedure LoadFromOptions;
189 procedure SaveToOptions;
190 procedure UpdateButtons;
ScannersToStringnull191 function ScannersToString(List: TStrings): string;
192 procedure SetComboBox(AComboBox: TComboBox; const AValue: string);
193 procedure SetOptions(TheOptions: TExternalUserTool);
194 procedure SetTransferMacros(TransferMacroList: TTransferMacroList);
195 public
196 property Options: TExternalUserTool read fOptions write SetOptions;
197 property MacroList: TTransferMacroList
198 read fTransferMacros write SetTransferMacros;
199 end;
200
201
ShowExtToolOptionDlgnull202 function ShowExtToolOptionDlg(TransferMacroList: TTransferMacroList;
203 ExternalToolMenuItem: TExternalUserTool;
204 AllKeys: TKeyCommandRelationList):TModalResult;
205
206 implementation
207
208 {$R *.lfm}
209
ShowExtToolOptionDlgnull210 function ShowExtToolOptionDlg(TransferMacroList: TTransferMacroList;
211 ExternalToolMenuItem: TExternalUserTool;
212 AllKeys: TKeyCommandRelationList):TModalResult;
213 var
214 ExternalToolOptionDlg: TExternalToolOptionDlg;
215 begin
216 Result:=mrCancel;
217 ExternalToolOptionDlg:=TExternalToolOptionDlg.Create(nil);
218 try
219 ExternalToolOptionDlg.fAllKeys:=AllKeys;
220 ExternalToolOptionDlg.Options:=ExternalToolMenuItem;
221 ExternalToolOptionDlg.MacroList:=TransferMacroList;
222 Result:=ExternalToolOptionDlg.ShowModal;
223 if Result=mrOk then
224 ExternalToolMenuItem.Assign(ExternalToolOptionDlg.Options);
225 finally
226 ExternalToolOptionDlg.Free;
227 end;
228 end;
229
230 { TExternalUserTool }
231
232 // inline
233 procedure TExternalUserTool.IncreaseChangeStamp;
234 begin
235 CTIncreaseChangeStamp(FChangeStamp);
236 end;
237
TExternalUserTool.GetModifiednull238 function TExternalUserTool.GetModified: boolean;
239 begin
240 Result:=FChangeStamp=fSavedChangeStamp;
241 end;
242
GetHasParsernull243 function TExternalUserTool.GetHasParser(aName: string): boolean;
244 begin
245 Result:=IndexInStringList(FParsers,cstCaseInsensitive,aName)>=0;
246 end;
247
248 procedure TExternalUserTool.SetChangeStamp(AValue: integer);
249 begin
250 if FChangeStamp=AValue then Exit;
251 FChangeStamp:=AValue;
252 end;
253
254 procedure TExternalUserTool.SetCmdLineParams(AValue: string);
255 begin
256 AValue:=UTF8Trim(AValue,[]);
257 if fCmdLineParams=AValue then Exit;
258 fCmdLineParams:=AValue;
259 IncreaseChangeStamp;
260 end;
261
262 procedure TExternalUserTool.SetEnvironmentOverrides(AValue: TStringList);
263 begin
264 if (FEnvironmentOverrides=AValue) or FEnvironmentOverrides.Equals(AValue) then Exit;
265 FEnvironmentOverrides.Assign(AValue);
266 IncreaseChangeStamp;
267 end;
268
269 procedure TExternalUserTool.SetFilename(AValue: string);
270 begin
271 AValue:=TrimFilename(AValue);
272 if fFilename=AValue then Exit;
273 fFilename:=AValue;
274 IncreaseChangeStamp;
275 end;
276
277 procedure TExternalUserTool.SetHasParser(aName: string; AValue: boolean);
278 var
279 i: Integer;
280 begin
281 i:=IndexInStringList(FParsers,cstCaseInsensitive,aName);
282 if i>=0 then begin
283 if AValue then exit;
284 FParsers.Delete(i);
285 end else begin
286 if not AValue then exit;
287 FParsers.Add(aName);
288 end;
289 IncreaseChangeStamp;
290 end;
291
292 procedure TExternalUserTool.SetHideWindow(AValue: boolean);
293 begin
294 if FHideWindow=AValue then Exit;
295 FHideWindow:=AValue;
296 IncreaseChangeStamp;
297 end;
298
299 procedure TExternalUserTool.SetModified(AValue: boolean);
300 begin
301 if AValue then
302 IncreaseChangeStamp
303 else
304 fSavedChangeStamp:=FChangeStamp;
305 end;
306
307 procedure TExternalUserTool.SetParsers(AValue: TStrings);
308 begin
309 if (FParsers=AValue) or FParsers.Equals(AValue) then Exit;
310 FParsers.Assign(AValue);
311 IncreaseChangeStamp;
312 end;
313
314 procedure TExternalUserTool.SetShowConsole(AValue: boolean);
315 begin
316 if FShowConsole=AValue then Exit;
317 FShowConsole:=AValue;
318 IncreaseChangeStamp;
319 end;
320
321 procedure TExternalUserTool.SetTitle(AValue: string);
322 begin
323 AValue:=UTF8Trim(AValue,[]);
324 if fTitle=AValue then Exit;
325 fTitle:=AValue;
326 IncreaseChangeStamp;
327 end;
328
329 procedure TExternalUserTool.SetWorkingDirectory(AValue: string);
330 begin
331 AValue:=TrimFilename(AValue);
332 if fWorkingDirectory=AValue then Exit;
333 fWorkingDirectory:=AValue;
334 IncreaseChangeStamp;
335 end;
336
337 constructor TExternalUserTool.Create(AOwner: TComponent);
338 begin
339 inherited Create(AOwner);
340 FEnvironmentOverrides:=TStringList.Create;
341 FParsers:=TStringList.Create;
342 fSavedChangeStamp:=CTInvalidChangeStamp;
343 Clear;
344 end;
345
346 destructor TExternalUserTool.Destroy;
347 begin
348 FreeAndNil(FEnvironmentOverrides);
349 FreeAndNil(FParsers);
350 inherited Destroy;
351 end;
352
353 procedure TExternalUserTool.Clear;
354 begin
355 CmdLineParams:='';
356 if FEnvironmentOverrides.Count>0 then
357 begin
358 IncreaseChangeStamp;
359 FEnvironmentOverrides.Clear;
360 end;
361 Filename:='';
362 if FParsers.Count>0 then
363 begin
364 FParsers.Clear;
365 IncreaseChangeStamp;
366 end;
367 Title:='';
368 WorkingDirectory:='';
369 ShowConsole:=false;
370 HideWindow:=true;
371 end;
372
Equalsnull373 function TExternalUserTool.Equals(Obj: TObject): boolean;
374 var
375 Src: TExternalUserTool;
376 begin
377 if Obj is TExternalUserTool then begin
378 Src:=TExternalUserTool(Obj);
379 Result:=(CmdLineParams=Src.CmdLineParams)
380 and EnvironmentOverrides.Equals(Src.EnvironmentOverrides)
381 and (Filename=Src.Filename)
382 and Parsers.Equals(Src.Parsers)
383 and (ShowConsole=Src.ShowConsole)
384 and (HideWindow=Src.HideWindow)
385 and (Title=Src.Title)
386 and (WorkingDirectory=Src.WorkingDirectory)
387 and (Key=Src.Key)
388 and (Shift=Src.Shift);
389 end else
390 Result:=inherited;
391 end;
392
393 procedure TExternalUserTool.Assign(Source: TPersistent);
394 var
395 Src: TExternalUserTool;
396 begin
397 if Equals(Source) then exit;
398 if Source is TExternalUserTool then begin
399 Src:=TExternalUserTool(Source);
400 CmdLineParams:=Src.CmdLineParams;
401 WorkingDirectory:=Src.WorkingDirectory;
402 EnvironmentOverrides:=Src.EnvironmentOverrides;
403 Filename:=Src.Filename;
404 Parsers:=Src.Parsers;
405 ShowConsole:=Src.ShowConsole;
406 HideWindow:=Src.HideWindow;
407 Title:=Src.Title;
408 Key:=Src.Key;
409 Shift:=Src.Shift;
410 end else
411 inherited;
412 end;
413
Loadnull414 function TExternalUserTool.Load(Config: TConfigStorage; CfgVersion: integer
415 ): TModalResult;
416 begin
417 Clear;
418 fTitle:=Config.GetValue('Title/Value','');
419 fFilename:=Config.GetValue('Filename/Value','');
420 fCmdLineParams:=Config.GetValue('CmdLineParams/Value','');
421 fWorkingDirectory:=Config.GetValue('WorkingDirectory/Value','');
422 Config.GetValue('EnvironmentOverrides/',FEnvironmentOverrides);
423 ShowConsole:=Config.GetValue('ShowConsole/Value',false);
424 HideWindow:=Config.GetValue('HideWindow/Value',true);
425
426 if CfgVersion<3 then
427 begin
428 if Config.GetValue('ScanOutputForFPCMessages/Value',false) then
429 FParsers.Add(SubToolFPC);
430 if Config.GetValue('ScanOutputForMakeMessages/Value',false) then
431 FParsers.Add(SubToolMake);
432 if Config.GetValue('ShowAllOutput/Value',false) then
433 FParsers.Add(SubToolDefault);
434 end else
435 Config.GetValue('Scanners/',FParsers);
436
437 Modified:=false;
438 Result:=mrOk;
439 end;
440
Savenull441 function TExternalUserTool.Save(Config: TConfigStorage): TModalResult;
442 begin
443 Config.SetDeleteValue('Title/Value',Title,'');
444 Config.SetDeleteValue('Filename/Value',Filename,'');
445 Config.SetDeleteValue('CmdLineParams/Value',CmdLineParams,'');
446 Config.SetDeleteValue('WorkingDirectory/Value',WorkingDirectory,'');
447 Config.SetValue('EnvironmentOverrides/',FEnvironmentOverrides);
448 Config.SetValue('Scanners/',FParsers);
449 Config.SetDeleteValue('ShowConsole/Value',ShowConsole,false);
450 Config.SetDeleteValue('HideWindow/Value',HideWindow,true);
451 Modified:=false;
452 Result:=mrOk;
453 end;
454
455 { TExternalUserTools }
456
457 // inline
TExternalUserTools.Countnull458 function TExternalUserTools.Count: integer;
459 begin
460 Result:=fItems.Count;
461 end;
462
463 // inline
TExternalUserTools.GetItemsnull464 function TExternalUserTools.GetItems(Index: integer): TExternalUserTool;
465 begin
466 Result:=TExternalUserTool(fItems[Index]);
467 end;
468
469 // inline
470 procedure TExternalUserTools.Clear;
471 begin
472 fItems.Clear;
473 end;
474
475 constructor TExternalUserTools.Create;
476 begin
477 fItems:=TObjectList.Create(true);
478 end;
479
480 destructor TExternalUserTools.Destroy;
481 begin
482 if ExternalUserTools=Self then
483 ExternalUserTools:=nil;
484 Clear;
485 FreeAndNil(fItems);
486 inherited Destroy;
487 end;
488
Equalsnull489 function TExternalUserTools.Equals(Obj: TObject): boolean;
490 var
491 Src: TExternalUserTools;
492 i: Integer;
493 begin
494 if Obj=Self then exit(true);
495 if Obj is TExternalUserTools then begin
496 Src:=TExternalUserTools(Obj);
497 Result:=false;
498 if Count<>Src.Count then exit;
499 for i:=0 to Count-1 do
500 if not Items[i].Equals(Src[i]) then exit;
501 Result:=true;
502 end else
503 Result:=inherited Equals(Obj);
504 end;
505
506 procedure TExternalUserTools.Assign(Src: TExternalUserTools);
507 var
508 Item: TExternalUserTool;
509 i: Integer;
510 begin
511 if Equals(Src) then exit;
512 Clear;
513 for i:=0 to Src.Count-1 do begin
514 Item:=TExternalUserTool.Create(nil);
515 Item.Assign(Src[i]);
516 Add(Item);
517 end;
518 end;
519
520 procedure TExternalUserTools.Add(Item: TExternalUserTool);
521 begin
522 fItems.Add(Item);
523 end;
524
525 procedure TExternalUserTools.Insert(Index: integer;
526 Item: TExternalUserTool);
527 begin
528 fItems.Insert(Index,Item);
529 end;
530
531 procedure TExternalUserTools.Delete(Index: integer);
532 begin
533 fItems.Delete(Index);
534 end;
535
536 procedure TExternalUserTools.Move(CurIndex, NewIndex: integer);
537 begin
538 fItems.Move(CurIndex,NewIndex);
539 end;
540
TExternalUserTools.Runnull541 function TExternalUserTools.Run(Index: integer; ShowAbort: boolean
542 ): TModalResult;
543 var
544 Item: TExternalUserTool;
545 Tool: TIDEExternalToolOptions;
546 begin
547 Result:=mrCancel;
548 Item:=Items[Index];
549
550 Tool:=TIDEExternalToolOptions.Create;
551 try
552 Tool.Title:=Item.Title;
553 Tool.Hint:='External tool '+IntToStr(Index+1);
554 Tool.Executable:=Item.Filename;
555 Tool.WorkingDirectory:=Item.WorkingDirectory;
556 Tool.CmdLineParams:=Item.CmdLineParams;
557 Tool.EnvironmentOverrides:=Item.EnvironmentOverrides;
558 Tool.Parsers:=Item.Parsers;
559 Tool.ShowConsole:=Item.ShowConsole;
560 Tool.HideWindow:=Item.HideWindow;
561 Tool.ResolveMacros:=true;
562 if not RunExternalTool(Tool) then exit;
563 finally
564 Tool.Free;
565 end;
566 end;
567
Loadnull568 function TExternalUserTools.Load(Config: TConfigStorage): TModalResult;
569 var
570 i: integer;
571 NewTool: TExternalUserTool;
572 NewCount: Integer;
573 CfgVersion: Integer;
574 begin
575 Clear;
576 NewCount:=Config.GetValue('Count',0);
577 CfgVersion:=Config.GetValue('Version',0);
578 for i:=1 to NewCount do begin
579 NewTool:=TExternalUserTool.Create(nil);
580 fItems.Add(NewTool);
581 Config.AppendBasePath('Tool'+IntToStr(i)+'/');
582 try
583 if NewTool.Load(Config,CfgVersion)<>mrOk then exit;
584 finally
585 Config.UndoAppendBasePath;
586 end;
587 end;
588 Result:=mrOk;
589 end;
590
Loadnull591 function TExternalUserTools.Load(Config: TConfigStorage; const Path: string
592 ): TModalResult;
593 begin
594 if Path<>'' then
595 Config.AppendBasePath(Path);
596 try
597 Result:=Load(Config);
598 finally
599 if Path<>'' then
600 Config.UndoAppendBasePath;
601 end;
602 end;
603
TExternalUserTools.Savenull604 function TExternalUserTools.Save(Config: TConfigStorage): TModalResult;
605 var
606 i: integer;
607 begin
608 Config.SetValue('Version',ExternalToolOptionsVersion);
609 Config.SetDeleteValue('Count',Count,0);
610 for i:=1 to Count do begin
611 Config.AppendBasePath('Tool'+IntToStr(i)+'/');
612 try
613 if Items[i-1].Save(Config)<>mrOk then exit;
614 finally
615 Config.UndoAppendBasePath;
616 end;
617 end;
618 Result:=mrOk;
619 end;
620
TExternalUserTools.Savenull621 function TExternalUserTools.Save(Config: TConfigStorage; const Path: string
622 ): TModalResult;
623 begin
624 if Path<>'' then
625 Config.AppendBasePath(Path);
626 try
627 Result:=Save(Config);
628 finally
629 if Path<>'' then
630 Config.UndoAppendBasePath;
631 end;
632 end;
633
634 procedure TExternalUserTools.LoadShortCuts(
635 KeyCommandRelationList: TKeyCommandRelationList);
636 var
637 i: integer;
638 KeyCommandRelation: TKeyCommandRelation;
639 begin
640 //debugln(['TExternalUserTools.LoadShortCuts ',KeyCommandRelationList.ExtToolCount,' ',Count]);
641 KeyCommandRelationList.ExtToolCount:=Count;
642 for i:=0 to Count-1 do begin
643 KeyCommandRelation:=KeyCommandRelationList.FindByCommand(ecExtToolFirst+i);
644 //debugln(['TExternalUserTools.LoadShortCuts ',i,'/',Count,' ',KeyCommandRelation.Name]);
645 if KeyCommandRelation<>nil then begin
646 Items[i].Key:=KeyCommandRelation.ShortcutA.Key1;
647 Items[i].Shift:=KeyCommandRelation.ShortcutA.Shift1;
648 end else begin
649 Items[i].Key:=VK_UNKNOWN;
650 Items[i].Shift:=[];
651 end;
652 end;
653 end;
654
655 procedure TExternalUserTools.SaveShortCuts(
656 KeyCommandRelationList: TKeyCommandRelationList);
657 var
658 i: integer;
659 KeyCommandRelation: TKeyCommandRelation;
660 begin
661 //debugln(['TExternalUserTools.SaveShortCuts ',KeyCommandRelationList.ExtToolCount,' ',Count]);
662 KeyCommandRelationList.ExtToolCount:=Count;
663 for i:=0 to Count-1 do begin
664 KeyCommandRelation:=KeyCommandRelationList.FindByCommand(ecExtToolFirst+i);
665 //debugln(['TExternalUserTools.SaveShortCuts ',i,'/',Count,' ',KeyCommandRelation.Name]);
666 if KeyCommandRelation<>nil then begin
667 KeyCommandRelation.ShortcutA:=IDEShortCut(Items[i].Key,Items[i].Shift,
668 VK_UNKNOWN,[]);
669 end else begin
670 DebugLn('[TExternalToolMenuItems.SaveShortCuts] Error: '
671 +'unable to save shortcut for external tool "',Items[i].Title,'"');
672 end;
673 end;
674 end;
675
676 { TExternalToolOptionDlg }
677
678 procedure TExternalToolOptionDlg.LoadFromOptions;
679 begin
680 TitleEdit.Text:=fOptions.Title;
681 FilenameEdit.Text:=fOptions.Filename;
682 MemoParameters.Lines.Text:=fOptions.CmdLineParams;
683 WorkingDirEdit.Text:=fOptions.WorkingDirectory;
684 fKeyBox.Key:=fOptions.Key;
685 fKeyBox.ShiftState:=fOptions.Shift;
686 ScanOutputForFPCMessagesCheckBox.Checked:=fOptions.HasParser[SubToolFPC];
687 ScanOutputForMakeMessagesCheckBox.Checked:=fOptions.HasParser[SubToolMake];
688 ShowConsoleCheckBox.Checked:=FOptions.ShowConsole;
689 HideWindowCheckBox.Checked:=FOptions.HideWindow;
690 fScanners.Assign(fOptions.Parsers);
691 UpdateButtons;
692 end;
693
694 procedure TExternalToolOptionDlg.SaveToOptions;
695 begin
696 fOptions.Title:=TitleEdit.Text;
697 fOptions.Filename:=FilenameEdit.Text;
698 fOptions.CmdLineParams:=MemoParameters.Lines.Text;
699 fOptions.WorkingDirectory:=WorkingDirEdit.Text;
700 fOptions.Key:=fKeyBox.Key;
701 fOptions.Shift:=fKeyBox.ShiftState;
702 FOptions.ShowConsole := ShowConsoleCheckBox.Checked;
703 FOptions.HideWindow := HideWindowCheckBox.Checked;
704 fOptions.HasParser[SubToolFPC]:=ScanOutputForFPCMessagesCheckBox.Checked;
705 fOptions.HasParser[SubToolMake]:=ScanOutputForMakeMessagesCheckBox.Checked;
706 end;
707
708 procedure TExternalToolOptionDlg.UpdateButtons;
709 begin
710 ScannersButton.Visible:=false;
711 {$IFDEF Windows}
712 HideWindowCheckBox.Visible:=true;
713 ShowConsoleCheckBox.Visible:=true;
714 {$ENDIF}
715 end;
716
TExternalToolOptionDlg.ScannersToStringnull717 function TExternalToolOptionDlg.ScannersToString(List: TStrings): string;
718 var
719 i: Integer;
720 begin
721 if (List=nil) or (List.Count=0) then begin
722 Result:='none';
723 end else begin
724 Result:='';
725 for i:=0 to List.Count-1 do begin
726 if Result<>'' then
727 Result:=Result+',';
728 Result:=Result+List[i];
729 if length(Result)>20 then begin
730 Result:=copy(Result,1,20);
731 break;
732 end;
733 end;
734 end;
735 end;
736
737 procedure TExternalToolOptionDlg.FormCreate(Sender: TObject);
738 begin
739 fScanners:=TStringList.Create;
740 Caption:=lisEdtExtToolEditTool;
741 TitleLabel.Caption:=dlgPOTitle;
742 FilenameLabel.Caption:=lisEdtExtToolProgramfilename;
743 FilenameEdit.ButtonHint:=lisClickHereToBrowseTheFileHint;
744
745 FilenameEdit.DialogTitle:=lisSelectFile;
746 FilenameEdit.Filter:=dlgFilterAll+' ('+GetAllFilesMask+')|'+GetAllFilesMask
747 +'|'+dlgFilterPrograms+' (*.exe)|*.exe';
748
749 ParametersLabel.Caption:=lisEdtExtToolParameters;
750 WorkingDirLabel.Caption:=lisEdtExtToolWorkingDirectory;
751 OptionsGroupBox.Caption:=lisLazBuildOptions;
752
753 with ScanOutputForFPCMessagesCheckBox do
754 Caption:=lisEdtExtToolScanOutputForFreePascalCompilerMessages;
755 with ScanOutputForMakeMessagesCheckBox do
756 Caption:=lisEdtExtToolScanOutputForMakeMessages;
757 ShowConsoleCheckBox.Caption:=lisShowConsole;
758 ShowConsoleCheckBox.Hint:=lisOnlyAvailableOnWindowsRunToolInANewConsole;
759 HideWindowCheckBox.Caption:=lisHideWindow;
760 HideWindowCheckBox.Hint:=lisOnlyAvailableOnWindowsRunTheToolHidden;
761
762 with KeyGroupBox do
763 Caption:=lisEdtExtToolKey;
764
765 fKeyBox:=TShortCutGrabBox.Create(Self);
766 with fKeyBox do begin
767 Name:='fKeyBox';
768 Align:=alClient;
769 BorderSpacing.Around:=6;
770 Parent:=KeyGroupBox;
771 end;
772
773 with MacrosGroupbox do
774 Caption:=lisEdtExtToolMacros;
775
776 with MacrosInsertButton do
777 Caption:=lisAdd;
778
779 ButtonPanel.OKButton.Caption:=lisMenuOk;
780 ButtonPanel.HelpButton.Caption:=lisMenuHelp;
781 ButtonPanel.CancelButton.Caption:=lisCancel;
782
783 fOptions:=TExternalUserTool.Create(nil);
784 end;
785
786 procedure TExternalToolOptionDlg.FormDestroy(Sender: TObject);
787 begin
788 FreeAndNil(fOptions);
789 FreeAndNil(fScanners);
790 end;
791
792 procedure TExternalToolOptionDlg.HelpButtonClick(Sender: TObject);
793 begin
794 LazarusHelp.ShowHelpForIDEControl(Self);
795 end;
796
797 procedure TExternalToolOptionDlg.SetOptions(TheOptions: TExternalUserTool);
798 begin
799 if fOptions=TheOptions then exit;
800 fOptions.Assign(TheOptions);
801 LoadFromOptions;
802 end;
803
804 procedure TExternalToolOptionDlg.SetTransferMacros(
805 TransferMacroList: TTransferMacroList);
806 begin
807 if fTransferMacros=TransferMacroList then exit;
808 fTransferMacros:=TransferMacroList;
809 if MacrosListbox=nil then exit;
810 FillMacroList;
811 end;
812
813 procedure TExternalToolOptionDlg.FillMacroList;
814 var i: integer;
815 begin
816 MacrosListbox.Items.BeginUpdate;
817 MacrosListbox.Items.Clear;
818 if fTransferMacros<>nil then begin
819 for i:=0 to fTransferMacros.Count-1 do begin
nilnull820 if fTransferMacros[i].MacroFunction=nil then begin
821 MacrosListbox.Items.Add('$('+fTransferMacros[i].Name+') - '
822 +fTransferMacros[i].Description);
823 end else begin
824 MacrosListbox.Items.Add('$'+fTransferMacros[i].Name+'() - '
825 +fTransferMacros[i].Description);
826 end;
827 end;
828 end;
829 MacrosListbox.Items.EndUpdate;
830 end;
831
KeyConflictsnull832 function TExternalToolOptionDlg.KeyConflicts(Key: word; Shift: TShiftState
833 ): TModalResult;
834 type
835 TConflictType = (ctNone,ctConflictKeyA,ctConflictKeyB);
836 var
837 i: Integer;
838 ct:TConflictType;
839 CurName: TCaption;
840 ConflictName: String;
841 begin
842 Result:=mrOK;
843 // look if we have already this key
844 if Key=VK_UNKNOWN then
845 exit;
846 i:=0;
847 for i:=0 to fAllKeys.RelationCount-1 do
848 begin
849 with fAllKeys.Relations[i] do
850 begin
851 ct:=ctnone;
852 if (ShortcutA.Key1=Key) and (ShortcutA.Shift1=Shift) then
853 ct:=ctConflictKeyA
854 else if (ShortcutB.Key1=Key) and (ShortcutB.Shift1=Shift) then
855 ct:=ctConflictKeyB;
856 if (ct<>ctNone) then begin
857 CurName:=TitleEdit.Text;
858 ConflictName:=GetCategoryAndName;
859 if ct=ctConflictKeyA then
860 ConflictName:=ConflictName
861 +' ('+KeyAndShiftStateToEditorKeyString(ShortcutA)+')'
862 else
863 ConflictName:=ConflictName
864 +' ('+KeyAndShiftStateToEditorKeyString(ShortcutB)+')';
865 case IDEMessageDialog(lisPEConflictFound,
866 Format(lisTheKeyIsAlreadyAssignedToRemoveTheOldAssignmentAnd,
867 [KeyAndShiftStateToKeyString(Key,Shift), LineEnding,
868 ConflictName, LineEnding, LineEnding, CurName]),
869 mtConfirmation, [mbYes, mbNo, mbCancel])
870 of
871 mrYes: Result:=mrOK;
872 mrCancel: Result:=mrCancel;
873 else Result:=mrRetry;
874 end;
875 if Result=mrOK then begin
876 if (ct=ctConflictKeyA) then
877 ShortcutA:=ShortcutB;
878 ClearShortcutB;
879 end
880 else
881 break;
882 end;
883 end;
884 end;
885 end;
886
887 procedure TExternalToolOptionDlg.SetComboBox(
888 AComboBox: TComboBox; const AValue: string);
889 var i: integer;
890 begin
891 i:=AComboBox.Items.IndexOf(AValue);
892 if i>=0 then
893 AComboBox.ItemIndex:=i
894 else begin
895 AComboBox.Items.Add(AValue);
896 AComboBox.ItemIndex:=AComboBox.Items.IndexOf(AValue);
897 end;
898 end;
899
900 procedure TExternalToolOptionDlg.MacrosInsertButtonClick(Sender: TObject);
901 var i, ALine: integer;
902 s, AStr: string;
903 begin
904 i:=MacrosListbox.ItemIndex;
905 if i<0 then exit;
nilnull906 if fTransferMacros[i].MacroFunction=nil then
907 s:='$('+fTransferMacros[i].Name+')'
908 else
909 s:='$'+fTransferMacros[i].Name+'()';
910 ALine := MemoParameters.CaretPos.Y;
911 if ALine >= MemoParameters.Lines.Count then
912 MemoParameters.Lines.Add('');
913 AStr := MemoParameters.Lines[Aline];
914 MemoParameters.Lines[Aline] := AStr + s;
915 end;
916
917 procedure TExternalToolOptionDlg.MacrosListboxClick(Sender: TObject);
918 begin
919 MacrosInsertButton.Enabled:=(MacrosListbox.ItemIndex>=0);
920 end;
921
922 procedure TExternalToolOptionDlg.MacrosListboxDblClick(Sender: TObject);
923 begin
924 MacrosInsertButtonClick(nil);
925 end;
926
927 procedure TExternalToolOptionDlg.OKButtonClick(Sender: TObject);
928 begin
929 case KeyConflicts(fKeyBox.Key,fKeyBox.ShiftState) of
930 mrCancel: begin
931 debugln('TExternalToolOptionDlg.OkButtonClick KeyConflicts failed for key1');
932 ModalResult:=mrCancel;
933 exit;
934 end;
935 mrRetry: begin
936 ModalResult:=mrNone;
937 exit;
938 end;
939 end;
940 if (TitleEdit.Text<>'') and (FilenameEdit.Text<>'') then
941 SaveToOptions
942 else begin
943 IDEMessageDialog(lisEdtExtToolTitleAndFilenameRequired,
944 lisEdtExtToolAValidToolNeedsAtLeastATitleAndAFilename,
945 mtError, [mbCancel]);
946 ModalResult:=mrCancel;
947 end;
948 end;
949
950 procedure TExternalToolOptionDlg.ShowConsoleCheckBoxChange(Sender: TObject);
951 begin
952 if ShowConsoleCheckBox.Checked then
953 HideWindowCheckBox.Checked:=false;
954 end;
955
956 initialization
957 ExternalUserToolsClass := TExternalUserTools;
958
959 end.
960