diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Library/ml_disc/copyprogress.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Library/ml_disc/copyprogress.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_disc/copyprogress.cpp | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_disc/copyprogress.cpp b/Src/Plugins/Library/ml_disc/copyprogress.cpp new file mode 100644 index 00000000..36bd36a7 --- /dev/null +++ b/Src/Plugins/Library/ml_disc/copyprogress.cpp @@ -0,0 +1,360 @@ +#include "main.h" +#include "./copyfiles.h" +#include "./copyinternal.h" +#include "./resource.h" +#include "./settings.h" +#include "../nu/trace.h" +#include <shlwapi.h> +#include <strsafe.h> + +typedef struct _PROGDLG +{ + COPYDATA *pCopyData; + HBITMAP hbmpLogo; +} PROGDLG; + +#define PROGDLG_PROP TEXT("PROGDLG") +#define GetProgDlg(__hdlg) ((PROGDLG*)GetProp((__hdlg), PROGDLG_PROP)) + +#define SetControlText(__hwnd, __ctrlId, __pszText)\ + SetDlgItemText((__hwnd), (__ctrlId), (IS_INTRESOURCE(__pszText) ? WASABI_API_LNGSTRINGW((UINT)(UINT_PTR)(__pszText)) : (__pszText))) + +#define SetTaskText(__hwnd, __pszText) SetControlText(__hwnd, IDC_LBL_TASK, __pszText) +#define SetOperationText(__hwnd, __pszText) SetControlText(__hwnd, IDC_LBL_OPERATION, __pszText) + + +static INT_PTR CopyProgress_OnInitDialog(HWND hdlg, HWND hFocus, LPARAM lParam) +{ + HWND hctrl; + PROGDLG *ppd = (PROGDLG*)calloc(1, sizeof(PROGDLG)); + if (!ppd) return 0; + + SetProp(hdlg, PROGDLG_PROP, ppd); + ppd->pCopyData = (COPYDATA*)lParam; + CopyFiles_AddRef(ppd->pCopyData); + if (ppd->pCopyData && ppd->pCopyData->hOwner) + { + RECT rw; + if (!GetWindowRect(ppd->pCopyData->hOwner, &rw)) SetRect(&rw, 0, 0, 0, 0); + if (hdlg && rw.left != rw.right) + { + RECT rw2; + GetWindowRect(hdlg, &rw2); + SetWindowPos(hdlg, HWND_TOP, + rw.left + ((rw.right - rw.left) - (rw2.right - rw2.left))/2, + rw.top + ((rw.bottom - rw.top) - (rw2.bottom - rw2.top))/2, + 0, 0, SWP_NOACTIVATE | SWP_NOSIZE); + } + } + + hctrl = GetDlgItem(hdlg, IDC_PRG_TOTAL); + if (NULL != hctrl) + { + SendMessage(hctrl, PBM_SETRANGE32, (WPARAM)0, (LPARAM)100); + SendMessage(hctrl, PBM_SETPOS, (WPARAM)0, 0L); + SendMessage(hctrl, PBM_SETSTEP, (WPARAM)1, 0L); + } + + SetTaskText(hdlg, MAKEINTRESOURCE(IDS_COPY_TASK_PREPARE)); + SetOperationText(hdlg, TEXT("")); + + SendMessage(hdlg, DM_REPOSITION, 0, 0L); + + ppd->hbmpLogo = CopyFiles_LoadResourcePng(MAKEINTRESOURCE(IDB_FILECOPY)); + if (ppd->hbmpLogo) SendDlgItemMessage(hdlg, IDC_PIC_LOGO, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)ppd->hbmpLogo); + else ShowWindow(GetDlgItem(hdlg, IDC_PIC_LOGO), SW_HIDE); + + return FALSE; +} + +static void CopyProgress_OnDestroy(HWND hdlg) +{ + PROGDLG *ppd = GetProgDlg(hdlg); + RemoveProp(hdlg, PROGDLG_PROP); + if (ppd) + { + if (ppd->pCopyData) CopyFiles_Release(ppd->pCopyData); + + if (ppd->hbmpLogo) + { + HBITMAP hbmp = (HBITMAP)SendDlgItemMessage(hdlg, IDC_PIC_LOGO, STM_GETIMAGE, IMAGE_BITMAP, 0L); + if (hbmp != ppd->hbmpLogo) DeleteObject(hbmp); + DeleteObject(ppd->hbmpLogo); + } + + free(ppd); + } +} + +static void ShowErrorBox(HWND hdlg) +{ + PROGDLG *ppd = GetProgDlg(hdlg); + if (!ppd || !ppd->pCopyData) return; + + + TCHAR szBuffer[2048] = {0}, szFormat[256] = {0}, szUnknown[64] = {0}; + LPTSTR pszMessage; + + if (ERROR_REQUEST_ABORTED == ppd->pCopyData->errorCode) return; // ignore user aborts + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, + ppd->pCopyData->errorCode, 0, (LPTSTR)&pszMessage, 0, NULL); + + WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN, szUnknown, ARRAYSIZE(szUnknown)); + WASABI_API_LNGSTRINGW_BUF(IDS_COPY_ERROR_MESSAGE, szFormat, ARRAYSIZE(szFormat)); + + StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szFormat, + ppd->pCopyData->szDestination, + (ppd->pCopyData->errorMsgId) ? WASABI_API_LNGSTRINGW(ppd->pCopyData->errorMsgId) : szUnknown, + ppd->pCopyData->errorCode, + (pszMessage) ? pszMessage : szUnknown); + + MessageBox(hdlg, szBuffer, WASABI_API_LNGSTRINGW(IDS_COPY_ERROR_CAPTION), MB_OK | MB_ICONERROR); + if (pszMessage) LocalFree(pszMessage); +} + +static void CopyProgress_OnDisplayNextFile(HWND hdlg, INT iFile, INT iCount) +{ + PROGDLG *ppd = GetProgDlg(hdlg); + if (!ppd || !ppd->pCopyData) return; + SetOperationText(hdlg, PathFindFileName(ppd->pCopyData->ppszFiles[iFile])); + +} + + +static INT_PTR CopyProgress_OnDestiantionNotExist(HWND hdlg, LPCTSTR pszDestination) +{ + PROGDLG *ppd = GetProgDlg(hdlg); + if (!ppd || !ppd->pCopyData) return FALSE; + QUESTIONBOX qb = {0}; + TCHAR szFormat[MAX_PATH] = {0}, szMessage[MAX_PATH*2] = {0}; + + WASABI_API_LNGSTRINGW_BUF(IDS_DESTINATION_NOT_EXIST_FORMAT, szFormat, ARRAYSIZE(szFormat)); + StringCchPrintf(szMessage, ARRAYSIZE(szMessage), szFormat, pszDestination); + + qb.hParent =hdlg; + qb.pszIcon = IDI_QUESTION; + qb.pszTitle = MAKEINTRESOURCE(IDS_CONFIRM_CREATE_DESTINATION); + qb.pszMessage = szMessage; + qb.pszBtnOkText = MAKEINTRESOURCE(IDS_YES); + qb.pszBtnCancelText = MAKEINTRESOURCE(IDS_NO); + qb.uBeepType = MB_ICONEXCLAMATION; + qb.uFlags = QBF_DEFAULT_OK | QBF_SETFOREGROUND | QBF_BEEP; + return (IDCANCEL == MLDisc_ShowQuestionBox(&qb)); +} + +static INT_PTR CopyProgress_OnReadOnly(HWND hdlg, LPCTSTR pszFile) +{ + PROGDLG *ppd = GetProgDlg(hdlg); + if (!ppd || !ppd->pCopyData) return FALSE; + QUESTIONBOX qb = {0}; + TCHAR szFormat[MAX_PATH] = {0}, szMessage[MAX_PATH*2] = {0}; + + WASABI_API_LNGSTRINGW_BUF(IDS_READONLY_FILE_DELETE_FORMAT, szFormat, ARRAYSIZE(szFormat)); + StringCchPrintf(szMessage, ARRAYSIZE(szMessage), szFormat, pszFile); + + qb.hParent =hdlg; + qb.pszIcon = IDI_QUESTION; + qb.pszTitle = MAKEINTRESOURCE(IDS_CONFIRM_FILE_DELETE); + qb.pszMessage = szMessage; + qb.pszBtnOkText = MAKEINTRESOURCE(IDS_YES); + qb.pszBtnCancelText = MAKEINTRESOURCE(IDS_CANCEL); + qb.pszCheckboxText = MAKEINTRESOURCE(IDS_APPLY_TO_ALL_FILES); + qb.uBeepType = MB_ICONEXCLAMATION; + qb.uFlags = QBF_DEFAULT_OK | QBF_SETFOREGROUND | QBF_BEEP | QBF_SHOW_CHECKBOX; + + switch(MLDisc_ShowQuestionBox(&qb)) + { + case IDCANCEL: return READONLY_CANCELCOPY; + case IDOK: return (qb.checkboxChecked) ? READONLY_DELETEALL : READONLY_DELETE; + } + + return FALSE; +} + +static LPTSTR FormatFileInfo(LPTSTR pszBuffer, size_t cchBufferMax, LPCTSTR pszFilePath) +{ + HANDLE hFile; + HRESULT hr; + BY_HANDLE_FILE_INFORMATION fi; + + pszBuffer[0] = TEXT('\0'); + + hFile = CreateFile(pszFilePath, FILE_READ_ATTRIBUTES | FILE_READ_EA, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL,OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL); + + if (INVALID_HANDLE_VALUE != hFile && + GetFileInformationByHandle(hFile, &fi)) + { + TCHAR szTemp[1024] = {0}, szKeyword[64] = {0}; + SYSTEMTIME st = {0}; + + LONGLONG fsize = (LONGLONG)(((__int64)fi.nFileSizeHigh<< 32) | fi.nFileSizeLow); + + WASABI_API_LNGSTRINGW_BUF(IDS_SIZE, szKeyword, ARRAYSIZE(szKeyword)); + hr = StringCchPrintfEx(pszBuffer, cchBufferMax, &pszBuffer, &cchBufferMax, STRSAFE_IGNORE_NULLS, TEXT("\n %s: %s"), szKeyword, StrFormatByteSize64(fsize, szTemp, ARRAYSIZE(szTemp))); + + if (S_OK == hr && FileTimeToSystemTime(&fi.ftCreationTime, &st) && + GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szTemp, ARRAYSIZE(szTemp))) + { + WASABI_API_LNGSTRINGW_BUF(IDS_CREATED, szKeyword, ARRAYSIZE(szKeyword)); + hr = StringCchPrintfEx(pszBuffer, cchBufferMax, &pszBuffer, &cchBufferMax, STRSAFE_IGNORE_NULLS, TEXT("\n %s: %s"), szKeyword, szTemp); + if (S_OK == hr && GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szTemp, ARRAYSIZE(szTemp))) + hr = StringCchPrintfEx(pszBuffer, cchBufferMax, &pszBuffer, &cchBufferMax, STRSAFE_IGNORE_NULLS, TEXT(", %s"), szTemp); + + } + + + if (S_OK == hr && FileTimeToSystemTime(&fi.ftLastWriteTime, &st) && + GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szTemp, ARRAYSIZE(szTemp))) + { + WASABI_API_LNGSTRINGW_BUF(IDS_MODIFIED, szKeyword, ARRAYSIZE(szKeyword)); + hr = StringCchPrintfEx(pszBuffer, cchBufferMax, &pszBuffer, &cchBufferMax, STRSAFE_IGNORE_NULLS, TEXT("\n %s: %s"), szKeyword, szTemp); + if (S_OK == hr && GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szTemp, ARRAYSIZE(szTemp))) + hr = StringCchPrintfEx(pszBuffer, cchBufferMax, &pszBuffer, &cchBufferMax, STRSAFE_IGNORE_NULLS, TEXT(", %s"), szTemp); + + } + if (S_OK == hr) + { + hr = StringCchCopyEx(pszBuffer, cchBufferMax, TEXT("\n\n"), &pszBuffer, &cchBufferMax, STRSAFE_IGNORE_NULLS); + } + } + else hr = S_FALSE; + + if (S_OK != hr) pszBuffer[0] = TEXT('\0'); + + if (INVALID_HANDLE_VALUE != hFile) CloseHandle(hFile); + return pszBuffer; + +} +static INT_PTR CopyProgress_OnFileAlreadyExist(HWND hdlg, FILECONFLICT *pConflict) +{ + PROGDLG *ppd = GetProgDlg(hdlg); + if (!ppd || !ppd->pCopyData) return FALSE; + QUESTIONBOX qb = {0}; + TCHAR szFormat[128] = {0}, szMessage[MAX_PATH*2] = {0}, szPath[MAX_PATH] = {0}, szFileInfo1[128] = {0}, szFileInfo2[128] = {0}; + + WASABI_API_LNGSTRINGW_BUF(IDS_FILE_REPLACE_FORMAT, szFormat, ARRAYSIZE(szFormat)); + + StringCchCopy(szPath, ARRAYSIZE(szPath), pConflict->pszNameExisting); + LPTSTR pszFileName = PathFindFileName(szPath); + if (pszFileName && pszFileName > szPath) *(pszFileName - 1) = TEXT('\0'); + + FormatFileInfo(szFileInfo1, ARRAYSIZE(szFileInfo1), pConflict->pszNameExisting); + FormatFileInfo(szFileInfo2, ARRAYSIZE(szFileInfo2), pConflict->pszNameNew); + + StringCchPrintf(szMessage, ARRAYSIZE(szMessage), szFormat, szPath, pszFileName, szFileInfo1, szFileInfo2); + + qb.hParent = hdlg; + qb.pszIcon = IDI_QUESTION; + qb.pszTitle = MAKEINTRESOURCE(IDS_CONFIRM_FILE_REPLACE); + qb.pszMessage = szMessage; + + qb.pszBtnExtraText = MAKEINTRESOURCE(IDS_SKIP); + qb.pszBtnOkText = MAKEINTRESOURCE(IDS_OVERWRITE); + qb.pszBtnCancelText = MAKEINTRESOURCE(IDS_CANCEL); + qb.pszCheckboxText = MAKEINTRESOURCE(IDS_APPLY_TO_ALL_FILES); + qb.uBeepType = MB_ICONEXCLAMATION; + + qb.uFlags = QBF_DEFAULT_OK | QBF_SETFOREGROUND | QBF_BEEP | QBF_SHOW_CHECKBOX | QBF_SHOW_EXTRA_BUTTON; + + INT_PTR qbr = MLDisc_ShowQuestionBox(&qb); + INT r = 0; + switch(qbr) + { + case IDCANCEL: r = EXISTFILE_CANCELCOPY; break; + case IDOK: r = EXISTFILE_OVERWRITE; break; + case IDC_BTN_EXTRA1: r = EXISTFILE_SKIP; break; + } + + if (qb.checkboxChecked) r |= EXISTFILE_APPLY_TO_ALL; + return r; +} + +static INT_PTR CopyProgress_OnCopyNotify(HWND hdlg, UINT uTask, UINT uOperation, LPARAM lParam) +{ + switch(uTask) + { + case CFT_INITIALIZING: + + switch(uOperation) + { + case CFO_INIT: + SetTaskText(hdlg, MAKEINTRESOURCE(IDS_COPY_TASK_PREPARE)); + SetOperationText(hdlg, TEXT("")); + break; + case CFO_CACLSIZE: + SetOperationText(hdlg, MAKEINTRESOURCE(IDS_COPY_OP_CALCULATESIZE)); + break; + case CFO_CHECKDESTINATION: + SetOperationText(hdlg, MAKEINTRESOURCE(IDS_COPY_OP_CHECKDESTINATION)); + break; + } + break; + case CFT_COPYING: + switch(uOperation) + { + case CFO_INIT: + SetTaskText(hdlg, MAKEINTRESOURCE(IDS_COPY_TASK_COPY)); + SetOperationText(hdlg, TEXT("")); + break; + case CFO_NEXTFILE: + CopyProgress_OnDisplayNextFile(hdlg, LOWORD(lParam), HIWORD(lParam)); + break; + case CFO_PROGRESS: + SendDlgItemMessage(hdlg, IDC_PRG_TOTAL, PBM_SETPOS, (WPARAM)lParam, 0L); + break; + } + break; + case CFT_FINISHED: + SetTaskText(hdlg, MAKEINTRESOURCE(IDS_COPY_TASK_FINISHED)); + switch(uOperation) + { + case CFO_SUCCESS: SetOperationText(hdlg, MAKEINTRESOURCE(IDS_COMPLETED)); break; + case CFO_CANCELLED: SetOperationText(hdlg, MAKEINTRESOURCE(IDS_CANCELLED)); break; + case CFO_FAILED: + SetOperationText(hdlg, MAKEINTRESOURCE(IDS_FAILED)); + ShowErrorBox(hdlg); + break; + } + DestroyWindow(hdlg); + break; + case CFT_CONFLICT: + switch(uOperation) + { + case CFO_DESTNOTEXIST: return CopyProgress_OnDestiantionNotExist(hdlg, (LPCTSTR)lParam); + case CFO_FILEALREDYEXIST: return CopyProgress_OnFileAlreadyExist(hdlg, (FILECONFLICT*)lParam); + case CFO_READONLY: return CopyProgress_OnReadOnly(hdlg, (LPCTSTR)lParam); + } + break; + } + return FALSE; +} +INT_PTR CALLBACK CopyProgress_DialogProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PROGDLG *ppd = GetProgDlg(hdlg); + + switch(uMsg) + { + case WM_INITDIALOG: return CopyProgress_OnInitDialog(hdlg, (HWND)wParam, lParam); + case WM_DESTROY: CopyProgress_OnDestroy(hdlg); break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: + if (ppd && ppd->pCopyData) + { + SetOperationText(hdlg, MAKEINTRESOURCE(IDS_CANCELLING)); + SendDlgItemMessage(hdlg, IDCANCEL, BM_SETSTATE, (WPARAM)TRUE, 0L); + EnableWindow(GetDlgItem(hdlg, IDCANCEL), FALSE); + CopyFiles_CancelCopy(ppd->pCopyData); + } + else DestroyWindow(hdlg); + break; + } + case CFM_NOTIFY: MSGRESULT(hdlg, CopyProgress_OnCopyNotify(hdlg, LOWORD(wParam), HIWORD(wParam), lParam)); + } + return 0; +}
\ No newline at end of file |