314 lines
8.4 KiB
C++
314 lines
8.4 KiB
C++
|
#include "main.h"
|
||
|
#include "api__ml_local.h"
|
||
|
#include "resource.h"
|
||
|
#include "../nu/listview.h"
|
||
|
|
||
|
#define WINAMP_FILE_ADDTOLIBRARY 40344
|
||
|
#define WINAMP_FILE_ADDCURRENTPLEDIT 40466
|
||
|
#define WINAMP_SHOWLIBRARY 40379
|
||
|
wchar_t *recent_fn = 0;
|
||
|
static HMENU last_viewmenu = 0;
|
||
|
WORD waMenuID = 0;
|
||
|
|
||
|
extern W_ListView resultlist;
|
||
|
extern volatile int no_lv_update;
|
||
|
void UpdateLocalResultsCache(const wchar_t *filename);
|
||
|
|
||
|
static void onPlayFileTrack()
|
||
|
{
|
||
|
int autoaddplays = g_config->ReadInt(L"autoaddplays", 0);
|
||
|
int trackplays = g_config->ReadInt(L"trackplays", 1);
|
||
|
if (!trackplays && !autoaddplays)
|
||
|
return ;
|
||
|
|
||
|
if (g_table && recent_fn)
|
||
|
{
|
||
|
wchar_t filename2[MAX_PATH] = {0}; // full lfn path if set
|
||
|
EnterCriticalSection(&g_db_cs);
|
||
|
|
||
|
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
|
||
|
int found=FindFileInDatabase(s, MAINTABLE_ID_FILENAME, recent_fn, filename2);
|
||
|
|
||
|
if (found) // if it's in the table already
|
||
|
{
|
||
|
if (trackplays) // if we're tracking plays
|
||
|
{
|
||
|
NDE_Scanner_Edit(s);
|
||
|
nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_PLAYCOUNT);
|
||
|
int cnt = f ? NDE_IntegerField_GetValue(f) : 0;
|
||
|
time_t t = time(NULL);
|
||
|
|
||
|
db_setFieldInt(s, MAINTABLE_ID_PLAYCOUNT, ++cnt);
|
||
|
db_setFieldInt(s, MAINTABLE_ID_LASTPLAY, (int)t);
|
||
|
if (asked_for_playcount)
|
||
|
PostMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_UPDTITLE);
|
||
|
|
||
|
// Issue a wasabi system callback after we have successfully added a file in the ml database
|
||
|
api_mldb::played_info info = {t, cnt};
|
||
|
WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_PLAYED, (size_t)recent_fn, (size_t)&info);
|
||
|
|
||
|
NDE_Scanner_Post(s);
|
||
|
// disabled in 5.65 (was added in 5.64?) as causing
|
||
|
// noticeable ui lockups on sync with large library
|
||
|
// so instead we'll risk it and flush on 50 instead
|
||
|
/*g_table_dirty = 0;
|
||
|
NDE_Table_Sync(g_table);*/
|
||
|
}
|
||
|
NDE_Table_DestroyScanner(g_table, s);
|
||
|
}
|
||
|
else // not found in main table, we are in the main table, time to add if set
|
||
|
{
|
||
|
NDE_Table_DestroyScanner(g_table, s);
|
||
|
|
||
|
if (autoaddplays)
|
||
|
{
|
||
|
int guess = -1, meta = -1, rec = 1;
|
||
|
autoscan_add_directory(recent_fn, &guess, &meta, &rec, 1); // use this folder's guess/meta options
|
||
|
if (guess == -1) guess = g_config->ReadInt(L"guessmode", 0);
|
||
|
if (meta == -1) meta = g_config->ReadInt(L"usemetadata", 1);
|
||
|
addFileToDb(recent_fn, 0, meta, guess, 1, (int)time(NULL));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (g_table_dirty > 50)
|
||
|
{
|
||
|
g_table_dirty = 0;
|
||
|
NDE_Table_Sync(g_table);
|
||
|
}
|
||
|
|
||
|
LeaveCriticalSection(&g_db_cs);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void onStartPlayFileTrack(const wchar_t *filename, bool resume)
|
||
|
{
|
||
|
if (!(wcsstr(filename, L"://") && _wcsnicmp(filename, L"cda://", 6) && _wcsnicmp(filename, L"file://", 7)))
|
||
|
{
|
||
|
int timer = -1, timer1 = -1, timer2 = -1;
|
||
|
|
||
|
KillTimer(plugin.hwndWinampParent, 8081);
|
||
|
if (!resume)
|
||
|
{
|
||
|
free(recent_fn);
|
||
|
recent_fn = _wcsdup(filename);
|
||
|
}
|
||
|
|
||
|
// wait for x seconds
|
||
|
if(g_config->ReadInt(L"trackplays_wait_secs",0))
|
||
|
{
|
||
|
timer1 = g_config->ReadInt(L"trackplays_wait_secs_lim",5)*1000;
|
||
|
}
|
||
|
|
||
|
// wait for x percent of the song (approx to a second)
|
||
|
if(g_config->ReadInt(L"trackplays_wait_percent",0))
|
||
|
{
|
||
|
basicFileInfoStructW bfiW = {0};
|
||
|
bfiW.filename = recent_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"trackplays_wait_percent_lim",50))/100;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 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;
|
||
|
}
|
||
|
|
||
|
// if no match or something went wrong then try to ensure the default timer value is used
|
||
|
SetTimer(plugin.hwndWinampParent, 8081, ((timer > 0)? timer : 350), NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void FileUpdated(const wchar_t *filename)
|
||
|
{
|
||
|
if (g_table)
|
||
|
{
|
||
|
EnterCriticalSection(&g_db_cs);
|
||
|
int guess = -1, meta = -1, rec = 1;
|
||
|
autoscan_add_directory(filename, &guess, &meta, &rec, 1); // use this folder's guess/meta options
|
||
|
if (guess == -1) guess = g_config->ReadInt(L"guessmode", 0);
|
||
|
if (meta == -1) meta = g_config->ReadInt(L"usemetadata", 1);
|
||
|
addFileToDb(filename, TRUE, meta, guess, 0, 0, true);
|
||
|
LeaveCriticalSection(&g_db_cs);
|
||
|
|
||
|
if (g_table_dirty > 10)
|
||
|
{
|
||
|
g_table_dirty = 0;
|
||
|
EnterCriticalSection(&g_db_cs);
|
||
|
NDE_Table_Sync(g_table);
|
||
|
LeaveCriticalSection(&g_db_cs);
|
||
|
}
|
||
|
|
||
|
if (!no_lv_update)
|
||
|
UpdateLocalResultsCache(filename);
|
||
|
}
|
||
|
ClearCache(filename);
|
||
|
ClearTitleHookCache();
|
||
|
}
|
||
|
|
||
|
LRESULT APIENTRY wa_newWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_TIMER:
|
||
|
if (recent_fn && wParam == 8081)
|
||
|
{
|
||
|
if (SendMessage(hwndDlg, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) > 350)
|
||
|
{
|
||
|
KillTimer(hwndDlg, 8081);
|
||
|
if (SendMessage(hwndDlg, WM_WA_IPC, 0, IPC_ISPLAYING) == 1)
|
||
|
{
|
||
|
onPlayFileTrack();
|
||
|
}
|
||
|
free(recent_fn);
|
||
|
recent_fn = 0;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case WM_WA_IPC:
|
||
|
switch (lParam)
|
||
|
{
|
||
|
case IPC_CB_MISC:
|
||
|
if (wParam == IPC_CB_MISC_TITLE)
|
||
|
{
|
||
|
if(!SendMessage(hwndDlg, WM_WA_IPC, 0, IPC_ISPLAYING))
|
||
|
{
|
||
|
KillTimer(hwndDlg, 8081);
|
||
|
}
|
||
|
}
|
||
|
else if (wParam == IPC_CB_MISC_PAUSE)
|
||
|
{
|
||
|
KillTimer(hwndDlg, 8081);
|
||
|
}
|
||
|
else if (wParam == IPC_CB_MISC_UNPAUSE)
|
||
|
{
|
||
|
if (recent_fn) onStartPlayFileTrack(recent_fn, true);
|
||
|
}
|
||
|
break;
|
||
|
case IPC_FILE_TAG_MAY_HAVE_UPDATEDW:
|
||
|
{
|
||
|
wchar_t *filename = (wchar_t *)wParam;
|
||
|
if (filename)
|
||
|
FileUpdated(filename);
|
||
|
}
|
||
|
break;
|
||
|
case IPC_FILE_TAG_MAY_HAVE_UPDATED:
|
||
|
{
|
||
|
char *filename = (char *)wParam;
|
||
|
if (filename)
|
||
|
FileUpdated(AutoWide(filename));
|
||
|
}
|
||
|
break;
|
||
|
case IPC_STOPPLAYING:
|
||
|
{
|
||
|
KillTimer(hwndDlg, 8081);
|
||
|
free(recent_fn);
|
||
|
recent_fn = 0;
|
||
|
}
|
||
|
break;
|
||
|
case IPC_GET_EXTENDED_FILE_INFO_HOOKABLE:
|
||
|
// guessing for metadata for when the library isn't open yet.
|
||
|
if (!g_table && wParam && !m_calling_getfileinfo) return doGuessProc(hwndDlg, uMsg, wParam, lParam);
|
||
|
break;
|
||
|
default:
|
||
|
{
|
||
|
if (lParam == IPC_CLOUD_ENABLED)
|
||
|
{
|
||
|
if (m_curview_hwnd) SendMessage(m_curview_hwnd, WM_APP + 6, 0, 0); //update current view
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case WM_INITMENUPOPUP:
|
||
|
{
|
||
|
HMENU hmenuPopup = (HMENU) wParam;
|
||
|
if (hmenuPopup == wa_play_menu)
|
||
|
{
|
||
|
if (last_viewmenu)
|
||
|
{
|
||
|
RemoveMenu(wa_play_menu, waMenuID, MF_BYCOMMAND);
|
||
|
DestroyMenu(last_viewmenu);
|
||
|
last_viewmenu = NULL;
|
||
|
}
|
||
|
|
||
|
mlGetTreeStruct mgts = { 1000, 55000, -1};
|
||
|
last_viewmenu = (HMENU)SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM) & mgts, ML_IPC_GETTREE);
|
||
|
if (last_viewmenu)
|
||
|
{
|
||
|
if (GetMenuItemCount(last_viewmenu) > 0)
|
||
|
{
|
||
|
int count = GetMenuItemCount(wa_play_menu);
|
||
|
MENUITEMINFOW menuItem = {sizeof(MENUITEMINFOW), MIIM_SUBMENU | MIIM_ID | MIIM_TYPE, MFT_STRING, MFS_ENABLED, waMenuID,
|
||
|
last_viewmenu, NULL, NULL, NULL, WASABI_API_LNGSTRINGW(IDS_MEDIA_LIBRARY_VIEW_RESULTS), 0};
|
||
|
InsertMenuItemW(wa_play_menu, count, TRUE, &menuItem);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DestroyMenu(last_viewmenu);
|
||
|
last_viewmenu = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case WM_COMMAND:
|
||
|
case WM_SYSCOMMAND:
|
||
|
WORD lowP = LOWORD(wParam);
|
||
|
if (lowP == WINAMP_FILE_ADDTOLIBRARY)
|
||
|
{
|
||
|
if (!plugin.hwndLibraryParent || !IsWindowVisible(plugin.hwndLibraryParent))
|
||
|
{
|
||
|
SendMessage(plugin.hwndWinampParent, WM_COMMAND, MAKEWPARAM(WINAMP_SHOWLIBRARY, 0), 0L);
|
||
|
}
|
||
|
add_to_library(plugin.hwndLibraryParent);
|
||
|
}
|
||
|
else if (lowP == WINAMP_FILE_ADDCURRENTPLEDIT)
|
||
|
{
|
||
|
add_pledit_to_library();
|
||
|
}
|
||
|
else if (uMsg == WM_COMMAND && wParam > 45000 && wParam < 55000)
|
||
|
{
|
||
|
int n = wParam - 45000;
|
||
|
if (m_query_list[n])
|
||
|
{
|
||
|
mediaLibrary.SwitchToPluginView(n);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
else if (uMsg == WM_COMMAND && wParam > 55000 && wParam < 65000)
|
||
|
{
|
||
|
int n = wParam - 55000;
|
||
|
if (m_query_list[n])
|
||
|
{
|
||
|
queryItem *item = m_query_list[n];
|
||
|
wchar_t configDir[MAX_PATH] = {0};
|
||
|
PathCombineW(configDir, g_viewsDir, item->metafn);
|
||
|
C_Config viewconf(configDir);
|
||
|
main_playQuery(&viewconf, item->query, 0, 1);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return CallWindowProcW(wa_oldWndProc, hwndDlg, uMsg, wParam, lParam);
|
||
|
}
|