/* Weather Protocol plugin for Miranda IM Copyright (c) 2012 Miranda NG Team Copyright (c) 2005-2009 Boris Krasnovskiy All Rights Reserved Copyright (c) 2002-2005 Calvin Che 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 . */ /* This file contain the source related to weather popups, including popup options, popup display, and the code for popup process. */ #include "weather.h" // variables for weather_popup.c static HANDLE hPopupContact; //============ SHOW WEATHER POPUPS ============ // display weather popups // wParam = the contact to display popup // lParam = whether the weather data is changed or not int WeatherPopup(WPARAM wParam, LPARAM lParam) { // determine if the popup should display or not if (opt.UsePopup && opt.UpdatePopup && (!opt.PopupOnChange || (BOOL)lParam) && !db_get_b((HANDLE)wParam, WEATHERPROTONAME, "DPopUp", 0)) { POPUPDATAT ppd = {0}; WEATHERINFO winfo; // setup the popup ppd.lchContact = (HANDLE)wParam; // if ((HANDLE)wParam != NULL) { // for actual contact winfo = LoadWeatherInfo((HANDLE)wParam); ppd.PluginData = ppd.lchIcon = LoadSkinnedProtoIcon(WEATHERPROTONAME, winfo.status); GetDisplay(&winfo, opt.pTitle, ppd.lptzContactName); GetDisplay(&winfo, opt.pText, ppd.lptzText); ppd.PluginWindowProc = PopupDlgProc; // } // else { // for preview // ppd.lchIcon = LoadSkinnedProtoIcon(WEATHERPROTONAME, ONLINE); // strcpy(ppd.lpzContactName, Translate("This is the name of the city")); // strcpy(ppd.lpzText, Translate("Here is a short weather description")); // ppd.PluginWindowProc = NULL; // } ppd.colorBack = (opt.UseWinColors)?GetSysColor(COLOR_BTNFACE):opt.BGColour; ppd.colorText = (opt.UseWinColors)?GetSysColor(COLOR_WINDOWTEXT):opt.TextColour; ppd.iSeconds = opt.pDelay; PUAddPopupT( &ppd ); } return 0; } //============ WEATHER ERROR POPUPS ============ // display weather error or notices (not threaded) // wParam = error text // lParam = display type // Type can either be SM_WARNING, SM_NOTIFY, or SM_WEATHERALERT int WeatherError(WPARAM wParam, LPARAM lParam) { if ( !opt.UsePopup) return 0; TCHAR* tszMsg = ( TCHAR* )wParam; if ((DWORD)lParam == SM_WARNING) PUShowMessageT( tszMsg, SM_WARNING ); else if ((DWORD)lParam == SM_NOTIFY) PUShowMessageT( tszMsg, SM_NOTIFY); else if ((DWORD)lParam == SM_WEATHERALERT) { POPUPDATAT ppd = {0}; TCHAR *chop, str1[512], str2[512]; // get the 2 strings _tcscpy(str1, tszMsg); _tcscpy(str2, tszMsg); chop = _tcschr(str1, 255); if (chop != NULL) *chop = '\0'; else str1[0] = 0; chop = _tcschr(str2, 255); if (chop != NULL) _tcscpy(str2, chop+1); else str2[0] = 0; // setup the popup ppd.lchIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(OIC_BANG), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); _tcscpy(ppd.lptzContactName, str1); _tcscpy(ppd.lptzText, str2); ppd.colorBack = (opt.UseWinColors)?GetSysColor(COLOR_BTNFACE):opt.BGColour; ppd.colorText = (opt.UseWinColors)?GetSysColor(COLOR_WINDOWTEXT):opt.TextColour; ppd.iSeconds = opt.pDelay; PUAddPopupT( &ppd ); } return 0; } // wrapper function for displaying weather warning popup by triggering an event // (threaded) // lpzText = error text // kind = display type (see m_popup.h) int WPShowMessage(TCHAR* lpzText, WORD kind) { NotifyEventHooks(hHookWeatherError, (WPARAM)lpzText, (LPARAM)kind); return 0; } //============ WEATHER POPUP PROCESSES ============ // popup dialog pocess // for selecting actions when click on the popup window // use for displaying contact menu LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { DWORD ID = 0; HANDLE hContact; hContact = PUGetContact(hWnd); switch(message) { case WM_COMMAND: ID = opt.LeftClickAction; if (ID != IDM_M7) PUDeletePopup(hWnd); SendMessage(hPopupWindow, ID, (WPARAM)hContact, 0); return TRUE; case WM_CONTEXTMENU: ID = opt.RightClickAction; if (ID != IDM_M7) PUDeletePopup(hWnd); SendMessage(hPopupWindow, ID, (WPARAM)hContact, 0); return TRUE; case UM_FREEPLUGINDATA: Skin_ReleaseIcon((HICON)PUGetPluginData(hWnd)); return FALSE; } return DefWindowProc(hWnd, message, wParam, lParam); } // process for the popup window // containing the code for popup actions LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { POINT pt; HMENU hMenu; switch (uMsg) { case IDM_M2: // brief info BriefInfo(wParam, 0); break; case IDM_M3: // read complete forecast LoadForecast(wParam, 0); break; case IDM_M4: // display weather map WeatherMap(wParam, 0); break; case IDM_M5: // open history window CallService(MS_HISTORY_SHOWCONTACTHISTORY, wParam, 0); break; case IDM_M6: // open external log ViewLog(wParam, 0); break; case IDM_M7: // display contact menu hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,wParam,0); GetCursorPos(&pt); hPopupContact = (HANDLE)wParam; TrackPopupMenu(hMenu,TPM_LEFTALIGN,pt.x,pt.y,0,hWnd,NULL); DestroyMenu(hMenu); break; case IDM_M8: // display contact detail CallService(MS_USERINFO_SHOWDIALOG, wParam, 0); case WM_COMMAND: //Needed by the contact's context menu if ( CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU), (LPARAM)hPopupContact)) break; return FALSE; case WM_MEASUREITEM: //Needed by the contact's context menu return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam); case WM_DRAWITEM: //Needed by the contact's context menu return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam); } return DefWindowProc(hWnd, uMsg, wParam, lParam);//FALSE; } //============ POPUP OPTIONS ============ // used to select the menu item for popup action menu static void SelectMenuItem(HMENU hMenu, int Check) { for (int i=0; i <= GetMenuItemCount(hMenu)-1; i++) CheckMenuItem(hMenu, i, MF_BYPOSITION|((int)GetMenuItemID(hMenu, i) == Check)*8); } // temporary read the current option to memory // but does not write to the database void ReadPopupOpt(HWND hdlg) { TCHAR text[MAX_TEXT_SIZE]; int num; TCHAR str[512]; // popup colour opt.TextColour = SendDlgItemMessage(hdlg,IDC_TEXTCOLOUR,CPM_GETCOLOUR,0,0); opt.BGColour = SendDlgItemMessage(hdlg,IDC_BGCOLOUR,CPM_GETCOLOUR,0,0); // get delay time GetDlgItemText(hdlg, IDC_DELAY, str, sizeof(str)); num = _ttoi(str); opt.pDelay = num; // other options opt.UseWinColors = (BYTE)IsDlgButtonChecked(hdlg, IDC_USEWINCOLORS); opt.UsePopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_E); opt.UpdatePopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_POP1); opt.AlertPopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_POP2); opt.PopupOnChange = (BYTE)IsDlgButtonChecked(hdlg, IDC_CH); opt.ShowWarnings = (BYTE)IsDlgButtonChecked(hdlg, IDC_W); // popup texts wfree(&opt.pText); wfree(&opt.pTitle); GetDlgItemText(hdlg, IDC_PText, text, MAX_TEXT_SIZE); wSetData(&opt.pText, text); GetDlgItemText(hdlg, IDC_PTitle, text, MAX_TEXT_SIZE); wSetData(&opt.pTitle, text); } // copied and modified from NewStatusNotify INT_PTR CALLBACK DlgPopupOpts(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { int ID; TCHAR str[512]; HMENU hMenu, hMenu1; RECT pos; HWND button; HANDLE hContact; switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hdlg); SaveOptions(); // click actions hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU)); hMenu1 = GetSubMenu(hMenu, 0); GetMenuString(hMenu1, opt.LeftClickAction, str, sizeof(str), MF_BYCOMMAND); SetDlgItemText(hdlg, IDC_LeftClick, TranslateTS(str)); GetMenuString(hMenu1, opt.RightClickAction, str, sizeof(str), MF_BYCOMMAND); SetDlgItemText(hdlg, IDC_RightClick, TranslateTS(str)); DestroyMenu(hMenu); // other options CheckDlgButton(hdlg, IDC_E, opt.UsePopup); CheckDlgButton(hdlg, IDC_POP2, opt.AlertPopup); CheckDlgButton(hdlg, IDC_POP1, opt.UpdatePopup); CheckDlgButton(hdlg, IDC_CH, opt.PopupOnChange); CheckDlgButton(hdlg, IDC_W, opt.ShowWarnings); SetDlgItemText(hdlg,IDC_PText, opt.pText); SetDlgItemText(hdlg,IDC_PTitle, opt.pTitle); // setting popup delay option _ltot(opt.pDelay, str, 10); SetDlgItemText(hdlg,IDC_DELAY, str); if (opt.pDelay == -1) CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD2); else if (opt.pDelay == 0) CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD1); else CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD3); //Colours. First step is configuring the colours. SendDlgItemMessage(hdlg,IDC_BGCOLOUR,CPM_SETCOLOUR,0,opt.BGColour); SendDlgItemMessage(hdlg,IDC_TEXTCOLOUR,CPM_SETCOLOUR,0,opt.TextColour); //Second step is disabling them if we want to use default Windows ones. CheckDlgButton(hdlg, IDC_USEWINCOLORS,opt.UseWinColors?BST_CHECKED:BST_UNCHECKED); EnableWindow(GetDlgItem(hdlg, IDC_BGCOLOUR), !opt.UseWinColors); EnableWindow(GetDlgItem(hdlg, IDC_TEXTCOLOUR), !opt.UseWinColors); // buttons SendMessage(GetDlgItem(hdlg,IDC_PREVIEW), BUTTONSETASFLATBTN, TRUE, 0); SendMessage(GetDlgItem(hdlg,IDC_PDEF), BUTTONSETASFLATBTN, TRUE, 0); SendMessage(GetDlgItem(hdlg,IDC_LeftClick), BUTTONSETASFLATBTN, TRUE, 0); SendMessage(GetDlgItem(hdlg,IDC_RightClick), BUTTONSETASFLATBTN, TRUE, 0); SendMessage(GetDlgItem(hdlg,IDC_VAR3), BUTTONSETASFLATBTN, TRUE, 0); return TRUE; case WM_COMMAND: // enable the "apply" button if (HIWORD(wParam) == BN_CLICKED && GetFocus() == (HWND)lParam) SendMessage(GetParent(hdlg),PSM_CHANGED,0,0); if ( !((LOWORD(wParam) == IDC_UPDATE || LOWORD(wParam) == IDC_DEGREE) && (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()))) SendMessage(GetParent(hdlg),PSM_CHANGED,0,0); //These are simple clicks: we don't save, but we tell the Options Page to enable the "Apply" button. switch(LOWORD(wParam)) { case IDC_BGCOLOUR: //Fall through case IDC_TEXTCOLOUR: // select new colors if (HIWORD(wParam) == CPN_COLOURCHANGED) SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); break; case IDC_USEWINCOLORS: // use window color - enable/disable color selection controls EnableWindow(GetDlgItem(hdlg, IDC_BGCOLOUR), !(opt.UseWinColors)); EnableWindow(GetDlgItem(hdlg, IDC_TEXTCOLOUR), !(opt.UseWinColors)); SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); break; case IDC_E: case IDC_CH: SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); break; case IDC_RightClick: // right click action selection menu button = GetDlgItem(hdlg, IDC_RightClick); GetWindowRect(button, &pos); hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU)); hMenu1 = GetSubMenu(hMenu, 0); TranslateMenu(hMenu1); SelectMenuItem(hMenu1, opt.RightClickAction); ID = TrackPopupMenu(hMenu1, TPM_LEFTBUTTON|TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, NULL); if (ID) opt.RightClickAction = ID; DestroyMenu(hMenu); hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU)); hMenu1 = GetSubMenu(hMenu, 0); GetMenuString(hMenu1, opt.RightClickAction, str, sizeof(str), MF_BYCOMMAND); SetDlgItemText(hdlg, IDC_RightClick, TranslateTS(str)); DestroyMenu(hMenu); break; case IDC_LeftClick: // left click action selection menu button = GetDlgItem(hdlg, IDC_LeftClick); GetWindowRect(button, &pos); hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU)); hMenu1 = GetSubMenu(hMenu, 0); TranslateMenu(hMenu1); SelectMenuItem(hMenu1, opt.LeftClickAction); ID = TrackPopupMenu(hMenu1, TPM_LEFTBUTTON|TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, NULL); if (ID) opt.LeftClickAction = ID; DestroyMenu(hMenu); hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU)); hMenu1 = GetSubMenu(hMenu, 0); GetMenuString(hMenu1, opt.LeftClickAction, str, sizeof(str), MF_BYCOMMAND); SetDlgItemText(hdlg, IDC_LeftClick, TranslateTS(str)); DestroyMenu(hMenu); break; case IDC_PD1: // Popup delay setting from Popup plugin SetDlgItemText(hdlg, IDC_DELAY, _T("0")); CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD1); break; case IDC_PD2: // Popup delay = permanent SetDlgItemText(hdlg, IDC_DELAY, _T("-1")); CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD2); break; case IDC_DELAY: // if text is edited CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD3); break; case IDC_PDEF: // set the default value for popup texts SetTextDefault("Pp"); SetDlgItemText(hdlg,IDC_PText, opt.pText); SetDlgItemText(hdlg,IDC_PTitle, opt.pTitle); wfree(&opt.pText); wfree(&opt.pTitle); break; case IDC_VAR3: // display variable list _tcscpy(str, _T(" \n")); // to make the message box wider _tcscat(str, TranslateT("%c\tcurrent condition\n%d\tcurrent date\n%e\tdewpoint\n%f\tfeel-like temperature\n%h\ttoday's high\n%i\twind direction\n%l\ttoday's low\n%m\thumidity\n%n\tstation name\n%p\tpressure\n%r\tsunrise time\n%s\tstation ID\n%t\ttemperature\n%u\tupdate time\n%v\tvisibility\n%w\twind speed\n%y\tsun set")); _tcscat(str, _T("\n")); _tcscat(str, TranslateT("%[..]\tcustom variables")); MessageBox(NULL, str, TranslateT("Variable List"), MB_OK|MB_ICONASTERISK|MB_TOPMOST); break; case IDC_PREVIEW: // popup preview hContact = opt.DefStn; ReadPopupOpt(hdlg); // read new options to memory WeatherPopup((WPARAM)opt.DefStn, (BOOL)TRUE); // display popup using new opt DestroyOptions(); LoadOptions(); // restore old option in memory opt.DefStn = hContact; break; } break; case WM_NOTIFY: //Here we have pressed either the OK or the APPLY button. switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: { ReadPopupOpt(hdlg); // save the options, and update main menu SaveOptions(); UpdatePopupMenu(opt.UsePopup); return TRUE; } } break; } return FALSE; }