486 lines
15 KiB
ObjectPascal
486 lines
15 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: JvDataProviderDesignerForm.pas, released on --.
|
|
|
|
The Initial Developer of the Original Code is Marcel Bestebroer
|
|
Portions created by Marcel Bestebroer are Copyright (C) 2002 - 2003 Marcel
|
|
Bestebroer
|
|
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: JvDataProviderDesignerForm.pas 10610 2006-05-19 13:35:08Z elahn $
|
|
|
|
unit JvDataProviderDesignerForm;
|
|
|
|
{$I jvcl.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, Classes,
|
|
Windows, Messages, Graphics, Controls, Forms, Dialogs,
|
|
ActnList, Menus, ImgList, ToolWin, ComCtrls, StdCtrls, ExtCtrls,
|
|
{$IFDEF COMPILER6_UP}
|
|
DesignIntf, DesignEditors,
|
|
{$ELSE}
|
|
DsgnIntf,
|
|
{$ENDIF COMPILER6_UP}
|
|
JvBaseDsgnForm, JvDataProvider, JvDataProviderItemDesign, JvDataProviderIntf,
|
|
JvProviderTreeListFrame, JvBaseDsgnFrame, JvBaseDsgnToolbarFrame,
|
|
JvStdToolbarDsgnFrame, JvProviderToolbarFrame, JvDsgnTypes;
|
|
|
|
type
|
|
TfrmDataProviderDesigner = class(TJvBaseDesign)
|
|
pmProviderEditor: TPopupMenu;
|
|
miAddItem: TMenuItem;
|
|
miDivider1: TMenuItem;
|
|
miDeleteItem: TMenuItem;
|
|
miClearSub: TMenuItem;
|
|
pmAddMenu: TPopupMenu;
|
|
miDivider2: TMenuItem;
|
|
miShowToolbar: TMenuItem;
|
|
fmeToolbar: TfmeJvProviderToolbar;
|
|
fmeTreeList: TfmeJvProviderTreeList;
|
|
procedure aiAddItemExecute(Sender: TObject);
|
|
procedure aiDeleteItemExecute(Sender: TObject);
|
|
procedure aiClearSubExecute(Sender: TObject);
|
|
procedure cbContextsChange(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
private
|
|
FDesigner: IJvFormDesigner;
|
|
protected
|
|
FOrgSelect: IDesignerSelections;
|
|
FPropView: TJvDataProviderItem;
|
|
FRootItem: IJvDataItem;
|
|
procedure ResetSelection;
|
|
procedure SetNewSelection(AnItem: IJvDataItem);
|
|
procedure NeedRoot(Sender: TObject; var AVirtualRoot: IJvDataItem);
|
|
procedure UpdateSelectedItem(Sender: TObject);
|
|
procedure InitContexts;
|
|
procedure InitViewList(Sender: TJvDataConsumer; SubSvc: TJvDataConsumerAggregatedObject);
|
|
function InternalProvider: IJvDataProvider;
|
|
function GetProvider: IJvDataProvider; virtual;
|
|
procedure SetProvider(Value: IJvDataProvider); virtual;
|
|
procedure SetDesigner(Value: IJvFormDesigner);
|
|
procedure Loaded; override;
|
|
function DesignerFormName: string; override;
|
|
function AutoStoreSettings: Boolean; override;
|
|
public
|
|
PropName: string;
|
|
property Provider: IJvDataProvider read GetProvider write SetProvider;
|
|
property Designer: IJvFormDesigner read FDesigner write SetDesigner;
|
|
end;
|
|
|
|
procedure DesignProvider(AProvider: IJvDataProvider;
|
|
ADesigner: IJvFormDesigner; PropName: string);
|
|
|
|
implementation
|
|
|
|
{$R *.dfm}
|
|
|
|
uses
|
|
CommCtrl,
|
|
JvConsts, JvDsgnConsts, JvTypes;
|
|
|
|
function IsProviderDesignForm(Form: TJvBaseDesign; const Args: array of const): Boolean;
|
|
begin
|
|
Result := Form is TfrmDataProviderDesigner;
|
|
if Result then
|
|
with Form as TfrmDataProviderDesigner do
|
|
Result := (Pointer(Provider) = Args[0].VInterface) and
|
|
(Pointer(Designer) = Args[1].VInterface);
|
|
end;
|
|
|
|
procedure DesignProvider(AProvider: IJvDataProvider;
|
|
ADesigner: IJvFormDesigner; PropName: string);
|
|
var
|
|
Form: TfrmDataProviderDesigner;
|
|
begin
|
|
Form := TfrmDataProviderDesigner(GetDesignerForm(IsProviderDesignForm, [AProvider, ADesigner]));
|
|
if Form = nil then
|
|
begin
|
|
Form := TfrmDataProviderDesigner.Create(nil);
|
|
try
|
|
if PropName <> '' then
|
|
Form.PropName := '.' + PropName;
|
|
Form.Provider := AProvider;
|
|
Form.Designer := ADesigner;
|
|
except
|
|
FreeAndNil(Form);
|
|
raise;
|
|
end;
|
|
end;
|
|
Form.Show;
|
|
Form.BringToFront;
|
|
end;
|
|
|
|
//=== { TJvProviderRootItem } ================================================
|
|
|
|
type
|
|
TJvProviderRootItem = class(TJvBaseDataItem)
|
|
protected
|
|
procedure InitID; override;
|
|
public
|
|
function GetInterface(const IID: TGUID; out Obj): Boolean; override;
|
|
end;
|
|
|
|
procedure TJvProviderRootItem.InitID;
|
|
begin
|
|
SetID(RsDataItemRootID);
|
|
end;
|
|
|
|
function TJvProviderRootItem.GetInterface(const IID: TGUID; out Obj): Boolean;
|
|
begin
|
|
Result := inherited GetInterface(IID, Obj);
|
|
if not Result then
|
|
Result := TExtensibleInterfacedPersistent(GetItems.GetImplementer).GetInterface(IID, Obj);
|
|
end;
|
|
|
|
//=== { TfrmDataProviderDesigner } ===========================================
|
|
|
|
procedure TfrmDataProviderDesigner.ResetSelection;
|
|
begin
|
|
if (Designer <> nil) and (FOrgSelect <> nil) then
|
|
Designer.SetSelections(FOrgSelect);
|
|
if FPropView <> nil then
|
|
FreeAndNil(FPropView);
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.SetNewSelection(AnItem: IJvDataItem);
|
|
begin
|
|
FreeAndNil(FPropView);
|
|
FPropView := TJvDataProviderItem.Create(AnItem);
|
|
if Designer <> nil then
|
|
Designer.SelectComponent(FPropView);
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.NeedRoot(Sender: TObject; var AVirtualRoot: IJvDataItem);
|
|
begin
|
|
AVirtualRoot := FRootItem;
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.UpdateSelectedItem(Sender: TObject);
|
|
var
|
|
Item: IJvDataItem;
|
|
Items: IJvDataItems;
|
|
Man: IJvDataItemsManagement;
|
|
Dsgn: IJvDataItemsDesigner;
|
|
ParentMan: IJvDataItemsManagement;
|
|
I: Integer;
|
|
|
|
function MakeMenuItem(const Idx: Integer; const AOwner: TComponent): TMenuItem;
|
|
var
|
|
S: string;
|
|
begin
|
|
Dsgn.GetKind(Idx, S);
|
|
Result := TMenuItem.Create(AOwner);
|
|
Result.Caption := S;
|
|
Result.OnClick := fmeToolbar.aiAddItem.OnExecute;
|
|
Result.Tag := Idx;
|
|
end;
|
|
|
|
begin
|
|
if fmeTreeList.lvProvider.SelCount <> 0 then
|
|
begin
|
|
Item := fmeTreeList.GetDataItem(fmeTreeList.lvProvider.Selected.Index);
|
|
if (Item <> nil) and Supports(Item, IJvDataItems, Items) then
|
|
if Supports(Items, IJvDataItemsManagement, Man) then
|
|
Supports(Items, IJvDataItemsDesigner, Dsgn);
|
|
if Item <> nil then
|
|
Item.GetItems.QueryInterface(IJvDataItemsManagement, ParentMan);
|
|
end
|
|
else
|
|
if Supports(InternalProvider, IJvDataItems, Items) then
|
|
if Supports(Items, IJvDataItemsManagement, Man) then
|
|
Supports(Items, IJvDataItemsDesigner, Dsgn);
|
|
|
|
// Update OI
|
|
if Item = nil then
|
|
ResetSelection
|
|
else
|
|
SetNewSelection(Item);
|
|
|
|
// Update action states
|
|
miAddItem.Clear;
|
|
pmAddMenu.Items.Clear;
|
|
if (Dsgn = nil) or (Dsgn.GetCount = 0) then
|
|
begin
|
|
miAddItem.Action := fmeToolbar.aiAddItem;
|
|
fmeToolbar.tbAddItem.Action := fmeToolbar.aiAddItem;
|
|
fmeToolbar.tbAddItem.Style := tbsButton;
|
|
end
|
|
else
|
|
begin
|
|
miAddItem.Action := nil;
|
|
miAddItem.OnClick := nil;
|
|
fmeToolbar.tbAddItem.Action := nil;
|
|
fmeToolbar.tbAddItem.OnClick := nil;
|
|
fmeToolbar.tbAddItem.Style := tbsDropDown;
|
|
for I := 0 to Dsgn.GetCount - 1 do
|
|
begin
|
|
miAddItem.Add(MakeMenuItem(I, miAddItem));
|
|
pmAddMenu.Items.Add(MakeMenuItem(I, pmAddMenu));
|
|
end;
|
|
miAddItem.Visible := Man <> nil;
|
|
miAddItem.Enabled := (Man <> nil) and (Items <> nil);
|
|
fmeToolbar.tbAddItem.Visible := miAddItem.Visible;
|
|
fmeToolbar.tbAddItem.Enabled := miAddItem.Enabled;
|
|
end;
|
|
fmeToolbar.aiAddItem.Enabled := (Man <> nil) and (Items <> nil);
|
|
fmeToolbar.aiDeleteItem.Enabled := (ParentMan <> nil) and (Item <> nil) and
|
|
(Item <> FRootItem) and Item.IsDeletable;
|
|
fmeToolbar.aiDeleteSubItems.Enabled := (Man <> nil) and (Items <> nil) and
|
|
(Items.Count > 0);
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.InitContexts;
|
|
var
|
|
Ctx: IJvDataContexts;
|
|
I: Integer;
|
|
begin
|
|
fmeToolbar.cbContexts.Items.BeginUpdate;
|
|
try
|
|
fmeToolbar.cbContexts.ItemIndex := -1;
|
|
fmeToolbar.cbContexts.Items.Clear;
|
|
fmeToolbar.cbContexts.Sorted := False;
|
|
if (InternalProvider <> nil) and Supports(InternalProvider, IJvDataContexts, Ctx) then
|
|
begin
|
|
for I := 0 to Ctx.GetCount - 1 do
|
|
fmeToolbar.cbContexts.Items.AddObject(Ctx.GetContext(I).Name, TObject(I));
|
|
fmeToolbar.cbContexts.Sorted := True;
|
|
fmeToolbar.cbContexts.Sorted := False;
|
|
end;
|
|
// (rom) TObject(-99) needs explanation.
|
|
fmeToolbar.cbContexts.Items.InsertObject(0, RsDefault, TObject(-99));
|
|
finally
|
|
fmeToolbar.cbContexts.Items.EndUpdate;
|
|
if fmeToolbar.cbContexts.Items.Count > 0 then
|
|
fmeToolbar.cbContexts.ItemIndex := 0;
|
|
fmeToolbar.pnlContexts.Visible := fmeToolbar.cbContexts.Items.Count > 1;
|
|
fmeToolbar.UpdateToolbarSeparators;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.InitViewList(Sender: TJvDataConsumer;
|
|
SubSvc: TJvDataConsumerAggregatedObject);
|
|
var
|
|
VL: IJvDataConsumerViewList;
|
|
begin
|
|
if SubSvc is TJvCustomDataConsumerViewList then
|
|
if SubSvc.GetInterface(IJvDataConsumerViewList, VL) then
|
|
VL.ExpandOnNewItem := True;
|
|
end;
|
|
|
|
function TfrmDataProviderDesigner.InternalProvider: IJvDataProvider;
|
|
begin
|
|
Result := fmeTreeList.Provider.ProviderIntf;
|
|
end;
|
|
|
|
function TfrmDataProviderDesigner.GetProvider: IJvDataProvider;
|
|
begin
|
|
Result := fmeTreeList.Provider.ProviderIntf;
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.SetProvider(Value: IJvDataProvider);
|
|
var
|
|
ViewList: IJvDataConsumerViewList;
|
|
ProviderImpl: TComponent;
|
|
begin
|
|
fmeTreeList.Provider.SetProviderIntf(Value);
|
|
if csDestroying in ComponentState then
|
|
Exit;
|
|
if Provider <> nil then
|
|
begin
|
|
FRootItem := TJvProviderRootItem.Create(Provider as IJvDataItems);
|
|
fmeTreeList.Provider.SetContextIntf(nil);
|
|
// Odd behaviour: ViewList is not filled when the provider is set. Look into this issue later!
|
|
if Supports(fmeTreeList.Provider as IJvDataConsumer, IJvDataConsumerViewList, ViewList) then
|
|
ViewList.RebuildView;
|
|
ProviderImpl := (Provider as IInterfaceComponentReference).GetComponent;
|
|
Caption := Format(RsDataProviderDesignerCaption, [ProviderImpl.Name, PropName]);
|
|
end;
|
|
InitContexts;
|
|
UpdateSelectedItem(Self);
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.SetDesigner(Value: IJvFormDesigner);
|
|
begin
|
|
if Value <> FDesigner then
|
|
begin
|
|
if FDesigner <> nil then
|
|
ResetSelection;
|
|
{$IFDEF COMPILER6_UP}
|
|
FOrgSelect := TDesignerSelections.Create;
|
|
{$ELSE}
|
|
FOrgSelect := TDesignerSelectionList.Create;
|
|
{$ENDIF COMPILER6_UP}
|
|
FDesigner := Value;
|
|
if Designer <> nil then
|
|
Designer.GetSelections(FOrgSelect);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
if fmeTreeList <> nil then
|
|
with fmeTreeList do
|
|
begin
|
|
OnGetVirtualRoot := NeedRoot;
|
|
OnItemSelect := UpdateSelectedItem;
|
|
Provider.AfterCreateSubSvc := InitViewList;
|
|
UseVirtualRoot := True;
|
|
end;
|
|
end;
|
|
|
|
function TfrmDataProviderDesigner.DesignerFormName: string;
|
|
begin
|
|
Result := RsDataProviderDesigner;
|
|
end;
|
|
|
|
function TfrmDataProviderDesigner.AutoStoreSettings: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.aiAddItemExecute(Sender: TObject);
|
|
var
|
|
Item: IJvDataItem;
|
|
Items: IJvDataItems;
|
|
Dsgn: IJvDataItemsDesigner;
|
|
Mangr: IJvDataItemsManagement;
|
|
begin
|
|
if fmeTreeList.lvProvider.Selected <> nil then
|
|
begin
|
|
Item := fmeTreeList.GetDataItem(fmeTreeList.lvProvider.Selected.Index);
|
|
if Item <> nil then
|
|
Item.QueryInterface(IJvDataItems, Items)
|
|
else // should never occur
|
|
raise EJVCLException.CreateRes(@RsEDataItemNotFound);
|
|
end
|
|
else
|
|
Items := InternalProvider as IJvDataItems;
|
|
Item := nil;
|
|
if Items <> nil then
|
|
begin
|
|
if Supports(Items, IJvDataItemsDesigner, Dsgn) then
|
|
Item := Dsgn.NewByKind(TMenuItem(Sender).Tag)
|
|
else
|
|
if Supports(Items, IJvDataItemsManagement, Mangr) then
|
|
Item := Mangr.New
|
|
else // should never occur
|
|
raise EJVCLException.CreateResFmt(@RsEDataProviderAddErrorReason, [RsEDataProviderNoManOrDsgn]);
|
|
if Item <> nil then
|
|
begin
|
|
fmeTreeList.SelectItemID(Item.GetID);
|
|
if Designer <> nil then
|
|
Designer.Modified;
|
|
end
|
|
else
|
|
raise EJVCLException.CreateRes(@RsEDataProviderAddFailed);
|
|
end
|
|
else // should never occur
|
|
raise EJVCLException.CreateResFmt(@RsEDataProviderAddErrorReason, [RsEDataProviderNoSubItems]);
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.aiDeleteItemExecute(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
Item: IJvDataItem;
|
|
Items: IJvDataItems;
|
|
Mangr: IJvDataItemsManagement;
|
|
begin
|
|
if fmeTreeList.lvProvider.Selected <> nil then
|
|
begin
|
|
I := fmeTreeList.lvProvider.Selected.Index;
|
|
Item := fmeTreeList.GetDataItem(I);
|
|
if Item <> nil then
|
|
Items := Item.GetItems
|
|
else
|
|
raise EJVCLException.CreateRes(@RsEDataItemNotFound);
|
|
if Supports(Items, IJvDataItemsManagement, Mangr) then
|
|
begin
|
|
ResetSelection;
|
|
Mangr.Remove(Item);
|
|
if Designer <> nil then
|
|
Designer.Modified;
|
|
end
|
|
else
|
|
raise EJVCLException.CreateResFmt(@RsEDataProviderDeleteErrorReason, [RsEDataProviderNoMan]);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.aiClearSubExecute(Sender: TObject);
|
|
var
|
|
Item: IJvDataItem;
|
|
Items: IJvDataItems;
|
|
Mangr: IJvDataItemsManagement;
|
|
begin
|
|
if fmeTreeList.lvProvider.Selected <> nil then
|
|
begin
|
|
Item := fmeTreeList.GetDataItem(fmeTreeList.lvProvider.Selected.Index);
|
|
if Item <> nil then
|
|
begin
|
|
if not Supports(Item, IJvDataItems, Items) then
|
|
raise EJVCLException.CreateResFmt(@RsEDataProviderDeleteErrorReason, [RsEDataProviderNoSubItems]);
|
|
end
|
|
else
|
|
raise EJVCLException.CreateRes(@RsEDataItemNotFound);
|
|
if Supports(Items, IJvDataItemsManagement, Mangr) then
|
|
begin
|
|
Mangr.Clear;
|
|
if Designer <> nil then
|
|
Designer.Modified;
|
|
end
|
|
else
|
|
raise EJVCLException.CreateResFmt(@RsEDataProviderDeleteErrorReason, [RsEDataProviderNoMan]);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.cbContextsChange(Sender: TObject);
|
|
var
|
|
CtxIdx: Integer;
|
|
CtxList: IJvDataContexts;
|
|
begin
|
|
if fmeToolbar.cbContexts.ItemIndex > 0 then
|
|
begin
|
|
CtxIdx := Integer(fmeToolbar.cbContexts.Items.Objects[fmeToolbar.cbContexts.ItemIndex]);
|
|
if CtxIdx >= 0 then
|
|
begin
|
|
{ Retrieve context and activate it in the consumer service. }
|
|
if Supports(InternalProvider, IJvDataContexts, CtxList) then
|
|
fmeTreeList.Provider.SetContextIntf(CtxList.GetContext(CtxIdx))
|
|
else
|
|
raise EJVCLException.CreateRes(@RsEInternalErrorUnableToRetrieveContext);
|
|
end
|
|
else
|
|
fmeTreeList.Provider.SetContextIntf(nil);
|
|
end
|
|
else
|
|
fmeTreeList.Provider.SetContextIntf(nil);
|
|
end;
|
|
|
|
procedure TfrmDataProviderDesigner.FormDestroy(Sender: TObject);
|
|
begin
|
|
ResetSelection;
|
|
FRootItem := nil;
|
|
Provider := nil;
|
|
Designer := nil;
|
|
end;
|
|
|
|
end.
|