{**************************************************************************************************} { WARNING: JEDI preprocessor generated unit. Do not edit. } {**************************************************************************************************} {**************************************************************************************************} { } { Project JEDI Code Library (JCL) extension } { } { The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); } { you may not use this file except in compliance with the License. You may obtain a copy of the } { License at http://www.mozilla.org/MPL/ } { } { Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF } { ANY KIND, either express or implied. See the License for the specific language governing rights } { and limitations under the License. } { } { The Original Code is JediInstallerMain.pas. } { } { The Initial Developer of the Original Code is Petr Vones. Portions created by Petr Vones are } { Copyright (C) of Petr Vones. All Rights Reserved. } { } { Contributors: } { Andreas Hausladen (ahuser) } { Robert Rossmair (rrossmair) - crossplatform & BCB support, refactoring } { } {**************************************************************************************************} // $Id: ProductFrames.pas,v 1.26 2006/02/05 13:26:15 outchy Exp $ unit ProductFrames; interface {$I jcl.inc} {$I crossplatform.inc} uses SysUtils, Classes, Graphics, Forms, Controls, StdCtrls, ComCtrls, ExtCtrls, JclBorlandTools, JediInstall; const // Feature masks FID_Expandable = $08000000; FID_RadioButton = $10000000; FID_NoAutoCheck = $20000000; // do not auto-check when the parent node gets checked FID_StandaloneParent = $40000000; // do not auto-uncheck when all child nodes are unchecked FID_Checked = $80000000; FID_NumberMask = $03FFFFFF; // Icon indexes IcoProduct = 0; IcoLevel1 = 1; IcoChecked = 2; IcoUnchecked = 3; type TProductFrame = class(TFrame) ComponentsTreePanel: TPanel; Label1: TLabel; TreeView: TTreeView; Splitter: TSplitter; InfoPanel: TPanel; Label2: TLabel; InfoDisplay: TRichEdit; OptionsGroupBox: TGroupBox; BplPathLabel: TLabel; DcpPathLabel: TLabel; BplPathEdit: TEdit; Button1: TButton; Button2: TButton; DcpPathEdit: TEdit; procedure PathEditChange(Sender: TObject); procedure PathSelectBtnClick(Sender: TObject); procedure SplitterCanResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean); procedure TreeViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TreeViewKeyPress(Sender: TObject; var Key: Char); procedure TreeViewCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean); private { Private declarations } FInstallation: TJclBorRADToolInstallation; function GetDCPPath: string; function GetBPLPath: string; function GetNodeChecked(Node: TTreeNode): Boolean; function GetPathForEdit(Path: string): string; function IsAutoChecked(Node: TTreeNode): Boolean; function IsRadioButton(Node: TTreeNode): Boolean; function IsStandAloneParent(Node: TTreeNode): Boolean; procedure SetDCPPath(const Value: string); procedure SetBPLPath(const Value: string); procedure SetInstallation(Value: TJclBorRADToolInstallation); procedure SetNodeChecked(Node: TTreeNode; const Value: Boolean); procedure ToggleNodeChecked(Node: TTreeNode); public { Public declarations } class function GetName(Installation: TJclBorRADToolInstallation): string; function FeatureChecked(FeatureID: Cardinal): Boolean; procedure LogOutputLine(const Line: string); procedure UpdateTree; procedure StartCompilation(Installation: TJclBorRADToolInstallation); procedure StopCompilation(Installation: TJclBorRADToolInstallation); property NodeChecked[Node: TTreeNode]: Boolean read GetNodeChecked write SetNodeChecked; property Installation: TJclBorRADToolInstallation read FInstallation write SetInstallation; property DCPPath: string read GetDCPPath write SetDCPPath; property BPLPath: string read GetBPLPath write SetBPLPath; end; function Collapsable(Node: TTreeNode): Boolean; implementation {$R *.dfm} uses Windows, Messages, FileCtrl, FrmCompile, JclStrings, JclInstall; resourcestring RsSelectPath = 'Select path'; RsEnterValidPath = '(Enter valid path)'; function Collapsable(Node: TTreeNode): Boolean; begin Result := (Cardinal(Node.Data) and FID_Expandable) <> 0; end; procedure TProductFrame.PathEditChange(Sender: TObject); begin with (Sender as TEdit) do if DirectoryExists(Text) then Font.Color := clWindowText else Font.Color := clRed; end; function TProductFrame.FeatureChecked(FeatureID: Cardinal): Boolean; var F: Cardinal; Node: TTreeNode; begin Result := False; Node := TreeView.Items.GetFirstNode; while Node <> nil do begin F := Cardinal(Node.Data); if F and FID_NumberMask = FeatureID then begin Result := F and FID_Checked <> 0; Break; end; Node := Node.GetNext; end; end; function TProductFrame.GetDCPPath: string; begin Result := DcpPathEdit.Text; end; function TProductFrame.GetBPLPath: string; begin Result := BplPathEdit.Text; end; class function TProductFrame.GetName(Installation: TJclBorRADToolInstallation): string; begin Result := Format('%sProduct', [Installation.VersionNumberStr]); end; function TProductFrame.GetNodeChecked(Node: TTreeNode): Boolean; begin Result := Cardinal(Node.Data) and FID_Checked <> 0; end; function TProductFrame.GetPathForEdit(Path: string): string; begin if DirectoryExists(Path) then Result := Path else Result := RsEnterValidPath; end; function TProductFrame.IsAutoChecked(Node: TTreeNode): Boolean; begin Result := Cardinal(Node.Data) and FID_NoAutoCheck = 0; end; function TProductFrame.IsRadioButton(Node: TTreeNode): Boolean; begin Result := Cardinal(Node.Data) and FID_RadioButton <> 0; end; function TProductFrame.IsStandAloneParent(Node: TTreeNode): Boolean; begin Result := Cardinal(Node.Data) and FID_StandAloneParent <> 0; end; procedure TProductFrame.LogOutputLine(const Line: string); function Cmp(const S: string): Boolean; begin Result := Copy(Line, 1, Length(S)) = S; end; begin if FormCompile.HandleLine(Line) <> clFileProgress then begin if Cmp(AnsiLineBreak + 'Installing package ') then FormCompile.Linking(Copy(Line, 20, MaxInt)) else if Cmp('Copying .hpp files...') then FormCompile.Done; InfoDisplay.Lines.Append(Line); InfoDisplay.Perform(EM_SCROLLCARET, 0, 0); end; end; procedure TProductFrame.SetDCPPath(const Value: string); begin DcpPathEdit.Text := GetPathForEdit(Value); end; procedure TProductFrame.SetBPLPath(const Value: string); begin BplPathEdit.Text := GetPathForEdit(Value); end; procedure TProductFrame.SetInstallation(Value: TJclBorRADToolInstallation); begin FInstallation := Value; Name := GetName(Value); if Value.RadToolKind = brCppBuilder then DcpPathLabel.Caption := '.bpi Path'; end; procedure TProductFrame.SetNodeChecked(Node: TTreeNode; const Value: Boolean); procedure UpdateNode(N: TTreeNode; C: Boolean); const CheckedState: array[Boolean] of Cardinal = (0, FID_Checked); begin N.Data := Pointer(Cardinal(N.Data) and (not FID_Checked) or CheckedState[C]); if C then begin N.ImageIndex := IcoChecked; N.SelectedIndex := IcoChecked; end else begin N.ImageIndex := IcoUnchecked; N.SelectedIndex := IcoUnchecked; end; end; procedure UpdateTreeDown(N: TTreeNode; C: Boolean); begin N := N.getFirstChild; while Assigned(N) do begin if not C or IsAutoChecked(N) then begin if not IsRadioButton(N) then UpdateNode(N, C); UpdateTreeDown(N, C); end; N := N.getNextSibling; end; end; procedure UpdateTreeUp(N: TTreeNode; C: Boolean); var ParentNode: TTreeNode; ParentChecked: Boolean; begin if C then while Assigned(N) do begin UpdateNode(N, True); N := N.Parent; end else begin ParentNode := N.Parent; while Assigned(ParentNode) do begin N := ParentNode.getFirstChild; ParentChecked := IsStandAloneParent(ParentNode); while Assigned(N) do if NodeChecked[N] and not IsRadioButton(N) then begin ParentChecked := True; Break; end else N := N.getNextSibling; UpdateNode(ParentNode, ParentChecked); ParentNode := ParentNode.Parent; end; end; end; procedure UpdateRadioButton(N: TTreeNode; C: Boolean); var Node: TTreeNode; begin if Value and not NodeChecked[N] then begin Node := N.Parent; if Node <> nil then begin Node := Node.getFirstChild; while Node <> nil do begin if IsRadioButton(Node) then UpdateNode(Node, Node = N); Node := Node.getNextSibling; end; end; end; end; begin if IsRadioButton(Node) then UpdateRadioButton(Node, Value) else begin UpdateNode(Node, Value); UpdateTreeDown(Node, Value); UpdateTreeUp(Node, Value); end; end; procedure TProductFrame.ToggleNodeChecked(Node: TTreeNode); begin if Assigned(Node) then NodeChecked[Node] := not NodeChecked[Node]; end; procedure TProductFrame.PathSelectBtnClick(Sender: TObject); var I: Integer; Button: TButton; Edit: TEdit; {$IFDEF USE_WIDESTRING} Directory: WideString; {$UNDEF USE_WIDESTRING} {$ELSE} Directory: string; {$ENDIF} begin Button := Sender as TButton; Edit := nil; with Button.Parent do for I := 0 to ControlCount - 1 do if (Controls[I].Top = Button.Top) and (Controls[I] is TEdit) then Edit := TEdit(Controls[I]); if Assigned(Edit) and SelectDirectory(RsSelectPath, '', Directory) then Edit.Text := Directory; end; procedure TProductFrame.SplitterCanResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean); begin Accept := NewSize > 150; end; procedure TProductFrame.TreeViewCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean); begin case TTreeNode(Node).Level of 0: begin Sender.Canvas.Font.Style := [fsBold, fsUnderline]; end; 1: begin Sender.Canvas.Font.Style := [fsBold]; end; end; end; procedure TProductFrame.TreeViewKeyPress(Sender: TObject; var Key: Char); begin with TTreeView(Sender) do case Key of #32: begin ToggleNodeChecked(Selected); Key := #0; end; '+': Selected.Expanded := True; '-': Selected.Expanded := False; end; end; function TreeNodeIconHit(TreeView: TTreeView; X, Y: Integer): Boolean; begin Result := htOnIcon in TreeView.GetHitTestInfoAt(X, Y); end; procedure TProductFrame.TreeViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var Node: TTreeNode; begin with TTreeView(Sender) do begin Node := GetNodeAt(X, Y); if (Button = mbLeft) and TreeNodeIconHit(TreeView, X, Y) then ToggleNodeChecked(Node); end; end; procedure TProductFrame.UpdateTree; var Node: TTreeNode; begin Node := TreeView.Items.GetFirstNode; while Node <> nil do begin if not Collapsable(Node) then Node.Expand(False); Node := Node.GetNext; end; end; procedure TProductFrame.StartCompilation(Installation: TJclBorRADToolInstallation); begin if not Assigned(FormCompile) then FormCompile := TFormCompile.Create(Self); SetWindowLong(FormCompile.Handle, GWL_HWNDPARENT, Handle); FormCompile.Init(Installation.Name, True); FormCompile.Show; Application.ProcessMessages; end; procedure TProductFrame.StopCompilation(Installation: TJclBorRADToolInstallation); begin if FormCompile.Errors > 0 then // do not make the dialog modal when no error occured FormCompile.Done(' ') else FormCompile.Done; FormCompile.Free; FormCompile := nil; end; end.