1138 lines
31 KiB
ObjectPascal
1138 lines
31 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: JvSbEdit.PAS, released on 2002-07-04.
|
|
|
|
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 2001,2002 SGB Software
|
|
All Rights Reserved.
|
|
|
|
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: JvSpeedbarForm.pas 10610 2006-05-19 13:35:08Z elahn $
|
|
|
|
unit JvSpeedbarForm;
|
|
|
|
{$I jvcl.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, Classes,
|
|
Windows, Messages, Graphics, Controls, Forms, Dialogs,
|
|
StdCtrls, Buttons, Grids, Menus,
|
|
{$IFDEF COMPILER6_UP}
|
|
DesignIntf, DesignEditors,
|
|
DesignWindows,
|
|
{$ELSE}
|
|
LibIntf, DsgnIntf, DsgnWnds,
|
|
{$ENDIF COMPILER6_UP}
|
|
{$IFDEF MSWINDOWS}
|
|
JvAppRegistryStorage,
|
|
{$ENDIF MSWINDOWS}
|
|
JvSpeedButton, JvSpeedBar, JvFormPlacement,
|
|
JvConsts, JvComponent, JvAppStorage;
|
|
|
|
type
|
|
TSelectData = record
|
|
bRowCount: Integer;
|
|
bRow: Integer;
|
|
sRowCount: Integer;
|
|
sRow: Integer;
|
|
end;
|
|
|
|
TJvSpeedbarEditorMain = class(TDesignWindow)
|
|
SectionsBox: TGroupBox;
|
|
NewSection: TButton;
|
|
DelSection: TButton;
|
|
ButtonsBox: TGroupBox;
|
|
UpBtn: TSpeedButton;
|
|
DownBtn: TSpeedButton;
|
|
AddButton: TButton;
|
|
RemoveButton: TButton;
|
|
CloseBtn: TButton;
|
|
SectionName: TEdit;
|
|
SectionNameLabel: TLabel;
|
|
SectionList: TDrawGrid;
|
|
ButtonsList: TDrawGrid;
|
|
LabelHint: TLabel;
|
|
PopupMenu: TPopupMenu;
|
|
CopyMenu: TMenuItem;
|
|
PasteMenu: TMenuItem;
|
|
CutMenu: TMenuItem;
|
|
FormPlacement1: TJvFormStorage;
|
|
AppStorage: TJvAppRegistryStorage;
|
|
procedure DelSectionClick(Sender: TObject);
|
|
procedure AddButtonClick(Sender: TObject);
|
|
procedure RemoveButtonClick(Sender: TObject);
|
|
procedure CloseBtnClick(Sender: TObject);
|
|
procedure UpBtnClick(Sender: TObject);
|
|
procedure DownBtnClick(Sender: TObject);
|
|
procedure FormClose(Sender: TObject; var Action: TCloseAction);
|
|
procedure SectionNameExit(Sender: TObject);
|
|
procedure SectionListSelectCell(Sender: TObject; Col, Row: Longint;
|
|
var CanSelect: Boolean);
|
|
procedure SectionListDrawCell(Sender: TObject; Col, Row: Longint;
|
|
Rect: TRect; State: TGridDrawState);
|
|
procedure ButtonsListDblClick(Sender: TObject);
|
|
procedure ButtonsListKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
procedure ButtonsListMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure ButtonsListMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer);
|
|
procedure ButtonsListMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure ButtonsListSelectCell(Sender: TObject; Col, Row: Longint;
|
|
var CanSelect: Boolean);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure NewSectionClick(Sender: TObject);
|
|
procedure SectionNameKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
procedure ButtonsListDrawCell(Sender: TObject; Col, Row: Longint;
|
|
Rect: TRect; State: TGridDrawState);
|
|
procedure SectionListMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure SectionListDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
procedure SectionListDragOver(Sender, Source: TObject; X, Y: Integer;
|
|
State: TDragState; var Accept: Boolean);
|
|
procedure SectionListKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
procedure CopyMenuClick(Sender: TObject);
|
|
procedure PasteMenuClick(Sender: TObject);
|
|
procedure CutMenuClick(Sender: TObject);
|
|
procedure FormShow(Sender: TObject);
|
|
private
|
|
FButton: TJvBtnControl;
|
|
FImage: TJvButtonImage;
|
|
FBar: TJvSpeedBar;
|
|
FDrag: Boolean;
|
|
FDragItem: TJvSpeedItem;
|
|
FLocked: Integer;
|
|
FSelectData: TSelectData;
|
|
procedure Copy;
|
|
procedure Cut;
|
|
procedure Paste;
|
|
procedure OnPasteItem(Item: TObject);
|
|
procedure SaveSelection;
|
|
procedure RestoreSelection;
|
|
procedure SelectButton(Section: Integer; Item: TJvSpeedItem; SelectBar: Boolean);
|
|
procedure UpdateEnabled(BtnRow, Section: Integer);
|
|
function CheckSpeedBar: Boolean;
|
|
function ConfirmDelete: Boolean;
|
|
function CurrentSection: Integer;
|
|
function GetForm: TCustomForm;
|
|
procedure SetSection(Section: Integer);
|
|
procedure UpdateData;
|
|
procedure UpdateListHeight;
|
|
procedure SetJvSpeedBar(Value: TJvSpeedBar);
|
|
function ItemByRow(Row: Integer): TJvSpeedItem;
|
|
function SectionByRow(Row: Integer): TJvSpeedbarSection;
|
|
function ItemBySectionRow(Section, Row: Integer): TJvSpeedItem;
|
|
procedure CMSpeedBarChanged(var Msg: TMessage); message CM_SPEEDBARCHANGED;
|
|
protected
|
|
procedure Activated; override;
|
|
function UniqueName(Component: TComponent): string; override;
|
|
public
|
|
{$IFDEF COMPILER6_UP}
|
|
procedure ItemsModified(const Designer: IDesigner); override;
|
|
procedure DesignerClosed(const ADesigner: IDesigner; AGoingDormant: Boolean); override;
|
|
{$ELSE}
|
|
procedure FormModified; override;
|
|
procedure FormClosed(Form: TCustomForm); override;
|
|
{$ENDIF COMPILER6_UP}
|
|
function GetEditState: TEditState; override;
|
|
{$IFDEF COMPILER6_UP}
|
|
function EditAction(Action: TEditAction): Boolean; override;
|
|
{$ELSE}
|
|
procedure EditAction(Action: TEditAction); override;
|
|
{$ENDIF COMPILER6_UP}
|
|
property JvSpeedBar: TJvSpeedBar read FBar write SetJvSpeedBar;
|
|
property OwnerForm: TCustomForm read GetForm;
|
|
end;
|
|
|
|
TJvSpeedbarEditor = class(TComponentEditor)
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
function GetVerbCount: Integer; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
TypInfo, Math,
|
|
JvPropertyStorage, JvDsgnConsts, JvDsgnTypes, JvJVCLUtils;
|
|
|
|
{$R *.dfm}
|
|
|
|
//== Utility routines ========================================================
|
|
|
|
function FindEditor(JvSpeedBar: TJvSpeedBar): TJvSpeedbarEditorMain;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to Screen.FormCount - 1 do
|
|
if Screen.Forms[I] is TJvSpeedbarEditorMain then
|
|
if TJvSpeedbarEditorMain(Screen.Forms[I]).JvSpeedBar = JvSpeedBar then
|
|
begin
|
|
Result := TJvSpeedbarEditorMain(Screen.Forms[I]);
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
procedure ShowSpeedbarDesigner(Designer: IJvDesigner; JvSpeedBar: TJvSpeedBar);
|
|
var
|
|
Editor: TJvSpeedbarEditorMain;
|
|
begin
|
|
if JvSpeedBar = nil then
|
|
Exit;
|
|
Editor := FindEditor(JvSpeedBar);
|
|
if Editor <> nil then
|
|
begin
|
|
Editor.Show;
|
|
if Editor.WindowState = wsMinimized then
|
|
Editor.WindowState := wsNormal;
|
|
end
|
|
else
|
|
begin
|
|
Editor := TJvSpeedbarEditorMain.Create(Application);
|
|
try
|
|
Editor.Designer := IJvFormDesigner(Designer);
|
|
Editor.JvSpeedBar := JvSpeedBar;
|
|
Editor.Show;
|
|
except
|
|
Editor.Free;
|
|
raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
//=== { TJvSpeedbarEditor } ==================================================
|
|
|
|
procedure TJvSpeedbarEditor.ExecuteVerb(Index: Integer);
|
|
begin
|
|
case Index of
|
|
0:
|
|
ShowSpeedbarDesigner(Designer, TJvSpeedBar(Component));
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedbarEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
case Index of
|
|
0:
|
|
Result := RsSpeedbarDesigner;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedbarEditor.GetVerbCount: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
//=== { TJvSpeedbarEditorMain } ==============================================
|
|
|
|
const
|
|
MaxBtnListHeight = 158;
|
|
|
|
function TJvSpeedbarEditorMain.UniqueName(Component: TComponent): string;
|
|
var
|
|
Temp: string;
|
|
begin
|
|
Result := '';
|
|
if Component <> nil then
|
|
Temp := Component.ClassName
|
|
else
|
|
Temp := TJvSpeedItem.ClassName;
|
|
if (UpCase(Temp[1]) = 'T') and (Length(Temp) > 1) then
|
|
System.Delete(Temp, 1, 1);
|
|
Result := Designer.UniqueName(Temp);
|
|
end;
|
|
|
|
function TJvSpeedbarEditorMain.GetEditState: TEditState;
|
|
begin
|
|
Result := [];
|
|
if RemoveButton.Enabled then
|
|
Result := [esCanDelete, esCanCut, esCanCopy];
|
|
if AddButton.Enabled and ClipboardComponents then
|
|
Include(Result, esCanPaste);
|
|
end;
|
|
|
|
{$IFDEF COMPILER6_UP}
|
|
function TJvSpeedbarEditorMain.EditAction(Action: TEditAction): Boolean;
|
|
begin
|
|
Result := True;
|
|
{$ELSE}
|
|
procedure TJvSpeedbarEditorMain.EditAction(Action: TEditAction);
|
|
begin
|
|
{$ENDIF COMPILER6_UP}
|
|
case Action of
|
|
eaCut:
|
|
Cut;
|
|
eaCopy:
|
|
Copy;
|
|
eaPaste:
|
|
Paste;
|
|
eaDelete:
|
|
RemoveButtonClick(Self);
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF COMPILER6_UP}
|
|
type
|
|
TDesignerSelectionList = IDesignerSelections;
|
|
{$ENDIF COMPILER6_UP}
|
|
|
|
procedure TJvSpeedbarEditorMain.SelectButton(Section: Integer; Item: TJvSpeedItem;
|
|
SelectBar: Boolean);
|
|
var
|
|
FCompList: TDesignerSelectionList;
|
|
Sect: TJvSpeedbarSection;
|
|
begin
|
|
if CheckSpeedBar and Active then
|
|
begin
|
|
//Designer.GetSelections(FCompList);
|
|
{$IFDEF COMPILER6_UP}
|
|
FCompList := TDesignerSelections.Create;
|
|
{$ELSE}
|
|
FCompList := TDesignerSelectionList.Create;
|
|
{$ENDIF COMPILER6_UP}
|
|
if not SelectBar then
|
|
begin
|
|
if (ActiveControl = SectionList) or (ActiveControl = SectionName) then
|
|
begin
|
|
Sect := SectionByRow(Section);
|
|
if Sect <> nil then
|
|
FCompList.Add(Sect);
|
|
end;
|
|
if (FCompList.Count = 0) and (Item <> nil) then
|
|
FCompList.Add(Item);
|
|
end;
|
|
if (FBar <> nil) and (FCompList.Count = 0) then
|
|
FCompList.Add(FBar);
|
|
SetSelection(FCompList);
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF COMPILER6_UP}
|
|
procedure TJvSpeedbarEditorMain.DesignerClosed(const ADesigner: IDesigner; AGoingDormant: Boolean);
|
|
{$ELSE}
|
|
procedure TJvSpeedbarEditorMain.FormClosed(Form: TCustomForm);
|
|
{$ENDIF COMPILER6_UP}
|
|
begin
|
|
{$IFDEF COMPILER6_UP}
|
|
if ADesigner.Root = OwnerForm then
|
|
{$ELSE}
|
|
if Form = OwnerForm then
|
|
{$ENDIF COMPILER6_UP}
|
|
Free;
|
|
end;
|
|
|
|
{$IFDEF COMPILER6_UP}
|
|
procedure TJvSpeedbarEditorMain.ItemsModified(const Designer: IDesigner);
|
|
{$ELSE}
|
|
procedure TJvSpeedbarEditorMain.FormModified;
|
|
{$ENDIF COMPILER6_UP}
|
|
begin
|
|
if not (csDestroying in ComponentState) then
|
|
UpdateData;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.Activated;
|
|
begin
|
|
SelectButton(CurrentSection, ItemByRow(ButtonsList.Row), False);
|
|
PasteMenu.Enabled := CheckSpeedBar and (FBar.SectionCount > 0) and
|
|
ClipboardComponents;
|
|
end;
|
|
|
|
function TJvSpeedbarEditorMain.ConfirmDelete: Boolean;
|
|
begin
|
|
Result := MessageDlg(RsConfirmSBDelete, mtWarning, mbYesNoCancel, 0) = mrYes;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SaveSelection;
|
|
begin
|
|
with FSelectData do
|
|
begin
|
|
bRowCount := ButtonsList.RowCount;
|
|
bRow := ButtonsList.Row;
|
|
sRowCount := SectionList.RowCount;
|
|
sRow := SectionList.Row;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.RestoreSelection;
|
|
var
|
|
NewSRow, NewBRow: Integer;
|
|
begin
|
|
NewSRow := FSelectData.sRow;
|
|
if (SectionList.RowCount > FSelectData.sRowCount) or
|
|
(NewSRow > SectionList.RowCount - 1) then
|
|
NewSRow := SectionList.RowCount - 1;
|
|
if NewSRow < 0 then
|
|
NewSRow := 0;
|
|
SectionList.Row := NewSRow;
|
|
SetSection(SectionList.Row); { set ButtonsList to current section }
|
|
NewBRow := FSelectData.bRow;
|
|
if (ButtonsList.RowCount > FSelectData.bRowCount) or
|
|
(NewBRow > ButtonsList.RowCount - 1) then
|
|
NewBRow := ButtonsList.RowCount - 1;
|
|
if NewBRow < 0 then
|
|
NewBRow := 0;
|
|
ButtonsList.Row := NewBRow;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.UpdateEnabled(BtnRow, Section: Integer);
|
|
var
|
|
EnableSect, EnableBtn: Boolean;
|
|
begin
|
|
EnableSect := CheckSpeedBar and (FBar.SectionCount > 0);
|
|
EnableBtn := EnableSect and (BtnRow >= 0) and (ItemBySectionRow(Section,
|
|
BtnRow) <> nil);
|
|
DelSection.Enabled := EnableSect;
|
|
SectionName.Enabled := EnableSect;
|
|
AddButton.Enabled := EnableSect;
|
|
RemoveButton.Enabled := EnableBtn;
|
|
CopyMenu.Enabled := EnableBtn;
|
|
CutMenu.Enabled := EnableBtn;
|
|
PasteMenu.Enabled := EnableSect and ClipboardComponents;
|
|
UpBtn.Enabled := EnableBtn and (BtnRow > 0);
|
|
DownBtn.Enabled := EnableBtn and (BtnRow < ButtonsList.RowCount - 1);
|
|
end;
|
|
|
|
function TJvSpeedbarEditorMain.CheckSpeedBar: Boolean;
|
|
begin
|
|
Result := (FBar <> nil) and (FBar.Owner <> nil) and (FBar.Parent <> nil) and
|
|
{$IFDEF COMPILER6_UP}
|
|
(Designer.Root <> nil);
|
|
{$ELSE}
|
|
(Designer.Form <> nil);
|
|
{$ENDIF COMPILER6_UP}
|
|
end;
|
|
|
|
function TJvSpeedbarEditorMain.CurrentSection: Integer;
|
|
begin
|
|
if CheckSpeedBar and (FBar.SectionCount > 0) then
|
|
Result := SectionList.Row
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SetSection(Section: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if CheckSpeedBar then
|
|
begin
|
|
I := Section;
|
|
if (I >= 0) and (I < FBar.SectionCount) then
|
|
begin
|
|
SectionName.Text := TJvSpeedbarSection(FBar.Sections[I]).Caption;
|
|
ButtonsList.RowCount := FBar.ItemsCount(I);
|
|
end
|
|
else
|
|
begin
|
|
SectionName.Text := '';
|
|
ButtonsList.RowCount := 0;
|
|
end;
|
|
SectionList.DefaultColWidth := SectionList.ClientWidth;
|
|
ButtonsList.DefaultColWidth := ButtonsList.ClientWidth;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.UpdateData;
|
|
begin
|
|
Inc(FLocked);
|
|
try
|
|
SaveSelection;
|
|
if CheckSpeedBar then
|
|
SectionList.RowCount := FBar.SectionCount
|
|
else
|
|
SectionList.RowCount := 0;
|
|
RestoreSelection; { set section }
|
|
finally
|
|
Dec(FLocked);
|
|
end;
|
|
UpdateEnabled(ButtonsList.Row, SectionList.Row);
|
|
SelectButton(CurrentSection, ItemByRow(ButtonsList.Row), False);
|
|
end;
|
|
|
|
function TJvSpeedbarEditorMain.GetForm: TCustomForm;
|
|
begin
|
|
{$IFDEF COMPILER6_UP}
|
|
Result := TCustomForm(Designer.Root); { GetParentForm(FBar) }
|
|
{$ELSE}
|
|
Result := Designer.Form; { GetParentForm(FBar) }
|
|
{$ENDIF COMPILER6_UP}
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.UpdateListHeight;
|
|
var
|
|
Cnt: Integer;
|
|
MaxHeight: Integer;
|
|
begin
|
|
Canvas.Font := Font;
|
|
MaxHeight := MulDiv(MaxBtnListHeight, Screen.PixelsPerInch, 96);
|
|
ButtonsList.DefaultRowHeight := FBar.BtnHeight + 2;
|
|
Cnt := Max(1, Max(ButtonsList.ClientHeight, MaxHeight) div (FBar.BtnHeight + 2));
|
|
ButtonsList.ClientHeight := Min(ButtonsList.DefaultRowHeight * Cnt, MaxHeight);
|
|
SectionList.DefaultRowHeight := CanvasMaxTextHeight(Canvas) + 2;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SetJvSpeedBar(Value: TJvSpeedBar);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if FBar <> Value then
|
|
begin
|
|
if FBar <> nil then
|
|
FBar.SetEditing(0);
|
|
FBar := Value;
|
|
if FBar <> nil then
|
|
FBar.SetEditing(Handle);
|
|
Inc(FLocked);
|
|
try
|
|
if FBar <> nil then
|
|
UpdateListHeight;
|
|
if FBar.SectionCount = 0 then
|
|
NewSectionClick(Self)
|
|
else
|
|
for I := 0 to FBar.SectionCount - 1 do
|
|
if FBar.Sections[I].Name = '' then
|
|
begin
|
|
FBar.Sections[I].Name := UniqueName(FBar.Sections[I]);
|
|
Designer.Modified;
|
|
end;
|
|
if ButtonsList.RowCount > 0 then
|
|
ActiveControl := ButtonsList
|
|
else
|
|
ActiveControl := SectionList;
|
|
UpdateData;
|
|
ButtonsList.Row := 0;
|
|
finally
|
|
Dec(FLocked);
|
|
end;
|
|
SectionList.Row := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.CMSpeedBarChanged(var Msg: TMessage);
|
|
begin
|
|
if Pointer(Msg.LParam) = FBar then
|
|
case Msg.WParam of
|
|
SBR_CHANGED:
|
|
Designer.Modified;
|
|
SBR_DESTROYED:
|
|
Close;
|
|
SBR_BTNSIZECHANGED:
|
|
if FBar <> nil then
|
|
UpdateListHeight;
|
|
end
|
|
else
|
|
if (Msg.WParam = SBR_BTNSELECT) and CheckSpeedBar then
|
|
begin
|
|
SelectButton(-1, nil, True);
|
|
Designer.Modified;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedbarEditorMain.ItemBySectionRow(Section, Row: Integer): TJvSpeedItem;
|
|
begin
|
|
if CheckSpeedBar then
|
|
Result := FBar.Items(Section, Row)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TJvSpeedbarEditorMain.SectionByRow(Row: Integer): TJvSpeedbarSection;
|
|
begin
|
|
if CheckSpeedBar and (Row >= 0) and (Row < FBar.SectionCount) then
|
|
Result := FBar.Sections[Row]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TJvSpeedbarEditorMain.ItemByRow(Row: Integer): TJvSpeedItem;
|
|
begin
|
|
Result := ItemBySectionRow(CurrentSection, Row);
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.NewSectionClick(Sender: TObject);
|
|
var
|
|
S: string;
|
|
I: Integer;
|
|
begin
|
|
if CheckSpeedBar then
|
|
begin
|
|
I := 0;
|
|
repeat
|
|
S := Format(RsNewSectionName, [I]);
|
|
Inc(I);
|
|
until FBar.SearchSection(S) < 0;
|
|
I := NewSpeedSection(FBar, S);
|
|
if I >= 0 then
|
|
FBar.Sections[I].Name := UniqueName(FBar.Sections[I]);
|
|
ActiveControl := SectionName;
|
|
Designer.Modified;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.DelSectionClick(Sender: TObject);
|
|
var
|
|
Sect: Integer;
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
if CheckSpeedBar and ConfirmDelete then
|
|
begin
|
|
Sect := SectionList.Row;
|
|
if (Sect >= 0) and (Sect < FBar.SectionCount) then
|
|
begin
|
|
// Self.ValidateRename(FBar.Sections[Sect],
|
|
{$IFDEF COMPILER6_UP}
|
|
TCustomForm(Designer.Root).Designer.ValidateRename(FBar.Sections[Sect],
|
|
FBar.Sections[Sect].Name, '');
|
|
{$ELSE}
|
|
Designer.ValidateRename(FBar.Sections[Sect],
|
|
FBar.Sections[Sect].Name, '');
|
|
{$ENDIF COMPILER6_UP}
|
|
try
|
|
while FBar.ItemsCount(Sect) > 0 do
|
|
begin
|
|
Item := FBar.Items(Sect, 0);
|
|
if Item <> nil then
|
|
begin
|
|
OwnerForm.RemoveComponent(Item);
|
|
Item.Free;
|
|
end;
|
|
end;
|
|
FBar.RemoveSection(Sect);
|
|
finally
|
|
Designer.Modified;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.Copy;
|
|
var
|
|
CompList: TDesignerSelectionList;
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
{$IFDEF COMPILER5}
|
|
CompList := TDesignerSelectionList.Create;
|
|
{$ELSE}
|
|
CompList := TDesignerSelections.Create;
|
|
{$ENDIF COMPILER5}
|
|
{$IFDEF COMPILER5}
|
|
try
|
|
{$ENDIF COMPILER5}
|
|
Item := ItemByRow(ButtonsList.Row);
|
|
if Item <> nil then
|
|
begin
|
|
Item.InvalidateItem;
|
|
CompList.Add(Item);
|
|
CopyComponents(OwnerForm, CompList);
|
|
Item.UpdateSection;
|
|
end;
|
|
{$IFDEF COMPILER5}
|
|
finally
|
|
CompList.Free;
|
|
end;
|
|
{$ENDIF COMPILER5}
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.Paste;
|
|
var
|
|
CompList: TDesignerSelectionList;
|
|
begin
|
|
if CheckSpeedBar then
|
|
begin
|
|
{$IFDEF COMPILER5}
|
|
CompList := TDesignerSelectionList.Create;
|
|
{$ELSE}
|
|
CompList := TDesignerSelections.Create;
|
|
{$ENDIF COMPILER5}
|
|
{$IFDEF COMPILER5}
|
|
try
|
|
{$ENDIF COMPILER5}
|
|
FBar.OnAddItem := OnPasteItem;
|
|
try
|
|
PasteComponents(OwnerForm, FBar, CompList);
|
|
finally
|
|
FBar.OnAddItem := nil;
|
|
end;
|
|
UpdateData;
|
|
{$IFDEF COMPILER5}
|
|
finally
|
|
CompList.Free;
|
|
end;
|
|
{$ENDIF COMPILER5}
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.Cut;
|
|
begin
|
|
Copy;
|
|
RemoveButtonClick(Self);
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.OnPasteItem(Item: TObject);
|
|
begin
|
|
if Item <> nil then
|
|
if CheckSpeedBar and (Item is TJvSpeedItem) then
|
|
begin
|
|
TJvSpeedItem(Item).ASection := CurrentSection;
|
|
TJvSpeedItem(Item).Visible := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.AddButtonClick(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
I := CurrentSection;
|
|
if I < 0 then
|
|
Exit;
|
|
Item := TJvSpeedItem.Create(OwnerForm);
|
|
if Item <> nil then
|
|
try
|
|
FBar.AddItem(I, Item);
|
|
Item.Name := UniqueName(Item);
|
|
Designer.Modified;
|
|
if Sender <> nil then
|
|
ActivateInspector(#0);
|
|
except
|
|
Item.Free;
|
|
raise;
|
|
end
|
|
else
|
|
raise EJvSpeedbarError.CreateRes(@RsESBItemNotCreate);
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.RemoveButtonClick(Sender: TObject);
|
|
var
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
Item := ItemByRow(ButtonsList.Row);
|
|
if Item <> nil then
|
|
begin
|
|
Self.ValidateRename(Item, Item.Name, '');
|
|
OwnerForm.RemoveComponent(Item);
|
|
Item.Free;
|
|
Designer.Modified;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.CloseBtnClick(Sender: TObject);
|
|
begin
|
|
Close;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.UpBtnClick(Sender: TObject);
|
|
var
|
|
I, Sect: Integer;
|
|
begin
|
|
if CheckSpeedBar and FBar.FindItem(ItemByRow(ButtonsList.Row), Sect, I) then
|
|
if I > 0 then
|
|
begin
|
|
FBar.Sections[Sect].List.Move(I, I - 1);
|
|
Designer.Modified;
|
|
ButtonsList.Invalidate;
|
|
ButtonsList.Row := ButtonsList.Row - 1;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.DownBtnClick(Sender: TObject);
|
|
var
|
|
I, Sect: Integer;
|
|
begin
|
|
if CheckSpeedBar and FBar.FindItem(ItemByRow(ButtonsList.Row), Sect, I) then
|
|
if I < FBar.ItemsCount(Sect) - 1 then
|
|
begin
|
|
FBar.Sections[Sect].List.Move(I, I + 1);
|
|
Designer.Modified;
|
|
ButtonsList.Invalidate;
|
|
ButtonsList.Row := ButtonsList.Row + 1;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.CopyMenuClick(Sender: TObject);
|
|
begin
|
|
Copy;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.PasteMenuClick(Sender: TObject);
|
|
begin
|
|
Paste;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.CutMenuClick(Sender: TObject);
|
|
begin
|
|
Cut;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SectionNameExit(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if CheckSpeedBar and (FBar.SectionCount > 0) then
|
|
begin
|
|
I := CurrentSection;
|
|
if I >= 0 then
|
|
begin
|
|
FBar.Sections[I].Caption := SectionName.Text;
|
|
Designer.Modified;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SectionListSelectCell(Sender: TObject; Col,
|
|
Row: Longint; var CanSelect: Boolean);
|
|
begin
|
|
CanSelect := False;
|
|
if CheckSpeedBar and (Row < FBar.SectionCount) and (Row >= 0) then
|
|
begin
|
|
if FLocked = 0 then
|
|
begin
|
|
SetSection(Row);
|
|
UpdateEnabled(ButtonsList.Row, Row);
|
|
ButtonsList.Invalidate;
|
|
SelectButton(Row, ItemBySectionRow(Row, ButtonsList.Row), False);
|
|
end;
|
|
CanSelect := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SectionListDrawCell(Sender: TObject; Col,
|
|
Row: Longint; Rect: TRect; State: TGridDrawState);
|
|
begin
|
|
if CheckSpeedBar then
|
|
if (Row < FBar.SectionCount) and (Row >= 0) then
|
|
DrawCellText(Sender as TDrawGrid, Col, Row,
|
|
FBar.Sections[Row].Caption, Rect, taLeftJustify, vaCenterJustify, TDrawGrid(Sender).IsRightToLeft);
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SectionListKeyDown(Sender: TObject;
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
case Key of
|
|
VK_RETURN:
|
|
if SectionByRow(SectionList.Row) <> nil then
|
|
ActivateInspector(#0);
|
|
VK_DELETE:
|
|
DelSectionClick(Self);
|
|
VK_INSERT, VK_ADD:
|
|
NewSectionClick(Self);
|
|
else
|
|
Exit;
|
|
end;
|
|
Key := 0;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.ButtonsListKeyDown(Sender: TObject;
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
case Key of
|
|
VK_RETURN:
|
|
if ItemByRow(ButtonsList.Row) <> nil then
|
|
ActivateInspector(#0);
|
|
VK_DELETE:
|
|
RemoveButtonClick(Self);
|
|
VK_INSERT, VK_ADD:
|
|
AddButtonClick(Self);
|
|
else
|
|
Exit;
|
|
end;
|
|
Key := 0;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.ButtonsListDblClick(Sender: TObject);
|
|
const
|
|
{$IFDEF BCB}
|
|
cSender: string[7] = '*Sender';
|
|
{$ELSE}
|
|
cSender: string[6] = 'Sender';
|
|
{$ENDIF BCB}
|
|
cObject: string[7] = 'TObject';
|
|
cClick = 'Click';
|
|
cOnClick = 'OnClick';
|
|
type
|
|
PParamData = ^TParamData;
|
|
TParamData = record
|
|
Flags: TParamFlags;
|
|
ParamNameAndType: array [0..100] of Char;
|
|
end;
|
|
var
|
|
Btn: TJvSpeedItem;
|
|
I, Num: Integer;
|
|
MethodName: string;
|
|
Method: TMethod;
|
|
TypeData: PTypeData;
|
|
ParamData: PParamData;
|
|
PropInfo: PPropInfo;
|
|
Candidates: TJvPropInfoList;
|
|
begin
|
|
Btn := ItemByRow(ButtonsList.Row);
|
|
if Btn = nil then
|
|
Exit;
|
|
Candidates := TJvPropInfoList.Create(Btn, [tkMethod]);
|
|
try
|
|
for I := Candidates.Count - 1 downto 0 do
|
|
begin
|
|
PropInfo := Candidates[I];
|
|
if CompareText(PropInfo^.Name, cOnClick) = 0 then
|
|
begin
|
|
Method := GetMethodProp(Btn, PropInfo);
|
|
MethodName := IJvFormDesigner(Designer).GetMethodName(Method);
|
|
if MethodName = '' then
|
|
begin
|
|
MethodName := Btn.Name + cClick;
|
|
Num := 0;
|
|
while IJvFormDesigner(Designer).MethodExists(MethodName) do
|
|
begin
|
|
MethodName := Btn.Name + cClick + IntToStr(Num);
|
|
Inc(Num);
|
|
end;
|
|
TypeData := AllocMem(SizeOf(TTypeData));
|
|
try
|
|
TypeData^.MethodKind := mkProcedure;
|
|
TypeData^.ParamCount := 1;
|
|
ParamData := PParamData(@TypeData^.ParamList);
|
|
with ParamData^ do
|
|
begin
|
|
Flags := [];
|
|
// (rom) WARNING! Needs check against buffer overflow.
|
|
ParamNameAndType[0] := Char(Length(cSender));
|
|
Move(cSender[1], ParamNameAndType[1], Length(cSender));
|
|
ParamNameAndType[Length(cSender) + 1] := Char(Length(cObject));
|
|
Move(cObject[1], ParamNameAndType[Length(cSender) + 2],
|
|
Length(cObject));
|
|
end;
|
|
Method := IJvFormDesigner(Designer).CreateMethod(MethodName, TypeData);
|
|
Method.Data := OwnerForm;
|
|
finally
|
|
FreeMem(TypeData, SizeOf(TTypeData));
|
|
end;
|
|
Btn.OnClick := TNotifyEvent(Method);
|
|
Designer.Modified;
|
|
end;
|
|
if (MethodName <> '') and IJvFormDesigner(Designer).MethodExists(MethodName) then
|
|
IJvFormDesigner(Designer).ShowMethod(MethodName);
|
|
Break;
|
|
end;
|
|
end;
|
|
finally
|
|
Candidates.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.ButtonsListMouseDown(Sender: TObject;
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
if (X < FBar.BtnWidth + 2) and (Button = mbLeft) then
|
|
begin
|
|
Item := ItemByRow(ButtonsList.Row);
|
|
if Item <> nil then
|
|
begin
|
|
FDrag := True;
|
|
if Item.Visible then
|
|
FDragItem := nil
|
|
else
|
|
begin
|
|
FDragItem := Item;
|
|
if FButton = nil then
|
|
begin
|
|
FButton := TJvBtnControl.Create(Self);
|
|
TJvBtnControl(FButton).AssignSpeedItem(Item);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.ButtonsListMouseMove(Sender: TObject;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
if FDrag and (FButton <> nil) and (FDragItem <> nil) then
|
|
begin
|
|
P := (Sender as TControl).ClientToScreen(Point(X, Y));
|
|
X := P.X - FButton.Width {div 2};
|
|
Y := P.Y - FButton.Height {div 2};
|
|
FButton.Activate(Bounds(X, Y, FBar.BtnWidth, FBar.BtnHeight));
|
|
end
|
|
else
|
|
if FDrag then
|
|
SetCursor(Screen.Cursors[crNoDrop]);
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.ButtonsListMouseUp(Sender: TObject;
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
if FDrag and (Button = mbLeft) then
|
|
try
|
|
if (FDragItem <> nil) and (FButton <> nil) then
|
|
begin
|
|
Dec(X, FButton.Width {div 2});
|
|
Dec(Y, FButton.Height {div 2});
|
|
P := (Sender as TControl).ClientToScreen(Point(X, Y));
|
|
FButton.Free;
|
|
FButton := nil;
|
|
if CheckSpeedBar and (FBar = FindSpeedBar(P)) then
|
|
begin
|
|
P := FBar.ScreenToClient(P);
|
|
if FBar.AcceptDropItem(FDragItem, P.X, P.Y) then
|
|
Designer.Modified;
|
|
end;
|
|
end
|
|
else
|
|
SetCursor(Screen.Cursors[ButtonsList.Cursor]);
|
|
finally
|
|
FDrag := False;
|
|
FDragItem := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.ButtonsListSelectCell(Sender: TObject;
|
|
Col, Row: Longint; var CanSelect: Boolean);
|
|
var
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
Item := ItemByRow(Row);
|
|
CanSelect := not FDrag and (Item <> nil);
|
|
if FLocked = 0 then
|
|
begin
|
|
if CanSelect then
|
|
begin
|
|
UpdateEnabled(Row, SectionList.Row);
|
|
SelectButton(CurrentSection, Item, False);
|
|
end
|
|
else
|
|
if not FDrag then
|
|
begin
|
|
UpdateEnabled(-1, SectionList.Row);
|
|
SelectButton(-1, nil, True);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.FormCreate(Sender: TObject);
|
|
begin
|
|
FImage := TJvButtonImage.Create;
|
|
FButton := nil;
|
|
FBar := nil;
|
|
FDrag := False;
|
|
if NewStyleControls then
|
|
Font.Style := [];
|
|
AppStorage.Root := SDelphiKey;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.FormDestroy(Sender: TObject);
|
|
begin
|
|
FImage.Free;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.FormClose(Sender: TObject; var Action: TCloseAction);
|
|
begin
|
|
Action := caFree;
|
|
FButton.Free;
|
|
FButton := nil;
|
|
if FBar <> nil then
|
|
begin
|
|
FBar.SetEditing(0);
|
|
SelectButton(-1, nil, True);
|
|
FBar.Invalidate;
|
|
end;
|
|
FBar := nil;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SectionNameKeyDown(Sender: TObject;
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if Key = VK_RETURN then
|
|
begin
|
|
SectionNameExit(SectionName);
|
|
Key := 0;
|
|
ActiveControl := SectionList;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.ButtonsListDrawCell(Sender: TObject; Col,
|
|
Row: Longint; Rect: TRect; State: TGridDrawState);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
I := CurrentSection;
|
|
if (I >= 0) and (Row < FBar.ItemsCount(I)) then
|
|
DrawCellButton(Sender as TDrawGrid, Rect, ItemByRow(Row), FImage, TDrawGrid(Sender).IsRightToLeft);
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SectionListMouseDown(Sender: TObject;
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
ACol, ARow: Longint;
|
|
begin
|
|
if Button = mbLeft then
|
|
with Sender as TDrawGrid do
|
|
begin
|
|
MouseToCell(X, Y, ACol, ARow);
|
|
Tag := Row;
|
|
BeginDrag(False);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SectionListDragDrop(Sender, Source: TObject; X,
|
|
Y: Integer);
|
|
var
|
|
Col, Row: Longint;
|
|
begin
|
|
try
|
|
(Sender as TDrawGrid).MouseToCell(X, Y, Col, Row);
|
|
FBar.Sections[(Sender as TDrawGrid).Tag].Index := Row;
|
|
Designer.Modified;
|
|
UpdateData;
|
|
SectionList.Row := Row;
|
|
finally
|
|
(Sender as TDrawGrid).Tag := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.SectionListDragOver(Sender, Source: TObject; X,
|
|
Y: Integer; State: TDragState; var Accept: Boolean);
|
|
var
|
|
Col, Row: Longint;
|
|
begin
|
|
(Sender as TDrawGrid).MouseToCell(X, Y, Col, Row);
|
|
Accept := (Row >= 0) and (Row <> (Sender as TDrawGrid).Tag);
|
|
end;
|
|
|
|
procedure TJvSpeedbarEditorMain.FormShow(Sender: TObject);
|
|
begin
|
|
if FBar <> nil then
|
|
UpdateListHeight;
|
|
SectionList.DefaultColWidth := SectionList.ClientWidth;
|
|
ButtonsList.DefaultColWidth := ButtonsList.ClientWidth;
|
|
end;
|
|
|
|
end.
|
|
|