winamp/Src/Plugins/Library/ml_local/wa_subclass.cpp
2024-09-24 14:54:57 +02:00

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);
}