summaryrefslogtreecommitdiff
path: root/protocols/Weather/src/weather_svcs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Weather/src/weather_svcs.cpp')
-rw-r--r--protocols/Weather/src/weather_svcs.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/protocols/Weather/src/weather_svcs.cpp b/protocols/Weather/src/weather_svcs.cpp
new file mode 100644
index 0000000000..7c3d2611aa
--- /dev/null
+++ b/protocols/Weather/src/weather_svcs.cpp
@@ -0,0 +1,375 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (c) 2012 Miranda NG team
+Copyright (c) 2005-2011 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 <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This file contain the source related to weather protocol services
+as required for a Miranda protocol. Also, it contains functions for
+building/changing the weather menu items.
+*/
+
+#include "stdafx.h"
+
+static HGENMENU hEnableDisablePopupMenu;
+static HGENMENU hEnableDisableMenu;
+
+//============ MIRANDA PROTOCOL SERVICES ============
+
+// protocol service function for setting weather protocol status
+INT_PTR WeatherSetStatus(WPARAM new_status, LPARAM)
+{
+ new_status = new_status != ID_STATUS_OFFLINE ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
+
+ // if we don't want to show status for default station
+ if (!opt.NoProtoCondition && status != new_status) {
+ old_status = status;
+ status = new_status != ID_STATUS_OFFLINE ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
+ ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status);
+
+ UpdateMenu(new_status != ID_STATUS_OFFLINE);
+ if (new_status != ID_STATUS_OFFLINE)
+ UpdateAll(FALSE, FALSE);
+ }
+
+ return 0;
+}
+
+// get capabilities protocol service function
+INT_PTR WeatherGetCaps(WPARAM wParam, LPARAM)
+{
+ INT_PTR ret = 0;
+
+ switch (wParam) {
+ case PFLAGNUM_1:
+ // support search and visible list
+ ret = PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_EXTSEARCH | PF1_VISLIST | PF1_MODEMSGRECV;
+ break;
+
+ case PFLAGNUM_2:
+ ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND |
+ PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE;
+ break;
+
+ case PFLAGNUM_4:
+ ret = PF4_AVATARS | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_FORCEAUTH;
+ break;
+
+ case PFLAGNUM_5: /* this is PFLAGNUM_5 change when alpha SDK is released */
+ ret = PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND |
+ PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE;
+ break;
+
+ case PFLAG_UNIQUEIDTEXT:
+ ret = (INT_PTR)Translate("Station ID");
+ break;
+ }
+ return ret;
+}
+
+// protocol service function to get weather protocol name
+INT_PTR WeatherGetName(WPARAM wParam, LPARAM lParam)
+{
+ strncpy((char*)lParam, WEATHERPROTOTEXT, wParam - 1);
+ *((char*)lParam + wParam - 1) = 0;
+ return 0;
+}
+
+// protocol service function to get the current status of the protocol
+INT_PTR WeatherGetStatus(WPARAM, LPARAM)
+{
+ return status;
+}
+
+// protocol service function to get the icon of the protocol
+INT_PTR WeatherLoadIcon(WPARAM wParam, LPARAM)
+{
+ return (LOWORD(wParam) == PLI_PROTOCOL) ? (INT_PTR)CopyIcon(LoadIconEx("main", FALSE)) : 0;
+}
+
+static void __cdecl AckThreadProc(HANDLE param)
+{
+ Sleep(100);
+ ProtoBroadcastAck(MODULENAME, (DWORD_PTR)param, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)1);
+}
+
+// nothing to do here because weather proto do not need to retrieve contact info form network
+// so just return a 0
+INT_PTR WeatherGetInfo(WPARAM, LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA *)lParam;
+ mir_forkthread(AckThreadProc, (void*)ccs->hContact);
+ return 0;
+}
+
+// avatars
+static const wchar_t *statusStr[] = { L"Light", L"Fog", L"SShower", L"Snow", L"RShower", L"Rain", L"PCloudy", L"Cloudy", L"Sunny", L"NA" };
+static const WORD statusValue[] = { LIGHT, FOG, SSHOWER, SNOW, RSHOWER, RAIN, PCLOUDY, CLOUDY, SUNNY, NA };
+
+INT_PTR WeatherGetAvatarInfo(WPARAM, LPARAM lParam)
+{
+ wchar_t szSearchPath[MAX_PATH], *chop;
+ unsigned i;
+ PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
+
+ GetModuleFileName(GetModuleHandle(nullptr), szSearchPath, _countof(szSearchPath));
+ chop = wcsrchr(szSearchPath, '\\');
+
+ if (chop) *chop = '\0';
+ else szSearchPath[0] = 0;
+
+ int iStatus = g_plugin.getWord(pai->hContact, "StatusIcon");
+ for (i = 0; i < 10; i++)
+ if (statusValue[i] == iStatus)
+ break;
+
+ if (i >= 10)
+ return GAIR_NOAVATAR;
+
+ pai->format = PA_FORMAT_PNG;
+ mir_snwprintf(pai->filename, L"%s\\Plugins\\Weather\\%s.png", szSearchPath, statusStr[i]);
+ if (_waccess(pai->filename, 4) == 0)
+ return GAIR_SUCCESS;
+
+ pai->format = PA_FORMAT_GIF;
+ mir_snwprintf(pai->filename, L"%s\\Plugins\\Weather\\%s.gif", szSearchPath, statusStr[i]);
+ if (_waccess(pai->filename, 4) == 0)
+ return GAIR_SUCCESS;
+
+ pai->format = PA_FORMAT_UNKNOWN;
+ pai->filename[0] = 0;
+ return GAIR_NOAVATAR;
+}
+
+void AvatarDownloaded(MCONTACT hContact)
+{
+ PROTO_AVATAR_INFORMATION ai = { 0 };
+ ai.hContact = hContact;
+
+ if (WeatherGetAvatarInfo(GAIF_FORCE, (LPARAM)&ai) == GAIR_SUCCESS)
+ ProtoBroadcastAck(MODULENAME, hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai);
+ else
+ ProtoBroadcastAck(MODULENAME, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr);
+}
+
+static void __cdecl WeatherGetAwayMsgThread(void *arg)
+{
+ Sleep(100);
+
+ MCONTACT hContact = (DWORD_PTR)arg;
+ DBVARIANT dbv;
+ if (!db_get_ws(hContact, "CList", "StatusMsg", &dbv)) {
+ ProtoBroadcastAck(MODULENAME, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, (LPARAM)dbv.pwszVal);
+ db_free(&dbv);
+ }
+ else ProtoBroadcastAck(MODULENAME, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1);
+}
+
+static INT_PTR WeatherGetAwayMsg(WPARAM, LPARAM lParam)
+{
+ CCSDATA* ccs = (CCSDATA*)lParam;
+ if (ccs == nullptr)
+ return 0;
+
+ mir_forkthread(WeatherGetAwayMsgThread, (void*)ccs->hContact);
+ return 1;
+}
+
+//============ PROTOCOL INITIALIZATION ============
+// protocol services
+void InitServices(void)
+{
+ CreateProtoServiceFunction(MODULENAME, PS_GETCAPS, WeatherGetCaps);
+ CreateProtoServiceFunction(MODULENAME, PS_GETNAME, WeatherGetName);
+ CreateProtoServiceFunction(MODULENAME, PS_LOADICON, WeatherLoadIcon);
+ CreateProtoServiceFunction(MODULENAME, PS_SETSTATUS, WeatherSetStatus);
+ CreateProtoServiceFunction(MODULENAME, PS_GETSTATUS, WeatherGetStatus);
+ CreateProtoServiceFunction(MODULENAME, PS_BASICSEARCH, WeatherBasicSearch);
+ CreateProtoServiceFunction(MODULENAME, PS_SEARCHBYEMAIL, WeatherBasicSearch);
+ CreateProtoServiceFunction(MODULENAME, PS_ADDTOLIST, WeatherAddToList);
+ CreateProtoServiceFunction(MODULENAME, PSS_GETINFO, WeatherGetInfo);
+ CreateProtoServiceFunction(MODULENAME, PS_GETAVATARINFO, WeatherGetAvatarInfo);
+ CreateProtoServiceFunction(MODULENAME, PSS_GETAWAYMSG, WeatherGetAwayMsg);
+ CreateProtoServiceFunction(MODULENAME, PS_CREATEADVSEARCHUI, WeatherCreateAdvancedSearchUI);
+ CreateProtoServiceFunction(MODULENAME, PS_SEARCHBYADVANCED, WeatherAdvancedSearch);
+
+ CreateProtoServiceFunction(MODULENAME, MS_WEATHER_GETDISPLAY, GetDisplaySvcFunc);
+}
+
+//============ MENU INITIALIZATION ============
+
+void UpdateMenu(BOOL State)
+{
+ // update option setting
+ opt.CAutoUpdate = State;
+ g_plugin.setByte("AutoUpdate", (BYTE)State);
+
+ if (State) { // to enable auto-update
+ Menu_ModifyItem(hEnableDisableMenu, LPGENW("Auto Update Enabled"), GetIconHandle("main"));
+ opt.AutoUpdate = 1;
+ }
+ else { // to disable auto-update
+ Menu_ModifyItem(hEnableDisableMenu, LPGENW("Auto Update Disabled"), GetIconHandle("disabled"));
+ opt.AutoUpdate = 0;
+ }
+
+ CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)hTBButton, !State ? TTBST_PUSHED : 0);
+}
+
+void UpdatePopupMenu(BOOL State)
+{
+ // update option setting
+ opt.UsePopup = State;
+ g_plugin.setByte("UsePopup", (BYTE)opt.UsePopup);
+
+ if (State) // to enable popup
+ Menu_ModifyItem(hEnableDisablePopupMenu, LPGENW("Disable &weather notification"), GetIconHandle("popup"));
+ else // to disable popup
+ Menu_ModifyItem(hEnableDisablePopupMenu, LPGENW("Enable &weather notification"), GetIconHandle("nopopup"));
+}
+
+// update the weather auto-update menu item when click on it
+INT_PTR EnableDisableCmd(WPARAM wParam, LPARAM lParam)
+{
+ UpdateMenu(wParam == TRUE ? (BOOL)lParam : !opt.CAutoUpdate);
+ return 0;
+}
+
+// update the weather popup menu item when click on it
+INT_PTR MenuitemNotifyCmd(WPARAM, LPARAM)
+{
+ UpdatePopupMenu(!opt.UsePopup);
+ return 0;
+}
+
+// adding weather contact menus
+// copied and modified form "modified MSN Protocol"
+void AddMenuItems(void)
+{
+ CMenuItem mi(&g_plugin);
+
+ // contact menu
+ SET_UID(mi, 0x266ef52b, 0x869a, 0x4cac, 0xa9, 0xf8, 0xea, 0x5b, 0xb8, 0xab, 0xe0, 0x24);
+ CreateServiceFunction(MS_WEATHER_UPDATE, UpdateSingleStation);
+ mi.position = -0x7FFFFFFA;
+ mi.hIcolibItem = GetIconHandle("update");
+ mi.name.a = LPGEN("Update Weather");
+ mi.pszService = MS_WEATHER_UPDATE;
+ Menu_AddContactMenuItem(&mi, MODULENAME);
+
+ SET_UID(mi, 0x45361b4, 0x8de, 0x44b4, 0x8f, 0x11, 0x9b, 0xe9, 0x6e, 0xa8, 0x83, 0x54);
+ CreateServiceFunction(MS_WEATHER_REFRESH, UpdateSingleRemove);
+ mi.position = -0x7FFFFFF9;
+ mi.hIcolibItem = GetIconHandle("update2");
+ mi.name.a = LPGEN("Remove Old Data then Update");
+ mi.pszService = MS_WEATHER_REFRESH;
+ Menu_AddContactMenuItem(&mi, MODULENAME);
+
+ SET_UID(mi, 0x4232975e, 0xb181, 0x46a5, 0xb7, 0x6e, 0xd2, 0x5f, 0xef, 0xb8, 0xc4, 0x4d);
+ CreateServiceFunction(MS_WEATHER_BRIEF, BriefInfoSvc);
+ mi.position = -0x7FFFFFF8;
+ mi.hIcolibItem = GetIconHandle("brief");
+ mi.name.a = LPGEN("Brief Information");
+ mi.pszService = MS_WEATHER_BRIEF;
+ Menu_AddContactMenuItem(&mi, MODULENAME);
+
+ SET_UID(mi, 0x3d6ed729, 0xd49a, 0x4ae9, 0x8e, 0x2, 0x9f, 0xe0, 0xf0, 0x2c, 0xcc, 0xb1);
+ CreateServiceFunction(MS_WEATHER_COMPLETE, LoadForecast);
+ mi.position = -0x7FFFFFF7;
+ mi.hIcolibItem = GetIconHandle("read");
+ mi.name.a = LPGEN("Read Complete Forecast");
+ mi.pszService = MS_WEATHER_COMPLETE;
+ Menu_AddContactMenuItem(&mi, MODULENAME);
+
+ SET_UID(mi, 0xc4b6c5e0, 0x13c3, 0x4e02, 0x8a, 0xeb, 0xeb, 0x8a, 0xe2, 0x66, 0x40, 0xd4);
+ CreateServiceFunction(MS_WEATHER_MAP, WeatherMap);
+ mi.position = -0x7FFFFFF6;
+ mi.hIcolibItem = GetIconHandle("map");
+ mi.name.a = LPGEN("Weather Map");
+ mi.pszService = MS_WEATHER_MAP;
+ Menu_AddContactMenuItem(&mi, MODULENAME);
+
+ SET_UID(mi, 0xee3ad7f4, 0x3377, 0x4e4c, 0x8f, 0x3c, 0x3b, 0xf5, 0xd4, 0x86, 0x28, 0x25);
+ CreateServiceFunction(MS_WEATHER_LOG, ViewLog);
+ mi.position = -0x7FFFFFF5;
+ mi.hIcolibItem = GetIconHandle("log");
+ mi.name.a = LPGEN("View Log");
+ mi.pszService = MS_WEATHER_LOG;
+ Menu_AddContactMenuItem(&mi, MODULENAME);
+
+ SET_UID(mi, 0x1b01cd6a, 0xe5ee, 0x42b4, 0xa1, 0x6d, 0x43, 0xb9, 0x4, 0x58, 0x43, 0x2e);
+ CreateServiceFunction(MS_WEATHER_EDIT, EditSettings);
+ mi.position = -0x7FFFFFF4;
+ mi.hIcolibItem = GetIconHandle("edit");
+ mi.name.a = LPGEN("Edit Settings");
+ mi.pszService = MS_WEATHER_EDIT;
+ Menu_AddContactMenuItem(&mi, MODULENAME);
+
+ // adding main menu items
+ mi.root = g_plugin.addRootMenu(MO_MAIN, LPGENW("Weather"), 500099000);
+ Menu_ConfigureItem(mi.root, MCI_OPT_UID, "82809D2F-2CF0-4E15-9350-D257A7748552");
+
+ SET_UID(mi, 0x5ad16188, 0xe0a0, 0x4c31, 0x85, 0xc3, 0xe4, 0x85, 0x79, 0x7e, 0x4b, 0x9c);
+ CreateServiceFunction(MS_WEATHER_ENABLED, EnableDisableCmd);
+ mi.name.a = LPGEN("Enable/Disable Weather Update");
+ mi.hIcolibItem = GetIconHandle("main");
+ mi.position = 10100001;
+ mi.pszService = MS_WEATHER_ENABLED;
+ hEnableDisableMenu = Menu_AddMainMenuItem(&mi);
+ UpdateMenu(opt.AutoUpdate);
+
+ SET_UID(mi, 0x2b1c2054, 0x2991, 0x4025, 0x87, 0x73, 0xb6, 0xf7, 0x85, 0xac, 0xc7, 0x37);
+ CreateServiceFunction(MS_WEATHER_UPDATEALL, UpdateAllInfo);
+ mi.position = 20100001;
+ mi.hIcolibItem = GetIconHandle("update");
+ mi.name.a = LPGEN("Update All Weather");
+ mi.pszService = MS_WEATHER_UPDATEALL;
+ Menu_AddMainMenuItem(&mi);
+
+ SET_UID(mi, 0x8234c00e, 0x788e, 0x424f, 0xbc, 0xc4, 0x2, 0xfd, 0x67, 0x58, 0x2d, 0x19);
+ CreateServiceFunction(MS_WEATHER_REFRESHALL, UpdateAllRemove);
+ mi.position = 20100002;
+ mi.hIcolibItem = GetIconHandle("update2");
+ mi.name.a = LPGEN("Remove Old Data then Update All");
+ mi.pszService = MS_WEATHER_REFRESHALL;
+ Menu_AddMainMenuItem(&mi);
+
+ // only run if popup service exists
+ if (ServiceExists(MS_POPUP_ADDPOPUPW)) {
+ SET_UID(mi, 0xdc5411cb, 0xb7c7, 0x443b, 0x88, 0x5a, 0x90, 0x24, 0x43, 0xde, 0x54, 0x3e);
+ CreateServiceFunction(MODULENAME "/PopupMenu", MenuitemNotifyCmd);
+ mi.name.a = LPGEN("Weather Notification");
+ mi.hIcolibItem = GetIconHandle("popup");
+ mi.position = 0;
+ mi.root = g_plugin.addRootMenu(MO_MAIN, LPGENW("Popups"), 0);
+ mi.pszService = MODULENAME "/PopupMenu";
+ hEnableDisablePopupMenu = Menu_AddMainMenuItem(&mi);
+ UpdatePopupMenu(opt.UsePopup);
+ }
+
+ if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) {
+ SET_UID(mi, 0xe193fe9b, 0xf6ad, 0x41ac, 0x95, 0x29, 0x45, 0x4, 0x44, 0xb1, 0xeb, 0x5d);
+ mi.pszService = "Weather/mwin_menu";
+ CreateServiceFunction(mi.pszService, Mwin_MenuClicked);
+ mi.position = -0x7FFFFFF0;
+ mi.hIcolibItem = nullptr;
+ mi.root = nullptr;
+ mi.name.a = LPGEN("Display in a frame");
+ hMwinMenu = Menu_AddContactMenuItem(&mi, MODULENAME);
+ }
+}