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