You've already forked lazarus-ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6991 8e941d3f-bd1b-0410-a28a-d453659cc2b4
724 lines
21 KiB
ObjectPascal
724 lines
21 KiB
ObjectPascal
{******************************************************************
|
|
|
|
JEDI-VCL Demo
|
|
|
|
Copyright (C) 2002 Project JEDI
|
|
|
|
Original author:
|
|
|
|
Contributor(s):
|
|
|
|
You may retrieve the latest version of this file at the JEDI-JVCL
|
|
home page, located at http://jvcl.delphi-jedi.org
|
|
|
|
The contents of this file are used with permission, 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_1Final.html
|
|
|
|
Software distributed under the License is distributed on an
|
|
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
implied. See the License for the specific language governing
|
|
rights and limitations under the License.
|
|
|
|
******************************************************************}
|
|
|
|
unit JvId3v2EditFormU;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
//Windows,
|
|
SysUtils, Classes, Graphics, Controls, Forms,
|
|
Dialogs, ComCtrls, ActnList, StdCtrls, ExtCtrls,
|
|
JvID3v2Base, JvId3v2; //, JvComponent, ImgList, ToolWin; //, JvComponentBase;
|
|
|
|
type
|
|
|
|
{ TJvID3v2EditForm }
|
|
|
|
TJvID3v2EditForm = class(TForm)
|
|
Notebook1: TNotebook;
|
|
PgWinAmpTags: TPage;
|
|
PgLyrics: TPage;
|
|
PgPicture: TPage;
|
|
PgAllFrames: TPage;
|
|
lsbNavigator: TListBox;
|
|
ToolBar1: TToolBar;
|
|
lblTitle: TLabel;
|
|
lblArtist: TLabel;
|
|
lblAlbum: TLabel;
|
|
lblYear: TLabel;
|
|
lblComposer: TLabel;
|
|
lblOrigArtist: TLabel;
|
|
lblCopyright: TLabel;
|
|
lblURL: TLabel;
|
|
lblEncodedBy: TLabel;
|
|
edtTitle: TEdit;
|
|
edtArtist: TEdit;
|
|
edtAlbum: TEdit;
|
|
edtYear: TEdit;
|
|
edtComposer: TEdit;
|
|
edtOrigArtist: TEdit;
|
|
edtCopyright: TEdit;
|
|
edtURL: TEdit;
|
|
edtEncodedBy: TEdit;
|
|
cmbGenre: TComboBox;
|
|
lblGenre: TLabel;
|
|
memComment: TMemo;
|
|
lblComment: TLabel;
|
|
acl16: TActionList;
|
|
iml16: TImageList;
|
|
actOK: TAction;
|
|
actCancel: TAction;
|
|
actRemove: TAction;
|
|
ToolButton1: TToolButton;
|
|
ToolButton2: TToolButton;
|
|
ToolButton3: TToolButton;
|
|
JvID3v21: TJvID3v2;
|
|
lblLanguage: TLabel;
|
|
cmbLanguage: TComboBox;
|
|
memLyrics: TMemo;
|
|
lblDescription: TLabel;
|
|
lblWriter: TLabel;
|
|
edtDescription: TEdit;
|
|
edtWriter: TEdit;
|
|
lsvPictures: TListView;
|
|
imgPicture: TImage;
|
|
actAddPicture: TAction;
|
|
actDeletePicture: TAction;
|
|
actSavePicture: TAction;
|
|
lblPictureName: TLabel;
|
|
lblPictureType: TLabel;
|
|
edtPictureName: TEdit;
|
|
cmbPictureType: TComboBox;
|
|
lsvAllFrames: TListView;
|
|
btnChange: TButton;
|
|
actChangePicture: TAction;
|
|
btnAdd: TButton;
|
|
btnDelete: TButton;
|
|
btnSave: TButton;
|
|
ToolButton4: TToolButton;
|
|
ToolButton5: TToolButton;
|
|
actCopyTov1: TAction;
|
|
actCopyFromv1: TAction;
|
|
procedure actAddPictureExecute(Sender: TObject);
|
|
procedure actCancelExecute(Sender: TObject);
|
|
procedure actChangePictureExecute(Sender: TObject);
|
|
procedure actCopyFromv1Execute(Sender: TObject);
|
|
procedure actCopyTov1Execute(Sender: TObject);
|
|
procedure actDeletePictureExecute(Sender: TObject);
|
|
procedure actOKExecute(Sender: TObject);
|
|
procedure actRemoveExecute(Sender: TObject);
|
|
procedure actSavePictureExecute(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormShow(Sender: TObject);
|
|
procedure ItemSelected(Sender: TObject);
|
|
procedure lsbNavigatorClick(Sender: TObject);
|
|
procedure lsvAllFramesInfoTip(Sender: TObject; Item: TListItem; var InfoTip: String);
|
|
procedure lsvPicturesClick(Sender: TObject);
|
|
private
|
|
FTagDeleted: Boolean;
|
|
protected
|
|
procedure Init;
|
|
procedure Final;
|
|
|
|
procedure InitAllFramesTab;
|
|
|
|
procedure TagToCtrls;
|
|
procedure CtrlsToTag;
|
|
procedure FillPictureTypes(Strings: TStrings);
|
|
|
|
class function Instance: TJvID3v2EditForm;
|
|
public
|
|
class function Execute(const AFileName: string): Boolean;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
ExtDlgs,
|
|
JvID3v2Types;
|
|
|
|
{$R *.lfm}
|
|
|
|
var
|
|
CFrameDescriptions: array[TJvID3FrameID] of string = (
|
|
'Error', {fiErrorFrame}
|
|
'Padding', {fiPaddingFrame}
|
|
'No known frame', {fiNoFrame}
|
|
'Audio encryption', {fiAudioCrypto}
|
|
'Attached picture', {fiPicture}
|
|
'Audio seek point index', {fiAudioSeekPoint}
|
|
'Comments', {fiComment}
|
|
'Commercial frame', {fiCommercial}
|
|
'Encryption method registration', {fiCryptoReg}
|
|
'Equalisation (2)', {fiEqualization2}
|
|
'Equalization', {fiEqualization}
|
|
'Event timing codes', {fiEventTiming}
|
|
'General encapsulated object', {fiGeneralObject}
|
|
'Group identification registration', {fiGroupingReg}
|
|
'Involved people list', {fiInvolvedPeople}
|
|
'Linked information', {fiLinkedInfo}
|
|
'Music CD identifier', {fiCDID}
|
|
'MPEG location lookup table', {fiMPEGLookup}
|
|
'Ownership frame', {fiOwnership}
|
|
'Private frame', {fiPrivate}
|
|
'Play counter', {fiPlayCounter}
|
|
'Popularimeter', {fiPopularimeter}
|
|
'Position synchronisation frame', {fiPositionsync}
|
|
'Recommended buffer size', {fiBufferSize}
|
|
'Relative volume adjustment (2)', {fiVolumeAdj2}
|
|
'Relative volume adjustment', {fiVolumeAdj}
|
|
'Reverb', {fiReverb}
|
|
'Seek frame', {fiSeekFrame}
|
|
'Signature frame', {fiSignature}
|
|
'Synchronized lyric/text', {fiSyncedLyrics}
|
|
'Synchronized tempo codes', {fiSyncedTempo}
|
|
'Album/Movie/Show title', {fiAlbum}
|
|
'BPM (beats per minute)', {fiBPM}
|
|
'Composer', {fiComposer}
|
|
'Content type', {fiContentType}
|
|
'Copyright message', {fiCopyright}
|
|
'Date', {fiDate}
|
|
'Encoding time', {fiEncodingTime}
|
|
'Playlist delay', {fiPlaylistDelay}
|
|
'Original release time', {fiOrigReleaseTime}
|
|
'Recording time', {fiRecordingTime}
|
|
'Release time', {fiReleaseTime}
|
|
'Tagging time', {fiTaggingTime}
|
|
'Involved people list', {fiInvolvedPeople2}
|
|
'Encoded by', {fiEncodedBy}
|
|
'Lyricist/Text writer', {fiLyricist}
|
|
'File type', {fiFileType}
|
|
'Time', {fiTime}
|
|
'Content group description', {fiContentGroup}
|
|
'Title/songname/content description', {fiTitle}
|
|
'Subtitle/Description refinement', {fiSubTitle}
|
|
'Initial key', {fiInitialKey}
|
|
'Language(s)', {fiLanguage}
|
|
'Length', {fiSongLen}
|
|
'Musician credits list', {fiMusicianCreditList}
|
|
'Media type', {fiMediaType}
|
|
'Mood', {fiMood}
|
|
'Original album/movie/show title', {fiOrigAlbum}
|
|
'Original filename', {fiOrigFileName}
|
|
'Original lyricist(s)/text writer(s)', {fiOrigLyricist}
|
|
'Original artist(s)/performer(s)', {fiOrigArtist}
|
|
'Original release year', {fiOrigYear}
|
|
'File owner/licensee', {fiFileOwner}
|
|
'Lead performer(s)/Soloist(s)', {fiLeadArtist}
|
|
'Band/orchestra/accompaniment', {fiBand}
|
|
'Conductor/performer refinement', {fiConductor}
|
|
'Interpreted, remixed, or otherwise modified by', {fiMixArtist}
|
|
'Part of a set', {fiPartInSet}
|
|
'Produced notice', {fiProducedNotice}
|
|
'Publisher', {fiPublisher}
|
|
'Track number/Position in set', {fiTrackNum}
|
|
'Recording dates', {fiRecordingDates}
|
|
'Internet radio station name', {fiNetRadioStation}
|
|
'Internet radio station owner', {fiNetRadioOwner}
|
|
'Size', {fiSize}
|
|
'Album sort order', {fiAlbumSortOrder}
|
|
'Performer sort order', {fiPerformerSortOrder}
|
|
'Title sort order', {fiTitleSortOrder}
|
|
'ISRC (international standard recording code)', {fiISRC}
|
|
'Software/Hardware and settings used for encoding', {fiEncoderSettings}
|
|
'Set subtitle', {fiSetSubTitle}
|
|
'User defined text information', {fiUserText}
|
|
'Year', {fiYear}
|
|
'Unique file identifier', {fiUniqueFileID}
|
|
'Terms of use', {fiTermsOfUse}
|
|
'Unsynchronized lyric/text transcription', {fiUnsyncedLyrics}
|
|
'Commercial information', {fiWWWCommercialInfo}
|
|
'Copyright/Legal information', {fiWWWCopyright}
|
|
'Official audio file webpage', {fiWWWAudioFile}
|
|
'Official artist/performer webpage', {fiWWWArtist}
|
|
'Official audio source webpage', {fiWWWAudioSource}
|
|
'Official internet radio station homepage', {fiWWWRadioPage}
|
|
'Payment', {fiWWWPayment}
|
|
'Official publisher webpage', {fiWWWPublisher}
|
|
'User defined URL link', {fiWWWUser}
|
|
'Encrypted meta frame', {fiMetaCrypto}
|
|
'Compressed meta frame' {fiMetaCompression}
|
|
);
|
|
|
|
CPictureTypeStr: array[TJvID3PictureType] of string = (
|
|
'Other',
|
|
'32x32 pixels ''file icon'' (PNG only)',
|
|
'Other file icon',
|
|
'Cover (front)',
|
|
'Cover (back)',
|
|
'Leaflet page',
|
|
'Media (e.g. lable side of CD)',
|
|
'Lead artist/lead performer/soloist',
|
|
'Artist/performer',
|
|
'Conductor',
|
|
'Band/Orchestra',
|
|
'Composer',
|
|
'Lyricist/text writer',
|
|
'Recording Location',
|
|
'During recording',
|
|
'During performance',
|
|
'Movie/video screen capture',
|
|
'A bright coloured fish',
|
|
'Illustration',
|
|
'Band/artist logotype',
|
|
'Publisher/Studio logotype'
|
|
);
|
|
|
|
procedure SetPictureListItemTo(ListItem: TListItem; Frame: TJvID3PictureFrame);
|
|
begin
|
|
ListItem.Caption := Frame.Description;
|
|
while ListItem.SubItems.Count < 3 do
|
|
ListItem.SubItems.Add('');
|
|
ListItem.SubItems[0] := CPictureTypeStr[Frame.PictureType]; //Type
|
|
ListItem.SubItems[1] := Frame.MIMEType; //Format
|
|
ListItem.SubItems[2] := IntToStr(Frame.DataSize); //Size
|
|
ListItem.Data := Frame;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.FormCreate(Sender: TObject);
|
|
begin
|
|
FillPictureTypes(cmbPictureType.Items);
|
|
ISO_639_2Names(cmbLanguage.Items);
|
|
ID3_Genres(cmbGenre.Items);
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actOKExecute(Sender: TObject);
|
|
var
|
|
HasTag: Boolean;
|
|
Version: TJvID3Version;
|
|
lCursor: TCursor;
|
|
begin
|
|
lCursor := Screen.Cursor;
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
CtrlsToTag;
|
|
JvID3v21.Frames.RemoveEmptyFrames;
|
|
|
|
HasTag := True;
|
|
if JvID3v21.FrameCount = 0 then
|
|
GetID3v2Version(JvID3v21.FileName, HasTag, Version);
|
|
if HasTag then
|
|
JvID3v21.Commit;
|
|
|
|
ModalResult := mrOk;
|
|
finally
|
|
Screen.Cursor := lCursor;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actCancelExecute(Sender: TObject);
|
|
begin
|
|
ModalResult := mrCancel;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actRemoveExecute(Sender: TObject);
|
|
var
|
|
lCursor: TCursor;
|
|
begin
|
|
if MessageDlg('Remove tag?', mtConfirmation, mbOKCancel, 0) <> mrOk then
|
|
Exit;
|
|
|
|
lCursor := Screen.Cursor;
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
JvID3v21.Erase;
|
|
FTagDeleted := True;
|
|
TagToCtrls;
|
|
finally
|
|
Screen.Cursor := lCursor;
|
|
end;
|
|
end;
|
|
|
|
class function TJvID3v2EditForm.Execute(const AFileName: string): Boolean;
|
|
begin
|
|
with TJvID3v2EditForm.Instance do
|
|
try
|
|
JvID3v21.FileName := AFileName;
|
|
Init;
|
|
try
|
|
Result := (ShowModal = mrOk) or FTagDeleted;
|
|
finally
|
|
Final;
|
|
end;
|
|
finally
|
|
Hide;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.Init;
|
|
begin
|
|
Caption := Format('Edit ''%s''', [ExtractFileName(JvID3v21.FileName)]);
|
|
JvID3v21.Open;
|
|
TagToCtrls;
|
|
imgPicture.Picture.Assign(nil);
|
|
lsbNavigator.ItemIndex := 0;
|
|
end;
|
|
|
|
function ChangeYear(const ADateTime: TDateTime; const NewYear: Word): TDateTime;
|
|
var
|
|
OldYear, Month, Day: Word;
|
|
begin
|
|
DecodeDate(ADateTime, OldYear, Month, Day);
|
|
if NewYear <= 0 then
|
|
Result := 0
|
|
else
|
|
Result := EncodeDate(NewYear, Month, Day);
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.CtrlsToTag;
|
|
|
|
//procedure SetFirstOfList(Strings: {$IFDEF COMPILER12_UP}TStrings{$ELSE}TWideStrings{$ENDIF COMPILER12_UP}; const S: string);
|
|
procedure SetFirstOfList(Strings: TStrings; const S: String);
|
|
begin
|
|
if Strings.Count > 0 then
|
|
Strings[0] := S
|
|
else
|
|
Strings.Add(S);
|
|
end;
|
|
|
|
begin
|
|
{ WinAmp tags }
|
|
|
|
{ WinAmp treats some tags as single line tags; mimic this behaviour by
|
|
using function SetFirstOfList }
|
|
JvID3v21.Texts.Title := edtTitle.Text;
|
|
SetFirstOfList(JvID3v21.Texts.LeadArtist, edtArtist.Text);
|
|
JvID3v21.Texts.Album := edtAlbum.Text;
|
|
{ The 'year' tag is replaced by the 'recordingtime' tag in v2.4 }
|
|
if JvID3v21.WriteVersion = ive2_4 then
|
|
JvID3v21.Texts.RecordingTime := ChangeYear(JvID3v21.Texts.RecordingTime, StrToIntDef(edtYear.Text, 0))
|
|
else
|
|
JvID3v21.Texts.Year := StrToIntDef(edtYear.Text, 0);
|
|
SetFirstOfList(JvID3v21.Texts.ContentType, NiceGenreToGenre(cmbGenre.Text));
|
|
{ Note that WinAmp doesn't care about other properties than Text of TJvID3ContentFrame }
|
|
TJvID3ContentFrame.FindOrCreate(JvID3v21, fiComment).Text := memComment.Lines.Text;
|
|
SetFirstOfList(JvID3v21.Texts.Composer, edtComposer.Text);
|
|
SetFirstOfList(JvID3v21.Texts.OrigArtist, edtOrigArtist.Text);
|
|
JvID3v21.Texts.Copyright := edtCopyright.Text;
|
|
{ Note that WinAmp doesn't care about other properties than URL of TJvID3URLUserFrame }
|
|
TJvID3URLUserFrame.FindOrCreate(JvID3v21, 0).URL := AnsiString(edtURL.Text);
|
|
JvID3v21.Texts.EncodedBy := edtEncodedBy.Text;
|
|
|
|
{ Lyrics }
|
|
with TJvID3ContentFrame.FindOrCreate(JvID3v21, fiUnsyncedLyrics) do
|
|
begin
|
|
Language := ISO_639_2NameToCode(cmbLanguage.Text);
|
|
Text := memLyrics.Lines.Text;
|
|
Description := edtDescription.Text;
|
|
end;
|
|
SetFirstOfList(JvID3v21.Texts.Lyricist, edtWriter.Text);
|
|
end;
|
|
|
|
function YearOf(const ADateTime: TDateTime): Word;
|
|
var
|
|
D1, D2: Word;
|
|
begin
|
|
DecodeDate(ADateTime, Result, D1, D2);
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.TagToCtrls;
|
|
|
|
//function GetFirstOfList(Strings: {$IFDEF COMPILER12_UP}TStrings{$ELSE}TWideStrings{$ENDIF COMPILER12_UP}): string;
|
|
function GetFirstOfList(Strings: TStrings): String;
|
|
begin
|
|
if Strings.Count > 0 then
|
|
Result := Strings[0]
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
var
|
|
Frame: TJvID3Frame;
|
|
begin
|
|
{ Determine which frames are in the tag before calls to JvID3v21.Texts.xxx and
|
|
FindOrCreate because those functions might create frames. }
|
|
InitAllFramesTab;
|
|
|
|
{ WinAmp tags }
|
|
|
|
{ WinAmp treats some tags as single line tags; mimic this behaviour by
|
|
using function GetFirstOfList }
|
|
edtTitle.Text := JvID3v21.Texts.Title;
|
|
edtArtist.Text := GetFirstOfList(JvID3v21.Texts.LeadArtist);
|
|
edtAlbum.Text := JvID3v21.Texts.Album;
|
|
{ The 'year' tag is replaced by the 'recordingtime' tag in v2.4 }
|
|
if JvID3v21.Version = ive2_4 then
|
|
edtYear.Text := IntToStr(YearOf(JvID3v21.Texts.RecordingTime))
|
|
else
|
|
edtYear.Text := IntToStr(JvID3v21.Texts.Year);
|
|
cmbGenre.Text := GenreToNiceGenre(GetFirstOfList(JvID3v21.Texts.ContentType));
|
|
{ Note that WinAmp doesn't care about other properties than Text of TJvID3ContentFrame }
|
|
memComment.Lines.Text := TJvID3ContentFrame.FindOrCreate(JvID3v21, fiComment).Text;
|
|
edtComposer.Text := GetFirstOfList(JvID3v21.Texts.Composer);
|
|
edtOrigArtist.Text := GetFirstOfList(JvID3v21.Texts.OrigArtist);
|
|
edtCopyright.Text := JvID3v21.Texts.Copyright;
|
|
{ Note that WinAmp doesn't care about other properties than URL of TJvID3URLUserFrame }
|
|
edtURL.Text := string(TJvID3URLUserFrame.FindOrCreate(JvID3v21, 0).URL);
|
|
edtEncodedBy.Text := JvID3v21.Texts.EncodedBy;
|
|
|
|
{ Lyrics }
|
|
with TJvID3ContentFrame.FindOrCreate(JvID3v21, fiUnsyncedLyrics) do
|
|
begin
|
|
cmbLanguage.ItemIndex := cmbLanguage.Items.IndexOf(string(ISO_639_2CodeToName(Language)));
|
|
memLyrics.Lines.Text := Text;
|
|
edtDescription.Text := Description;
|
|
end;
|
|
edtWriter.Text := GetFirstOfList(JvID3v21.Texts.Lyricist);
|
|
|
|
{ Pictures }
|
|
lsvPictures.Items.BeginUpdate;
|
|
try
|
|
lsvPictures.Items.Clear;
|
|
if JvID3v21.FindFirstFrame(fiPicture, Frame) then
|
|
repeat
|
|
if Frame is TJvID3PictureFrame then
|
|
SetPictureListItemTo(lsvPictures.Items.Add, TJvID3PictureFrame(Frame));
|
|
until not JvID3v21.FindNextFrame(fiPicture, Frame);
|
|
finally
|
|
lsvPictures.Items.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actAddPictureExecute(Sender: TObject);
|
|
var
|
|
Frame: TJvID3PictureFrame;
|
|
begin
|
|
if cmbPictureType.ItemIndex < 0 then
|
|
begin
|
|
MessageDlg('Select a picture type', mtError, [mbOK], 0);
|
|
FocusControl(cmbPictureType);
|
|
Exit;
|
|
end;
|
|
|
|
with TOpenPictureDialog.Create(Application) do
|
|
try
|
|
if not Execute then
|
|
Exit;
|
|
|
|
Frame := TJvID3PictureFrame(JvID3v21.AddFrame(fiPicture));
|
|
with Frame do
|
|
begin
|
|
with cmbPictureType do
|
|
PictureType := TJvID3PictureType(PtrInt(Items.Objects[ItemIndex]));
|
|
Description := edtPictureName.Text;
|
|
MIMEType := AnsiString(ExtToMIMEType(ExtractFileExt(FileName)));
|
|
LoadFromFile(FileName);
|
|
|
|
lsvPictures.Items.BeginUpdate;
|
|
try
|
|
SetPictureListItemTo(lsvPictures.Items.Add, Frame);
|
|
finally
|
|
lsvPictures.Items.EndUpdate;
|
|
end;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actDeletePictureExecute(Sender: TObject);
|
|
begin
|
|
if not Assigned(lsvPictures.Selected) then
|
|
Exit;
|
|
|
|
JvID3v21.Frames.Remove(TJvID3Frame(lsvPictures.Selected.Data));
|
|
lsvPictures.Items.Delete(lsvPictures.Selected.Index);
|
|
imgPicture.Picture.Assign(nil);
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actSavePictureExecute(Sender: TObject);
|
|
var
|
|
Frame: TJvID3PictureFrame;
|
|
begin
|
|
if not Assigned(lsvPictures.Selected) then
|
|
Exit;
|
|
|
|
Frame := TJvID3PictureFrame(lsvPictures.Selected.Data);
|
|
|
|
if Assigned(Frame) and (Frame.DataSize > 0) and (Frame.MIMEType <> '-->') then
|
|
with TSavePictureDialog.Create(Application) do
|
|
try
|
|
if Execute then
|
|
Frame.SaveToFile(FileName);
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.FormShow(Sender: TObject);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
P := Point(0, EdtEncodedBy.Top + EdtEncodedby.Height + EdtEncodedBy.BorderSpacing.Bottom);
|
|
P := ScreenToClient(EdtEncodedBy.Parent.ClientToScreen(P));
|
|
Height := P.Y;
|
|
Notebook1.PageIndex := lsbNavigator.ItemIndex;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.lsvPicturesClick(Sender: TObject);
|
|
var
|
|
Frame: TJvID3PictureFrame;
|
|
begin
|
|
if Assigned(lsvPictures.Selected) then
|
|
Frame := TJvID3PictureFrame(lsvPictures.Selected.Data)
|
|
else
|
|
Frame := nil;
|
|
|
|
if Assigned(Frame) then
|
|
begin
|
|
edtPictureName.Text := Frame.Description;
|
|
with cmbPictureType do
|
|
ItemIndex := Items.IndexOfObject(TObject(PtrInt(Frame.PictureType)));
|
|
end;
|
|
|
|
imgPicture.Picture.Assign(Frame);
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.lsbNavigatorClick(Sender: TObject);
|
|
begin
|
|
Notebook1.PageIndex := lsbNavigator.ItemIndex;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.FillPictureTypes(Strings: TStrings);
|
|
var
|
|
PictureType: TJvID3PictureType;
|
|
begin
|
|
Strings.BeginUpdate;
|
|
try
|
|
Strings.Clear;
|
|
for PictureType := Low(TJvID3PictureType) to High(TJvID3PictureType) do
|
|
Strings.AddObject(CPictureTypeStr[PictureType], TObject(PtrInt(PictureType)));
|
|
finally
|
|
Strings.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.InitAllFramesTab;
|
|
var
|
|
I: Integer;
|
|
ListItem: TListItem;
|
|
begin
|
|
lsvAllFrames.Items.BeginUpdate;
|
|
try
|
|
lsvAllFrames.Items.Clear;
|
|
for I := 0 to JvID3v21.FrameCount - 1 do
|
|
with JvID3v21.Frames[I] do
|
|
begin
|
|
ListItem := lsvAllFrames.Items.Add;
|
|
ListItem.Caption := string(FrameName);
|
|
if ClassType <> TJvID3SkipFrame then
|
|
ListItem.SubItems.Add('Yes')
|
|
else
|
|
ListItem.SubItems.Add('No');
|
|
ListItem.SubItems.Add(CFrameDescriptions[FrameID]);
|
|
ListItem.Data := JvID3v21.Frames[I];
|
|
end;
|
|
finally
|
|
lsvAllFrames.Items.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actChangePictureExecute(Sender: TObject);
|
|
var
|
|
Frame: TJvID3PictureFrame;
|
|
begin
|
|
if not Assigned(lsvPictures.Selected) then
|
|
Exit;
|
|
|
|
if cmbPictureType.ItemIndex < 0 then
|
|
begin
|
|
MessageDlg('Select a picture type', mtError, [mbOK], 0);
|
|
FocusControl(cmbPictureType);
|
|
Exit;
|
|
end;
|
|
|
|
Frame := TJvID3PictureFrame(lsvPictures.Selected.Data);
|
|
|
|
with Frame do
|
|
begin
|
|
with cmbPictureType do
|
|
PictureType := TJvID3PictureType(PtrInt(Items.Objects[ItemIndex]));
|
|
Description := edtPictureName.Text;
|
|
|
|
lsvPictures.Items.BeginUpdate;
|
|
try
|
|
SetPictureListItemTo(lsvPictures.Selected, Frame);
|
|
finally
|
|
lsvPictures.Items.EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.ItemSelected(Sender: TObject);
|
|
begin
|
|
if Sender is TAction then
|
|
TAction(Sender).Enabled := Assigned(lsvPictures.Selected);
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actCopyTov1Execute(Sender: TObject);
|
|
begin
|
|
if not JvID3v21.CopyToID3v1 then
|
|
ShowMessage('Error');
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.actCopyFromv1Execute(Sender: TObject);
|
|
begin
|
|
if JvID3v21.CopyFromID3v1 then
|
|
TagToCtrls
|
|
else
|
|
ShowMessage('Error');
|
|
end;
|
|
|
|
var
|
|
GInstance: TJvID3v2EditForm = nil;
|
|
|
|
class function TJvID3v2EditForm.Instance: TJvID3v2EditForm;
|
|
begin
|
|
if not Assigned(GInstance) then
|
|
GInstance := TJvID3v2EditForm.Create(Application);
|
|
|
|
Result := GInstance;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.Final;
|
|
begin
|
|
JvID3v21.Close;
|
|
end;
|
|
|
|
procedure TJvID3v2EditForm.lsvAllFramesInfoTip(Sender: TObject;
|
|
Item: TListItem; var InfoTip: String);
|
|
var
|
|
Frame: TJvID3Frame;
|
|
S: string;
|
|
begin
|
|
Frame := TJvID3Frame(Item.Data);
|
|
if Frame is TJvID3TextFrame then
|
|
InfoTip := TJvID3TextFrame(Frame).Text
|
|
else if Frame is TJvID3NumberFrame then
|
|
InfoTip := IntToStr(TJvID3NumberFrame(Frame).Value)
|
|
else if Frame is TJvID3UserFrame then
|
|
with Frame as TJvID3UserFrame do
|
|
InfoTip := Format('%s: %s', [Description, Value])
|
|
else if Frame is TJvID3PictureFrame then
|
|
with Frame as TJvID3PictureFrame do
|
|
InfoTIp := Format('%s (%s) %d bytes', [Description, MIMEType, DataSize])
|
|
else if Frame is TJvID3TimestampFrame then
|
|
InfoTip := DateTimeToStr(TJvID3TimestampFrame(Frame).Value)
|
|
else if Frame is TJvID3ContentFrame then
|
|
InfoTip := TJvID3ContentFrame(Frame).Text
|
|
else if Frame is TJvID3SimpleListFrame then
|
|
begin
|
|
S := TJvID3SimpleListFrame(Frame).List.GetText;
|
|
Delete(S, Length(S) - 1, 2);
|
|
InfoTip := S;
|
|
end;
|
|
end;
|
|
|
|
end.
|