453 lines
14 KiB
ObjectPascal
453 lines
14 KiB
ObjectPascal
{**************************************************************************************************}
|
|
{ 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.
|