{ Main unit for Cactus Jukebox written by Sebastian Kraft, 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(' ', 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.