/* FTP File YM plugin Copyright (C) 2007-2010 Jan Holub 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 version 2 of the License. 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, see . */ #include "dialog.h" #include "dbentry.h" #include "options.h" #include "job_upload.h" #include "job_packer.h" UploadDialog *UploadDialog::instance = NULL; UploadDialog *uDlg = NULL; Mutex UploadDialog::mutexTabs; WNDPROC UploadDialog::oldTabControlProc; extern Options &opt; extern BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD); UploadDialog::UploadDialog() { this->hwnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DLG_UPLOAD), 0, UploadDlgProc); this->hwndTabs = GetDlgItem(this->hwnd, IDC_TAB); MyEnableThemeDialogTexture(this->hwnd, ETDT_ENABLETAB); MONITORINFO mi = {0}; mi.cbSize = sizeof(mi); HMONITOR hMonitor = MonitorFromWindow(this->hwnd, MONITOR_DEFAULTTONEAREST); GetMonitorInfo(hMonitor, &mi); RECT rc; GetWindowRect(this->hwnd, &rc); rc.left = mi.rcWork.left + ((mi.rcWork.right - mi.rcWork.left) - (rc.right-rc.left)) / 2; rc.top = mi.rcWork.top + ((mi.rcWork.bottom - mi.rcWork.top) - (rc.bottom-rc.top)) / 2; SetWindowPos(this->hwnd, 0, rc.left, rc.top, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); } UploadDialog::~UploadDialog() { if (this->hwnd) { ShowWindow(this->hwnd, SW_HIDE); SendMessage(this->hwnd, WMU_DESTROY, 0, 0); } instance = NULL; uDlg = NULL; } void UploadDialog::selectTab(int index) { if (tabs[index] != NULL) tabs[index]->select(); } void UploadDialog::show() { ShowWindow(this->hwnd, SW_SHOWNORMAL); } UploadDialog::Tab::Tab(GenericJob *Job) :job(Job),bOptCloseDlg(opt.bCloseDlg),bOptCopyLink(opt.bCopyLink),bOptAutosend(opt.bAutosend),iOptAutoDelete(-1) { if (opt.bAutoDelete) this->iOptAutoDelete = Utils::getDeleteTimeMin(); this->stzSpeed[0] = 0; this->stzComplet[0] = 0; this->stzRemain[0] = 0; TCHAR buff[256]; TCITEM tab = {0}; tab.mask = TCIF_TEXT; tab.pszText = Utils::getTextFragment(job->stzFileName, 20, buff); TabCtrl_InsertItem(uDlg->hwndTabs, uDlg->tabs.size(), &tab); Lock *lock = new Lock(mutexTabs); uDlg->tabs.push_back(this); delete lock; this->select(); } UploadDialog::Tab::~Tab() { Lock *lock = new Lock(mutexTabs); TabCtrl_DeleteItem(uDlg->hwndTabs, this->index()); uDlg->tabs.erase(uDlg->tabs.begin() + this->index()); delete lock; if (this->job->isCompleted()) delete this->job; if (uDlg->tabs.size() == 0) delete uDlg; else uDlg->selectTab(0); } int UploadDialog::Tab::index() { for (UINT i = 0; i < uDlg->tabs.size(); i++) { if (uDlg->tabs[i] == this) return i; } return -1; } void UploadDialog::Tab::select() { TabCtrl_SetCurSel(uDlg->hwndTabs, this->index()); Lock *lock = new Lock(mutexTabs); uDlg->activeTab = this->index(); delete lock; this->job->refreshTab(true); InvalidateRect(uDlg->hwnd, NULL, TRUE); } void UploadDialog::Tab::labelCompleted() { TCHAR buff[64], buff2[256]; mir_sntprintf(buff2, SIZEOF(buff2), _T("* %s"), Utils::getTextFragment(this->job->stzFileName, 20, buff)); TCITEM tab = {0}; tab.mask = TCIF_TEXT; tab.pszText = buff2; TabCtrl_SetItem(uDlg->hwndTabs, this->index(), &tab); } INT_PTR CALLBACK UploadDialog::TabControlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_LBUTTONDBLCLK: case WM_MBUTTONDOWN: { POINT pt; GetCursorPos(&pt); ScreenToClient(uDlg->hwndTabs, &pt); TCHITTESTINFO tch; tch.pt = pt; tch.flags = 0; int index = TabCtrl_HitTest(uDlg->hwndTabs, &tch); if (index != -1) uDlg->tabs[index]->job->closeTab(); } break; } return CallWindowProc(UploadDialog::oldTabControlProc, hwnd, msg, wParam, lParam); } INT_PTR CALLBACK UploadDialog::UploadDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { TranslateDialogDefault(hwndDlg); SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)Utils::loadIconEx("main")); UploadDialog::oldTabControlProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TAB), GWLP_WNDPROC, (LONG_PTR)TabControlProc); LOGFONT logFont = {0}; HFONT hFont = (HFONT)SendMessage(GetDlgItem(hwndDlg, IDC_ST_FILE), WM_GETFONT, 0, 0); GetObject(hFont, sizeof(logFont), &logFont); logFont.lfWeight = FW_BOLD; hFont = CreateFontIndirect(&logFont); SendMessage(GetDlgItem(hwndDlg, IDC_ST_CONTACT), WM_SETFONT, (WPARAM)hFont, 0); SendMessage(GetDlgItem(hwndDlg, IDC_ST_FILE), WM_SETFONT, (WPARAM)hFont, 0); SendMessage(GetDlgItem(hwndDlg, IDC_ST_SERVER), WM_SETFONT, (WPARAM)hFont, 0); SendMessage(GetDlgItem(hwndDlg, IDC_ST_SPEED), WM_SETFONT, (WPARAM)hFont, 0); SendMessage(GetDlgItem(hwndDlg, IDC_ST_COMPLETED), WM_SETFONT, (WPARAM)hFont, 0); SendMessage(GetDlgItem(hwndDlg, IDC_ST_REMAIN), WM_SETFONT, (WPARAM)hFont, 0); logFont.lfHeight -= 4; hFont = CreateFontIndirect(&logFont); SendMessage(GetDlgItem(hwndDlg, IDC_UP_CONTACT), WM_SETFONT, (WPARAM)hFont, 0); SendDlgItemMessage(hwndDlg, IDC_BTN_PROTO, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, IDC_BTN_PROTO, BUTTONADDTOOLTIP, (WPARAM)TranslateT("User Info"), BATF_TCHAR); SendDlgItemMessage(hwndDlg, IDC_BTN_PAUSE, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, IDC_BTN_PAUSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("pause")); SendDlgItemMessage(hwndDlg, IDC_BTN_PAUSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Pause"), BATF_TCHAR); SendDlgItemMessage(hwndDlg, IDC_BTN_CLIPBOARD, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, IDC_BTN_CLIPBOARD, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("clipboard")); SendDlgItemMessage(hwndDlg, IDC_BTN_CLIPBOARD, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Copy Link to Clipboard"), BATF_TCHAR); SendDlgItemMessage(hwndDlg, IDC_BTN_DOWNLOAD, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, IDC_BTN_DOWNLOAD, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_EVENT_URL)); SendDlgItemMessage(hwndDlg, IDC_BTN_DOWNLOAD, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open in Browser"), BATF_TCHAR); SendDlgItemMessage(hwndDlg, IDC_BTN_FILEMANAGER, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, IDC_BTN_FILEMANAGER, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("main")); SendDlgItemMessage(hwndDlg, IDC_BTN_FILEMANAGER, BUTTONADDTOOLTIP, (WPARAM)TranslateT("FTP File Manager"), BATF_TCHAR); SendDlgItemMessage(hwndDlg, IDC_BTN_OPTIONS, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, IDC_BTN_OPTIONS, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_OPTIONS)); SendDlgItemMessage(hwndDlg, IDC_BTN_OPTIONS, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Options"), BATF_TCHAR); SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_DELETE)); SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Close"), BATF_TCHAR); break; } case WM_MEASUREITEM: { return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); } case WM_DRAWITEM: { return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); } case WM_COMMAND: { HANDLE hContact = uDlg->tabs[uDlg->activeTab]->job->hContact; if (hContact != NULL) { if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU), (LPARAM)hContact)) break; } if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDC_BTN_PROTO: { if (hContact != NULL) { RECT rc; HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)hContact, 0); GetWindowRect((HWND)lParam, &rc); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); DestroyMenu(hMenu); } break; } case IDC_BTN_PAUSE: { uDlg->tabs[uDlg->activeTab]->job->pauseHandler(); return TRUE; } case IDC_BTN_CLIPBOARD: { UploadJob *job = (UploadJob *)uDlg->tabs[uDlg->activeTab]->job; Utils::copyToClipboard(job->szFileLink); return TRUE; } case IDC_BTN_DOWNLOAD: { UploadJob *job = (UploadJob *)uDlg->tabs[uDlg->activeTab]->job; ShellExecuteA(NULL, "open", job->szFileLink, NULL, NULL, SW_SHOWNORMAL); return TRUE; } case IDC_BTN_FILEMANAGER: { CallService(MS_FTPFILE_SHOWMANAGER, 0, 0); return TRUE; } case IDC_BTN_OPTIONS: { Tab *tab = uDlg->tabs[uDlg->activeTab]; POINT pt; GetCursorPos(&pt); SetForegroundWindow(uDlg->hwndTabs); HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU_UPLOAD)); if (hMenu) { HMENU hPopupMenu = GetSubMenu(hMenu, 0); CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hPopupMenu, 0); CheckMenuItem(hPopupMenu, IDM_CLOSEDLG, MF_BYCOMMAND | tab->bOptCloseDlg ? MF_CHECKED : 0); CheckMenuItem(hPopupMenu, IDM_COPYLINK, MF_BYCOMMAND | tab->bOptCopyLink ? MF_CHECKED : 0); CheckMenuItem(hPopupMenu, IDM_AUTOSEND, MF_BYCOMMAND | tab->bOptAutosend ? MF_CHECKED : 0); HMENU hTimeMenu = GetSubMenu(hPopupMenu, 3); CheckMenuItem(hTimeMenu, IDM_DISABLED, MF_BYCOMMAND | (tab->iOptAutoDelete == -1) ? MF_CHECKED : MF_UNCHECKED); int times[10] = {5, 15, 30, 1 * 60, 2 * 60, 5 * 60, 10 * 60, 1 * 24 * 60, 2 * 24 * 60, 7 * 24 * 60}; bool bChecked = (tab->iOptAutoDelete == -1) ? true : false; TCHAR buff[256]; for (int i = 0; i < SIZEOF(times); i++) { if (i == 3 || i == 7) AppendMenu(hTimeMenu, MF_SEPARATOR, 0, 0); if (i < 3) mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d minutes"), times[i]); else if (i < 7) mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d hours"), times[i] / 60); else mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d days"), times[i] / 60 / 24); UINT check = MF_UNCHECKED; if (!bChecked && tab->iOptAutoDelete == times[i]) { check = MF_CHECKED; bChecked = true; } AppendMenu(hTimeMenu, MF_STRING | check, times[i], buff); } if (opt.bAutoDelete) { switch (opt.timeRange) { case Options::TR_MINUTES: mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d minutes"), opt.iDeleteTime); break; case Options::TR_HOURS: mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d hours"), opt.iDeleteTime); break; case Options::TR_DAYS: mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d days"), opt.iDeleteTime); break; } AppendMenu(hTimeMenu, MF_SEPARATOR, 0, 0); AppendMenu(hTimeMenu, MF_STRING | bChecked ? MF_UNCHECKED : MF_CHECKED, IDM_CUSTOM, buff); } int command = TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RETURNCMD, pt.x, pt.y, 0, uDlg->hwndTabs, NULL); switch (command) { case IDM_CLOSEDLG: tab->bOptCloseDlg = !tab->bOptCloseDlg; break; case IDM_COPYLINK: tab->bOptCopyLink = !tab->bOptCopyLink; break; case IDM_AUTOSEND: tab->bOptAutosend = !tab->bOptAutosend; break; case IDM_DISABLED: tab->iOptAutoDelete = -1; break; case IDM_CUSTOM: switch (opt.timeRange) { case Options::TR_MINUTES: tab->iOptAutoDelete = opt.iDeleteTime; break; case Options::TR_HOURS: tab->iOptAutoDelete = opt.iDeleteTime * 60; break; case Options::TR_DAYS: tab->iOptAutoDelete = opt.iDeleteTime * 60 * 24; break; } break; default: tab->iOptAutoDelete = command; break; } if (command && ((UploadJob *)tab->job)->isCompleted()) DBEntry::setDeleteTS(tab->job); DestroyMenu(hMenu); } return TRUE; } case IDC_BTN_CLOSE: { uDlg->tabs[uDlg->activeTab]->job->closeTab(); return TRUE; } } } break; } case WM_NOTIFY: { switch (((LPNMHDR)lParam)->code) { case TCN_SELCHANGE: { uDlg->selectTab(TabCtrl_GetCurSel(uDlg->hwndTabs)); break; } case TTN_GETDISPINFO: { LPNMTTDISPINFO pInfo = (LPNMTTDISPINFO)lParam; POINT pt; GetCursorPos(&pt); ScreenToClient(hwndDlg, &pt); UINT i; RECT rc; for (i = 0; i < uDlg->tabs.size(); i++) { if (uDlg->tabs[i] != NULL) { TabCtrl_GetItemRect(uDlg->hwndTabs, i, &rc); if (PtInRect(&rc, pt)) break; } } if (i < uDlg->tabs.size()) { uDlg->tabs[i]->job->createToolTip(); HWND hToolTip = TabCtrl_GetToolTips(uDlg->hwndTabs); SendMessage(hToolTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM)500); pInfo->lpszText = uDlg->stzToolTipText; } break; } } break; } case WM_CLOSE: { for (UINT i = 0; i < uDlg->tabs.size(); i++) uDlg->tabs[i]->job->pause(); int result = IDYES; if (!Miranda_Terminated() && UploadJob::iRunningJobCount > 0) result = Utils::msgBox(TranslateT("Do you really want to cancel all running jobs?"), MB_YESNO | MB_ICONQUESTION); if (result == IDYES) { SkinPlaySound(SOUND_CANCEL); size_t count = uDlg->tabs.size(); for (UINT i = 0; i < count; i++) uDlg->tabs[0]->job->closeAllTabs(); } else { for (UINT i = 0; i < uDlg->tabs.size(); i++) uDlg->tabs[i]->job->resume(); } break; } case WMU_DESTROY: { DestroyWindow(hwndDlg); break; } } return FALSE; }