lazarus-ccr/components/orpheus/ovctbcls.pas
macpgmr 2c37512236 Attempted fix of resizing issue in TOvcTable as a result of LCL 0.9.29 change in SetBounds behavior.
http://wiki.lazarus.freepascal.org/Lazarus_0.9.30_release_notes#overriding_TControl.SetBounds

Unknown how many other places where this or similar fixes will be needed; Orpheus overrides SetBounds throughout.

Also uncommented two place where Screen.DataModules was used as this now appears to be implemented in LCL.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1471 8e941d3f-bd1b-0410-a28a-d453659cc2b4
2011-01-29 23:51:20 +00:00

609 lines
18 KiB
ObjectPascal

{*********************************************************}
{* OVCTBCLS.PAS 4.06 *}
{*********************************************************}
{* ***** BEGIN LICENSE BLOCK ***** *}
{* Version: MPL 1.1 *}
{* *}
{* 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 TurboPower Orpheus *}
{* *}
{* The Initial Developer of the Original Code is TurboPower Software *}
{* *}
{* Portions created by TurboPower Software Inc. are Copyright (C)1995-2002 *}
{* TurboPower Software Inc. All Rights Reserved. *}
{* *}
{* Contributor(s): *}
{* *}
{* ***** END LICENSE BLOCK ***** *}
{$I OVC.INC}
{$B-} {Complete Boolean Evaluation}
{$I+} {Input/Output-Checking}
{$P+} {Open Parameters}
{$T-} {Typed @ Operator}
{W-} {Windows Stack Frame}
{$X+} {Extended Syntax}
unit ovctbcls;
{-Table column, column array classes}
interface
uses
{$IFNDEF LCL} Windows, {$ELSE} LclIntf, LclType, {$ENDIF}
SysUtils, Graphics, Classes, Controls, Forms,
OvcConst, OvcTCmmn, OvcTCell;
type
TOvcTableColumnClass = class of TOvcTableColumn;
TOvcTableColumn = class(TPersistent)
protected {private}
{property fields-even size}
FDefCell : TOvcBaseTableCell;
FNumber : TColNum;
FOnColumnChanged : TColChangeNotifyEvent;
FTable : TOvcTableAncestor;
FWidth : Integer;
{property fields-odd size}
FHidden : boolean;
Filler : byte;
protected
{property access}
procedure SetDefCell(BTC : TOvcBaseTableCell);
procedure SetHidden(H : boolean);
procedure SetWidth(W : Integer);
{miscellaneous}
procedure tcDoColumnChanged;
procedure tcNotifyCellDeletion(Cell : TOvcBaseTableCell);
public {protected}
{internal only usage}
property Number : TColNum
read FNumber write FNumber;
property OnColumnChanged : TColChangeNotifyEvent
write FOnColumnChanged;
public
procedure Assign(Source : TPersistent); override;
constructor Create(ATable : TOvcTableAncestor); virtual;
destructor Destroy; override;
{properties}
property Table : TOvcTableAncestor
read FTable;
published
{properties for streaming}
property DefaultCell: TOvcBaseTableCell
read FDefCell write SetDefCell;
property Hidden : boolean
read FHidden write SetHidden;
property Width : Integer
read FWidth write SetWidth;
end;
TOvcTableColumns = class(TPersistent)
protected {private}
{property fields}
FList : TList;
FOnColumnChanged: TColChangeNotifyEvent;
FFixups : TStringList;
FTable : TOvcTableAncestor;
{other fields}
tcColumnClass : TOvcTableColumnClass;
protected
{property access}
function GetCol(ColNum : TColNum) : TOvcTableColumn;
function GetCount : Integer;
function GetDefaultCell(ColNum : TColNum) : TOvcBaseTableCell;
function GetHidden(ColNum : TColNum) : boolean;
function GetWidth(ColNum : TColNum) : Integer;
procedure SetCol(ColNum : TColNum; C : TOvcTableColumn);
procedure SetCount(C : Integer);
procedure SetDefaultCell(ColNum : TColNum; C : TOvcBaseTableCell);
procedure SetHidden(ColNum : TColNum; H : boolean);
procedure SetWidth(ColNum : TColNum; W : Integer);
{event access}
procedure SetOnColumnChanged(OC : TColChangeNotifyEvent);
{other}
procedure tcDoColumnChanged(ColNum1, ColNum2 : TColNum;
Action : TOvcTblActions);
public
{internal only usage}
procedure tcNotifyCellDeletion(Cell : TOvcBaseTableCell);
function tcStartLoading : TStringList;
procedure tcStopLoading;
property OnColumnChanged : TColChangeNotifyEvent
write SetOnColumnChanged;
public
constructor Create(ATable : TOvcTableAncestor; ANumber : Integer;
AColumnClass : TOvcTableColumnClass);
destructor Destroy; override;
procedure Append(C : TOvcTableColumn);
procedure Clear;
procedure Delete(ColNum : TColNum);
procedure Exchange(ColNum1, ColNum2 : TColNum);
procedure Insert(const ColNum : TColNum; C : TOvcTableColumn);
property Count : Integer
read GetCount write SetCount;
property DefaultCell [ColNum : TColNum] : TOvcBaseTableCell
read GetDefaultCell write SetDefaultCell;
property Hidden [ColNum : TColNum] : boolean
read GetHidden write SetHidden;
property List [ColNum : TColNum] : TOvcTableColumn
read GetCol write SetCol;
default;
property Table : TOvcTableAncestor
read FTable write FTable;
property Width [ColNum : TColNum] : Integer
read GetWidth write SetWidth;
end;
implementation
{===TOvcTableColumn=====================================================}
constructor TOvcTableColumn.Create(ATable : TOvcTableAncestor);
begin
inherited Create;
FWidth := tbDefColWidth;
FDefCell := nil;
FTable := ATable;
end;
{--------}
destructor TOvcTableColumn.Destroy;
begin
DefaultCell := nil;
inherited Destroy;
end;
{--------}
procedure TOvcTableColumn.Assign(Source : TPersistent);
var
Src : TOvcTableColumn absolute Source;
begin
if not (Source is TOvcTableColumn) then
Exit;
FWidth := Src.Width;
FHidden := Src.Hidden;
DefaultCell := Src.DefaultCell;
end;
{--------}
procedure TOvcTableColumn.tcDoColumnChanged;
begin
if Assigned(FOnColumnChanged) then
FOnColumnChanged(Self, FNumber, 0, taSingle);
end;
{--------}
procedure TOvcTableColumn.tcNotifyCellDeletion(Cell : TOvcBaseTableCell);
begin
if (Cell = FDefCell) then
DefaultCell := nil;
end;
{--------}
procedure TOvcTableColumn.SetDefCell(BTC : TOvcBaseTableCell);
var
DoIt : boolean;
begin
DoIt := false;
if (BTC <> FDefCell) then
if Assigned(BTC) then
begin
if (BTC.References = 0) or
((BTC.References > 0) and (BTC.Table = FTable)) then
DoIt := true;
end
else
DoIt := true;
if DoIt then
begin
if Assigned(FDefCell) then
FDefCell.DecRefs;
FDefCell := BTC;
if Assigned(FDefCell) then
begin
if (FDefCell.References = 0) then
FDefCell.Table := FTable;
FDefCell.IncRefs;
end;
tcDoColumnChanged;
end;
end;
{--------}
procedure TOvcTableColumn.SetHidden(H : boolean);
begin
if (H <> FHidden) then
begin
FHidden := H;
tcDoColumnChanged;
end;
end;
{--------}
procedure TOvcTableColumn.SetWidth(W : Integer);
begin
if (W <> FWidth) then
begin
FWidth := W;
tcDoColumnChanged;
end;
end;
{====================================================================}
{===TOvcTableColumns=======================================================}
constructor TOvcTableColumns.Create(ATable : TOvcTableAncestor;
ANumber : Integer;
AColumnClass : TOvcTableColumnClass);
var
i : Integer;
Col : TOvcTableColumn;
begin
inherited Create;
FTable := ATable;
FList := TList.Create;
tcColumnClass := AColumnClass;
for i := 0 to pred(ANumber) do
begin
Col := AColumnClass.Create(FTable);
Col.Number := i;
Append(Col);
end;
end;
{--------}
destructor TOvcTableColumns.Destroy;
begin
if Assigned(FList) then
begin
OnColumnChanged := nil;
Clear;
FList.Free;
end;
FFixups.Free;
end;
{--------}
procedure TOvcTableColumns.Append(C : TOvcTableColumn);
begin
if (FList.Count = Classes.MaxListSize) then
TableErrorRes(SCTableMaxColumns);
if (C.Table <> FTable) or (not (C is tcColumnClass)) then
Exit;
C.Number := FList.Count;
FList.Add(C);
C.OnColumnChanged := FOnColumnChanged;
tcDoColumnChanged(C.Number, 0, taInsert);
end;
{--------}
procedure TOvcTableColumns.Clear;
var
i : Integer;
begin
for i := 0 to pred(FList.Count) do
TOvcTableColumn(FList[i]).Free;
FList.Clear;
tcDoColumnChanged(0, 0, taAll);
end;
{--------}
procedure TOvcTableColumns.Delete(ColNum : TColNum);
var
i : integer;
begin
if (0 <= ColNum) and (ColNum < FList.Count) then
begin
TOvcTableColumn(FList[ColNum]).Free;
FList.Delete(ColNum);
for i := 0 to pred(FList.Count) do
TOvcTableColumn(FList[i]).Number := i;
tcDoColumnChanged(ColNum, 0, taDelete);
if Assigned(FFixups) then
if (ColNum < FFixups.Count) then
FFixups.Delete(ColNum);
end;
end;
{--------}
procedure TOvcTableColumns.Exchange(ColNum1, ColNum2 : TColNum);
var
Temp1, Temp2 : pointer;
begin
if (ColNum1 <> ColNum2) and
(0 <= ColNum1) and (ColNum1 < FList.Count) and
(0 <= ColNum2) and (ColNum2 < FList.Count) then
begin
Temp1 := FList[ColNum1];
Temp2 := FList[ColNum2];
TOvcTableColumn(Temp1).Number := ColNum2;
TOvcTableColumn(Temp2).Number := ColNum1;
FList[ColNum1] := Temp2;
FList[ColNum2] := Temp1;
tcDoColumnChanged(ColNum1, ColNum2, taExchange);
end;
end;
{--------}
function TOvcTableColumns.GetCol(ColNum : TColNum) : TOvcTableColumn;
begin
if (0 <= ColNum) and (ColNum < FList.Count) then
Result := TOvcTableColumn(FList[ColNum])
else
Result := nil;
end;
{--------}
function TOvcTableColumns.GetCount : Integer;
begin
Result := FList.Count;
end;
{--------}
function TOvcTableColumns.GetDefaultCell(ColNum : TColNum) : TOvcBaseTableCell;
begin
Result := nil;
if (0 <= ColNum) and (ColNum < FList.Count) then
Result := TOvcTableColumn(FList[ColNum]).DefaultCell;
end;
{--------}
function TOvcTableColumns.GetHidden(ColNum : TColNum) : boolean;
begin
Result := True;
if (0 <= ColNum) and (ColNum < FList.Count) then
Result := TOvcTableColumn(FList[ColNum]).Hidden;
end;
{--------}
function TOvcTableColumns.GetWidth(ColNum : TColNum) : Integer;
begin
Result := 0;
if (0 <= ColNum) and (ColNum < FList.Count) then
Result := TOvcTableColumn(FList[ColNum]).Width;
end;
{--------}
procedure TOvcTableColumns.Insert(const ColNum : TColNum;
C : TOvcTableColumn);
var
i : integer;
begin
if (FList.Count = Classes.MaxListSize) then
TableErrorRes(SCTableMaxColumns);
if (C.Table <> FTable) or (not (C is tcColumnClass)) then
Exit;
if (0 <= ColNum) and (ColNum < FList.Count) then
begin
FList.Insert(ColNum, C);
for i := 0 to pred(FList.Count) do
TOvcTableColumn(FList[i]).Number := i;
C.OnColumnChanged := FOnColumnChanged;
tcDoColumnChanged(ColNum, 0, taInsert);
if Assigned(FFixups) then begin
FFixups.Insert(ColNum, 'unknown');
FFixups.Objects[ColNum] := C;
end;
end;
end;
{--------}
procedure TOvcTableColumns.tcDoColumnChanged(ColNum1, ColNum2 : TColNum;
Action : TOvcTblActions);
begin
if Assigned(FOnColumnChanged) then
FOnColumnChanged(Self, ColNum1, ColNum2, Action);
end;
{--------}
procedure TOvcTableColumns.tcNotifyCellDeletion(Cell : TOvcBaseTableCell);
var
ColNum : TColNum;
begin
for ColNum := 0 to pred(FList.Count) do
TOvcTableColumn(FList[ColNum]).tcNotifyCellDeletion(Cell);
end;
{--------}
procedure TOvcTableColumns.SetCol(ColNum : TColNum; C : TOvcTableColumn);
var
PC : TOvcTableColumn;
begin
if (C.Table <> FTable) or (not (C is tcColumnClass)) then
Exit;
if (0 <= ColNum) and (ColNum < FList.Count) then
begin
PC := GetCol(ColNum);
PC.Assign(C);
end;
end;
{--------}
procedure TOvcTableColumns.SetCount(C : Integer);
var
ColNum : TColNum;
Col : TOvcTableColumn;
begin
if (C > 0) and (C <> Count) then
if (C < Count) then
begin
{must destroy the end set of columns}
for ColNum := pred(Count) downto C do
Delete(ColNum);
end
else {C > Count}
begin
{must add some new columns on the end}
for ColNum := Count to pred(C) do
begin
Col := tcColumnClass.Create(FTable);
Col.Number := ColNum;
Append(Col);
end;
end;
end;
{--------}
procedure TOvcTableColumns.SetDefaultCell(ColNum : TColNum; C : TOvcBaseTableCell);
begin
if (0 <= ColNum) and (ColNum < FList.Count) then
TOvcTableColumn(FList[ColNum]).DefaultCell := C;
end;
{--------}
procedure TOvcTableColumns.SetHidden(ColNum : TColNum; H : boolean);
begin
if (0 <= ColNum) and (ColNum < FList.Count) then
TOvcTableColumn(FList[ColNum]).Hidden := H;
end;
{--------}
procedure TOvcTableColumns.SetOnColumnChanged(OC : TColChangeNotifyEvent);
var
i : Integer;
begin
FOnColumnChanged := OC;
for i := 0 to pred(FList.Count) do
TOvcTableColumn(FList[i]).OnColumnChanged := OC;
end;
{--------}
procedure TOvcTableColumns.SetWidth(ColNum : TColNum; W : Integer);
begin
if (0 <= ColNum) and (ColNum < FList.Count) then
TOvcTableColumn(FList[ColNum]).Width := W;
end;
{--------}
function TOvcTableColumns.tcStartLoading : TStringList;
begin
if Assigned(FFixups) then
FFixups.Clear
else
FFixups := TStringList.Create;
Result := FFixups;
end;
{--------}
procedure TOvcTableColumns.tcStopLoading;
{------}
function GetImmediateParentForm(Control : TControl) : TWinControl;
var
ParentCtrl : TControl;
begin
ParentCtrl := Control.Parent;
while (Assigned(ParentCtrl)) and
(not (ParentCtrl is TCustomForm))
{$IFDEF VERSION5}
and (not (ParentCtrl is TCustomFrame))
{$ENDIF}
do
ParentCtrl := ParentCtrl.Parent;
Result := TForm(ParentCtrl);
end;
{------}
function GetFormName(const S, FormName : string) : string;
var
PosDot : integer;
begin
PosDot := Pos('.', S);
if (PosDot <> 0) then
Result := Copy(S, 1, pred(PosDot))
else
Result := FormName;
end;
{------}
function FormNamesEqual(const CmptFormName, FormName : string) : boolean;
var
PosUL : integer;
begin
Result := true;
if (FormName = '') or (CmptFormName = FormName) then
Exit;
PosUL := length(FormName);
while (PosUL > 0) and (FormName[PosUL] <> '_') do
dec(PosUL);
if (PosUL > 0) then
if (CmptFormName = Copy(FormName, 1, pred(PosUL))) then
Exit;
Result := false;
end;
{------}
function GetComponentName(const S : string) : string;
var
PosDot : integer;
begin
PosDot := Pos('.', S);
if (PosDot <> 0) then
Result := Copy(S, succ(PosDot), length(S))
else
Result := S;
end;
{------}
var
i : integer;
Form : TWinControl;
Compnt : TComponent;
DM : integer;
DataMod: TDataModule;
DMCount: integer;
begin
{if there's nothing to fix up, exit now}
if not Assigned(FFixups) then
Exit;
{fixup references to cell components on the table's form}
try
Form := GetImmediateParentForm(FTable);
for i := pred(FFixups.Count) downto 0 do
if FormNamesEqual(GetFormName(FFixups[i], Form.Name),
Form.Name) then
begin
Compnt := Form.FindComponent(GetComponentName(FFixups[i]));
if Assigned(Compnt) and (Compnt is TOvcBaseTableCell) then
begin
TOvcTableColumn(FFixups.Objects[i]).DefaultCell := TOvcBaseTableCell(Compnt);
FFixups.Delete(i);
end;
end;
{fixup references to cell components on any data modules}
if (FFixups.Count <> 0) then begin
DM := 0;
//{$IFNDEF LCL}
DMCount := Screen.DataModuleCount;
//{$ELSE}
// DMCount := 0;
//{$ENDIF}
while (FFixups.Count > 0) and (DM < DMCount) do begin
//{$IFNDEF LCL}
DataMod := Screen.DataModules[DM];
//{$ENDIF}
for i := pred(FFixups.Count) downto 0 do
if (GetFormName(FFixups[i], Form.Name) = DataMod.Name) then begin
Compnt := DataMod.FindComponent(GetComponentName(FFixups[i]));
if Assigned(Compnt) and (Compnt is TOvcBaseTableCell) then begin
TOvcTableColumn(FFixups.Objects[i]).DefaultCell
:= TOvcBaseTableCell(Compnt);
FFixups.Delete(i);
end;
end;
inc(DM);
end;
end;
finally
FFixups.Free;
FFixups := nil;
end;
end;
{====================================================================}
end.