PageRenderTime 46ms CodeModel.GetById 28ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 1ms

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