|
From: <na...@us...> - 2009-04-07 10:07:50
|
Revision: 801
http://instantobjects.svn.sourceforge.net/instantobjects/revision/?rev=801&view=rev
Author: nandod
Date: 2009-04-07 10:07:35 +0000 (Tue, 07 Apr 2009)
Log Message:
-----------
* Fixed error 'Control "" has no parent window' when creating controls such as TDBMemo in overridden CreateObjectEditor method.
Modified Paths:
--------------
trunk/Source/Core/InstantExplorer.pas
Modified: trunk/Source/Core/InstantExplorer.pas
===================================================================
--- trunk/Source/Core/InstantExplorer.pas 2009-03-21 23:32:31 UTC (rev 800)
+++ trunk/Source/Core/InstantExplorer.pas 2009-04-07 10:07:35 UTC (rev 801)
@@ -627,6 +627,7 @@
Result := TPanel.Create(AOwner);
Result.BevelInner := bvNone;
Result.BevelOuter := bvNone;
+ Result.Parent := Self;
end;
procedure TInstantExplorer.CreateSplitter;
|
|
From: <na...@us...> - 2009-08-20 09:27:21
|
Revision: 855
http://instantobjects.svn.sourceforge.net/instantobjects/revision/?rev=855&view=rev
Author: nandod
Date: 2009-08-20 09:27:11 +0000 (Thu, 20 Aug 2009)
Log Message:
-----------
* InstantExplorer enhancements:
* use checkboxes for boolean fields
* use comboboxes for string fields if an event handler provides a picklist.
* ability to order fields and hide specific fields in the object editor through an event.
* Automatic labels from CamelCaps property names.
Modified Paths:
--------------
trunk/Source/Core/InstantExplorer.pas
Modified: trunk/Source/Core/InstantExplorer.pas
===================================================================
--- trunk/Source/Core/InstantExplorer.pas 2009-08-20 09:23:30 UTC (rev 854)
+++ trunk/Source/Core/InstantExplorer.pas 2009-08-20 09:27:11 UTC (rev 855)
@@ -46,7 +46,7 @@
{$IFDEF LINUX}
QControls, QForms, QComCtrls, QExtCtrls, QDBGrids, QImgList,
{$ENDIF}
- Classes, Db, InstantPersistence, InstantPresentation;
+ Classes, DB, TypInfo, InstantPersistence, InstantPresentation, DbCtrls;
type
TInstantExplorer = class;
@@ -87,13 +87,45 @@
const Value: string; var NodeData: TInstantExplorerNodeData) of object;
TInstantExplorerGetNodeTextEvent = procedure(Sender: TInstantExplorer;
NodeData: TInstantExplorerNodeData; var Text: string) of object;
-
+ TInstantExplorerGetAllowedValuesEvent = procedure (Sender: TInstantExplorer;
+ const AObject: TObject; const APropName: string;
+ const AAllowedValues: TStrings) of object;
+ TInstantExplorerGetFieldNamesEvent = procedure (Sender: TInstantExplorer;
+ const AObject: TObject; const AFieldNames: TStrings) of object;
+
TInstantExplorerLayout = (loTreeOnly, loDetailOnly, loVertical, loHorizontal);
+ TInstantExplorerDBComboBox = class(TDBComboBox)
+ private
+ procedure ApplyToRecord;
+ protected
+ procedure Change; override;
+ procedure Click; override;
+ end;
+
+ TInstantExplorerDBGrid = class(TDBGrid)
+ private
+ procedure UpdateLastColumnWidth;
+ protected
+ procedure Resize; override;
+ end;
+
+ TInstantExplorerContentEditor = class(TPanel)
+ private
+ FGrid: TInstantExplorerDBGrid;
+ function GetDataSource: TDataSource;
+ procedure SetDataSource(const AValue: TDataSource);
+ function GetGrid: TDBGrid;
+ public
+ constructor Create(AOwner: TComponent); override;
+ property Grid: TDBGrid read GetGrid;
+ property DataSource: TDataSource read GetDataSource write SetDataSource;
+ end;
+
TInstantExplorer = class(TCustomControl)
private
FAutoAdjust: Boolean;
- FContentEditor: TDBGrid;
+ FContentEditor: TInstantExplorerContentEditor;
FContentView: TPanel;
FDetailPanel: TPanel;
FDetailView: TPanel;
@@ -115,6 +147,8 @@
FOnGetImageIndex: TInstantExplorerNodeEvent;
FOnGetNodeText: TInstantExplorerGetNodeTextEvent;
FOnIncludeNode: TInstantExplorerIncludeNodeEvent;
+ FOnGetAllowedValues: TInstantExplorerGetAllowedValuesEvent;
+ FOnGetFieldNames: TInstantExplorerGetFieldNamesEvent;
function AddNode(NodeType: TInstantExplorerNodeType; Parent: TTreeNode;
Name: string; AObject: TObject; Value: string = ''): TTreeNode;
procedure ArrangeControls;
@@ -130,12 +164,15 @@
procedure DestroyObjectEditor;
procedure ExpandNode(Node: TTreeNode);
function GetCurrentObject: TObject;
+ procedure GetAllowedValues(const AObject: TObject;
+ const APropName: string; const AAllowedValues: TStrings);
function GetImages: TCustomImageList;
procedure LoadContainerNode(Node: TTreeNode; Container: TInstantContainer);
procedure LoadNode(Node: TTreeNode; LoadChildren: Boolean);
procedure LoadObjectNode(Node: TTreeNode; Instance: TObject;
var ChildCount: Integer; LoadChildren: Boolean);
function NodeIsLoaded(Node: TTreeNode): Boolean;
+ procedure ObjectExposerAfterDelete(Sender: TDataSet);
procedure ObjectExposerAfterPost(Sender: TDataSet);
procedure ResizeControls;
procedure SetAutoAdjust(const Value: Boolean);
@@ -146,10 +183,13 @@
var AllowExpansion: Boolean);
procedure TreeViewGetImageIndex(Sender: TObject; Node: TTreeNode);
procedure TreeViewNodeDeletion(Sender: TObject; Node: TTreeNode);
+ procedure SetCurrentObject(const AValue: TObject);
+ function GetContentEditor: TWinControl;
+ function CreateFieldList: TStrings;
protected
procedure ChangeNode(Node: TTreeNode); virtual;
function CreateContentEditor(AOwner: TComponent;
- DataSource: TDataSource): TDBGrid; virtual;
+ DataSource: TDataSource): TInstantExplorerContentEditor; virtual;
function CreateExposer: TInstantExposer; virtual;
function CreateNode(Nodes: TTreeNodes; Parent: TTreeNode;
NodeData: TInstantExplorerNodeData): TTreeNode; virtual;
@@ -170,13 +210,15 @@
procedure SetRootObject(const Value: TObject); virtual;
procedure UpdateDetails;
public
+ procedure SetupContentEditor;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Clear;
procedure Refresh;
procedure RefreshNode(Node: TTreeNode);
+ property ContentEditor: TWinControl read GetContentEditor;
property ContentView: TPanel read FContentView;
- property CurrentObject: TObject read GetCurrentObject;
+ property CurrentObject: TObject read GetCurrentObject write SetCurrentObject;
property DetailPanel: TPanel read FDetailPanel;
property DetailView: TPanel read FDetailView write SetDetailView;
property ObjectExposer: TInstantExposer read FObjectExposer;
@@ -206,6 +248,10 @@
property OnCreateNodeData: TInstantExplorerCreateNodeDataEvent read FOnCreateNodeData write FOnCreateNodeData;
property OnClick;
property OnDblClick;
+ property OnGetAllowedValues: TInstantExplorerGetAllowedValuesEvent
+ read FOnGetAllowedValues write FOnGetAllowedValues;
+ property OnGetFieldNames: TInstantExplorerGetFieldNamesEvent
+ read FOnGetFieldNames write FOnGetFieldNames;
property OnGetImageIndex: TInstantExplorerNodeEvent read FOnGetImageIndex write FOnGetImageIndex;
property OnGetNodeText: TInstantExplorerGetNodeTextEvent read FOnGetNodeText write FOnGetNodeText;
property OnIncludeNode: TInstantExplorerIncludeNodeEvent read FOnIncludeNode write FOnIncludeNode;
@@ -220,10 +266,10 @@
implementation
uses
- SysUtils, InstantClasses, InstantRtti, TypInfo, InstantMetadata,
+ SysUtils, Math, InstantClasses, InstantRtti, InstantMetadata,
InstantTypes,
{$IFDEF MSWINDOWS}
- Graphics, StdCtrls, DbCtrls, Windows;
+ Graphics, StdCtrls, Windows;
{$ENDIF}
{$IFDEF LINUX}
QGraphics, QStdCtrls, QDbCtrls;
@@ -232,6 +278,8 @@
const
NotLoaded = Pointer(-1);
+ MAX_DROPDOWN_ITEMS = 10;
+
procedure InstantExploreObject(AObject: TObject);
var
Form: TForm;
@@ -261,6 +309,28 @@
end;
end;
+// Converts CamelCaps to words with spaces among them.
+function Beautify(const APropName: string): string;
+var
+ LCharIndex: Integer;
+ LLastWasSpace: Boolean;
+begin
+ Result := '';
+ LLastWasSpace := False;
+ for LCharIndex := 1 to Length(APropName) do
+ begin
+ if (APropName[LCharIndex] = AnsiUpperCase(APropName[LCharIndex])[1]) and not LLastWasSpace then
+ begin
+ Result := Result + ' ';
+ LLastWasSpace := True;
+ end
+ else
+ LLastWasSpace := False;
+ Result := Result + APropName[LCharIndex];
+ end;
+end;
+
+
{ TInstantExplorerNodeData }
constructor TInstantExplorerNodeData.Create(ANodeType: TInstantExplorerNodeType;
@@ -394,21 +464,19 @@
procedure TInstantExplorer.AssignRootObject(Value: TObject);
var
Node: TTreeNode;
- ItemIndex: Integer;
+ LCurrentObject: TObject;
SaveOnChange: TTVChangedEvent;
ChildCount: Integer;
-
begin
- ItemIndex := 0;
+ LCurrentObject := nil;
with TreeView do
begin
SaveOnChange := OnChange;
OnChange := nil;
Items.BeginUpdate;
try
-
if Assigned(Selected) then
- ItemIndex := Selected.AbsoluteIndex;
+ LCurrentObject := TinstantExplorerNodeData(Selected.Data).Instance;
Items.Clear;
FRootObject := Value;
if Assigned(FRootObject) then
@@ -427,12 +495,8 @@
finally
Items.EndUpdate;
OnChange := SaveOnChange;
- if Items.Count > ItemIndex then
- Selected := Items[ItemIndex]
- else begin
- Selected := nil;
- TreeViewChange(TreeView, nil);
- end;
+ CurrentObject := LCurrentObject;
+ TreeView.FullExpand;
end;
end;
end;
@@ -466,26 +530,22 @@
end;
function TInstantExplorer.CreateContentEditor(AOwner: TComponent;
- DataSource: TDataSource): TDBGrid;
-var
- Grid: TDBGrid;
+ DataSource: TDataSource): TInstantExplorerContentEditor;
begin
- Grid := TDBGrid.Create(AOwner);
- Grid.DataSource := DataSource;
- Grid.BorderStyle := bsNone;
- Result := Grid;
+ Result := TInstantExplorerContentEditor.Create(AOwner);
+ Result.DataSource := DataSource;
end;
procedure TInstantExplorer.CreateContentView;
begin
FContentView := CreatePanel(Self);
+ FContentView.Parent := DetailPanel;
FContentEditor := CreateContentEditor(FContentView, ObjectSource);
if Assigned(FContentEditor) then
with FContentEditor do
begin
Align := alClient;
Parent := FContentView;
- Show;
end;
end;
@@ -494,6 +554,7 @@
FDetailPanel := CreatePanel(Self);
with FDetailPanel do
begin
+ Parent := Self;
BorderStyle := bsSingle;
Height := Self.Height div 2;
Align := alClient;
@@ -545,74 +606,170 @@
function TInstantExplorer.CreateObjectEditor(AOwner: TComponent;
DataSource: TDataSource): TControl;
+const
+ LABEL_WIDTH = 132;
+ LABEL_LEFT = 8;
+ VERT_SPACING = 4;
+ MIN_CONTROL_WIDTH = 24;
procedure CreateEditControl(AParent: TWinControl; var ATop: Integer;
PropInfo: PPropInfo; ADataSource: TDataSource);
var
- Edit: TDBEdit;
+ LControl: TWinControl;
+ LAllowedValues: TStrings;
begin
- Edit := TDBEdit.Create(AParent);
- with Edit do
- begin
- Left := 108;
- Top := ATop;
- Anchors := [akLeft, akTop, akRight];
- Constraints.MinWidth := 8;
- Width := AParent.Width - Left - 8;
- Anchors := [akLeft, akTop, akRight];
- Parent := AParent;
- DataField := InstantGetPropName(PropInfo);
- DataSource := ADataSource;
- if not Assigned(PropInfo.SetProc) then
+ case DataSource.DataSet.FieldByName(InstantGetPropName(PropInfo)).DataType of
+ ftMemo:
begin
- ReadOnly := True;
- Color := clBtnFace;
+ LControl := TDBMemo.Create(AParent);
+ with TDBMemo(LControl) do
+ begin
+ Left := LABEL_LEFT + LABEL_WIDTH;
+ Top := ATop;
+ Anchors := [akLeft, akTop, akRight];
+ Constraints.MinWidth := MIN_CONTROL_WIDTH;
+ Parent := AParent;
+ Anchors := [akLeft, akTop, akRight];
+ Width := Parent.Width - Left - 8;
+ DataField := InstantGetPropName(PropInfo);
+ DataSource := ADataSource;
+ if not Assigned(PropInfo.SetProc) then
+ begin
+ ReadOnly := True;
+ Color := clBtnFace;
+ end;
+ end;
end;
+ ftBoolean:
+ begin
+ LControl := TDBCheckBox.Create(AParent);
+ with TDBCheckBox(LControl) do
+ begin
+ Left := LABEL_LEFT + LABEL_WIDTH;
+ Top := ATop;
+ Width := 16;
+ Parent := AParent;
+ DataField := InstantGetPropName(PropInfo);
+ DataSource := ADataSource;
+ if not Assigned(PropInfo.SetProc) then
+ begin
+ ReadOnly := True;
+ Color := clBtnFace;
+ end;
+ end;
+ end
+ else
+ begin
+ LAllowedValues := TStringList.Create;
+ try
+ GetAllowedValues(ObjectExposer.CurrentObject, InstantGetPropName(PropInfo), LAllowedValues);
+ if LAllowedValues.Count > 0 then
+ begin
+ LControl := TInstantExplorerDBComboBox.Create(AParent);
+ with TInstantExplorerDBComboBox(LControl) do
+ begin
+ Left := LABEL_LEFT + LABEL_WIDTH;
+ Top := ATop;
+ Anchors := [akLeft, akTop, akRight];
+ Constraints.MinWidth := MIN_CONTROL_WIDTH;
+ Width := AParent.Width - Left - 8;
+ Anchors := [akLeft, akTop, akRight];
+ Parent := AParent;
+ Items := LAllowedValues;
+ Style := csDropDownList;
+ DataField := InstantGetPropName(PropInfo);
+ DataSource := ADataSource;
+ if not Assigned(PropInfo.SetProc) then
+ begin
+ ReadOnly := True;
+ Color := clBtnFace;
+ end;
+ end;
+ end
+ else
+ begin
+ LControl := TDBEdit.Create(AParent);
+ with TDBEdit(LControl) do
+ begin
+ Left := LABEL_LEFT + LABEL_WIDTH;
+ Top := ATop;
+ Anchors := [akLeft, akTop, akRight];
+ Constraints.MinWidth := MIN_CONTROL_WIDTH;
+ Width := AParent.Width - Left - 8;
+ Anchors := [akLeft, akTop, akRight];
+ Parent := AParent;
+ DataField := InstantGetPropName(PropInfo);
+ DataSource := ADataSource;
+ if not Assigned(PropInfo.SetProc) then
+ begin
+ ReadOnly := True;
+ Color := clBtnFace;
+ end;
+ end;
+ end;
+ finally
+ FreeAndNil(LAllowedValues);
+ end;
+ end;
end;
+
with TLabel.Create(AParent) do
begin
- Left := 8;
+ Left := LABEL_LEFT;
Top := ATop + 3;
Parent := AParent;
- Caption := InstantGetPropName(PropInfo);
- FocusControl := Edit;
+ Caption := Beautify(InstantGetPropName(PropInfo));
+ FocusControl := LControl;
end;
- Inc(ATop, Edit.Height);
+ Inc(ATop, LControl.Height);
end;
var
I, Top: Integer;
AObject: TObject;
Editor: TScrollBox;
+ LProperties: TInstantProperties;
+ LFieldNames: TStrings;
+ LFieldIndex: Integer;
begin
Editor := TScrollBox.Create(AOwner);
with Editor do
begin
BorderStyle := bsNone;
Align := alClient;
+ Parent := ObjectView;
end;
AObject := ObjectExposer.CurrentObject;
- Top := 4;
- with TInstantProperties.Create(AObject) do
+ Top := VERT_SPACING;
+ LProperties := TInstantProperties.Create(AObject);
try
- for I := 0 to Pred(Count) do
- if Types[I] <> tkClass then
+ LFieldNames := CreateFieldList;
+ try
+ for LFieldIndex := 0 to LFieldNames.Count - 1 do
begin
- Inc(Top, 4);
- CreateEditControl(Editor, Top, PropInfos[I], DataSource);
+ for I := 0 to Pred(LProperties.Count) do
+ begin
+ if (LProperties.Types[I] <> tkClass) and (LProperties.Names[I] = LFieldNames[LFieldIndex]) then
+ begin
+ Inc(Top, VERT_SPACING);
+ CreateEditControl(Editor, Top, LProperties.PropInfos[I], DataSource);
+ end;
+ end;
end;
+ finally
+ LFieldNames.Free;
+ end;
finally
- Free;
+ LProperties.Free;
end;
- Editor.Parent := ObjectView;
Result := Editor;
end;
procedure TInstantExplorer.CreateObjectExposer;
begin
FObjectExposer := CreateExposer;
- if Assigned(FObjectExposer) then
- FObjectExposer.AfterPost := ObjectExposerAfterPost;
+ FObjectExposer.AfterPost := ObjectExposerAfterPost;
+ FObjectExposer.AfterDelete := ObjectExposerAfterDelete;
FObjectSource := TDataSource.Create(Self);
FObjectSource.DataSet := FObjectExposer;
end;
@@ -620,6 +777,7 @@
procedure TInstantExplorer.CreateObjectView;
begin
FObjectView := CreatePanel(Self);
+ FObjectView.Parent := DetailPanel;
end;
function TInstantExplorer.CreatePanel(AOwner: TComponent): TPanel;
@@ -634,6 +792,9 @@
FSplitter := TSplitter.Create(Self);
with FSplitter do
begin
+ Parent := Self;
+ AutoSnap := False;
+ MinSize := 30;
Top := FTreePanel.Top + FTreePanel.Height + 1;
Align := alTop;
end;
@@ -644,6 +805,7 @@
FTreePanel := CreatePanel(Self);
with FTreePanel do
begin
+ Parent := Self;
Align := alTop;
FTreeView := CreateTreeView(FTreePanel);
with FTreeView do
@@ -689,6 +851,18 @@
LoadNode(Node, True);
end;
+procedure TInstantExplorer.GetAllowedValues(const AObject: TObject;
+ const APropName: string; const AAllowedValues: TStrings);
+begin
+ if Assigned(FOnGetAllowedValues) then
+ FOnGetAllowedValues(Self, AObject, APropName, AAllowedValues);
+end;
+
+function TInstantExplorer.GetContentEditor: TWinControl;
+begin
+ Result := FContentEditor;
+end;
+
function TInstantExplorer.GetCurrentObject: TObject;
begin
with TreeView do
@@ -855,9 +1029,14 @@
procedure TInstantExplorer.ObjectExposerAfterPost(Sender: TDataSet);
begin
- RefreshNode(TreeView.Selected);
+ Refresh;
end;
+procedure TInstantExplorer.ObjectExposerAfterDelete(Sender: TDataSet);
+begin
+ Refresh;
+end;
+
procedure TInstantExplorer.Refresh;
begin
AssignRootObject(FRootObject);
@@ -902,21 +1081,32 @@
end;
end;
+procedure TInstantExplorer.SetCurrentObject(const AValue: TObject);
+var
+ LNodeIndex: Integer;
+begin
+ for LNodeIndex := 0 to TreeView.Items.Count - 1 do
+ begin
+ if Integer(TreeView.Items[LNodeIndex].Data) > 0 then
+ if TInstantExplorerNodeData(TreeView.Items[LNodeIndex].Data).Instance = AValue then
+ begin
+ TreeView.Selected := TreeView.Items[LNodeIndex];
+ Break;
+ end;
+ end;
+end;
+
procedure TInstantExplorer.SetDetailView(const Value: TPanel);
begin
if Value <> FDetailView then
begin
if Assigned(FDetailView) then
- begin
- FDetailView.Hide;
- FDetailView.Parent := nil;
- end;
+ FDetailView.Visible := False;
FDetailView := Value;
if Assigned(FDetailView) then
begin
FDetailView.Align := alClient;
- FDetailView.Parent := DetailPanel;
- FDetailView.Show;
+ FDetailView.Visible := True;
end;
end;
end;
@@ -1007,7 +1197,9 @@
ObjectExposer.ContainerName := Container.Name;
ObjectExposer.Subject := Container.Owner;
DetailView := ContentView;
- end else if Assigned(AObject) then
+ SetupContentEditor;
+ end
+ else if Assigned(AObject) then
begin
if AObject.ClassType <> ObjectExposer.ObjectClass then
DestroyObjectEditor;
@@ -1023,6 +1215,156 @@
ObjectExposer.Subject := nil;
DetailView := nil;
end;
+ // Reduces a treeview painting problem in D2007 with runtime themes enabled
+ // and checkboxes in the object editor.
+ Update;
end;
+procedure TInstantExplorer.SetupContentEditor;
+var
+ LColumnIndex: Integer;
+ LField: TField;
+ LFieldNames: TStrings;
+ LFieldIndex: Integer;
+
+begin
+ // Arrange columns.
+ LFieldNames := CreateFieldList;
+ try
+ FContentEditor.Grid.Columns.Clear;
+ for LFieldIndex := 0 to LFieldNames.Count - 1 do
+ with FContentEditor.Grid.Columns.Add do
+ begin
+ FieldName := LFieldNames[LFieldIndex];
+ Width := DefaultWidth;
+ end;
+ finally
+ LFieldNames.Free;
+ end;
+
+ for LColumnIndex := 0 to FContentEditor.Grid.Columns.Count - 1 do
+ begin
+ LField := FContentEditor.Grid.Columns[LColumnIndex].Field;
+ // Beautify caption.
+ FContentEditor.Grid.Columns[LColumnIndex].Title.Caption := Beautify(LField.DisplayLabel);
+ // Add combo box for boolean fields.
+ if LField.DataType = ftBoolean then
+ begin
+ FContentEditor.Grid.Columns[LColumnIndex].PickList.Clear;
+ FContentEditor.Grid.Columns[LColumnIndex].PickList.Add(BoolToStr(True, True));
+ FContentEditor.Grid.Columns[LColumnIndex].PickList.Add(BoolToStr(False, True));
+ end
+ else
+ // Add picklist for all columns.
+ begin
+ FContentEditor.Grid.Columns[LColumnIndex].PickList.Clear;
+ GetAllowedValues(ObjectExposer.CurrentObject,
+ FContentEditor.Grid.Columns[LColumnIndex].FieldName,
+ FContentEditor.Grid.Columns[LColumnIndex].PickList);
+ end;
+ FContentEditor.Grid.Columns[LColumnIndex].DropDownRows :=
+ Min(MAX_DROPDOWN_ITEMS, FContentEditor.Grid.Columns[LColumnIndex].PickList.Count);
+ // Hide detail and memo columns, useless in standard grids.
+ if LField.DataType in [ftBlob, ftMemo, ftDataSet] then
+ FContentEditor.Grid.Columns[LColumnIndex].Visible := False;
+ end;
+end;
+
+function TInstantExplorer.CreateFieldList: TStrings;
+var
+ LFieldIndex: Integer;
+begin
+ Result := TStringList.Create;
+ try
+ for LFieldIndex := 0 to FObjectExposer.FieldCount - 1 do
+ Result.Add(FObjectExposer.Fields[LFieldIndex].FieldName);
+ if Assigned(FOnGetFieldNames) then
+ FOnGetFieldNames(Self, ObjectExposer.CurrentObject, Result);
+ except
+ Result.Free;
+ raise;
+ end;
+end;
+
+{ TInstantExplorerDBGrid }
+
+procedure TInstantExplorerDBGrid.Resize;
+begin
+ inherited;
+ UpdateLastColumnWidth;
+end;
+
+procedure TInstantExplorerDBGrid.UpdateLastColumnWidth;
+
+ function GetAllColumnsWidth(const AMinus: Integer): Integer;
+ var
+ LColumnIndex: Integer;
+ begin
+ Result := 0;
+ for LColumnIndex := 0 to Columns.Count - 1 - AMinus do
+ Inc(Result, Columns[LColumnIndex].Width);
+ end;
+
+begin
+ if Columns.Count >= 1 then
+ Columns[Columns.Count - 1].Width := ClientWidth - GetAllColumnsWidth(1);
+end;
+
+{ TInstantExplorerContentEditor }
+
+constructor TInstantExplorerContentEditor.Create(AOwner: TComponent);
+begin
+ inherited;
+ BevelInner := bvNone;
+ BevelOuter := bvNone;
+
+ FGrid := TInstantExplorerDBGrid.Create(Self);
+ FGrid.Parent := Self;
+ FGrid.Align := alClient;
+end;
+
+function TInstantExplorerContentEditor.GetDataSource: TDataSource;
+begin
+ Result := FGrid.DataSource;
+end;
+
+function TInstantExplorerContentEditor.GetGrid: TDBGrid;
+begin
+ Result := FGrid;
+end;
+
+procedure TInstantExplorerContentEditor.SetDataSource(const AValue: TDataSource);
+begin
+ FGrid.DataSource := AValue;
+end;
+
+{ TInstantExplorerDBComboBox }
+
+procedure TInstantExplorerDBComboBox.ApplyToRecord;
+var
+ LDataLink: TDataLink;
+begin
+ // Provides the auto-apply feature.
+ LDataLink := TDataLink(Perform(CM_GETDATALINK, 0, 0));
+ try
+ LDataLink.UpdateRecord;
+ except
+ SelectAll;
+ SetFocus;
+ raise;
+ end;
+end;
+
+procedure TInstantExplorerDBComboBox.Change;
+begin
+ inherited;
+ ApplyToRecord;
+end;
+
+procedure TInstantExplorerDBComboBox.Click;
+begin
+ inherited;
+ ApplyToRecord;
+end;
+
end.
|
|
From: <na...@us...> - 2009-08-25 14:35:26
|
Revision: 858
http://instantobjects.svn.sourceforge.net/instantobjects/revision/?rev=858&view=rev
Author: nandod
Date: 2009-08-25 14:35:18 +0000 (Tue, 25 Aug 2009)
Log Message:
-----------
* Fixed: content editor was sometimes visible in TInstantExplorer at the wrong time.
Modified Paths:
--------------
trunk/Source/Core/InstantExplorer.pas
Modified: trunk/Source/Core/InstantExplorer.pas
===================================================================
--- trunk/Source/Core/InstantExplorer.pas 2009-08-20 14:17:50 UTC (rev 857)
+++ trunk/Source/Core/InstantExplorer.pas 2009-08-25 14:35:18 UTC (rev 858)
@@ -540,6 +540,7 @@
begin
FContentView := CreatePanel(Self);
FContentView.Parent := DetailPanel;
+ FContentView.Visible := False;
FContentEditor := CreateContentEditor(FContentView, ObjectSource);
if Assigned(FContentEditor) then
with FContentEditor do
@@ -778,6 +779,7 @@
begin
FObjectView := CreatePanel(Self);
FObjectView.Parent := DetailPanel;
+ FObjectView.Visible := False;
end;
function TInstantExplorer.CreatePanel(AOwner: TComponent): TPanel;
|
|
From: <na...@us...> - 2009-08-28 07:36:41
|
Revision: 868
http://instantobjects.svn.sourceforge.net/instantobjects/revision/?rev=868&view=rev
Author: nandod
Date: 2009-08-28 07:36:34 +0000 (Fri, 28 Aug 2009)
Log Message:
-----------
* Made it easier to plug a custom content editor in TInstantExplorer.
Modified Paths:
--------------
trunk/Source/Core/InstantExplorer.pas
Modified: trunk/Source/Core/InstantExplorer.pas
===================================================================
--- trunk/Source/Core/InstantExplorer.pas 2009-08-28 07:34:57 UTC (rev 867)
+++ trunk/Source/Core/InstantExplorer.pas 2009-08-28 07:36:34 UTC (rev 868)
@@ -112,10 +112,12 @@
TInstantExplorerContentEditor = class(TPanel)
private
- FGrid: TInstantExplorerDBGrid;
- function GetDataSource: TDataSource;
- procedure SetDataSource(const AValue: TDataSource);
+ FGrid: TDBGrid;
function GetGrid: TDBGrid;
+ protected
+ function GetDataSource: TDataSource; virtual;
+ procedure SetDataSource(const AValue: TDataSource); virtual;
+ function CreateGrid: TDBGrid; virtual;
public
constructor Create(AOwner: TComponent); override;
property Grid: TDBGrid read GetGrid;
@@ -1320,11 +1322,16 @@
BevelInner := bvNone;
BevelOuter := bvNone;
- FGrid := TInstantExplorerDBGrid.Create(Self);
+ FGrid := CreateGrid;
FGrid.Parent := Self;
FGrid.Align := alClient;
end;
+function TInstantExplorerContentEditor.CreateGrid: TDBGrid;
+begin
+ Result := TInstantExplorerDBGrid.Create(Self);
+end;
+
function TInstantExplorerContentEditor.GetDataSource: TDataSource;
begin
Result := FGrid.DataSource;
|
|
From: <na...@us...> - 2010-09-11 16:46:44
|
Revision: 903
http://instantobjects.svn.sourceforge.net/instantobjects/revision/?rev=903&view=rev
Author: nandod
Date: 2010-09-11 16:46:38 +0000 (Sat, 11 Sep 2010)
Log Message:
-----------
* InstantExplorer fixes and enhancements.
Modified Paths:
--------------
trunk/Source/Core/InstantExplorer.pas
Modified: trunk/Source/Core/InstantExplorer.pas
===================================================================
--- trunk/Source/Core/InstantExplorer.pas 2010-09-11 16:44:56 UTC (rev 902)
+++ trunk/Source/Core/InstantExplorer.pas 2010-09-11 16:46:38 UTC (rev 903)
@@ -122,6 +122,7 @@
constructor Create(AOwner: TComponent); override;
property Grid: TDBGrid read GetGrid;
property DataSource: TDataSource read GetDataSource write SetDataSource;
+ procedure Setup;
end;
TInstantExplorer = class(TCustomControl)
@@ -212,7 +213,7 @@
procedure SetRootObject(const Value: TObject); virtual;
procedure UpdateDetails;
public
- procedure SetupContentEditor;
+ procedure SetupContentEditor; virtual;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Clear;
@@ -497,8 +498,10 @@
finally
Items.EndUpdate;
OnChange := SaveOnChange;
- CurrentObject := LCurrentObject;
- TreeView.FullExpand;
+ if LCurrentObject <> nil then
+ CurrentObject := LCurrentObject
+ else if Items.Count > 0 then
+ Selected := Items[0];
end;
end;
end;
@@ -1089,14 +1092,23 @@
var
LNodeIndex: Integer;
begin
- for LNodeIndex := 0 to TreeView.Items.Count - 1 do
+ if (AValue <> nil) and (TreeView.Items.Count > 0) then
begin
- if Integer(TreeView.Items[LNodeIndex].Data) > 0 then
- if TInstantExplorerNodeData(TreeView.Items[LNodeIndex].Data).Instance = AValue then
- begin
- TreeView.Selected := TreeView.Items[LNodeIndex];
- Break;
- end;
+ for LNodeIndex := 0 to TreeView.Items.Count - 1 do
+ begin
+ if Integer(TreeView.Items[LNodeIndex].Data) > 0 then
+ if TInstantExplorerNodeData(TreeView.Items[LNodeIndex].Data).Instance = AValue then
+ begin
+ TreeView.Selected := TreeView.Items[LNodeIndex];
+ TreeViewChange(TreeView, nil);
+ Break;
+ end;
+ end;
+ end
+ else
+ begin
+ TreeView.Selected := nil;
+ TreeViewChange(TreeView, nil);
end;
end;
@@ -1196,12 +1208,18 @@
begin
DestroyObjectEditor;
Container := TInstantContainer(AObject);
- ObjectExposer.Subject := nil;
- ObjectExposer.Mode := amContent;
- ObjectExposer.ContainerName := Container.Name;
- ObjectExposer.Subject := Container.Owner;
- DetailView := ContentView;
- SetupContentEditor;
+ if (ObjectExposer.Subject <> Container.Owner) or (ObjectExposer.ContainerName <> Container.Name) then
+ begin
+ ObjectExposer.Subject := nil;
+ ObjectExposer.Mode := amContent;
+ ObjectExposer.ContainerName := Container.Name;
+ ObjectExposer.Subject := Container.Owner;
+ end;
+ if DetailView <> ContentView then
+ begin
+ DetailView := ContentView;
+ SetupContentEditor;
+ end;
end
else if Assigned(AObject) then
begin
@@ -1272,6 +1290,7 @@
if LField.DataType in [ftBlob, ftMemo, ftDataSet] then
FContentEditor.Grid.Columns[LColumnIndex].Visible := False;
end;
+ FContentEditor.Setup;
end;
function TInstantExplorer.CreateFieldList: TStrings;
@@ -1311,7 +1330,8 @@
begin
if Columns.Count >= 1 then
- Columns[Columns.Count - 1].Width := ClientWidth - GetAllColumnsWidth(1);
+ Columns[Columns.Count - 1].Width := ClientWidth - GetAllColumnsWidth(1)
+ - IndicatorWidth - GetSystemMetrics(SM_CXVSCROLL);
end;
{ TInstantExplorerContentEditor }
@@ -1347,6 +1367,12 @@
FGrid.DataSource := AValue;
end;
+procedure TInstantExplorerContentEditor.Setup;
+begin
+ if FGrid is TInstantExplorerDBGrid then
+ TInstantExplorerDBGrid(FGrid).UpdateLastColumnWidth;
+end;
+
{ TInstantExplorerDBComboBox }
procedure TInstantExplorerDBComboBox.ApplyToRecord;
|
|
From: <na...@us...> - 2010-11-04 16:23:36
|
Revision: 932
http://instantobjects.svn.sourceforge.net/instantobjects/revision/?rev=932&view=rev
Author: nandod
Date: 2010-11-04 16:23:29 +0000 (Thu, 04 Nov 2010)
Log Message:
-----------
* Removed too heavy borders from one of InstantExplorer's panels.
Modified Paths:
--------------
trunk/Source/Core/InstantExplorer.pas
Modified: trunk/Source/Core/InstantExplorer.pas
===================================================================
--- trunk/Source/Core/InstantExplorer.pas 2010-10-11 14:08:09 UTC (rev 931)
+++ trunk/Source/Core/InstantExplorer.pas 2010-11-04 16:23:29 UTC (rev 932)
@@ -561,7 +561,7 @@
with FDetailPanel do
begin
Parent := Self;
- BorderStyle := bsSingle;
+ BorderStyle := bsNone;
Height := Self.Height div 2;
Align := alClient;
end;
|
|
From: <car...@us...> - 2014-11-26 10:21:41
|
Revision: 968
http://sourceforge.net/p/instantobjects/code/968
Author: carlobar
Date: 2014-11-26 10:21:38 +0000 (Wed, 26 Nov 2014)
Log Message:
-----------
Fix InstantExplore for refreshing virtual containers.
Modified Paths:
--------------
trunk/Source/Core/InstantExplorer.pas
Modified: trunk/Source/Core/InstantExplorer.pas
===================================================================
--- trunk/Source/Core/InstantExplorer.pas 2014-11-26 10:20:23 UTC (rev 967)
+++ trunk/Source/Core/InstantExplorer.pas 2014-11-26 10:21:38 UTC (rev 968)
@@ -60,12 +60,13 @@
FName: string;
FInstance: TObject;
FValue: string;
+ FLevel: integer;
protected
function GetCaption: string; virtual;
function GetImageIndex: Integer; virtual;
public
- constructor Create(ANodeType: TInstantExplorerNodeType; AName: string;
- AInstance: TObject; AValue: string);
+ constructor Create(ANodeType: TInstantExplorerNodeType; const AName: string;
+ AInstance: TObject; const AValue: string; const ALevel: integer);
destructor Destroy; override;
property Caption: string read GetCaption;
property ImageIndex: Integer read GetImageIndex;
@@ -73,6 +74,7 @@
property Name: string read FName;
property NodeType: TInstantExplorerNodeType read FNodeType;
property Value: string read FValue;
+ property Level: integer read FLevel;
end;
TInstantExplorerNodeEvent = procedure(Sender: TInstantExplorer;
@@ -200,7 +202,7 @@
NodeData: TInstantExplorerNodeData): TTreeNode; virtual;
function CreateNodeData(NodeType: TInstantExplorerNodeType;
const Name: string; AObject: TObject;
- const Value: string): TInstantExplorerNodeData; virtual;
+ const Value: string; const Level: integer): TInstantExplorerNodeData; virtual;
function CreateObjectEditor(AOwner: TComponent;
DataSource: TDataSource): TControl; virtual;
function CreateTreeView(AOwner: TComponent): TTreeView; virtual;
@@ -213,7 +215,7 @@
procedure SetImages(const Value: TCustomImageList); virtual;
procedure SetNodeTypes(const Value: TInstantExplorerNodeTypes); virtual;
procedure SetRootObject(const Value: TObject); virtual;
- procedure UpdateDetails;
+ procedure UpdateDetails(ForceRefresh: boolean = False);
function GetAttributesCount(Instance: TInstantObject): integer; virtual;
function GetAttribute(Instance: TInstantObject; I: integer): TObject; virtual;
public
@@ -341,10 +343,11 @@
{ TInstantExplorerNodeData }
constructor TInstantExplorerNodeData.Create(ANodeType: TInstantExplorerNodeType;
- AName: string; AInstance: TObject; AValue: string);
+ const AName: string; AInstance: TObject; const AValue: string; const ALevel: integer);
begin
FNodeType := ANodeType;
FName := AName;
+ FLevel := ALevel;
FInstance := AInstance;
if (FNodeType = ntObject) and (FInstance is TInstantObject) then
TInstantObject(FInstance).AddRef;
@@ -400,8 +403,13 @@
Parent: TTreeNode; Name: string; AObject: TObject; Value: string): TTreeNode;
var
NodeData: TInstantExplorerNodeData;
+ LLevel: integer;
begin
- NodeData := CreateNodeData(NodeType, Name, AObject, Value);
+ if Assigned(Parent) then
+ LLevel := Parent.Level
+ else
+ LLevel := 0;
+ NodeData := CreateNodeData(NodeType, Name, AObject, Value, LLevel);
if Assigned(NodeData) then
begin
if IncludeNode(NodeData) then
@@ -608,14 +616,14 @@
function TInstantExplorer.CreateNodeData(
NodeType: TInstantExplorerNodeType; const Name: string; AObject: TObject;
- const Value: string): TInstantExplorerNodeData;
+ const Value: string; const Level: integer): TInstantExplorerNodeData;
begin
if Assigned(FOnCreateNodeData) then
begin
Result := nil;
FOnCreateNodeData(Self, NodeType, Name, AObject, Value, Result);
end else
- Result := TInstantExplorerNodeData.Create(NodeType, Name, AObject, Value);
+ Result := TInstantExplorerNodeData.Create(NodeType, Name, AObject, Value, Level);
end;
function TInstantExplorer.CreateObjectEditor(AOwner: TComponent;
@@ -953,11 +961,7 @@
Instance := NodeData.Instance;
ChildCount := 0;
if Instance is TInstantContainer then
- begin
- if (Instance is TInstantReferences) and (TInstantReferences(Instance).Metadata.StorageKind = skVirtual) then
- TInstantReferences(Instance).Owner.Refresh;
- LoadContainerNode(Node, TInstantContainer(Instance));
- end
+ LoadContainerNode(Node, TInstantContainer(Instance))
else if Instance is TInstantQuery then
LoadInstantQueryNode(Node, TInstantQuery(Instance))
else
@@ -1109,10 +1113,18 @@
procedure TInstantExplorer.RefreshNode(Node: TTreeNode);
var
IsExpanded: Boolean;
+ NodeData: TInstantExplorerNodeData;
+ Container: TInstantContainer;
begin
if not Assigned(Node) then
Exit;
IsExpanded := Node.Expanded;
+ if NodeDataIsAssigned(Node) then
+ begin
+ NodeData := TInstantExplorerNodeData(Node.Data);
+ if (NodeData.Instance is TInstantReferences) and (TInstantReferences(NodeData.Instance).isVirtual) then
+ UpdateDetails(True);
+ end;
LoadNode(Node, IsExpanded);
if IsExpanded then
Node.Expand(False);
@@ -1249,13 +1261,14 @@
end;
end;
-procedure TInstantExplorer.UpdateDetails;
+procedure TInstantExplorer.UpdateDetails(ForceRefresh: boolean = False);
var
AObject: TObject;
Container: TInstantContainer;
InstantQuery: TInstantQuery;
begin
- ObjectExposer.PostChanges;
+ if not ForceRefresh then
+ ObjectExposer.PostChanges;
if Layout = loTreeOnly then
begin
ObjectExposer.Subject := nil;
@@ -1268,11 +1281,15 @@
Container := TInstantContainer(AObject);
if (ObjectExposer.Subject <> Container.Owner) or (ObjectExposer.ContainerName <> Container.Name) then
begin
+ ObjectExposer.Close;
ObjectExposer.Subject := nil;
ObjectExposer.Mode := amContent;
ObjectExposer.ContainerName := Container.Name;
ObjectExposer.Subject := Container.Owner;
- end;
+ end
+ else if ForceRefresh then
+ Container.Owner.Refresh;
+
if DetailView <> ContentView then
begin
DetailView := ContentView;
|