fccollectioneditor.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:14k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit fcCollectionEditor;
  2. {
  3. //
  4. // Components : TfcCollectionEditorForm
  5. //
  6. // Copyright (c) 1998 by Woll2Woll Software
  7. //
  8. }
  9. { This collection editor may only support the navigator currently due to
  10.   only having one global collection editor }
  11.   
  12. interface
  13. {$i fcIfDef.pas}
  14. uses
  15.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  16.   StdCtrls, ExtCtrls,
  17.        {$ifdef fcdelphi6up}
  18.        designintf, designeditors,
  19.        {$else}
  20.        dsgnintf,
  21.        {$endif}
  22.   fcCommon, fcCollection, ComCtrls, Buttons,
  23.   {$ifdef fcDelphi4Up}ImgList,{$endif} ToolWin, Menus;
  24. const
  25.   sfcInvalidParameter = 'Parameter %s of %s cannot be %s';
  26. type
  27.   TfcCollectionEditorForm = class(TForm)
  28.     ItemsList: TListView;
  29.     ToolBar: TToolBar;
  30.     AddButton: TSpeedButton;
  31.     DeleteButton: TSpeedButton;
  32.     ToolButton1: TToolButton;
  33.     MoveUpButton: TSpeedButton;
  34.     MoveDownButton: TSpeedButton;
  35.     ToolButton2: TToolButton;
  36.     UserButton1: TSpeedButton;
  37.     UserButton2: TSpeedButton;
  38.     PopupMenu1: TPopupMenu;
  39.     Add1: TMenuItem;
  40.     Delete1: TMenuItem;
  41.     MoveUp1: TMenuItem;
  42.     MoveDown1: TMenuItem;
  43.     SelectAll1: TMenuItem;
  44.     N1: TMenuItem;
  45.     ShowToolbarMenu: TMenuItem;
  46.     procedure MoveButtonClick(Sender: TObject);
  47.     procedure DeleteButtonClick(Sender: TObject);
  48.     procedure AddButtonClick(Sender: TObject);
  49.     procedure ItemsListBoxKeyDown(Sender: TObject; var Key: Word;
  50.       Shift: TShiftState);
  51.     procedure FormResize(Sender: TObject);
  52.     procedure ItemsListDragOver(Sender, Source: TObject; X, Y: Integer;
  53.       State: TDragState; var Accept: Boolean);
  54.     procedure ItemsListDragDrop(Sender, Source: TObject; X, Y: Integer);
  55.     procedure ItemsListKeyUp(Sender: TObject; var Key: Word;
  56.       Shift: TShiftState);
  57.     procedure ItemsListMouseUp(Sender: TObject; Button: TMouseButton;
  58.       Shift: TShiftState; X, Y: Integer);
  59.     procedure FormShow(Sender: TObject);
  60.     procedure SelectAll1Click(Sender: TObject);
  61.     procedure ShowToolbarMenuClick(Sender: TObject);
  62.     procedure PopupMenu1Popup(Sender: TObject);
  63.     procedure FormKeyDown(Sender: TObject; var Key: Word;
  64.       Shift: TShiftState);
  65.   protected
  66.     IgnoreChange: Boolean;
  67.     function GetSelectedComponent(Index: Integer): TfcCollectionItem;
  68.     function GetItemText(Item: TfcCollectionItem): string;
  69.     procedure ItemUpdateSelection(Item: TfcCollectionItem);
  70.     procedure ItemRefreshDesign(Sender: TObject);
  71.     procedure ResetForm;
  72.   public
  73.     Collection: TfcCollection;
  74.     Designer: //{$ifdef fcDelphi4Up}IFormDesigner{$else}TFormDesigner{$endif};
  75.         {$ifdef fcDelphi6Up} IDesigner;
  76.         {$else} {$ifdef fcDelphi4Up} IFormDesigner; {$else} TFormDesigner; {$endif}
  77.         {$endif}
  78.     PropertyName: string;  // Name of property being edited
  79.     Component: TComponent; // Handle to component being edited
  80.     procedure Reload;
  81.     procedure SetSelection(Instance: TPersistent; Selected: Boolean); virtual;
  82.     procedure Update; override;
  83.     destructor Destroy; override;
  84.   end;
  85.   TfcCollectionCustomizeEvent = procedure(EditorForm: TfcCollectionEditorForm) of object;
  86.   procedure fcExecuteCollectionEditor(ACaption: string;
  87.     ADesigner:
  88.         {$ifdef fcDelphi6Up} IDesigner;
  89.         {$else} {$ifdef fcDelphi4Up} IFormDesigner; {$else} TFormDesigner; {$endif}
  90.         {$endif}
  91. //  ADesigner: {$ifdef fcDelphi4Up}IFormDesigner{$else}TFormDesigner{$endif};
  92.     APropertyName: string; ACollection: TfcCollection; CustomizeEvent: TfcCollectionCustomizeEvent);
  93. var
  94.   fcCollectionEditorForm: TfcCollectionEditorForm = nil;
  95. implementation
  96. {$R *.DFM}
  97. // This function executes our Collection Editor.  The
  98. // meaning of the parameters are as follows:
  99. //
  100. // ACaption -    The Caption of the Collection Editor form.
  101. //               i.e. 'fcDBNavigator1.Buttons'
  102. // ADesigner -   The Designer property of TComponentEditor,
  103. //               TPropertyEditor, etc.
  104. // AComponent -  The actual component getting edited.
  105. //               i.e. In the context of TComponentEditor,
  106. //               just pass the Component property.
  107. // ACollection - The property that implements ICollection.
  108. //               i.e. fcDBNavigator1.Buttons as IfcCollection
  109. // -ksw (7/3/98)
  110. procedure fcExecuteCollectionEditor(ACaption: string;
  111.     ADesigner:
  112.         {$ifdef fcDelphi6Up} IDesigner;
  113.         {$else} {$ifdef fcDelphi4Up} IFormDesigner; {$else} TFormDesigner; {$endif}
  114.         {$endif}
  115.  // ADesigner: {$ifdef fcDelphi4Up}IFormDesigner{$else}TFormDesigner{$endif};
  116.   APropertyName: string; ACollection: TfcCollection; CustomizeEvent: TfcCollectionCustomizeEvent);
  117. begin
  118.   // ACollection and AComponent cannot be nil.
  119.   if ACollection = nil then raise EInvalidOperation.Create(Format(sfcInvalidParameter, ['ACollection', 'fcExecuteCollectionEditor', 'nil']));
  120.   if fcCollectionEditorForm = nil then
  121.     fcCollectionEditorForm := TfcCollectionEditorForm.Create(Application)
  122.   else fcCollectionEditorForm.ResetForm;
  123.   with fcCollectionEditorForm do
  124.   begin
  125.     PropertyName := APropertyName;
  126.     ACollection.Designer := fcCollectionEditorForm;
  127.     Designer := ADesigner;
  128.     if (ACollection<>Collection) and (Collection<>nil) then
  129.        Collection.Designer:= nil; { Detach previous collection }
  130.     Collection := ACollection;
  131.     Reload;
  132.     Caption := ACaption;
  133.     if Assigned(CustomizeEvent) then CustomizeEvent(fcCollectionEditorForm);
  134.     Show;
  135.   end
  136. end;
  137. procedure TfcCollectionEditorForm.ResetForm;
  138. begin
  139.   IgnoreChange := True;
  140.   ItemsList.Items.Clear;
  141.   IgnoreChange := False;
  142. end;
  143. procedure TfcCollectionEditorForm.Update;
  144. begin
  145.   inherited Update;
  146.   Reload;
  147. end;
  148. procedure TfcCollectionEditorForm.Reload;
  149. var i: integer;
  150. begin
  151.   ItemsList.Items.BeginUpdate;
  152.   ItemsList.Items.Clear;
  153.   for i:= 0 to Collection.Count - 1 do
  154.   begin
  155.     ItemsList.Items.Add.Caption := GetItemText(Collection.Items[i]);
  156.     Collection.Items[i].SelectionMethod := ItemUpdateSelection;
  157.     Collection.Items[i].OnRefreshDesign := ItemRefreshDesign; { RSW - 4/27/99 (Refresh collection editor on text change) }
  158.   end;
  159.   ItemsList.Items.EndUpdate;
  160. end;
  161. destructor TfcCollectionEditorForm.Destroy;
  162. begin
  163.   Collection.Designer := nil;
  164.   fcCollectionEditorForm := nil;
  165.   inherited Destroy;
  166. end;
  167. function TfcCollectionEditorForm.GetSelectedComponent(Index: Integer): TfcCollectionItem;
  168. begin
  169.   result := Collection.Items[Index];
  170.   if result = nil then raise EInvalidOperation.Create('GetSelectedComponent is returning nil');
  171. end;
  172. procedure TfcCollectionEditorForm.MoveButtonClick(Sender: TObject);
  173. var Item: TfcCollectionItem;
  174.     Button: TComponent;
  175. begin
  176.   if ItemsList.Selected = nil then Exit;
  177.   Item := GetSelectedComponent(ItemsList.Selected.Index);
  178.   Button := Sender as TComponent;
  179.   if (Item <> nil) and
  180.      (((Button.Tag = -1) and (Item.Index > 0)) or
  181.       ((Button.Tag = 1) and (Item.Index < Collection.Count - 1))) then
  182.   begin
  183.     Item.Index := Item.Index + Button.Tag;
  184.     Reload;
  185.     ItemsList.Items[Item.Index].Selected := True;
  186.     if Designer <> nil then Designer.Modified;
  187.   end
  188. end;
  189. {$ifndef fcDelphi5}
  190. function ExtractPersistent(Component: TPersistent): TPersistent; //Component;
  191. begin
  192.    result:= Component as TPersistent;
  193. end;
  194. {$endif}
  195. procedure TfcCollectionEditorForm.DeleteButtonClick(Sender: TObject);
  196. var i, OldItemIndex: integer;
  197.     {$ifdef fcDelphi5Up}
  198.     Selections, NoSel: IDesignerSelections;
  199.     {$else}
  200.     Selections, NoSel: TComponentList;
  201.     {$endif}
  202.     OldSel: TListItem;
  203. begin
  204.   // Prevent OnChange event from firing.
  205.   IgnoreChange := True;
  206.   if ItemsList.Selected = nil then Exit;
  207.   OldItemIndex := ItemsList.Selected.Index;
  208.   {$ifndef fcDelphi5Up}
  209.   Selections := TComponentList.Create;
  210.   {$else}
  211.   Selections := CreateSelectionList;
  212.   {$endif}
  213.   if Designer <> nil then
  214.   begin
  215.     Designer.GetSelections(Selections);
  216.     {$ifndef fcDelphi5Up}
  217.     NoSel := TComponentList.Create;
  218.     {$else}
  219.     NoSel := CreateSelectionList;
  220.     {$endif}
  221.     Designer.SetSelections(NoSel);
  222.     {$ifndef fcDelphi5Up}
  223.     NoSel.Free;
  224.     {$endif}
  225.   end;
  226.   for i := 0 to Selections.Count - 1 do ExtractPersistent(Selections[i]).Free;
  227.   {$ifndef fcDelphi5Up}
  228.   Selections.Free;
  229.   {$endif}
  230.   Reload;
  231.   OldSel := ItemsList.Items[fcMin(OldItemIndex, ItemsList.Items.Count - 1)];
  232.   if OldSel <> nil then OldSel.Selected := True;
  233.   // Allow OnChange event to fire.
  234.   IgnoreChange := False;
  235.   // Set the currently selected ListView item to be selected
  236.   ItemsListMouseUp(ItemsList, mbLeft, [], 0, 0);
  237.   if Designer <> nil then Designer.Modified;
  238. end;
  239. procedure TfcCollectionEditorForm.AddButtonClick(Sender: TObject);
  240. begin
  241.   Collection.AddItem;
  242.   Reload;
  243.   if Designer <> nil then Designer.Modified;
  244. end;
  245. function TfcCollectionEditorForm.GetItemText(Item: TfcCollectionItem): string;
  246. var DisplayName: string;
  247. begin
  248.   DisplayName := Item.DisplayName;
  249.   if (DisplayName = '') and (Item.GetInstance(PropertyName) is TComponent) then
  250.     DisplayName := (Item.GetInstance(PropertyName) as TComponent).Name;
  251.   result := InttoStr(Item.Index) + ' - ' + DisplayName;
  252. end;
  253. procedure TfcCollectionEditorForm.ItemRefreshDesign(Sender: TObject);
  254. begin
  255.   Reload;
  256. end;
  257. procedure TfcCollectionEditorForm.ItemUpdateSelection(Item: TfcCollectionItem);
  258. begin
  259.   ItemsList.Selected := ItemsList.Items[Item.Index];
  260. end;
  261. procedure TfcCollectionEditorForm.ItemsListBoxKeyDown(Sender: TObject;
  262.   var Key: Word; Shift: TShiftState);
  263. begin
  264.   // F11 is the default character keystroke to bring up the
  265.   // object inspector.  If that keystroke is overridable,
  266.   // then this code becomes unpredictable.  -!- Need to look
  267.   // into that.  -ksw (7/3/98)
  268.   case Key of
  269.     VK_INSERT: AddButtonClick(AddButton);
  270.     VK_DELETE: DeleteButtonClick(DeleteButton);
  271.     VK_UP, VK_DOWN: if ssCtrl in Shift then
  272.     begin
  273.       if Key = VK_UP then
  274.         MoveButtonClick(MoveUpButton)
  275.       else MoveButtonClick(MoveDownButton);
  276.       Key := 0;
  277.     end;
  278.     VK_RETURN: fcPlayKeystroke(Handle, VK_F11, 0);
  279.   end;
  280. end;
  281. procedure TfcCollectionEditorForm.FormResize(Sender: TObject);
  282. begin
  283.   // The Items list is a TListView.  It is in the Report viewstyle
  284.   // and has one column.  This "aligns" that column to the client
  285.   // width of the list view.
  286.   with ItemsList.ClientRect do
  287.     ItemsList.Columns[0].Width := Right - Left;
  288. end;
  289. procedure TfcCollectionEditorForm.ItemsListDragOver(Sender,
  290.   Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
  291. begin
  292.   Accept := (Source <> nil) and (Source is TListView) and (Source = Sender) and ((Sender as TListView).GetItemAt(X,Y) <> (Sender as TListView).Selected);
  293. end;
  294. procedure TfcCollectionEditorForm.ItemsListDragDrop(Sender,
  295.   Source: TObject; X, Y: Integer);
  296. var Item: TListItem;
  297.     Index: Integer;
  298.     SelItem: TfcCollectionItem;
  299. begin
  300.   Item := (Sender as TListView).GetItemAt(X,Y);
  301.   if Item = nil then Index := (Sender as TListView).Items.Count - 1
  302.   else Index := Item.Index;
  303.   SelItem := GetSelectedComponent(ItemsList.Selected.Index);
  304.   SelItem.Index := Index;
  305.   Reload;
  306.   ItemsList.Items[SelItem.Index].Selected := True;
  307.   if Designer <> nil then Designer.Modified;
  308. end;
  309. procedure TfcCollectionEditorForm.SetSelection(Instance: TPersistent; Selected: Boolean);
  310. var i: Integer;
  311. begin
  312.   IgnoreChange := True;
  313.   for i := 0 to ItemsList.Items.Count - 1 do
  314.     if Collection.Items[i].GetInstance(PropertyName) = Instance then
  315.     begin
  316.       ItemsList.Items[i].Selected := Selected;
  317.       Break;
  318.     end;
  319.   IgnoreChange := False;
  320. end;
  321. procedure TfcCollectionEditorForm.ItemsListKeyUp(Sender: TObject;
  322.   var Key: Word; Shift: TShiftState);
  323. begin
  324.   if Key in [VK_RIGHT, VK_LEFT, VK_UP, VK_DOWN, VK_HOME, VK_END, VK_NEXT, VK_PRIOR, VK_SPACE] then
  325.     ItemsListMouseUp(ItemsList, mbLeft, [], 0, 0);
  326. end;
  327. procedure TfcCollectionEditorForm.ItemsListMouseUp(Sender: TObject;
  328.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  329. var
  330.     {$ifdef fcDelphi5Up}
  331.     Selections: IDesignerSelections;
  332.     {$else}
  333.     Selections: TComponentList;
  334.     {$endif}
  335.     i: Integer;
  336. begin
  337.   if (csDestroying in ComponentState) then Exit;
  338.   DeleteButton.Enabled := ItemsList.Selected <> nil;
  339.   MoveUpButton.Enabled := ItemsList.Selected <> nil;
  340.   MoveDownButton.Enabled := ItemsList.Selected <> nil;
  341.   if (Designer = nil) or IgnoreChange then Exit;
  342.   {$ifndef fcDelphi5Up}
  343.   Selections := TComponentList.Create;
  344.   {$else}
  345.   Selections := CreateSelectionList;
  346.   {$endif}
  347.   for i:= 0 to ItemsList.Items.Count - 1 do
  348.     if ItemsList.Items[i].Selected then
  349.       {$ifdef fcDelphi5}
  350.       Selections.Add(MakeIPersistent(GetSelectedComponent(i).GetInstance(PropertyName)));
  351.       {$else}
  352.       Selections.Add(GetSelectedComponent(i).GetInstance(Propertyname));
  353.       {$endif}
  354.   if Selections.Count > 0 then
  355.     Designer.SetSelections(Selections);
  356.   {$ifndef fcDelphi5Up}
  357.   Selections.Free;
  358.   {$endif}
  359.   if ItemsList.SelCount = 1 then
  360.     GetSelectedComponent(ItemsList.Selected.Index).GotSelected;
  361. end;
  362. procedure TfcCollectionEditorForm.FormShow(Sender: TObject);
  363. begin
  364.   ItemsListMouseUp(ItemsList, mbLeft, [], 0, 0);
  365. end;
  366. procedure TfcCollectionEditorForm.SelectAll1Click(Sender: TObject);
  367. var i: Integer;
  368. begin
  369.   for i := 0 to ItemsList.Items.Count - 1 do
  370.     ItemsList.Items[i].Selected := True;
  371. end;
  372. procedure TfcCollectionEditorForm.ShowToolbarMenuClick(Sender: TObject);
  373. begin
  374.   ShowToolBarMenu.Checked := not ShowToolBarMenu.Checked;
  375.   ToolBar.Visible := ShowToolBarMenu.Checked;
  376. end;
  377. procedure TfcCollectionEditorForm.PopupMenu1Popup(Sender: TObject);
  378. begin
  379.   ShowToolBarMenu.Checked := ToolBar.Visible;
  380. end;
  381. procedure TfcCollectionEditorForm.FormKeyDown(Sender: TObject;
  382.   var Key: Word; Shift: TShiftState);
  383. begin
  384.   if Key = VK_F1 then
  385.     fcHelp(Handle, 'TfcCollection');
  386. end;
  387. initialization
  388. finalization
  389.   fcCollectionEditorForm.Free;
  390.   fcCollectionEditorForm := nil;
  391. end.