diff options
Diffstat (limited to 'src/core/stdfile/fileexistsdlg.cpp')
-rw-r--r-- | src/core/stdfile/fileexistsdlg.cpp | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/src/core/stdfile/fileexistsdlg.cpp b/src/core/stdfile/fileexistsdlg.cpp new file mode 100644 index 0000000000..c0592c8b39 --- /dev/null +++ b/src/core/stdfile/fileexistsdlg.cpp @@ -0,0 +1,341 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "file.h"
+
+static void SetControlToUnixTime(HWND hwndDlg, UINT idCtrl, time_t unixTime)
+{
+ LARGE_INTEGER liFiletime;
+ FILETIME filetime;
+ SYSTEMTIME st;
+ char szTime[64], szDate[64], szOutput[128];
+
+ liFiletime.QuadPart = (BIGI(11644473600)+(__int64)unixTime)*10000000;
+ filetime.dwHighDateTime = liFiletime.HighPart;
+ filetime.dwLowDateTime = liFiletime.LowPart;
+ FileTimeToSystemTime(&filetime, &st);
+ GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, szTime, SIZEOF(szTime));
+ GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, szDate, SIZEOF(szDate));
+ mir_snprintf(szOutput, SIZEOF(szOutput), "%s %s", szDate, szTime);
+ SetDlgItemTextA(hwndDlg, idCtrl, szOutput);
+}
+
+#define C_CONTEXTMENU 0
+#define C_PROPERTIES 1
+// not defined in VC++ 6.0 SE
+#ifndef CMF_EXTENDEDVERBS
+#define CMF_EXTENDEDVERBS 0x00000100
+#endif
+static void DoAnnoyingShellCommand(HWND hwnd, const TCHAR *szFilename, int cmd, POINT *ptCursor)
+{
+ IShellFolder *pDesktopFolder;
+ if (SHGetDesktopFolder(&pDesktopFolder) == NOERROR) {
+ ITEMIDLIST *pCurrentIdl;
+ WCHAR* wszFilename = (LPWSTR)szFilename;
+
+ if (pDesktopFolder->ParseDisplayName(NULL, NULL, wszFilename, NULL, &pCurrentIdl, NULL) == NOERROR) {
+ if (pCurrentIdl->mkid.cb) {
+ ITEMIDLIST *pidl, *pidlNext, *pidlFilename;
+ IShellFolder *pFileFolder;
+
+ for (pidl = pCurrentIdl;;) {
+ pidlNext = (ITEMIDLIST*)((PBYTE)pidl+pidl->mkid.cb);
+ if (pidlNext->mkid.cb == 0) {
+ pidlFilename = (ITEMIDLIST*)CoTaskMemAlloc(pidl->mkid.cb+sizeof(pidl->mkid.cb));
+ CopyMemory(pidlFilename, pidl, pidl->mkid.cb+sizeof(pidl->mkid.cb));
+ pidl->mkid.cb = 0;
+ break;
+ }
+ pidl = pidlNext;
+ }
+ if (pDesktopFolder->BindToObject(pCurrentIdl, NULL, IID_IShellFolder, (void**)&pFileFolder) == NOERROR) {
+ IContextMenu *pContextMenu;
+ if (pFileFolder->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidlFilename, IID_IContextMenu, NULL, (void**)&pContextMenu) == NOERROR) {
+ switch(cmd) {
+ case C_PROPERTIES:
+ { CMINVOKECOMMANDINFO ici = {0};
+ ici.cbSize = sizeof(ici);
+ ici.hwnd = hwnd;
+ ici.lpVerb = "properties";
+ ici.nShow = SW_SHOW;
+ pContextMenu->InvokeCommand(&ici);
+ break;
+ }
+ case C_CONTEXTMENU:
+ { HMENU hMenu;
+ hMenu = CreatePopupMenu();
+ if (SUCCEEDED(pContextMenu->QueryContextMenu(hMenu, 0, 1000, 65535, (GetKeyState(VK_SHIFT)&0x8000?CMF_EXTENDEDVERBS:0)|CMF_NORMAL))) {
+ int cmd;
+ cmd = TrackPopupMenu(hMenu, TPM_RETURNCMD, ptCursor->x, ptCursor->y, 0, hwnd, NULL);
+ if (cmd) {
+ CMINVOKECOMMANDINFO ici = {0};
+ ici.cbSize = sizeof(ici);
+ ici.hwnd = hwnd;
+ ici.lpVerb = MAKEINTRESOURCEA(cmd-1000);
+ ici.nShow = SW_SHOW;
+ pContextMenu->InvokeCommand(&ici);
+ }
+ }
+ DestroyMenu(hMenu);
+ break;
+ }
+ }
+ pContextMenu->Release();
+ }
+ pFileFolder->Release();
+ }
+ CoTaskMemFree(pidlFilename);
+ }
+ CoTaskMemFree(pCurrentIdl);
+ }
+ pDesktopFolder->Release();
+ }
+}
+
+static WNDPROC pfnIconWindowProc;
+static LRESULT CALLBACK IconCtrlSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ PROTOFILETRANSFERSTATUS* pft = (PROTOFILETRANSFERSTATUS*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+
+ switch(msg) {
+ case WM_LBUTTONDBLCLK:
+ ShellExecute(hwnd, NULL, pft->tszCurrentFile, NULL, NULL, SW_SHOW);
+ break;
+ case WM_RBUTTONUP:
+ { POINT pt;
+ pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam);
+ ClientToScreen(hwnd, &pt);
+ DoAnnoyingShellCommand(hwnd, pft->tszCurrentFile, C_CONTEXTMENU, &pt);
+ return 0;
+ }
+ }
+ return CallWindowProc(pfnIconWindowProc, hwnd, msg, wParam, lParam);
+}
+
+struct loadiconsstartinfo {
+ HWND hwndDlg;
+ TCHAR *szFilename;
+};
+
+void __cdecl LoadIconsAndTypesThread(void* param)
+{
+ loadiconsstartinfo *info = (loadiconsstartinfo*)param;
+ SHFILEINFO fileInfo;
+
+ if (SHGetFileInfo(info->szFilename, 0, &fileInfo, sizeof(fileInfo), SHGFI_TYPENAME|SHGFI_ICON|SHGFI_LARGEICON)) {
+ TCHAR *pszExtension, *pszFilename;
+ TCHAR szExtension[64];
+ TCHAR szIconFile[MAX_PATH];
+
+ pszFilename = _tcsrchr(info->szFilename, '\\');
+ if (pszFilename == NULL)
+ pszFilename = info->szFilename;
+
+ pszExtension = _tcsrchr(pszFilename, '.');
+ if (pszExtension)
+ lstrcpyn(szExtension, pszExtension+1, SIZEOF(szExtension));
+ else {
+ pszExtension = _T(".");
+ szExtension[0] = '\0';
+ }
+ CharUpper(szExtension);
+ if (fileInfo.szTypeName[0] == '\0')
+ mir_sntprintf(fileInfo.szTypeName, SIZEOF(fileInfo.szTypeName), TranslateT("%s File"), szExtension);
+ SetDlgItemText(info->hwndDlg, IDC_EXISTINGTYPE, fileInfo.szTypeName);
+ SetDlgItemText(info->hwndDlg, IDC_NEWTYPE, fileInfo.szTypeName);
+ SendDlgItemMessage(info->hwndDlg, IDC_EXISTINGICON, STM_SETICON, (WPARAM)fileInfo.hIcon, 0);
+ szIconFile[0] = '\0';
+ if ( !lstrcmp(szExtension, _T("EXE")))
+ SRFile_GetRegValue(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons"), _T("2"), szIconFile, SIZEOF(szIconFile));
+ else {
+ TCHAR szTypeName[MAX_PATH];
+ if (SRFile_GetRegValue(HKEY_CLASSES_ROOT, pszExtension, NULL, szTypeName, SIZEOF(szTypeName))) {
+ lstrcat(szTypeName, _T("\\DefaultIcon"));
+ if (SRFile_GetRegValue(HKEY_CLASSES_ROOT, szTypeName, NULL, szIconFile, SIZEOF(szIconFile))) {
+ if (_tcsstr(szIconFile, _T("%1")))
+ SRFile_GetRegValue(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons"), _T("0"), szIconFile, SIZEOF(szIconFile));
+ else szIconFile[0] = '\0';
+ } } }
+
+ if (szIconFile[0]) {
+ TCHAR *pszComma = _tcsrchr(szIconFile, ',');
+ int iconIndex = (pszComma == NULL) ? 0 :_ttoi(pszComma+1); *pszComma = '\0';
+ HICON hIcon = ExtractIcon(hInst, szIconFile, iconIndex);
+ if (hIcon)
+ fileInfo.hIcon = hIcon;
+ }
+ SendDlgItemMessage(info->hwndDlg, IDC_NEWICON, STM_SETICON, (WPARAM)fileInfo.hIcon, 0);
+ }
+ mir_free(info->szFilename);
+ mir_free(info);
+}
+
+INT_PTR CALLBACK DlgProcFileExists(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ PROTOFILETRANSFERSTATUS *fts;
+
+ fts = (PROTOFILETRANSFERSTATUS*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ switch(msg) {
+ case WM_INITDIALOG:
+ {
+ TCHAR szSize[64];
+ struct _stati64 statbuf;
+ HWND hwndFocus;
+ struct TDlgProcFileExistsParam *dat = (struct TDlgProcFileExistsParam *)lParam;
+
+ SetPropA(hwndDlg, "Miranda.Preshutdown", HookEventMessage(ME_SYSTEM_PRESHUTDOWN, hwndDlg, M_PRESHUTDOWN));
+ SetPropA(hwndDlg, "Miranda.ParentWnd", dat->hwndParent);
+
+ TranslateDialogDefault(hwndDlg);
+ fts = (PROTOFILETRANSFERSTATUS*)mir_alloc(sizeof(PROTOFILETRANSFERSTATUS));
+ CopyProtoFileTransferStatus(fts, dat->fts);
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)fts);
+ SetDlgItemText(hwndDlg, IDC_FILENAME, fts->tszCurrentFile);
+ SetControlToUnixTime(hwndDlg, IDC_NEWDATE, fts->currentFileTime);
+ GetSensiblyFormattedSize(fts->currentFileSize, szSize, SIZEOF(szSize), 0, 1, NULL);
+ SetDlgItemText(hwndDlg, IDC_NEWSIZE, szSize);
+
+ pfnIconWindowProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EXISTINGICON), GWLP_WNDPROC, (LONG_PTR)IconCtrlSubclassProc);
+
+ hwndFocus = GetDlgItem(hwndDlg, IDC_RESUME);
+ if (_tstati64(fts->tszCurrentFile, &statbuf) == 0) {
+ SetControlToUnixTime(hwndDlg, IDC_EXISTINGDATE, statbuf.st_mtime);
+ GetSensiblyFormattedSize(statbuf.st_size, szSize, SIZEOF(szSize), 0, 1, NULL);
+ SetDlgItemText(hwndDlg, IDC_EXISTINGSIZE, szSize);
+ if (statbuf.st_size>(int)fts->currentFileSize) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RESUME), FALSE);
+ hwndFocus = GetDlgItem(hwndDlg, IDC_OVERWRITE);
+ } }
+
+ loadiconsstartinfo *lisi = (loadiconsstartinfo*)mir_alloc(sizeof(loadiconsstartinfo));
+ lisi->hwndDlg = hwndDlg;
+ lisi->szFilename = mir_tstrdup(fts->tszCurrentFile);
+ //can be a little slow, so why not?
+ forkthread(LoadIconsAndTypesThread, 0, lisi);
+ SetFocus(hwndFocus);
+ SetWindowLongPtr(hwndFocus, GWL_STYLE, GetWindowLongPtr(hwndFocus, GWL_STYLE)|BS_DEFPUSHBUTTON);
+ return FALSE;
+ }
+ case WM_COMMAND:
+ {
+ PROTOFILERESUME pfr = {0};
+ switch(LOWORD(wParam)) {
+ case IDC_OPENFILE:
+ ShellExecute(hwndDlg, NULL, fts->tszCurrentFile, NULL, NULL, SW_SHOW);
+ return FALSE;
+
+ case IDC_OPENFOLDER:
+ {
+ TCHAR szFile[MAX_PATH];
+ lstrcpyn(szFile, fts->tszCurrentFile, SIZEOF(szFile));
+ TCHAR* pszLastBackslash = _tcsrchr(szFile, '\\');
+ if (pszLastBackslash)
+ *pszLastBackslash = '\0';
+ ShellExecute(hwndDlg, NULL, szFile, NULL, NULL, SW_SHOW);
+ return FALSE;
+ }
+ case IDC_PROPERTIES:
+ DoAnnoyingShellCommand(hwndDlg, fts->tszCurrentFile, C_PROPERTIES, NULL);
+ return FALSE;
+ case IDC_RESUME:
+ pfr.action = FILERESUME_RESUME;
+ break;
+ case IDC_RESUMEALL:
+ pfr.action = FILERESUME_RESUMEALL;
+ break;
+ case IDC_OVERWRITE:
+ pfr.action = FILERESUME_OVERWRITE;
+ break;
+ case IDC_OVERWRITEALL:
+ pfr.action = FILERESUME_OVERWRITEALL;
+ break;
+
+ case IDC_AUTORENAME:
+ pfr.action = FILERESUME_RENAMEALL;
+ break;
+
+ case IDC_SAVEAS:
+ {
+ OPENFILENAME ofn = {0};
+ TCHAR filter[512], *pfilter;
+ TCHAR str[MAX_PATH];
+
+ lstrcpyn(str, fts->tszCurrentFile, SIZEOF(str));
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner = hwndDlg;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
+ _tcscpy(filter, TranslateT("All Files"));
+ _tcscat(filter, _T(" (*)"));
+ pfilter = filter + _tcslen(filter) + 1;
+ _tcscpy(pfilter, _T("*"));
+ pfilter = pfilter + _tcslen(pfilter) + 1;
+ *pfilter = '\0';
+ ofn.lpstrFilter = filter;
+ ofn.lpstrFile = str;
+ ofn.nMaxFile = SIZEOF(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ if ( !GetSaveFileName(&ofn))
+ return FALSE;
+
+ pfr.szFilename = mir_tstrdup(str);
+ pfr.action = FILERESUME_RENAME;
+ break;
+ }
+ case IDC_SKIP:
+ pfr.action = FILERESUME_SKIP;
+ break;
+ case IDCANCEL:
+ pfr.action = FILERESUME_CANCEL;
+ break;
+ default:
+ return FALSE;
+ }
+ { PROTOFILERESUME *pfrCopy;
+ pfrCopy = (PROTOFILERESUME*)mir_alloc(sizeof(pfr));
+ CopyMemory(pfrCopy, &pfr, sizeof(pfr));
+ PostMessage((HWND)GetPropA(hwndDlg, "Miranda.ParentWnd"), M_FILEEXISTSDLGREPLY, (WPARAM)mir_tstrdup(fts->tszCurrentFile), (LPARAM)pfrCopy);
+ DestroyWindow(hwndDlg);
+ }
+ break;
+ }
+
+ case WM_CLOSE:
+ PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, IDCANCEL));
+ break;
+
+ case M_PRESHUTDOWN:
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ break;
+
+ case WM_DESTROY:
+ UnhookEvent(GetPropA(hwndDlg, "Miranda.Preshutdown")); // GetProp() will return NULL if it couldnt find anything
+ RemovePropA(hwndDlg, "Miranda.Preshutdown");
+ RemovePropA(hwndDlg, "Miranda.ParentWnd");
+ DestroyIcon((HICON)SendDlgItemMessage(hwndDlg, IDC_EXISTINGICON, STM_GETICON, 0, 0));
+ DestroyIcon((HICON)SendDlgItemMessage(hwndDlg, IDC_NEWICON, STM_GETICON, 0, 0));
+ FreeProtoFileTransferStatus(fts);
+ mir_free(fts);
+ break;
+ }
+ return FALSE;
+}
|