Componentes.Terceros.jvcl/official/3.32/design/JvID3v2EditorForm.pas

991 lines
25 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: JvID3v2Editor.PAS, released on 2003-04-16.
The Initial Developer of the Original Code is Remko Bonte [remkobonte att myrealbox dott com]
Portions created by Remko Bonte are Copyright (C) 2003 Remko Bonte.
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: JvID3v2EditorForm.pas 10610 2006-05-19 13:35:08Z elahn $
unit JvID3v2EditorForm;
{$I jvcl.inc}
interface
{ Most code is copied from DSDesign.pas }
uses
Classes, Windows, Messages, Forms, StdCtrls, ExtCtrls, Menus, Controls,
{$IFDEF COMPILER6_UP}
DesignEditors, DesignIntf, DesignMenus, DesignWindows,
{$ELSE}
DsgnIntf, DsgnWnds,
{$ENDIF COMPILER6_UP}
JvID3v2Base, JvID3v2Types, JvDsgnTypes;
type
TSelectionProc = function(AFrame: TJvID3Frame): Boolean of object;
TFSDesigner = class;
TJvID3FramesEditor = class(TDesignWindow)
FrameListBox: TListBox;
LocalMenu: TPopupMenu;
NewItem: TMenuItem;
N1: TMenuItem;
DeleteItem: TMenuItem;
SelectAllItem: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure ListBoxClick(Sender: TObject);
procedure ListBoxKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure ListBoxDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure ListBoxDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure FormDestroy(Sender: TObject);
procedure NewFrameClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
procedure SelectAllClick(Sender: TObject);
private
FFSDesigner: TFSDesigner;
FController: TJvID3Controller;
FFocusRectItem: Integer;
FMinWidth: Integer;
FMinHeight: Integer;
procedure MoveFrames(MoveOffset: Integer);
procedure RemoveFrames;
procedure SelectAll;
procedure RestoreSelection(var Selection: TStringList;
ItemIndex, TopIndex: Integer; RestoreUpdate: Boolean);
procedure SaveSelection(var Selection: TStringList;
var ItemIndex, TopIndex: Integer; NoUpdate: Boolean);
procedure SetController(Value: TJvID3Controller);
procedure UpdateDisplay;
procedure UpdateCaption;
procedure UpdateFrameList;
procedure UpdateSelection;
procedure WMGetMinMaxInfo(var Msg: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
protected
procedure Activated; override;
function UniqueName(Component: TComponent): string; override;
public
function ForEachSelection(Proc: TSelectionProc): Boolean;
function DoNewFrame: TJvID3Frame;
{$IFDEF COMPILER5}
procedure SelectionChanged(ASelection: TDesignerSelectionList); override;
procedure EditAction(Action: TEditAction); override;
procedure ComponentDeleted(Component: IPersistent); override;
procedure FormModified; override;
{$ELSE}
function EditAction(Action: TEditAction): Boolean; override;
procedure ItemDeleted(const ADesigner: IDesigner; AItem: TPersistent); override;
procedure SelectionChanged(const ADesigner: IDesigner; const ASelection: IDesignerSelections); override;
procedure ItemsModified(const Designer: IDesigner); override;
{$ENDIF COMPILER5}
property Controller: TJvID3Controller read FController write SetController;
end;
TJvID3ControllerEditor = class(TComponentEditor)
protected
procedure Commit;
procedure RemoveTag;
public
procedure ExecuteVerb(Index: Integer); override;
function GetVerb(Index: Integer): string; override;
function GetVerbCount: Integer; override;
end;
TFSDesigner = class(TJvID3ControllerDesigner)
private
FFramesEditor: TJvID3FramesEditor;
function GetFrameDescription(const FrameID: TJvID3FrameID): string;
public
destructor Destroy; override;
procedure ID3Event(Event: TJvID3Event; Info: Longint); override;
property FramesEditor: TJvID3FramesEditor read FFramesEditor;
property FrameDescription[const FrameID: TJvID3FrameID]: string read GetFrameDescription;
end;
TJvID3FileInfoEditor = class(TClassProperty)
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes; override;
end;
procedure ShowFramesEditor(Designer: IJvFormDesigner; AController: TJvID3Controller);
function CreateFramesEditor(Designer: IJvFormDesigner;
AController: TJvID3Controller; var Shared: Boolean): TJvID3FramesEditor;
procedure ShowFileInfo(AController: TJvID3Controller);
implementation
uses
Dialogs,
Math, SysUtils,
JvID3v2DefineForm, JvTypes, JvDsgnConsts;
{$R *.dfm}
type
TJvID3ControllerAccess = class(TJvID3Controller);
const
cFrameDescriptions: array [TJvID3FrameID] of string =
(
RsfiErrorFrame,
RsfiPaddingFrame,
RsfiNoFrame,
RsfiAudioCrypto,
RsfiPicture,
RsfiAudioSeekPoint,
RsfiComment,
RsfiCommercial,
RsfiCryptoReg,
RsfiEqualization2,
RsfiEqualization,
RsfiEventTiming,
RsfiGeneralObject,
RsfiGroupingReg,
RsfiInvolvedPeople,
RsfiLinkedInfo,
RsfiCDID,
RsfiMPEGLookup,
RsfiOwnership,
RsfiPrivate,
RsfiPlayCounter,
RsfiPopularimeter,
RsfiPositionsync,
RsfiBufferSize,
RsfiVolumeAdj2,
RsfiVolumeAdj,
RsfiReverb,
RsfiSeekFrame,
RsfiSignature,
RsfiSyncedLyrics,
RsfiSyncedTempo,
RsfiAlbum,
RsfiBPM,
RsfiComposer,
RsfiContentType,
RsfiCopyright,
RsfiDate,
RsfiEncodingTime,
RsfiPlaylistDelay,
RsfiOrigReleaseTime,
RsfiRecordingTime,
RsfiReleaseTime,
RsfiTaggingTime,
RsfiInvolvedPeople2,
RsfiEncodedBy,
RsfiLyricist,
RsfiFileType,
RsfiTime,
RsfiContentGroup,
RsfiTitle,
RsfiSubTitle,
RsfiInitialKey,
RsfiLanguage,
RsfiSongLen,
RsfiMusicianCreditList,
RsfiMediaType,
RsfiMood,
RsfiOrigAlbum,
RsfiOrigFileName,
RsfiOrigLyricist,
RsfiOrigArtist,
RsfiOrigYear,
RsfiFileOwner,
RsfiLeadArtist,
RsfiBand,
RsfiConductor,
RsfiMixArtist,
RsfiPartInSet,
RsfiProducedNotice,
RsfiPublisher,
RsfiTrackNum,
RsfiRecordingDates,
RsfiNetRadioStation,
RsfiNetRadioOwner,
RsfiSize,
RsfiAlbumSortOrder,
RsfiPerformerSortOrder,
RsfiTitleSortOrder,
RsfiISRC,
RsfiEncoderSettings,
RsfiSetSubTitle,
RsfiUserText,
RsfiYear,
RsfiUniqueFileID,
RsfiTermsOfUse,
RsfiUnsyncedLyrics,
RsfiWWWCommercialInfo,
RsfiWWWCopyright,
RsfiWWWAudioFile,
RsfiWWWArtist,
RsfiWWWAudioSource,
RsfiWWWRadioPage,
RsfiWWWPayment,
RsfiWWWPublisher,
RsfiWWWUser,
RsfiMetaCrypto,
RsfiMetaCompression
);
procedure ShowFramesEditor(Designer: IJvFormDesigner; AController: TJvID3Controller);
var
FramesEditor: TJvID3FramesEditor;
VShared: Boolean;
begin
FramesEditor := CreateFramesEditor(Designer, AController, VShared);
if FramesEditor <> nil then
FramesEditor.Show;
end;
function CreateFramesEditor(Designer: IJvFormDesigner;
AController: TJvID3Controller; var Shared: Boolean): TJvID3FramesEditor;
begin
Shared := True;
if AController.Designer <> nil then
Result := (AController.Designer as TFSDesigner).FFramesEditor
else
begin
Result := TJvID3FramesEditor.Create(Application);
Result.Designer := Designer;
Result.Controller := AController;
Shared := False;
end;
end;
procedure ShowFileInfo(AController: TJvID3Controller);
const
cVersion: array [TJvMPEGVersion] of string =
(RsMPEG25, RsMPEGUnknown, RsMPEG20, RsMPEG10);
cLayer: array [TJvMPEGLayer] of string =
(RsLayerUnknown, RsLayer3, RsLayer2, RsLayer1);
cChannelMode: array [TJvMPEGChannelMode] of string =
(RsChannelModeStereo, RsChannelModeJointStereo,
RsChannelModeDualChannel, RsChannelModeMono);
cEmphasis: array [TJvMPEGEmphasis] of string =
(RsEmphasisNone, RsEmphasisMicrosec, RsEmphasisUnknown, RsEmphasisCCITTJ17);
cBool: array [Boolean] of string =
(RsBoolNo, RsBoolYes);
cVbr: array [Boolean] of string =
(RsVbrNo, RsVbrVbr);
var
Msg: string;
SavedActive: Boolean;
begin
SavedActive := AController.Active;
try
with TJvID3ControllerAccess(AController) do
begin
if FileName = '' then
begin
MessageDlg(RsID3Err_NoFileSpecified, mtError, [mbOK], 0);
Exit;
end;
if not FileExists(FileName) then
begin
MessageDlg(Format(RSID3Err_FileDoesNotExists, [FileName]),
mtError, [mbOK], 0);
Exit;
end;
Active := True;
with FileInfo do
begin
if not IsValid then
begin
MessageDlg(RSID3Err_NoValidMPEGTag, mtError, [mbOK], 0);
Exit;
end;
Msg := Format(RsIDV2FileInfoFmt, [FileSize, HeaderFoundAt, LengthInSec,
cVersion[Version], cLayer[Layer], Bitrate, cVbr[IsVbr], FrameCount,
SamplingRateFrequency, cChannelMode[ChannelMode],
cBool[mbProtection in Bits], cBool[mbCopyrighted in Bits],
cBool[mbOriginal in Bits], cEmphasis[Emphasis]]);
end;
end;
{ We don't use MessageDlg now, because we want a custom caption }
with CreateMessageDialog(Msg, mtCustom, [mbOK]) do
try
Position := poScreenCenter;
Caption := RsIDV2FileInfoCaption;
ShowModal;
finally
Free;
end;
finally
AController.Active := SavedActive;
end;
end;
//=== { TJvID3FrameEditor } ==================================================
procedure TJvID3FramesEditor.Activated;
begin
{$IFDEF COMPILER6_UP}
Designer.Activate;
{$ENDIF COMPILER6_UP}
try
UpdateSelection;
except
FrameListBox.Items.Clear;
end;
end;
{$IFDEF COMPILER5}
procedure TJvID3FramesEditor.ComponentDeleted(Component: IPersistent);
var
P: TPersistent;
begin
P := ExtractPersistent(Component);
if P = Controller then
Controller := nil
else
if (P is TJvID3Frame) and (TJvID3Frame(P).Controller = Controller) then
UpdateDisplay;
end;
{$ENDIF COMPILER5}
function TJvID3FramesEditor.DoNewFrame: TJvID3Frame;
var
DefineFrame: TJvID3DefineDlg;
begin
Result := nil;
DefineFrame := TJvID3DefineDlg.Create(Application);
try
DefineFrame.FSDesigner := FFSDesigner;
DefineFrame.Designer := Designer;
DefineFrame.Controller := Controller;
if DefineFrame.ShowModal = mrOk then
begin
Result := DefineFrame.Frame;
if Visible then
UpdateDisplay;
Designer.Modified;
end;
finally
DefineFrame.Release;
end;
end;
{$IFDEF COMPILER6_UP}
function TJvID3FramesEditor.EditAction(Action: TEditAction): Boolean;
{$ELSE}
procedure TJvID3FramesEditor.EditAction(Action: TEditAction);
{$ENDIF COMPILER6_UP}
begin
{$IFDEF COMPILER6_UP}
Result := True;
{$ENDIF COMPILER6_UP}
case Action of
{eaCut: Cut;
eaCopy: Copy;
eaPaste: Paste;}
eaDelete:
RemoveFrames;
eaSelectAll:
begin
SelectAll;
UpdateSelection;
end;
{$IFDEF COMPILER6_UP}
else
Result := False;
{$ENDIF COMPILER6_UP}
end;
end;
function TJvID3FramesEditor.ForEachSelection(Proc: TSelectionProc): Boolean;
var
Frame: TJvID3Frame;
I: Integer;
begin
Result := False;
with FrameListBox do
for I := 0 to Items.Count - 1 do
if Selected[I] then
begin
Frame := TJvID3Frame(Items.Objects[I]);
if (Frame <> nil) and not Proc(Frame) then
Exit;
end;
Result := True;
end;
{$IFDEF COMPILER6_UP}
procedure TJvID3FramesEditor.ItemDeleted(const ADesigner: IDesigner; AItem: TPersistent);
begin
if AItem = Controller then
Controller := nil
else
if (AItem is TJvID3Frame) and (TJvID3Frame(AItem).Controller = Controller) then
UpdateDisplay;
end;
{$ENDIF COMPILER6_UP}
{$IFDEF COMPILER6_UP}
procedure TJvID3FramesEditor.ItemsModified(const Designer: IDesigner);
{$ELSE}
procedure TJvID3FramesEditor.FormModified;
{$ENDIF COMPILER6_UP}
begin
UpdateCaption;
end;
procedure TJvID3FramesEditor.MoveFrames(MoveOffset: Integer);
var
I, E: Integer;
begin
try
FFSDesigner.BeginDesign;
try
with FrameListBox do
begin
I := 0;
E := Items.Count;
if MoveOffset > 0 then
begin
I := E - 1;
E := -1;
end;
while I <> E do
begin
if Selected[I] then
with TJvID3Frame(Items.Objects[I]) do
Index := Index + MoveOffset;
Inc(I, -MoveOffset);
end;
end;
finally
FFSDesigner.EndDesign;
end;
finally
UpdateDisplay;
Designer.Modified;
end;
end;
procedure TJvID3FramesEditor.RemoveFrames;
var
I, Focused: Integer;
begin
try
FFSDesigner.BeginDesign;
try
Focused := FrameListBox.ItemIndex;
with FrameListBox do
for I := Items.Count - 1 downto 0 do
if Selected[I] then
TJvID3Frame(Items.Objects[I]).Free;
finally
FFSDesigner.EndDesign;
Designer.Modified;
end;
finally
UpdateDisplay;
end;
if Focused <> -1 then
begin
Focused := Min(Focused, FrameListBox.Items.Count - 1);
FrameListBox.ItemIndex := Focused;
FrameListBox.Selected[Focused] := True;
UpdateSelection;
end;
FrameListBox.SetFocus;
end;
procedure TJvID3FramesEditor.RestoreSelection(var Selection: TStringList;
ItemIndex, TopIndex: Integer; RestoreUpdate: Boolean);
var
I: Integer;
begin
try
with FrameListBox do
for I := 0 to Items.Count - 1 do
Selected[I] := Selection.IndexOf(TComponent(Items.Objects[I]).Name) <> -1;
if TopIndex <> -1 then
FrameListBox.TopIndex := TopIndex;
if ItemIndex <> -1 then
FrameListBox.ItemIndex := ItemIndex;
finally
if RestoreUpdate then
FrameListBox.Items.EndUpdate;
FrameListBox.Invalidate;
Selection.Free;
Selection := nil;
UpdateSelection;
end;
end;
procedure TJvID3FramesEditor.SaveSelection(var Selection: TStringList;
var ItemIndex, TopIndex: Integer; NoUpdate: Boolean);
var
I: Integer;
begin
{ Name of a frame is unique, thus fill Selection with these names
of frames that are selected }
Selection := TStringList.Create;
try
ItemIndex := FrameListBox.ItemIndex;
TopIndex := FrameListBox.TopIndex;
with FrameListBox do
for I := 0 to Items.Count - 1 do
if Selected[I] then
Selection.Add(TComponent(Items.Objects[I]).Name);
if NoUpdate then
FrameListBox.Items.BeginUpdate;
except
Selection.Free;
Selection := nil;
end;
end;
procedure TJvID3FramesEditor.SelectAll;
var
I: Integer;
begin
with FrameListBox do
for I := 0 to Items.Count - 1 do
Selected[I] := True;
end;
{$IFDEF COMPILER6_UP}
procedure TJvID3FramesEditor.SelectionChanged(const ADesigner: IDesigner;
const ASelection: IDesignerSelections);
{$ELSE}
procedure TJvID3FramesEditor.SelectionChanged(ASelection: TDesignerSelectionList);
{$ENDIF COMPILER6_UP}
var
I: Integer;
S: Boolean;
function InSelection(Component: TComponent): Boolean;
var
I: Integer;
begin
Result := True;
if ASelection <> nil then
with ASelection do
for I := 0 to Count - 1 do
if Component = Items[I] then
Exit;
Result := False;
end;
begin
with FrameListBox do
for I := 0 to Items.Count - 1 do
begin
S := InSelection(TComponent(Items.Objects[I]));
if Selected[I] <> S then
Selected[I] := S;
end;
end;
procedure TJvID3FramesEditor.SetController(Value: TJvID3Controller);
begin
if FController <> Value then
begin
if FController <> nil then
FreeAndNil(FFSDesigner);
FController := Value;
if FController <> nil then
begin
FFSDesigner := TFSDesigner.Create(Value);
FFSDesigner.FFramesEditor := Self;
UpdateDisplay;
end
else
begin
if not (csDestroying in ComponentState) then
Release;
end;
end;
end;
function TJvID3FramesEditor.UniqueName(Component: TComponent): string;
var
FrameName: string;
begin
if Component is TJvID3Frame then
FrameName := TJvID3Frame(Component).FrameName
else
FrameName := '';
Result := CreateUniqueName(Controller, FrameName,
TJvID3FrameClass(Component.ClassType), Component)
end;
procedure TJvID3FramesEditor.UpdateCaption;
const
cFrameEditor = '%s%s%s';
var
NewCaption: string;
begin
if (Controller <> nil) and (Controller.Owner <> nil) then
NewCaption := Format(cFrameEditor,
[Controller.Owner.Name, '.', Controller.Name]);
if Caption <> NewCaption then
Caption := NewCaption;
end;
procedure TJvID3FramesEditor.UpdateDisplay;
begin
UpdateFrameList;
UpdateCaption;
UpdateSelection;
end;
procedure TJvID3FramesEditor.UpdateFrameList;
var
ItemIndex, TopIndex: Integer;
Selection: TStringList;
EnableList: Boolean;
I: Integer;
Frame: TJvID3Frame;
FrameName: string;
begin
SaveSelection(Selection, ItemIndex, TopIndex, True);
try
FrameListBox.Clear;
EnableList := False;
try
if Controller = nil then
Exit;
for I := 0 to Controller.Frames.Count - 1 do
begin
Frame := Controller.Frames[I];
if not (csDestroying in Frame.ComponentState) then
begin
FrameName := Frame.FrameName;
if FrameName = '' then
FrameName := Format('<%s>', [Controller.Frames[I].Name]);
FrameName := FrameName + ' - ' + cFrameDescriptions[Frame.FrameID];
FrameListBox.Items.AddObject(FrameName, Frame);
end;
end;
EnableList := True;
finally
FrameListBox.Enabled := EnableList;
end;
finally
RestoreSelection(Selection, ItemIndex, TopIndex, True)
end;
end;
procedure TJvID3FramesEditor.UpdateSelection;
var
I: Integer;
Frame: TJvID3Frame;
{$IFDEF COMPILER6_UP}
ComponentList: IDesignerSelections;
{$ELSE}
ComponentList: TDesignerSelectionList;
{$ENDIF COMPILER6_UP}
begin
if Active then
begin
{$IFDEF COMPILER6_UP}
ComponentList := TDesignerSelections.Create;
{$ELSE}
ComponentList := TDesignerSelectionList.Create;
{$ENDIF COMPILER6_UP}
try
with FrameListBox do
for I := 0 to Items.Count - 1 do
if Selected[I] then
begin
Frame := TJvID3Frame(Items.Objects[I]);
if Frame <> nil then
ComponentList.Add(Frame);
end;
if ComponentList.Count = 0 then
ComponentList.Add(Controller);
except
{$IFDEF COMPILER5}
// In D6 up it's an interface, so no need to free up
ComponentList.Free;
{$ENDIF COMPILER5}
raise;
end;
{$IFDEF COMPILER5}
SetSelection(ComponentList);
{$ELSE}
Designer.SetSelections(ComponentList);
{$ENDIF COMPILER5}
end;
end;
procedure TJvID3FramesEditor.WMGetMinMaxInfo(var Msg: TWMGetMinMaxInfo);
begin
inherited;
with Msg.MinMaxInfo^.ptMinTrackSize do
begin
X := FMinWidth;
Y := FMinHeight;
end;
end;
//=== { TJvID3ControllerEditor } =============================================
procedure TJvID3ControllerEditor.Commit;
begin
if MessageDlg(RsCommit, mtConfirmation, mbOKCancel, 0) = mrOk then
TJvID3Controller(Component).Commit;
end;
procedure TJvID3ControllerEditor.ExecuteVerb(Index: Integer);
begin
case Index of
0:
ShowFramesEditor(Designer, TJvID3Controller(Component));
1:
RemoveTag;
2:
ShowFileInfo(TJvID3Controller(Component));
3:
Commit;
end;
end;
function TJvID3ControllerEditor.GetVerb(Index: Integer): string;
begin
case Index of
0:
Result := RSID3FrameEditorTag;
1:
Result := RSID3RemoveTag;
2:
Result := RSID3FileInfoTag;
3:
Result := RSID3CommitTag;
end;
end;
function TJvID3ControllerEditor.GetVerbCount: Integer;
begin
Result := 3;
with TJvID3Controller(Component) do
if Active and Modified then
Inc(Result);
end;
procedure TJvID3FramesEditor.FormCreate(Sender: TObject);
begin
FMinWidth := Width;
FMinHeight := Height;
end;
procedure TJvID3ControllerEditor.RemoveTag;
begin
with TJvID3Controller(Component) do
begin
if FileName = '' then
begin
MessageDlg(RsID3Err_NoFileSpecified, mtError, [mbOK], 0);
Exit;
end;
if not FileExists(FileName) then
begin
MessageDlg(Format(RSID3Err_FileDoesNotExists, [FileName]), mtError, [mbOK], 0);
Exit;
end;
if MessageDlg(RSID3RemoveTagConfirmation, mtConfirmation, mbOKCancel, 0) = mrOk then
Erase;
end;
end;
//=== { TFSDesigner } ========================================================
destructor TFSDesigner.Destroy;
var
F: TJvID3FramesEditor;
begin
if FFramesEditor <> nil then
begin
F := FFramesEditor;
FFramesEditor := nil;
F.FFSDesigner := nil;
{ (rb) DSDesign.pas uses Release, but that gave problems, with recompiling }
F.Free;
end;
inherited Destroy;
end;
procedure TJvID3FramesEditor.ListBoxClick(Sender: TObject);
begin
UpdateSelection;
end;
function TFSDesigner.GetFrameDescription(const FrameID: TJvID3FrameID): string;
begin
Result := cFrameDescriptions[FrameID];
end;
procedure TFSDesigner.ID3Event(Event: TJvID3Event; Info: Longint);
begin
if Event in [ideFrameListChange, ideID3Change] then
FFramesEditor.UpdateFrameList;
end;
procedure TJvID3FramesEditor.ListBoxKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case Key of
VK_INSERT:
NewFrameClick(Self);
VK_DELETE:
RemoveFrames;
VK_UP:
if (ssCtrl in Shift) and (Sender = FrameListBox) then
MoveFrames(-1)
else
Exit;
VK_DOWN:
if (ssCtrl in Shift) and (Sender = FrameListBox) then
MoveFrames(1)
else
Exit;
else
Exit;
end;
Key := 0;
end;
procedure TJvID3FramesEditor.ListBoxDragDrop(Sender, Source: TObject;
X, Y: Integer);
var
F: TJvID3Frame;
I: Integer;
begin
try
FFSDesigner.BeginDesign;
try
with FrameListBox do
begin
F := TJvID3Frame(Items.Objects[ItemAtPos(Point(X, Y), True)]);
for I := 0 to Items.Count - 1 do
if Selected[I] then
TJvID3Frame(Items.Objects[I]).Index := F.Index;
end;
finally
FFSDesigner.EndDesign;
end;
finally
UpdateDisplay;
Designer.Modified;
end;
end;
procedure TJvID3FramesEditor.ListBoxDragOver(Sender, Source: TObject;
X, Y: Integer; State: TDragState; var Accept: Boolean);
var
Item: Integer;
procedure DrawRect(Item: Integer);
begin
if Item <> -1 then
with FrameListBox do
Canvas.DrawFocusRect(ItemRect(Item));
FFocusRectItem := Item;
end;
begin
Item := FrameListBox.ItemAtPos(Point(X, Y), False);
Accept := (Source = FrameListBox) and
(Item >= 0) and (Item < FrameListBox.Items.Count) and
not FrameListBox.Selected[Item];
if State = dsDragEnter then
FFocusRectItem := -1;
if (State = dsDragLeave) or not Accept then
Item := -1;
DrawRect(FFocusRectItem);
DrawRect(Item);
end;
procedure TJvID3FramesEditor.FormDestroy(Sender: TObject);
begin
if FFSDesigner <> nil then
begin
{ Destroy the designer if the editor is destroyed }
FFSDesigner.FFramesEditor := nil;
FFSDesigner.Free;
FFSDesigner := nil;
end;
end;
procedure TJvID3FramesEditor.NewFrameClick(Sender: TObject);
var
Selection: TStringList;
Frame: TJvID3Frame;
begin
Frame := DoNewFrame;
if Frame <> nil then
begin
Selection := TStringList.Create;
try
Selection.Add(Frame.Name);
finally
RestoreSelection(Selection, -1, -1, False);
end;
end;
FrameListBox.SetFocus;
end;
procedure TJvID3FramesEditor.DeleteClick(Sender: TObject);
begin
RemoveFrames;
end;
procedure TJvID3FramesEditor.SelectAllClick(Sender: TObject);
begin
SelectAll;
UpdateSelection;
end;
//=== { TJvID3FileInfoEditor } ===============================================
procedure TJvID3FileInfoEditor.Edit;
var
P: TPersistent;
begin
P := TPersistent(GetComponent(0));
if P is TJvID3Controller then
ShowFileInfo(TJvID3Controller(P));
end;
function TJvID3FileInfoEditor.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog];
end;
end.