/jcl/install/VclGui/JediGUIInstall.pas

https://github.com/the-Arioch/jcl · Pascal · 787 lines · 656 code · 84 blank · 47 comment · 51 complexity · d16f2f34c46ca08c578322fad7551422 MD5 · raw file

  1. {**************************************************************************************************}
  2. { }
  3. { Project JEDI Code Library (JCL) extension }
  4. { }
  5. { The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
  6. { you may not use this file except in compliance with the License. You may obtain a copy of the }
  7. { License at http://www.mozilla.org/MPL/ }
  8. { }
  9. { Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
  10. { ANY KIND, either express or implied. See the License for the specific language governing rights }
  11. { and limitations under the License. }
  12. { }
  13. { The Original Code is JediInstallerMain.pas. }
  14. { }
  15. { The Initial Developer of the Original Code is Petr Vones. Portions created by Petr Vones are }
  16. { Copyright (C) of Petr Vones. All Rights Reserved. }
  17. { }
  18. { Contributors: }
  19. { Andreas Hausladen (ahuser) }
  20. { Robert Rossmair (rrossmair) - crossplatform & BCB support, refactoring }
  21. { Florent Ouchet (outchy) - New installer core }
  22. { }
  23. {**************************************************************************************************}
  24. { }
  25. { Last modified: $Date:: $ }
  26. { Revision: $Rev:: $ }
  27. { Author: $Author:: $ }
  28. { }
  29. {**************************************************************************************************}
  30. unit JediGUIInstall;
  31. {$I jcl.inc}
  32. {$I crossplatform.inc}
  33. interface
  34. uses
  35. SysUtils, Classes,
  36. Graphics, Forms, Controls, StdCtrls, ComCtrls, ExtCtrls, FrmCompile,
  37. JclIDEUtils, JediInstall;
  38. type
  39. TSetIconEvent = procedure(Sender: TObject; const FileName: string) of object;
  40. TInstallFrame = class(TFrame, IJediInstallPage, IJediPage)
  41. ComponentsTreePanel: TPanel;
  42. LabelSelectComponents: TLabel;
  43. TreeView: TTreeView;
  44. Splitter: TSplitter;
  45. InfoPanel: TPanel;
  46. LabelInstallationLog: TLabel;
  47. InfoDisplay: TRichEdit;
  48. OptionsGroupBox: TGroupBox;
  49. ProgressBar: TProgressBar;
  50. procedure SplitterCanResize(Sender: TObject; var NewSize: Integer;
  51. var Accept: Boolean);
  52. procedure TreeViewMouseDown(Sender: TObject; Button: TMouseButton;
  53. Shift: TShiftState; X, Y: Integer);
  54. procedure TreeViewKeyPress(Sender: TObject; var Key: Char);
  55. procedure TreeViewCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
  56. State: TCustomDrawState; var DefaultDraw: Boolean);
  57. private
  58. FNodeData: TList;
  59. FDirectories: TList;
  60. FCheckedCount: Integer;
  61. FInstallCount: Integer;
  62. FInstalling: Boolean;
  63. FOnSetIcon: TSetIconEvent;
  64. FFormCompile: TFormCompile;
  65. FInstallGUI: IJediInstallGUI;
  66. function GetFormCompile: TFormCompile;
  67. function GetNodeChecked(Node: TTreeNode): Boolean;
  68. function IsAutoChecked(Node: TTreeNode): Boolean;
  69. function IsRadioButton(Node: TTreeNode): Boolean;
  70. function IsStandAloneParent(Node: TTreeNode): Boolean;
  71. function IsExpandable(Node: TTreeNode): Boolean;
  72. procedure UpdateNode(N: TTreeNode; C: Boolean);
  73. procedure SetNodeChecked(Node: TTreeNode; const Value: Boolean);
  74. procedure ToggleNodeChecked(Node: TTreeNode);
  75. procedure DirectoryEditChange(Sender: TObject);
  76. procedure DirectorySelectBtnClick(Sender: TObject);
  77. function GetNode(Id: Integer): TTreeNode;
  78. procedure UpdateImageIndex(N: TTreeNode);
  79. public
  80. constructor Create(AOwner: TComponent; AInstallGUI: IJediInstallGUI); reintroduce;
  81. destructor Destroy; override;
  82. // IJediPage
  83. function GetCaption: string;
  84. procedure SetCaption(const Value: string);
  85. function GetHintAtPos(ScreenX, ScreenY: Integer): string;
  86. procedure Show;
  87. // IJediInstallPage
  88. procedure AddInstallOption(Id: Integer; Options: TJediInstallGUIOptions;
  89. const Caption: string = ''; const Hint: string = ''; Parent: Integer = -1);
  90. procedure InitDisplay;
  91. function GetOptionChecked(Id: Integer): Boolean;
  92. procedure SetOptionChecked(Id: Integer; Value: Boolean);
  93. function GetDirectoryCount: Integer;
  94. function GetDirectory(Index: Integer): string;
  95. procedure SetDirectory(Index: Integer; const Value: string);
  96. function AddDirectory(const Caption: string): Integer;
  97. function GetProgress: Integer;
  98. procedure SetProgress(Value: Integer);
  99. procedure BeginInstall;
  100. procedure MarkOptionBegin(Id: Integer);
  101. procedure MarkOptionEnd(Id: Integer; Failed: Boolean);
  102. procedure EndInstall;
  103. procedure CompilationStart(const ProjectName: string);
  104. procedure AddLogLine(const Line: string);
  105. procedure AddHint(const Line: string);
  106. procedure AddWarning(const Line: string);
  107. procedure AddError(const Line: string);
  108. procedure AddFatal(const Line: string);
  109. procedure AddText(const Line: string);
  110. procedure CompilationProgress(const FileName: string; LineNumber: Integer);
  111. procedure SetIcon(const FileName: string);
  112. property OnSetIcon: TSetIconEvent read FOnSetIcon write FOnSetIcon;
  113. end;
  114. implementation
  115. {$R *.dfm}
  116. uses
  117. {$IFDEF HAS_UNIT_TYPES}
  118. Types, // inlining of Point
  119. {$ENDIF HAS_UNIT_TYPES}
  120. Windows, Messages,
  121. FileCtrl,
  122. JclStrings,
  123. JediInstallResources;
  124. const
  125. // Icon indexes
  126. IcoUnchecked = 0;
  127. IcoChecked = 1;
  128. IcoRadioUnchecked = 2;
  129. IcoRadioChecked = 3;
  130. IcoNotInstalled = 4;
  131. IcoFailed = 5;
  132. IcoInstalled = 6;
  133. IconIndexes: array [Boolean {RadioButton}, Boolean {Checked}] of Integer =
  134. ( (IcoUnchecked, IcoChecked), (IcoRadioUnchecked, IcoRadioChecked) );
  135. type
  136. TNodeRec = record
  137. Id: Integer;
  138. Options: TJediInstallGUIOptions;
  139. Hint: string;
  140. end;
  141. PNodeRec = ^TNodeRec;
  142. TDirectoryRec = record
  143. Edit: TEdit;
  144. Button: TButton;
  145. end;
  146. PDirectoryRec = ^TDirectoryRec;
  147. constructor TInstallFrame.Create(AOwner: TComponent; AInstallGUI: IJediInstallGUI);
  148. begin
  149. inherited Create(AOwner);
  150. FNodeData := TList.Create;
  151. FDirectories := TList.Create;
  152. FInstallGUI := AInstallGUI;
  153. end;
  154. destructor TInstallFrame.Destroy;
  155. var
  156. Index: Integer;
  157. begin
  158. for Index := FNodeData.Count - 1 downto 0 do
  159. Dispose(FNodeData.Items[Index]);
  160. FNodeData.Free;
  161. for Index := FDirectories.Count - 1 downto 0 do
  162. Dispose(FDirectories.Items[Index]);
  163. FDirectories.Free;
  164. inherited Destroy;
  165. end;
  166. procedure TInstallFrame.DirectoryEditChange(Sender: TObject);
  167. var
  168. AEdit: TEdit;
  169. begin
  170. AEdit := Sender as TEdit;
  171. if {$IFDEF RTL220_UP}SysUtils.{$ENDIF RTL220_UP}DirectoryExists(AEdit.Text) then
  172. AEdit.Font.Color := clWindowText
  173. else
  174. AEdit.Font.Color := clRed;
  175. end;
  176. function TInstallFrame.GetNodeChecked(Node: TTreeNode): Boolean;
  177. begin
  178. Result := goChecked in PNodeRec(Node.Data)^.Options;
  179. end;
  180. function TInstallFrame.IsAutoChecked(Node: TTreeNode): Boolean;
  181. begin
  182. Result := not (goNoAutoCheck in PNodeRec(Node.Data)^.Options);
  183. end;
  184. function TInstallFrame.IsRadioButton(Node: TTreeNode): Boolean;
  185. begin
  186. Result := goRadioButton in PNodeRec(Node.Data)^.Options;
  187. end;
  188. function TInstallFrame.IsStandAloneParent(Node: TTreeNode): Boolean;
  189. begin
  190. Result := goStandaloneParent in PNodeRec(Node.Data)^.Options;
  191. end;
  192. function TInstallFrame.IsExpandable(Node: TTreeNode): Boolean;
  193. begin
  194. Result := goExpandable in PNodeRec(Node.Data)^.Options;
  195. end;
  196. procedure TInstallFrame.SetIcon(const FileName: string);
  197. begin
  198. if Assigned(FOnSetIcon) then
  199. FOnSetIcon(Self, FileName);
  200. end;
  201. procedure TInstallFrame.UpdateNode(N: TTreeNode; C: Boolean);
  202. var
  203. ANodeRec: PNodeRec;
  204. begin
  205. ANodeRec := N.Data;
  206. if C then
  207. Include(ANodeRec^.Options, goChecked)
  208. else
  209. Exclude(ANodeRec^.Options, goChecked);
  210. UpdateImageIndex(N);
  211. end;
  212. procedure TInstallFrame.SetNodeChecked(Node: TTreeNode; const Value: Boolean);
  213. procedure UpdateTreeDown(N: TTreeNode; C: Boolean);
  214. begin
  215. N := N.getFirstChild;
  216. while Assigned(N) do
  217. begin
  218. if not C or IsAutoChecked(N) then
  219. begin
  220. if not IsRadioButton(N) then
  221. UpdateNode(N, C);
  222. UpdateTreeDown(N, C);
  223. end;
  224. N := N.getNextSibling;
  225. end;
  226. end;
  227. procedure UpdateTreeUp(N: TTreeNode; C: Boolean);
  228. var
  229. ParentNode: TTreeNode;
  230. ParentChecked: Boolean;
  231. begin
  232. if C then
  233. while Assigned(N) do
  234. begin
  235. UpdateNode(N, True);
  236. N := N.Parent;
  237. end
  238. else
  239. begin
  240. ParentNode := N.Parent;
  241. while Assigned(ParentNode) do
  242. begin
  243. N := ParentNode.getFirstChild;
  244. ParentChecked := IsStandAloneParent(ParentNode);
  245. while Assigned(N) do
  246. if GetNodeChecked(N) and not IsRadioButton(N) then
  247. begin
  248. ParentChecked := True;
  249. Break;
  250. end
  251. else
  252. N := N.getNextSibling;
  253. UpdateNode(ParentNode, ParentChecked);
  254. ParentNode := ParentNode.Parent;
  255. end;
  256. end;
  257. end;
  258. procedure UpdateRadioButton(N: TTreeNode; C: Boolean);
  259. var
  260. Node: TTreeNode;
  261. begin
  262. if Value and not GetNodeChecked(N) then
  263. begin
  264. Node := N.Parent;
  265. if Node <> nil then
  266. begin
  267. Node := Node.getFirstChild;
  268. while Node <> nil do
  269. begin
  270. if IsRadioButton(Node) then
  271. UpdateNode(Node, Node = N);
  272. Node := Node.getNextSibling;
  273. end;
  274. end;
  275. end;
  276. end;
  277. begin
  278. if IsRadioButton(Node) then
  279. UpdateRadioButton(Node, Value)
  280. else
  281. begin
  282. UpdateTreeDown(Node, Value);
  283. UpdateNode(Node, Value);
  284. UpdateTreeUp(Node, Value);
  285. end;
  286. TreeView.Invalidate;
  287. end;
  288. procedure TInstallFrame.ToggleNodeChecked(Node: TTreeNode);
  289. begin
  290. if Assigned(Node) then
  291. SetNodeChecked(Node, not GetNodeChecked(Node));
  292. end;
  293. function TInstallFrame.GetNode(Id: Integer): TTreeNode;
  294. begin
  295. Result := TreeView.Items.GetFirstNode;
  296. while Assigned(Result) do
  297. begin
  298. if PNodeRec(Result.Data)^.Id = Id then
  299. Break;
  300. Result := Result.GetNext;
  301. end;
  302. end;
  303. procedure TInstallFrame.UpdateImageIndex(N: TTreeNode);
  304. var
  305. ImgIndex: Integer;
  306. begin
  307. ImgIndex := IconIndexes[IsRadioButton(N), GetNodeChecked(N)];
  308. N.ImageIndex := ImgIndex;
  309. N.SelectedIndex := ImgIndex;
  310. end;
  311. procedure TInstallFrame.DirectorySelectBtnClick(Sender: TObject);
  312. var
  313. Index: Integer;
  314. Button: TButton;
  315. Edit: TEdit;
  316. {$IFDEF USE_WIDESTRING}
  317. Directory: WideString;
  318. {$UNDEF USE_WIDESTRING}
  319. {$ELSE}
  320. Directory: string;
  321. {$ENDIF}
  322. DirectoryRec: PDirectoryRec;
  323. begin
  324. Button := Sender as TButton;
  325. Edit := nil;
  326. for Index := 0 to FDirectories.Count - 1 do
  327. begin
  328. DirectoryRec := FDirectories.Items[Index];
  329. if DirectoryRec^.Button = Button then
  330. begin
  331. Edit := DirectoryRec^.Edit;
  332. Break;
  333. end;
  334. end;
  335. if Assigned(Edit) and SelectDirectory(RsSelectPath, '', Directory) then
  336. Edit.Text := Directory;
  337. end;
  338. procedure TInstallFrame.SplitterCanResize(Sender: TObject;
  339. var NewSize: Integer; var Accept: Boolean);
  340. begin
  341. Accept := NewSize > 150;
  342. end;
  343. procedure TInstallFrame.TreeViewCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
  344. State: TCustomDrawState; var DefaultDraw: Boolean);
  345. begin
  346. case TTreeNode(Node).Level of
  347. 0: begin
  348. Sender.Canvas.Font.Style := [fsBold, fsUnderline];
  349. end;
  350. 1: begin
  351. Sender.Canvas.Font.Style := [fsBold];
  352. end;
  353. end;
  354. end;
  355. procedure TInstallFrame.TreeViewKeyPress(Sender: TObject; var Key: Char);
  356. begin
  357. with TTreeView(Sender) do
  358. case Key of
  359. #32:
  360. if not FInstalling then
  361. begin
  362. ToggleNodeChecked(Selected);
  363. Key := #0;
  364. end;
  365. '+':
  366. Selected.Expanded := True;
  367. '-':
  368. Selected.Expanded := False;
  369. end;
  370. end;
  371. function TreeNodeIconHit(TreeView: TTreeView; X, Y: Integer): Boolean;
  372. begin
  373. Result := htOnIcon in TreeView.GetHitTestInfoAt(X, Y);
  374. end;
  375. procedure TInstallFrame.TreeViewMouseDown(Sender: TObject;
  376. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  377. var
  378. Node: TTreeNode;
  379. begin
  380. if not FInstalling then
  381. with TTreeView(Sender) do
  382. begin
  383. Node := GetNodeAt(X, Y);
  384. if (Button = mbLeft) and TreeNodeIconHit(TreeView, X, Y) then
  385. ToggleNodeChecked(Node);
  386. end;
  387. end;
  388. function TInstallFrame.GetFormCompile: TFormCompile;
  389. begin
  390. if not Assigned(FFormCompile) then
  391. begin
  392. FFormCompile := TFormCompile.Create(Self, FInstallGUI);
  393. SetWindowLong(FFormCompile.Handle, GWL_HWNDPARENT, Handle);
  394. FFormCompile.Init(Caption, True);
  395. FFormCompile.Show;
  396. Application.ProcessMessages;
  397. end;
  398. Result := FFormCompile;
  399. end;
  400. // IJediPage
  401. function TInstallFrame.GetCaption: string;
  402. begin
  403. Result := (Parent as TTabSheet).Caption;
  404. end;
  405. procedure TInstallFrame.SetCaption(const Value: string);
  406. begin
  407. (Parent as TTabSheet).Caption := Value;
  408. AddInstallOption(JediTargetOption, [goExpandable], Value, LoadResString(@RsHintTarget), -1);
  409. end;
  410. function TInstallFrame.GetHintAtPos(ScreenX, ScreenY: Integer): string;
  411. var
  412. TreeViewCoord: TPoint;
  413. ANode: TTreeNode;
  414. begin
  415. TreeViewCoord := TreeView.ScreenToClient(Point(ScreenX, ScreenY));
  416. if (TreeViewCoord.X >= 0) and (TreeViewCoord.Y >= 0) and
  417. (TreeViewCoord.X < TreeView.Width) and (TreeViewCoord.Y < TreeView.Height) then
  418. begin
  419. ANode := TreeView.GetNodeAt(TreeViewCoord.X, TreeViewCoord.Y);
  420. if Assigned(ANode) then
  421. Result := PNodeRec(ANode.Data)^.Hint;
  422. end;
  423. end;
  424. procedure TInstallFrame.Show;
  425. var
  426. ATabSheet: TTabSheet;
  427. begin
  428. ATabSheet := Parent as TTabSheet;
  429. (ATabSheet.Parent as TPageControl).ActivePage := ATabSheet;
  430. end;
  431. // IJediInstallPage
  432. procedure TInstallFrame.AddInstallOption(Id: Integer; Options: TJediInstallGUIOptions;
  433. const Caption: string = ''; const Hint: string = ''; Parent: Integer = -1);
  434. var
  435. NodeRec: PNodeRec;
  436. ParentNode, ThisNode: TTreeNode;
  437. begin
  438. if Id = -1 then
  439. raise Exception.CreateResFmt(@RsInvalidOption, [Id]);
  440. if Parent <> -1 then
  441. ParentNode := GetNode(Parent)
  442. else
  443. ParentNode := nil;
  444. ThisNode := GetNode(Id);
  445. if Assigned(ThisNode) then
  446. ThisNode.Text := Caption
  447. else
  448. begin
  449. New(NodeRec);
  450. NodeRec^.Id := Id;
  451. NodeRec^.Hint := Hint;
  452. NodeRec^.Options := Options;
  453. ThisNode := TreeView.Items.AddChildObject(ParentNode, Caption, NodeRec);
  454. FNodeData.Add(NodeRec);
  455. end;
  456. UpdateImageIndex(ThisNode);
  457. end;
  458. procedure TInstallFrame.InitDisplay;
  459. var
  460. ANode: TTreeNode;
  461. begin
  462. LabelSelectComponents.Caption := LoadResString(@RsGUISelectComponents);
  463. LabelInstallationLog.Caption := LoadResString(@RsGUIInstallationLog);
  464. OptionsGroupBox.Caption := LoadResString(@RsGUIAdvancedOptions);
  465. ANode := TreeView.Items.GetFirstNode;
  466. while Assigned(ANode) do
  467. begin
  468. if (ANode.Count > 0) and IsExpandable(ANode) then
  469. ANode.Expand(False);
  470. ANode := ANode.GetNext;
  471. end;
  472. ANode := TreeView.Items.GetFirstNode;
  473. if Assigned(ANode) then
  474. TreeView.TopItem := ANode;
  475. end;
  476. function TInstallFrame.GetOptionChecked(Id: Integer): Boolean;
  477. var
  478. ANode: TTreeNode;
  479. begin
  480. ANode := GetNode(Id);
  481. Result := Assigned(ANode) and GetNodeChecked(ANode);
  482. end;
  483. procedure TInstallFrame.SetOptionChecked(Id: Integer; Value: Boolean);
  484. var
  485. ANode: TTreeNode;
  486. begin
  487. ANode := GetNode(Id);
  488. while Assigned(ANode) do
  489. begin
  490. UpdateNode(ANode, Value);
  491. // if an option is checked, ensure that all parent options are checked too
  492. if IsRadioButton(ANode) or not Value then
  493. Break;
  494. ANode := ANode.Parent;
  495. end;
  496. end;
  497. function TInstallFrame.GetDirectoryCount: Integer;
  498. begin
  499. Result := FDirectories.Count;
  500. end;
  501. function TInstallFrame.GetDirectory(Index: Integer): string;
  502. begin
  503. Result := PDirectoryRec(FDirectories.Items[Index])^.Edit.Text;
  504. end;
  505. procedure TInstallFrame.SetDirectory(Index: Integer; const Value: string);
  506. begin
  507. PDirectoryRec(FDirectories.Items[Index])^.Edit.Text := Value;
  508. end;
  509. function TInstallFrame.AddDirectory(const Caption: string): Integer;
  510. var
  511. ADirectoryRec: PDirectoryRec;
  512. ALabel: TLabel;
  513. ControlTop, ButtonWidth, LabelRight: Integer;
  514. begin
  515. if FDirectories.Count > 0 then
  516. begin
  517. ADirectoryRec := FDirectories.Items[FDirectories.Count - 1];
  518. ControlTop := ADirectoryRec^.Edit.Top + ADirectoryRec^.Edit.Height + 10;
  519. end
  520. else
  521. ControlTop := 16;
  522. New(ADirectoryRec);
  523. ALabel := TLabel.Create(Self);
  524. ALabel.Parent := OptionsGroupBox;
  525. ALabel.Caption := Caption;
  526. ALabel.AutoSize := True;
  527. ADirectoryRec^.Edit := TEdit.Create(Self);
  528. ADirectoryRec^.Edit.Parent := OptionsGroupBox;
  529. ADirectoryRec^.Edit.Anchors := [akLeft, akTop, akRight];
  530. ADirectoryRec^.Button := TButton.Create(Self);
  531. ADirectoryRec^.Button.Parent := OptionsGroupBox;
  532. ADirectoryRec^.Button.Caption := '...';
  533. ADirectoryRec^.Button.Anchors := [akTop, akRight];
  534. ButtonWidth := 2 * ALabel.Height;
  535. LabelRight := (ALabel.Width div 16) * 16 + 32 + ALabel.Left; // make edits aligned when label widths are nearly equals
  536. ADirectoryRec^.Edit.SetBounds(LabelRight, ControlTop,
  537. OptionsGroupBox.ClientWidth - LabelRight - ButtonWidth - 16,
  538. ADirectoryRec^.Edit.Height);
  539. ADirectoryRec^.Button.SetBounds(OptionsGroupBox.ClientWidth - ButtonWidth - 8,
  540. ControlTop, ButtonWidth, ADirectoryRec^.Edit.Height);
  541. ALabel.SetBounds(8, ControlTop + (ADirectoryRec^.Edit.Height - ALabel.Height) div 2,
  542. ALabel.Width, ALabel.Height);
  543. ADirectoryRec^.Edit.OnChange := DirectoryEditChange;
  544. ADirectoryRec^.Button.OnClick := DirectorySelectBtnClick;
  545. OptionsGroupBox.ClientHeight := ADirectoryRec^.Edit.Top + ADirectoryRec^.Edit.Height + 10;
  546. OptionsGroupBox.Top := TreeView.Height + TreeView.Top - OptionsGroupBox.Height;
  547. InfoDisplay.Height := OptionsGroupBox.Top - InfoDisplay.Top - 8;
  548. Result := FDirectories.Add(ADirectoryRec);
  549. end;
  550. function TInstallFrame.GetProgress: Integer;
  551. begin
  552. Result := ProgressBar.Position;
  553. end;
  554. procedure TInstallFrame.SetProgress(Value: Integer);
  555. begin
  556. ProgressBar.Position := Value;
  557. end;
  558. procedure TInstallFrame.BeginInstall;
  559. var
  560. ANode: TTreeNode;
  561. begin
  562. ProgressBar.Visible := True;
  563. InfoDisplay.Lines.Clear;
  564. FCheckedCount := 0;
  565. FInstallCount := 0;
  566. ANode := TreeView.Items.GetFirstNode;
  567. while Assigned(ANode) do
  568. begin
  569. if GetNodeChecked(ANode) then
  570. Inc(FCheckedCount);
  571. ANode := ANode.GetNext;
  572. end;
  573. FInstalling := True;
  574. end;
  575. procedure TInstallFrame.MarkOptionBegin(Id: Integer);
  576. var
  577. ANode: TTreeNode;
  578. begin
  579. ANode := GetNode(Id);
  580. while Assigned(ANode) do
  581. begin
  582. ANode.ImageIndex := IcoNotInstalled;
  583. ANode.SelectedIndex := IcoNotInstalled;
  584. ANode := ANode.Parent;
  585. end;
  586. end;
  587. procedure TInstallFrame.MarkOptionEnd(Id: Integer; Failed: Boolean);
  588. var
  589. ANode, BNode: TTreeNode;
  590. Index: Integer;
  591. ChangeIcon: Boolean;
  592. begin
  593. if Assigned(FFormCompile) then
  594. begin
  595. if FFormCompile.Errors > 0 then // do not make the dialog modal when no error occured
  596. FFormCompile.Done(' ')
  597. else
  598. FFormCompile.Done;
  599. FreeAndNil(FFormCompile);
  600. end;
  601. ANode := GetNode(Id);
  602. while Assigned(ANode) and GetNodeChecked(ANode) do
  603. begin
  604. ChangeIcon := (ANode.Count = 0) or Failed;
  605. if not ChangeIcon then
  606. begin
  607. ChangeIcon := True;
  608. for Index := 0 to ANode.Count - 1 do
  609. begin
  610. BNode := ANode.Item[Index];
  611. case BNode.ImageIndex of
  612. IcoNotInstalled:
  613. begin
  614. ChangeIcon := False;
  615. Break;
  616. end;
  617. IcoFailed:
  618. begin
  619. Failed := True;
  620. Break;
  621. end;
  622. IcoInstalled: ;
  623. else
  624. ChangeIcon := ChangeIcon and not GetNodeChecked(BNode);
  625. end;
  626. end;
  627. end;
  628. if ChangeIcon then
  629. begin
  630. if Failed then
  631. begin
  632. ANode.ImageIndex := IcoFailed;
  633. ANode.SelectedIndex := IcoFailed;
  634. end
  635. else
  636. begin
  637. ANode.ImageIndex := IcoInstalled;
  638. ANode.SelectedIndex := IcoInstalled;
  639. end;
  640. end
  641. else
  642. Break;
  643. ANode := ANode.Parent;
  644. end;
  645. Inc(FInstallCount);
  646. if FCheckedCount > 0 then
  647. SetProgress(100 * FInstallCount div FCheckedCount);
  648. end;
  649. procedure TInstallFrame.EndInstall;
  650. var
  651. ANode: TTreeNode;
  652. begin
  653. FInstalling := False;
  654. MarkOptionEnd(-1, True);
  655. ANode := TreeView.Items.GetFirstNode;
  656. while Assigned(ANode) do
  657. begin
  658. UpdateImageIndex(ANode);
  659. ANode := ANode.GetNext;
  660. end;
  661. ProgressBar.Visible := False;
  662. end;
  663. procedure TInstallFrame.CompilationStart(const ProjectName: string);
  664. begin
  665. GetFormCompile.Init(ProjectName, True);
  666. end;
  667. procedure TInstallFrame.AddLogLine(const Line: string);
  668. begin
  669. InfoDisplay.Lines.Append(Line);
  670. InfoDisplay.Perform(EM_SCROLLCARET, 0, 0);
  671. end;
  672. procedure TInstallFrame.AddHint(const Line: string);
  673. begin
  674. GetFormCompile.AddHint(Line);
  675. AddLogLine(Line);
  676. end;
  677. procedure TInstallFrame.AddWarning(const Line: string);
  678. begin
  679. GetFormCompile.AddWarning(Line);
  680. AddLogLine(Line);
  681. end;
  682. procedure TInstallFrame.AddError(const Line: string);
  683. begin
  684. GetFormCompile.AddError(Line);
  685. AddLogLine(Line);
  686. end;
  687. procedure TInstallFrame.AddFatal(const Line: string);
  688. begin
  689. GetFormCompile.AddFatal(Line);
  690. AddLogLine(Line);
  691. end;
  692. procedure TInstallFrame.AddText(const Line: string);
  693. begin
  694. //{$IFDEF VCL}
  695. //GetFormCompile.AddText(Line);
  696. //{$ENDIF VCL}
  697. AddLogLine(Line);
  698. end;
  699. procedure TInstallFrame.CompilationProgress(const FileName: string; LineNumber: Integer);
  700. begin
  701. GetFormCompile.CompilationProgress(FileName, LineNumber);
  702. end;
  703. end.