aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Library/ml_rg/Progress.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Library/ml_rg/Progress.cpp')
-rw-r--r--Src/Plugins/Library/ml_rg/Progress.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_rg/Progress.cpp b/Src/Plugins/Library/ml_rg/Progress.cpp
new file mode 100644
index 00000000..18c26031
--- /dev/null
+++ b/Src/Plugins/Library/ml_rg/Progress.cpp
@@ -0,0 +1,261 @@
+#include "main.h"
+#include "resource.h"
+#include"api__ml_rg.h"
+#include <strsafe.h>
+
+struct Progress
+{
+ Progress()
+ {
+ processedFiles = 0;
+ currentBytes = 0;
+ totalBytes = 0;
+ activeHWND = 0;
+ threadHandle = 0;
+ openDialogs = 0;
+ done = false;
+ killSwitch = 0;
+ }
+
+ size_t processedFiles;
+ uint64_t currentBytes;
+ uint32_t totalBytes;
+ WorkQueue activeQueue;
+ HWND activeHWND;
+ HANDLE threadHandle;
+ size_t openDialogs;
+ bool done;
+ int killSwitch;
+};
+
+DWORD WINAPI ThreadProc(void *param)
+{
+ Progress *progress = (Progress *)param;
+ ProgressCallback callback(progress->activeHWND);
+ progress->activeQueue.Calculate(&callback, &progress->killSwitch);
+ PostMessage(progress->activeHWND, WM_USER + 2, 0, 0);
+
+ return 0;
+}
+
+void getViewport(RECT *r, HWND wnd, int full, RECT *sr)
+{
+ POINT *p = NULL;
+
+ if (p || sr || wnd)
+ {
+ HMONITOR hm = NULL;
+
+ if (sr)
+ hm = MonitorFromRect(sr, MONITOR_DEFAULTTONEAREST);
+ else if (wnd)
+ hm = MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
+ else if (p)
+ hm = MonitorFromPoint(*p, MONITOR_DEFAULTTONEAREST);
+
+ if (hm)
+ {
+ MONITORINFOEXW mi;
+ memset(&mi, 0, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+
+ if (GetMonitorInfoW(hm, &mi))
+ {
+ if (!full)
+ *r = mi.rcWork;
+ else
+ *r = mi.rcMonitor;
+
+ return ;
+ }
+ }
+ }
+ if (full)
+ { // this might be borked =)
+ r->top = r->left = 0;
+ r->right = GetSystemMetrics(SM_CXSCREEN);
+ r->bottom = GetSystemMetrics(SM_CYSCREEN);
+ }
+ else
+ {
+ SystemParametersInfoW(SPI_GETWORKAREA, 0, r, 0);
+ }
+}
+
+BOOL windowOffScreen(HWND hwnd, POINT pt)
+{
+ RECT r = {0}, wnd = {0}, sr = {0};
+ GetWindowRect(hwnd, &wnd);
+ sr.left = pt.x;
+ sr.top = pt.y;
+ sr.right = sr.left + (wnd.right - wnd.left);
+ sr.bottom = sr.top + (wnd.bottom - wnd.top);
+ getViewport(&r, hwnd, 0, &sr);
+ return !PtInRect(&r, pt);
+}
+
+void SaveWindowPos(HWND hwnd)
+{
+ RECT rect = {0};
+ GetWindowRect(hwnd, &rect);
+ char buf[16] = {0};
+ StringCchPrintfA(buf, 16, "%d", rect.left);
+ WritePrivateProfileStringA("ml_rg", "prog_x", buf, iniFile);
+ StringCchPrintfA(buf, 16, "%d", rect.top);
+ WritePrivateProfileStringA("ml_rg", "prog_y", buf, iniFile);
+}
+
+INT_PTR WINAPI ReplayGainProgressProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ Progress *progress = (Progress *)lParam;
+ progress->killSwitch = 0;
+ progress->done = false;
+ progress->openDialogs = 0;
+ progress->processedFiles = 0;
+ progress->activeHWND = hwndDlg;
+
+ wchar_t dummy[64] = {0};
+ StringCchPrintfW(dummy, 64, WASABI_API_LNGSTRINGW(IDS_1_OF_X_FILES), progress->activeQueue.totalFiles);
+ SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, dummy);
+
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)progress);
+ DWORD threadId;
+ progress->threadHandle = CreateThread(NULL, 0, ThreadProc, (void *)progress, CREATE_SUSPENDED, &threadId);
+ SetThreadPriority(progress->threadHandle, THREAD_PRIORITY_IDLE);
+ ResumeThread(progress->threadHandle);
+
+ POINT pt = {(LONG)GetPrivateProfileIntA("ml_rg", "prog_x", -1, iniFile),
+ (LONG)GetPrivateProfileIntA("ml_rg", "prog_y", -1, iniFile)};
+ if (!windowOffScreen(hwndDlg, pt))
+ SetWindowPos(hwndDlg, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
+ else
+ ShowWindow(hwndDlg, SW_SHOW);
+ }
+ break;
+ case WM_DESTROY:
+ {
+ SaveWindowPos(hwndDlg);
+ Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ CloseHandle(progress->threadHandle);
+ progress->activeHWND = 0;
+ delete progress;
+ }
+ break;
+ case WM_USER: // file finished
+ {
+ Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ progress->processedFiles++;
+
+ if (progress->processedFiles + 1 > progress->activeQueue.totalFiles)
+ SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, WASABI_API_LNGSTRINGW(IDS_FINISHED));
+ else
+ {
+ wchar_t dummy[64] = {0};
+ StringCchPrintfW(dummy, 64,
+ WASABI_API_LNGSTRINGW(IDS_X_OF_X_FILES),
+ progress->processedFiles + 1, progress->activeQueue.totalFiles);
+ SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, dummy);
+ }
+ }
+ break;
+ case WM_USER + 1: // album done
+ {
+ Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ WorkQueue::RGWorkQueue *queue = (WorkQueue::RGWorkQueue *)lParam;
+ SaveWindowPos(hwndDlg);
+ if (config_ask && config_ask_each_album)
+ {
+ progress->openDialogs++;
+ DoResults(*queue);
+ progress->openDialogs--;
+ if (!progress->openDialogs && progress->done)
+ DestroyWindow(hwndDlg);
+ }
+ else if (config_ask == 0)
+ {
+ WriteAlbum(*queue);
+ }
+ }
+ break;
+ case WM_USER + 2: // all tracks done
+ {
+ Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ ShowWindow(hwndDlg, SW_HIDE);
+ SaveWindowPos(hwndDlg);
+ if (config_ask && config_ask_each_album == 0)
+ {
+ DoResults(progress->activeQueue);
+ }
+ progress->killSwitch = 1;
+ WaitForSingleObject(progress->threadHandle, INFINITE);
+ progress->done = true;
+ if (!progress->openDialogs)
+ DestroyWindow(hwndDlg);
+ }
+ break;
+ case WM_USER + 3: // total bytes of current file
+ {
+ Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ progress->currentBytes = 0;
+ progress->totalBytes = (uint32_t)lParam;
+ if (progress->totalBytes == 0)
+ {
+ SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, WASABI_API_LNGSTRINGW(IDS_PROCESSING));
+ }
+ else
+ {
+ wchar_t dummy[64] = {0};
+ StringCchPrintfW(dummy, 64, L"%u%%", (progress->currentBytes * 100) / progress->totalBytes);
+ SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, dummy);
+ }
+ }
+ break;
+ case WM_USER + 4: // more bytes read
+ {
+ Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ progress->currentBytes += lParam;
+ if (progress->totalBytes == 0)
+ {
+ SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, WASABI_API_LNGSTRINGW(IDS_PROCESSING));
+ }
+ else
+ {
+ wchar_t dummy[64] = {0};
+ StringCchPrintfW(dummy, 64, L"%u%%", (progress->currentBytes * 100) / progress->totalBytes);
+ SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, dummy);
+ }
+ }
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ {
+ Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ progress->killSwitch = 1;
+ break;
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+void DoProgress(WorkQueue &workQueue)
+{
+ Progress *progress = new Progress;
+ progress->activeQueue = workQueue; // this is a huge slow copy, but I don't care at the moment
+ WASABI_API_CREATEDIALOGPARAMW(IDD_PROGRESS, GetDialogBoxParent(), ReplayGainProgressProc, (LPARAM)progress);
+}
+
+HWND GetDialogBoxParent()
+{
+ HWND parent = (HWND)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
+ if (!parent || parent == (HWND)1)
+ return plugin.hwndWinampParent;
+ return parent;
+} \ No newline at end of file