Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,93 @@
#include "HistoryAPI.h"
#include "ml_history.h"
static void saveQueryToList(nde_scanner_t s, historyRecordList *obj)
{
emptyRecentRecordList(obj);
NDE_Scanner_First(s);
int r;
do
{
nde_field_t f = NDE_Scanner_GetFieldByID(s, HISTORYVIEW_COL_FILENAME);
if (f)
{
allocRecentRecordList(obj, obj->Size + 1);
if (!obj->Alloc) break;
wchar_t *strval = NDE_StringField_GetString(f);
ndestring_retain(strval);
obj->Items[obj->Size].filename = strval;
recentScannerRefToObjCacheNFN(s, obj);
}
r = NDE_Scanner_Next(s);
}
while (r && !NDE_Scanner_EOF(s));
if (obj->Size && obj->Size < obj->Alloc - 1024)
{
size_t old_Alloc = obj->Alloc;
obj->Alloc = obj->Size;
historyRecord *data = (historyRecord*)realloc(obj->Items, sizeof(historyRecord) * obj->Alloc);
if (data)
{
obj->Items=data;
}
else
{
data=(historyRecord*)malloc(sizeof(historyRecord)*obj->Alloc);
if (data)
{
memcpy(data, obj->Items, sizeof(historyRecord)*old_Alloc);
free(obj->Items);
obj->Items=data;
}
else obj->Alloc = (int)old_Alloc;
}
}
}
historyRecordList *HistoryAPI::Query(const wchar_t *query)
{
if (!openDb())
return 0;
// run query
EnterCriticalSection(&g_db_cs);
nde_scanner_t s=NDE_Table_CreateScanner(g_table);
NDE_Scanner_Query(s, query);
historyRecordList obj;
obj.Alloc = 0;
obj.Items = NULL;
obj.Size = 0;
saveQueryToList(s, &obj);
NDE_Table_DestroyScanner(g_table, s);
LeaveCriticalSection(&g_db_cs);
if (obj.Size)
{
historyRecordList *result = (historyRecordList *)malloc(sizeof(historyRecordList));
memcpy(result, &obj, sizeof(historyRecordList));
return result;
}
else
{
freeRecentRecordList(&obj);
return 0;
}
}
void HistoryAPI::FreeHistoryList(historyRecordList *historyList)
{
freeRecentRecordList(historyList);
}
#define CBCLASS HistoryAPI
START_DISPATCH;
CB(API_HISTORY_QUERY, Query)
VCB(API_HISTORY_FREEHISTORYLIST, FreeHistoryList)
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,12 @@
#pragma once
#include "api_history.h"
class HistoryAPI : public api_history
{
public:
historyRecordList *Query(const wchar_t *query);
void FreeHistoryList(historyRecordList *historyList);
protected:
RECVS_DISPATCH;
};

View file

@ -0,0 +1,62 @@
#include "HistoryAPIFactory.h"
#include "api__ml_history.h"
#include "HistoryAPI.h"
HistoryAPI historyAPI;
static const char serviceName[] = "History API";
FOURCC HistoryAPIFactory::GetServiceType()
{
return WaSvc::UNIQUE;
}
const char *HistoryAPIFactory::GetServiceName()
{
return serviceName;
}
GUID HistoryAPIFactory::GetGUID()
{
return HistoryApiGuid;
}
void *HistoryAPIFactory::GetInterface(int global_lock)
{
// if (global_lock)
// plugin.service->service_lock(this, (void *)ifc);
return &historyAPI;
}
int HistoryAPIFactory::SupportNonLockingInterface()
{
return 1;
}
int HistoryAPIFactory::ReleaseInterface(void *ifc)
{
//plugin.service->service_unlock(ifc);
return 1;
}
const char *HistoryAPIFactory::GetTestString()
{
return 0;
}
int HistoryAPIFactory::ServiceNotify(int msg, int param1, int param2)
{
return 1;
}
#define CBCLASS HistoryAPIFactory
START_DISPATCH;
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
CB(WASERVICEFACTORY_GETGUID, GetGUID)
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,21 @@
#pragma once
#include "api__ml_history.h"
#include <api/service/waservicefactory.h>
#include <api/service/services.h>
class HistoryAPIFactory : public waServiceFactory
{
public:
FOURCC GetServiceType();
const char *GetServiceName();
GUID GetGUID();
void *GetInterface(int global_lock);
int SupportNonLockingInterface();
int ReleaseInterface(void *ifc);
const char *GetTestString();
int ServiceNotify(int msg, int param1, int param2);
protected:
RECVS_DISPATCH;
};

View file

@ -0,0 +1,95 @@
#include "api__ml_history.h"
#include "JSAPI2_Creator.h"
#include "JSAPI2_HistoryAPI.h"
#include "resource.h"
IDispatch *JSAPI2_Creator::CreateAPI(const wchar_t *name, const wchar_t *key, JSAPI::ifc_info *info)
{
if (!_wcsicmp(name, L"History"))
return new JSAPI2::HistoryAPI(key, info);
else
return 0;
}
int JSAPI2_Creator::PromptForAuthorization(HWND parent, const wchar_t *group, const wchar_t *action, const wchar_t *authorization_key, JSAPI2::api_security::AuthorizationData *data)
{
if (group && !_wcsicmp(group, L"history"))
{
const wchar_t *title_str = AGAVE_API_JSAPI2_SECURITY->GetAssociatedName(authorization_key);
return AGAVE_API_JSAPI2_SECURITY->SecurityPrompt(parent, title_str, L"This service is requesting access to your playback history.", JSAPI2::svc_apicreator::AUTHORIZATION_FLAG_GROUP_ONLY);
}
else
return JSAPI2::svc_apicreator::AUTHORIZATION_UNDEFINED;
}
#define CBCLASS JSAPI2_Creator
START_DISPATCH;
CB(JSAPI2_SVC_APICREATOR_CREATEAPI, CreateAPI);
CB(JSAPI2_SVC_APICREATOR_PROMPTFORAUTHORIZATION, PromptForAuthorization);
END_DISPATCH;
#undef CBCLASS
static JSAPI2_Creator jsapi2_svc;
static const char serviceName[] = "History Javascript Objects";
// {D9F59F89-82F3-446d-8CD8-6D4445094D50}
static const GUID jsapi2_factory_guid =
{ 0xd9f59f89, 0x82f3, 0x446d, { 0x8c, 0xd8, 0x6d, 0x44, 0x45, 0x9, 0x4d, 0x50 } };
FOURCC JSAPI2Factory::GetServiceType()
{
return jsapi2_svc.getServiceType();
}
const char *JSAPI2Factory::GetServiceName()
{
return serviceName;
}
GUID JSAPI2Factory::GetGUID()
{
return jsapi2_factory_guid;
}
void *JSAPI2Factory::GetInterface(int global_lock)
{
// if (global_lock)
// plugin.service->service_lock(this, (void *)ifc);
return &jsapi2_svc;
}
int JSAPI2Factory::SupportNonLockingInterface()
{
return 1;
}
int JSAPI2Factory::ReleaseInterface(void *ifc)
{
//plugin.service->service_unlock(ifc);
return 1;
}
const char *JSAPI2Factory::GetTestString()
{
return 0;
}
int JSAPI2Factory::ServiceNotify(int msg, int param1, int param2)
{
return 1;
}
#define CBCLASS JSAPI2Factory
START_DISPATCH;
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
CB(WASERVICEFACTORY_GETGUID, GetGUID)
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,31 @@
#pragma once
#include "../Winamp/JSAPI2_svc_apicreator.h"
#include <api/service/waservicefactory.h>
#include <api/service/services.h>
class JSAPI2Factory : public waServiceFactory
{
public:
FOURCC GetServiceType();
const char *GetServiceName();
GUID GetGUID();
void *GetInterface(int global_lock);
int SupportNonLockingInterface();
int ReleaseInterface(void *ifc);
const char *GetTestString();
int ServiceNotify(int msg, int param1, int param2);
protected:
RECVS_DISPATCH;
};
class JSAPI2_Creator : public JSAPI2::svc_apicreator
{
IDispatch *CreateAPI(const wchar_t *name, const wchar_t *key, JSAPI::ifc_info *info);
int PromptForAuthorization(HWND parent, const wchar_t *group, const wchar_t *action, const wchar_t *authorization_key, JSAPI2::api_security::AuthorizationData *data);
protected:
RECVS_DISPATCH;
};

View file

@ -0,0 +1,123 @@
#include "api__ml_history.h"
#include "JSAPI2_HistoryAPI.h"
#include "../Winamp/JSAPI.h"
#include "JSAPI2_HistoryRecordList.h"
#include "HistoryAPI.h"
extern HistoryAPI historyAPI;
JSAPI2::HistoryAPI::HistoryAPI(const wchar_t *_key, JSAPI::ifc_info *_info)
{
info = _info;
key = _key;
refCount = 1;
}
#define DISP_TABLE \
CHECK_ID(Query)\
#define CHECK_ID(str) JSAPI_DISP_ENUMIFY(str),
enum {
DISP_TABLE
};
#undef CHECK_ID
#define CHECK_ID(str) if (wcscmp(rgszNames[i], L## #str) == 0) { rgdispid[i] = JSAPI_DISP_ENUMIFY(str); continue; }
HRESULT JSAPI2::HistoryAPI::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
{
bool unknowns = false;
for (unsigned int i = 0;i != cNames;i++)
{
DISP_TABLE
rgdispid[i] = DISPID_UNKNOWN;
unknowns = true;
}
if (unknowns)
return DISP_E_UNKNOWNNAME;
else
return S_OK;
}
HRESULT JSAPI2::HistoryAPI::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryAPI::GetTypeInfoCount(unsigned int FAR * pctinfo)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryAPI::Query(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
{
JSAPI_VERIFY_METHOD(wFlags);
JSAPI_VERIFY_PARAMCOUNT(pdispparams, 1);
JSAPI_VERIFY_PARAMTYPE(pdispparams, 1, VT_BSTR, puArgErr);
JSAPI_INIT_RESULT(pvarResult, VT_DISPATCH);
if (AGAVE_API_JSAPI2_SECURITY->GetActionAuthorization(L"history", L"query", key, info, JSAPI2::api_security::ACTION_PROMPT) == JSAPI2::api_security::ACTION_ALLOWED)
{
if (pvarResult) // no sense in running the query if they don't care about the return value!
{
historyRecordList *query_results = historyAPI.Query(JSAPI_PARAM(pdispparams, 1).bstrVal);
if (query_results)
V_DISPATCH(pvarResult) = new JSAPI2::HistoryRecordList(query_results);
else
V_DISPATCH(pvarResult) = 0;
}
return S_OK;
}
else
{
V_DISPATCH(pvarResult) = 0;
return S_OK;
}
return E_FAIL;
}
#undef CHECK_ID
#define CHECK_ID(str) case JSAPI_DISP_ENUMIFY(str): return str(wFlags, pdispparams, pvarResult, puArgErr);
HRESULT JSAPI2::HistoryAPI::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
{
switch (dispid)
{
DISP_TABLE
}
return DISP_E_MEMBERNOTFOUND;
}
STDMETHODIMP JSAPI2::HistoryAPI::QueryInterface(REFIID riid, PVOID *ppvObject)
{
if (!ppvObject)
return E_POINTER;
else if (IsEqualIID(riid, IID_IDispatch))
*ppvObject = (IDispatch *)this;
else if (IsEqualIID(riid, IID_IUnknown))
*ppvObject = this;
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG JSAPI2::HistoryAPI::AddRef(void)
{
return InterlockedIncrement(&refCount);
}
ULONG JSAPI2::HistoryAPI::Release(void)
{
LONG lRef = InterlockedDecrement(&refCount);
if (lRef == 0) delete this;
return lRef;
}

View file

@ -0,0 +1,27 @@
#pragma once
#include <ocidl.h>
#include "../Winamp/JSAPI_Info.h"
namespace JSAPI2
{
class HistoryAPI : public IDispatch
{
public:
HistoryAPI(const wchar_t *_key, JSAPI::ifc_info *info);
STDMETHOD(QueryInterface)(REFIID riid, PVOID *ppvObject);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
// *** IDispatch Methods ***
STDMETHOD (GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid);
STDMETHOD (GetTypeInfo)(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo);
STDMETHOD (GetTypeInfoCount)(unsigned int FAR * pctinfo);
STDMETHOD (Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr);
private:
const wchar_t *key;
volatile LONG refCount;
JSAPI::ifc_info *info;
STDMETHOD (Query)(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr);
};
}

View file

@ -0,0 +1,260 @@
#include "JSAPI2_HistoryRecord.h"
#include "../Winamp/JSAPI.h"
#define DISP_TABLE \
CHECK_ID(filename)\
CHECK_ID(title)\
CHECK_ID(length)\
CHECK_ID(playcount)\
CHECK_ID(lastplay)\
CHECK_ID(offset)\
#define CHECK_ID(str) JSAPI_DISP_ENUMIFY(str),
enum {
DISP_TABLE
DISP_TABLE_NUM_ENTRIES,
};
JSAPI2::HistoryRecord::HistoryRecord(IUnknown *_parent, const historyRecord *_record)
{
parent = _parent;
parent->AddRef();
record = _record;
refCount = 1;
}
JSAPI2::HistoryRecord::~HistoryRecord()
{
if (parent)
parent->Release();
}
HRESULT JSAPI2::HistoryRecord::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
{
bool unknowns = false;
for (unsigned int i = 0;i != cNames;i++)
{
if (GetDispID(rgszNames[i], fdexNameCaseSensitive, &rgdispid[i]) == DISPID_UNKNOWN)
unknowns=true;
}
if (unknowns)
return DISP_E_UNKNOWNNAME;
else
return S_OK;
}
HRESULT JSAPI2::HistoryRecord::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
{
return InvokeEx(dispid, lcid, wFlags, pdispparams, pvarResult, pexecinfo, 0);
}
HRESULT JSAPI2::HistoryRecord::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecord::GetTypeInfoCount(unsigned int FAR * pctinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP JSAPI2::HistoryRecord::QueryInterface(REFIID riid, PVOID *ppvObject)
{
if (!ppvObject)
return E_POINTER;
else if (IsEqualIID(riid, IID_IDispatch))
*ppvObject = (IDispatch *)this;
else if (IsEqualIID(riid, IID_IUnknown))
*ppvObject = this;
else if (IsEqualIID(riid, IID_IDispatchEx))
*ppvObject = (IDispatchEx *)this;
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG JSAPI2::HistoryRecord::AddRef(void)
{
return InterlockedIncrement(&refCount);
}
ULONG JSAPI2::HistoryRecord::Release(void)
{
LONG lRef = InterlockedDecrement(&refCount);
if (lRef == 0) delete this;
return lRef;
}
#undef CHECK_ID
#define CHECK_ID(str) if (wcscmp(bstrName, L## #str) == 0) { *pid = JSAPI_DISP_ENUMIFY(str); return S_OK; }
HRESULT JSAPI2::HistoryRecord::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid)
{
DISP_TABLE
return DISP_E_MEMBERNOTFOUND;
}
#undef CHECK_ID
#define CHECK_ID(str) case JSAPI_DISP_ENUMIFY(str): return str(wFlags, pdp, pvarRes);
HRESULT JSAPI2::HistoryRecord::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
if (wFlags & DISPATCH_PROPERTYGET)
{
switch(id)
{
DISP_TABLE
}
}
return DISP_E_MEMBERNOTFOUND;
}
HRESULT JSAPI2::HistoryRecord::DeleteMemberByName(BSTR bstrName, DWORD grfdex)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecord::DeleteMemberByDispID(DISPID id)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecord::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
{
return E_NOTIMPL;
}
#undef CHECK_ID
#define CHECK_ID(str) case JSAPI_DISP_ENUMIFY(str): *pbstrName = SysAllocString(L ## #str); return S_OK;
HRESULT JSAPI2::HistoryRecord::GetMemberName(DISPID id, BSTR *pbstrName)
{
switch(id)
{
DISP_TABLE
}
return E_NOTIMPL;
}
#undef CHECK_ID
#define CHECK_ID(str) case JSAPI_DISP_ENUMIFY(str): *pid = JSAPI_DISP_ENUMIFY(str) + 1; break;
HRESULT JSAPI2::HistoryRecord::GetNextDispID(DWORD grfdex, DISPID id, DISPID *pid)
{
if (grfdex == fdexEnumDefault)
{
switch(id)
{
case DISPID_UNKNOWN:
*pid = 0;
break;
DISP_TABLE
}
if (*pid == DISP_TABLE_NUM_ENTRIES)
return S_FALSE;
else
return S_OK;
}
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecord::GetNameSpaceParent(IUnknown **ppunk)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecord::filename(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult)
{
if (wFlags & DISPATCH_PROPERTYGET)
{
JSAPI_INIT_RESULT(pvarResult, VT_BSTR);
JSAPI_SET_RESULT(pvarResult, bstrVal, SysAllocString(record->filename));
return S_OK;
}
else
return DISP_E_MEMBERNOTFOUND;
}
HRESULT JSAPI2::HistoryRecord::title(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult)
{
if (wFlags & DISPATCH_PROPERTYGET)
{
JSAPI_INIT_RESULT(pvarResult, VT_BSTR);
JSAPI_SET_RESULT(pvarResult, bstrVal, SysAllocString(record->title));
return S_OK;
}
else
return DISP_E_MEMBERNOTFOUND;
}
HRESULT JSAPI2::HistoryRecord::length(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult)
{
if (wFlags & DISPATCH_PROPERTYGET)
{
JSAPI_INIT_RESULT(pvarResult, VT_I4);
JSAPI_SET_RESULT(pvarResult, lVal, record->length);
return S_OK;
}
else
return DISP_E_MEMBERNOTFOUND;
}
HRESULT JSAPI2::HistoryRecord::offset(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult)
{
if (wFlags & DISPATCH_PROPERTYGET)
{
JSAPI_INIT_RESULT(pvarResult, VT_I4);
JSAPI_SET_RESULT(pvarResult, lVal, record->offset);
return S_OK;
}
else
return DISP_E_MEMBERNOTFOUND;
}
HRESULT JSAPI2::HistoryRecord::playcount(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult)
{
if (wFlags & DISPATCH_PROPERTYGET)
{
JSAPI_INIT_RESULT(pvarResult, VT_I4);
JSAPI_SET_RESULT(pvarResult, lVal, record->playcnt);
return S_OK;
}
else
return DISP_E_MEMBERNOTFOUND;
}
HRESULT JSAPI2::HistoryRecord::lastplay(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult)
{
if (wFlags & DISPATCH_PROPERTYGET)
{
JSAPI_INIT_RESULT(pvarResult, VT_DATE);
if (pvarResult)
{
__time64_t convertTime = record->lastplayed;
SYSTEMTIME sysTime = {0};
tm *newtime = _localtime64(&convertTime);
sysTime.wYear = newtime->tm_year + 1900;
sysTime.wMonth = newtime->tm_mon + 1;
sysTime.wDayOfWeek = newtime->tm_wday;
sysTime.wDay = newtime->tm_mday;
sysTime.wHour = newtime->tm_hour;
sysTime.wMinute = newtime->tm_min;
sysTime.wSecond = newtime->tm_sec;
SystemTimeToVariantTime(&sysTime, &pvarResult->date);
}
return S_OK;
}
else
return DISP_E_MEMBERNOTFOUND;
}

View file

@ -0,0 +1,46 @@
#pragma once
#include <dispex.h>
#include "history.h"
namespace JSAPI2
{
class HistoryRecord : public IDispatchEx
{
public:
HistoryRecord(IUnknown *_parent, const historyRecord *_record);
~HistoryRecord();
STDMETHOD(QueryInterface)(REFIID riid, PVOID *ppvObject);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
void AddObject(IDispatch *obj);
private:
// *** IDispatch Methods ***
STDMETHOD (GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid);
STDMETHOD (GetTypeInfo)(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo);
STDMETHOD (GetTypeInfoCount)(unsigned int FAR * pctinfo);
STDMETHOD (Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr);
// *** IDispatchEx Methods ***
STDMETHOD (GetDispID)(BSTR bstrName, DWORD grfdex, DISPID *pid);
STDMETHOD (InvokeEx)(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller);
STDMETHOD (DeleteMemberByName)(BSTR bstrName, DWORD grfdex) ;
STDMETHOD (DeleteMemberByDispID)(DISPID id);
STDMETHOD (GetMemberProperties)(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex);
STDMETHOD (GetMemberName)(DISPID id, BSTR *pbstrName);
STDMETHOD (GetNextDispID)(DWORD grfdex, DISPID id, DISPID *pid);
STDMETHOD (GetNameSpaceParent)(IUnknown **ppunk);
private:
const historyRecord *record;
IUnknown *parent;
volatile LONG refCount;
STDMETHOD (filename)(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult);
STDMETHOD (title)(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult);
STDMETHOD (length)(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult);
STDMETHOD (playcount)(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult);
STDMETHOD (lastplay)(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult);
STDMETHOD (offset)(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult);
};
}

View file

@ -0,0 +1,198 @@
#include "JSAPI2_HistoryRecordList.h"
#include "JSAPI2_HistoryRecord.h"
#include "ml_history.h"
#include "../Winamp/JSAPI.h"
#include <strsafe.h>
JSAPI2::HistoryRecordList::HistoryRecordList(historyRecordList *_record)
{
recordList = _record;
refCount = 1;
}
JSAPI2::HistoryRecordList::~HistoryRecordList()
{
freeRecentRecordList(recordList);
}
enum
{
OBJ_ARRAY_DISP_LENGTH,
OBJ_ARRAY_NUM_DISP,
};
HRESULT JSAPI2::HistoryRecordList::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
{
bool unknowns = false;
for (unsigned int i = 0;i != cNames;i++)
{
if (GetDispID(rgszNames[i], fdexNameCaseSensitive, &rgdispid[i]) == DISPID_UNKNOWN)
unknowns=true;
}
if (unknowns)
return DISP_E_UNKNOWNNAME;
else
return S_OK;
}
HRESULT JSAPI2::HistoryRecordList::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
{
return InvokeEx(dispid, lcid, wFlags, pdispparams, pvarResult, pexecinfo, 0);
}
HRESULT JSAPI2::HistoryRecordList::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecordList::GetTypeInfoCount(unsigned int FAR * pctinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP JSAPI2::HistoryRecordList::QueryInterface(REFIID riid, PVOID *ppvObject)
{
if (!ppvObject)
return E_POINTER;
else if (IsEqualIID(riid, IID_IDispatch))
*ppvObject = (IDispatch *)this;
else if (IsEqualIID(riid, IID_IUnknown))
*ppvObject = this;
else if (IsEqualIID(riid, IID_IDispatchEx))
*ppvObject = (IDispatchEx *)this;
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG JSAPI2::HistoryRecordList::AddRef(void)
{
return InterlockedIncrement(&refCount);
}
ULONG JSAPI2::HistoryRecordList::Release(void)
{
LONG lRef = InterlockedDecrement(&refCount);
if (lRef == 0) delete this;
return lRef;
}
HRESULT JSAPI2::HistoryRecordList::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid)
{
if (!_wcsicmp(bstrName, L"length"))
*pid=OBJ_ARRAY_DISP_LENGTH;
else
{
if (bstrName[0] >= L'0' && bstrName[0] <= L'9')
*pid=_wtoi(bstrName) + OBJ_ARRAY_NUM_DISP;
else
return DISP_E_MEMBERNOTFOUND;
}
return S_OK;
}
HRESULT JSAPI2::HistoryRecordList::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
JSAPI_VERIFY_PARAMCOUNT(pdp, 0);
switch(id)
{
case OBJ_ARRAY_DISP_LENGTH:
{
JSAPI_INIT_RESULT(pvarRes, VT_I4);
JSAPI_SET_RESULT(pvarRes, lVal, recordList->Size);
return S_OK;
}
default:
{
if (id < OBJ_ARRAY_NUM_DISP)
return DISP_E_MEMBERNOTFOUND;
int index = id - OBJ_ARRAY_NUM_DISP;
if (index>=recordList->Size)
return DISP_E_MEMBERNOTFOUND;
JSAPI_INIT_RESULT(pvarRes, VT_DISPATCH);
JSAPI_SET_RESULT(pvarRes, pdispVal, new JSAPI2::HistoryRecord(this, &recordList->Items[index]));
return S_OK;
}
}
}
HRESULT JSAPI2::HistoryRecordList::DeleteMemberByName(BSTR bstrName, DWORD grfdex)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecordList::DeleteMemberByDispID(DISPID id)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecordList::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
{
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecordList::GetMemberName(DISPID id, BSTR *pbstrName)
{
if (id >= OBJ_ARRAY_NUM_DISP)
{
wchar_t temp[64];
StringCbPrintfW(temp, sizeof(temp), L"%d", id-OBJ_ARRAY_NUM_DISP);
*pbstrName = SysAllocString(temp);
return S_OK;
}
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecordList::GetNextDispID(DWORD grfdex, DISPID id, DISPID *pid)
{
if (grfdex == fdexEnumDefault)
{
if (id == DISPID_UNKNOWN)
{
if (recordList->Size == 0)
return S_FALSE;
else
{
*pid = OBJ_ARRAY_NUM_DISP;
return S_OK;
}
}
else if (id < OBJ_ARRAY_NUM_DISP)
{
return S_FALSE;
}
else
{
int index = (id - OBJ_ARRAY_NUM_DISP) + 1;
if (index >= recordList->Size)
{
return S_FALSE;
}
else
{
*pid = OBJ_ARRAY_NUM_DISP + index;
return S_OK;
}
}
}
return E_NOTIMPL;
}
HRESULT JSAPI2::HistoryRecordList::GetNameSpaceParent(IUnknown **ppunk)
{
return E_NOTIMPL;
}

View file

@ -0,0 +1,37 @@
#pragma once
#include <dispex.h>
#include "history.h"
namespace JSAPI2
{
class HistoryRecordList : public IDispatchEx
{
public:
HistoryRecordList(historyRecordList *_record);
~HistoryRecordList();
STDMETHOD(QueryInterface)(REFIID riid, PVOID *ppvObject);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
void AddObject(IDispatch *obj);
private:
// *** IDispatch Methods ***
STDMETHOD (GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid);
STDMETHOD (GetTypeInfo)(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo);
STDMETHOD (GetTypeInfoCount)(unsigned int FAR * pctinfo);
STDMETHOD (Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr);
// *** IDispatchEx Methods ***
STDMETHOD (GetDispID)(BSTR bstrName, DWORD grfdex, DISPID *pid);
STDMETHOD (InvokeEx)(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller);
STDMETHOD (DeleteMemberByName)(BSTR bstrName, DWORD grfdex) ;
STDMETHOD (DeleteMemberByDispID)(DISPID id);
STDMETHOD (GetMemberProperties)(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex);
STDMETHOD (GetMemberName)(DISPID id, BSTR *pbstrName);
STDMETHOD (GetNextDispID)(DWORD grfdex, DISPID id, DISPID *pid);
STDMETHOD (GetNameSpaceParent)(IUnknown **ppunk);
private:
historyRecordList *recordList;
volatile LONG refCount;
};
}

View file

@ -0,0 +1,349 @@
#include "api__ml_history.h"
#include "main.h"
#include "..\..\General\gen_ml/config.h"
#include "HistoryAPIFactory.h"
#include "JSAPI2_Creator.h"
#include "..\..\General\gen_ml/ml_ipc_0313.h"
#include "../nu/AutoCharFn.h"
#include <strsafe.h>
#define LOCAL_WRITE_VER L"2.03"
// wasabi based services for localisation support
api_language *WASABI_API_LNG = 0;
api_explorerfindfile *WASABI_API_EXPLORERFINDFILE = 0;
JSAPI2::api_security *AGAVE_API_JSAPI2_SECURITY = 0;
api_application *WASABI_API_APP=0;
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
static HistoryAPIFactory historyAPIFactory;
static JSAPI2Factory jsapi2Factory;
static int Init();
static void Quit();
static INT_PTR MessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3);
prefsDlgRecW preferences = {0};
wchar_t g_tableDir[MAX_PATH] = {0};
extern "C" winampMediaLibraryPlugin plugin =
{
MLHDR_VER,
"nullsoft(ml_history.dll)",
Init,
Quit,
MessageProc,
0,
0,
0,
};
// Delay load library control << begin >>
#include <delayimp.h>
#pragma comment(lib, "delayimp")
bool nde_error = false;
FARPROC WINAPI FailHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
nde_error = true;
return 0;
}
/*
extern "C"
{
PfnDliHook __pfnDliFailureHook2 = FailHook;
}
*/
// Delay load library control << end >>
int Init()
{
InitializeCriticalSection(&g_db_cs);
g_db = NULL;
g_table = NULL;
mediaLibrary.library = plugin.hwndLibraryParent;
mediaLibrary.winamp = plugin.hwndWinampParent;
mediaLibrary.instance = plugin.hDllInstance;
wchar_t configName[ MAX_PATH ] = { 0 };
const wchar_t *dir = mediaLibrary.GetIniDirectoryW();
if ( (INT_PTR)( dir ) < 65536 )
return ML_INIT_FAILURE;
PathCombineW( g_tableDir, dir, L"Plugins" );
PathCombineW( configName, g_tableDir, L"gen_ml.ini" );
g_config = new C_Config( configName );
CreateDirectoryW( g_tableDir, NULL );
PathCombineW( g_tableDir, g_tableDir, L"ml" );
CreateDirectoryW( g_tableDir, NULL );
// loader so that we can get the localisation service api for use
waServiceFactory *sf = plugin.service->service_getServiceByGuid( languageApiGUID );
if ( sf )
WASABI_API_LNG = reinterpret_cast<api_language *>( sf->getInterface() );
sf = plugin.service->service_getServiceByGuid( JSAPI2::api_securityGUID );
if ( sf )
AGAVE_API_JSAPI2_SECURITY = reinterpret_cast<JSAPI2::api_security *>( sf->getInterface() );
sf = plugin.service->service_getServiceByGuid( applicationApiServiceGuid );
if ( sf )
WASABI_API_APP = reinterpret_cast<api_application *>( sf->getInterface() );
sf = plugin.service->service_getServiceByGuid( ExplorerFindFileApiGUID );
if ( sf )
WASABI_API_EXPLORERFINDFILE = reinterpret_cast<api_explorerfindfile *>( sf->getInterface() );
plugin.service->service_register( &historyAPIFactory );
plugin.service->service_register( &jsapi2Factory );
// need to have this initialised before we try to do anything with localisation features
WASABI_API_START_LANG( plugin.hDllInstance, MlHistoryLangGUID );
g_context_menus2 = WASABI_API_LOADMENUW(IDR_CONTEXTMENUS);
static wchar_t szDescription[256];
StringCchPrintfW( szDescription, ARRAYSIZE( szDescription ), WASABI_API_LNGSTRINGW( IDS_NULLSOFT_HISTORY ), LOCAL_WRITE_VER );
plugin.description = (char*)szDescription;
static wchar_t preferencesName[64] = {0};
preferences.hInst = WASABI_API_LNG_HINST;
preferences.dlgID = IDD_PREFS;
preferences.proc = (void *)PrefsProc;
preferences.name = WASABI_API_LNGSTRINGW_BUF( IDS_HISTORY, preferencesName, 64 );
preferences.where = 6; // media library
SENDWAIPC( plugin.hwndWinampParent, IPC_ADD_PREFS_DLGW, &preferences );
if ( !history_init() )
return ML_INIT_FAILURE;
return ML_INIT_SUCCESS;
}
void Quit()
{
plugin.service->service_deregister(&historyAPIFactory);
plugin.service->service_deregister(&jsapi2Factory);
history_quit();
delete g_config;
DeleteCriticalSection(&g_db_cs);
waServiceFactory *sf = plugin.service->service_getServiceByGuid(languageApiGUID);
if (sf) sf->releaseInterface(WASABI_API_LNG);
sf = plugin.service->service_getServiceByGuid(JSAPI2::api_securityGUID);
if (sf) sf->releaseInterface(AGAVE_API_JSAPI2_SECURITY);
}
static INT_PTR History_OnContextMenu(INT_PTR param1, HWND hHost, POINTS pts)
{
HNAVITEM hItem = (HNAVITEM)param1;
HNAVITEM myItem = MLNavCtrl_FindItemById(plugin.hwndLibraryParent, ml_history_tree);
if (hItem != myItem)
return FALSE;
POINT pt;
POINTSTOPOINT(pt, pts);
if (-1 == pt.x || -1 == pt.y)
{
NAVITEMGETRECT itemRect;
itemRect.fItem = FALSE;
itemRect.hItem = hItem;
if (MLNavItem_GetRect(plugin.hwndLibraryParent, &itemRect))
{
MapWindowPoints(hHost, HWND_DESKTOP, (POINT*)&itemRect.rc, 2);
pt.x = itemRect.rc.left + 2;
pt.y = itemRect.rc.top + 2;
}
}
HMENU hMenu = WASABI_API_LOADMENUW(IDR_CONTEXTMENUS);
HMENU subMenu = (NULL != hMenu) ? GetSubMenu(hMenu, 1) : NULL;
if (NULL != subMenu)
{
INT r = Menu_TrackPopup(plugin.hwndLibraryParent, subMenu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY |
TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON,
pt.x, pt.y, hHost, NULL);
switch(r)
{
case ID_NAVIGATION_PREFERENCES:
SENDWAIPC(plugin.hwndWinampParent, IPC_OPENPREFSTOPAGE, &preferences);
break;
case ID_NAVIGATION_HELP:
SENDWAIPC(plugin.hwndWinampParent, IPC_OPEN_URL, L"https://help.winamp.com/hc/articles/8105304048660-The-Winamp-Media-Library");
break;
}
}
if (NULL != hMenu)
DestroyMenu(hMenu);
return TRUE;
}
void History_StartTracking(const wchar_t *filename, bool resume)
{
KillTimer(plugin.hwndWinampParent, 8082);
if (!resume)
{
free(history_fn);
history_fn = 0;
history_fn_mode = 0;
if (wcsstr(filename, L"://") && _wcsnicmp(filename, L"cda://", 6) && _wcsnicmp(filename, L"file://", 7))
{
history_fn_mode = 1;
}
history_fn = _wcsdup(filename);
}
int timer1 = -1, timer2 = -1, timer3 = -1;
// wait for x seconds
if(g_config->ReadInt(L"recent_wait_secs",0))
{
timer1 = g_config->ReadInt(L"recent_wait_secs_lim",5)*1000;
}
// wait for x percent of the song (approx to a second)
if(g_config->ReadInt(L"recent_wait_percent",0))
{
basicFileInfoStructW bfiW = {0};
bfiW.filename = history_fn;
SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&bfiW, IPC_GET_BASIC_FILE_INFOW);
if(bfiW.length > 0)
{
bfiW.length=bfiW.length*1000;
timer2 = (bfiW.length*g_config->ReadInt(L"recent_wait_percent_lim",50))/100;
}
}
// wait for the end of the item (within the last second of the track hopefully)
if(g_config->ReadInt(L"recent_wait_end",0))
{
basicFileInfoStructW bfiW = {0};
bfiW.filename = history_fn;
SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&bfiW, IPC_GET_BASIC_FILE_INFOW);
if(bfiW.length > 0)
{
timer3=(bfiW.length-1)*1000;
}
}
// decide on which playback option will be the prefered duration (smallest wins)
if(timer1 != -1 && timer2 != -1)
{
if(timer1 > timer2)
{
timer = timer2;
}
if(timer2 > timer1)
{
timer = timer1;
}
}
else if(timer1 == -1 && timer2 != -1)
{
timer = timer2;
}
else if(timer2 == -1 && timer1 != -1)
{
timer = timer1;
}
// only track on end of file as very last method
if((timer <= 0) && (timer3 > 0)){ timer = timer3; }
// if no match or something went wrong then try to ensure the default timer value is used
SetTimer(plugin.hwndWinampParent, 8082, ((timer > 0)? timer : 350), NULL);
}
INT_PTR MessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3)
{
switch (message_type)
{
case ML_MSG_TREE_ONCREATEVIEW: // param1 = param of tree item, param2 is HWND of parent. return HWND if it is us
return (param1 == ml_history_tree) ? (INT_PTR)onTreeViewSelectChange((HWND)param2) : 0;
case ML_MSG_CONFIG:
mediaLibrary.GoToPreferences((int)preferences._id);
return TRUE;
case ML_MSG_VIEW_PLAY_ENQUEUE_CHANGE:
enqueuedef = (int)param1;
groupBtn = (int)param2;
PostMessage(m_curview_hwnd, WM_APP + 104, param1, param2);
return 0;
case ML_MSG_NAVIGATION_CONTEXTMENU:
return History_OnContextMenu(param1, (HWND)param2, MAKEPOINTS(param3));
case ML_MSG_PLAYING_FILE:
if (param1)
{
int resume = g_config->ReadInt(L"resumeplayback",0);
if(resume)
{
int is_playing = (int)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_ISPLAYING);
//int play_pos = SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_GETOUTPUTTIME);
if(is_playing == 1/* && !(play_pos/1000 > 0)*/) //playing, look up last play offset and send seek message
{
wchar_t genre[256]={0};
extendedFileInfoStructW efis={
(wchar_t*)param1,
L"genre",
genre,
ARRAYSIZE(genre),
};
SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&efis,IPC_GET_EXTENDED_FILE_INFOW);
wchar_t ispodcast[8]={0};
extendedFileInfoStructW efis1={
(wchar_t*)param1,
L"ispodcast",
ispodcast,
ARRAYSIZE(ispodcast),
};
SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&efis1,IPC_GET_EXTENDED_FILE_INFOW_HOOKABLE);
if (resume == 2 || (ispodcast[0] && _wtoi(ispodcast) > 0) || (genre[0] && !_wcsicmp(genre, L"podcast")))
{
int offset = retrieve_offset((wchar_t*)param1);
if (offset > 0 && (offset/1000 > 0)) PostMessage(plugin.hwndWinampParent,WM_WA_IPC,offset,IPC_JUMPTOTIME);
}
}
}
History_StartTracking((const wchar_t *)param1, false);
}
break;
case ML_MSG_WRITE_CONFIG:
if(param1)
{
closeDb();
openDb();
}
break;
}
return 0;
}
extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
{
return &plugin;
}

View file

@ -0,0 +1,34 @@
#ifndef NULLSOFT_MAINH
#define NULLSOFT_MAINH
#include <windows.h>
#include "..\..\General\gen_ml/ml.h"
#include "resource.h"
#include "../nu/MediaLibraryInterface.h"
#include "..\..\General\gen_ml/menu.h"
#include <commctrl.h>
#include <shlwapi.h>
#include "ml_history.h"
#include <windowsx.h>
#include "..\..\General\gen_ml/ml.h"
#include "..\..\General\gen_ml/ml_ipc.h"
#include "../nde/nde_c.h"
#include "api__ml_history.h"
#include "../Winamp/JSAPI2_svc_apicreator.h"
#include <api/service/waservicefactory.h>
#include <api/service/services.h>
extern winampMediaLibraryPlugin plugin;
extern bool nde_error;
extern int history_fn_mode;
extern wchar_t *history_fn;
extern int timer;
extern HWND m_curview_hwnd;
extern int groupBtn, enqueuedef;
extern HMENU g_context_menus2;
void History_StartTracking(const wchar_t *filename, bool resume);
#endif

View file

@ -0,0 +1,18 @@
#ifndef NULLSOFT_ML_HISTORY_API_H
#define NULLSOFT_ML_HISTORY_API_H
#include <api/application/api_application.h>
extern api_application *applicationApi;
#define WASABI_API_APP applicationApi
#include "../Winamp/JSAPI2_api_security.h"
extern JSAPI2::api_security *jsapi2_security;
#define AGAVE_API_JSAPI2_SECURITY jsapi2_security
#include <api/service/waServiceFactory.h>
#include "../Agave/Language/api_language.h"
#include "../Agave/ExplorerFindFile/api_explorerfindfile.h"
#endif // !NULLSOFT_ML_HISTORY_API_H

View file

@ -0,0 +1 @@
#include "api_history.h"

View file

@ -0,0 +1,34 @@
#pragma once
#include <bfc/dispatch.h>
#include "history.h"
class api_history : public Dispatchable
{
protected:
api_history() {}
~api_history() {}
public:
historyRecordList *Query(const wchar_t *query);
void FreeHistoryList(historyRecordList *historyList);
enum
{
API_HISTORY_QUERY = 0,
API_HISTORY_FREEHISTORYLIST = 1,
};
};
inline historyRecordList *api_history::Query(const wchar_t *query)
{
return _call(API_HISTORY_QUERY, (historyRecordList *)0, query);
}
inline void api_history::FreeHistoryList(historyRecordList *historyList)
{
_voidcall(API_HISTORY_FREEHISTORYLIST, historyList);
}
// {F9BF9119-D163-4118-BEA7-5980869DBB2E}
static const GUID HistoryApiGuid =
{ 0xf9bf9119, 0xd163, 0x4118, { 0xbe, 0xa7, 0x59, 0x80, 0x86, 0x9d, 0xbb, 0x2e } };

View file

@ -0,0 +1,6 @@
There was an error reading the history database. This could be due to the database becoming corrupted or having been removed.
If the database files (recent.dat and recent.idx) have become corrupted then unless you have a back up, you will need to reset the database.
By resetting the database, any playing history will be lost which also will have happened if the database was corrupted.

View file

@ -0,0 +1,35 @@
#pragma once
#ifndef NULLSOFT_ML_HISTORY_HISTORY_H
#define NULLSOFT_ML_HISTORY_HISTORY_H
#include <time.h>
typedef struct
{
wchar_t *filename;
wchar_t *title;
wchar_t *ext;
int length;
unsigned int playcnt;
__time64_t lastplayed;
int offset;
} historyRecord;
typedef struct
{
historyRecord *Items;
int Size;
int Alloc;
} historyRecordList;
enum
{
HISTORY_SORT_LASTPLAYED = 0,
HISTORY_SORT_PLAYCOUNT = 1,
HISTORY_SORT_TITLE = 2,
HISTORY_SORT_LENGTH = 3,
HISTORY_SORT_FILENAME = 4,
HISTORY_SORT_OFFSET = 5,
};
#endif

View file

@ -0,0 +1,289 @@
#include "main.h"
#include "..\..\General\gen_ml/config.h"
#include "..\..\General\gen_ml/gaystring.h"
#include "..\..\General\gen_hotkeys/wa_hotkeys.h"
#include "..\..\General\gen_ml/MediaLibraryCOM.h"
#include "..\..\General\gen_ml/ml_ipc_0313.h"
#include <malloc.h>
int ml_history_tree = -1;
HWND m_curview_hwnd = NULL;
static WNDPROC wa_oldWndProc=0;
wchar_t *history_fn = 0;
int timer = -1;
static wchar_t *last_history_fn;
static int last_timer=-1;
static int last_play_pos=0;
int history_fn_mode = 0;
nde_database_t g_db = NULL;
nde_table_t g_table = NULL;
int g_table_dirty = 0;
C_Config *g_config;
CRITICAL_SECTION g_db_cs;
HWND onTreeViewSelectChange(HWND hwnd)
{
openDb();
if (m_curview_hwnd) DestroyWindow(m_curview_hwnd);
if (!g_table || nde_error)
{
m_curview_hwnd = WASABI_API_CREATEDIALOGPARAMW(IDD_VIEW_DB_ERROR, hwnd, view_errorinfoDialogProc, 0);
}
else
{
m_curview_hwnd = WASABI_API_CREATEDIALOGPARAMW(IDD_VIEW_RECENTITEMS, hwnd, view_historyDialogProc, 0);
}
return m_curview_hwnd;
}
static void history_cleanupifnecessary();
static LRESULT APIENTRY wa_newWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
int history_init()
{
if ( !g_config->ReadInt( L"showrecentitems", 1 ) )
return 1;
NAVINSERTSTRUCT nis = {0};
nis.item.cbSize = sizeof(NAVITEM);
nis.item.pszText = WASABI_API_LNGSTRINGW(IDS_HISTORY);
nis.item.pszInvariant = L"History";
nis.item.mask = NIMF_TEXT | NIMF_TEXTINVARIANT | NIMF_IMAGE | NIMF_IMAGESEL;
nis.item.iSelectedImage = nis.item.iImage = mediaLibrary.AddTreeImageBmp(IDB_TREEITEM_RECENT);
// map to item id (will probably have to change but is a quick port to support invariant item naming)
NAVITEM nvItem = {sizeof(NAVITEM),0,NIMF_ITEMID,};
nvItem.hItem = MLNavCtrl_InsertItem(plugin.hwndLibraryParent, &nis);
MLNavItem_GetInfo(plugin.hwndLibraryParent, &nvItem);
ml_history_tree = nvItem.id;
if (!wa_oldWndProc) // don't double dip (we call history_init() dynamically if the user fiddles with prefs
{
wa_oldWndProc = (WNDPROC)SetWindowLongPtrW(plugin.hwndWinampParent, GWLP_WNDPROC, (LONG_PTR)wa_newWndProc);
}
return 1;
}
void history_quit()
{
if (last_history_fn)
{
if ((last_timer <= 0) || (last_play_pos > last_timer))
{
if (last_play_pos) history_onFile(last_history_fn, last_play_pos);
}
}
free(last_history_fn);
last_history_fn = 0;
free(history_fn);
history_fn = 0;
closeDb();
mediaLibrary.RemoveTreeItem(ml_history_tree);
ml_history_tree=0;
}
static void RetypeFilename(nde_table_t table)
{
// TODO: UI
int totalRecords = NDE_Table_GetRecordsCount(g_table);
if (totalRecords == 0) // bail out early so we don't flash a dialog
return;
nde_scanner_t pruneScanner = NDE_Table_CreateScanner(table);
if (pruneScanner)
{
NDE_Scanner_First(pruneScanner);
while (!NDE_Scanner_EOF(pruneScanner))
{
nde_field_t f = NDE_Scanner_GetFieldByID(pruneScanner, HISTORYVIEW_COL_FILENAME);
if (f && NDE_Field_GetType(f) == FIELD_STRING)
{
wchar_t *s = NDE_StringField_GetString(f);
ndestring_retain(s);
NDE_Scanner_DeleteField(pruneScanner, f);
nde_field_t new_f = NDE_Scanner_NewFieldByID(pruneScanner, HISTORYVIEW_COL_FILENAME);
NDE_StringField_SetNDEString(new_f, s);
ndestring_release(s);
NDE_Scanner_Post(pruneScanner);
}
else if (f)
break;
NDE_Scanner_Next(pruneScanner);
}
NDE_Table_DestroyScanner(table, pruneScanner);
NDE_Table_Sync(table);
}
}
static void CreateFields(nde_table_t table)
{
// create defaults
NDE_Table_NewColumnW(g_table, HISTORYVIEW_COL_LASTPLAYED, L"lastplay", FIELD_DATETIME);
NDE_Table_NewColumnW(g_table, HISTORYVIEW_COL_PLAYCOUNT, L"playcount", FIELD_INTEGER);
NDE_Table_NewColumnW(g_table, HISTORYVIEW_COL_TITLE, L"title", FIELD_STRING);
NDE_Table_NewColumnW(g_table, HISTORYVIEW_COL_LENGTH, L"length", FIELD_INTEGER);
NDE_Table_NewColumnW(g_table, HISTORYVIEW_COL_FILENAME, L"filename", FIELD_FILENAME);
NDE_Table_NewColumnW(g_table, HISTORYVIEW_COL_OFFSET, L"offset", FIELD_INTEGER);
NDE_Table_PostColumns(g_table);
NDE_Table_AddIndexByIDW(g_table, 0, L"filename");}
int openDb()
{
if (g_table) return 1; // need to close first
EnterCriticalSection(&g_db_cs);
// benski> i know this looks redundant, but we might have sat and blocked at the above Critical Section for a while
if (g_table)
{
LeaveCriticalSection(&g_db_cs);
return 1;
}
if (!g_db)
{
__try
{
g_db = NDE_CreateDatabase(plugin.hDllInstance);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
g_db = NULL;
LeaveCriticalSection(&g_db_cs);
return 0;
}
}
wchar_t tableName[MAX_PATH] = {0}, indexName[MAX_PATH] = {0};
PathCombineW(tableName, g_tableDir, L"recent.dat");
PathCombineW(indexName, g_tableDir, L"recent.idx");
if (!g_db)
{
LeaveCriticalSection(&g_db_cs);
return 0;
}
g_table = NDE_Database_OpenTable(g_db, tableName, indexName, NDE_OPEN_ALWAYS, NDE_CACHE);
if (g_table)
{
CreateFields(g_table);
RetypeFilename(g_table);
}
LeaveCriticalSection(&g_db_cs);
return (g_table != NULL);
}
void closeDb(bool clear_dirty)
{
if (g_table_dirty && g_table)
{
history_bgQuery_Stop();
NDE_Table_Sync(g_table);
if (clear_dirty) g_table_dirty=0;
}
if (g_db)
{
__try
{
if (g_table)
NDE_Database_CloseTable(g_db, g_table);
NDE_DestroyDatabase(g_db);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
g_db = NULL;
g_table = NULL;
}
INT_PTR pluginHandleIpcMessage(int msg, INT_PTR param)
{
return (INT_PTR) SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, param, msg);
}
static LRESULT APIENTRY wa_newWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if ((uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYDOWN) &&
wParam == 'H' &&
!(GetAsyncKeyState(VK_MENU)&0x8000) &&
!(GetAsyncKeyState(VK_SHIFT)&0x8000) &&
(GetAsyncKeyState(VK_CONTROL)&0x8000)
&& ml_history_tree > 0)
{
mediaLibrary.ShowMediaLibrary();
mediaLibrary.SelectTreeItem(ml_history_tree);
}
else if (history_fn && uMsg == WM_TIMER && wParam == 8082)
{
if (!history_fn_mode || SendMessage(hwndDlg, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) > 350)
{
KillTimer(hwndDlg, 8082);
if (SendMessage(hwndDlg, WM_WA_IPC, 0, IPC_ISPLAYING) == 1)
{
history_onFile(history_fn, -1);
}
free(history_fn);
history_fn = 0;
}
return CallWindowProcW(wa_oldWndProc, hwndDlg, uMsg, wParam, lParam);
}
else if (last_history_fn && uMsg == WM_TIMER && wParam == 8083)
{
KillTimer(hwndDlg, 8083);
history_onFile(last_history_fn, last_play_pos);
return CallWindowProcW(wa_oldWndProc, hwndDlg, uMsg, wParam, lParam);
}
else if (uMsg == WM_WA_IPC)
{
if(lParam == IPC_STOPPLAYING && g_config->ReadInt(L"resumeplayback",0))
{
KillTimer(hwndDlg, 8082);
if (last_history_fn)
{
free(last_history_fn);
last_history_fn = 0;
}
if (history_fn) last_history_fn = _wcsdup(history_fn);
// copes with stopping after playback was tracked otherwise this aspect will fail!
else last_history_fn = _wcsdup((wchar_t*)SendMessage(hwndDlg,WM_WA_IPC,0,IPC_GET_PLAYING_FILENAME));
last_timer = timer;
stopPlayingInfoStruct *stopPlayingInfo = (stopPlayingInfoStruct *)wParam;
last_play_pos = stopPlayingInfo->last_time;
if (!stopPlayingInfo->g_fullstop)
{
if ((last_timer <= 0) || (last_play_pos > last_timer))
{
if (last_play_pos) SetTimer(hwndDlg, 8083, 150, NULL);
}
}
else // clean up play offset
{
if (last_history_fn) history_onFile(last_history_fn, 0);
}
}
else if(lParam == IPC_CB_MISC)
{
if (wParam == IPC_CB_MISC_PAUSE)
{
KillTimer(hwndDlg, 8082);
}
else if (wParam == IPC_CB_MISC_UNPAUSE)
{
if (history_fn) History_StartTracking(history_fn, true);
}
}
} // wm_wa_ipc
return CallWindowProcW(wa_oldWndProc, hwndDlg, uMsg, wParam, lParam);
}

View file

@ -0,0 +1,64 @@
#ifndef ML_HISTORY_MAIN_H
#define ML_HISTORY_MAIN_H
#include "main.h"
#include <windows.h>
#include <commctrl.h>
#include "..\..\General\gen_ml/gaystring.h"
#include "..\..\General\gen_ml/config.h"
#include "../nde/nde_c.h"
#define HISTORYVIEW_COL_LASTPLAYED 0
#define HISTORYVIEW_COL_PLAYCOUNT 1
#define HISTORYVIEW_COL_TITLE 2
#define HISTORYVIEW_COL_LENGTH 3
#define HISTORYVIEW_COL_FILENAME 4
#define HISTORYVIEW_COL_OFFSET 5
#define UPDATE_QUERY_TIMER_ID 505
extern int ml_history_tree;
HWND onTreeViewSelectChange(HWND hwnd);
int history_init();
void history_quit();
int openDb();
void closeDb(bool clear_dirty=true);
extern wchar_t g_tableDir[];
extern C_Config *g_config;
extern CRITICAL_SECTION g_db_cs;
extern nde_database_t g_db;
extern nde_table_t g_table;
extern int g_table_dirty;
inline BOOL WINAPI IsCharSpaceW(wchar_t c) { return (c == L' ' || c == L'\t'); }
inline bool IsTheW(const wchar_t *str) { if (str && (str[0] == L't' || str[0] == L'T') && (str[1] == L'h' || str[1] == L'H') && (str[2] == L'e' || str[2] == L'E') && (str[3] == L' ')) return true; else return false; }
#define SKIP_THE_AND_WHITESPACE(x) { wchar_t *save##x=(wchar_t*)x; while (IsCharSpaceW(*x) && *x) x++; if (IsTheW(x)) x+=4; while (IsCharSpaceW(*x)) x++; if (!*x) x=save##x; }
void history_bgQuery_Stop();
void history_onFile(const wchar_t *fn, int offset);
int retrieve_offset(const wchar_t *fn);
BOOL CALLBACK view_historyDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
BOOL CALLBACK view_errorinfoDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
void db_setFieldInt(nde_scanner_t s, unsigned char id, int data);
void db_setFieldString(nde_scanner_t s, unsigned char id, const wchar_t *data);
void makeFilename2(const wchar_t *filename, wchar_t *filename2, int filename2_len);
void queryStrEscape(const char *p, GayString &str);
INT_PTR pluginHandleIpcMessage(int msg, INT_PTR param);
//prefs.cpp
BOOL CALLBACK PrefsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
#include "history.h"
void allocRecentRecordList(historyRecordList *obj, int newsize, int granularity=512);
void emptyRecentRecordList(historyRecordList *obj);
void recentScannerRefToObjCacheNFN(nde_scanner_t s, historyRecordList *obj);
void sortResults(historyRecordList *obj, int column, int dir);
void freeRecentRecordList(historyRecordList *obj);
void saveQueryToList(nde_scanner_t s, historyRecordList *obj);
#endif ML_HISTORY_MAIN_H

View file

@ -0,0 +1,264 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_VIEW_RECENTITEMS DIALOGEX 0, 0, 291, 248
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "Search:",IDC_SEARCHCAPTION,1,2,25,8,SS_CENTERIMAGE
EDITTEXT IDC_QUICKSEARCH,28,1,209,10,ES_AUTOHSCROLL | NOT WS_BORDER
CONTROL "Clear Search",IDC_CLEAR,"Button",BS_OWNERDRAW | WS_TABSTOP,240,0,49,11
CONTROL "List4",IDC_LIST2,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_OWNERDATA | WS_TABSTOP,0,14,289,220
CONTROL "Play",IDC_BUTTON_PLAY,"Button",BS_OWNERDRAW | WS_TABSTOP,0,237,35,11
CONTROL "Enqueue",IDC_BUTTON_ENQUEUE,"Button",BS_OWNERDRAW | WS_TABSTOP,38,237,35,11
CONTROL "Remove",IDC_REMOVEBOOK,"Button",BS_OWNERDRAW | WS_TABSTOP,76,237,36,11
CONTROL "",IDC_MEDIASTATUS,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | SS_ENDELLIPSIS | WS_GROUP,113,238,178,10
END
IDD_PREFS DIALOGEX 0, 0, 272, 247
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
GROUPBOX "History",IDC_STATIC,0,0,272,246
LTEXT "When 'History' is enabled, Winamp will keep track of when and how many times any items are played through Winamp.",IDC_STATIC2,6,12,259,16
CONTROL "Enable 'History' view in Media Library",IDC_CHECK1,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,34,132,10
CONTROL "Track when and how many times all files are played",IDC_CHECK2,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,49,177,10
CONTROL "Track when and how many times all streams are played",IDC_CHECK3,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,62,189,10
CONTROL "Limit tracking to items played in the last",IDC_CHECK4,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,75,138,10
EDITTEXT IDC_EDIT1,157,74,24,12,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "days",IDC_STATIC1,183,76,16,8
GROUPBOX "Tracking Control",IDC_STATIC,16,89,249,89
CONTROL "Wait",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,103,30,8
EDITTEXT IDC_EDIT2,53,101,24,12,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "seconds before tracking items",IDC_STATIC4,81,103,174,8
CONTROL "Wait",IDC_CHECK6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,119,30,8
EDITTEXT IDC_EDIT3,53,117,24,12,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "percent of playback before tracking items",IDC_STATIC5,81,119,174,8
CONTROL "Wait until the end of complete playback\n(May count before the displayed end due to output buffer sizes)",IDC_CHECK7,
"Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,23,133,232,16
LTEXT "Note: When the first match against any of the above selected option(s) is met then the currently playing item will be tracked.",IDC_STATIC6,23,156,235,16
GROUPBOX "Playback Resume",IDC_STATIC,16,184,249,52
COMBOBOX IDC_COMBO1,22,196,236,39,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Note: This will make Winamp resume playback of tracked files from the last played position (once the first Tracking Control target has been reached).",IDC_STATIC7,22,212,249,16
END
IDD_VIEW_DB_ERROR DIALOGEX 0, 0, 194, 166
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
CTEXT "",IDC_DB_ERROR,10,10,174,129,0x2000
CONTROL "Reset Database",IDC_RESET_DB_ON_ERROR,"Button",BS_OWNERDRAW | WS_TABSTOP,61,144,70,12
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_CONTEXTMENUS MENU
BEGIN
POPUP "RecentWnd"
BEGIN
MENUITEM "Play selection\tEnter", ID_MEDIAWND_PLAYSELECTEDFILES
MENUITEM "Enqueue selection\tShift+Enter", ID_MEDIAWND_ENQUEUESELECTEDFILES
POPUP "Send to:"
BEGIN
MENUITEM "", 40003
END
MENUITEM SEPARATOR
MENUITEM "Select all\tCtrl+A", ID_MEDIAWND_SELECTALL
MENUITEM SEPARATOR
MENUITEM "View f&ile info...\tAlt+3", ID_PE_ID3
MENUITEM "Remove from recent list\tDel", ID_MEDIAWND_REMOVEFROMLIBRARY
MENUITEM SEPARATOR
MENUITEM "&Clear playback offset\tShift+Del", ID_MEDIAWND_REMOVEOFFSETFROMLIBRARY
MENUITEM SEPARATOR
MENUITEM "Explore item folder\tCtrl+F", 40007
END
POPUP "Navigation"
BEGIN
MENUITEM "&Preferences", ID_NAVIGATION_PREFERENCES
MENUITEM SEPARATOR
MENUITEM "Help", ID_NAVIGATION_HELP
END
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_PREFS, DIALOG
BEGIN
BOTTOMMARGIN, 246
END
IDD_VIEW_DB_ERROR, DIALOG
BEGIN
LEFTMARGIN, 10
RIGHTMARGIN, 184
TOPMARGIN, 10
BOTTOMMARGIN, 156
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_TREEITEM_RECENT BITMAP "resources\\ti_history_items_16x16x16.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// TEXT
//
IDR_DB_ERROR TEXT ".\\db_error.txt"
IDR_NDE_ERROR TEXT "..\\ml_local\\nde_error.txt"
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_VIEW_ACCELERATORS ACCELERATORS
BEGIN
"3", ID_PE_ID3, VIRTKEY, ALT, NOINVERT
"A", ID_MEDIAWND_SELECTALL, VIRTKEY, CONTROL, NOINVERT
"F", ID_MEDIAWND_EXPLOREFOLDER, VIRTKEY, CONTROL, NOINVERT
VK_DELETE, ID_MEDIAWND_REMOVEFROMLIBRARY, VIRTKEY, NOINVERT
VK_DELETE, ID_MEDIAWND_REMOVEOFFSETFROMLIBRARY, VIRTKEY, SHIFT, NOINVERT
VK_RETURN, ID_MEDIAWND_PLAYSELECTEDFILES, VIRTKEY, NOINVERT
VK_RETURN, ID_MEDIAWND_ENQUEUESELECTEDFILES, VIRTKEY, SHIFT, NOINVERT
VK_RETURN, IDC_BUTTON_CUSTOM, VIRTKEY, SHIFT, CONTROL, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NULLSOFT_HISTORY "Nullsoft History v%s"
65535 "{F8756C00-11D2-4857-8C50-163AE4A57783}"
END
STRINGTABLE
BEGIN
IDS_HISTORY "History"
IDS_DELAYLOAD_FAILURE "History was unable to load library ('%s') which is required. \nHistory cannot continue succesfully and will be turned off."
IDS_ERROR "Error"
IDS_SCANNING_ELLIPSE "Scanning..."
IDS_COL_LAST_PLAYED "Last Played"
IDS_COL_PLAY_COUNT "Play Count"
IDS_COL_TITLE "Title"
IDS_COL_LENGTH "Length"
IDS_COL_FILENAME "Filename"
IDS_EST_TIME_NO_SECS "%d %s, %u %s [%u:%02u estimated playtime]"
IDS_EST_TIME_HAS_SECS "%d %s, %u %s [%u:%02u:%02u estimated playtime]"
IDS_SCANNING "Scanning"
IDS_ITEM "item"
IDS_ITEMS "items"
END
STRINGTABLE
BEGIN
IDS_PLAY "play"
IDS_PLAYS "plays"
IDS_DAY "day"
IDS_DAYS "days"
IDS_REMOVE_ALL_HISTORY "Are you sure you want to reset your playing history?"
IDS_CONFIRMATION "Confirmation"
IDS_DISABLED "Disabled"
IDS_PODCAST_ONLY "Enabled for Podcast files only"
IDS_ANY_APPLICABLE "Enabled for any applicable files"
END
STRINGTABLE
BEGIN
IDS_COL_OFFSET "Play Offset"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,94 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29509.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ml_history", "ml_history.vcxproj", "{840EEC3D-03D7-4186-8FC7-763392D13309}"
ProjectSection(ProjectDependencies) = postProject
{57C90706-B25D-4ACA-9B33-95CDB2427C27} = {57C90706-B25D-4ACA-9B33-95CDB2427C27}
{4D25C321-7F8B-424E-9899-D80A364BAF1A} = {4D25C321-7F8B-424E-9899-D80A364BAF1A}
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11} = {44AEBB50-1331-4F2E-8AEC-56C82DE16C11}
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915} = {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}
{E105A0A2-7391-47C5-86AC-718003524C3D} = {E105A0A2-7391-47C5-86AC-718003524C3D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nde", "..\nde\nde.vcxproj", "{4D25C321-7F8B-424E-9899-D80A364BAF1A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nx", "..\replicant\nx\nx.vcxproj", "{57C90706-B25D-4ACA-9B33-95CDB2427C27}"
ProjectSection(ProjectDependencies) = postProject
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11} = {44AEBB50-1331-4F2E-8AEC-56C82DE16C11}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nu", "..\replicant\nu\nu.vcxproj", "{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jnetlib", "..\replicant\jnetlib\jnetlib.vcxproj", "{E105A0A2-7391-47C5-86AC-718003524C3D}"
ProjectSection(ProjectDependencies) = postProject
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11} = {44AEBB50-1331-4F2E-8AEC-56C82DE16C11}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\replicant\zlib\zlib.vcxproj", "{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{840EEC3D-03D7-4186-8FC7-763392D13309}.Debug|Win32.ActiveCfg = Debug|Win32
{840EEC3D-03D7-4186-8FC7-763392D13309}.Debug|Win32.Build.0 = Debug|Win32
{840EEC3D-03D7-4186-8FC7-763392D13309}.Debug|x64.ActiveCfg = Debug|x64
{840EEC3D-03D7-4186-8FC7-763392D13309}.Debug|x64.Build.0 = Debug|x64
{840EEC3D-03D7-4186-8FC7-763392D13309}.Release|Win32.ActiveCfg = Release|Win32
{840EEC3D-03D7-4186-8FC7-763392D13309}.Release|Win32.Build.0 = Release|Win32
{840EEC3D-03D7-4186-8FC7-763392D13309}.Release|x64.ActiveCfg = Release|x64
{840EEC3D-03D7-4186-8FC7-763392D13309}.Release|x64.Build.0 = Release|x64
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Debug|Win32.ActiveCfg = Debug|Win32
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Debug|Win32.Build.0 = Debug|Win32
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Debug|x64.ActiveCfg = Debug|x64
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Debug|x64.Build.0 = Debug|x64
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Release|Win32.ActiveCfg = Release|Win32
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Release|Win32.Build.0 = Release|Win32
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Release|x64.ActiveCfg = Release|x64
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Release|x64.Build.0 = Release|x64
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|Win32.ActiveCfg = Debug|Win32
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|Win32.Build.0 = Debug|Win32
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|x64.ActiveCfg = Debug|x64
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|x64.Build.0 = Debug|x64
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|Win32.ActiveCfg = Release|Win32
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|Win32.Build.0 = Release|Win32
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|x64.ActiveCfg = Release|x64
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|x64.Build.0 = Release|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|Win32.ActiveCfg = Debug|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|Win32.Build.0 = Debug|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|x64.ActiveCfg = Debug|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|x64.Build.0 = Debug|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|Win32.ActiveCfg = Release|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|Win32.Build.0 = Release|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|x64.ActiveCfg = Release|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|x64.Build.0 = Release|x64
{E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|Win32.ActiveCfg = Debug|Win32
{E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|Win32.Build.0 = Debug|Win32
{E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|x64.ActiveCfg = Debug|x64
{E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|x64.Build.0 = Debug|x64
{E105A0A2-7391-47C5-86AC-718003524C3D}.Release|Win32.ActiveCfg = Release|Win32
{E105A0A2-7391-47C5-86AC-718003524C3D}.Release|Win32.Build.0 = Release|Win32
{E105A0A2-7391-47C5-86AC-718003524C3D}.Release|x64.ActiveCfg = Release|x64
{E105A0A2-7391-47C5-86AC-718003524C3D}.Release|x64.Build.0 = Release|x64
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}.Debug|Win32.ActiveCfg = Debug|Win32
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}.Debug|Win32.Build.0 = Debug|Win32
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}.Debug|x64.ActiveCfg = Debug|x64
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}.Debug|x64.Build.0 = Debug|x64
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}.Release|Win32.ActiveCfg = Release|Win32
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}.Release|Win32.Build.0 = Release|Win32
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}.Release|x64.ActiveCfg = Release|x64
{44AEBB50-1331-4F2E-8AEC-56C82DE16C11}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C4E799C1-027B-487B-8E1A-31F2D26A1AFE}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,341 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{840EEC3D-03D7-4186-8FC7-763392D13309}</ProjectGuid>
<RootNamespace>ml_history</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;_DEBUG;_WINDOWS;_USRDLL;ML_HISTORY_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>true</BufferSecurityCheck>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Manifest>
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;_DEBUG;_WINDOWS;_USRDLL;ML_HISTORY_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>true</BufferSecurityCheck>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Manifest>
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;NDEBUG;_WINDOWS;_USRDLL;ML_HISTORY_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Manifest>
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;NDEBUG;_WINDOWS;_USRDLL;ML_HISTORY_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Manifest>
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\General\gen_ml\config.cpp" />
<ClCompile Include="..\..\General\gen_ml\gaystring.cpp" />
<ClCompile Include="..\..\General\gen_ml\menu.cpp" />
<ClCompile Include="..\..\..\nu\DialogSkinner.cpp" />
<ClCompile Include="..\..\..\nu\listview.cpp" />
<ClCompile Include="..\..\..\nu\MediaLibraryInterface.cpp" />
<ClCompile Include="..\..\..\nu\menushortcuts.cpp" />
<ClCompile Include="..\..\..\nu\sort.cpp" />
<ClCompile Include="..\..\..\Winamp\strutil.cpp" />
<ClCompile Include="api_history.cpp" />
<ClCompile Include="HistoryAPI.cpp" />
<ClCompile Include="HistoryAPIFactory.cpp" />
<ClCompile Include="JSAPI2_Creator.cpp" />
<ClCompile Include="JSAPI2_HistoryAPI.cpp" />
<ClCompile Include="JSAPI2_HistoryRecord.cpp" />
<ClCompile Include="JSAPI2_HistoryRecordList.cpp" />
<ClCompile Include="Main.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">main.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="ml_history.cpp" />
<ClCompile Include="prefs.cpp" />
<ClCompile Include="view_history.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\General\gen_ml\config.h" />
<ClInclude Include="..\..\General\gen_ml\gaystring.h" />
<ClInclude Include="..\..\General\gen_ml\menu.h" />
<ClInclude Include="..\..\..\nu\menushortcuts.h" />
<ClInclude Include="..\..\..\Winamp\strutil.h" />
<ClInclude Include="api__ml_history.h" />
<ClInclude Include="api_history.h" />
<ClInclude Include="history.h" />
<ClInclude Include="HistoryAPI.h" />
<ClInclude Include="HistoryAPIFactory.h" />
<ClInclude Include="JSAPI2_Creator.h" />
<ClInclude Include="JSAPI2_HistoryAPI.h" />
<ClInclude Include="JSAPI2_HistoryRecord.h" />
<ClInclude Include="JSAPI2_HistoryRecordList.h" />
<ClInclude Include="Main.h" />
<ClInclude Include="ml_history.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<Text Include="..\ml_local\nde_error.txt" />
<Text Include="db_error.txt" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ml_history.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="resources\ti_history_items_16x16x16.bmp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\nde\nde.vcxproj">
<Project>{4d25c321-7f8b-424e-9899-d80a364baf1a}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="api_history.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HistoryAPI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HistoryAPIFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JSAPI2_Creator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JSAPI2_HistoryAPI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JSAPI2_HistoryRecord.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JSAPI2_HistoryRecordList.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ml_history.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="prefs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="view_history.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\General\gen_ml\config.cpp">
<Filter>Source Files\gen_ml</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\DialogSkinner.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\General\gen_ml\gaystring.cpp">
<Filter>Source Files\gen_ml</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\listview.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\MediaLibraryInterface.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\General\gen_ml\menu.cpp">
<Filter>Source Files\gen_ml</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\menushortcuts.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\sort.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Winamp\strutil.cpp">
<Filter>Source Files\Winamp</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="api__ml_history.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="api_history.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="history.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HistoryAPI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HistoryAPIFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JSAPI2_Creator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JSAPI2_HistoryAPI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JSAPI2_HistoryRecord.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JSAPI2_HistoryRecordList.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Main.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ml_history.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\General\gen_ml\config.h">
<Filter>Header Files\gen_ml</Filter>
</ClInclude>
<ClInclude Include="..\..\General\gen_ml\gaystring.h">
<Filter>Header Files\gen_ml</Filter>
</ClInclude>
<ClInclude Include="..\..\General\gen_ml\menu.h">
<Filter>Header Files\gen_ml</Filter>
</ClInclude>
<ClInclude Include="..\..\..\nu\menushortcuts.h">
<Filter>Header Files\nu</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Winamp\strutil.h">
<Filter>Header Files\Winamp</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\ml_local\nde_error.txt" />
<Text Include="db_error.txt" />
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{c2e8f027-5cef-4e02-911f-4719fc3ae234}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{a71fca4c-7b5a-4857-9d5d-ac9a8635df44}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{bd330ba0-d0e2-4ac8-b30d-b936c4549d0c}</UniqueIdentifier>
</Filter>
<Filter Include="Image Files">
<UniqueIdentifier>{b97ef514-3134-4462-b767-54f001121b05}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\gen_ml">
<UniqueIdentifier>{73085ff5-df6e-41f0-a474-a193e6007e23}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nu">
<UniqueIdentifier>{6091f753-b15a-4842-b822-d511183811d7}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Winamp">
<UniqueIdentifier>{02146aa6-27b8-4603-89ac-f219ea316867}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\gen_ml">
<UniqueIdentifier>{91facc1d-0b70-4a53-a029-b731c6a5fc00}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\nu">
<UniqueIdentifier>{a9cf0eec-25c4-45ad-a116-77cc32baf3fa}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Winamp">
<UniqueIdentifier>{b4d6ce84-5fe5-48af-a5b1-f0e01e83d9c5}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ml_history.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Image Include="resources\ti_history_items_16x16x16.bmp">
<Filter>Image Files</Filter>
</Image>
</ItemGroup>
</Project>

View file

@ -0,0 +1,178 @@
#include "main.h"
#include "..\..\General\gen_ml/config.h"
#include "resource.h"
void hideShowRecentItemsCheckboxes(HWND hwndDlg)
{
int enabled = IsDlgButtonChecked(hwndDlg, IDC_CHECK1);
int wait_secs = !!g_config->ReadInt(L"recent_wait_secs",0);
int wait_percent = !!g_config->ReadInt(L"recent_wait_percent",0);
int wait_end = !!g_config->ReadInt(L"recent_wait_end",0);
EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK2), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK3), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK4), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK5), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK6), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK7), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT1), enabled && !!g_config->ReadInt(L"recent_limitd",1));
EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC1), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC3), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC4), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC5), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC6), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT2), enabled && wait_secs);
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT3), enabled && wait_percent);
EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC7), enabled && !(wait_end && !wait_secs && !wait_percent));
EnableWindow(GetDlgItem(hwndDlg, IDC_COMBO1), enabled && !(wait_end && !wait_secs && !wait_percent));
}
BOOL CALLBACK PrefsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
static int need_ref;
switch (uMsg)
{
case WM_INITDIALOG:
{
CheckDlgButton(hwndDlg,IDC_CHECK2,(g_config->ReadInt(L"recent_track",1)&1)?BST_CHECKED:0);
CheckDlgButton(hwndDlg,IDC_CHECK3,(g_config->ReadInt(L"recent_track",1)&2)?0:BST_CHECKED);
CheckDlgButton(hwndDlg,IDC_CHECK1,!!g_config->ReadInt(L"showrecentitems",1));
CheckDlgButton(hwndDlg,IDC_CHECK4,!!g_config->ReadInt(L"recent_limitd",1));
CheckDlgButton(hwndDlg,IDC_CHECK5,!!g_config->ReadInt(L"recent_wait_secs",0));
CheckDlgButton(hwndDlg,IDC_CHECK6,!!g_config->ReadInt(L"recent_wait_percent",0));
CheckDlgButton(hwndDlg,IDC_CHECK7,!!g_config->ReadInt(L"recent_wait_end",0));
int item = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_DISABLED));
SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_SETITEMDATA,item,0);
item = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_PODCAST_ONLY));
SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_SETITEMDATA,item,1);
item = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_ANY_APPLICABLE));
SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_SETITEMDATA,item,2);
SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_SETCURSEL,g_config->ReadInt(L"resumeplayback",0),0);
SetDlgItemInt(hwndDlg,IDC_EDIT1,g_config->ReadInt(L"recent_limitnd",30),FALSE);
SetDlgItemInt(hwndDlg,IDC_EDIT2,g_config->ReadInt(L"recent_wait_secs_lim",5),FALSE);
SetDlgItemInt(hwndDlg,IDC_EDIT3,g_config->ReadInt(L"recent_wait_percent_lim",50),FALSE);
need_ref=0;
hideShowRecentItemsCheckboxes(hwndDlg);
break;
}
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_CHECK1:
{
int a=!!IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
g_config->WriteInt(L"showrecentitems",a);
if (a) history_init();
else history_quit();
hideShowRecentItemsCheckboxes(hwndDlg);
}
break;
case IDC_EDIT1:
if (HIWORD(wParam) == EN_CHANGE)
{
BOOL t;
int v=GetDlgItemInt(hwndDlg,IDC_EDIT1,&t,FALSE);
if (t) g_config->WriteInt(L"recent_limitnd",v);
need_ref++;
}
break;
case IDC_CHECK4:
g_config->WriteInt(L"recent_limitd",!!IsDlgButtonChecked(hwndDlg,IDC_CHECK4));
EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),!!g_config->ReadInt(L"recent_limitd",1));
need_ref++;
break;
case IDC_CHECK2:
case IDC_CHECK3:
g_config->WriteInt(L"recent_track",(IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0) | (IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?0:2));
break;
case IDC_CHECK5:
g_config->WriteInt(L"recent_wait_secs",!!IsDlgButtonChecked(hwndDlg,IDC_CHECK5));
hideShowRecentItemsCheckboxes(hwndDlg);
break;
case IDC_CHECK6:
g_config->WriteInt(L"recent_wait_percent",!!IsDlgButtonChecked(hwndDlg,IDC_CHECK6));
hideShowRecentItemsCheckboxes(hwndDlg);
break;
case IDC_CHECK7:
g_config->WriteInt(L"recent_wait_end",!!IsDlgButtonChecked(hwndDlg,IDC_CHECK7));
hideShowRecentItemsCheckboxes(hwndDlg);
break;
case IDC_COMBO1:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
int item = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
if (item != CB_ERR)
{
g_config->WriteInt(L"resumeplayback", (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO1,CB_GETITEMDATA,item,0));
}
}
break;
case IDC_EDIT2:
if (HIWORD(wParam) == EN_CHANGE)
{
BOOL t;
int v=GetDlgItemInt(hwndDlg,IDC_EDIT2,&t,FALSE);
if (t)
{
if(v < 0)
{
v = 1;
SetDlgItemInt(hwndDlg, IDC_EDIT2, v, 0);
}
g_config->WriteInt(L"recent_wait_secs_lim",v);
}
need_ref++;
}
break;
case IDC_EDIT3:
if (HIWORD(wParam) == EN_CHANGE)
{
BOOL t;
int v=GetDlgItemInt(hwndDlg,IDC_EDIT3,&t,FALSE);
if(t)
{
int tweaked = 0;
if(v > 99){
v = 99;
tweaked = 1;
}
else if(v < 1)
{
v = 1;
tweaked = 1;
}
if(tweaked)
{
SetDlgItemInt(hwndDlg, IDC_EDIT3, v, 0);
}
g_config->WriteInt(L"recent_wait_percent_lim",v);
}
need_ref++;
}
break;
};
break;
case WM_DESTROY:
if (need_ref)
{
g_config->WriteInt(L"recent_limitlt",0); // make sure it gets refreshed
// TODO: only do this if the history view is open
PostMessage(plugin.hwndLibraryParent,WM_USER+30,0,0);
}
break;
}
return 0;
}

View file

@ -0,0 +1,92 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ml_history.rc
//
#define IDS_HISTORY 1
#define IDS_DELAYLOAD_FAILURE 2
#define IDS_ERROR 3
#define IDS_SCANNING_ELLIPSE 4
#define IDS_COL_LAST_PLAYED 5
#define IDS_COL_PLAY_COUNT 6
#define IDS_COL_TITLE 7
#define IDS_COL_LENGTH 8
#define IDS_COL_FILENAME 9
#define IDS_EST_TIME_NO_SECS 10
#define IDS_EST_TIME_HAS_SECS 11
#define IDS_SCANNING 13
#define IDS_ITEM 14
#define IDS_ITEMS 15
#define IDS_PLAY 16
#define IDS_PLAYS 17
#define IDS_DAY 18
#define IDS_DAYS 19
#define IDS_REMOVE_ALL_HISTORY 20
#define IDS_CONFIRMATION 21
#define IDS_DISABLED 22
#define IDS_PODCAST_ONLY 23
#define IDS_ANY_APPLICABLE 24
#define IDR_CONTEXTMENUS 101
#define IDD_DIALOG1 102
#define IDB_BITMAP1 103
#define IDB_TREEITEM_RECENT 103
#define IDD_PREFS 104
#define IDS_COL_OFFSET 107
#define IDR_ACCELERATOR1 109
#define IDR_VIEW_ACCELERATORS 109
#define IDR_DB_ERROR 110
#define IDD_VIEW_DB_ERROR 111
#define IDR_NDE_ERROR 111
#define IDD_VIEW_RECENTITEMS 246
#define IDC_BUTTON_CUSTOM 1000
#define IDC_LIST2 1001
#define IDC_STATIC6 1001
#define IDC_CLEAR 1005
#define IDC_QUICKSEARCH 1006
#define IDC_COMBO1 1006
#define IDC_MEDIASTATUS 1015
#define IDC_BUTTON_PLAY 1016
#define IDC_BUTTON_ENQUEUE 1017
#define IDC_SEARCHCAPTION 1020
#define IDC_CHECK1 1050
#define IDC_CHECK2 1051
#define IDC_CHECK3 1052
#define IDC_CHECK4 1053
#define IDC_EDIT1 1054
#define IDC_CHECK5 1055
#define IDC_EDIT2 1056
#define IDC_STATIC1 1057
#define IDC_STATIC2 1058
#define IDC_STATIC3 1059
#define IDC_STATIC4 1060
#define IDC_CHECK6 1061
#define IDC_EDIT3 1062
#define IDC_STATIC5 1063
#define IDC_CHECK7 1064
#define IDC_CHECK8 1065
#define IDC_STATIC7 1066
#define IDC_REMOVEBOOK 1084
#define IDC_DB_ERROR 1085
#define IDC_RESET_DB_ON_ERROR 1086
#define ID_MEDIAWND_PLAYSELECTEDFILES 40001
#define ID_MEDIAWND_ENQUEUESELECTEDFILES 40002
#define ID_MEDIAWND_ADDTOPLAYLIST 40003
#define ID_MEDIAWND_SELECTALL 40004
#define ID_PE_ID3 40005
#define ID_MEDIAWND_REMOVEFROMLIBRARY 40006
#define ID_MEDIAWND_EXPLOREFOLDER 40007
#define ID_NAVIGATION_PREFERENCES 40008
#define ID_NAVIGATION_HELP 40009
#define ID_MEDIAWND_REMOVEOFFSETFROMLIBRARY 40010
#define ID_RECENTWND_CLEARPLAYBACKOFFSET 40011
#define IDS_NULLSOFT_HISTORY 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 113
#define _APS_NEXT_COMMAND_VALUE 40012
#define _APS_NEXT_CONTROL_VALUE 1007
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 B

View file

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,0,3,0
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Winamp SA"
VALUE "FileDescription", "Winamp Media Library Plug-in"
VALUE "FileVersion", "2,0,3,0"
VALUE "InternalName", "Nullsoft History"
VALUE "LegalCopyright", "Copyright © 2003-2023 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "ml_history.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

File diff suppressed because it is too large Load diff