From 864081102a5f252415f41950b3039a896b4ae9c5 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 8 Oct 2012 18:43:29 +0000 Subject: Awkwars's plugins - welcome to our trunk git-svn-id: http://svn.miranda-ng.org/main/trunk@1822 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Watrack/stat/default.tmpl | 89 +++++ plugins/Watrack/stat/report.inc | 315 +++++++++++++++++ plugins/Watrack/stat/stat.rc | 50 +++ plugins/Watrack/stat/stat.res | Bin 0 -> 3320 bytes plugins/Watrack/stat/stat_data.inc | 16 + plugins/Watrack/stat/stat_dlg.inc | 223 +++++++++++++ plugins/Watrack/stat/stat_opt.inc | 62 ++++ plugins/Watrack/stat/stat_rc.inc | 29 ++ plugins/Watrack/stat/stat_vars.inc | 21 ++ plugins/Watrack/stat/statlog.pas | 650 ++++++++++++++++++++++++++++++++++++ plugins/Watrack/stat/wat_report.ico | Bin 0 -> 1406 bytes 11 files changed, 1455 insertions(+) create mode 100644 plugins/Watrack/stat/default.tmpl create mode 100644 plugins/Watrack/stat/report.inc create mode 100644 plugins/Watrack/stat/stat.rc create mode 100644 plugins/Watrack/stat/stat.res create mode 100644 plugins/Watrack/stat/stat_data.inc create mode 100644 plugins/Watrack/stat/stat_dlg.inc create mode 100644 plugins/Watrack/stat/stat_opt.inc create mode 100644 plugins/Watrack/stat/stat_rc.inc create mode 100644 plugins/Watrack/stat/stat_vars.inc create mode 100644 plugins/Watrack/stat/statlog.pas create mode 100644 plugins/Watrack/stat/wat_report.ico (limited to 'plugins/Watrack/stat') diff --git a/plugins/Watrack/stat/default.tmpl b/plugins/Watrack/stat/default.tmpl new file mode 100644 index 0000000000..0e1920fc5d --- /dev/null +++ b/plugins/Watrack/stat/default.tmpl @@ -0,0 +1,89 @@ +const + IntTmpl:PAnsiChar= +''#13#10+ +''#13#10+ +''#13#10+ +'Report on %currenttime%'#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +'

Report


created %currenttime%

'#13#10+ +'%block_freqartist%'#13#10+ +'

Most popular artists:

'#13#10+ +'%start%'#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +'%end%'#13#10+ +'
%num%.%artist%
%count%
'#13#10+ +'%block_end%'#13#10+ +'%block_freqsongs%'#13#10+ +'

Most frequently played songs:

'#13#10+ +'%start%'#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +'%end%'#13#10+ +'
%num%.%artist% - %title% (%album%)
%count%
'#13#10+ +'%block_end%'#13#10+ +'%block_freqalbum%'#13#10+ +'

Most frequently played albums:

'#13#10+ +'%start%'#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +'%end%'#13#10+ +'
%num%.%album%
%count%
'#13#10+ +'%block_end%'#13#10+ +'%block_lastsongs%'#13#10+ +'

Last played songs:

'#13#10+ +'%start%'#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +'%end%'#13#10+ +'
%num%.[%date%]%artist% - %title%
'#13#10+ +'%block_end%'#13#10+ +'%block_songtime%'#13#10+ +'

Longest songs:

'#13#10+ +'%start%'#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +'%end%'#13#10+ +'
%num%.%artist% - %title%
%length%
'#13#10+ +'%block_end%'#13#10+ +'%block_freqpath%'#13#10+ +'

Most frequently used paths:

'#13#10+ +'%start%'#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +''#13#10+ +'%end%'#13#10+ +'
%num%.%path%
%count%
'#13#10+ +'%block_end%'#13#10+ +'

Total played time is:

'#13#10+ +''#13#10+ +''#13#10+ +'
Total logged music time - %totaltime%Total logged music files - %totalfiles%
'#13#10+ +''#13#10+ +'
'#13#10+ +''#13#10+ +''#13#10; diff --git a/plugins/Watrack/stat/report.inc b/plugins/Watrack/stat/report.inc new file mode 100644 index 0000000000..0cd4fcfb22 --- /dev/null +++ b/plugins/Watrack/stat/report.inc @@ -0,0 +1,315 @@ +{$include default.tmpl} +function ReadTemplate(fname:PAnsiChar;var buf:PAnsiChar):integer; +var + f:THANDLE; + size:integer; +begin + if (fname=nil) or (fname^=#0) then + f:=INVALID_HANDLE_VALUE + else + f:=Reset(fname); + if f=THANDLE(INVALID_HANDLE_VALUE) then + result:=0 + else + begin + size:=FileSize(f); + mGetMem(buf,size+1); + buf[size+1]:=#0; + BlockRead(f,buf^,size); + CloseHandle(f); + result:=size; + end; +end; + +function StatOut(report,log,template:PAnsiChar):boolean; + +const + bufsize = 16384; +var + fout:THANDLE; + tt,tf:array [0..15] of AnsiChar; + timebuf:array [0..17] of AnsiChar; // for current date / time + outbuf:PAnsiChar; + outpos:PAnsiChar; + + procedure OutChar(var pc:PAnsiChar); + begin + outpos^:=pc^; + inc(pc); + inc(outpos); + if (outpos-outbuf)=bufsize then + begin + BlockWrite(fout,outbuf^,bufsize); + outpos:=outbuf; + end; + end; + + procedure OutStr(pc:PAnsiChar); + begin + while pc^<>#0 do + OutChar(pc); + end; + + procedure OutputBlock(var start:PAnsiChar;var Root:pCells;asortmode:integer); + const + blocksize = 8192; + var + i,max,cnt,len:integer; + items:cardinal; + Cell:pStatCell; + ls,ls1:array [0..511] of AnsiChar; + block:array [0..blocksize-1] of AnsiChar; + begin + len:=StrIndex(start,'%end%'); + if len=0 then + len:=StrLen(start) + else + dec(len); + if len>6143 then + err('Template block too large'); + + Resort(Root,asortmode); + + case asortmode of + stArtist,stAlbum,stPath: begin + + Cell:=Root^.Cells[0]; + max:=Cell^.Count; + if asortmode=stPath then OnlyPath(ls,Cell^.MFile); // speed optimization + + for i:=0 to Root^.Count-1 do + begin + with Root^.Cells[i]^ do + begin + AltCount:=0; + if asortmode=stArtist then cnt:=lstrcmpia(Cell^.Artist,Artist) + else if asortmode=stAlbum then cnt:=lstrcmpia(Cell^.Album,Album) + else cnt:=lstrcmpia(ls,OnlyPath(ls1,MFile)); + if cnt=0 then + inc(max,Count) + else + begin + Cell^.AltCount:=max; + Cell:=Root^.Cells[i]; + if asortmode=stPath then OnlyPath(ls,Cell^.MFile); // speed optimization + max:=Count; + end; + end; + end; + Cell^.AltCount:=max; + + Resort(Root,stAltCount); + if (asortmode=stAlbum) and (Root^.Cells[0]^.Album^=#0) then + begin + if Root^.Count>1 then + max:=Root^.Cells[1]^.AltCount + else + max:=0; + end + else + max:=Root^.Cells[0]^.AltCount; + end; + stCount: begin + max:=Root^.Cells[0]^.Count; + end; + stLength: begin + max:=Root^.Cells[0]^.Length; + end; + else + max:=1; + end; + + items:=1; + if ReportItems>0 then + for i:=0 to Root^.Count-1 do + begin + with Root^.Cells[i]^ do + begin + if (asortmode=stAlbum) and (Album^=#0) then continue; + case asortmode of + stArtist, + stAlbum, + stPath : cnt:=AltCount; + stCount : cnt:=Count; + stLength: cnt:=Length; + else + cnt:=1; + end; + if cnt=0 then break; + move(start^,block,len); + block[len]:=#0; + StrReplace(block,'%date%' ,ShowTime(ls,LastTime)); + StrReplace(block,'%length%' ,IntToTime(ls,Length)); + StrReplace(block,'%artist%' ,Artist); + StrReplace(block,'%title%' ,Title); + StrReplace(block,'%album%' ,Album); + StrReplace(block,'%file%' ,MFile); + StrReplace(block,'%path%' ,OnlyPath(ls,MFile)); + StrReplace(block,'%num%' ,IntToStr(ls,items)); + StrReplace(block,'%currenttime%',timebuf); + StrReplace(block,'%totaltime%' ,tt); + StrReplace(block,'%totalfiles%' ,tf); + StrReplace(block,'%percent%' ,IntToStr(ls,round(cnt*100/max))); + StrReplace(block,'%count%' ,IntToStr(ls,cnt)); + OutStr(block); + end; + if items=ReportItems then break; + inc(items); + end; + inc(start,len+5); + end; + +var + TmplBuf:PAnsiChar; + ptr:PAnsiChar; + i,j,k:integer; + size:integer; + lsortmode:integer; + MyTime:TSYSTEMTIME; + Root:pCells; + b1,tmp:PAnsiChar; +begin + result:=false; + GetLocalTime(MyTime); + ShowTime(timebuf,PackTime(MyTime)); + + Lock:=true; + Root:=BuildTree(log,b1); + if Root<>nil then + begin + Resort(Root,stArtist); + Lock:=false; + size:=ReadTemplate(template,TmplBuf); + if size=0 then + begin + StrDup(TmplBuf,IntTmpl); + size:=StrLen(IntTmpl); + end; + ptr:=TmplBuf; + fout:=Rewrite(report); + if fout=THANDLE(INVALID_HANDLE_VALUE) then + exit; + mGetMem(outbuf,bufsize); + outpos:=outbuf; + + i:=0; + k:=0; + for j:=0 to Root^.Count-1 do + begin + inc(k); + with Root^.Cells[j]^ do + inc(i,Length*Count); + end; + IntToTime(tt,i); // total time + IntToStr(tf,k); // total files + + lsortmode:=stDate; + while (ptr-TmplBuf)'%') and (ptr^<>#0) do + OutChar(ptr); + if ptr^=#0 then break; + if StrCmp(ptr,'%block_',7)=0 then + begin + if ptr>@TmplBuf then + begin + if (ptr-1)^<' ' then + k:=-1; + end; + inc(ptr,7); + if StrCmp(ptr,'end%',4)=0 then + begin + i:=4; + end + else if StrCmp(ptr,'freqartist%',11)=0 then + begin + lsortmode:=stArtist; + i:=11; + end + else if StrCmp(ptr,'freqsongs%',10)=0 then + begin + lsortmode:=stCount; + i:=10; + end + else if StrCmp(ptr,'freqalbum%',10)=0 then + begin + lsortmode:=stAlbum; + i:=10; + end + else if StrCmp(ptr,'lastsongs%',10)=0 then + begin + lsortmode:=stDate; + i:=10; + end + else if StrCmp(ptr,'songtime%',9)=0 then + begin + lsortmode:=stLength; + i:=9; + end + else if StrCmp(ptr,'freqpath%',9)=0 then + begin + lsortmode:=stPath; + i:=9; + end + else + begin + OutChar(ptr); + continue; + end; + inc(ptr,i); + if k<0 then + begin + while (ptr^<' ') and (ptr^<>#0) do inc(ptr); + k:=0; + end; + if (ReportMask and lsortmode)=0 then + begin + tmp:=StrPos(ptr,'%block_end%'); + if tmp<>nil then + ptr:=tmp+11 + else + break; + end; + end + else if StrCmp(ptr,'%start%',7)=0 then + begin + if ptr>@TmplBuf then + begin + if (ptr-1)^<' ' then + k:=-1; + end; + inc(ptr,7); + if k<0 then + begin + while (ptr^<' ') and (ptr^<>#0) do inc(ptr); + k:=0; + end; + OutputBlock(ptr,Root,lsortmode); + end + else if StrCmp(ptr,'%currenttime%',13)=0 then + begin + inc(ptr,13); + OutStr(timebuf); + end + else if StrCmp(ptr,'%totalfiles%',12)=0 then + begin + inc(ptr,12); + OutStr(tf); + end + else if StrCmp(ptr,'%totaltime%',11)=0 then + begin + inc(ptr,11); + OutStr(tt); + end + else + OutChar(ptr); + end; + BlockWrite(fout,outbuf^,outpos-outbuf); + CloseHandle(fout); + mFreeMem(outbuf); + mFreeMem(TmplBuf); + ClearStatCells(Root); + result:=true; + end; + mFreeMem(b1); +end; diff --git a/plugins/Watrack/stat/stat.rc b/plugins/Watrack/stat/stat.rc new file mode 100644 index 0000000000..9bedcabf3d --- /dev/null +++ b/plugins/Watrack/stat/stat.rc @@ -0,0 +1,50 @@ +#include "stat_rc.inc" + +LANGUAGE 0,0 + +STATS DIALOGEX 0, 0, 304, 226, 0 +STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0 +{ + PUSHBUTTON "Delete", IDC_CLEAR , 242, 11, 56, 14 + LTEXT "Statistic log file", -1 , 16, 17, 148, 12 + EDITTEXT IDC_STATNAME , 6, 29, 214, 14 + PUSHBUTTON "...", IDC_SNBUTTON , 222, 29, 16, 14 + PUSHBUTTON "Sort", IDC_SORTFILE , 242, 29, 56, 14 + RTEXT "Autosort period, days",-1 , 124, 45, 142, 12, SS_CENTERIMAGE + EDITTEXT IDC_AUTOSORT , 270, 45, 28, 12, ES_RIGHT | ES_NUMBER + LTEXT "Report file", -1 , 16, 47, 148, 12 + EDITTEXT IDC_REPNAME , 6, 59, 214, 14 + PUSHBUTTON "...", IDC_RNBUTTON , 222, 59, 16, 14 + PUSHBUTTON "Report", IDC_REPORT , 242, 59, 56, 14 + LTEXT "Template file", -1 , 16, 77, 148, 12 + EDITTEXT IDC_TMPLNAME , 6, 89, 214, 14 + PUSHBUTTON "...", IDC_TNBUTTON , 222, 89, 16, 14 + PUSHBUTTON "Export default", IDC_EXPORTDEF, 242, 89, 56, 14 + + CONTROL "", -1, "STATIC", SS_ETCHEDHORZ, 4, 107, 296, 2 + + GROUPBOX "Show in report", -1, 6, 111, 144, 84 + AUTOCHECKBOX "Freq. songs" , IDC_FREQART , 12, 121, 136, 12, BS_VCENTER + AUTOCHECKBOX "Freq. artists" , IDC_FREQSONG , 12, 133, 136, 12, BS_VCENTER + AUTOCHECKBOX "Freq. album" , IDC_FREQALBUM, 12, 145, 136, 12, BS_VCENTER + AUTOCHECKBOX "Freq. paths" , IDC_FREQPATH , 12, 157, 136, 12, BS_VCENTER + AUTOCHECKBOX "Last played songs", IDC_LASTSONG , 12, 169, 136, 12, BS_VCENTER + AUTOCHECKBOX "Song time" , IDC_SONGTIME , 12, 181, 136, 12, BS_VCENTER + + GROUPBOX "Sort log file", -1, 154, 111, 144, 84 + AUTORADIOBUTTON "by Title" , IDC_BYTITLE , 158, 121, 136, 12, NOT WS_TABSTOP + AUTORADIOBUTTON "by Date" , IDC_BYDATE , 158, 133, 136, 12, NOT WS_TABSTOP + AUTORADIOBUTTON "by Count" , IDC_BYCOUNT , 158, 145, 136, 12, NOT WS_TABSTOP + AUTORADIOBUTTON "by Path" , IDC_BYPATH , 158, 157, 136, 12, NOT WS_TABSTOP + AUTORADIOBUTTON "by Length" , IDC_BYLENGTH , 158, 169, 136, 12, NOT WS_TABSTOP + AUTOCHECKBOX "Reverse order", IDC_DIRECTION, 158, 181, 136, 12, BS_VCENTER | BS_MULTILINE + + LTEXT "Report Items", -1, 38, 208, 112, 12, SS_CENTERIMAGE + EDITTEXT IDC_ITEMS, 6, 208, 28, 12, ES_RIGHT | ES_NUMBER + AUTOCHECKBOX "Open report" , IDC_RUNREPORT, 154, 196, 146, 12, BS_VCENTER + AUTOCHECKBOX "Add report file ext.", IDC_ADDEXT , 154, 208, 146, 12, BS_VCENTER | BS_MULTILINE +} + +BTN_REPORT ICON "wat_report.ico" diff --git a/plugins/Watrack/stat/stat.res b/plugins/Watrack/stat/stat.res new file mode 100644 index 0000000000..eca192d5ba Binary files /dev/null and b/plugins/Watrack/stat/stat.res differ diff --git a/plugins/Watrack/stat/stat_data.inc b/plugins/Watrack/stat/stat_data.inc new file mode 100644 index 0000000000..ec539a3ecd --- /dev/null +++ b/plugins/Watrack/stat/stat_data.inc @@ -0,0 +1,16 @@ +{statistic data} +const + MenuReportPos = 500050001; + +const + smDirect = 1; + smReverse = 2; + +const + stArtist = $0001; + stCount = $0002; + stPath = $0004; + stDate = $0008; + stLength = $0010; + stAltCount = $0020; + stAlbum = $0040; diff --git a/plugins/Watrack/stat/stat_dlg.inc b/plugins/Watrack/stat/stat_dlg.inc new file mode 100644 index 0000000000..64a9b97f7c --- /dev/null +++ b/plugins/Watrack/stat/stat_dlg.inc @@ -0,0 +1,223 @@ +{Statistic Dialog} + +{$include stat_rc.inc} + +procedure SetReportMask(Dlg:hwnd); +begin + ReportMask:=0; + if IsDlgButtonChecked(Dlg,IDC_FREQART)=BST_CHECKED then + ReportMask:=ReportMask or stArtist; + if IsDlgButtonChecked(Dlg,IDC_FREQSONG)=BST_CHECKED then + ReportMask:=ReportMask or stCount; + if IsDlgButtonChecked(Dlg,IDC_FREQPATH)=BST_CHECKED then + ReportMask:=ReportMask or stPath; + if IsDlgButtonChecked(Dlg,IDC_LASTSONG)=BST_CHECKED then + ReportMask:=ReportMask or stDate; + if IsDlgButtonChecked(Dlg,IDC_SONGTIME)=BST_CHECKED then + ReportMask:=ReportMask or stLength; + if IsDlgButtonChecked(Dlg,IDC_FREQALBUM)=BST_CHECKED then + ReportMask:=ReportMask or stAlbum; +end; + +procedure EnableItems(Dlg:hwnd;enable:boolean); +begin + EnableWindow(GetDlgItem(Dlg,IDC_STATNAME) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_SNBUTTON) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_SORTFILE) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_REPORT) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_CLEAR) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_BYTITLE) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_BYDATE) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_BYCOUNT) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_BYPATH) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_BYLENGTH) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_DIRECTION),enable); + EnableWindow(GetDlgItem(Dlg,IDC_REPNAME) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_RNBUTTON) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_ITEMS) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_FREQART) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_FREQSONG) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_FREQALBUM),enable); + EnableWindow(GetDlgItem(Dlg,IDC_FREQPATH) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_LASTSONG) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_SONGTIME) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_RUNREPORT),enable); + EnableWindow(GetDlgItem(Dlg,IDC_ADDEXT) ,enable); + EnableWindow(GetDlgItem(Dlg,IDC_AUTOSORT) ,enable); +end; + +function DlgProcOptions(Dialog:HWnd; hMessage:dword;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall; +const + changed:boolean=false; +var + buf,buf1:array [0..511] of AnsiChar; + tmp:longbool; + p:PAnsiChar; + f:THANDLE; +begin + result:=0; + case hMessage of + WM_INITDIALOG: begin + TranslateDialogDefault(Dialog); + SetDlgItemInt(Dialog,IDC_ITEMS,ReportItems,false); + if ReportName=nil then + p:='' + else + p:=ReportName; + SetDlgItemTextA(Dialog,IDC_REPNAME,p); + if StatName=nil then + p:='' + else + p:=StatName; + SetDlgItemTextA(Dialog,IDC_STATNAME,p); + if TmplName=nil then + p:='' + else + p:=TmplName; + SetDlgItemTextA(Dialog,IDC_TMPLNAME,p); + SetDlgItemInt(Dialog,IDC_AUTOSORT,AutoSort,false); + CheckDlgButton(Dialog,IDC_RUNREPORT,RunReport); + CheckDlgButton(Dialog,IDC_ADDEXT,DoAddExt); + + CheckDlgButton(Dialog,IDC_BYTITLE ,ord(SortMode=stArtist)); + CheckDlgButton(Dialog,IDC_BYDATE ,ord(SortMode=stDate)); + CheckDlgButton(Dialog,IDC_BYCOUNT ,ord(SortMode=stCount)); + CheckDlgButton(Dialog,IDC_BYPATH ,ord(SortMode=stPath)); + CheckDlgButton(Dialog,IDC_BYLENGTH,ord(SortMode=stLength)); + + if Direction=smReverse then + CheckDlgButton(Dialog,IDC_DIRECTION,BST_CHECKED); + + if (ReportMask and stArtist)<>0 then + CheckDlgButton(Dialog,IDC_FREQART,BST_CHECKED); + if (ReportMask and stAlbum)<>0 then + CheckDlgButton(Dialog,IDC_FREQALBUM,BST_CHECKED); + if (ReportMask and stCount)<>0 then + CheckDlgButton(Dialog,IDC_FREQSONG,BST_CHECKED); + if (ReportMask and stPath)<>0 then + CheckDlgButton(Dialog,IDC_FREQPATH,BST_CHECKED); + if (ReportMask and stDate)<>0 then + CheckDlgButton(Dialog,IDC_LASTSONG,BST_CHECKED); + if (ReportMask and stLength)<>0 then + CheckDlgButton(Dialog,IDC_SONGTIME,BST_CHECKED); + result:=0; + changed:=false; + end; + + WM_COMMAND: begin + if (wParam shr 16)=BN_CLICKED then + begin + case loword(wParam) of + IDC_BYTITLE : SortMode:=stArtist; + IDC_BYDATE : SortMode:=stDate; + IDC_BYCOUNT : SortMode:=stCount; + IDC_BYPATH : SortMode:=stPath; + IDC_BYLENGTH: SortMode:=stLength; + IDC_RUNREPORT: RunReport :=IsDlgButtonChecked(Dialog,IDC_RUNREPORT); + IDC_ADDEXT: DoAddExt :=IsDlgButtonChecked(Dialog,IDC_ADDEXT); + IDC_DIRECTION: begin + if IsDlgButtonChecked(Dialog,IDC_DIRECTION)=BST_CHECKED then + Direction:=smReverse + else + Direction:=smDirect; + end; + + IDC_CLEAR: begin + DeleteFileA(StatName); + exit; + end; + IDC_SNBUTTON: begin + if ShowDlg(buf,StatName) then + SetDlgItemTextA(Dialog,IDC_STATNAME,buf); + end; + IDC_TNBUTTON: begin + if ShowDlg(buf,TmplName) then + SetDlgItemTextA(Dialog,IDC_TMPLNAME,buf); + end; + IDC_RNBUTTON: begin + if ShowDlg(buf,ReportName) then + SetDlgItemTextA(Dialog,IDC_REPNAME,buf); + end; + IDC_SORTFILE: begin + GetDlgItemTextA(Dialog,IDC_STATNAME,buf,511); + if buf[0]<>#0 then + SortFile(buf,SortMode,Direction); + exit; + end; + IDC_EXPORTDEF: begin + if ShowDlg(buf,TmplName) then + begin + f:=Rewrite(buf); + if f=THANDLE(INVALID_HANDLE_VALUE) then + err('Can''t create file') + else + begin + BlockWrite(f,IntTmpl^,StrLen(IntTmpl)); + CloseHandle(f); + end; + end; + exit; + end; + IDC_REPORT: begin + ReportItems:=GetDlgItemInt(Dialog,IDC_ITEMS,tmp,false); + if ReportItems=0 then + ReportItems:=1; + GetDlgItemTextA(Dialog,IDC_REPNAME,buf1,511); + GetDlgItemTextA(Dialog,IDC_TMPLNAME,buf,511); + SetReportMask(Dialog); + CallService(MS_WAT_MAKEREPORT,TWPARAM(@buf),TLPARAM(@buf1)); + end; + end; + end; + if ((wParam shr 16)=EN_CHANGE) or ((wParam shr 16)=BN_CLICKED) then + begin + SendMessage(GetParent(Dialog),PSM_CHANGED,0,0); + changed:=true; + end; + result:=1; + end; + + WM_NOTIFY: begin + if (integer(PNMHdr(lParam)^.code)=PSN_APPLY) and changed then + begin + GetDlgItemTextA(Dialog,IDC_STATNAME,buf,511); + mFreeMem(StatName); + if buf[0]<>#0 then + begin + buf1[0]:=#0; + CallService(MS_UTILS_PATHTORELATIVE,TWPARAM(@buf),TLPARAM(@buf1)); + StrDup(StatName,buf1); + end; + + GetDlgItemTextA(Dialog,IDC_REPNAME,buf,511); + mFreeMem(ReportName); + if buf[0]<>#0 then + begin + buf1[0]:=#0; + CallService(MS_UTILS_PATHTORELATIVE,TWPARAM(@buf),TLPARAM(@buf1)); + StrDup(ReportName,buf1); + end; + + GetDlgItemTextA(Dialog,IDC_TMPLNAME,buf,511); + mFreeMem(TmplName); + if buf[0]<>#0 then + begin + buf1[0]:=#0; + CallService(MS_UTILS_PATHTORELATIVE,TWPARAM(@buf),TLPARAM(@buf1)); + StrDup(TmplName,buf1); + end; + + AutoSort:=GetDlgItemInt(Dialog,IDC_AUTOSORT,tmp,false); + ReportItems:=GetDlgItemInt(Dialog,IDC_ITEMS,tmp,false); + if ReportItems=0 then + ReportItems:=1; + SetReportMask(Dialog); + result:=1; + savestat; + changed:=false; + end; + end; + else + {result:=}DefWindowProc(Dialog,hMessage,wParam,lParam); + end; +end; diff --git a/plugins/Watrack/stat/stat_opt.inc b/plugins/Watrack/stat/stat_opt.inc new file mode 100644 index 0000000000..8d8bed6bb5 --- /dev/null +++ b/plugins/Watrack/stat/stat_opt.inc @@ -0,0 +1,62 @@ +{statistic load/save options} +const + opt_ModStatus :PAnsiChar = 'module/statistic'; + + opt_StatName :PAnsiChar = 'report/statname'; + opt_RepName :PAnsiChar = 'report/repname'; + opt_TmplName :PAnsiChar = 'report/tmplname'; + opt_SortMode :PAnsiChar = 'report/sortmode'; + opt_ReportMask:PAnsiChar = 'report/reportmask'; + opt_ReportItem:PAnsiChar = 'report/reportitems'; + opt_Direction :PAnsiChar = 'report/direction'; + opt_RunReport :PAnsiChar = 'report/runreport'; + opt_AddExt :PAnsiChar = 'report/addext'; + opt_AutoSort :PAnsiChar = 'report/autosort'; + opt_LastSort :PAnsiChar = 'report/lastsort'; + +function GetModStatus:integer; +begin + result:=DBReadByte(0,PluginShort,opt_ModStatus,1); +end; + +procedure SetModStatus(stat:integer); +begin + DBWriteByte(0,PluginShort,opt_ModStatus,stat); +end; + +procedure loadstat; +begin + ReportName :=DBReadString(0,PluginShort,opt_RepName ,nil); + StatName :=DBReadString(0,PluginShort,opt_StatName,nil); + TmplName :=DBReadString(0,PluginShort,opt_TmplName,nil); + DoAddExt :=DBReadByte (0,PluginShort,opt_AddExt ,BST_CHECKED); + RunReport :=DBReadByte (0,PluginShort,opt_RunReport ,BST_UNCHECKED); + Direction :=DBReadByte (0,PluginShort,opt_Direction ,smDirect); + SortMode :=DBReadByte (0,PluginShort,opt_SortMode ,stArtist); + ReportItems:=DBReadWord (0,PluginShort,opt_ReportItem,10); + ReportMask :=DBReadWord (0,PluginShort,opt_ReportMask,$FFFF); + AutoSort :=DBReadByte (0,PluginShort,opt_AutoSort ,1); + LastSort :=DBReadDWord (0,PluginShort,opt_LastSort ,0); +end; + +procedure savestat; +begin + DBWriteString(0,PluginShort,opt_RepName ,ReportName); + DBWriteString(0,PluginShort,opt_StatName,StatName); + DBWriteString(0,PluginShort,opt_TmplName,TmplName); + DBWriteByte (0,PluginShort,opt_AddExt ,DoAddExt); + DBWriteByte (0,PluginShort,opt_RunReport ,RunReport); + DBWriteByte (0,PluginShort,opt_Direction ,Direction); + DBWriteByte (0,PluginShort,opt_SortMode ,SortMode); + DBWriteWord (0,PluginShort,opt_ReportItem ,ReportItems); + DBWriteWord (0,PluginShort,opt_ReportMask ,ReportMask); + DBWriteByte (0,PluginShort,opt_AutoSort ,AutoSort); +// DBWriteDWord (0,PluginShort,opt_LastSort ,LastSort); +end; + +procedure FreeStat; +begin + mFreeMem(ReportName); + mFreeMem(StatName); + mFreeMem(TmplName); +end; diff --git a/plugins/Watrack/stat/stat_rc.inc b/plugins/Watrack/stat/stat_rc.inc new file mode 100644 index 0000000000..ff697e95f7 --- /dev/null +++ b/plugins/Watrack/stat/stat_rc.inc @@ -0,0 +1,29 @@ +const + IDC_STATNAME = 1026; + IDC_SNBUTTON = 1027; + IDC_SORTFILE = 1028; + IDC_REPORT = 1029; + IDC_BYTITLE = 1030; + IDC_BYDATE = 1031; + IDC_BYCOUNT = 1032; + IDC_BYPATH = 1033; + IDC_DIRECTION = 1034; + IDC_REPNAME = 1035; + IDC_RNBUTTON = 1036; + IDC_ITEMS = 1037; + IDC_CLEAR = 1038; + IDC_FREQART = 1040; + IDC_FREQSONG = 1041; + IDC_FREQPATH = 1042; + IDC_LASTSONG = 1043; + IDC_SONGTIME = 1044; + IDC_TMPLNAME = 1045; + IDC_TNBUTTON = 1046; + IDC_EXPORTDEF = 1047; + IDC_RUNREPORT = 1048; + IDC_ADDEXT = 1049; + IDC_FREQALBUM = 1050; + IDC_AUTOSORT = 1051; + IDC_BYLENGTH = 1052; + + BTN_REPORT = 12; diff --git a/plugins/Watrack/stat/stat_vars.inc b/plugins/Watrack/stat/stat_vars.inc new file mode 100644 index 0000000000..ccc7c0c5b2 --- /dev/null +++ b/plugins/Watrack/stat/stat_vars.inc @@ -0,0 +1,21 @@ +{statistic variables} +var + SortMode:dword; + ReportMask:dword; + ReportItems:cardinal; + Direction:cardinal; + RunReport:cardinal; + DoAddExt:cardinal; + AutoSort:cardinal; + LastSort:dword; +const + StatName :PAnsiChar=nil; + ReportName:PAnsiChar=nil; + TmplName :PAnsiChar=nil; +var + hPackLog, + hMakeReport, + hAddToLog, + plStatusHook, + sic, + hMenuReport:THANDLE; diff --git a/plugins/Watrack/stat/statlog.pas b/plugins/Watrack/stat/statlog.pas new file mode 100644 index 0000000000..50af34508d --- /dev/null +++ b/plugins/Watrack/stat/statlog.pas @@ -0,0 +1,650 @@ +{Statistic} +unit StatLog; +{$include compilers.inc} +interface +{$Resource stat.res} +implementation + +uses windows,messages,shellapi,commctrl + ,wrapper,io,wat_api,common,global,m_api,dbsettings,mirutils; + +{$include stat_data.inc} +{$include stat_vars.inc} +{$include stat_opt.inc} + +type + pStatCell = ^tStatCell; + tStatCell = record + Count :integer; + AltCount :integer; + LastTime :dword; + Length :integer; + Artist :PAnsiChar; + Title :PAnsiChar; + MFile :PAnsiChar; + Album :PAnsiChar; + next :pStatCell; // only for fill + end; + +type + pCells = ^tCells; + tCells = record + Count:integer; + Cells:array [0..1] of pStatCell + end; + +const + IcoBtnReport:PAnsiChar='WATrack_Report'; +const + DelimChar = '|'; +const + buflen = 2048; + +const + Lock:boolean=false; + +procedure err(str:PWideChar); +begin + MessageBoxW(0,TranslateW(str),TranslateW('Music Statistic'),MB_OK); +end; + +function OnlyPath(dst,src:PAnsiChar):PAnsiChar; +var + i:integer; +begin + i:=StrLen(src)-1; + while (i>0) and (src[i]<>'\') do dec(i); + StrCopy(dst,src,i); + result:=dst; +end; + +function PackTime(aTime:TSYSTEMTIME):dword; +begin + with aTime do + result:=wSecond+ + (wMinute shl 06)+ + (wHour shl 12)+ + (wDay shl 17)+ + (wMonth shl 22)+ + (((wYear-2000) and $3F) shl 26); +end; + +procedure UnPackTime(aTime:dword;var MyTime:TSYSTEMTIME); +begin + with MyTime do + begin + wYear :=(aTime shr 26)+2000; + wMonth :=(aTime shr 22) and $0F; + wDay :=(aTime shr 17) and $1F; + wHour :=(aTime shr 12) and $1F; + wMinute:=(aTime shr 6 ) and $3F; + wSecond:=aTime and $3F; + end; +end; + +function ShowTime(buf:PAnsiChar;aTime:dword):PAnsiChar; +var + MyTime:TSYSTEMTIME; +begin + UnPackTime(aTime,MyTime); + with MyTime do + begin + IntToStr(buf ,wDay ,2); + IntToStr(buf+3 ,wMonth ,2); + IntToStr(buf+6 ,wYear ,2); + IntToStr(buf+9 ,wHour ,2); + IntToStr(buf+12,wMinute,2); + IntToStr(buf+15,wSecond,2); + end; + buf[2] :='.'; buf[5] :='.'; buf[8] :=' '; + buf[11]:=':'; buf[14]:=':'; buf[17]:=#0; + result:=buf; +end; + +function AppendStr(src:PAnsiChar;var dst:PAnsiChar):PAnsiChar; overload; +begin + dst^:=DelimChar; inc(dst); + while src^<>#0 do + begin + dst^:=src^; + inc(dst); + inc(src); + end; + result:=dst; +end; + +function AppendStr(src:PWideChar;var dst:PAnsiChar):PAnsiChar; overload; +var + p,lp:PAnsiChar; +begin + dst^:=DelimChar; inc(dst); + lp:=WideToUTF8(src,p); + while lp^<>#0 do + begin + dst^:=lp^; + inc(dst); + inc(lp); + end; + mFreeMem(p); + result:=dst; +end; + +procedure AppendStat(fname:PAnsiChar;si:pSongInfo); +var + f:THANDLE; + MyTime:TSYSTEMTIME; + buf:array [0..buflen-1] of char; + lp:PAnsiChar; +begin + if Lock then + exit; + if (si^.artist=NIL) and (si^.title=NIL) and + (si^.album =NIL) and (si^.mfile=NIL) then + exit; + f:=Append(fname); +// if dword(f)=INVALID_HANDLE_VALUE then f:=Rewrite(fname); + if f=THANDLE(INVALID_HANDLE_VALUE) then exit; + FillChar(buf,SizeOf(buf),0); + lp:=@buf; + buf[0]:='1'; buf[1]:=DelimChar; inc(lp,2); // Count + + GetLocalTime(MyTime); + IntToStr(lp,PackTime(MyTime),9); + inc(lp,9); + lp^:=DelimChar; + inc(lp); + IntToStr(lp,si^.total); while lp^<>#0 do inc(lp); + + AppendStr(si^.artist,lp); + AppendStr(si^.title ,lp); + AppendStr(si^.mfile ,lp); + AppendStr(si^.album ,lp); + + lp^:=#$0D; inc(lp); lp^:=#$0A; + BlockWrite(f,buf,lp-PAnsiChar(@buf)+1); + CloseHandle(f); +end; + +procedure OutputStat(fname:PAnsiChar;aCells:pCells); +var + f:THANDLE; + buf:array [0..2047] of char; + lp:PAnsiChar; + i:integer; +begin + f:=Rewrite(fname); + if f=THANDLE(INVALID_HANDLE_VALUE) then + exit; + for i:=0 to aCells^.Count-1 do + begin + lp:=@buf; + with aCells^.Cells[i]^ do + begin + IntToStr(buf,Count); while lp^<>#0 do inc(lp); + lp^:=DelimChar; inc(lp); + IntToStr(lp,LastTime,9); inc(lp,9); + lp^:=DelimChar; inc(lp); + IntToStr(lp,Length); while lp^<>#0 do inc(lp); + AppendStr(Artist,lp); + AppendStr(Title ,lp); + AppendStr(MFile ,lp); + AppendStr(Album ,lp); + + lp^:=#$0D; inc(lp); lp^:=#$0A; + BlockWrite(f,buf,lp-PAnsiChar(@buf)+1); + end; + end; + CloseHandle(f); +end; + +function CutStr(var src:PAnsiChar):PAnsiChar; +begin + result:=src; + while (src^<>DelimChar) and (src^>=' ') do inc(src); + src^:=#0; + inc(src); +end; + +procedure ClearStatCells(aCells:pCells); +begin + with aCells^ do + while Count>0 do + begin + dec(Count); + mFreeMem(Cells[Count]); + end; + mFreeMem(aCells); +end; + +function FillCell(src:PAnsiChar):pStatCell; +var + Cell:pStatCell; +begin + mGetMem(Cell,SizeOf(tStatCell)); + FillChar(Cell^,SizeOf(tStatCell),0); + Cell^.Count :=StrToInt(src); + while src^<>DelimChar do inc(src); inc(src); + Cell^.LastTime:=StrToInt(src); + while src^<>DelimChar do inc(src); inc(src); + Cell^.Length :=StrToInt(src); + while src^<>DelimChar do inc(src); inc(src); + Cell^.Artist:=CutStr(src); + Cell^.Title :=CutStr(src); + Cell^.MFile :=CutStr(src); + Cell^.Album :=CutStr(src); + + result:=Cell; +end; + +function Compare(C1,C2:pStatCell; SortType:integer):integer; +var + ls,ls1:array [0..511] of AnsiChar; +begin + case SortType of + stArtist: begin + result:=lstrcmpia(C1^.Artist,C2^.Artist); + if result=0 then + result:=lstrcmpia(C1^.Title,C2^.Title); + if result=0 then + result:=lstrcmpia(C1^.Album,C2^.Album); + end; + stAlbum: result:=lstrcmpia(C1^.Album,C2^.Album); + stPath : result:=lstrcmpia(OnlyPath(ls,C1^.MFile),OnlyPath(ls1,C2^.MFile)); + stDate : result:=C2^.LastTime-C1^.LastTime; + stCount : result:=C2^.Count-C1^.Count; + stLength : result:=C2^.Length-C1^.Length; + stAltCount: result:=C2^.AltCount-C1.AltCount; + else + result:=0; + end; +end; + +function SwapProc(var Root:pCells;First,Second:integer):integer; +var + p:pStatCell; +begin + p:=Root^.Cells[First]; + Root^.Cells[First]:=Root^.Cells[Second]; + Root^.Cells[Second]:=p; + result:=0; +end; + +procedure Resort(var Root:pCells;sort:integer;adirection:integer=smDirect); + + function CompareProc(First,Second:integer):integer; + begin + result:=Compare(Root^.cells[First],Root^.cells[Second],sort); + if direction=smReverse then + result:=-result; + end; + +var + i,j,gap:longint; +begin + gap:=Root^.Count shr 1; + while gap>0 do + begin + for i:=gap to Root^.Count-1 do + begin + j:=i-gap; + while (j>=0) and (CompareProc(j,UInt(j+gap))>0) do + begin + SwapProc(Root,j,UInt(j+gap)); + dec(j,gap); + end; + end; + gap:=gap shr 1; + end; +// now pack doubles +end; + +function BuildTree(fname:PAnsiChar;var buffer:PAnsiChar):pCells; +var + f:THANDLE; + i,cnt:integer; + FirstCell,CurCell,Cell:pStatCell; + lRec:TWin32FindDataA;//WIN32_FIND_DATAA; + h:THANDLE; + p,p1,p2:PAnsiChar; + ls,buf:PAnsiChar; + arr:pCells; +begin + result:=nil; + buffer:=nil; + h:=FindFirstFileA(fname,lRec); + if h=THANDLE(INVALID_HANDLE_VALUE) then + exit; + i:=lRec.nFileSizeLow; + FindClose(h); + if i<22 then + Exit; + f:=Reset(fname); + if f=THANDLE(INVALID_HANDLE_VALUE) then + exit; + mGetMem(buffer,i+1); + p:=buffer; + BlockRead(f,p^,i); + CloseHandle(f); + p1:=p; + p2:=p+i; + FirstCell:=nil; + mGetMem(buf,buflen); + buf^:=#0; + cnt:=0; + while p#$0D do inc(p); + i:=p-p1; + p^:=#0; + if i>=20 then //min log template + min fname [d:\.e] + begin + ls:=p1; +// skip duplicates one-by-one + while ls^<>DelimChar do inc(ls); inc(ls); // Count + while ls^<>DelimChar do inc(ls); inc(ls); // time + while ls^<>DelimChar do inc(ls); inc(ls); // length + if StrCmp(buf,ls)<>0 then + begin + inc(cnt); + StrCopy(buf,ls); + Cell:=FillCell(p1); + + if FirstCell=nil then + begin + FirstCell:=Cell; + CurCell :=FirstCell; + end + else + begin + CurCell^.next:=Cell; + CurCell:=Cell; + end; + end; + end; + inc(p,2); p1:=p; + end; + mFreeMem(buf); + // Fill array + if cnt>0 then + begin + mGetMem(arr,SizeOf(integer)+cnt*SizeOf(pStatCell)); + arr^.Count:=cnt; + CurCell:=FirstCell; + i:=0; + while CurCell<>nil do + begin + arr^.Cells[i]:=CurCell; + CurCell:=CurCell.next; + inc(i); + end; + result:=arr; + // sort & pack + Resort(arr,stArtist); + + i:=1; + Cell:=arr^.Cells[0]; + while inil then + begin + if (mode<>stArtist) or (adirection<>smDirect) then + Resort(Root,mode,adirection); + OutputStat(buf1,Root); + ClearStatCells(Root); + end; + mFreeMem(buf); + Lock:=false; +end; + +{$include report.inc} + +// --------------- service functions ----------------- + +function ThAddToLog(param:pdword):dword; stdcall; +begin + result:=0; +end; + +procedure ThPackLog(param:pdword); cdecl; +begin + SortFile(StatName,SortMode,Direction); +end; + +function ThMakeReport(param:pdword):dword; stdcall; +begin + result:=0; +end; + +function AddToLog(wParam:WPARAM;lParam:LPARAM):integer;cdecl; +var + fname:PAnsiChar; + log:array [0..511] of AnsiChar; +begin + result:=0; + if (StatName=nil) or (StatName[0]=#0) then + exit; + if wParam=0 then + fname:=StatName + else + fname:=PAnsiChar(wParam); + ConvertFileName(fname,log); +// CallService(MS_UTILS_PATHTOABSOLUTE,dword(fname),dword(@log)); + AppendStat(log,pSongInfo(lParam)); +end; + +function PackLog(wParam:WPARAM;lParam:LPARAM):integer;cdecl; +begin + result:=0; + CloseHandle(mir_forkthread(@ThPackLog,nil)); +end; + +function MakeReport(wParam:WPARAM;lParam:LPARAM):integer;cdecl; +var + report,log,template:array [0..511] of AnsiChar; + l,r:PAnsiChar; +begin + result:=0; + if CallService(MS_WAT_PLUGINSTATUS,2,0)=WAT_RES_DISABLED then + exit; + if (wParam<>0) and (wParam<>MenuReportPos) then + l:=PAnsiChar(wParam) + else + l:=TmplName; + if PAnsiChar(lParam)<>nil then r:=PAnsiChar(lParam) else r:=ReportName; + if (r=nil) or (r^=#0) then + err('Report file name not defined') + else if (StatName=nil) or (StatName^=#0) then + err('Log file name not defined') + else + begin + ConvertFileName(r,report); + ConvertFileName(l,template); + ConvertFileName(StatName,log); +// CallService(MS_UTILS_PATHTOABSOLUTE,dword(r),dword(@report)); +// CallService(MS_UTILS_PATHTOABSOLUTE,dword(l),dword(@template)); +// CallService(MS_UTILS_PATHTOABSOLUTE,dword(StatName),dword(@log)); + if DoAddExt=BST_CHECKED then + ChangeExt(report,'htm'); + if StatOut(report,log,template) then + begin + if RunReport=BST_CHECKED then + begin + ShellExecuteA(0,nil{'open'},report,nil,nil,SW_SHOWNORMAL); + end; + result:=1; + end + else + err('Oops, something wrong!'); + end; +end; + +{$include stat_dlg.inc} + +function NewPlStatus(wParam:WPARAM;lParam:LPARAM):int;cdecl; +var + flag:integer; + mi:tClistMenuItem; + CurTime:dword; +begin + result:=0; + case wParam of + WAT_EVENT_NEWTRACK: begin + if (StatName<>nil) and (StatName[0]<>#0) then + begin + AppendStat(StatName,pSongInfo(lParam)); + if AutoSort>0 then + begin + CurTime:=GetCurrentTime; + if (CurTime-LastSort)>=(86400*AutoSort) then + begin + SortFile(StatName,SortMode,Direction); //PackLog(0,0); + LastSort:=CurTime; + DBWriteDWord(0,PluginShort,opt_LastSort,LastSort); + end; + end; + end; + end; + WAT_EVENT_PLUGINSTATUS: begin + case lParam of + 0: flag:=0; + 2: flag:=CMIF_GRAYED; + else // like 1 + exit + end; + FillChar(mi,sizeof(mi),0); + mi.cbSize:=sizeof(mi); + mi.flags :=CMIM_FLAGS+flag; + CallService(MS_CLIST_MODIFYMENUITEM,hMenuReport,tlparam(@mi)); + end; + end; +end; + +function IconChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl; +var + mi:TCListMenuItem; +begin + result:=0; + FillChar(mi,SizeOf(mi),0); + mi.cbSize:=sizeof(mi); + mi.flags :=CMIM_ICON; + mi.hIcon :=CallService(MS_SKIN2_GETICON,0,tlparam(IcoBtnReport)); + CallService(MS_CLIST_MODIFYMENUITEM,hMenuReport,tlparam(@mi)); +end; + +// ------------ base interface functions ------------- + +function InitProc(aGetStatus:boolean=false):integer; +var + mi:TCListMenuItem; + sid:TSKINICONDESC; +begin + if aGetStatus then + begin + if GetModStatus=0 then + begin + result:=0; + exit; + end; + end + else + SetModStatus(1); + result:=1; + + hPackLog :=CreateServiceFunction(MS_WAT_PACKLOG ,@PackLog); + hMakeReport:=CreateServiceFunction(MS_WAT_MAKEREPORT,@MakeReport); + hAddToLog :=CreateServiceFunction(MS_WAT_ADDTOLOG ,@AddToLog); + loadstat; + + FillChar(sid,SizeOf(TSKINICONDESC),0); + sid.cbSize:=SizeOf(TSKINICONDESC); + sid.cx:=16; + sid.cy:=16; + sid.szSection.a:='WATrack'; + sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(BTN_REPORT),IMAGE_ICON,16,16,0); + sid.pszName :=IcoBtnReport; + sid.szDescription.a:='Create Report'; + Skin_AddIcon(@sid); + DestroyIcon(sid.hDefaultIcon); + sic:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged); + + FillChar(mi, sizeof(mi), 0); + mi.cbSize :=sizeof(mi); + mi.flags :=0; + mi.szPopupName.a:=PluginShort; + mi.hIcon :=CallService(MS_SKIN2_GETICON,0,tlparam(IcoBtnReport)); + mi.szName.a :='Create WATrack report'; + mi.pszService :=MS_WAT_MAKEREPORT; + mi.popupPosition:=MenuReportPos; + hMenuReport :=Menu_AddMainMenuItem(@mi); + plStatusHook:=HookEvent(ME_WAT_NEWSTATUS,@NewPlStatus); +end; + +procedure DeInitProc(aSetDisable:boolean); +begin + if aSetDisable then + SetModStatus(0); + + CallService(MS_CLIST_REMOVEMAINMENUITEM,hMenuReport,0); + UnhookEvent(plStatusHook); + UnhookEvent(sic); + DestroyServiceFunction(hPackLog); + DestroyServiceFunction(hMakeReport); + DestroyServiceFunction(hAddToLog); + FreeStat; +end; + +function AddOptionsPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer; +begin + tmpl:='STATS'; + proc:=@DlgProcOptions; + name:='Statistics'; + result:=0; +end; + +var + Stat:twModule; + +procedure Init; +begin + Stat.Next :=ModuleLink; + Stat.Init :=@InitProc; + Stat.DeInit :=@DeInitProc; + Stat.AddOption :=@AddOptionsPage; + Stat.ModuleName:='Statistic'; + ModuleLink :=@Stat; +end; + +begin + Init; +end. diff --git a/plugins/Watrack/stat/wat_report.ico b/plugins/Watrack/stat/wat_report.ico new file mode 100644 index 0000000000..8e9c02fb93 Binary files /dev/null and b/plugins/Watrack/stat/wat_report.ico differ -- cgit v1.2.3