Files
lazarus-ccr/applications/cactusjukebox/source/mainform.pas
yangjixian e801f62380 M source/mainform.lfm
M    source/mainform.pas


git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1869 8e941d3f-bd1b-0410-a28a-d453659cc2b4
2011-08-30 01:42:36 +00:00

4865 lines
140 KiB
ObjectPascal

{
Main unit for Cactus Jukebox
written by Sebastian Kraft, <c> 2006-2008
Contact the author at: sebastian_kraft@gmx.de
This Software is published under the GPL
}
//TODO: Check if position icon in playlist works after loading playlist from file
unit mainform;
//{$mode delphi}{$H+}
{$mode objfpc}{$H+}
{$ifdef CPU86}//compile with fmod support enabled by default on i386
{$define fmod}
{$endif}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
ExtCtrls, ComCtrls, StdCtrls, Menus,{$ifdef fmod} fmodplayer,{$endif}
ActnList, FileUtil, mediacol, dos, SimpleIPC, functions, EditBtn, last_fm, debug, config,
playlist, playerclass, MPlayer, mp3file, Messages, LMessages, cj_interfaces;
resourcestring
rsQuit = 'Quit';
rsFile = 'File';
rsOpenFile = 'Open File...';
rsOpenDirector = 'Open Directory...';
rsPlayerOnly = 'Player only';
rsChooseSkin = 'Choose Skin...';
rsSettings = 'Settings...';
rsLibrary = 'Library';
rsNewLibrary = 'New library';
rsLoadLibrary = 'Load library';
rsSaveLibrary = 'Save library';
rsLibraryInfo = 'Library info';
rsManageLibrar = 'Manage library...';
// unused ? rsRescanDirect = 'Rescan directories';
rsPlaylist = 'Playlist';
rsPlay = 'Play';
rsNext = 'Next';
rsPrevious = 'Previous';
rsMute = 'Mute';
rsLoadPlaylist = 'Load playlist';
rsSavePlaylist = 'Save playlist';
rsMobilePlayer = 'Mobile player';
rsClearPlaylist = 'Clear Playlist';
rsRandomPlaylist = 'Random Playlist';
rsDevices = 'Devices';
rsDeviceInfo = 'Device info';
rsScanPlayer = 'Scan player';
rsSync = 'Sync';
rsClearPlayer = 'Clear player';
rsUndoSelectio = 'Undo selection';
rsAudioCD = 'Audio CD';
rsRipEncode = 'Rip / Encode...';
rsHelp = 'Help';
rsAbout = 'About...';
rsManual = 'Manual...';
rsClear = 'Clear';
rsSearch = 'Search';
rsAlbum = 'Album';
rsFilename = 'Filename';
rsArtist = 'Artist';
rsTitle = 'Title';
rsRandom = 'Random';
rsNotConnected = 'Device not Connected';
rsOK = 'OK';
rsLenght = 'Length';
rsTrack = 'Track';
type
TCactusFlags = (cfTrayIconPressed, cfProgHide);
{ TMain }
TMain = class(TForm)
ApplicationProperties1: TApplicationProperties;
ArtistTree: TTreeView;
artistsearch: TEdit;
Button1: TButton;
Button2: TButton;
clear_list: TBitBtn;
CoverImage: TImage;
current_title_edit: TEdit;
current_title_edit1: TEdit;
FileItem: TMenuItem;
filetypebox: TComboBox;
ImageListNormal: TImageList;
ImageListHot: TImageList;
ImageListDis: TImageList;
itemPlugins: TMenuItem;
lblPath: TLabel;
Mainmenu1: TMainMenu;
MenuItem12: TMenuItem;
Menuitem21: TMenuItem;
Menuitem24: TMenuItem;
MenuItem25: TMenuItem;
itemTrayExit: TMenuItem;
itemTrayPlay: TMenuItem;
itemTrayStop: TMenuItem;
itemTrayNext: TMenuItem;
itemTrayPrev: TMenuItem;
MenuItem27: TMenuItem;
MenuItem34: TMenuItem;
MenuItem35: TMenuItem;
MIabout: TMenuItem;
MIClearPlayer: TMenuItem;
MIclear_playlist: TMenuItem;
MIDeviceInfo: TMenuItem;
MIDevices: TMenuItem;
MIhelp: TMenuItem;
MIlibinfo: TMenuItem;
MIlibrary: TMenuItem;
MIloadlib: TMenuItem;
MIload_list: TMenuItem;
MIManagLib: TMenuItem;
MImanual: TMenuItem;
MIMobilePlayer: TMenuItem;
MImute: TMenuItem;
MInewlib: TMenuItem;
MInext: TMenuItem;
MIplay: TMenuItem;
MIPlaylist: TMenuItem;
MIprevious: TMenuItem;
MIrandom_playlist: TMenuItem;
MIRipAudio: TMenuItem;
MIsavelib: TMenuItem;
MIsave_list: TMenuItem;
MIScanPlayer: TMenuItem;
MISyncPlayer: TMenuItem;
MIUndoPlayer: TMenuItem;
MIViewArtist: TMenuItem;
MIViewTitle: TMenuItem;
MIViewAlbum: TMenuItem;
MIViewTrack: TMenuItem;
MIViewGenre: TMenuItem;
MIViewFilename: TMenuItem;
mnuCleanLib: TMenuItem;
MTitleView: TMenuItem;
opendir: TMenuItem;
openfile: TMenuItem;
player_lib: TMenuItem;
PopupMenuTray: TPopupMenu;
MIremoveRadio: TMenuItem;
MenuItem28: TMenuItem;
MenuItem29: TMenuItem;
MenuItem32: TMenuItem;
mute: TSpeedButton;
NetworktreePopup: TPopupMenu;
NextButtonImg: TImage;
Panel2: TPanel;
Panel3: TPanel;
pnlPlaytime: TPanel;
PauseButtonImg: TImage;
PlayButtonImg: TImage;
PlayerControlsPanel: TPanel;
Playlist: TListView;
PreviousButtonImg: TImage;
QuitItem: TMenuItem;
randomcheck: TCheckBox;
RemoveItem: TMenuItem;
removselectItem: TMenuItem;
searchstr: TEdit;
SettingsItem: TMenuItem;
skinmenu: TMenuItem;
space3: TMenuItem;
space4: TMenuItem;
spacer15: TMenuItem;
spacer29: TMenuItem;
spacer41: TMenuItem;
Splitter2: TSplitter;
SrchFileItem: TMenuItem;
SrchArtItem: TMenuItem;
SrchTitleItem: TMenuItem;
SrchAlbumItem: TMenuItem;
SearchMenu: TPopupMenu;
SidebarImgList: TImageList;
MenuItem13: TMenuItem;
MenuItem15: TMenuItem;
MenuItem19: TMenuItem;
MenuItem22: TMenuItem;
MenuItem23: TMenuItem;
MenuItem7: TMenuItem;
MenuItem9: TMenuItem;
MenuItem6: TMenuItem;
srch_button: TButton;
StopButtonImg: TImage;
ToolBar1: TToolBar;
LibModeBtn: TToolButton;
NetModeBtn: TToolButton;
DeviceModeBtn: TToolButton;
Label2: TLabel;
MenuItem2: TMenuItem;
Panel4: TPanel;
ArtistSrchField: TPanel;
SimpleIPCServer1: TSimpleIPCServer;
SpeedButton1: TSpeedButton;
TitleTree: TListView;
MenuItem11: TMenuItem;
Panel1: TPanel;
Menuitem26: TMenuItem;
MenuItem3: TMenuItem;
Splitter1: TSplitter;
StatusBar1: TStatusBar;
toplaylistitem: TMenuItem;
ImageList1: TImageList;
MenuItem14: TMenuItem;
MenuItem16: TMenuItem;
MenuItem17: TMenuItem;
MenuItem18: TMenuItem;
MenuItem20: TMenuItem;
MenuItem30: TMenuItem;
rm_artist_playeritem: TMenuItem;
MenuItem37: TMenuItem;
MenuItem38: TMenuItem;
MenuItem10: TMenuItem;
MenuItem33: TMenuItem;
SaveDialog1: TSaveDialog;
checkmobile: TTimer;
space11: TMenuItem;
Menuitem27a: TMenuItem;
space1: TMenuItem;
artisttreemenu: TPopupMenu;
TEditID3item: TMenuItem;
Menuitem1: TMENUITEM;
Menuitem4: TMENUITEM;
Menuitem5: TMENUITEM;
Menuitem8: TMENUITEM;
playlistmenu: TPOPUPMENU;
titlelistmenu: TPOPUPMENU;
Selectdirectorydialog1: TSELECTDIRECTORYDIALOG;
playtimer: TTimer;
seldirdialog: TSelectDirectoryDialog;
trackbar: TTrackBar;
Trackinfo: TSpeedButton;
TrayIcon: TTrayIcon;
Volumebar: TProgressBar;
procedure ApplicationProperties1Minimize(Sender: TObject);
procedure ArtistTreeClick(Sender: TObject);
procedure ArtistTreeDblClick(Sender: TObject);
procedure ArtistTreeEndDrag(Sender, Target: TObject; X, Y: integer);
procedure ArtistTreeKeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
procedure ArtistTreeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure ArtistTreeSelectionChanged(Sender: TObject);
procedure ArtistTreeStartDrag(Sender: TObject; var DragObject: TDragObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure CoverImageMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure DeviceModeBtnClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure itemTrayExitClick(Sender: TObject);
procedure itemTrayPlayClick(Sender: TObject);
procedure LibModeBtnClick(Sender: TObject);
procedure MenuItem15Click(Sender: TObject);
procedure MenuItem25Click(Sender: TObject);
procedure MIrandom_playlistClick(Sender: TObject);
procedure MIViewAlbumClick(Sender: TObject);
procedure MIViewArtistClick(Sender: TObject);
procedure MenuItem32Click(Sender: TObject);
procedure MenuItem6Click(Sender: TObject);
procedure MenuItem7Click(Sender: TObject);
procedure MenuItem9Click(Sender: TObject);
procedure MIDeviceInfoClick(Sender: TObject);
procedure MIremoveRadioClick(Sender: TObject);
procedure MIRipAudioClick(Sender: TObject);
procedure MIViewFilenameClick(Sender: TObject);
procedure MIViewGenreClick(Sender: TObject);
procedure MIViewTitleClick(Sender: TObject);
procedure MIViewTrackClick(Sender: TObject);
procedure mnuCleanLibClick(Sender: TObject);
procedure NetModeBtnClick(Sender: TObject);
procedure NextButtonImgClick(Sender: TObject);
procedure NextButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure NextButtonImgMouseEnter(Sender: TObject);
procedure NextButtonImgMouseLeave(Sender: TObject);
procedure NextButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure PlaylistCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState;
var DefaultDraw: boolean);
procedure pnlPlaytimeClick(Sender: TObject);
procedure PopupMenuTrayPopup(Sender: TObject);
procedure randomcheckChange(Sender: TObject);
procedure SearchPanelClick(Sender: TObject);
procedure PlayerControlsPanelClick(Sender: TObject);
procedure PauseButtonImgClick(Sender: TObject);
procedure PauseButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure PauseButtonImgMouseEnter(Sender: TObject);
procedure PauseButtonImgMouseLeave(Sender: TObject);
procedure PauseButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure PlayButtonImgClick(Sender: TObject);
procedure PlayButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure PlayButtonImgMouseEnter(Sender: TObject);
procedure PlayButtonImgMouseLeave(Sender: TObject);
procedure PlayButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure MainClose(Sender: TObject; var CloseAction: TCloseAction);
procedure MainCreate(Sender: TObject);
procedure MenuItem11Click(Sender: TObject);
procedure MenuItem14Click(Sender: TObject);
procedure MenuItem16Click(Sender: TObject);
procedure MenuItem20Click(Sender: TObject);
procedure MenuItem26Click(Sender: TObject);
procedure MenuItem27Click(Sender: TObject);
procedure MenuItem2Click(Sender: TObject);
procedure MenuItem37Click(Sender: TObject);
procedure MenuItem43Click(Sender: TObject);
procedure Panel1Click(Sender: TObject);
procedure Panel1Resize(Sender: TObject);
procedure Panel4Click(Sender: TObject);
procedure ArtistSrchFieldClick(Sender: TObject);
procedure PreviousButtonImgClick(Sender: TObject);
procedure PreviousButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure PreviousButtonImgMouseEnter(Sender: TObject);
procedure PreviousButtonImgMouseLeave(Sender: TObject);
procedure PreviousButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure SettingsItemClick(Sender: TObject);
procedure SimpleIPCServer1Message(Sender: TObject);
procedure skinmenuClick(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure Splitter1Moved(Sender: TObject);
procedure SrchAlbumItemClick(Sender: TObject);
procedure SrchArtItemClick(Sender: TObject);
procedure SrchFileItemClick(Sender: TObject);
procedure SrchTitleItemClick(Sender: TObject);
procedure StopButtonImgClick(Sender: TObject);
procedure StopButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure StopButtonImgMouseEnter(Sender: TObject);
procedure StopButtonImgMouseLeave(Sender: TObject);
procedure StopButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure TestPlugin1(Sender: TObject);
procedure TitleTreeClick(Sender: TObject);
procedure TitleTreeColumnClick(Sender: TObject; Column: TListColumn);
procedure TitleTreeDragOver(Sender, Source: TObject; X, Y: integer;
State: TDragState; var Accept: boolean);
procedure TitleTreeEndDrag(Sender, Target: TObject; X, Y: integer);
procedure TitleTreeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure TitleTreeSelectItem(Sender: TObject; Item: TListItem;
Selected: boolean);
procedure TitleTreeStartDrag(Sender: TObject; var DragObject: TDragObject);
procedure TrackInfoClick(Sender: TObject);
procedure artisttreemenuPopup(Sender: TObject);
procedure checkmobileTimer(Sender: TObject);
procedure clearPlayerItemClick(Sender: TObject);
procedure clear_listClick(Sender: TObject);
procedure filetypeboxChange(Sender: TObject);
procedure libinfoClick(Sender: TObject);
procedure muteClick(Sender: TObject);
procedure opendirClick(Sender: TObject);
procedure openfileClick(Sender: TObject);
procedure pauseClick(Sender: TObject);
procedure player_libClick(Sender: TObject);
procedure playlistClick(Sender: TObject);
procedure playlistDblClick(Sender: TObject);
procedure playlistDragDrop(Sender, Source: TObject; X, Y: integer);
procedure playlistDragOver(Sender, Source: TObject; X, Y: integer;
State: TDragState; var Accept: boolean);
procedure playlistEndDrag(Sender, Target: TObject; X, Y: integer);
procedure playlistKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
procedure playlistKeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
procedure playlistMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure playlistSelectItem(Sender: TObject; Item: TListItem;
Selected: boolean);
procedure playlistStartDrag(Sender: TObject; var DragObject: TDragObject);
procedure playtimerStartTimer(Sender: TObject);
procedure prevClick(Sender: TObject);
procedure EditID3itemClick(Sender: TObject);
procedure MenuItem30Click(Sender: TObject);
procedure MenuItem33Click(Sender: TObject);
procedure rm_artist_playeritemClick(Sender: TObject);
procedure searchstrClick(Sender: TObject);
procedure syncplayeritem(Sender: TObject);
procedure MenuItem3Click(Sender: TObject);
procedure MenuItem22aClick(Sender: TObject);
procedure Menuitem10Click(Sender: TObject);
procedure RemoveClick(Sender: TObject);
procedure QuitItemClick(Sender: TObject);
procedure TitleTreeDblClick(Sender: TObject);
procedure loadlibClick(Sender: TObject);
procedure newlibClick(Sender: TObject);
procedure nextClick(Sender: TObject);
procedure playClick(Sender: TObject);
procedure playtimerTimer(Sender: TObject);
procedure removeselectClick(Sender: TObject);
procedure save_listClick(Sender: TObject);
procedure savelibClick(Sender: TObject);
procedure scanplayeritemClick(Sender: TObject);
procedure searchstrKeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
procedure srch_buttonClick(Sender: TObject);
procedure stopClick(Sender: TObject);
procedure titlelistmenuPopup(Sender: TObject);
procedure toggle_playpause(Sender: TObject);
procedure trackbarMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure trackbarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure TrayIconClick(Sender: TObject);
procedure undoSyncItemClick(Sender: TObject);
procedure loadskin(Sender: TObject);
procedure update_player_hdd_relations;
procedure VolumebarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
private
{ private declarations }
ctrl_pressed, SplitterResize: boolean;
oldSplitterWidth, LoopCount: integer;
sourceitem: TListItem;
CoverFound, title_drag, playlist_drag, artist_drag: boolean;
DeviceMode, NetworkMode, LibraryMode: boolean;
LastFMAPI: TLastfmAPIObject;
ScanSyncCount: integer;
FileOpneDialogPath: string;
bPnlPlaytimeNegated: boolean;
oldWindowState: TWindowState;
fromTrayDBLClick: boolean;
FFlags: set of TCactusFlags;
procedure MoveNode(TargetNode, SourceNode: TTreeNode);
procedure ApplicationIdle(Sender: TObject; var Done: boolean);
procedure update_player_display;
function LoadFile(path: string): boolean;
procedure MinimizeMe(Data: Ptrint);
public
player_connected, playermode: boolean;
playpos: integer;
playnode: TTreeNode;
playitem: TListitem;
curlib: string;
tempbitmap, timetmpbmp: TBitmap;
player_freespace, player_totalspace: longint;
skinmenuitems: array[1..16] of TMenuItem;
TestPluginI: TCJ_MenuItem;
procedure update_playlist;
procedure disconnectDAP;
function connectDAP: byte;
procedure ScanSyncronize(dir: string);
procedure update_artist_view;
{ public declarations }
//Test Plugins....cut in future
procedure SayHello(Sender: TCJ_MenuItem);
function SayMsgHello(var Message: TMessage): boolean;
function SayMsgHello2(var Message: TMessage): boolean;
end;
type
{ TScanThread }
TScanThread = class(TThread)
private
procedure ShowStatus;
protected
procedure Execute;
override;
public
fStatus: byte;
tmpcollection: TMediaCollectionClass;
PTargetCollection: TMediaCollectionClass;
constructor Create(Suspd: boolean);
end;
{ TScanThread }
type
{ TSyncThread }
TSyncAction = (SCopy, SDelete);
TSyncThread = class(TThread)
private
procedure SyncStatus;
protected
CopyList, TargetList, DeleteList: TStringList;
DeletedCnt, DeleteTotal, CopyTotal, CopiedCnt: integer;
OpSuccess, finished: boolean;
SAction: TSyncAction;
TargetCollection: TMediaCollectionClass;
procedure Execute;
override;
public
Target: string;
constructor Create(Suspd: boolean);
destructor Destroy;
override;
procedure CopyFile(fromFile, toFile: string);
procedure DeleteFile(path: string);
end;
{ TSyncThread }
var
Main: TMain;
SyncThread: TSyncThread;
ScanThread: TscanThread;
//procedure update_title_view_album;
procedure update_title_view;
procedure artist_to_playlist;
procedure artist_to_playlist_at(index: integer);
procedure title_to_playlist_at(index: integer);
procedure title_to_playlist;
implementation
uses editid3, status, settings, player, directories, skin, cdrip,
translations, bigcoverimg,
streamcol, addradio, CleanLibrary, global_vars, cj_pluginslist,
cj_interfaces_impl, LCLType;
{$R *.lfm}
{$i cactus_const.inc}
var
sizediff: int64;
{ TSyncThread }
procedure TSyncThread.SyncStatus;
begin
if finished = False then
begin
if SAction = SCopy then
Main.StatusBar1.Panels[1].Text :=
IntToStr(CopiedCnt) + ' of ' + IntToStr(
CopyTotal) +
' copied. Don''t Disconnect...';
if SAction = SDelete then
Main.StatusBar1.Panels[1].Text :=
IntToStr(DeletedCnt) + ' of ' + IntToStr
(DeleteTotal) +
' deleted. Don''t Disconnect...';
end
else
begin
writeln('finished');
TargetCollection.SaveToFile;
TargetCollection.Free;
main.connectDAP;
Main.StatusBar1.Panels[1].Text := 'Synchronizing finished. Device Ready...';
end;
end;
procedure TSyncThread.Execute;
begin
finished := False;
DeleteTotal := DeleteList.Count;
CopyTotal := CopyList.Count;
DeletedCnt := 0;
CopiedCnt := 0;
TargetCollection := TMediaCollectionClass.Create;
TargetCollection.PathFmt := FRelative;
TargetCollection.LoadFromFile(Target);
while DeleteList.Count > 0 do
begin
OpSuccess := False;
try
SysUtils.DeleteFile(self.DeleteList[0]);
if FileExists(self.DeleteList[0]) = False then
begin
TargetCollection.remove(TargetCollection.getIndexByPath(self.DeleteList[0]));
end;
if DirectoryIsEmpty(ExtractFileDir(DeleteList[0])) then
RemoveDir(ExtractFileDir(DeleteList[0]))
except
end;
Inc(DeletedCnt);
SAction := SDelete;
self.DeleteList.Delete(0);
Synchronize(@SyncStatus);
end;
DebugOutLn('copying files...', 6);
while CopyList.Count > 0 do
begin
OpSuccess := False;
OpSuccess := FileCopy(CopyList[0], TargetList[0]);
Inc(CopiedCnt);
SAction := SCopy;
TargetCollection.add(TargetList[0]);
CopyList.Delete(0);
TargetList.Delete(0);
Synchronize(@SyncStatus);
end;
Finished := True;
Synchronize(@SyncStatus);
end;
constructor TSyncThread.Create(Suspd: boolean);
begin
inherited Create(suspd);
FreeOnTerminate := True;
CopyList := TStringList.Create;
TargetList := TStringList.Create;
DeleteList := TStringList.Create;
DeletedCnt := 0;
CopiedCnt := 0;
end;
destructor TSyncThread.Destroy;
begin
inherited Destroy;
CopyList.Free;
TargetList.Free;
DeleteList.Free;
end;
procedure TSyncThread.CopyFile(fromFile, toFile: string);
begin
CopyList.Add(fromFile);
TargetList.Add(toFile);
end;
procedure TSyncThread.DeleteFile(path: string);
begin
DeleteList.Add(path);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{ TScanThread : Thread to scan for new media files in background }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TScanThread.ShowStatus;
begin
if fStatus = 1 then
Main.StatusBar1.Panels[0].Text := 'Scanning folders in background...';
if fStatus = 0 then
begin
main.Enabled := False;
if MessageDlg('Some files on your harddisk seem to have changed.' + LineEnding +
'Adopt changes in Cactus library?', mtWarning, mbOKCancel, 0) = mrOk then
begin
writeln(1);
fstatus := 255;
writeln('assigning');
// PTargetCollection^.Assign(tmpcollection);
writeln('saving');
// PTargetCollection^.save_lib(PTargetCollection^.savepath);
Main.clear_listClick(nil);
writeln('WARNING: if excption occurs, playlist has to be cleared here!');
// Main.update_player_hdd_relations;
main.update_artist_view;
update_title_view;
Main.StatusBar1.Panels[0].Text := ('Succesfully updated library...');
tmpcollection.Free;
end;
main.Enabled := True;
end;
if (fstatus = 0) or (fstatus = 128) then
begin
Main.StatusBar1.Panels[0].Text := 'Ready';
writeln('fstatus 0, 126');
Main.StatusBar1.Panels[1].Alignment := taRightJustify;
tmpcollection.Free;
end;
writeln('showStatus');
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TScanThread.Execute;
begin
fStatus := 1;
Synchronize(@ShowStatus);
// fstatus:=tmpcollection.ScanForNew;
Synchronize(@ShowStatus);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
constructor TScanThread.Create(Suspd: boolean);
begin
inherited Create(suspd);
FreeOnTerminate := True;
tmpcollection := TMediaCollectionClass.Create;
fStatus := 255;
end;
{ // End TScanThread }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{ TMain }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.loadskin(Sender: TObject);
begin
DebugOutLn('loading skin', 2);
with (Sender as TMenuitem) do
begin
SkinData.load_skin(Caption);
CactusConfig.CurrentSkin := Caption;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.update_player_hdd_relations;
var
i, z: integer;
begin
for i := 0 to PlayerCol.itemcount - 1 do
begin
z := 0;
PlayerCol.items[i].action := AONPLAYER;
while z < MediaCollection.ItemCount - 1 do
begin
if MediaCollection.items[z].id = PlayerCol.items[i].id then
begin
MediaCollection.items[z].action := 1;
z := MediaCollection.ItemCount - 1;
end;
Inc(z);
end;
end;
Playercol.SaveToFile(CactusConfig.DAPPath + 'cactuslib');
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.VolumebarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
var
newVolume: byte;
begin
if y > Volumebar.Height then
y := Volumebar.Height;
if y < 0 then
y := 0;
writeln(y);
newVolume := 100 - ((y * 100) div (Volumebar.Height));
PlayerObj.set_volume(newVolume);
Volumebar.Position := newVolume;
DebugOutLn('volume set ' + IntToStr(PlayerObj.volume), 3);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.loadlibClick(Sender: TObject);
var
OpenDialog: TOpenDialog;
begin
OpenDialog := TOpenDialog.Create(self);
OpenDialog.Filter := 'Mp3lib Library|*.mlb';
OpenDialog.InitialDir := CactusConfig.HomeDir;
OpenDialog.FilterIndex := 1;
if Opendialog.Execute = True then
MediaCollection.LoadFromFile(Opendialog.Filename);
OpenDialog.Free;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.newlibClick(Sender: TObject);
begin
Enabled := False;
Selectdirectorydialog1.initialdir := CactusConfig.HomeDir;
Selectdirectorydialog1.title := 'Add Directory...';
if Selectdirectorydialog1.Execute = True then
begin
DebugOutLn('clear old collection', 7);
MediaCollection.Clear;
DebugOutLn('lll', 7);
update_artist_view;
update_title_view;
Application.ProcessMessages;
MediaCollection.add_directory(Selectdirectorydialog1.Filename);
DebugOutLn('finished scan of ' + Selectdirectorydialog1.Filename, 2);
if MediaCollection.ItemCount > 0 then
begin
ArtistTree.Selected := nil;
update_artist_view;
update_title_view;
end;
end;
Enabled := True;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.nextClick(Sender: TObject);
var
oldindex, err, i: integer;
begin
playtimer.Enabled := False;
oldindex := PlayerObj.CurrentTrack;
if randomcheck.Checked = False then
err := PlayerObj.next_track
else
err := PlayerObj.play(PlayerObj.Playlist.RandomIndex);
if err = 0 then
begin
i := PlayerObj.CurrentTrack;
if i >= 0 then
begin
if oldindex >= 0 then
playlist.Items[oldindex].ImageIndex := -1;
writeln(oldindex);
playlist.Items[i].ImageIndex := 0;
playlist.Items[i].MakeVisible(False);
playtimer.Enabled := True;
//CactusPlugins.SendEvent(evnStartPlay, PlayerObj.Playlist.Items[PlayerObj.CurrentTrack].artist+' - '+PlayerObj.Playlist.Items[PlayerObj.CurrentTrack].title);
end;
end
else
stopClick(nil);
update_player_display;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.prevClick(Sender: TObject);
var
err: byte;
i, OldTrack: integer;
begin
playtimer.Enabled := False;
OldTrack := PlayerObj.CurrentTrack;
err := PlayerObj.prev_track;
if (err = 0) then
begin
i := PlayerObj.CurrentTrack;
if playlist.Items.Count > 1 then
begin
if OldTrack >= 0 then
playlist.Items[OldTrack].ImageIndex := -1;
playlist.Items[i].ImageIndex := 0;
playlist.Items[i].MakeVisible(False);
//CactusPlugins.SendEvent(evnStartPlay, PlayerObj.Playlist.Items[PlayerObj.CurrentTrack].artist+' - '+PlayerObj.Playlist.Items[PlayerObj.CurrentTrack].title);
end;
playtimer.Enabled := True;
end
else
stopClick(nil);
update_player_display;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playClick(Sender: TObject);
var
err: integer;
begin
if (not PlayerObj.paused) then
begin
playtimer.Enabled := False;
if (Playlist.items.Count > 0) and (Playlist.Selected = nil) then
playitem := Playlist.Items[0]
else
playitem := playlist.selected;
if (PlayerObj.playing) and (PlayerObj.Playlist.Count > 0) and
(PlayerObj.CurrentTrack < PlayerObj.Playlist.Count) and (PlayerObj.CurrentTrack >= 0)
then
playlist.Items[PlayerObj.CurrentTrack].ImageIndex := -1;
;
if playitem <> nil then
begin
err := PlayerObj.play(playitem.Index);
if (err = 0) then
begin
Playlist.BeginUpdate;
playitem.ImageIndex := 0;
Playlist.EndUpdate;
writeln(playitem.ImageIndex);
writeln(playitem.index);
playitem.MakeVisible(False);
update_player_display;
//CactusPlugins.SendEvent(evnStartPlay, PlayerObj.Playlist.Items[PlayerObj.CurrentTrack].artist+' - '+PlayerObj.Playlist.Items[PlayerObj.CurrentTrack].title);
playtimer.Enabled := True;
end
else
begin
if (err = 1) then
ShowMessage(
'File not Found! Goto Library/Rescan Directories for updating file links'
);
if (err = 2) then
ShowMessage('Init of sound device failed.' + #10 + #13 +
'Perhaps sound ressource is blocked by another application...'
);
end;
end;
end
else
begin
//if player paused
pauseClick(nil);
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.StopClick(Sender: TObject);
begin
playtimer.Enabled := False;
if (PlayerObj.CurrentTrack >= 0) and
(PlayerObj.CurrentTrack < PlayerObj.Playlist.ItemCount) then
playlist.Items[PlayerObj.CurrentTrack].ImageIndex := -1;
PlayerObj.stop;
PlayerObj.playlist.reset_random;
update_player_display;
//CactusPlugins.SendEvent(evnStopPlay, '');
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playtimerTimer(Sender: TObject);
var
spos, slength: real;
r: real;
x2: integer;
tmppos: integer;
fileobj: TMediaFileClass;
begin
try
// if PlayerObj.playing=false then stopClick(nil);
if PlayerObj.PlaybackMode = STREAMING_MODE then
begin
if PlayerObj.Get_Stream_Status = STREAM_READY then
StatusBar1.Panels[0].Text := 'Stream Ready'
else
StatusBar1.Panels[0].Text := 'Buffering Stream...';
end;
// writeln('ontimer');
if (PlayerObj.playing) and (PlayerObj.PlaybackMode = FILE_MODE) and
(PlayerObj.paused = False) then
begin
// writeln('player playing');
if not bPnlPlaytimeNegated then
pnlPlaytime.Caption := PlayerObj.get_timestr
else
pnlPlaytime.Caption := PlayerObj.Get_TimeRemainingStr;
playwin.TimeImg.Picture.LoadFromFile(SkinData.Time.Img);
playwin.TimeImg.Canvas.Font.Color := ClNavy;
playwin.TimeImg.Canvas.TextOut(5, 3, pnlPlaytime.Caption);
tmppos := PlayerObj.Get_FilePosition;
trackbar.position := tmppos;
// writeln(tmppos);
x2 := (trackbar.position * 2) - 3;
if x2 < 3 then
x2 := 3;
if (tmppos = 100) then
begin
// writeln('nexttrack');
// WriteLn(PlayerObj.CurrentTrack);
if (PlayerObj.CurrentTrack < PlayerObj.Playlist.ItemCount) then
nextclick(nil)
else
stopClick(nil);
end;
if CactusConfig.CoverDownload and (CoverFound = False) and (LoopCount < 20) then
begin
Inc(LoopCount);
if (assigned(LastFMAPI)) and (LastFMAPI.data_ready) then
begin
fileobj := TMediaFileClass(playlist.Items[PlayerObj.CurrentTrack].Data);
if FileExists(fileobj.CoverPath) then
begin
try
CoverImage.Picture.LoadFromFile(fileobj.CoverPath);
playwin.AlbumCoverImg.Picture.LoadFromFile(fileobj.CoverPath);
except
DebugOutLn('EXCEPTION', 3);
end;
end;
CoverFound := True;
FreeAndNil(LastFMAPI);
end;
end
else if (LoopCount >= 20) and (CoverFound = False) then
CoverImage.Picture.Clear;
end
else
{playtimer.Enabled:=false};
except
DebugOutLn('CAUGHT EXCEPTION IN PLAYTIMER!!!!', 3);
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.removeselectClick(Sender: TObject);
var
curartist, curalbum: string;
album_mode: boolean;
MediaFileObj: TMediaFileClass;
MediaColObj: TMediaCollectionClass;
z: integer;
tsnode: TTreeNode;
begin
tsnode := Main.ArtistTree.Selected;
if (tsnode <> nil) and (tsnode.Level > 0) then
begin
if MessageDlg('The selected file(s) will permanently be' + #10 +
#13 + 'removed from harddisk!' + #10 + #13 + ' Proceed?', mtWarning,
mbOKCancel, 0) = mrOk then
begin
if tsnode.level < 2 then
album_mode := False
else
album_mode := True;
MediaFileObj := TMediaFileClass(tsnode.Data);
MediaColObj := MediaFileObj.Collection;
curartist := lowercase(MediaFileObj.Artist);
curalbum := lowercase(MediaFileObj.album);
z := MediaColObj.getTracks(curartist, MediaFileObj.index);
repeat
begin
if (album_mode = False) or ((album_mode = True) and
(lowercase(MediaColObj.items[z].album) = curalbum)) then
begin
if DeleteFile(MediaColObj.items[z].path) then
begin
DebugOutLn('deleted file from disk: ' + MediaColObj.items[z].path, 2);
MediaColObj.remove(z);
end
else
DebugOutLn('ERROR deleting file: ' + MediaColObj.items[z].path, 2);
end;
z := MediaColObj.getNext;
end;
until (z = -1);
update_artist_view;
update_title_view;
MediaColObj.SaveToFile;
end;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.save_listClick(Sender: TObject);
begin
SaveDialog1.Title := 'Save Playlist...';
saveDialog1.Filter := 'M3U Playlist|*.m3u';
saveDialog1.DefaultExt := 'm3u';
saveDialog1.FilterIndex := 1;
SaveDialog1.InitialDir := CactusConfig.HomeDir;
if Savedialog1.Execute = True then
begin
if FileExists(SaveDialog1.FileName) then
if MessageDlg('File ' + SaveDialog1.FileName + ' alreday exists' +
sLineBreak + sLineBreak + 'Overwrite?', mtWarning, mbOKCancel, 0) = mrCancel then
exit;
PlayerObj.playlist.SaveToFile(Savedialog1.Filename);
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.savelibClick(Sender: TObject);
begin
SaveDialog1.Title := 'Save Library...';
saveDialog1.Filter := 'Cactus Media Library|*.cml';
saveDialog1.DefaultExt := 'cml';
saveDialog1.FilterIndex := 1;
SaveDialog1.InitialDir := CactusConfig.HomeDir;
if Savedialog1.Execute = True then
MediaCollection.SaveToFile(Savedialog1.Filename);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.scanplayeritemClick(Sender: TObject);
var
tmps: string;
ScanCol: TMediaCollectionClass;
begin
if FileExists(CactusConfig.DAPPath) = False then
begin
ShowMessage(rsNotConnected);
exit;
end;
if FileExists(CactusConfig.DAPPath) then
begin
checkmobile.Enabled := False;
writeln('ooo');
disconnectDAP;
writeln('aa');
ScanCol := TMediaCollectionClass.Create;
ScanCol.syncronize := @ScanSyncronize;
Enabled := False;
writeln('ll');
ScanCol.PathFmt := FRelative;
ScanCol.savepath := CactusConfig.DAPPath + 'cactuslib';
writeln('dd');
ScanCol.add_directory(CactusConfig.DAPPath);
ScanCol.SaveToFile;
ScanCol.Free;
Enabled := True;
connectDAP;
checkmobile.Enabled := True;
tmps := ByteToFmtString(FreeSpaceOnDAP, 3, 2);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' Free';
end
else
DebugOutLn(CactusConfig.DAPPath + ' does not exist', 2);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.searchstrKeyUp(Sender: TObject; var Key: word;
Shift: TShiftState);
begin
if length(searchstr.Text) > 1 then
srch_buttonClick(nil)
else
TitleTree.Clear;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.srch_buttonClick(Sender: TObject);
var
searchstring, ft: string;
found: boolean;
Listitem: TListitem;
i: integer;
begin
TitleTree.Items.Clear;
TitleTree.BeginUpdate;
artisttree.selected := nil;
searchstring := lowercase(searchstr.Text);
found := False;
for i := 0 to MediaCollection.ItemCount - 1 do
begin
if SrchTitleItem.Checked then
if pos(searchstring, lowercase(MediaCollection.items[i].title)) <> 0 then
found := True;
if SrchArtItem.Checked then
if pos(searchstring, lowercase(MediaCollection.items[i].Artist)) <> 0 then
found := True;
if SrchAlbumItem.Checked then
if pos(searchstring, lowercase(MediaCollection.items[i].album)) <> 0 then
found := True;
if SrchFileItem.Checked then
if pos(searchstring, lowercase(extractfilename(MediaCollection.items[i].path))) <> 0 then
found := True;
if found then
begin
found := False;
ft := '';
case filetypebox.ItemIndex of
0: ft := 'all';
1: ft := '.flac';
2: ft := '.mp3';
3: ft := '.ogg';
4: ft := '.wav';
end;
if (ft = 'all') or (ft = MediaCollection.items[i].filetype) then
begin
ListItem := Main.Titletree.Items.Add;
listitem.Data := MediaCollection.items[i];
Listitem.ImageIndex := MediaCollection.items[i].action;
Listitem.Caption := '';
if MediaCollection.items[i].title <> '' then
ListItem.SubItems.Add(MediaCollection.items[i].Artist)
else
ListItem.SubItems.Add(SysToUTF8(extractfilename(MediaCollection.items[i].path)));
ListItem.SubItems.Add(MediaCollection.items[i].title);
ListItem.SubItems.Add(MediaCollection.items[i].album);
ListItem.SubItems.Add(MediaCollection.items[i].Track);
ListItem.SubItems.Add(MediaCollection.items[i].playtime);
end;
end;
end;
TitleTree.EndUpdate;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.EditID3itemClick(Sender: TObject);
var
tsitem: TListitem;
begin
tsitem := TitleTree.Selected;
if tsitem <> nil then
begin
editid3win.display_window(TMediaFileClass(tsitem.Data));
EditID3win.ShowModal;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ArtistTreeSelectionChanged(Sender: TObject);
begin
if not NetworkMode then
update_title_view;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ArtistTreeStartDrag(Sender: TObject; var DragObject: TDragObject);
begin
artist_drag := True;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.Button1Click(Sender: TObject);
begin
TitleTree.Clear;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.CoverImageMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
var
medFileObj: TMediaFileClass;
begin
//TODO: check why large cover image is linux only?
if PlayerObj.playing and (PlayerObj.PlaybackMode = FILE_MODE) and
(PlayerObj.CurrentTrack >= 0) then
begin
MedFileObj := TMediaFileClass(playlist.Items[PlayerObj.CurrentTrack].Data);
if (MedFileObj.CoverPath <> '') and FileExists(MedFileObj.CoverPath) then
begin
BigCoverImgForm := TBigCoverImg.Create(self);
BigCoverImgForm.Caption :=
PlayerObj.Playlist.Items[PlayerObj.CurrentTrack].Album;
BigCoverImgForm.Image1.Picture.LoadFromFile(MedFileObj.CoverPath);
BigCoverImgForm.Width := BigCoverImgForm.Image1.Picture.Width + 32;
BigCoverImgForm.Height := BigCoverImgForm.Image1.Picture.Height + 32;
BigCoverImgForm.Image1.AutoSize := True;
BigCoverImgForm.BackImg.Width := BigCoverImgForm.Image1.Picture.Width + 32;
BigCoverImgForm.BackImg.Height := BigCoverImgForm.Image1.Picture.Height + 32;
BigCoverImgForm.BackImg.Canvas.FillRect(0, 0, BigCoverImgForm.Width,
BigCoverImgForm.Height);
BigCoverImgForm.BackImg.Canvas.Rectangle(8, 8, BigCoverImgForm.Width - 8,
BigCoverImgForm.Height - 8);
BigCoverImgForm.Image1.Top := 16;
BigCoverImgForm.Image1.Left := 16;
BigCoverImgForm.Left := x + Panel1.Left + self.Left;
BigCoverImgForm.Top := y + Panel1.Height + self.top - 220;
{$ifdef win32 or win64}
BigCoverImgForm.Position := poScreenCenter;
{$endif}
BigCoverImgForm.BorderStyle := bsDialog;
BigCoverImgForm.ShowModal;
end;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.DeviceModeBtnClick(Sender: TObject);
begin
DeviceModeBtn.Down := True;
if not DeviceMode then
begin
ArtistTree.Selected := nil;
LibModeBtn.Down := False;
NetModeBtn.Down := False;
LibraryMode := False;
DeviceMode := True;
NetworkMode := False;
Playlist.Enabled := True;
TitleTree.Enabled := True;
trackbar.Enabled := True;
update_artist_view;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
ArtistSrchField.hide;
//unguenstig, wird bei jedem klick aufgerufen... :(
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.itemTrayExitClick(Sender: TObject);
begin
Close;
end;
procedure TMain.itemTrayPlayClick(Sender: TObject);
begin
if (PlayerObj.playing) then
pauseClick(nil)
else
playClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.LibModeBtnClick(Sender: TObject);
begin
LibModeBtn.Down := True;
if not LibraryMode then
begin
ArtistTree.Selected := nil;
DeviceModeBtn.Down := False;
NetModeBtn.Down := False;
LibraryMode := True;
DeviceMode := False;
NetworkMode := False;
Playlist.Enabled := True;
TitleTree.Enabled := True;
trackbar.Enabled := True;
update_artist_view;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem15Click(Sender: TObject);
var
i: integer;
begin
i := playlist.Items.Count;
artist_to_playlist;
Playlist.Selected := nil;
if playlist.Items.Count > 0 then
playlist.Items[i].Selected := True;
playClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem25Click(Sender: TObject);
begin
addRadioForm := TaddRadioForm.Create(self);
addRadioForm.ShowModal;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIViewAlbumClick(Sender: TObject);
begin
MIViewAlbum.Checked := not MIViewAlbum.Checked;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIViewArtistClick(Sender: TObject);
begin
MIViewArtist.Checked := not MIViewArtist.Checked;
CactusConfig.TLShowArtist := MIViewArtist.Checked;
TitleTree.Column[1].Visible := CactusConfig.TLShowArtist;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem32Click(Sender: TObject);
begin
if (ArtistTree.Selected <> nil) and (ArtistTree.Selected.Level > 0) then
begin
editid3win.display_window(TStreamInfoItemClass(ArtistTree.Selected.Data));
EditID3win.ShowModal;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem6Click(Sender: TObject);
var
MedFileObj: TMediaFileClass;
MedColObj: TMediaCollectionClass;
i: integer;
begin
if TitleTree.Selected <> nil then
if MessageDlg('The selected file(s) will permanently be' + #10 + #13 +
'removed from harddisk!' + #10 + #13 + ' Proceed?', mtWarning, mbOKCancel, 0) = mrOk then
begin
MedFileObj := TMediaFileClass(TitleTree.Selected.Data);
MedColObj := MedFileObj.collection;
i := MedFileObj.index;
if DeleteFile(MedFileObj.path) then
begin
DebugOutLn('deleted file from disk: ' + MedFileObj.path, 2);
MedColObj.remove(i);
end
else
if FileGetAttr(MedFileObj.path) = faReadOnly then
ShowMessage('File is read only!');
update_artist_view;
update_title_view;
MedColObj.SaveToFile;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem7Click(Sender: TObject);
begin
title_to_playlist;
Playlist.Items[Playlist.Items.Count - 1].Focused := True;
{$ifdef win32}
Playlist.Items[Playlist.Items.Count - 1].Selected := True;
{$endif}
playClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem9Click(Sender: TObject);
begin
title_to_playlist_at(PlayerObj.CurrentTrack + 1);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIDeviceInfoClick(Sender: TObject);
var
z: int64;
s, tmps, used: string;
i: integer;
begin
if player_connected then
begin
z := 0;
for i := 0 to PlayerCol.ItemCount - 1 do
z := z + PlayerCol.items[i].size;
used := ByteToFmtString(z, 4, 2);
tmps := ByteToFmtString(FreeSpaceOnDAP, 4, 2);
str(PlayerCol.ItemCount - 1, s);
ShowMessage(s + ' Files on mobile player ' + #10 + used + ' of music' + #10 +
'Free Disk Space: ' + tmps);
end
else
ShowMessage(rsNotConnected);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIremoveRadioClick(Sender: TObject);
var
index: integer;
begin
if (ArtistTree.Selected <> nil) and (ArtistTree.Selected.Level > 0) then
begin
index := StreamCollection.IndexOfObject(TStreamInfoItemClass(
ArtistTree.Selected.Data));
StreamCollection.Delete(index);
ArtistTree.Selected := nil;
end;
update_artist_view;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIRipAudioClick(Sender: TObject);
begin
cdripwin := Tcdrip.Create(Application);
Enabled := False;
cdripwin.ShowModal;
cdripwin.Free;
Enabled := True;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIViewFilenameClick(Sender: TObject);
begin
MIViewFilename.Checked := not MIViewFilename.Checked;
CactusConfig.TLShowFilename := MIViewFilename.Checked;
TitleTree.Column[6].Visible := CactusConfig.TLShowFilename;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIViewGenreClick(Sender: TObject);
begin
MIViewGenre.Checked := not MIViewGenre.Checked;
CactusConfig.TLShowGenre := MIViewGenre.Checked;
TitleTree.Column[5].Visible := CactusConfig.TLShowGenre;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIViewTitleClick(Sender: TObject);
begin
MIViewTitle.Checked := not MIViewTitle.Checked;
CactusConfig.TLShowTitle := MIViewTitle.Checked;
TitleTree.Column[2].Visible := CactusConfig.TLShowTitle;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MIViewTrackClick(Sender: TObject);
begin
MIViewTrack.Checked := not MIViewTrack.Checked;
CactusConfig.TLShowTrack := MIViewTrack.Checked;
TitleTree.Column[4].Visible := CactusConfig.TLShowTrack;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.mnuCleanLibClick(Sender: TObject);
begin
FrmCleanLibrary := TFrmCleanLibrary.Create(Application);
Enabled := False;
FrmCleanLibrary.ShowModal;
FrmCleanLibrary.Free;
update_artist_view;
update_title_view;
Enabled := True;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.NetModeBtnClick(Sender: TObject);
begin
NetModeBtn.Down := True;
if not NetworkMode then
begin
ArtistTree.Selected := nil;
DeviceModeBtn.down := False;
LibModeBtn.down := False;
LibraryMode := False;
DeviceMode := False;
NetworkMode := True;
Playlist.Enabled := False;
TitleTree.Enabled := False;
trackbar.Enabled := False;
update_artist_view;
update_title_view;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.NextButtonImgClick(Sender: TObject);
begin
nextClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.NextButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
NextButtonImg.Picture.LoadFromFile(SkinData.Next.Clicked);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.NextButtonImgMouseEnter(Sender: TObject);
begin
NextButtonImg.Picture.LoadFromFile(SkinData.Next.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.NextButtonImgMouseLeave(Sender: TObject);
begin
NextButtonImg.Picture.LoadFromFile(SkinData.Next.Img);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.NextButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
NextButtonImg.Picture.LoadFromFile(SkinData.Next.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PlaylistCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState;
var DefaultDraw: boolean);
begin
// not working because font colors not implemented in Lazarus 0.9.23
if (PlayerObj.Playlist.Items[Item.Index].Played) and
(PlayerObj.CurrentTrack <> Item.Index) then
Sender.Canvas.Font.Color := clGrayText
else
Sender.Canvas.Font.Color := clWindowText;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.pnlPlaytimeClick(Sender: TObject);
begin
bPnlPlaytimeNegated := not bPnlPlaytimeNegated;
end;
procedure TMain.PopupMenuTrayPopup(Sender: TObject);
begin
if (PlayerObj.playing) and (not (PlayerObj.paused)) then
begin
itemTrayPlay.Caption := 'Pause';
itemTrayPlay.ImageIndex := 2;
end
else
begin
itemTrayPlay.Caption := 'Play';
itemTrayPlay.ImageIndex := 1;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.randomcheckChange(Sender: TObject);
begin
PlayerObj.Playlist.reset_random;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.SearchPanelClick(Sender: TObject);
begin
ArtistSrchField.Hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PlayerControlsPanelClick(Sender: TObject);
begin
ArtistSrchField.hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PauseButtonImgClick(Sender: TObject);
begin
pauseClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PauseButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
pauseButtonImg.Picture.LoadFromFile(SkinData.pause.Clicked);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PauseButtonImgMouseEnter(Sender: TObject);
begin
pauseButtonImg.Picture.LoadFromFile(SkinData.pause.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PauseButtonImgMouseLeave(Sender: TObject);
begin
pauseButtonImg.Picture.LoadFromFile(SkinData.pause.Img);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PauseButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
pauseButtonImg.Picture.LoadFromFile(SkinData.pause.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PlayButtonImgClick(Sender: TObject);
begin
playclick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PlayButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
PlayButtonImg.Picture.LoadFromFile(SkinData.play.Clicked);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PlayButtonImgMouseEnter(Sender: TObject);
begin
PlayButtonImg.Picture.LoadFromFile(SkinData.play.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PlayButtonImgMouseLeave(Sender: TObject);
begin
PlayButtonImg.Picture.LoadFromFile(SkinData.play.Img);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PlayButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
PlayButtonImg.Picture.LoadFromFile(SkinData.play.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MainClose(Sender: TObject; var CloseAction: TCloseAction);
begin
PlayerObj.stop;
// if CactusConfig.PluginsEnabled then CactusPlugins.SendEvent(evnStopPlay, 'ps');
CactusConfig.WHeight := Height;
CactusConfig.WWidth := Width;
CactusConfig.WSplitterWidth := Splitter1.Left;
CactusConfig.bDisplayPlayTimeNegated := bPnlPlaytimeNegated;
if CactusConfig.LoadLastPlaylist and (PlayerObj.Playlist.Count > 0) then
begin
if PlayerObj.Playlist.SaveToFile(CactusConfig.ConfigPrefix +
'lib' + DirectorySeparator + 'last.m3u') <> 0 then
DebugOutLn('ERROR saving playlist', 2);
end
else if PlayerObj.Playlist.Count = 0 then
DeleteFile(CactusConfig.ConfigPrefix + 'lib' + DirectorySeparator + 'last.m3u');
if (MediaCollection.ItemCount > 0) then
begin
MediaCollection.SaveToFile(CactusConfig.ConfigPrefix + 'lib' +
DirectorySeparator + 'last.mlb');
CactusConfig.LastLib := MediaCollection.savepath;
end;
if StreamCollection.Count > 0 then
begin
StreamCollection.SaveToFile(CactusConfig.ConfigPrefix + 'lib' +
DirectorySeparator + 'streams.col');
CactusConfig.StreamColPath :=
CactusConfig.ConfigPrefix + 'lib' + DirectorySeparator + 'streams.col';
end
else
begin
if not DeleteFile(CactusConfig.ConfigPrefix + 'lib' + DirectorySeparator +
'streams.col') then
DebugOutLn('Cannot delete streamcolelction savefile: ' +
CactusConfig.ConfigPrefix + 'lib' + DirectorySeparator + 'streams.col', 1);
end;
MediaCollection.Free;
PlayerCol.Free;
checkmobile.Enabled := False;
playtimer.Enabled := False;
PlayerObj.Free;
CoverImage.Free;
if playermode = False then
begin
playwin.Close;
// playwin.Free;
end;
try
SimpleIPCServer1.StopServer;
SimpleIPCServer1.Free;
except
DebugOutLn('ERROR: Exception while shutting down IPC server', 2);
end;
writeln('end.');
//CactusPlugins.FlushPluginConfig;
//CactusPlugins.Free;
if CactusConfig.FlushConfig then
DebugOutLn('Config succesfully written to disk', 3)
else
DebugOutLn('ERROR: writing config to disk', 3);
CactusConfig.Free;
Application.Terminate;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.FormCloseQuery(Sender: TObject; var CanClose: boolean);
begin
CanClose := PluginsList.CanClose;
if CanClose then
begin
PluginsList.Free;
CJ_Interface.Free;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MainCreate(Sender: TObject);
var
tmps1: string;
MPlayerExeDialog: TSelectDirectoryDialog;
id: longint;
listitem: TListItem;
begin
DebugOutLn('## Main.onCreate ##', 3);
Caption := 'Cactus Jukebox ' + CACTUS_VERSION;
LibraryMode := True;
DeviceMode := False;
NetworkMode := False;
LibModeBtn.Down := True;
DeviceModeBtn.Down := False;
NetModeBtn.Down := False;
MediaCollection.syncronize := @ScanSyncronize;
Width := CactusConfig.WWidth;
Height := CactusConfig.WHeight;
DebugOutLn('loading main form translations...', 5);
TranslateUnitResourceStrings('mainform', CactusConfig.DataPrefix +
'languages' + DirectorySeparator + 'cactus.%s.po',
CactusConfig.language, copy(CactusConfig.language, 0, 2));
if SystemCharSetIsUTF8 then
DebugOutLn('##System charset is UTF8', 3);
// Load resourcestrings to Captions
QuitItem.Caption := rsQuit;
FileItem.Caption := rsFile;
openfile.Caption := rsOpenFile;
opendir.Caption := rsOpenDirector;
player_lib.Caption := rsPlayerOnly;
skinmenu.Caption := rsChooseSkin;
SettingsItem.Caption := rsSettings;
MIlibrary.Caption := rsLibrary;
MInewlib.Caption := rsNewLibrary;
MIloadlib.Caption := rsLoadLibrary;
MIsavelib.Caption := rsSaveLibrary;
MIlibinfo.Caption := rsLibraryInfo;
MIManagLib.Caption := rsManageLibrar;
MIPlaylist.Caption := rsPlaylist;
MIplay.Caption := rsPlay;
MInext.Caption := rsNext;
MIprevious.Caption := rsPrevious;
MImute.Caption := rsMute;
MIload_list.Caption := rsLoadPlaylist;
MIsave_list.Caption := rsSavePlaylist;
MIclear_playlist.Caption := rsClearPlaylist;
MIrandom_playlist.Caption := rsRandomPlaylist;
MIDevices.Caption := rsDevices;
MIMobilePlayer.Caption := rsMobilePlayer;
MIDeviceInfo.Caption := rsDeviceInfo;
MIScanPlayer.Caption := rsScanPlayer;
MISyncPlayer.Caption := rsSync;
MIClearPlayer.Caption := rsClearPlayer;
MIUndoPlayer.Caption := rsUndoSelectio;
MIRipAudio.Caption := rsRipEncode;
MIhelp.Caption := rsHelp;
MIabout.Caption := rsAbout;
MImanual.Caption := rsManual;
Playlist.Column[0].Caption := rsPlaylist;
clear_list.Caption := rsClear;
srch_button.Caption := rsSearch;
SrchAlbumItem.Caption := rsAlbum;
SrchArtItem.Caption := rsArtist;
SrchFileItem.Caption := rsFilename;
SrchTitleItem.Caption := rsTitle;
randomcheck.Caption := rsRandom;
TitleTree.Column[1].Caption := rsArtist;
TitleTree.Column[2].Caption := rsTitle;
TitleTree.Column[3].Caption := rsAlbum;
TitleTree.Column[4].Caption := rsTrack;
TitleTree.Column[7].Caption := rsLenght;
TitleTree.Column[1].Visible := CactusConfig.TLShowArtist;
TitleTree.Column[2].Visible := CactusConfig.TLShowTitle;
TitleTree.Column[3].Visible := CactusConfig.TLShowAlbum;
TitleTree.Column[4].Visible := CactusConfig.TLShowTrack;
TitleTree.Column[5].Visible := CactusConfig.TLShowGenre;
TitleTree.Column[6].Visible := CactusConfig.TLShowFilename;
TitleTree.Column[7].Visible := True;
MIViewFilename.Checked := CactusConfig.TLShowFilename;
MIViewGenre.Checked := CactusConfig.TLShowGenre;
MIViewTrack.Checked := CactusConfig.TLShowTrack;
MIViewAlbum.Checked := CactusConfig.TLShowAlbum;
MIViewTitle.Checked := CactusConfig.TLShowTitle;
MIViewArtist.Checked := CactusConfig.TLShowArtist;
oldSplitterWidth := CactusConfig.WSplitterWidth;
bPnlPlaytimeNegated := CactusConfig.bDisplayPlayTimeNegated;
SplitterResize := True;
SrchTitleItem.Checked := True;
SrchArtItem.Checked := True;
{$ifdef CPU86}
if CactusConfig.AudioBackend = MPLAYERBACK then
begin
PlayerObj := TMPlayerClass.Create;
DebugOutLn('MPlayer audio backend loaded', 2);
end
else
begin
{$ifndef fmod}
DebugOutLn(
'WARNING: Cactus Jukebox has been compiled without fmod support. Trying to load mplayer backend instead',
0);
PlayerObj := TMPlayerClass.Create;
DebugOutLn('MPlayer audio backend loaded', 2);
{$endif}
{$ifdef fmod}
PlayerObj := TFModPlayerClass.Create;
DebugOutLn('FMOD audio backend loaded', 2);
{$endif}
end;
{$endif}
{$ifdef CPUX86_64}// Fmod library is only available on 32bit systems. Always try to load mplayer instead
if CactusConfig.AudioBackend = MPLAYERBACK then
begin
PlayerObj := TMPlayerClass.Create;
DebugOutLn('MPlayer audio backend loaded', 2);
end
else
begin
PlayerObj := TMPlayerClass.Create;
DebugOutLn(
'WARNING: Fmod backend not available on 64bit systems. Trying to load mplayer backend instead',
0);
end;
{$endif}
if (PlayerObj is TMPlayerClass) then
begin
(PlayerObj as TMPlayerClass).UseExternalConfig :=
CactusConfig.MPlayerUseExternalConfig;
if FileExists(IncludeTrailingPathDelimiter(CactusConfig.DataPrefix) +
'mplayer.cfg') then
(PlayerObj as TMPlayerClass).ExternalConfigFile :=
IncludeTrailingPathDelimiter(CactusConfig.DataPrefix) + 'mplayer.cfg';
if FileExists(IncludeTrailingPathDelimiter(CactusConfig.ConfigPrefix) +
'mplayer.cfg') then
(PlayerObj as TMPlayerClass).ExternalConfigFile :=
IncludeTrailingPathDelimiter(CactusConfig.ConfigPrefix) + 'mplayer.cfg';
end;
if (PlayerObj is TMPlayerClass) and ((PlayerObj as TMPlayerClass).MPlayerPath = '') then
begin
if CactusConfig.MPlayerPath = '' then
begin
ShowMessage('MPlayer executable not found! Please select MPlayer directory...');
MPlayerExeDialog := TSelectDirectoryDialog.Create(self);
MPlayerExeDialog.Title := 'Locate mplayer executable...';
if MPlayerExeDialog.Execute then
begin
CactusConfig.MPlayerPath := MPlayerExeDialog.FileName;
end;
end;
if (PlayerObj as TMPlayerClass).setMplayerBinaryDir(
CactusConfig.MPlayerPath) = False then
begin
ShowMessage('MPlayer executable not found in ' + LineEnding +
MPlayerExeDialog.FileName);
halt;
end;
end;
PlayerObj.OutputMode := CactusConfig.AudioSystem;
player_connected := False;
{$ifdef linux}
try
DebugOut('loading program icon... ', 2);
Icon.LoadFromFile(CactusConfig.DataPrefix + 'icon' + DirectorySeparator +
'cactus-icon.ico');
// CoverImage.Picture.LoadFromFile(DataPrefix+'tools'+DirectorySeparator+'cactus-logo-small.png');
DebugOutLn('... loaded', 2);
except
DebugOutLn('ERROR loading bitmaps, files not found', 2);
end;
{$endif}
{$ifdef win32}
pnlPlaytime.Canvas.Font.Height := 10;
pnlPlaytime.Canvas.Font.Size := 10;
{$endif win32}
{$ifdef LCLGtk}
pnlplaytime.Font.Height := 13;
pnlplaytime.Font.Size := 13;
{$endif}
{$ifdef LCLGtk2}
Main.Titletree.Columns[0].Width := 20;
{$endif LCLGtk2}
SimpleIPCServer1.ServerID := 'cactusjukeboxipc';
{$ifdef unix}
Application.OnIdle := @ApplicationIdle;
{$endif}
SimpleIPCServer1.Global := True;
SimpleIPCServer1.StartServer;
checkmobile.Enabled := True;
// unused ??
main.tempbitmap := TBitmap.Create;
main.timetmpbmp := TBitmap.Create;
main.tempbitmap.Width := 300;
main.tempbitmap.Height := 150;
// ------
if FileExists(CactusConfig.LastLib) then
begin
//main.StatusBar1.Panels[0].Text:='Loading last library...';
if Mediacollection.LoadFromFile(CactusConfig.LastLib) = False then
begin
//MediaCollection.clear;
ShowMessage('ERROR while reading last library. You need to create a new one.' +
LineEnding + 'Please choose a directory to scan for mediafiles...');
newlibClick(nil);
TitleTree.Clear;
end;
end;
if FileExists(CactusConfig.StreamColPath) then
begin
if StreamCollection.LoadFromFile(CactusConfig.StreamColPath) = False then
begin
writeln('Error loading stream collection');
end;
end;
if CactusConfig.LoadLastPlaylist then
begin
if FileExists(CactusConfig.ConfigPrefix + 'lib' + DirectorySeparator + 'last.m3u') then
begin
if PlayerObj.Playlist.LoadFromFile(
CactusConfig.ConfigPrefix + 'lib' + DirectorySeparator + 'last.m3u') <> 0 then
DebugOutLn('ERROR loading last playlist', 2);
for id := 0 to PlayerObj.Playlist.Count - 1 do
begin
ListItem := Playlist.Items.Add;
listitem.Data :=
TMediaFileClass.Create(PlayerObj.Playlist.Items[id].path, nil);
if (PlayerObj.Playlist.items[id].Artist <> '') or
(PlayerObj.Playlist.items[id].Title <> '') then
ListItem.Caption :=
PlayerObj.Playlist.items[id].Artist + ' - ' + PlayerObj.Playlist.Items[id].Title
else
ListItem.Caption :=
UTF8Encode(ExtractFileName(PlayerObj.Playlist.items[id].Path));
end;
if Playlist.Items.Count > 0 then
Playlist.Selected := Playlist.Items[0];
end;
end;
if CactusConfig.AlbumCoverFirsttime then
begin
tmps1 :=
'Cactus Jukebox can download album cover art from internet and show it on playback'
+ LineEnding + '(No private data is submitted. Only album title and artist)'
+ LineEnding + LineEnding + 'Do you want to enable this feature?'
+ LineEnding + LineEnding +
'You can change this behaviour later in File->Settings';
if MessageDlg(tmps1, mtConfirmation, mbYesNo, 0) = mrYes then
CactusConfig.CoverDownload :=
True
;
end;
// Load file specified on commandline
if CactusConfig.LoadOnStart <> '' then
begin
LoadFile(CactusConfig.LoadOnStart);
end;
DebugOutLn('main.create end', 5);
update_artist_view;
//update_title_view;
DebugOutLn('main.create end', 5);
Self.fromTrayDBLClick := False;
oldWindowState := Self.WindowState;
//Build of Interfaces and Plugins List (may be moved....)
MenuOwner := Self;
CJ_Interface := TCJ_Interface_Impl.Create;
global_vars.AppMainMenu := Self.Mainmenu1;
global_vars.AppTrayIcon := Self.TrayIcon;
global_vars.ImageListNormal := Self.ImageListNormal;
PluginsList := TCJ_PluginsList.Create;
PluginsList.LoadFromINI;
Self.TrayIcon.Hint := 'Cactus Juke Box...';
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ApplicationIdle(Sender: TObject; var Done: boolean);
begin
{$ifdef linux}
//linux doesn't recognize onIPCMessage Event. so we call it manually
if SimpleIPCServer1.PeekMessage(1, True) then
begin
//PeekMessage automaticly calls OnMessage event
DebugOutLn('IPC Messge received', 2);
end;
{$endif}
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.update_player_display;
var
i: integer;
begin
if PlayerObj.playing then
begin
i := PlayerObj.CurrentTrack;
//MedFileObj:=playlist.Items[player.CurrentTrack].Data;
if PlayerObj.Playlist.items[i].Artist <> '' then
current_title_edit.Text := PlayerObj.Playlist.items[i].Artist
else
current_title_edit.Text := ExtractFileName(PlayerObj.Playlist.items[i].path);
current_title_edit1.Text := PlayerObj.Playlist.items[i].title;
playwin.TitleImg.Picture.LoadFromFile(SkinData.Title.Img);
playwin.TitleImg.canvas.Font.Color := Clnavy;
if PlayerObj.Playlist.items[i].Artist <> '' then
playwin.TitleImg.canvas.textout(5, 5, PlayerObj.Playlist.items[i].Artist)
else
playwin.TitleImg.canvas.textout(5, 5, ExtractFileName(PlayerObj.Playlist.items[i].path));
playwin.TitleImg.canvas.textout(5, 25, PlayerObj.Playlist.items[i].title);
end
else
begin
//clear everything
playwin.TitleImg.canvas.Clear;
CoverImage.Picture.Clear;
playwin.TimeImg.Canvas.Clear;
current_title_edit.Text := '';
current_title_edit1.Text := '';
pnlPlaytime.Caption := '00:00';
trackbar.Position := 0;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function TMain.LoadFile(path: string): boolean;
var
z: integer;
listitem: TListItem;
begin
DebugOutLn('** Loadfile **', 2);
Application.ProcessMessages;
if FileExistsUTF8(Path) then
begin
z := MediaCollection.GetIndexByPath(path);
DebugOutLn(z, 3);
if z < 0 then
begin
z := MediaCollection.add(path);
end;
PlayerObj.playlist.add(MediaCollection.items[z]);
ListItem := Playlist.Items.Add;
listitem.Data := MediaCollection.items[z];
if MediaCollection.items[z].title <> '' then
ListItem.Caption := MediaCollection.items[z].Artist
+
' - ' + MediaCollection.items[z]
.title
else
ListItem.Caption := extractfilename(MediaCollection.items[z].path);
playlist.Column[0].Caption :=
'Playlist (' + IntToStr(
PlayerObj.playlist.ItemCount) +
' Files/ ' + PlayerObj.Playlist.TotalPlayTimeStr + ')';
Result := True;
update_artist_view;
update_title_view;
end
else
Result := False;
Application.ProcessMessages;
end;
procedure TMain.MinimizeMe(Data: Ptrint);
begin
Include(FFlags, cfProgHide);
Hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ScanSyncronize(dir: string);
begin
Inc(ScanSyncCount);
if ScanSyncCount >= 500 then
begin
update_artist_view;
ScanSyncCount := 0;
end;
if (ScanSyncCount mod 50) = 0 then
begin
StatusBar1.Panels[0].Text := 'scanning trough: ' + dir;
Application.ProcessMessages;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.update_artist_view;
// TODO: rewrite method to reselect artist
var
curartist, curalbum: string;
tsnode, artnode, TopNode: Ttreenode;
AlbumList: TStringList;
MedFileObj: TMediaFileClass;
i, z: integer;
restoreEnabled, album_selected: boolean;
begin
if Enabled then
restoreEnabled := True
else
restoreEnabled := False;
Enabled := False;
StatusBar1.Panels[0].Text := 'Please wait... updating...';
ArtistTree.OnSelectionChanged := nil;
//Disable event while working on selection in artisttree!!
DebugOutLn('', 2);
DebugOut('## update artist view... ', 2);
tsnode := ArtistTree.Selected;
if (tsnode <> nil) then
begin
if tsnode.Level = 1 then
begin
curartist := lowercase(tsnode.Text);
curalbum := '';
album_selected := False;
end;
if tsnode.Level = 2 then
begin
curartist := lowercase(tsnode.Parent.Text);
curalbum := lowercase(tsnode.Text);
// writeln(curalbum);
album_selected := True;
end;
end
else
curartist := '';
artisttree.beginupdate;
DebugOut(' clear tree...', 2);
ArtistTree.Items.Clear;
if NetworkMode then
begin
TopNode := ArtistTree.Items.Add(nil, 'Webradio stations');
TopNode.Data := pointer(1);
for i := 0 to StreamCollection.Count - 1 do
begin
artnode := ArtistTree.Items.AddChild(TopNode, StreamCollection.Strings[i]);
with artnode do
begin
MakeVisible;
ImageIndex := -1;
SelectedIndex := -1;
Data := StreamCollection.Objects[i];
end;
end;
end;
// If library mode add Mediacollection
if LibraryMode and (MediaCollection.Count > 0) then
begin
TopNode := Main.ArtistTree.Items.Add(nil, rsLibrary);
TopNode.ImageIndex := 4;
TopNode.SelectedIndex := 4;
TopNode.Data := pointer(1);
i := MediaCollection.getArtists;
repeat
begin
if MediaCollection.Items[i].Artist <> '' then
artnode := Main.ArtistTree.Items.AddChild(
TopNode,
MediaCollection.Items[i].
Artist)
else
artnode := Main.ArtistTree.Items.AddChild(TopNode, 'Unknown');
with artnode do
begin
MakeVisible;
ImageIndex := 6; //MediaCollection.Items[i].Action;
SelectedIndex := 6; //MediaCollection.Items[i].Action;
Data := MediaCollection.items[i];
Expanded := False;
end;
AlbumList := MediaCollection.getAlbums(MediaCollection.Items[i].Artist, i);
for z := 0 to AlbumList.Count - 1 do
begin
// add albums to node of current SrchArtItem
with Main.ArtistTree.Items.Addchild(artnode, AlbumList[z]) do
begin
MakeVisible;
MedFileObj := TMediaFileClass(AlbumList.Objects[z]);
ImageIndex := 7;//MedFileObj.Action;
SelectedIndex := 7;//MedFileObj.Action;
Data := AlbumList.Objects[z];
end;
end;
artnode.Expanded := False;
i := MediaCollection.getNextArtist;
end;
until i < 0;
// finally free AlbumList
AlbumList.Free;
end;
// If Device mode add playercollection and other devices
if DeviceMode and player_connected then
begin
TopNode := Main.ArtistTree.Items.Add(nil, rsMobileDevice);
TopNode.SelectedIndex := 1;
TopNode.ImageIndex := 1;
TopNode.Data := pointer(0);
i := PlayerCol.getArtists;
repeat
begin
if PlayerCol.Items[i].Artist <> '' then
artnode := Main.ArtistTree.Items.AddChild(TopNode,
PlayerCol.Items[i].Artist)
else
artnode := Main.ArtistTree.Items.AddChild(TopNode, 'Unknown');
with artnode do
begin
MakeVisible;
ImageIndex := PlayerCol.Items[i].Action;
SelectedIndex := PlayerCol.Items[i].Action;
Data := PlayerCol.items[i];
end;
AlbumList := PlayerCol.getAlbums(PlayerCol.Items[i].Artist, i);
for z := 0 to AlbumList.Count - 1 do
begin
// add albums to node of current SrchArtItem
with Main.ArtistTree.Items.Addchild(artnode, AlbumList[z]) do
begin
MakeVisible;
MedFileObj := TMediaFileClass(AlbumList.Objects[z]);
ImageIndex := MedFileObj.Action;
SelectedIndex := MedFileObj.Action;
Data := AlbumList.Objects[z];
end;
end;
artnode.Expanded := False;
i := PlayerCol.getNextArtist;
end;
until i < 0;
// finally free AlbumList
AlbumList.Free;
end;
ArtistTree.EndUpdate;
DebugOut(' reselecting last item ', 2);
// Reselect last selected item if possible
i := 0;
if ArtistTree.Items.Count > 0 then
ArtistTree.Selected := ArtistTree.Items[0];
if ((curalbum <> '') or (curartist <> '')) and (ArtistTree.Items.Count > 0) then
begin
repeat //try to keep old album
begin
MedFileObj := TMediaFileClass(ArtistTree.items[i].Data);
Inc(i);
end;
until ((lowercase(artisttree.items[i].Text) = curalbum) and
(ArtistTree.Items[i].Level = 2)) or (i >= artisttree.items.Count - 1);
if lowercase(artisttree.items[i].Text) = curalbum then
begin
artisttree.selected := main.artisttree.items[i];
end
else if (curartist <> '') and (ArtistTree.Items.Count > 0) then
begin //Select artist if album not possible
i := 0;
repeat
begin
MedFileObj := TMediaFileClass(ArtistTree.items[i].Data);
Inc(i);
end;
until ((lowercase(artisttree.items[i].Text) = curartist) and
(ArtistTree.Items[i].Level = 1)) or (i >= artisttree.items.Count - 1);
writeln(curartist);
writeln(artisttree.items[i].Text);
if lowercase(artisttree.items[i].Text) = curartist then
begin
artisttree.selected := main.artisttree.items[i];
end;
end;
if ArtistTree.Selected.AbsoluteIndex < ArtistTree.Items.Count - 10 then
begin
ArtistTree.Items[ArtistTree.Selected.AbsoluteIndex + 9].MakeVisible;
if ArtistTree.Items[ArtistTree.Selected.AbsoluteIndex + 9].Level > 1 then
ArtistTree.Items[ArtistTree.Selected.AbsoluteIndex +
9].Parent.Expanded := False;
end
else
begin
ArtistTree.Items[ArtistTree.Items.Count - 1].MakeVisible;
if ArtistTree.Items[ArtistTree.Items.Count - 1].Level > 1 then
ArtistTree.Items[ArtistTree.Items.Count - 1].Parent.Expanded := False;
end;
end;
ArtistTree.OnSelectionChanged := @ArtistTreeSelectionChanged; //Reenable event!!
DebugOutLn(' finished artistview ##', 2);
StatusBar1.Panels[0].Text := 'Ready.';
Enabled := restoreEnabled;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem11Click(Sender: TObject);
begin
dirwin := Tdirwin.Create(Application);
Enabled := False;
dirwin.ShowModal;
dirwin.Free;
Enabled := True;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem14Click(Sender: TObject);
var
tsitem: TListItem;
tmps: string;
MedFileObj: TMediaFileClass;
i: integer;
begin
tsitem := TitleTree.Selected;
if (tsitem <> nil) and player_connected then
begin
MedFileObj := TMediaFileClass(tsitem.Data);
for i := 1 to MediaCollection.ItemCount - 1 do
if MedFileObj.id = MediaCollection.items[i].id then
MediaCollection.items[i].action := AREMOVE;
for i := 1 to PlayerCol.ItemCount - 1 do
if MedFileObj.id = PlayerCol.items[i].id then
PlayerCol.items[i].action := AREMOVE;
update_artist_view;
update_title_view;
tmps := ByteToFmtString(FreeSpaceOnDAP + sizediff, 3, 2);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' Free';
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem16Click(Sender: TObject);
var
tsitem: TListItem;
tmps: string;
MedFileObj: TMediaFileClass;
begin
tsitem := TitleTree.Selected;
if (tsitem <> nil) and player_connected then
begin
MedFileObj := TMediaFileClass(tsitem.Data);
MedFileObj.action := AUPLOAD;
update_artist_view;
update_title_view;
tmps := ByteToFmtString(FreeSpaceOnDAP + sizediff, 3, 2);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' Free';
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem20Click(Sender: TObject);
var
tsitem: TListItem;
MedFileObj: TMediaFileClass;
tmps: string;
i: integer;
begin
tsitem := TitleTree.Selected;
if tsitem <> nil then
begin
MedFileObj := TMediaFileClass(tsitem.Data);
if MedFileObj.action = AREMOVE then
begin
//PFobj^.action:=1;
sizediff := sizediff - MedFileObj.size;
for i := 1 to MediaCollection.ItemCount - 1 do
if MedFileObj.id = MediaCollection.items[i].id then
MediaCollection.items[i].action := 1;
for i := 1 to PlayerCol.ItemCount - 1 do
if MedFileObj.id = PlayerCol.items[i].id then
PlayerCol.items[i].action := -1;
end
else
begin
MedFileObj.action := -1;
sizediff := sizediff + MedFileObj.size;
end;
update_artist_view;
update_title_view;
tmps := ByteToFmtString(FreeSpaceOnDAP + sizediff, 3, 2);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' Free';
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Random Paylist with 50 tracks by monta
procedure TMain.MIrandom_playlistClick(Sender: TObject);
var
listitem: TListitem;
MedFileObj: TMediaFileClass;
i: integer;
begin
if MediaCollection.Count < 2 then
exit;
Randomize;
i := 1;
repeat
MedFileObj := MediaCollection.Items[Random(MediaCollection.Count)];
PlayerObj.playlist.add(MedFileObj);
ListItem := Main.Playlist.Items.Add;
listitem.Data := MedFileObj;
listitem.MakeVisible(False);
if MedFileObj.title <> '' then
ListItem.Caption := MedFileObj.Artist + ' - ' + MedFileObj.title
else
ListItem.Caption := extractfilename(MedFileObj.path);
if not PlayerObj.playing and CactusConfig.AutostartPlay and
(main.Playlist.Items.Count = 1) then
begin
main.Playlist.Selected := Main.Playlist.Items[0];
DebugOutLn(Main.Playlist.Selected.Caption, 3);
Main.playClick(main);
end;
Inc(i);
until (i > 50) or (i >= MediaCollection.Count);
main.playlist.Column[0].Caption :=
rsplaylist + ' (' + IntToStr(
PlayerObj.playlist.ItemCount) +
' Files/ ' + PlayerObj.Playlist.TotalPlayTimeStr + ' )';
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem26Click(Sender: TObject);
begin
ShowMessage('Cactus Jukebox' + LineEnding + 'version' + CACTUS_VERSION + LineEnding +
'written by Sebastian Kraft ' + LineEnding + LineEnding +
'(c) 2005-2009' + LineEnding + 'http://cactus.hey-you-freaks.de ');
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem27Click(Sender: TObject);
var
id: longint;
listitem: TListitem;
OpenDialog: TOpenDialog;
begin
OpenDialog := TOpenDialog.Create(self);
OpenDialog.Filter := 'M3U Playlist|*.m3u|All Files|*.*';
OpenDialog.InitialDir := CactusConfig.HomeDir;
OpenDialog.FilterIndex := 1;
if Opendialog.Execute = True then
begin
playlist.Clear;
PlayerObj.Playlist.Clear;
DebugOut('Loading playlist from -> ' + Opendialog.Filename + ' ... ', 2);
if PlayerObj.Playlist.LoadFromFile(Opendialog.Filename) = 0 then
begin
DebugOutLn('done', 2);
DebugOut('Adding items... ', 4);
for id := 0 to PlayerObj.Playlist.Count - 1 do
begin
ListItem := Playlist.Items.Add;
listitem.ImageIndex := -1;
listitem.Data :=
TMediaFileClass.Create(PlayerObj.Playlist.Items[id].path, nil);
if (PlayerObj.Playlist.items[id].Artist <> '') or
(PlayerObj.Playlist.items[id].Title <> '') then
ListItem.Caption :=
PlayerObj.Playlist.items[id].Artist + ' - ' + PlayerObj.Playlist.Items[id].Title
else
ListItem.Caption :=
UTF8Encode(ExtractFileName(PlayerObj.Playlist.items[id].Path));
end;
DebugOutLn('done', 4);
if Playlist.Items.Count > 0 then
Playlist.Selected := Playlist.Items[0];
end
else
ShowMessage('ERROR loading Playlist');
end;
OpenDialog.Free;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem2Click(Sender: TObject);
var
i: integer;
MedFileObj: TMediaFileClass;
Listitem: TListItem;
begin
if (TitleTree.Items.Count > 0) then
begin
for i := 0 to TitleTree.Items.Count - 1 do
begin
MedFileObj := TMediaFileClass(TitleTree.Items[i].Data);
PlayerObj.playlist.add(MedFileObj);
ListItem := Playlist.Items.Add;
listitem.Data := MedFileObj;
if MedFileObj.title <> '' then
ListItem.Caption := MedFileObj.Artist + ' - ' + MedFileObj.title
else
ListItem.Caption := extractfilename(MedFileObj.path);
end;
end;
playlist.Column[0].Caption :=
'Playlist (' + IntToStr(
PlayerObj.playlist.ItemCount) + ' Files/ ' +
PlayerObj.Playlist.TotalPlayTimeStr + ')';
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem37Click(Sender: TObject);
var
MedColObj: TMediaCollectionClass;
curartist, curalbum, tmps: string;
MedFileObj: TMediaFileClass;
i: integer;
tsnode: TTreeNode;
begin
tsnode := ArtistTree.Selected;
if (tsnode <> nil) and (tsnode.level > 0) then
begin
MedFileObj := TMediaFileClass(tsnode.Data);
MedColObj := MedFileObj.collection;
i := MedColObj.getTracks(MedFileObj.Artist, MedFileObj.index);
if tsnode.level = 2 then
begin
curartist := lowercase(MedFileObj.Artist);
curalbum := lowercase(MedFileObj.album);
repeat
begin
if (lowercase(MedColObj.items[i].album) = curalbum) and
(MedColObj.items[i].action = AREMOVE) then
begin
MedColObj.items[i].action := AONPLAYER;
sizediff := sizediff - MedColObj.items[i].size;
end;
if (lowercase(MedColObj.items[i].album) = curalbum) and
(MedColObj.items[i].action <> AONPLAYER) then
begin
MedColObj.items[i].action := ANOTHING;
sizediff := sizediff + MedColObj.items[i].size;
end;
i := MedColObj.GetNext;
end;
until i < 0;
end;
if tsnode.level = 1 then
begin
curartist := lowercase(MedFileObj.Artist);
repeat
begin
if (MedColObj.items[i].action = AREMOVE) then
begin
MedColObj.items[i].action := AONPLAYER;
sizediff := sizediff - MedColObj.items[i].size;
end;
if (MedColObj.items[i].action <> AONPLAYER) then
begin
MedColObj.items[i].action := ANOTHING;
sizediff := sizediff + MedColObj.items[i].size;
end;
i := MedColObj.GetNext;
end;
until i < 0;
end;
update_artist_view;
update_title_view;
tmps := ByteToFmtString(FreeSpaceOnDAP + sizediff, 3, 2);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' Free';
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Open manual/homepage in browser
procedure TMain.MenuItem43Click(Sender: TObject);
begin
{$ifdef linux}
exec('/usr/bin/firefox', 'http://cactus.hey-you-freaks.de');
if Dosexitcode <> 0 then
exec('/usr/bin/mozilla-firefox',
'http://cactus.hey-you-freaks.de/index.php?page=manual');
if Dosexitcode <> 0 then
exec('/usr/bin/konqueror',
'http://cactus.hey-you-freaks.de/index.php?page=manual');
if Dosexitcode <> 0 then
ShowMessage('The manual can be found at http://cactus.hey-you-freaks.de');
{$endif}
{$ifdef win32}//TODO: Open manual in Browser on win32
ShowMessage('The manual can be found at http://cactus.hey-you-freaks.de');
{$endif}
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.Panel1Click(Sender: TObject);
begin
ArtistSrchField.hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.Panel1Resize(Sender: TObject);
var
i: integer;
begin
// Splitter1.Left:=oldSplitterWidth;
{$ifdef win32}//TODO: check column autosize on win32
Playlist.Columns[0].Width := Playlist.Width;
Titletree.Columns[5].Width := 45;
Titletree.Columns[4].Width := 45;
Titletree.Columns[3].Width := 110;
i := TitleTree.Width - 45 - 45 - 110 - 140 - 16 - 15;
if i > 0 then
Titletree.Columns[2].Width := i;
Titletree.Columns[1].Width := 140;
Titletree.Columns[0].Width := 16;
{$endif}
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.Panel4Click(Sender: TObject);
begin
ArtistSrchField.hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ArtistSrchFieldClick(Sender: TObject);
begin
ArtistSrchField.hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PreviousButtonImgClick(Sender: TObject);
begin
prevClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PreviousButtonImgMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
PreviousButtonImg.Picture.LoadFromFile(SkinData.previous.Clicked);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PreviousButtonImgMouseEnter(Sender: TObject);
begin
PreviousButtonImg.Picture.LoadFromFile(SkinData.previous.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PreviousButtonImgMouseLeave(Sender: TObject);
begin
PreviousButtonImg.Picture.LoadFromFile(SkinData.previous.Img);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.PreviousButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
PreviousButtonImg.Picture.LoadFromFile(SkinData.previous.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.SettingsItemClick(Sender: TObject);
begin
Enabled := False;
setupwin := Tsettings.Create(Application);
setupwin.ShowModal;
setupwin.Free;
Enabled := True;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.SimpleIPCServer1Message(Sender: TObject);
var
fpath: string;
CommandCode: integer;
begin
DebugOutLn(' IPC Message received', 2);
if length(SimpleIPCServer1.StringMessage) > 2 then
begin
fpath := copy(SimpleIPCServer1.StringMessage,
Pos(':', SimpleIPCServer1.StringMessage) + 2, length(
SimpleIPCServer1.StringMessage));
CommandCode := StrToInt(Copy(SimpleIPCServer1.StringMessage, 0,
Pos(':', SimpleIPCServer1.StringMessage) - 1));
end
else
begin
fpath := '';
CommandCode := StrToInt(SimpleIPCServer1.StringMessage);
end;
case CommandCode of
VOLUME_UP: if volumebar.Position > 4 then
volumebar.Position := volumebar.Position - 5;
VOLUME_DOWN: if volumebar.Position < 46 then
volumebar.Position := volumebar.Position + 5;
NEXT_TRACK: nextClick(self);
STOP_PLAYING: stopClick(self);
START_PLAYING: playClick(self);
PREV_TRACK: prevClick(self);
PAUSE_PLAYING: pauseClick(self);
OPEN_FILE: if FileExists(fpath) then
begin
LoadFile(fpath);
Playlist.Selected := Playlist.Items[Playlist.Items.Count - 1];
playClick(self);
end
else
DebugOutLn('--> Filename received from IPC does not exist', 2);
ENQUEU_FILE: if FileExists(fpath) then
begin
LoadFile(fpath);
end
else
DebugOutLn('--> Filename received from IPC does not exist', 2);
else
DebugOutLn(' --> Invalid message/filename received via IPC', 2);
end;
Writeln('IPC end');
end;
procedure TMain.skinmenuClick(Sender: TObject);
begin
// JRA
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.SpeedButton1Click(Sender: TObject);
begin
ArtistSrchField.hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.Splitter1Moved(Sender: TObject);
begin
oldSplitterWidth := Panel4.Width;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.SrchAlbumItemClick(Sender: TObject);
begin
SrchAlbumItem.Checked := not SrchAlbumItem.Checked;
end;
procedure TMain.SrchArtItemClick(Sender: TObject);
begin
SrchArtItem.Checked := not SrchArtItem.Checked;
end;
procedure TMain.SrchFileItemClick(Sender: TObject);
begin
SrchFileItem.Checked := not SrchFileItem.Checked;
end;
procedure TMain.SrchTitleItemClick(Sender: TObject);
begin
SrchTitleItem.Checked := not SrchTitleItem.Checked;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.StopButtonImgClick(Sender: TObject);
begin
stopClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.StopButtonImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
StopButtonImg.Picture.LoadFromFile(SkinData.stop.Clicked);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.StopButtonImgMouseEnter(Sender: TObject);
begin
StopButtonImg.Picture.LoadFromFile(SkinData.stop.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.StopButtonImgMouseLeave(Sender: TObject);
begin
StopButtonImg.Picture.LoadFromFile(SkinData.stop.Img);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.StopButtonImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
StopButtonImg.Picture.LoadFromFile(SkinData.stop.MouseOver);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TitleTreeClick(Sender: TObject);
begin
ArtistSrchField.Hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function NumericCompare(List: TStringList; Index1, Index2: integer): integer;
var
i1, i2: integer;
begin
try
i1 := StrToInt(List[Index2]);
i2 := StrToInt(List[Index1]);
Result := i2 - i1;
except
Result := 0;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TitleTreeColumnClick(Sender: TObject; Column: TListColumn);
var
sl: TStringList;
//used for sorting
counter, ListitemCount, SubItemsColumnCount, IndexOfCurrentColumn, i: integer;
begin
sl := TStringList.Create;
try
IndexOfCurrentColumn := column.index;
writeln(IndexOfCurrentColumn);
if IndexOfCurrentColumn <> 0 then
begin
ListitemCount := TitleTree.Items.Count;
for counter := 0 to ListitemCount - 1 do
begin
SubItemsColumnCount := titletree.items[counter].subitems.Count;
sl.AddObject(titletree.items[counter].SubItems[IndexOfCurrentColumn - 1],
titletree.items[counter]);
end;
// for i:= 0 to sl.Count-1 do writeln(sl[i]);
if IndexOfCurrentColumn <> 4 then
sl.sort
else
sl.CustomSort(@NumericCompare);
// TitleTree.BeginUpdate;
// TitleTree.Clear;
// TitleTree.Items.
for counter := 0 to ListitemCount - 1 do
begin
titletree.items[counter] := (TListItem(sl.Objects[counter]));
// writeln(sl[counter]);
end;
// TitleTree.EndUpdate;
end;
finally
sl.Free;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TitleTreeDragOver(Sender, Source: TObject; X, Y: integer;
State: TDragState; var Accept: boolean);
begin
{$ifdef LCLGtk}
//Workaround for GTK1.x to reset selected Item while dragging
if title_drag then
begin
TitleTree.Selected := nil;
TitleTree.Items[sourceitem.Index].Selected := True;
end;
{$endif}
Accept := False;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TitleTreeEndDrag(Sender, Target: TObject; X, Y: integer);
begin
title_drag := False;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TitleTreeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
// ensure that the popup menu is only opened when an item is selected
// the menu is reanabled in TMain.TitleTreeSelectItem
{$ifdef LCLQT}//TODO: QT interface doesn't set selected item
TitleTree.Selected := TitleTree.GetItemAt(x, y);
{$endif}
{$ifdef LCLGtk2}//TODO: GTK2 interface doe snot selcte item on right click
if (Button = mbRight) then
TitleTree.Selected := TitleTree.GetItemAt(x, y);
{$endif}
//TODO check titlelist popupmenu on win32
{$ifdef win32}
if (Button = mbRight) and (TitleTree.Selected <> nil) then
TitleTree.PopupMenu.PopUp(self.Left + Panel1.Left + TitleTree.left + X,
self.top + Panel1.Top + TitleTree.top + Y + 50);
{$else}
if (Button = mbRight) and (TitleTree.Selected = nil) then
TitleTree.PopupMenu.AutoPopup := False;
{$endif}
//Enable Dragging
if Button = mbLeft then
begin { only drag if left button pressed }
sourceitem := nil;
sourceitem := TitleTree.GetItemAt(x, y);
if sourceitem <> nil then
TitleTree.BeginDrag(False, 10);
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TitleTreeSelectItem(Sender: TObject; Item: TListItem;
Selected: boolean);
begin
// reanable the popupmenu in case ist was disabled in TMain.TitleTreeMouseDown
TitleTree.PopupMenu.AutoPopup := True;
lblPath.Caption := UTF8Encode(TMediaFileClass(Item.Data).Path);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TitleTreeStartDrag(Sender: TObject; var DragObject: TDragObject);
begin
title_drag := True;
//sourceitem:=TitleTree.Selected;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TrackInfoClick(Sender: TObject);
begin
if (PlayerObj.CurrentTrack) >= 0 then
begin
playlist.selected := playlist.Items[PlayerObj.CurrentTrack];
MenuItem10Click(nil);
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.artisttreemenuPopup(Sender: TObject);
var
MedFileObj: TMediaFileClass;
begin
if ArtistTree.Selected.Level > 0 then
begin
MedFileObj := TMediaFileClass(ArtistTree.Selected.Data);
if MedFileObj.collection = PlayerCol then
Menuitem30.Enabled := False
else
Menuitem30.Enabled := True;
if ArtistTree.Selected.Level = 1 then
begin
if ArtistTree.Selected.ImageIndex = 1 then
begin
MenuItem37.Enabled := False;
rm_artist_playeritem.Enabled := True;
MenuItem30.Enabled := True;
end;
if ArtistTree.Selected.ImageIndex = -1 then
begin
MenuItem37.Enabled := False;
rm_artist_playeritem.Enabled := False;
MenuItem30.Enabled := True;
end;
if ArtistTree.Selected.ImageIndex = 2 then
begin
MenuItem37.Enabled := True;
rm_artist_playeritem.Enabled := False;
MenuItem30.Enabled := False;
end;
if ArtistTree.Selected.ImageIndex = 3 then
begin
MenuItem37.Enabled := True;
rm_artist_playeritem.Enabled := False;
MenuItem30.Enabled := False;
end;
end
else
begin
MenuItem37.Enabled := True;
rm_artist_playeritem.Enabled := True;
MenuItem30.Enabled := True;
end;
if player_connected = False then
begin
MenuItem30.Visible := False;
rm_artist_playeritem.Visible := False;
menuitem37.Visible := False;
space1.Visible := False;
end;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.checkmobileTimer(Sender: TObject);
var
PlayerScanThread: TScanThread;
tmps: string;
begin
if (player_connected = False) and FileExists(CactusConfig.DAPPath + 'cactuslib') then
begin
DebugOut('DAP detected...', 2);
if connectDAP = 0 then
begin
tmps := GetCurrentDir;
// get free memory on player, format string
DebugOut('loaded', 2);
tmps := ByteToFmtString(FreeSpaceOnDAP, 3, 2);
writeln(FreeSpaceOnDAP);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' free';
if CactusConfig.background_scan then
begin
PlayerScanThread := TScanThread.Create(True);
PlayerScanThread.tmpcollection.Assign(PlayerCol);
PlayerScanThread.PTargetCollection := PlayerCol;
PlayerScanThread.Resume;
end;
end
else
begin
checkmobile.Enabled := False;
ShowMessage('Error while opening player device. ' + #10 + #13 +
'Try to scan player again...');
player_connected := True;
end;
end;
Application.ProcessMessages;
if (player_connected = True) and
(FileExists(CactusConfig.DAPPath + 'cactuslib') = False) then
begin
disconnectDAP;
StatusBar1.Panels[1].Text := 'Device disconnected';
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.clearPlayerItemClick(Sender: TObject);
begin
(*if player_connected then begin
res:=MessageDlg('All music files on the player will definitely be removed!!'+#10+#13+' Continue?', mtWarning, mbOKCancel, 0);
if res=mrOK then begin
err:=true
i:= PlayerCol.max_index-1;
repeat begin
err:=DeleteFile(PlayerCol.items[i].path);
if err=true then dec(PlayerCol.max_index); {array length is not shorten here !!}
dec(i);
End;
Until i=0;
If err=false Then ShowMessage('Error while deleting one or more files.'+#10+#13+
' Perhaps no write permission or file doesn''t exist')
End;
End
Else ShowMessage(rsNotConnected);*)
ShowMessage('Not implemented yet!');
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.Menuitem10Click(Sender: TObject);
var
MedFileObj: TMediaFileClass;
begin
if playlist.Selected <> nil then
begin
MedFileObj := TMediaFileClass(Playlist.Selected.Data);
editid3win.display_window(MedFileObj);
Enabled := False;
EditID3win.ShowModal;
Enabled := True;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.clear_listClick(Sender: TObject);
begin
if CactusConfig.StopOnClear then
StopButtonImgClick(Sender);
Playlist.BeginUpdate;
writeln(Playlist.Items.Count);
Playlist.Items.Clear;
writeln('clear');
playlist.Column[0].Caption := rsPlaylist;
PlayerObj.playlist.Clear;
Playlist.EndUpdate;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.filetypeboxChange(Sender: TObject);
begin
srch_buttonClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.libinfoClick(Sender: TObject);
var
z: int64;
s, used: string;
i: integer;
begin
z := 0;
for i := 1 to MediaCollection.ItemCount - 1 do
z := z + MediaCollection.items[i].size;
used := ByteToFmtString(z, 3, 2);
s := IntToStr(MediaCollection.ItemCount);
ShowMessage(s + ' Files in library ' + #10 + ' ' + used + ' of music files');
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.muteClick(Sender: TObject);
var
png: TPortableNetworkGraphic;
begin
if PlayerObj.playing then
begin
PlayerObj.mute;
png := TPortableNetworkGraphic.Create;
if PlayerObj.muted then
png.LoadFromFile(SkinData.DefaultPath + DirectorySeparator +
'icon' +
DirectorySeparator + 'mute2.png')
else
png.LoadFromFile(SkinData.DefaultPath + DirectorySeparator +
'icon' +
DirectorySeparator + 'mute1.png');
mute.Glyph.Assign(png);
png.Free;
end;
end;
procedure TMain.opendirClick(Sender: TObject);
var
i: integer;
begin
SelectDirectoryDialog1.InitialDir := CactusConfig.HomeDir;
Selectdirectorydialog1.title := 'Add Directory...';
if SelectDirectoryDialog1.Execute = True then
begin
for i := 0 to MediaCollection.dirlist.Count - 1 do
begin
if pos(MediaCollection.dirlist[i], SelectDirectoryDialog1.FileName) = 1 then
begin
ShowMessage('Directory ' + SelectDirectoryDialog1.FileName +
' is still part of directorylist');
exit;
end;
end;
Enabled := False;
Application.ProcessMessages;
MediaCollection.add_directory(SelectDirectoryDialog1.FileName);
DebugOutLn('finished scan of ' + Selectdirectorydialog1.Filename, 3);
if MediaCollection.ItemCount > 1 then
begin
Main.ArtistTree.Selected := nil;
update_artist_view;
update_title_view;
end;
Enabled := True;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.openfileClick(Sender: TObject);
var
OpenDialog: TOpenDialog;
begin
OpenDialog := TOpenDialog.Create(self);
OpenDialog.Filter :=
'All supported audio|*.wav;*.mp3;*.ogg;*.wma;*.flac;*.fla|MP3|*.mp3|OGG|*.ogg|WAV|*.wav|WMA|*.wma|FLAC|*.flac;*.fla';
if FileOpneDialogPath <> '' then
OpenDialog.InitialDir := FileOpneDialogPath
else
OpenDialog.InitialDir := CactusConfig.HomeDir;
OpenDialog.FilterIndex := 1;
if Opendialog.Execute = True then
begin
LoadFile(Opendialog.Filename);
FileOpneDialogPath := ExtractFilePath(OpenDialog.FileName);
end;
OpenDialog.Free;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.pauseClick(Sender: TObject);
begin
PlayerObj.pause;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.player_libClick(Sender: TObject);
begin
if playwin.Active then
begin
playwin.hide;
main.Show;
playermode := False;
end
else
begin
playwin.Show;
main.hide;
playermode := True;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistClick(Sender: TObject);
begin
ArtistSrchField.hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistDblClick(Sender: TObject);
begin
playclick(nil);
end;
procedure TMain.playlistDragDrop(Sender, Source: TObject; X, Y: integer);
var
Targetitem, tmpitem: TListItem;
sourceNode: TTreeNode;
ind: integer;
MedFileObj: TMediaFileClass;
begin
if not NetworkMode then
begin
DebugOutLn('ondragdrop', 3);
Targetitem := nil;
try
if Playlist.Items.Count > 0 then
Targetitem := Playlist.GetItemAt(x, y);
except
Targetitem := nil;
end;
if Playlist.Items.Count = 0 then
Targetitem := nil;
if Targetitem <> nil then
DebugOutLn(Targetitem.Index, 3)
else
DebugOutLn('TARGET NIL', 3);
if title_drag then
begin
title_drag := False;
MedFileObj := TMediaFileClass(sourceitem.Data);
tmpitem := TListItem.Create(Playlist.Items);
if (MedFileObj.Artist <> '') or (MedFileObj.Title <> '') then
begin
tmpitem.Caption := MedFileObj.Artist + ' - ' + MedFileObj.Title;
end
else
tmpitem.Caption := ExtractFileName(MedFileObj.Path);
tmpitem.Data := MedFileObj;
if (Targetitem <> nil) and (Targetitem.Index < Playlist.Items.Count - 1) and
(Playlist.Items.Count > 0) then
begin
ind := Targetitem.Index;
Playlist.Items.InsertItem(tmpitem, ind + 1);
PlayerObj.Playlist.insert(tmpitem.Index + 1, MedFileObj);
end
else
begin
Playlist.Items.AddItem(tmpitem);
PlayerObj.playlist.add(MedFileObj);
end;
sourceitem := nil;
if not PlayerObj.playing and (CactusConfig.AutostartPlay) and
(Playlist.Items.Count = 1) then
playClick(self);
end;
if artist_drag then
begin
artist_drag := False;
sourceNode := ArtistTree.Selected;
if (Targetitem <> nil) and (Targetitem.Index < Playlist.Items.Count - 1) and
(Playlist.Items.Count > 0) then
artist_to_playlist_at(Targetitem.Index + 1)
else
artist_to_playlist;
end;
if playlist_drag then
begin
playlist_drag := False;
sourceitem := Playlist.Selected;
DebugOutLn('playlist_Drag', 3);
if (sourceitem <> nil) and (Targetitem <> sourceitem) then
begin
ind := sourceitem.Index;
DebugOutLn('OK', 3);
tmpitem := TListItem.Create(Playlist.Items);
tmpitem.Assign(sourceitem);
if (Targetitem <> nil) and (Targetitem.Index < Playlist.Items.Count - 1) then
begin
Playlist.Items.InsertItem(tmpitem, Targetitem.Index + 1);
sourceitem.Delete;
if ind > tmpitem.Index - 1 then
PlayerObj.Playlist.move(ind, tmpitem.Index)
else
PlayerObj.Playlist.move(ind, tmpitem.Index);
DebugOutLn('MOVE', 3);
end
else
begin
Playlist.Items.AddItem(tmpitem);
sourceitem.Delete;
PlayerObj.Playlist.move(ind, tmpitem.Index);
DebugOutLn('ADD', 3);
end;
end;
end;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistDragOver(Sender, Source: TObject; X, Y: integer;
State: TDragState; var Accept: boolean);
begin
{$ifdef LCLGtk}
//Workaround for GTK1.x to reset selected Item while dragging
DebugOutLn('gtk1', 5);
if playlist_drag then
begin
playlist.Selected := nil;
playlist.Items[sourceitem.Index].Selected := True;
end;
{$endif}
accept := True;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistEndDrag(Sender, Target: TObject; X, Y: integer);
var
tmplitem: TListItem;
begin
playlist_drag := False;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistKeyDown(Sender: TObject; var Key: word;
Shift: TShiftState);
var
tempitem: TListItem;
i: integer;
begin
DebugOutLn('Playlist keypress event: Keycode ', 2);
writeln(key);
case key of
// Key Ctrl
17: ctrl_pressed := True;
// Key UP
38: if playlist.Selected.Index > 0 then
begin
i := playlist.Selected.Index;
DebugOutLn(i, 2);
if ctrl_pressed then
begin
tempitem := playlist.selected;
PlayerObj.playlist.move(i, i - 1);
playlist.items[i] := playlist.items[i - 1];
playlist.items[i - 1] := tempitem;
Playlist.SetFocus;
playlist.items[i].Selected := False;
playlist.items[i - 1].Selected := True;
//tempitem.MakeVisible(true);
end;
writeln(playlist.Selected.Index);
end;
// Key DOWN
40: if playlist.Selected.Index < playlist.items.Count - 1 then
begin
i := playlist.Selected.Index;
DebugOutLn(i, 2);
if ctrl_pressed then
begin
tempitem := playlist.selected;
PlayerObj.playlist.move(i, i + 1);
playlist.items[i] := playlist.items[i + 1];
playlist.items[i + 1] := tempitem;
Playlist.SetFocus;
playlist.items[i].Selected := False;
playlist.items[i + 1].Selected := True;
//tempitem.MakeVisible(true);
end;
DebugOutLn(playlist.Selected.Index, 2);
end;
// Key Del
46: MenuItem3Click(nil);
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistKeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
begin
if key = 17 then
ctrl_pressed := False;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
var
tempitem: TListItem;
begin
// ensure that the popup menu is only opened when an item is selected
// the menu is reanabled in TMain.playlistSelectItem
{$ifdef LCLQT}//TODO: QT interface doesn't set selected item
Playlist.Selected := Playlist.GetItemAt(x, y);
{$endif}
{$ifdef LCLGtk2}//TODO: GTK2 interface doe snot selcte item on right click
if (Button = mbRight) then
Playlist.Selected := Playlist.GetItemAt(x, y);
{$endif}
{$ifdef win32}
if (Button = mbRight) and (Playlist.Selected <> nil) then
Playlist.PopupMenu.PopUp(self.Left + panel4.Width + Panel3.Left + Playlist.left + X + 10,
self.top + Panel3.Top + Playlist.top + Y + 50);
{$else}
if (Button = mbRight) and (playlist.Selected = nil) then
playlist.PopupMenu.AutoPopup := False;
{$endif}
//Enable Dragging
if Button = mbLeft then
begin { only drag if left button pressed }
sourceitem := nil;
sourceitem := Playlist.GetItemAt(x, y);
if sourceitem <> nil then
Playlist.BeginDrag(False, 10);
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistSelectItem(Sender: TObject; Item: TListItem;
Selected: boolean);
begin
// reanable the popupmenu in case ist was disabled in TMain.playlistMouseDown
playlist.PopupMenu.AutoPopup := True;
if (Item.Data <> nil) then
begin
lblPath.Caption := UTF8Encode(TMediaFileClass(Item.Data).Path);
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playlistStartDrag(Sender: TObject; var DragObject: TDragObject);
begin
playlist_drag := True;
DebugOutLn('playlist drag', 3);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.playtimerStartTimer(Sender: TObject);
var
MedFileObj: TMediaFileClass;
i: integer;
begin
if PlayerObj.PlaybackMode = FILE_MODE then
begin
CoverFound := False;
LoopCount := 0;
i := PlayerObj.CurrentTrack;
MedFileObj := TMediaFileClass(playlist.Items[PlayerObj.CurrentTrack].Data);
if (MedFileObj.album <> '') then
begin
MedFileObj.CoverPath := CactusConfig.GetCoverPath(MedFileObj.GetCoverFile);
if (FileExists(MedFileObj.CoverPath) = False) then
begin
CoverImage.Picture.Clear;
if (CactusConfig.CoverDownload) then
begin
LastFMAPI := TLastfmAPIObject.Create;
if CactusConfig.CoverSize = 'large' then
LastFMAPI.CoverSize := ExtralargeImage
else
LastFMAPI.CoverSize := LargeImage;
LastFMAPI.album_downloadCover(MedFileObj.Artist,
MedFileObj.Album, MedFileObj.CoverPath);
end;
end
else
begin
try
CoverImage.Picture.LoadFromFile(MedFileObj.CoverPath);
playwin.AlbumCoverImg.Picture.LoadFromFile(MedFileObj.CoverPath);
except
DebugOutLn('EXCEPTION', 3);
end;
CoverFound := True;
end;
end
else
CoverImage.Picture.Clear;
//CoverImage.Picture.LoadFromFile(DataPrefix+'tools'+DirectorySeparator+'cactus-logo-small.png');
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ArtistTreeDblClick(Sender: TObject);
var
StreamInfoObj: TStreamInfoItemClass;
begin
if LibraryMode or DeviceMode then
begin
if (ArtistTree.Selected <> nil) and (ArtistTree.Selected.Level > 0) then
artist_to_playlist;
end;
if NetworkMode then
begin
if (ArtistTree.Selected <> nil) and (ArtistTree.Selected.Level > 0) then
begin
StatusBar1.Panels[0].Text := 'Buffering stream...';
StreamInfoObj := TStreamInfoItemClass(ArtistTree.Selected.Data);
writeln(PlayerObj.play(StreamInfoObj.URL));
current_title_edit.Text := 'Playing radio stream...';
current_title_edit1.Text := StreamInfoObj.Name;
playtimer.Enabled := True;
end;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ArtistTreeEndDrag(Sender, Target: TObject; X, Y: integer);
begin
artist_drag := False;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ArtistTreeClick(Sender: TObject);
begin
ArtistSrchField.Hide;
// if ArtistTree.Selected<>nil then update_title_view;
end;
procedure TMain.ApplicationProperties1Minimize(Sender: TObject);
begin
Application.QueueAsyncCall(@MinimizeMe, 0);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ArtistTreeKeyUp(Sender: TObject; var Key: word;
Shift: TShiftState);
var
b: byte;
c: char;
i: integer;
begin
writeln(key);
b := key;
c := char(b);
case key of
45: for i := 0 to ArtistTree.Items.Count - 1 do
if ArtistTree.Items[i].Level = 0 then
ArtistTree.Items[i].Expanded := False;
43: for i := 0 to ArtistTree.Items.Count - 1 do
if ArtistTree.Items[i].Level = 0 then
ArtistTree.Items[i].Expanded := True;
27: ArtistSrchField.Hide;
13: ArtistSrchField.Hide;
65..255:
begin
if not ArtistSrchField.Visible then
begin
ArtistSrchField.Top := main.Height - 120;
ArtistSrchField.Left := Panel4.Width - 155;
ArtistSrchField.Show;
artistsearch.Text := c;
artistsearch.SetFocus;
artistsearch.SelStart := 1;
artistsearch.SelLength := 0;
end;
i := 0;
repeat
Inc(i)
until ((pos(lowercase(artistsearch.Text),
lowercase(ArtistTree.Items[i].Text)) = 1) and
(ArtistTree.Items[i].Level = 1)) or (i >= ArtistTree.Items.Count - 1);
if ArtistTree.Items[i].Level > 0 then
begin
ArtistTree.Selected := ArtistTree.Items[i];
if ArtistTree.Selected.AbsoluteIndex < ArtistTree.Items.Count - 10 then
begin
ArtistTree.Items[ArtistTree.Selected.AbsoluteIndex +
9].MakeVisible;
if ArtistTree.Items[ArtistTree.Selected.AbsoluteIndex +
9].Level > 1 then
ArtistTree.Items[ArtistTree.Selected.AbsoluteIndex +
9].Parent.Expanded := False;
end
else
begin
ArtistTree.Items[ArtistTree.Items.Count - 1].MakeVisible;
if ArtistTree.Items[ArtistTree.Items.Count - 1].Level > 1 then
ArtistTree.Items[ArtistTree.Items.Count -
1].Parent.Expanded := False;
end;
end;
end;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.ArtistTreeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
ArtistTree.SetFocus;
// ensure that the popup menu is only opened when an item is selected
if Button = mbRight then
begin
if NetworkMode then
ArtistTree.PopupMenu := NetworktreePopup
else
ArtistTree.PopupMenu := artisttreemenu;
if (ArtistTree.GetNodeAt(X, Y) = nil) then
ArtistTree.PopupMenu.AutoPopup := False
else
ArtistTree.PopupMenu.AutoPopup := True;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem30Click(Sender: TObject);
var
MedColObj: TMediaCollectionClass;
curartist, curalbum, tmps: string;
tmpsize: int64;
MedFileObj: TMediaFileClass;
i: integer;
tsnode: TTreeNode;
begin
tsnode := ArtistTree.Selected;
tmpsize := 0;
if (tsnode <> nil) and (tsnode.level > 0) and player_connected then
begin
MedFileObj := TMediaFileClass(tsnode.Data);
MedColObj := MedFileObj.collection;
curartist := lowercase(MedFileObj.Artist);
i := MedColObj.getTracks(MedFileObj.Artist, MedFileObj.index);
if tsnode.level = 2 then //album
begin
curalbum := lowercase(MedFileObj.album);
repeat
begin
if (lowercase(MedColObj.items[i].album) = curalbum) and
(MedColObj.items[i].action = AREMOVE) then
begin
MedColObj.items[i].action := AONPLAYER;
sizediff := sizediff - MedColObj.items[i].size;
end;
if (lowercase(MedColObj.items[i].album) = curalbum) and
(MedColObj.items[i].action <> AONPLAYER) then
begin
MedColObj.items[i].action := AUPLOAD;
sizediff := sizediff - MedColObj.items[i].size;
end;
i := MedColObj.GetNext;
end;
until i < 0;
end;
if tsnode.level = 1 then //SrchArtItem
begin
repeat
begin
if (MedColObj.items[i].action = AREMOVE) then
begin
MedColObj.items[i].action := AONPLAYER;
sizediff := sizediff - MedColObj.items[i].size;
end;
if (MedColObj.items[i].action <> AONPLAYER) then
begin
MedColObj.items[i].action := AUPLOAD;
sizediff := sizediff - MedColObj.items[i].size;
end;
i := MedColObj.GetNext;
end;
until i < 0;
end;
update_artist_view;
update_title_view;
tmps := ByteToFmtString(FreeSpaceOnDAP + sizediff, 3, 2);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' Free';
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem33Click(Sender: TObject);
var
MedFileObj: TMediaFileClass;
tsnode: TTreeNode;
begin
if ArtistTree.Selected <> nil then
begin
tsnode := ArtistTree.Selected;
MedFileObj := TMediaFileClass(tsnode.Data);
if tsnode.level = 1 then
begin
editid3win.display_window(MedFileObj, ARTIST_MODE);
end;
if tsnode.level = 2 then
begin
editid3win.display_window(MedFileObj, ALBUM_MODE);
end;
EditID3win.ShowModal;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.rm_artist_playeritemClick(Sender: TObject);
var
MedColObj: TMediaCollectionClass;
tmps: string;
MedFileObj: TMediaFileClass;
i, z: integer;
tsnode: TTreeNode;
begin
tsnode := ArtistTree.Selected;
if (tsnode <> nil) and (tsnode.level > 0) and player_connected then
begin
MedFileObj := TMediaFileClass(tsnode.Data);
MedColObj := MedFileObj.collection;
if tsnode.level = 2 then //remove one album
begin
i := PlayerCol.getTracks(MedFileObj.Artist, MedFileObj.Album);
repeat
begin
if PlayerCol.Items[i].Action = AONPLAYER then
begin
PlayerCol.items[i].action := AREMOVE;
for z := 0 to MediaCollection.ItemCount - 1 do
if PlayerCol.items[i].id = MediaCollection.items[z].id then
MediaCollection.items[z].action := AREMOVE;
sizediff := sizediff + PlayerCol.items[i].size;
end;
i := PlayerCol.getNext;
end;
until (i < 0);
end;
if tsnode.level = 1 then //remove the SrchArtItem
begin
i := PlayerCol.getTracks(MedFileObj.Artist);
repeat
begin
if PlayerCol.items[i].action = AONPLAYER then
begin
PlayerCol.items[i].action := AREMOVE;
for z := 0 to MediaCollection.ItemCount - 1 do
if PlayerCol.items[i].id = MediaCollection.items[z].id then
MediaCollection.items[
z].action := AREMOVE;
sizediff := sizediff + PlayerCol.items[i].size;
end;
i := PlayerCol.getNext;
end;
until (i < 0);
end;
update_artist_view;
update_title_view;
tmps := ByteToFmtString(FreeSpaceOnDAP + sizediff, 3, 2);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' Free';
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.searchstrClick(Sender: TObject);
begin
ArtistSrchField.Hide;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.syncplayeritem(Sender: TObject);
var
newfile: string;
n: integer;
ucount, rcount: integer;
bytesneeded: int64;
begin
if player_connected = False then
begin
ShowMessage(rsNotConnected);
exit;
end;
StatusBar1.Panels[1].Text := 'Calculating...';
rcount := 1;
ucount := 1;
bytesneeded := 0;
//Calculation the disk space that has to be available on player
SyncThread := TSyncThread.Create(True);
SyncThread.Target := PlayerCol.savepath;
Enabled := False;
for n := 0 to MediaCollection.ItemCount - 1 do
begin
//search for uploads in mediacollection
if MediaCollection.items[n].action = AUPLOAD then
begin
Inc(ucount);
bytesneeded := bytesneeded + MediaCollection.items[n].size;
if CactusConfig.mobile_subfolders then
begin
if not DirectoryExists(CactusConfig.DAPPath + lowercase(
MediaCollection.items[n].Artist)) then
mkdir(CactusConfig.DAPPath + lowercase(MediaCollection.items[n].Artist));
newfile := CactusConfig.DAPPath + lowercase(
MediaCollection.items[n].Artist) + '/' + ExtractFileName(
MediaCollection.items[n].path);
end
else
newfile := CactusConfig.DAPPath + ExtractFileName(
MediaCollection.items[n].path);
DoDirSeparators(newfile);
SyncThread.copyFile(MediaCollection.items[n].path, newfile);
end;
end;
for n := 0 to PlayerCol.ItemCount - 1 do
begin
//find files to be deleted in playercollection
if PlayerCol.items[n].action = AREMOVE then
begin
Inc(rcount);
bytesneeded := bytesneeded - PlayerCol.items[n].size;
SyncThread.deleteFile(PlayerCol.items[n].path);
DebugOutLn(PlayerCol.items[n].path + ' to be deleted', 2);
end;
end;
Enabled := True;
if FreeSpaceOnDAP < bytesneeded then
begin
//Check if there is enough free disk space on player
ShowMessage('ERROR: Not enough free disk space on mobile device!');
StatusBar1.Panels[1].Text := 'Ready';
SyncThread.Free;
exit;
//Free thread and exit
end;
checkmobile.Enabled := False;
disconnectDAP;
StatusBar1.Panels[1].Text := 'Please Wait...';
SyncThread.Resume;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem3Click(Sender: TObject);
var
s1, s2: string;
i: integer;
begin
if playlist.selected <> nil then
begin
i := playlist.selected.index;
PlayerObj.playlist.remove(i);
Playlist.Selected.Delete;
s1 := IntToStr((PlayerObj.Playlist.TotalPlayTime div 60) mod 60);
s2 := IntToStr((PlayerObj.Playlist.TotalPlayTime div 60) div 60);
playlist.Column[0].Caption :=
rsPlaylist + ' (' + IntToStr(
PlayerObj.Playlist.ItemCount) +
' Files/ ' + s2 + 'h ' + s1 + 'min )';
if (i >= 1) and (i = playlist.items.Count) then
Dec(i);
playlist.selected := playlist.items[i];
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MenuItem22aClick(Sender: TObject);
begin
if PlayerObj.playing then
artist_to_playlist_at(PlayerObj.CurrentTrack + 1)
else
artist_to_playlist;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.RemoveClick(Sender: TObject);
begin
MediaCollection.Clear;
TitleTree.Items.Clear;
ArtistTree.Items.Clear;
Playlist.Items.Clear;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.QuitItemClick(Sender: TObject);
begin
Main.Close;
Application.ProcessMessages;
// halt;
Application.Terminate;
// Application.Free;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.MoveNode(TargetNode, SourceNode: TTreeNode);
var
nodeTmp: TTreeNode;
begin
{ with Selecttree do
begin
nodeTmp := Items.AddChild(TargetNode,SourceNode.Text);
for i := 0 to SourceNode.Count -1 do
begin
MoveNode(nodeTmp,SourceNode.items[i]);
end;
end;}
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.titlelistmenuPopup(Sender: TObject);
var
MedFileObj: TMediaFileClass;
begin
writeln('titletree popupmenu');
if TitleTree.Selected <> nil then
begin
MedFileObj := TMediaFileClass(TitleTree.Selected.Data);
// Menuitem16.ImageIndex:=1;
if MedFileObj.collection = PlayerCol then
begin
Menuitem16.Enabled := False;
Menuitem14.Enabled := True;
end
else
begin
Menuitem16.Enabled := False;
//upload
Menuitem14.Enabled := False;
//remove
if MedFileObj.action = -1 then
begin
Menuitem16.Enabled := True;
end;
if MedFileObj.action = 1 then
begin
Menuitem14.Enabled := True;
end;
end;
if player_connected = False then
begin
MenuItem16.Visible := False;
menuitem14.Visible := False;
menuitem20.Visible := False;
menuitem11.Visible := False;
end;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.toggle_playpause(Sender: TObject);
begin
if PlayerObj.playing then
pauseClick(nil)
else
playClick(nil);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.trackbarMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
playtimer.Enabled := False;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.trackbarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
var
k: real;
i: integer;
begin
k := (x * 100) / trackbar.Width;
i := round(k);
PlayerObj.set_fileposition(i);
trackbar.Position := i;
if PlayerObj.playing then
playtimer.Enabled := True;
end;
procedure TMain.TrayIconClick(Sender: TObject);
begin
if not Visible then
begin
Show;
BringToFront;
end
else
begin
Hide;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.undoSyncItemClick(Sender: TObject);
var
tmps: string;
i: integer;
begin
begin
for i := 1 to MediaCollection.ItemCount - 1 do
begin
if MediaCollection.items[i].action = AUPLOAD then
MediaCollection.items[i].action :=
ANOTHING
;
if MediaCollection.items[i].action = AREMOVE then
MediaCollection.items[i].action :=
AONPLAYER
;
end;
for i := 1 to PlayerCol.ItemCount - 1 do
begin
if PlayerCol.items[i].action = AUPLOAD then
PlayerCol.items[i].action := ANOTHING;
if PlayerCol.items[i].action = AREMOVE then
PlayerCol.items[i].action := AONPLAYER;
end;
update_artist_view;
update_title_view;
sizediff := 0;
tmps := ByteToFmtString(FreeSpaceOnDAP, 3, 2);
StatusBar1.Panels[1].Text := 'Device connected ' + tmps + ' Free';
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TitleTreeDblClick(Sender: TObject);
begin
Application.ProcessMessages;
title_to_playlist;
Application.ProcessMessages;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure title_to_playlist_at(index: integer);
var
tsnode: TListitem;
listitem: TListitem;
MedFileObj: TMediaFileClass;
begin
tsnode := main.TitleTree.Selected;
if (tsnode <> nil) and (tsnode.ImageIndex <> 4) then
begin
if main.Playlist.Items.Count = 0 then
begin
title_to_playlist;
exit;
end;
MedFileObj := TMediaFileClass(tsnode.Data);
PlayerObj.playlist.Insert(index, MedFileObj);
ListItem := Main.Playlist.Items.Insert(index);
listitem.Data := MedFileObj;
listitem.MakeVisible(False);
if MedFileObj.title <> '' then
ListItem.Caption := MedFileObj.Artist + ' - ' + MedFileObj.title
else
ListItem.Caption := extractfilename(MedFileObj.path);
end;
main.playlist.Column[0].Caption :=
rsPlaylist + ' (' + IntToStr(
PlayerObj.playlist.ItemCount) +
' Files/ ' + PlayerObj.Playlist.TotalPlayTimeStr + ')';
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure title_to_playlist;
var
tsnode: TListitem;
listitem: TListitem;
MedFileObj: TMediaFileClass;
begin
tsnode := main.TitleTree.Selected;
DebugOutLn('title to playlist', 5);
if (tsnode <> nil) and (tsnode.ImageIndex <> 4) then
begin
DebugOutLn('title to playlist2', 5);
MedFileObj := TMediaFileClass(tsnode.Data);
PlayerObj.playlist.add(MedFileObj);
ListItem := Main.Playlist.Items.Add;
listitem.Data := MedFileObj;
listitem.MakeVisible(False);
// listitem.Focused:=true;
if MedFileObj.title <> '' then
ListItem.Caption := MedFileObj.Artist + ' - ' + MedFileObj.title
else
ListItem.Caption := extractfilename(MedFileObj.path);
if not PlayerObj.playing and CactusConfig.AutostartPlay and
(main.Playlist.Items.Count = 1) then
begin
DebugOutLn('title to playlist3', 5);
main.Playlist.Selected := Main.Playlist.Items[0];
DebugOutLn(Main.Playlist.Selected.Caption, 3);
Main.playClick(main);
end;
end;
main.playlist.Column[0].Caption :=
rsPlaylist + ' (' + IntToStr(
PlayerObj.playlist.ItemCount) +
' Files/ ' + PlayerObj.Playlist.TotalPlayTimeStr + ')';
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure artist_to_playlist_at(index: integer);
var
tsnode: TTreeNode;
curartist, curalbum: string;
Listitem: TListitem;
album_mode: boolean;
MedColObj: TMediaCollectionClass;
MedFileObj: TMediaFileClass;
z: integer;
begin
tsnode := Main.ArtistTree.Selected;
if main.Playlist.Items.Count = 0 then
begin
artist_to_playlist;
exit;
end;
if (tsnode <> nil) and (tsnode.Level > 0) then
begin
if tsnode.level < 2 then
album_mode := False
else
album_mode := True;
MedFileObj := TMediaFileClass(tsnode.Data);
MedColObj := MedFileObj.Collection;
curartist := lowercase(MedFileObj.Artist);
curalbum := lowercase(MedFileObj.Album);
z := MedColObj.getTracks(MedFileObj.Artist, MedFileObj.index);
repeat
begin
DebugOutLn(MedColObj.items[z].title, 3);
if (album_mode = False) or ((album_mode = True) and
(lowercase(MedColObj.items[z].album) = curalbum)) then
begin
PlayerObj.playlist.insert(index, MedColObj.items[z]);
ListItem := Main.Playlist.Items.Insert(index);
Inc(index);
listitem.Data := MedColObj.items[z];
// Listitem.Focused:=true;
if MedColObj.items[z].title <> '' then
ListItem.Caption := MedColObj.items[z].Artist +
' - ' +
MedColObj.items[z].
title
else
ListItem.Caption := extractfilename(MedColObj.items[z].path);
end;
z := MedColObj.GetNext;
end;
until z < 0;
Listitem.MakeVisible(False);
end;
main.playlist.Column[0].Caption :=
rsPlaylist + ' (' + IntToStr(
PlayerObj.playlist.ItemCount) +
' Files/ ' + PlayerObj.Playlist.TotalPlayTimeStr + ' )';
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure artist_to_playlist;
var
tsnode: TTreeNode;
curartist, curalbum: string;
Listitem: TListitem;
album_mode: boolean;
MedColObj: TMediaCollectionClass;
MedFileObj: TMediaFileClass;
z, oldcount: integer;
begin
//TODO: add album to playlist sorted by TRACK
tsnode := Main.ArtistTree.Selected;
if (tsnode <> nil) and (tsnode.Level > 0) then
begin
oldcount := main.Playlist.Items.Count;
if tsnode.level < 2 then
album_mode := False
else
album_mode := True;
MedFileObj := TMediaFileClass(tsnode.Data);
MedColObj := MedFileObj.Collection;
curartist := lowercase(MedFileObj.Artist);
curalbum := lowercase(MedFileObj.Album);
z := MedColObj.getTracks(MedFileObj.Artist, MedFileObj.index);
repeat
begin
DebugOutLn(MedColObj.items[z].title, 3);
if (album_mode = False) or ((album_mode = True) and
(lowercase(MedColObj.items[z].album) = curalbum)) then
begin
PlayerObj.playlist.add(MedColObj.items[z]);
ListItem := Main.Playlist.Items.Add;
listitem.Data := MedColObj.items[z];
// Listitem.Focused:=true;
if MedColObj.items[z].title <> '' then
ListItem.Caption := MedColObj.items[z].Artist +
' - ' +
MedColObj.items[z].
title
else
ListItem.Caption := extractfilename(MedColObj.items[z].path);
end;
z := MedColObj.GetNext;
end;
until z < 0;
Listitem.MakeVisible(False);
if CactusConfig.AutostartPlay and (oldcount = 0) and
(main.Playlist.Items.Count > 0) then
begin
main.Playlist.Selected := Main.Playlist.Items[0];
Main.playClick(main);
end;
end;
main.playlist.Column[0].Caption :=
rsplaylist + ' (' + IntToStr(
PlayerObj.playlist.ItemCount) +
' Files/ ' + PlayerObj.Playlist.TotalPlayTimeStr + ' )';
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure update_title_view;
var
tsnode: TTreeNode;
curartist, curalbum: string;
Listitem: TListItem;
album_mode: boolean;
MedColObj: TMediaCollectionClass;
MedFileObj: TMediaFileClass;
i: integer;
begin
tsnode := Main.ArtistTree.Selected;
main.StatusBar1.Panels[0].Text := 'Please wait... updating...';
DebugOutLn('', 2);
DebugOut('## update title view...', 2);
main.TitleTree.Selected := nil;
Main.TitleTree.Clear;
{$ifndef LCLGtk2}
Main.TitleTree.BeginUpdate;
{$endif}
{$ifdef LCLGtk2}
DebugOut(' <TODO: BeginUpdate/EndUpdate disabled in GTK2 due to some bugs in LCL> ',
2);
//TODO: BeginUpdate/EndUpdate disabled in GTK2 due to some bugs in LCL
{$endif}
DebugOut(' cleared items... ', 2);
if (tsnode <> nil) and (tsnode.level > 0) then
begin
if tsnode.level = 2 then
album_mode := True
else
album_mode := False;
MedFileObj := TMediaFileClass(tsnode.Data);
MedColObj := MedFileObj.Collection;
curartist := lowercase(MedFileObj.Artist);
curalbum := lowercase(MedFileObj.album);
DebugOut(curartist, 2);
i := MedColObj.getTracks(MedFileObj.Artist, 0{MedFileObj.index});
repeat
begin
if (album_mode = False) or ((album_mode) and
(curalbum = lowercase(MedColObj.items[i].album))) then
begin
ListItem := Main.Titletree.Items.Add;
MedColObj.items[i].index := i;
listitem.Data := MedColObj.items[i];
Listitem.ImageIndex := MedColObj.items[i].action;
Listitem.Caption := '';
if MedColObj.items[i].title <> '' then
ListItem.SubItems.Add(MedColObj.items[i].Artist)
else
ListItem.SubItems.Add(SysToUTF8(ExtractFileName(MedColObj.items[i].path)));
ListItem.SubItems.Add((MedColObj.items[i].title));
ListItem.SubItems.Add((MedColObj.items[i].album));
ListItem.SubItems.Add(MedColObj.items[i].track);
ListItem.SubItems.Add(ID3Genre[MedColObj.items[i].GenreID]);
ListItem.SubItems.Add(SysToUTF8(ExtractFileName(MedColObj.items[i].Path)));
ListItem.SubItems.Add(MedColObj.items[i].playtime);
end;
i := MedColObj.GetNext;
end;
until (i < 0);
end;
if CactusConfig.SortAlbumByTrack and album_mode then
main.TitleTreeColumnClick(main, main.TitleTree.Column[4]);
DebugOutLn(' finished title view ##', 2);
{$ifndef LCLGtk2}
Main.TitleTree.EndUpdate;
{$endif}
main.StatusBar1.Panels[0].Text := 'Ready.';
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.update_playlist;
var
MedfileObj: TMediaFileClass;
i: integer;
begin
for i := 0 to PlayerObj.Playlist.ItemCount - 1 do
begin
MedfileObj := TMediaFileClass(playlist.Items[i].Data);
PlayerObj.Playlist.Items[i].update(MedfileObj);
if MedfileObj.title <> '' then
playlist.Items[i].Caption := MedfileObj.Artist + ' - ' + MedfileObj.title
else
playlist.Items[i].Caption := extractfilename(MedfileObj.path);
end;
update_player_display;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.disconnectDAP;
var
i: integer;
begin
if player_connected then
begin
DebugOutLn('### Disconnect DAP ###', 2);
Enabled := False;
i := 0;
while i < playlist.Items.Count do
begin
if TMediaFileClass(playlist.Items[i].Data).collection = PlayerCol then
begin
PlayerObj.playlist.remove(i);
if PlayerObj.Playlist.ItemCount <> 0 then
Playlist.Items[i].Delete;
Dec(i);
end;
Inc(i);
end;
FreeAndNil(PlayerCol);
player_connected := False;
for i := 1 to MediaCollection.ItemCount - 1 do
MediaCollection.items[i].action := -1;
ArtistTree.Selected := nil;
Enabled := True;
update_artist_view;
update_title_view;
end;
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function TMain.connectDAP: byte;
var
i, z: integer;
begin
Result := 255;
PlayerCol := TMediaCollectionClass.Create;
PlayerCol.PathFmt := FRelative;
DebugOutLn('### ConnectDAP ###', 2);
if PlayerCol.LoadFromFile(CactusConfig.DAPPath + 'cactuslib') = True then
begin
sizediff := 0;
for i := 0 to PlayerCol.ItemCount - 1 do
begin
z := 0;
PlayerCol.items[i].action := AONPLAYER;
while z < MediaCollection.ItemCount - 1 do
begin
if MediaCollection.items[z].id = PlayerCol.items[i].id then
begin
MediaCollection.items[z].action := AONPLAYER;
z := MediaCollection.ItemCount - 1;
end;
Inc(z);
end;
end;
player_connected := True;
update_artist_view;
update_title_view;
checkmobile.Enabled := True;
Result := 0;
end
else
FreeAndNil(PlayerCol);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TMain.TestPlugin1(Sender: TObject);
var
tt: TCJ_Signals;
begin
//TestPluginI :=CJ_Interface.GetMenu.Add(-CJ_MAINMENU_PLUGINS, 'Hello World...', @SayHello);
//TestPluginI :=CJ_Interface.GetMenu.Add(-CJ_MAINMENU_ROOT, 'Hello World...', @SayHello);
TestPluginI := CJ_Interface.GetMenu.Add(-CJ_TRAYMENU_ROOT,
'Hello World...', @SayHello);
tt := CJ_Interface.GetSignals;
if tt <> nil then
begin
tt.Connect(@SayMsgHello, 1);
tt.Connect(@SayMsgHello2, 1);
tt.Connect(@SayMsgHello, 1); //Test for no insertion of this....
end;
end;
procedure TMain.SayHello(Sender: TCJ_MenuItem);
begin
Dialogs.MessageDlg('Plugins', 'Hello World Click', mtInformation, [mbOK], 0);
CJ_Interface.GetMenu.Remove(TestPluginI);
end;
function TMain.SayMsgHello(var Message: TMessage): boolean;
begin
Dialogs.MessageDlg('Plugins', 'Hello World From Messages...' +
#13#10 + IntToStr(Message.WParam) + ' ' + IntToStr(Message.LParam), mtInformation, [mbOK], 0);
Result := True;
end;
function TMain.SayMsgHello2(var Message: TMessage): boolean;
begin
Dialogs.MessageDlg('Plugins', 'Hello World 2 From Messages...' +
#13#10 + IntToStr(Message.WParam) + ' ' + IntToStr(Message.LParam), mtInformation, [mbOK], 0);
Result := True;
end;
procedure TMain.Button2Click(Sender: TObject);
var
msgHandled: boolean;
begin
CJ_Interface.GetSignals.Signal(1, 24, 50, msgHandled);
end;
end.