Componentes.Terceros.jvcl/official/3.32/install/JVCLInstall/PageBuilder.pas

550 lines
16 KiB
ObjectPascal

{-----------------------------------------------------------------------------
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/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: PageBuilder.pas, released on 2004-03-29.
The Initial Developer of the Original Code is Andreas Hausladen
(Andreas dott Hausladen att gmx dott de)
Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
All Rights Reserved.
Contributor(s): -
You may retrieve the latest version of this file at the Project JEDI's JVCL
home page, located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: PageBuilder.pas 10610 2006-05-19 13:35:08Z elahn $
unit PageBuilder;
{$I jvcl.inc}
interface
uses
Windows, SysUtils, Classes, Controls, Forms, Graphics, StdCtrls, ExtCtrls,
ComCtrls, ActnList,
JvWizard,
Core;
function CreatePage(Page: TJvWizardInteriorPage; Inst: IInstallerPage): TWinControl;
{ returns the active control }
function PreparePage(Page: TJvWizardInteriorPage; Inst: IInstallerPage): TPanel;
procedure DestroyPage(Page: TJvWizardInteriorPage);
implementation
uses
Main, Utils;
function CreateWelcomePage(Page: TJvWizardInteriorPage; Inst: IWelcomePage): TWinControl; forward;
{ returns the active control }
function CreateMultiChoosePage(Page: TJvWizardInteriorPage; Inst: IMultiChoosePage): TWinControl; forward;
{ returns the active control }
function CreateSingleChoosePage(Page: TJvWizardInteriorPage; Inst: ISingleChoosePage): TWinControl; forward;
{ returns the active control }
function CreateSummaryPage(Page: TJvWizardInteriorPage; Inst: ISummaryPage): TWinControl; forward;
{ returns the active control }
type
TSingleChooseOptionClick = class(TComponent)
public
Index: Integer;
Page: ISingleChoosePage;
procedure Click(Sender: TObject);
end;
TMultiChooseCheckBoxClick = class(TComponent)
public
Index: Integer;
Page: IMultiChoosePage;
procedure Click(Sender: TObject);
end;
procedure TSingleChooseOptionClick.Click(Sender: TObject);
begin
Page.SetSelectedOption(Index);
end;
procedure TMultiChooseCheckBoxClick.Click(Sender: TObject);
begin
Page.SetCheckBox(Index, (Sender as TCheckBox).Checked);
end;
function GetDefaultCheckBoxSize: TSize;
begin
{$IFDEF VCL}
with TBitmap.Create do
try
Handle := LoadBitmap(0, PChar(OBM_CHECKBOXES));
Result.cx := Width div 4;
Result.cy := Height div 3;
finally
Free;
end;
{$ENDIF VCL}
{$IFDEF VisualCLX}
Result.cx := 12;
Result.cy := 12;
{$ENDIF VisualCLX}
end;
// -----------------------------------------------------------------------------
function CreateLayoutPanel(Parent: TWinControl; const Name: string;
const BoundsRect: TRect): TPanel;
begin
Result := TPanel.Create(Parent);
Result.Name := Name;
Result.BevelInner := bvNone;
Result.BevelOuter := bvNone;
Result.BoundsRect := BoundsRect;
Result.Caption := '';
Result.Parent := Parent;
end;
function PreparePage(Page: TJvWizardInteriorPage; Inst: IInstallerPage): TPanel;
var
Title, SubTitle: WideString;
begin
// caption
Title := '';
SubTitle := '';
Inst.Title(Title, SubTitle);
Page.Title.Text := Title;
Page.Subtitle.Text := SubTitle;
Page.Caption := Title;
Page.Header.Title.Indent := 5;
Page.Header.Subtitle.Indent := 5;
Page.Header.Visible := (Title <> '') or (SubTitle <> '');
Result := nil;
end;
function CreatePage(Page: TJvWizardInteriorPage; Inst: IInstallerPage): TWinControl;
var
Y: Integer;
PageClient: TPanel;
FocusControl: TWinControl;
begin
Result := nil;
if (Page.FindComponent('piPageClient') <> nil) and not Supports(Inst, ISummaryPage) then // do not localize
Exit;
if Supports(Inst, ISummaryPage) then
Page.FindComponent('piPageClient').Free;
if Page.Header.Visible then
Y := Page.Header.Height
else
Y := 0;
PageClient := CreateLayoutPanel(Page, 'piPageClient', // do not localize
Rect(0, Y, Page.ClientWidth, Page.ClientHeight));
if Supports(Inst, IWelcomePage) then
Result := CreateWelcomePage(Page, Inst as IWelcomePage)
else
if Supports(Inst, ISingleChoosePage) then
Result := CreateSingleChoosePage(Page, Inst as ISingleChoosePage)
else
if Supports(Inst, IMultiChoosePage) then
Result := CreateMultiChoosePage(Page, Inst as IMultiChoosePage)
else
if Supports(Inst, ISummaryPage) then
Result := CreateSummaryPage(Page, Inst as ISummaryPage)
;
// maybe the user wants some extra controls
if Supports(Inst, IUserDefinedPage) then
begin
FocusControl := (Inst as IUserDefinedPage).SetupPage(PageClient);
if FocusControl <> nil then
Result := FocusControl;
end;
end;
procedure DestroyPage(Page: TJvWizardInteriorPage);
procedure RemoveActionLists(Owner: TComponent);
var
i: Integer;
begin
for i := Owner.ComponentCount - 1 downto 0 do
RemoveActionLists(Owner.Components[i]);
if (Owner is TCustomActionList) then
Owner.Free;
end;
var
Panel: TPanel;
begin
Panel := TPanel(Page.FindComponent('piPageClient')); // do not localize
if Panel <> nil then
begin
RemoveActionLists(Panel); // Bug in VCL does not remove the action list from the frame's actionlist list.
Panel.Free;
end;
end;
function CreateSingleChooseControls(Parent: TWinControl; Inst: ISingleChoosePage;
var LockedHorzOrientation: THorzOrientation): TWinControl;
var
Options: TStrings;
i, AbsH, X, Y, ps: Integer;
RadioButton: TRadioButton;
ItemIndex: Integer;
S: string;
HorzOrientation: THorzOrientation;
Width, tmpWidth: Integer;
Canvas: TControlCanvas;
begin
Result := nil;
Options := TStringList.Create;
Canvas := TControlCanvas.Create;
try
Canvas.Control := Parent;
// RadioButtons
HorzOrientation := hoDefault;
Inst.Options(Options, HorzOrientation);
case LockedHorzOrientation of
hoLeft:
HorzOrientation := hoRight;
hoRight:
HorzOrientation := hoLeft;
hoCenter:
Exit; // error
end;
if HorzOrientation = hoDefault then
HorzOrientation := hoLeft;
LockedHorzOrientation := HorzOrientation;
if Options.Count > 0 then
begin
ItemIndex := Inst.GetSelectedOption;
// find text with largest width
Width := 0;
for i := 0 to Options.Count - 1 do
begin
S := Options[i];
if S <> '' then
begin
ps := Pos('|', S);
if ps = 0 then
ps := Length(S) + 1;
tmpWidth := Canvas.TextWidth(Copy(S, 1, ps - 1));
if tmpWidth > Width then
Width := tmpWidth;
end;
end;
Inc(Width, GetDefaultCheckBoxSize.cx*4 div 2); // add checkbox size
if HorzOrientation = hoLeft then
X := 8
else if HorzOrientation = hoCenter then
X := (Parent.ClientWidth - Width) div 2
else
X := Parent.ClientWidth - 8 - Width;
// create radion buttons
AbsH := (Parent.ClientHeight - 8) div Options.Count;
Y := 8;
for i := 0 to Options.Count - 1 do
begin
S := Options[i];
if S <> '' then
begin
ps := Pos('|', S);
if ps = 0 then
ps := Length(S) + 1;
RadioButton := TRadioButton.Create(Parent);
RadioButton.Name := 'piOption_' + IntToStr(i); // do not localize
RadioButton.Left := X;
RadioButton.Top := Y;
RadioButton.Caption := Copy(S, 1, ps - 1);
RadioButton.Hint := Copy(S, ps + 1, MaxInt);
RadioButton.ShowHint := RadioButton.Hint <> '';
RadioButton.Parent := Parent;
RadioButton.ClientWidth := Width;
with TSingleChooseOptionClick.Create(Parent) do
begin
Page := Inst;
Index := i;
RadioButton.OnClick := Click;
end;
if i = ItemIndex then
begin
if Result = nil then
Result := RadioButton;
RadioButton.Checked := True;
end;
Inst.SetupRadioButton(i, RadioButton);
end;
Inc(Y, AbsH);
end;
end;
finally
Options.Free;
Canvas.Free;
end;
end;
function CreateMultiChooseControls(Parent: TWinControl; Inst: IMultiChoosePage;
var LockedHorzOrientation: THorzOrientation): TWinControl;
var
CheckBoxes: TStrings;
i, AbsH, X, Y, ps: Integer;
CheckBox: TCheckBox;
S: string;
HorzOrientation: THorzOrientation;
Width, tmpWidth: Integer;
Canvas: TControlCanvas;
begin
Result := nil;
CheckBoxes := TStringList.Create;
Canvas := TControlCanvas.Create;
try
Canvas.Control := Parent;
HorzOrientation := hoDefault;
Inst.CheckBoxes(CheckBoxes, HorzOrientation);
case LockedHorzOrientation of
hoLeft:
HorzOrientation := hoRight;
hoRight:
HorzOrientation := hoLeft;
hoCenter:
Exit; // error
end;
if HorzOrientation = hoDefault then
HorzOrientation := hoLeft;
LockedHorzOrientation := HorzOrientation;
if CheckBoxes.Count > 0 then
begin
// find text with largest width
Width := 0;
for i := 0 to CheckBoxes.Count - 1 do
begin
S := CheckBoxes[i];
if S <> '' then
begin
ps := Pos('|', S);
if ps = 0 then
ps := Length(S) + 1;
tmpWidth := Canvas.TextWidth(Copy(S, 1, ps - 1));
if tmpWidth > Width then
Width := tmpWidth;
end;
end;
Inc(Width, GetDefaultCheckBoxSize.cx*4 div 2); // add checkbox size
if HorzOrientation = hoLeft then
X := 8
else if HorzOrientation = hoCenter then
X := (Parent.ClientWidth - Width) div 2
else
X := Parent.ClientWidth - 8 - Width;
// create check boxes
AbsH := (Parent.ClientHeight - 8) div CheckBoxes.Count;
Y := 8;
for i := 0 to CheckBoxes.Count - 1 do
begin
S := CheckBoxes[i];
if S <> '' then
begin
ps := Pos('|', S);
if ps = 0 then
ps := Length(S) + 1;
CheckBox := TCheckBox.Create(Parent);
CheckBox.Name := 'piCheckBox_' + IntToStr(i);
CheckBox.Left := X;
CheckBox.Top := Y;
CheckBox.Caption := Copy(S, 1, ps - 1);
CheckBox.Hint := Copy(S, ps + 1, MaxInt);
CheckBox.ShowHint := CheckBox.Hint <> '';
CheckBox.Parent := Parent;
CheckBox.ClientWidth := Width;
with TMultiChooseCheckBoxClick.Create(Parent) do
begin
Page := Inst;
Index := i;
CheckBox.OnClick := Click;
end;
if Result = nil then
Result := CheckBox;
CheckBox.Checked := Inst.GetCheckBox(i);
Inst.SetupCheckBox(i, CheckBox);
end;
Inc(Y, AbsH);
end;
end;
finally
CheckBoxes.Free;
Canvas.Free;
end;
end;
function CreateWelcomePage(Page: TJvWizardInteriorPage; Inst: IWelcomePage): TWinControl;
var
Text: WideString;
Memo: TMemo;
PageClient, ControlsPanel: TPanel;
Y: Integer;
HorzOrientation: THorzOrientation;
MultiChoosePage: IMultiChoosePage;
begin
PageClient := TPanel(Page.FindComponent('piPageClient')); // do not localize
Text := Inst.Text;
if Text <> '' then
begin
Memo := TMemo.Create(PageClient);
Memo.Parent := PageClient;
Memo.Name := 'piPageMemo'; // do not localize
Memo.Left := 8;
Memo.Top := 8;
Memo.Width := PageClient.ClientWidth - Memo.Left * 2;
Memo.Height := (PageClient.ClientHeight - Memo.Top * 2) * 2 div 3;
Memo.ReadOnly := True;
Memo.Font.Name := 'Arial';
Memo.Lines.Text := Text;
Memo.ScrollBars := ssVertical;
Memo.Visible := True;
Y := Memo.Top + Memo.Height;
end
else
Y := 0;
ControlsPanel := CreateLayoutPanel(PageClient, 'piControlsPanel', // do not localize
Rect(0, Y, PageClient.ClientWidth, PageClient.ClientHeight));
HorzOrientation := hoDefault;
Result := CreateSingleChooseControls(ControlsPanel, Inst, HorzOrientation);
if Supports(Inst, IMultiChoosePage, MultiChoosePage) then
CreateMultiChooseControls(ControlsPanel, MultiChoosePage, HorzOrientation);
end;
function CreateSingleChoosePage(Page: TJvWizardInteriorPage; Inst: ISingleChoosePage): TWinControl;
var
PageClient: TPanel;
HortOrientation: THorzOrientation;
begin
PageClient := TPanel(Page.FindComponent('piPageClient')); // do not localize
HortOrientation := hoDefault;
Result := CreateSingleChooseControls(PageClient, Inst, HortOrientation);
end;
function CreateMultiChoosePage(Page: TJvWizardInteriorPage; Inst: IMultiChoosePage): TWinControl;
var
PageClient: TPanel;
HortOrientation: THorzOrientation;
begin
PageClient := TPanel(Page.FindComponent('piPageClient')); // do not localize
HortOrientation := hoDefault;
Result := CreateMultiChooseControls(PageClient, Inst, HortOrientation);
end;
function CreateSummaryPage(Page: TJvWizardInteriorPage; Inst: ISummaryPage): TWinControl;
var
PageClient: TPanel;
ListView: TListView;
Actions, Comments: TStrings;
I, MaxWidth, TextWidth, Count, ActionsWidth: Integer;
ListItem: TListItem;
begin
PageClient := TPanel(Page.FindComponent('piPageClient')); // do not localize
ListView := TListView.Create(PageClient);
ListView.Parent := PageClient;
ListView.SetBounds(8, 8, PageClient.ClientWidth - 8 * 2, PageClient.ClientHeight - 8 * 2);
ListView.ReadOnly := True;
ListView.ViewStyle := vsReport;
ListView.RowSelect := True;
ListView.ShowColumnHeaders := False;
ListView.SmallImages := FormMain.ImageList;
MaxWidth := 150;
ActionsWidth := 0;
Actions := TStringList.Create;
Comments := TStringList.Create;
ListView.Items.BeginUpdate;
try
Inst.GetSummary(Actions, Comments);
Count := Actions.Count;
if Count < Comments.Count then
Count := Comments.Count;
for I := 0 to Count - 1 do
begin
ListItem := ListView.Items.Add;
if I >= Actions.Count then
begin
ListItem.Caption := '';
end
else
begin
ListItem.Caption := Actions[I];
TextWidth := ListView.Canvas.TextWidth(Actions[I]);
if TextWidth > ActionsWidth then
ActionsWidth := TextWidth;
end;
if ListItem.Caption = '' then
ListItem.ImageIndex := -1
else
ListItem.ImageIndex := 0;
if I >= Comments.Count then
ListItem.SubItems.Add('')
else
begin
ListItem.SubItems.Add(Comments[I]);
TextWidth := ListView.Canvas.TextWidth(Comments[I]);
if MaxWidth < TextWidth then
MaxWidth := TextWidth;
end;
end;
ListView.Columns.Add.Width := ActionsWidth+30; // +30 to cope for the bullet width
if ListView.ClientWidth < MaxWidth + 50 then
ListView.Columns.Add.Width := MaxWidth + 50
else
ListView.Columns.Add.AutoSize := True;
ListView.Width := ListView.Width + 1; // force AutoSize
finally
ListView.Items.EndUpdate;
Actions.Free;
Comments.Free;
end;
Result := ListView;
end;
end.