/components/h2pas/h2pasdlg.pas

http://github.com/graemeg/lazarus · Pascal · 1290 lines · 1104 code · 122 blank · 64 comment · 103 complexity · 3b01867bc96bb4866217dad558d80cc3 MD5 · raw file

  1. { Copyright (C) 2006 Mattias Gaertner
  2. This source is free software; you can redistribute it and/or modify it under
  3. the terms of the GNU General Public License as published by the Free
  4. Software Foundation; either version 2 of the License, or (at your option)
  5. any later version.
  6. This code is distributed in the hope that it will be useful, but WITHOUT ANY
  7. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  9. details.
  10. A copy of the GNU General Public License is available on the World Wide Web
  11. at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
  12. to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  13. MA 02111-1307, USA.
  14. }
  15. unit H2PasDlg;
  16. {$mode objfpc}{$H+}
  17. interface
  18. uses
  19. Classes, SysUtils, LCLProc, LCLType, LResources, Forms, Controls, Graphics,
  20. Dialogs, ComCtrls, Buttons, StdCtrls, ExtCtrls,
  21. LazConfigStorage, LazFileUtils, LazFileCache, SynEdit,
  22. FileProcs, IDEMsgIntf, MenuIntf, IDECommands, BaseIDEIntf,
  23. IDEDialogs, LazIDEIntf, SrcEditorIntf, IDEExternToolIntf, CompOptsIntf,
  24. IDETextConverter, H2PasStrConsts, H2PasConvert, IDETextConvListEdit;
  25. type
  26. { TH2PasDialog }
  27. TH2PasDialog = class(TForm)
  28. MergeAllCHeadersExceptCurrentButton: TButton;
  29. MergeFileCheckBox: TCheckBox;
  30. FileInfoMemo: TMemo;
  31. FileStateImageList: TImageList;
  32. MoveFileDownButton: TButton;
  33. MoveFileUpButton: TButton;
  34. ConvertAndBuildButton: TButton;
  35. FileInfoGroupBox: TGroupBox;
  36. MainPageControl: TPageControl;
  37. AddIncludedCHeaderFilesButton: TButton;
  38. // c header files
  39. FilesTabSheet: TTabSheet;
  40. CHeaderFilesSplitter1: TSplitter;
  41. AddCHeadersButton: TButton;
  42. DisableAllCHeadersButton: TButton;
  43. EnableAllCHeadersButton: TButton;
  44. DeleteCHeadersButton: TButton;
  45. CHeaderFilesCheckTreeView: TTreeView;
  46. // pre h2pas
  47. PreH2PasTabSheet: TTabSheet;
  48. PreH2PasGroupBox: TGroupBox;
  49. PreH2PasEdit: TTextConvListEditor;
  50. // h2pas
  51. h2pasOptionsTabSheet: TTabSheet;
  52. h2pasOptionsCheckGroup: TCheckGroup;
  53. LibnameEdit: TEdit;
  54. LibNameLabel: TLabel;
  55. OutputExtEdit: TEdit;
  56. OutputExtLabel: TLabel;
  57. OutputDirEdit: TEdit;
  58. OutputDirLabel: TLabel;
  59. OutputDirBrowseButton: TButton;
  60. // post h2pas
  61. PostH2PasTabSheet: TTabSheet;
  62. PostH2PasGroupBox: TGroupBox;
  63. PostH2PasEdit: TTextConvListEditor;
  64. // settings
  65. SettingsTabSheet: TTabSheet;
  66. h2pasFilenameBrowseButton: TButton;
  67. H2PasFilenameEdit: TEdit;
  68. H2PasFilenameLabel: TLabel;
  69. NewSettingsButton: TButton;
  70. SaveSettingsAsButton: TButton;
  71. OpenLastProjectOnStartCheckBox: TCheckBox;
  72. // buttons at bottom
  73. OpenSettingsButton: TButton;
  74. SaveSettingsButton: TButton;
  75. ConvertButton: TButton;
  76. CloseButton: TButton;
  77. procedure AddCHeadersButtonClick(Sender: TObject);
  78. procedure AddIncludedCHeaderFilesButtonClick(Sender: TObject);
  79. procedure CHeaderFilesCheckTreeViewDblClick(Sender: TObject);
  80. procedure CHeaderFilesCheckTreeViewMouseDown(Sender: TOBject;
  81. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  82. procedure CHeaderFilesCheckTreeViewSelectionChanged(Sender: TObject);
  83. procedure CloseButtonClick(Sender: TObject);
  84. procedure ConvertAndBuildButtonClick(Sender: TObject);
  85. procedure ConvertButtonClick(Sender: TObject);
  86. procedure DeleteCHeadersButtonClick(Sender: TObject);
  87. procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
  88. procedure FormCreate(Sender: TObject);
  89. procedure FormDestroy(Sender: TObject);
  90. procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  91. procedure H2PasFilenameEditEditingDone(Sender: TObject);
  92. procedure LibnameEditEditingDone(Sender: TObject);
  93. procedure MergeAllCHeadersExceptCurrentButtonClick(Sender: TObject);
  94. procedure MergeFileCheckBoxEditingDone(Sender: TObject);
  95. procedure MoveFileDownButtonClick(Sender: TObject);
  96. procedure MoveFileUpButtonClick(Sender: TObject);
  97. procedure NewSettingsButtonClick(Sender: TObject);
  98. procedure OpenLastProjectOnStartCheckBoxChange(Sender: TObject);
  99. procedure OpenSettingsButtonClick(Sender: TObject);
  100. procedure OutputDirBrowseButtonClick(Sender: TObject);
  101. procedure OutputDirEditEditingDone(Sender: TObject);
  102. procedure OutputExtEditEditingDone(Sender: TObject);
  103. procedure PostH2PasEditModified(Sender: TObject);
  104. procedure PreH2PasEditModified(Sender: TObject);
  105. procedure SaveSettingsAsButtonClick(Sender: TObject);
  106. procedure SaveSettingsButtonClick(Sender: TObject);
  107. procedure EnableAllCHeadersButtonClick(Sender: TObject);
  108. procedure DisableAllCHeadersButtonClick(Sender: TObject);
  109. procedure h2pasFilenameBrowseButtonClick(Sender: TObject);
  110. procedure h2pasOptionsCheckGroupItemClick(Sender: TObject; Index: LongInt);
  111. procedure OnShowSrcEditSection(Sender: TObject);
  112. procedure OnAddSearchAndReplaceBeforeH2PasClick(Sender: TObject);
  113. private
  114. FConverter: TH2PasConverter;
  115. FSrcEditAddSearchReplaceMenuItem: TIDEMenuCommand;
  116. FSrcEditSection: TIDEMenuSection;
  117. function GetProject: TH2PasProject;
  118. procedure UpdateAll(ScanIncludes: boolean);
  119. procedure UpdateProjectChanged(ScanIncludes: boolean); // show project settings
  120. procedure UpdateCaption;
  121. procedure UpdateFileInfo;
  122. procedure ClearMessages;
  123. procedure CreateLazarusMenuItems;
  124. function GetNodeFilename(Node: TTreeNode): string;
  125. function GetCurrentCHeaderFile: TH2PasFile;
  126. procedure MoveCurrentFile(Offset: integer);
  127. function GetFileNodeStateIndex(aFile: TH2PasFile): Integer;
  128. procedure MarkAllCHeadersExceptCurrentToMerge;
  129. // project settings
  130. procedure UpdateFilesPage(ScanIncludes: boolean);
  131. procedure UpdateH2PasPage;
  132. procedure UpdateConvertPage;
  133. // global settings
  134. procedure UpdateSettingsPage;
  135. function ShowSelectDirDialog(const Title: string;
  136. var ADirectory: string): boolean;
  137. function ShowOpenFileDialog(const Title: string;
  138. var AFilename: string): boolean;
  139. // IDE events
  140. function OnIDESavedAll(Sender: TObject): TModalResult;
  141. public
  142. function Convert: TModalResult;
  143. procedure ShowH2PasError;
  144. function SaveSettings: TModalResult;
  145. function SaveGlobalSettings: TModalResult;
  146. function LoadGlobalSettings: TModalResult;
  147. function SaveProject(const Filename: string; Flags: TSaveFlags): TModalResult;
  148. function OpenProject(const Filename: string; Flags: TOpenFlags): TModalResult;
  149. property Converter: TH2PasConverter read FConverter;
  150. property Project: TH2PasProject read GetProject;
  151. property SrcEditSection: TIDEMenuSection read FSrcEditSection;
  152. property SrcEditAddSearchReplaceMenuItem: TIDEMenuCommand
  153. read FSrcEditAddSearchReplaceMenuItem;
  154. end;
  155. var
  156. H2PasDialog: TH2PasDialog = nil;
  157. CmdH2PasTool: TIDECommand = nil;
  158. procedure ExecuteH2PasTool(Sender: TObject);
  159. procedure Register;
  160. implementation
  161. {$R h2pasdlg.lfm}
  162. procedure ExecuteH2PasTool(Sender: TObject);
  163. begin
  164. if H2PasDialog=nil then
  165. H2PasDialog:=TH2PasDialog.Create(Application);
  166. H2PasDialog.ShowOnTop;
  167. end;
  168. procedure Register;
  169. var
  170. Key: TIDEShortCut;
  171. Cat: TIDECommandCategory;
  172. begin
  173. // register IDE shortcut and menu item
  174. Key := IDEShortCut(VK_UNKNOWN,[],VK_UNKNOWN,[]);
  175. Cat:=IDECommandList.FindCategoryByName(CommandCategoryToolMenuName);
  176. CmdH2PasTool := RegisterIDECommand(Cat ,
  177. h2pH2Pas, h2pCreateUnitsFromCHeaderFiles, Key, nil, @ExecuteH2PasTool);
  178. RegisterIDEMenuCommand(itmSecondaryTools, h2pH2PasTool, h2pH2Pas, nil, nil,
  179. CmdH2PasTool);
  180. // register text converter tools
  181. TextConverterToolClasses.RegisterClass(TPreH2PasTools);
  182. TextConverterToolClasses.RegisterClass(TRemoveCPlusPlusExternCTool);
  183. TextConverterToolClasses.RegisterClass(TRemoveEmptyCMacrosTool);
  184. TextConverterToolClasses.RegisterClass(TReplaceEdgedBracketPairWithStar);
  185. TextConverterToolClasses.RegisterClass(TReplaceMacro0PointerWithNULL);
  186. TextConverterToolClasses.RegisterClass(TConvertFunctionTypesToPointers);
  187. TextConverterToolClasses.RegisterClass(TConvertEnumsToTypeDef);
  188. TextConverterToolClasses.RegisterClass(TCommentComplexCMacros);
  189. TextConverterToolClasses.RegisterClass(TCommentComplexCFunctions);
  190. TextConverterToolClasses.RegisterClass(TAddMissingMacroBrackets);
  191. TextConverterToolClasses.RegisterClass(TPostH2PasTools);
  192. TextConverterToolClasses.RegisterClass(TReplaceUnitFilenameWithUnitName);
  193. TextConverterToolClasses.RegisterClass(TRemoveIncludeDirectives);
  194. TextConverterToolClasses.RegisterClass(TRemoveDoubleSemicolons);
  195. TextConverterToolClasses.RegisterClass(TRemoveSystemTypes);
  196. TextConverterToolClasses.RegisterClass(TRemoveRedefinedPointerTypes);
  197. TextConverterToolClasses.RegisterClass(TRemoveEmptyTypeVarConstSections);
  198. TextConverterToolClasses.RegisterClass(TFixH2PasMissingIFDEFsInUnit);
  199. TextConverterToolClasses.RegisterClass(TReduceCompilerDirectivesInUnit);
  200. TextConverterToolClasses.RegisterClass(TReplaceImplicitTypes);
  201. TextConverterToolClasses.RegisterClass(TFixArrayOfParameterType);
  202. TextConverterToolClasses.RegisterClass(TAddMissingPointerTypes);
  203. TextConverterToolClasses.RegisterClass(TRemoveRedefinitionsInUnit);
  204. TextConverterToolClasses.RegisterClass(TFixAliasDefinitionsInUnit);
  205. TextConverterToolClasses.RegisterClass(TReplaceConstFunctionsInUnit);
  206. TextConverterToolClasses.RegisterClass(TReplaceTypeCastFunctionsInUnit);
  207. TextConverterToolClasses.RegisterClass(TFixForwardDefinitions);
  208. TextConverterToolClasses.RegisterClass(TAddToUsesSection);
  209. // register h2pas output parser
  210. ExternalToolList.RegisterParser(TH2PasParser);
  211. end;
  212. { TH2PasDialog }
  213. procedure TH2PasDialog.FormCreate(Sender: TObject);
  214. begin
  215. Caption:=h2pCHeaderFileConverter;
  216. FilesTabSheet.Caption := h2pCHeaderFiles;
  217. AddCHeadersButton.Caption := h2pAddHFiles;
  218. DeleteCHeadersButton.Caption := h2pDeleteSelectedHFiles;
  219. EnableAllCHeadersButton.Caption := h2pEnableAllHFiles;
  220. DisableAllCHeadersButton.Caption := h2pDisableAllHFiles;
  221. MoveFileDownButton.Caption := h2pMoveFileDown;
  222. MoveFileUpButton.Caption := h2pMoveFileUp;
  223. FileInfoGroupBox.Caption := h2pFileInformation;
  224. AddIncludedCHeaderFilesButton.Caption := h2pAddIncludedHFiles;
  225. MergeAllCHeadersExceptCurrentButton.Caption := h2pMergeAllButThis;
  226. MergeFileCheckBox.Caption := h2pMergeFile;
  227. h2pasOptionsTabSheet.Caption := h2pH2pasOptions;
  228. h2pasOptionsCheckGroup.Caption := h2pOptions;
  229. with h2pasOptionsCheckGroup.Items do begin
  230. Add(h2pDUseExternalForAllProcedures);
  231. Add(h2pDUseExternalLibnameNameFunc__nameForFunctions);
  232. Add(h2pEConstantsInsteadOfEnumerationTypeForCEnums);
  233. Add(h2pCCompactOutputmodeLessSpacesAndEmptyLines);
  234. Add(h2pICreateAnIncludeFileInsteadOfAUnit);
  235. Add(h2pPUseLetterPForPointerTypesInsteadOf);
  236. Add(h2pPrPackAllRecords1ByteAlignment);
  237. Add(h2pPUseProcVarsForImports);
  238. Add(h2pSStripComments);
  239. Add(h2pSStripCommentsAndInfo);
  240. Add(h2pTPrependTypedefTypesWithT);
  241. Add(h2pTPrependTypedefTypesWithTAndRemove__);
  242. Add(h2pVReplacePointerParametersByVar);
  243. Add(h2pWHandleSpecialWin32Macros);
  244. Add(h2pXHandleSYS__TRAPOfThePalmOSHeaderFiles);
  245. Add(h2pCUseTypesInCtypesUnit);
  246. end;
  247. OutputExtLabel.Caption := h2pOutputExtensionOfNewFile;
  248. OutputDirLabel.Caption := h2pOutputDirectory;
  249. LibNameLabel.Caption := h2pLLibraryName;
  250. PreH2PasTabSheet.Caption := h2pBeforeH2pas;
  251. PreH2PasGroupBox.Caption := h2pConversionsBeforeRunningH2pas;
  252. PostH2PasTabSheet.Caption := h2pAfterH2pas;
  253. PostH2PasGroupBox.Caption := h2pConversionsAfterRunningH2pas;
  254. SettingsTabSheet.Caption := h2pSettings;
  255. H2PasFilenameLabel.Caption := h2pH2pasProgramPath;
  256. OpenLastProjectOnStartCheckBox.Caption := h2pOpenLastSettingsOnStart;
  257. SaveSettingsAsButton.Caption := h2pSaveSettingsAs;
  258. NewSettingsButton.Caption := h2pNewClearSettings;
  259. OpenSettingsButton.Caption := h2pOpenSettings;
  260. SaveSettingsButton.Caption := h2pSaveSettings;
  261. ConvertButton.Caption := h2pRunH2pas;
  262. ConvertAndBuildButton.Caption := h2pRunH2pasAndCompile;
  263. CloseButton.Caption := h2pClose;
  264. PreH2PasEdit:=TTextConvListEditor.Create(Self);
  265. with PreH2PasEdit do
  266. begin
  267. Name:='PreH2PasEdit';
  268. Align:=alClient;
  269. OnModified:=@PreH2PasEditModified;
  270. Dock(PreH2PasGroupBox, Rect(0, 0, 0, 0));
  271. Visible:=true;// Note: it's a form, and visible default is false
  272. end;
  273. PostH2PasEdit:=TTextConvListEditor.Create(Self);
  274. with PostH2PasEdit do begin
  275. Name:='PostH2PasEdit';
  276. Align:=alClient;
  277. OnModified:=@PostH2PasEditModified;
  278. Dock(PostH2PasGroupBox, Rect(0, 0, 0, 0));
  279. Visible:=true;// Note: it's a form, and visible default is false
  280. end;
  281. LazarusIDE.AddHandlerOnSavedAll(@OnIDESavedAll);
  282. CreateLazarusMenuItems;
  283. // create converter
  284. FConverter:=TH2PasConverter.Create;
  285. LoadGlobalSettings;
  286. // create project
  287. if Converter.AutoOpenLastProject
  288. and FileExistsUTF8(Converter.CurrentProjectFilename) then
  289. OpenProject(Converter.CurrentProjectFilename,[]);
  290. if Project=nil then begin
  291. Converter.Project:=TH2PasProject.Create;
  292. PreH2PasEdit.ListOfTools:=Project.PreH2PasTools;
  293. PostH2PasEdit.ListOfTools:=Project.PostH2PasTools;
  294. end;
  295. UpdateAll(false);
  296. end;
  297. procedure TH2PasDialog.FormCloseQuery(Sender: TObject; var CanClose: boolean);
  298. var
  299. DlgResult: TModalResult;
  300. begin
  301. //DebugLn(['TH2PasDialog.FormCloseQuery Converter.Modified=',Converter.Modified,' Project.Modified=',Project.Modified]);
  302. if Converter.Modified
  303. or ((Project<>nil) and (Project.Modified)) then begin
  304. DlgResult := QuestionDlg(h2pSaveChanges,
  305. h2pSaveSettings2, mtConfirmation,
  306. [mrYes, h2pSaveAndExit, mrNo, h2pDiscardChangesAndExit,
  307. mrCancel, h2pDoNotExit], 0);
  308. case DlgResult of
  309. mrYes: CanClose:=SaveSettings=mrOk;
  310. mrNo: ;
  311. else CanClose:=false;
  312. end;
  313. end;
  314. end;
  315. procedure TH2PasDialog.CloseButtonClick(Sender: TObject);
  316. begin
  317. Close;
  318. end;
  319. procedure TH2PasDialog.ConvertAndBuildButtonClick(Sender: TObject);
  320. begin
  321. if Convert=mrOk then
  322. LazarusIDE.DoBuildProject(crCompile,[]);
  323. end;
  324. procedure TH2PasDialog.ConvertButtonClick(Sender: TObject);
  325. begin
  326. Convert;
  327. end;
  328. procedure TH2PasDialog.DeleteCHeadersButtonClick(Sender: TObject);
  329. var
  330. DeleteFiles: TStringList;
  331. Node: TTreeNode;
  332. begin
  333. DeleteFiles:=TStringList.Create;
  334. Node:=CHeaderFilesCheckTreeView.GetFirstMultiSelected;
  335. while Node<>nil do begin
  336. if Node.Parent=nil then begin
  337. // top lvl node is a .h file
  338. DeleteFiles.Add(GetNodeFilename(Node));
  339. end;
  340. Node:=Node.GetNextMultiSelected;
  341. end;
  342. if DeleteFiles.Count>0 then begin
  343. if QuestionDlg(h2pConfirmRemoval,
  344. Format(h2pDeleteTheseHFilesFromList, [#13, #13, DeleteFiles.Text]),
  345. mtConfirmation, [mrYes, h2pRemoveAllFiles, mrCancel], 0) = mrYes
  346. then begin
  347. Project.DeleteFiles(DeleteFiles);
  348. end;
  349. UpdateFilesPage(true);
  350. end;
  351. DeleteFiles.Free;
  352. end;
  353. procedure TH2PasDialog.AddCHeadersButtonClick(Sender: TObject);
  354. var
  355. OpenDialog: TOpenDialog;
  356. begin
  357. OpenDialog:=TOpenDialog.Create(nil);
  358. try
  359. InitIDEFileDialog(OpenDialog);
  360. OpenDialog.Title := h2pAddHFiles2;
  361. OpenDialog.Options:=OpenDialog.Options+[ofAllowMultiSelect,ofFileMustExist];
  362. OpenDialog.Filter := Format(h2pCHeaderFileHHAllFiles, [FileMask]);
  363. if OpenDialog.Execute then begin
  364. Project.AddFiles(OpenDialog.Files);
  365. UpdateFilesPage(true);
  366. end;
  367. finally
  368. StoreIDEFileDialog(OpenDialog);
  369. OpenDialog.Free;
  370. end;
  371. end;
  372. procedure TH2PasDialog.CHeaderFilesCheckTreeViewMouseDown(Sender: TOBject;
  373. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  374. var
  375. Node: TTreeNode;
  376. StateIconLeft: LongInt;
  377. AFilename: String;
  378. CurFile: TH2PasFile;
  379. begin
  380. if (Button=mbLeft) and (Shift=[]) then ;
  381. Node:=CHeaderFilesCheckTreeView.GetNodeAt(X,Y);
  382. if (Node=nil) or (Node.Parent<>nil) then exit;
  383. StateIconLeft:=Node.DisplayStateIconLeft;
  384. if (x>=StateIconLeft) and (x<StateIconLeft+FileStateImageList.Width) then
  385. begin
  386. AFilename:=GetNodeFilename(Node);
  387. CurFile:=Project.CHeaderFileWithFilename(AFilename);
  388. if CurFile=nil then exit;
  389. CurFile.Enabled:=not CurFile.Enabled;
  390. Node.StateIndex:=GetFileNodeStateIndex(CurFile);
  391. end;
  392. end;
  393. procedure TH2PasDialog.AddIncludedCHeaderFilesButtonClick(Sender: TObject);
  394. var
  395. AFile: TH2PasFile;
  396. sl: TStringList;
  397. i: Integer;
  398. IncFile: TH2PasFileCInclude;
  399. CurFilename: String;
  400. j: Integer;
  401. s: String;
  402. begin
  403. AFile:=GetCurrentCHeaderFile;
  404. if AFile=nil then exit;
  405. AFile.ReadCIncludes(false);
  406. sl:=TStringList.Create;
  407. try
  408. for i:=0 to AFile.CIncludeCount-1 do begin
  409. IncFile:=AFile.CIncludes[i];
  410. CurFilename:=IncFile.Filename;
  411. if CurFilename='' then continue;
  412. // .h file found in include directories
  413. if Project.CHeaderFileWithFilename(CurFilename)<>nil then continue;
  414. // .h file not yet in project
  415. j:=sl.Count-1;
  416. while (j>=0) and (CompareFilenames(CurFilename,sl[j])<>0) do dec(j);
  417. if j>=0 then continue;
  418. // .h file not yet in list
  419. sl.Add(CurFilename);
  420. end;
  421. if sl.Count>0 then begin
  422. s:='';
  423. for i:=0 to sl.Count-1 do begin
  424. CurFilename:=Project.ShortenFilename(sl[i]);
  425. s:=s+#13+CurFilename;
  426. end;
  427. if QuestionDlg(h2pAddHFiles3,
  428. Format(h2pAddTheseHFilesToH2pasProject, [#13, s, #13]),
  429. mtConfirmation,[mrYes,mrNo],0)=mrYes
  430. then begin
  431. Project.AddFiles(sl);
  432. Project.ReadAllCIncludes(true);
  433. UpdateFilesPage(false);
  434. end;
  435. end;
  436. finally
  437. sl.Free;
  438. end;
  439. end;
  440. procedure TH2PasDialog.CHeaderFilesCheckTreeViewDblClick(Sender: TObject);
  441. var
  442. CurFile: TH2PasFile;
  443. begin
  444. CurFile:=GetCurrentCHeaderFile;
  445. if CurFile<>nil then
  446. LazarusIDE.DoOpenEditorFile(CurFile.Filename,-1, -1,[]);
  447. end;
  448. procedure TH2PasDialog.CHeaderFilesCheckTreeViewSelectionChanged(Sender: TObject);
  449. begin
  450. UpdateFileInfo;
  451. end;
  452. procedure TH2PasDialog.FormDestroy(Sender: TObject);
  453. begin
  454. PreH2PasEdit.ListOfTools:=nil;
  455. PostH2PasEdit.ListOfTools:=nil;
  456. FreeAndNil(FConverter);
  457. end;
  458. procedure TH2PasDialog.FormKeyDown(Sender: TObject; var Key: Word;
  459. Shift: TShiftState);
  460. begin
  461. if (Key=VK_ESCAPE) and (Shift=[]) then begin
  462. ModalResult:=mrCancel;
  463. Key:=VK_UNKNOWN;
  464. end;
  465. if (Key=VK_S) and (Shift=[ssCtrl]) then begin
  466. SaveSettings;
  467. Key:=VK_UNKNOWN;
  468. end;
  469. end;
  470. procedure TH2PasDialog.H2PasFilenameEditEditingDone(Sender: TObject);
  471. begin
  472. Converter.h2pasFilename:=H2PasFilenameEdit.Text;
  473. end;
  474. procedure TH2PasDialog.LibnameEditEditingDone(Sender: TObject);
  475. begin
  476. if Project<>nil then
  477. Project.Libname:=LibnameEdit.Text;
  478. end;
  479. procedure TH2PasDialog.MergeAllCHeadersExceptCurrentButtonClick(Sender: TObject);
  480. begin
  481. MarkAllCHeadersExceptCurrentToMerge;
  482. end;
  483. procedure TH2PasDialog.MergeFileCheckBoxEditingDone(Sender: TObject);
  484. var
  485. CurFile: TH2PasFile;
  486. begin
  487. if Project=nil then exit;
  488. CurFile:=GetCurrentCHeaderFile;
  489. if CurFile=nil then exit;
  490. CurFile.Merge:=MergeFileCheckBox.Checked;
  491. UpdateFileInfo;
  492. end;
  493. procedure TH2PasDialog.MoveFileDownButtonClick(Sender: TObject);
  494. begin
  495. MoveCurrentFile(1);
  496. end;
  497. procedure TH2PasDialog.MoveFileUpButtonClick(Sender: TObject);
  498. begin
  499. MoveCurrentFile(-1);
  500. end;
  501. procedure TH2PasDialog.NewSettingsButtonClick(Sender: TObject);
  502. begin
  503. Project.Filename:='';
  504. Project.Clear(true);
  505. UpdateAll(true);
  506. end;
  507. procedure TH2PasDialog.OpenLastProjectOnStartCheckBoxChange(Sender: TObject);
  508. begin
  509. Converter.AutoOpenLastProject:=OpenLastProjectOnStartCheckBox.Checked;
  510. end;
  511. procedure TH2PasDialog.OpenSettingsButtonClick(Sender: TObject);
  512. var
  513. OpenDialog: TOpenDialog;
  514. begin
  515. OpenDialog:=TOpenDialog.Create(nil);
  516. try
  517. InitIDEFileDialog(OpenDialog);
  518. OpenDialog.Title := h2pOpenProjectH2p;
  519. OpenDialog.Options:=OpenDialog.Options+[ofFileMustExist];
  520. OpenDialog.Filter := Format(h2pH2pasProjectH2pH2pAllFiles, [FileMask]);
  521. if OpenDialog.Execute then begin
  522. OpenProject(OpenDialog.FileName,[]);
  523. end;
  524. finally
  525. StoreIDEFileDialog(OpenDialog);
  526. OpenDialog.Free;
  527. end;
  528. end;
  529. procedure TH2PasDialog.OutputDirBrowseButtonClick(Sender: TObject);
  530. var
  531. ADirectory: String;
  532. begin
  533. ADirectory:=OutputDirEdit.Text;
  534. if not ShowSelectDirDialog(h2pOutputDirectory, ADirectory) then exit;
  535. Project.OutputDirectory:=Project.ShortenFilename(ADirectory);
  536. OutputDirEdit.Text:=Project.OutputDirectory;
  537. end;
  538. procedure TH2PasDialog.OutputDirEditEditingDone(Sender: TObject);
  539. begin
  540. Project.OutputDirectory:=OutputDirEdit.Text;
  541. end;
  542. procedure TH2PasDialog.OutputExtEditEditingDone(Sender: TObject);
  543. begin
  544. Project.OutputExt:=OutputExtEdit.Text;
  545. end;
  546. procedure TH2PasDialog.PostH2PasEditModified(Sender: TObject);
  547. begin
  548. Project.Modified:=true;
  549. end;
  550. procedure TH2PasDialog.PreH2PasEditModified(Sender: TObject);
  551. begin
  552. Project.Modified:=true;
  553. end;
  554. procedure TH2PasDialog.SaveSettingsAsButtonClick(Sender: TObject);
  555. begin
  556. SaveProject('',[sfSaveAs]);
  557. end;
  558. procedure TH2PasDialog.SaveSettingsButtonClick(Sender: TObject);
  559. begin
  560. SaveProject('',[]);
  561. end;
  562. procedure TH2PasDialog.EnableAllCHeadersButtonClick(Sender: TObject);
  563. var
  564. i: Integer;
  565. begin
  566. CHeaderFilesCheckTreeView.BeginUpdate;
  567. for i:=0 to CHeaderFilesCheckTreeView.Items.TopLvlCount-1 do
  568. CHeaderFilesCheckTreeView.Items.TopLvlItems[i].StateIndex:=1;
  569. for i:=0 to Project.CHeaderFileCount-1 do
  570. Project.CHeaderFiles[i].Enabled:=true;
  571. CHeaderFilesCheckTreeView.EndUpdate;
  572. UpdateFileInfo;
  573. end;
  574. procedure TH2PasDialog.DisableAllCHeadersButtonClick(Sender: TObject);
  575. var
  576. i: Integer;
  577. begin
  578. CHeaderFilesCheckTreeView.BeginUpdate;
  579. for i:=0 to CHeaderFilesCheckTreeView.Items.TopLvlCount-1 do
  580. CHeaderFilesCheckTreeView.Items.TopLvlItems[i].StateIndex:=0;
  581. for i:=0 to Project.CHeaderFileCount-1 do
  582. Project.CHeaderFiles[i].Enabled:=false;
  583. CHeaderFilesCheckTreeView.EndUpdate;
  584. UpdateFileInfo;
  585. end;
  586. procedure TH2PasDialog.h2pasFilenameBrowseButtonClick(Sender: TObject);
  587. var
  588. AFilename: String;
  589. begin
  590. AFilename:=H2PasFilenameEdit.Text;
  591. if not ShowOpenFileDialog(h2pFilenameOfH2pasProgram, AFilename) then exit;
  592. Converter.h2pasFilename:=AFilename;
  593. H2PasFilenameEdit.Text:=Converter.h2pasFilename;
  594. end;
  595. procedure TH2PasDialog.h2pasOptionsCheckGroupItemClick(Sender: TObject;
  596. Index: LongInt);
  597. var
  598. s: string;
  599. p: Integer;
  600. OptionStr: String;
  601. NewValue: boolean;
  602. begin
  603. if Index<0 then exit;
  604. NewValue:=h2pasOptionsCheckGroup.Checked[Index];
  605. s:=h2pasOptionsCheckGroup.Items[Index];
  606. p:=2;
  607. while (p<=length(s)) and (s[p]<>' ') do inc(p);
  608. OptionStr:=copy(s,2,p-2);
  609. if length(OptionStr)=1 then begin
  610. case OptionStr[1] of
  611. 'd': Project.UseExternal:=NewValue;
  612. 'D': Project.UseExternalLibname:=NewValue;
  613. 'e': Project.ConstantsInsteadOfEnums:=NewValue;
  614. 'c': Project.CompactOutputmode:=NewValue;
  615. 'i': Project.CreateIncludeFile:=NewValue;
  616. 'p': Project.PforPointers:=NewValue;
  617. 'P': Project.UseProcVarsForImport:=NewValue;
  618. 's': Project.StripComments:=NewValue;
  619. 'S': Project.StripCommentsAndInfo:=NewValue;
  620. 't': Project.TforTypedefs:=NewValue;
  621. 'T': Project.TforTypedefsRemoveUnderscore:=NewValue;
  622. 'v': Project.VarParams:=NewValue;
  623. 'w': Project.Win32Header:=NewValue;
  624. 'x': Project.PalmOSSYSTrap:=NewValue;
  625. 'C': Project.UseCTypes:=NewValue;
  626. else
  627. raise Exception.Create(Format(h2pTH2PasDialogH2pasOptionsCheckGroupItemClickUnknown, [OptionStr]));
  628. end;
  629. end else begin
  630. if OptionStr='pr' then
  631. Project.PackAllRecords:=NewValue;
  632. end;
  633. end;
  634. procedure TH2PasDialog.OnShowSrcEditSection(Sender: TObject);
  635. var
  636. SrcEdit: TSourceEditorInterface;
  637. begin
  638. SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
  639. SrcEditSection.Visible:=(SrcEdit<>nil)
  640. and Converter.FileIsRelated(SrcEdit.FileName);
  641. //DebugLn(['TH2PasDialog.OnShowSrcEditSection ',SrcEditSection.Visible]);
  642. end;
  643. procedure TH2PasDialog.OnAddSearchAndReplaceBeforeH2PasClick(Sender: TObject);
  644. var
  645. Tool: TCustomTextConverterTool;
  646. SrcEdit: TSourceEditorInterface;
  647. s: String;
  648. begin
  649. //DebugLn(['TH2PasDialog.OnAddSearchAndReplaceBeforeH2PasClick']);
  650. SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
  651. if SrcEdit=nil then exit;
  652. MainPageControl.ActivePage:=PreH2PasTabSheet;
  653. ShowOnTop;
  654. // get current source editor selection or line
  655. s:=SrcEdit.Selection;
  656. if s='' then
  657. s:=SrcEdit.CurrentLineText;
  658. // add a search and replace tool
  659. Tool:=PreH2PasEdit.CreateTool(TTextReplaceTool);
  660. TTextReplaceTool(Tool).SearchFor:=s;
  661. if (System.Pos(#10,s)>0) or (System.Pos(#13,s)>0) then
  662. TTextReplaceTool(Tool).Options:=TTextReplaceTool(Tool).Options+[trtMultiLine];
  663. PreH2PasEdit.PropertyGrid.RefreshPropertyValues;
  664. //DebugLn(['TH2PasDialog.OnAddSearchAndReplaceBeforeH2PasClick ',s]);
  665. end;
  666. function TH2PasDialog.GetProject: TH2PasProject;
  667. begin
  668. Result:=Converter.Project;
  669. end;
  670. procedure TH2PasDialog.UpdateAll(ScanIncludes: boolean);
  671. begin
  672. UpdateCaption;
  673. UpdateFilesPage(ScanIncludes);
  674. UpdateH2PasPage;
  675. UpdateConvertPage;
  676. UpdateSettingsPage;
  677. end;
  678. procedure TH2PasDialog.UpdateProjectChanged(ScanIncludes: boolean);
  679. begin
  680. UpdateCaption;
  681. UpdateFilesPage(ScanIncludes);
  682. UpdateH2PasPage;
  683. UpdateConvertPage;
  684. end;
  685. procedure TH2PasDialog.UpdateCaption;
  686. var
  687. s: String;
  688. begin
  689. s:=h2pCHeaderFileConverter;
  690. if Project<>nil then
  691. s:=s+' - '+ExtractFileNameOnly(Project.Filename);
  692. Caption:=s;
  693. end;
  694. procedure TH2PasDialog.UpdateFileInfo;
  695. var
  696. AFile: TH2PasFile;
  697. s: String;
  698. Filename: String;
  699. OutputFilename: String;
  700. i: Integer;
  701. IncFile: TH2PasFileCInclude;
  702. begin
  703. AFile:=GetCurrentCHeaderFile;
  704. if AFile<>nil then begin
  705. Filename:=AFile.Filename;
  706. s := Format(h2pFile, [Filename]);
  707. if not FileExistsCached(Filename) then
  708. s := s + #13 + h2pERRORFileNotFound2;
  709. if AFile.MergedBy<>nil then begin
  710. OutputFilename:=AFile.MergedBy.GetOutputFilename;
  711. s := s + #13 + Format(h2pMergedInto, [OutputFilename]);
  712. end else begin
  713. OutputFilename:=AFile.GetOutputFilename;
  714. s := s + #13 + Format(h2pOutput, [OutputFilename]);
  715. end;
  716. AFile.ReadCIncludes(false);
  717. if AFile.CIncludeCount>0 then begin
  718. s := s + #13#13 + h2pIncludes;
  719. for i:=0 to AFile.CIncludeCount-1 do begin
  720. IncFile:=AFile.CIncludes[i];
  721. s:=s+#13+Project.ShortenFilename(IncFile.Filename)+':'+IntToStr(IncFile.SrcPos.Y);
  722. end;
  723. AddIncludedCHeaderFilesButton.Enabled:=true;
  724. end else begin
  725. AddIncludedCHeaderFilesButton.Enabled:=false;
  726. end;
  727. if AFile.CIncludedByCount>0 then begin
  728. s := s + #13#13 + h2pIncludedBy;
  729. for i:=0 to AFile.CIncludedByCount-1 do begin
  730. IncFile:=AFile.CIncludedBy[i];
  731. s:=s+#13+Project.ShortenFilename(IncFile.Owner.Filename)+':'+IntToStr(IncFile.SrcPos.Y);
  732. end;
  733. end;
  734. FileInfoMemo.Caption:=s;
  735. MergeFileCheckBox.Checked:=AFile.Merge;
  736. MergeFileCheckBox.Enabled:=true;
  737. end else begin
  738. FileInfoMemo.Caption := h2pNoFileSelected;
  739. MergeFileCheckBox.Enabled:=false;
  740. AddIncludedCHeaderFilesButton.Enabled:=false;
  741. end;
  742. end;
  743. procedure TH2PasDialog.ClearMessages;
  744. begin
  745. IDEMessagesWindow.Clear;
  746. end;
  747. procedure TH2PasDialog.CreateLazarusMenuItems;
  748. begin
  749. // add a context menu to the source editor. It will be freed by ide automatically
  750. fSrcEditSection:=RegisterIDESubMenu(SrcEditMenuSectionFirstStatic,
  751. h2pH2pasProject, 'h2pas', nil, nil);
  752. fSrcEditSection.AddHandlerOnShow(@OnShowSrcEditSection);
  753. // add a menu item to easily create a Search and replace from the current
  754. // selection or line of the source editor.
  755. fSrcEditAddSearchReplaceMenuItem:=RegisterIDEMenuCommand(SrcEditSection,
  756. h2pAddSearchAndReplaceToolBeforeH2pas,
  757. h2pAddSearchAndReplaceToolBeforeH2pas,
  758. @OnAddSearchAndReplaceBeforeH2PasClick);
  759. end;
  760. function TH2PasDialog.GetNodeFilename(Node: TTreeNode): string;
  761. var
  762. p: LongInt;
  763. begin
  764. Result:=Node.Text;
  765. p:=System.Pos('(',Result);
  766. if p>0 then
  767. Result:=copy(Result,1,p-2);
  768. Result:=Project.LongenFilename(Result);
  769. end;
  770. function TH2PasDialog.GetCurrentCHeaderFile: TH2PasFile;
  771. var
  772. AFilename: String;
  773. Node: TTreeNode;
  774. begin
  775. Result:=nil;
  776. Node:=CHeaderFilesCheckTreeView.Selected;
  777. if (Node=nil) or (Node.Parent<>nil) then exit;
  778. AFilename:=GetNodeFilename(Node);
  779. Result:=Project.CHeaderFileWithFilename(AFilename);
  780. end;
  781. procedure TH2PasDialog.MoveCurrentFile(Offset: integer);
  782. var
  783. Index: LongInt;
  784. AFilename: String;
  785. NewIndex: Integer;
  786. Node: TTreeNode;
  787. begin
  788. if Offset=0 then begin
  789. DebugLn(['TH2PasDialog.MoveCurrentFile Offset=0']);
  790. exit;
  791. end;
  792. Node:=CHeaderFilesCheckTreeView.Selected;
  793. if (Node=nil) or (Node.Parent<>nil) then exit;
  794. AFilename:=GetNodeFilename(Node);
  795. Index:=Project.CHeaderFileIndexWithFilename(AFilename);
  796. if Index<0 then begin
  797. DebugLn(['TH2PasDialog.MoveCurrentFile not found: Filename=',AFilename]);
  798. exit;
  799. end;
  800. NewIndex:=Index+Offset;
  801. if (NewIndex<0) or (NewIndex>=Project.CHeaderFileCount) then begin
  802. DebugLn(['TH2PasDialog.MoveCurrentFile out of bounds: NewIndex=',NewIndex]);
  803. exit;
  804. end;
  805. Project.CHeaderFileMove(Index,NewIndex);
  806. CHeaderFilesCheckTreeView.ConsistencyCheck;
  807. Node.Index:=NewIndex;
  808. CHeaderFilesCheckTreeView.ConsistencyCheck;
  809. end;
  810. function TH2PasDialog.GetFileNodeStateIndex(aFile: TH2PasFile): Integer;
  811. begin
  812. if aFile=nil then
  813. Result:=0
  814. else if aFile.Enabled then
  815. Result:=1
  816. else
  817. Result:=0;
  818. end;
  819. procedure TH2PasDialog.MarkAllCHeadersExceptCurrentToMerge;
  820. var
  821. CurFile: TH2PasFile;
  822. i: Integer;
  823. OtherFile: TH2PasFile;
  824. begin
  825. if Project=nil then exit;
  826. CurFile:=GetCurrentCHeaderFile;
  827. if CurFile=nil then exit;
  828. for i:=0 to Project.CHeaderFileCount-1 do begin
  829. OtherFile:=Project.CHeaderFiles[i];
  830. OtherFile.Merge:=OtherFile<>CurFile;
  831. end;
  832. UpdateFileInfo;
  833. end;
  834. procedure TH2PasDialog.UpdateFilesPage(ScanIncludes: boolean);
  835. var
  836. i: Integer;
  837. CurFile: TH2PasFile;
  838. OldSelection: TStringList;
  839. s: String;
  840. OldExpandedState: TTreeNodeExpandedState;
  841. Node: TTreeNode;
  842. OldSelected: String;
  843. j: Integer;
  844. begin
  845. if ScanIncludes and (Project<>nil) then
  846. Project.ReadAllCIncludes(false);
  847. CHeaderFilesCheckTreeView.BeginUpdate;
  848. OldSelection:=nil;
  849. OldExpandedState:=TTreeNodeExpandedState.Create(CHeaderFilesCheckTreeView);
  850. try
  851. // remember old selection
  852. OldSelected:='';
  853. if CHeaderFilesCheckTreeView.Selected<>nil then
  854. OldSelected:=CHeaderFilesCheckTreeView.Selected.Text;
  855. OldSelection:=TStringList.Create;
  856. Node:=CHeaderFilesCheckTreeView.GetFirstMultiSelected;
  857. while Node<>nil do begin
  858. //DebugLn(['TH2PasDialog.UpdateFilesPage Node.Text="',Node.Text,'" Index=',Node.Index]);
  859. OldSelection.Add(Node.GetTextPath);
  860. Node:=Node.GetNextMultiSelected;
  861. end;
  862. // clear
  863. CHeaderFilesCheckTreeView.Items.Clear;
  864. // fill
  865. for i:=0 to Project.CHeaderFileCount-1 do begin
  866. CurFile:=Project.CHeaderFiles[i];
  867. s:=Project.ShortenFilename(CurFile.Filename);
  868. if CurFile.CIncludedByCount>0 then
  869. s := Format(h2pIncludedBy2, [s, IntToStr(CurFile.CIncludedByCount)]);
  870. Node:=CHeaderFilesCheckTreeView.Items.Add(nil,s);
  871. Node.MultiSelected:=OldSelection.IndexOf(Node.GetTextPath)>=0;
  872. Node.Selected:=Node.Text=OldSelected;
  873. Node.StateIndex:=GetFileNodeStateIndex(CurFile);
  874. for j:=0 to CurFile.CIncludeCount-1 do begin
  875. end;
  876. end;
  877. // restore expanded state
  878. OldExpandedState.Apply(CHeaderFilesCheckTreeView);
  879. finally
  880. OldExpandedState.Free;
  881. OldSelection.Free;
  882. CHeaderFilesCheckTreeView.EndUpdate;
  883. end;
  884. UpdateFileInfo;
  885. end;
  886. procedure TH2PasDialog.UpdateH2PasPage;
  887. procedure Check(const Option: string; NewValue: boolean);
  888. var
  889. i: Integer;
  890. s: string;
  891. begin
  892. for i:=0 to h2pasOptionsCheckGroup.Items.Count-1 do begin
  893. s:=h2pasOptionsCheckGroup.Items[i];
  894. if copy(s,1,length(Option)+1)=Option+' ' then
  895. h2pasOptionsCheckGroup.Checked[i]:=NewValue;
  896. end;
  897. end;
  898. begin
  899. Check('-d',Project.UseExternal);
  900. Check('-D',Project.UseExternalLibname);
  901. Check('-e',Project.ConstantsInsteadOfEnums);
  902. Check('-c',Project.CompactOutputmode);
  903. Check('-i',Project.CreateIncludeFile);
  904. Check('-p',Project.PforPointers);
  905. Check('-pr',Project.PackAllRecords);
  906. Check('-P',Project.UseProcVarsForImport);
  907. Check('-s',Project.StripComments);
  908. Check('-S',Project.StripCommentsAndInfo);
  909. Check('-t',Project.TforTypedefs);
  910. Check('-T',Project.TforTypedefsRemoveUnderscore);
  911. Check('-v',Project.VarParams);
  912. Check('-w',Project.Win32Header);
  913. Check('-x',Project.PalmOSSYSTrap);
  914. Check('-C',Project.UseCTypes);
  915. LibnameEdit.Text:=Project.Libname;
  916. OutputExtEdit.Text:=Project.OutputExt;
  917. OutputDirEdit.Text:=Project.OutputDirectory;
  918. end;
  919. procedure TH2PasDialog.UpdateConvertPage;
  920. begin
  921. ClearMessages;
  922. PreH2PasEdit.ListOfTools:=Project.PreH2PasTools;
  923. PreH2PasEdit.UpdateAll;
  924. PostH2PasEdit.ListOfTools:=Project.PostH2PasTools;
  925. PostH2PasEdit.UpdateAll;
  926. //DebugLn(['TH2PasDialog.UpdateConvertPage PreH2PasEdit.ListOfTools=',PreH2PasEdit.ListOfTools.COmponentCount]);
  927. end;
  928. procedure TH2PasDialog.UpdateSettingsPage;
  929. begin
  930. H2PasFilenameEdit.Text:=Converter.h2pasFilename;
  931. OpenLastProjectOnStartCheckBox.Checked:=Converter.AutoOpenLastProject;
  932. end;
  933. function TH2PasDialog.ShowSelectDirDialog(const Title: string;
  934. var ADirectory: string): boolean;
  935. var
  936. SelectDirDialog: TSelectDirectoryDialog;
  937. begin
  938. Result:=false;
  939. SelectDirDialog:=TSelectDirectoryDialog.Create(nil);
  940. try
  941. InitIDEFileDialog(SelectDirDialog);
  942. SelectDirDialog.Title:=Title;
  943. if (ADirectory<>'')
  944. and (FilenameIsAbsolute(ADirectory)) then
  945. SelectDirDialog.InitialDir:=ADirectory;
  946. if SelectDirDialog.Execute then begin
  947. ADirectory:=SelectDirDialog.FileName;
  948. Result:=true;
  949. end;
  950. finally
  951. StoreIDEFileDialog(SelectDirDialog);
  952. SelectDirDialog.Free;
  953. end;
  954. end;
  955. function TH2PasDialog.ShowOpenFileDialog(const Title: string;
  956. var AFilename: string): boolean;
  957. var
  958. OpenDialog: TOpenDialog;
  959. begin
  960. Result:=false;
  961. OpenDialog:=TOpenDialog.Create(nil);
  962. try
  963. InitIDEFileDialog(OpenDialog);
  964. OpenDialog.Title:=Title;
  965. if (AFilename<>'')
  966. and (FilenameIsAbsolute(AFilename)) then
  967. OpenDialog.InitialDir:=ExtractFilePath(AFilename);
  968. if AFilename<>'' then
  969. OpenDialog.Filename:=ExtractFileName(AFilename);
  970. if OpenDialog.Execute then begin
  971. AFilename:=OpenDialog.FileName;
  972. Result:=true;
  973. end;
  974. finally
  975. StoreIDEFileDialog(OpenDialog);
  976. OpenDialog.Free;
  977. end;
  978. end;
  979. function TH2PasDialog.OnIDESavedAll(Sender: TObject): TModalResult;
  980. begin
  981. Result:=SaveSettings;
  982. end;
  983. function TH2PasDialog.Convert: TModalResult;
  984. begin
  985. Result:=mrCancel;
  986. if not Project.HasEnabledFiles then begin
  987. IDEMessageDialog(h2pNothingToDo,
  988. h2pPleaseEnableAtLeastOneCHeaderFileThatIsNotMerged,
  989. mtInformation,[mbOk],'');
  990. Result:=mrOK;
  991. exit;
  992. end;
  993. // save settings
  994. if SaveSettings<>mrOk then begin
  995. DebugLn(['TH2PasDialog.Convert SaveSettings failed']);
  996. exit;
  997. end;
  998. // save IDE files
  999. if LazarusIDE.DoSaveProject([])<>mrOK then begin
  1000. DebugLn(['TH2PasDialog.Convert LazarusIDE.DoSaveProject failed']);
  1001. exit;
  1002. end;
  1003. LazarusIDE.SaveSourceEditorChangesToCodeCache(nil);
  1004. Result:=Converter.Execute;
  1005. if Result<>mrOk then begin
  1006. ShowH2PasError;
  1007. end;
  1008. end;
  1009. procedure TH2PasDialog.ShowH2PasError;
  1010. begin
  1011. LazarusIDE.DoJumpToCompilerMessage(true);
  1012. end;
  1013. function TH2PasDialog.SaveSettings: TModalResult;
  1014. begin
  1015. Result:=SaveGlobalSettings;
  1016. if Result<>mrOk then exit;
  1017. if (Project<>nil) and Project.Modified then
  1018. Result:=SaveProject('',[]);
  1019. end;
  1020. function TH2PasDialog.SaveGlobalSettings: TModalResult;
  1021. var
  1022. Config: TConfigStorage;
  1023. begin
  1024. Result:=mrCancel;
  1025. try
  1026. Config:=GetIDEConfigStorage('h2pastool.xml',false);
  1027. try
  1028. Converter.WindowBounds:=BoundsRect;
  1029. Converter.Save(Config);
  1030. Config.WriteToDisk;
  1031. finally
  1032. Config.Free;
  1033. end;
  1034. Result:=mrOk;
  1035. except
  1036. on E: Exception do begin
  1037. MessageDlg(h2pWriteError,
  1038. Format(h2pErrorWritingGlobalConfig, [#13, E.Message]), mtError, [mbCancel], 0);
  1039. end;
  1040. end;
  1041. end;
  1042. function TH2PasDialog.LoadGlobalSettings: TModalResult;
  1043. var
  1044. Config: TConfigStorage;
  1045. begin
  1046. Result:=mrCancel;
  1047. try
  1048. Config:=GetIDEConfigStorage('h2pastool.xml',true);
  1049. try
  1050. Converter.Load(Config);
  1051. if (Converter.WindowBounds.Left>-10)
  1052. and (Converter.WindowBounds.Right<Screen.Width+10)
  1053. and (Converter.WindowBounds.Top>-10)
  1054. and (Converter.WindowBounds.Bottom<Screen.Height+10)
  1055. and (Converter.WindowBounds.Right-Converter.WindowBounds.Left>100)
  1056. and (Converter.WindowBounds.Bottom-Converter.WindowBounds.Top>50)
  1057. then
  1058. BoundsRect:=Converter.WindowBounds;
  1059. UpdateSettingsPage;
  1060. finally
  1061. Config.Free;
  1062. end;
  1063. Result:=mrOk;
  1064. except
  1065. on E: Exception do begin
  1066. MessageDlg(h2pReadError,
  1067. Format(h2pErrorReadingGlobalConfig, [#13, E.Message]), mtError, [mbCancel], 0);
  1068. end;
  1069. end;
  1070. end;
  1071. function TH2PasDialog.SaveProject(const Filename: string; Flags: TSaveFlags
  1072. ): TModalResult;
  1073. var
  1074. NewFilename: String;
  1075. SaveDialog: TSaveDialog;
  1076. NewPath: String;
  1077. begin
  1078. Result:=mrCancel;
  1079. if Project=nil then exit(mrOk);
  1080. NewFilename:=Filename;
  1081. if NewFilename='' then
  1082. NewFilename:=Project.Filename;
  1083. // choose a filename
  1084. if (not FilenameIsAbsolute(NewFilename))
  1085. or (sfSaveAs in Flags) then begin
  1086. SaveDialog:=TSaveDialog.Create(nil);
  1087. try
  1088. InitIDEFileDialog(SaveDialog);
  1089. SaveDialog.Title := h2pSaveProjectAsH2p;
  1090. //choose a nice default name
  1091. if NewFilename='' then
  1092. NewFilename:='project1.h2p';
  1093. SaveDialog.FileName:=NewFilename;
  1094. SaveDialog.Filter := Format(h2pH2pasProjectH2pH2pAllFiles, [FileMask]);
  1095. NewPath:=ExtractFilePath(NewFilename);
  1096. if NewPath<>'' then
  1097. SaveDialog.InitialDir:=NewPath;
  1098. if (not SaveDialog.Execute) then exit;
  1099. NewFilename:=SaveDialog.FileName;
  1100. if NewFilename='' then exit;
  1101. // append default file extension
  1102. if ExtractFileExt(NewFilename)='' then
  1103. NewFilename:=NewFilename+'.h2p';
  1104. // warn if overwriting
  1105. if FileExistsUTF8(NewFilename) then begin
  1106. if QuestionDlg(h2pReplaceFile,
  1107. Format(h2pTheFileAlreadyExists, [NewFilename, #13]),
  1108. mtConfirmation, [mrOk, h2pOverwrite, mrCancel, h2pCancel], 0) <> mrOk
  1109. then exit;
  1110. end;
  1111. finally
  1112. StoreIDEFileDialog(SaveDialog);
  1113. SaveDialog.Free;
  1114. end;
  1115. end;
  1116. // save
  1117. try
  1118. DebugLn(['TH2PasDialog.SaveProject saving project']);
  1119. Converter.SaveProject(NewFilename);
  1120. Result:=mrOk;
  1121. except
  1122. on E: Exception do begin
  1123. MessageDlg(h2pWriteError,
  1124. Format(h2pErrorWritingGlobalConfig, [#13, E.Message]), mtError, [mbCancel], 0);
  1125. end;
  1126. end;
  1127. UpdateCaption;
  1128. end;
  1129. function TH2PasDialog.OpenProject(const Filename: string; Flags: TOpenFlags
  1130. ): TModalResult;
  1131. var
  1132. NewFilename: String;
  1133. begin
  1134. Result:=mrCancel;
  1135. NewFilename:=ExpandFileNameUTF8(TrimFilename(Filename));
  1136. if not FileExistsUTF8(NewFilename) then begin
  1137. if ofOnlyIfExists in Flags then begin
  1138. MessageDlg(h2pFileNotFound,
  1139. Format(h2pFileNotFound2, [NewFilename]), mtError, [mbCancel], 0);
  1140. exit;
  1141. end;
  1142. end;
  1143. // create new project
  1144. if Project=nil then
  1145. Converter.Project:=TH2PasProject.Create;
  1146. if FileExistsUTF8(NewFilename) then begin
  1147. // load
  1148. try
  1149. Converter.LoadProject(NewFilename);
  1150. Result:=mrOk;
  1151. except
  1152. on E: Exception do begin
  1153. MessageDlg(h2pReadError,
  1154. Format(h2pErrorReadingProjectFromFile, [#13, NewFilename, #13, #13, E.Message]), mtError, [mbCancel], 0);
  1155. end;
  1156. end;
  1157. end else begin
  1158. // new project
  1159. Project.Clear(true);
  1160. Converter.CurrentProjectFilename:=NewFilename;
  1161. Project.Filename:=NewFilename;
  1162. end;
  1163. UpdateProjectChanged(true);
  1164. end;
  1165. end.