diff options
Diffstat (limited to 'protocols/Weather/src')
-rw-r--r-- | protocols/Weather/src/proto.h | 89 | ||||
-rw-r--r-- | protocols/Weather/src/resource.h | 2 | ||||
-rw-r--r-- | protocols/Weather/src/stdafx.h | 57 | ||||
-rw-r--r-- | protocols/Weather/src/version.h | 6 | ||||
-rw-r--r-- | protocols/Weather/src/weather.cpp | 47 | ||||
-rw-r--r-- | protocols/Weather/src/weather_addstn.cpp | 14 | ||||
-rw-r--r-- | protocols/Weather/src/weather_contacts.cpp | 26 | ||||
-rw-r--r-- | protocols/Weather/src/weather_conv.cpp | 11 | ||||
-rw-r--r-- | protocols/Weather/src/weather_data.cpp | 8 | ||||
-rw-r--r-- | protocols/Weather/src/weather_mwin.cpp | 44 | ||||
-rw-r--r-- | protocols/Weather/src/weather_opt.cpp | 13 | ||||
-rw-r--r-- | protocols/Weather/src/weather_popup.cpp | 9 | ||||
-rw-r--r-- | protocols/Weather/src/weather_proto.cpp | 74 | ||||
-rw-r--r-- | protocols/Weather/src/weather_svcs.cpp | 107 | ||||
-rw-r--r-- | protocols/Weather/src/weather_update.cpp | 109 | ||||
-rw-r--r-- | protocols/Weather/src/weather_userinfo.cpp | 15 |
16 files changed, 313 insertions, 318 deletions
diff --git a/protocols/Weather/src/proto.h b/protocols/Weather/src/proto.h index 6e1747b8c2..d94e1b1850 100644 --- a/protocols/Weather/src/proto.h +++ b/protocols/Weather/src/proto.h @@ -1,5 +1,32 @@ #pragma once +struct UPDATELIST +{ + MCONTACT hContact; + UPDATELIST *next; +}; + +struct WEATHERINFO +{ + MCONTACT hContact; + TCHAR id[128]; + TCHAR city[128]; + TCHAR update[64]; + TCHAR cond[128]; + TCHAR temp[16]; + TCHAR low[16]; + TCHAR high[16]; + TCHAR feel[16]; + TCHAR wind[16]; + TCHAR winddir[64]; + TCHAR dewpoint[16]; + TCHAR pressure[16]; + TCHAR humid[16]; + TCHAR vis[16]; + TCHAR sunrise[32]; + TCHAR sunset[32]; +}; + struct MYOPTIONS { // main options @@ -60,6 +87,7 @@ class CWeatherProto : public PROTO<CWeatherProto> friend class CPopupOptsDlg; friend class CBriefInfoDlg; friend class COptionsTextDlg; + friend class WeatherUserInfoDlg; class CProtoImpl { @@ -90,16 +118,19 @@ class CWeatherProto : public PROTO<CWeatherProto> } m_impl; - void DoUpdate(); - void StartUpdate(); + // avatars + void AvatarDownloaded(MCONTACT hContact); + + INT_PTR __cdecl AdvancedStatusIconSvc(WPARAM, LPARAM); + INT_PTR __cdecl GetAvatarInfoSvc(WPARAM, LPARAM); // contacts - INT_PTR __cdecl ViewLog(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl LoadForecast(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl WeatherMap(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl EditSettings(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl ViewLog(WPARAM, LPARAM); + INT_PTR __cdecl LoadForecast(WPARAM, LPARAM); + INT_PTR __cdecl WeatherMap(WPARAM, LPARAM); + INT_PTR __cdecl EditSettings(WPARAM, LPARAM); - int __cdecl BriefInfoEvt(WPARAM wParam, LPARAM lParam); + int __cdecl BriefInfoEvt(WPARAM, LPARAM); bool IsMyContact(MCONTACT hContact); @@ -116,6 +147,8 @@ class CWeatherProto : public PROTO<CWeatherProto> void ConvertDataValue(struct WIDATAITEM *UpdateData, wchar_t *Data); void EraseAllInfo(void); void GetDataValue(WIDATAITEM *UpdateData, wchar_t *Data, wchar_t **szData); + void GetStationID(MCONTACT hContact, wchar_t *id, int idlen); + WEATHERINFO LoadWeatherInfo(MCONTACT hContact); // http int InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **szData); @@ -124,13 +157,18 @@ class CWeatherProto : public PROTO<CWeatherProto> void InitMenuItems(); void UpdateMenu(BOOL State); - INT_PTR __cdecl EnableDisableCmd(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl EnableDisableCmd(WPARAM, LPARAM); // mwin + void AddFrameWindow(MCONTACT hContact); + void RemoveFrameWindow(MCONTACT hContact); + void InitMwin(void); void DestroyMwin(void); - int __cdecl BuildContactMenu(WPARAM wparam, LPARAM lparam); + int __cdecl BuildContactMenu(WPARAM, LPARAM); + + INT_PTR __cdecl Mwin_MenuClicked(WPARAM, LPARAM); // options void LoadOptions(); @@ -138,7 +176,7 @@ class CWeatherProto : public PROTO<CWeatherProto> void RestartTimer(); void InitPopupOptions(WPARAM); - int __cdecl OptInit(WPARAM wParam, LPARAM lParam); + int __cdecl OptInit(WPARAM, LPARAM); CMStringW GetTextValue(int c); @@ -147,6 +185,8 @@ class CWeatherProto : public PROTO<CWeatherProto> int WeatherPopup(MCONTACT hContact, bool bNew); // search + bool CheckSearch(); + int IDSearch(wchar_t *id, const int searchId); int IDSearchProc(wchar_t *sID, const int searchId, struct WIIDSEARCH *sData, wchar_t *svc, wchar_t *svcname); @@ -157,7 +197,14 @@ class CWeatherProto : public PROTO<CWeatherProto> void __cdecl BasicSearchThread(void *); // update weather - HANDLE hUpdateMutex; + UPDATELIST *UpdateListHead = nullptr, *UpdateListTail = nullptr; + + // check if weather is currently updating + bool m_bThreadRunning; + mir_cs m_csUpdate; + + void DoUpdate(); + void StartUpdate(); int GetWeatherData(MCONTACT hContact); int UpdateWeather(MCONTACT hContact); @@ -171,8 +218,8 @@ class CWeatherProto : public PROTO<CWeatherProto> INT_PTR __cdecl UpdateSingleStation(WPARAM, LPARAM); INT_PTR __cdecl UpdateSingleRemove(WPARAM, LPARAM); - INT_PTR __cdecl UpdateAllInfo(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl UpdateAllRemove(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl UpdateAllInfo(WPARAM, LPARAM); + INT_PTR __cdecl UpdateAllRemove(WPARAM, LPARAM); // user info int __cdecl UserInfoInit(WPARAM, LPARAM); @@ -182,10 +229,15 @@ public: ~CWeatherProto(); MYOPTIONS opt; + CMOption<bool> m_bPopups; INT_PTR __cdecl BriefInfo(WPARAM, LPARAM); - static LRESULT CALLBACK CWeatherProto::PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + int MapCondToStatus(MCONTACT hContact); + HICON GetStatusIcon(MCONTACT hContact); + HICON GetStatusIconBig(MCONTACT hContact); + + static LRESULT CALLBACK CWeatherProto::PopupWndProc(HWND hWnd, UINT uMsg, WPARAM, LPARAM); // PROTO_INTERFACE MCONTACT AddToList(int flags, PROTOSEARCHRESULT *psr) override; @@ -196,9 +248,17 @@ public: INT_PTR GetCaps(int type, MCONTACT hContact) override; int SetStatus(int iNewStatus) override; + void __cdecl GetAwayMsgThread(void *arg); + HANDLE GetAwayMsg(MCONTACT hContact) override; + + void __cdecl AckThreadProc(void *arg); + int GetInfo(MCONTACT hContact, int) override; + bool OnContactDeleted(MCONTACT, uint32_t flags) override; void OnModulesLoaded() override; void OnShutdown() override; + + int __cdecl OnToolbarLoaded(WPARAM, LPARAM); }; typedef CProtoDlgBase<CWeatherProto> CWeatherDlgBase; @@ -211,7 +271,6 @@ struct CMPlugin : public ACCPROTOPLUGIN<CWeatherProto> CMPlugin(); HINSTANCE hIconsDll = nullptr; - CMOption<bool> bPopups; int Load() override; int Unload() override; diff --git a/protocols/Weather/src/resource.h b/protocols/Weather/src/resource.h index 28b2aa9163..25effcf355 100644 --- a/protocols/Weather/src/resource.h +++ b/protocols/Weather/src/resource.h @@ -39,7 +39,6 @@ #define IDC_CH 2013 #define IDC_NTEXT 2015 #define IDC_DEGREE 2016 -#define IDC_E 2017 #define IDC_W 2018 #define IDC_POP1 2019 #define IDC_XTEXT 2020 @@ -157,7 +156,6 @@ #define ID_T2 40011 #define ID_MPREVIEW 40020 #define ID_MRESET 40021 -#define IDC_STATIC -1 // Next default values for new objects // diff --git a/protocols/Weather/src/stdafx.h b/protocols/Weather/src/stdafx.h index 59f2e4fa38..a6992c2d62 100644 --- a/protocols/Weather/src/stdafx.h +++ b/protocols/Weather/src/stdafx.h @@ -24,8 +24,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #pragma once
-//============ THE INCLUDES ===========
-
#include <share.h>
#include <time.h>
#include <windows.h>
@@ -57,14 +55,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <m_xstatus.h>
#include <m_tipper.h>
-#include <m_weather.h>
#include <m_toptoolbar.h>
#include "resource.h"
#include "version.h"
#include "proto.h"
-//============ CONSTANTS ============
+/////////////////////////////////////////////////////////////////////////////////////////
+// CONSTANTS
// name
#define MODULENAME "Weather"
@@ -119,17 +117,8 @@ enum EWeatherCondition // defaults constants
#define VAR_LIST_OPT TranslateT("%c\tcurrent condition\n%d\tcurrent date\n%e\tdewpoint\n%f\tfeel-like temp\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\n----------\n\\n\tnew line")
-//============ STRUCT USED TO MAKE AN UPDATE LIST ============
-struct WCONTACTLIST {
- MCONTACT hContact;
- struct WCONTACTLIST *next;
-};
-
-typedef struct WCONTACTLIST UPDATELIST;
-
-extern UPDATELIST *UpdateListHead, *UpdateListTail;
-
-//============ DATA FORMAT STRUCT ============
+/////////////////////////////////////////////////////////////////////////////////////////
+// DATA FORMAT STRUCT
#define WID_NORMAL 0
#define WID_SET 1
@@ -227,7 +216,8 @@ struct WIDATA WICONDLIST CondList[MAX_COND];
};
-//============ DATA LIST (LINKED LIST) ============
+/////////////////////////////////////////////////////////////////////////////////////////
+// DATA LIST (LINKED LIST)
struct DATALIST
{
@@ -237,7 +227,8 @@ struct DATALIST typedef struct DATALIST WIDATALIST;
-//============ GLOBAL VARIABLES ============
+/////////////////////////////////////////////////////////////////////////////////////////
+// GLOBAL VARIABLES
extern WIDATALIST *WIHead, *WITail;
@@ -249,20 +240,12 @@ extern HANDLE hTBButton; extern HGENMENU hMwinMenu;
-// check if weather is currently updating
-extern BOOL ThreadRunning;
extern bool g_bIsUtf;
-//============ FUNCTION PRIMITIVES ============
-
-// functions in weather_addstn.c
-BOOL CheckSearch();
-
+/////////////////////////////////////////////////////////////////////////////////////////
// functions in weather_conv.c
+
void ClearStatusIcons();
-int MapCondToStatus(MCONTACT hContact);
-HICON GetStatusIcon(MCONTACT hContact);
-HICON GetStatusIconBig(MCONTACT hContact);
uint16_t GetIcon(const wchar_t* cond, WIDATA *Data);
void CaseConv(wchar_t *str);
@@ -272,16 +255,15 @@ void ConvertBackslashes(char *str); char *GetSearchStr(char *dis);
wchar_t *GetDisplay(WEATHERINFO *w, const wchar_t *dis, wchar_t* str);
-INT_PTR GetDisplaySvcFunc(WPARAM wParam, LPARAM lParam);
void GetSvc(wchar_t *pszID);
void GetID(wchar_t *pszID);
wchar_t *GetError(int code);
+/////////////////////////////////////////////////////////////////////////////////////////
// functions in weather_data.c
-void GetStationID(MCONTACT hContact, wchar_t* id, int idlen);
-WEATHERINFO LoadWeatherInfo(MCONTACT Change);
+
int DBGetData(MCONTACT hContact, char *setting, DBVARIANT *dbv);
void wSetData(char *&Data, const char *Value);
@@ -292,7 +274,9 @@ void wfree(wchar_t *&Data); void DBDataManage(MCONTACT hContact, uint16_t Mode, WPARAM wParam, LPARAM lParam);
+/////////////////////////////////////////////////////////////////////////////////////////
// functions in weather_ini.c
+
WIDATA* GetWIData(wchar_t *pszServ);
bool IsContainedInCondList(const wchar_t *pszStr, WICONDLIST *List);
@@ -300,24 +284,19 @@ bool IsContainedInCondList(const wchar_t *pszStr, WICONDLIST *List); void DestroyWIList();
bool LoadWIData(bool dial);
+/////////////////////////////////////////////////////////////////////////////////////////
// functions in weather_info.c
+
void GetINIInfo(wchar_t *pszSvc);
wchar_t* GetINIVersionNum(int iVersion);
const wchar_t *GetDefaultText(int c);
void MoreVarList();
-// functions in weather_svcs.c
-void InitServices(void);
-
-INT_PTR WeatherLoadIcon(WPARAM wParam, LPARAM lParam);
-
-void AvatarDownloaded(MCONTACT hContact);
-
+/////////////////////////////////////////////////////////////////////////////////////////
// function from multiwin module
-INT_PTR Mwin_MenuClicked(WPARAM wParam, LPARAM lParam);
+
void UpdateMwinData(MCONTACT hContact);
-void removeWindow(MCONTACT hContact);
/////////////////////////////////////////////////////////////////////////////////////////
// UI Classes
diff --git a/protocols/Weather/src/version.h b/protocols/Weather/src/version.h index ab7538244e..cf07dd1fa3 100644 --- a/protocols/Weather/src/version.h +++ b/protocols/Weather/src/version.h @@ -1,7 +1,7 @@ -#define __MAJOR_VERSION 0
-#define __MINOR_VERSION 4
+#define __MAJOR_VERSION 1
+#define __MINOR_VERSION 1
#define __RELEASE_NUM 0
-#define __BUILD_NUM 8
+#define __BUILD_NUM 1
#include <stdver.h>
diff --git a/protocols/Weather/src/weather.cpp b/protocols/Weather/src/weather.cpp index f84a009ff8..7c61a6c075 100644 --- a/protocols/Weather/src/weather.cpp +++ b/protocols/Weather/src/weather.cpp @@ -37,14 +37,6 @@ MWindowList hDataWindowList, hWindowList; CMPlugin g_plugin; -MYOPTIONS opt; - -// check if weather is currently updating -BOOL ThreadRunning; - -// variable to determine if module loaded -BOOL ModuleLoaded = FALSE; - VARSW g_pwszIconsName(L"%miranda_path%\\Icons\\proto_Weather.dll"); HANDLE hTBButton = nullptr; @@ -67,8 +59,7 @@ static const PLUGININFOEX pluginInfoEx = }; CMPlugin::CMPlugin() : - ACCPROTOPLUGIN<CWeatherProto>(MODULENAME, pluginInfoEx), - bPopups(MODULENAME, "UsePopup", true) + ACCPROTOPLUGIN<CWeatherProto>(MODULENAME, pluginInfoEx) { SetUniqueId("ID"); } @@ -79,23 +70,11 @@ extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOC ///////////////////////////////////////////////////////////////////////////////////////// -static int OnToolbarLoaded(WPARAM, LPARAM) +static int OnPreShutdown(WPARAM, LPARAM) { - TTBButton ttb = {}; - ttb.name = LPGEN("Enable/disable auto update"); - ttb.pszService = MS_WEATHER_ENABLED; - ttb.pszTooltipUp = LPGEN("Auto Update Enabled"); - ttb.pszTooltipDn = LPGEN("Auto Update Disabled"); - ttb.hIconHandleUp = g_plugin.getIconHandle(IDI_ICON); - ttb.hIconHandleDn = g_plugin.getIconHandle(IDI_DISABLED); - ttb.dwFlags = (g_plugin.getByte("AutoUpdate", 1) ? 0 : TTBBF_PUSHED) | TTBBF_ASPUSHBUTTON | TTBBF_VISIBLE; - hTBButton = g_plugin.addTTB(&ttb); - return 0; -} - -static int OnModulesLoaded(WPARAM, LPARAM) -{ - HookEvent(ME_TTB_MODULELOADED, OnToolbarLoaded); + WindowList_Broadcast(hWindowList, WM_CLOSE, 0, 0); + WindowList_Broadcast(hDataWindowList, WM_CLOSE, 0, 0); + SendMessage(hWndSetup, WM_CLOSE, 0, 0); return 0; } @@ -118,32 +97,24 @@ int CMPlugin::Load() { g_plugin.registerIcon(MODULENAME, iconList, MODULENAME); + HookEvent(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown); + // load dll with icons hIconsDll = LoadLibraryW(g_pwszIconsName); // load weather update data LoadWIData(true); - // initialize options and network - HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - + // window lists hDataWindowList = WindowList_Create(); hWindowList = WindowList_Create(); - // initialize weather protocol services - InitServices(); - // add sound event addSound("weatherupdated", _A2W(MODULENAME), LPGENW("Condition Changed")); addSound("weatheralert", _A2W(MODULENAME), LPGENW("Alert Issued")); - // popup initialization - addPopupOption(LPGEN("Weather notifications"), bPopups); - // window needed for popup commands - wchar_t SvcFunc[100]; - mir_snwprintf(SvcFunc, L"%s__PopupWindow", _A2W(MODULENAME)); - hPopupWindow = CreateWindowEx(WS_EX_TOOLWINDOW, L"static", SvcFunc, 0, CW_USEDEFAULT, CW_USEDEFAULT, + hPopupWindow = CreateWindowEx(WS_EX_TOOLWINDOW, L"static", _A2W(MODULENAME) L"__PopupWindow", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, nullptr, g_plugin.getInst(), nullptr); SetWindowLongPtr(hPopupWindow, GWLP_WNDPROC, (LONG_PTR)&CWeatherProto::PopupWndProc); return 0; diff --git a/protocols/Weather/src/weather_addstn.cpp b/protocols/Weather/src/weather_addstn.cpp index 3704dc68c4..3de0e48984 100644 --- a/protocols/Weather/src/weather_addstn.cpp +++ b/protocols/Weather/src/weather_addstn.cpp @@ -40,7 +40,7 @@ MCONTACT CWeatherProto::AddToList(int, PROTOSEARCHRESULT *psr) for (auto &hContact : AccContacts()) { DBVARIANT dbv; // check ID to see if the contact already exist in the database - if (!g_plugin.getWString(hContact, "ID", &dbv)) { + if (!getWString(hContact, "ID", &dbv)) { if (!mir_wstrcmpi(psr->email.w, dbv.pwszVal)) { // remove the flag for not on list and hidden, thus make the contact visible // and add them on the list @@ -61,7 +61,7 @@ MCONTACT CWeatherProto::AddToList(int, PROTOSEARCHRESULT *psr) return 0; MCONTACT hContact = db_add_contact(); - Proto_AddToContact(hContact, MODULENAME); + Proto_AddToContact(hContact, m_szModuleName); // suppress online notification for the new contact Ignore_Ignore(hContact, IGNOREEVENT_USERONLINE); @@ -103,14 +103,14 @@ MCONTACT CWeatherProto::AddToList(int, PROTOSEARCHRESULT *psr) GetStationID(hContact, opt.Default, _countof(opt.Default)); opt.DefStn = hContact; - ptrW wszNick(g_plugin.getWStringA(hContact, "Nick")); + ptrW wszNick(getWStringA(hContact, "Nick")); if (mir_wstrlen(wszNick)) { // notification message box mir_snwprintf(str, TranslateT("%s is now the default weather station"), wszNick); MessageBox(nullptr, str, TranslateT("Weather Protocol"), MB_OK | MB_ICONINFORMATION); } - g_plugin.setWString("Default", opt.Default); + setWString("Default", opt.Default); } // display the Edit Settings dialog box @@ -121,13 +121,13 @@ MCONTACT CWeatherProto::AddToList(int, PROTOSEARCHRESULT *psr) ///////////////////////////////////////////////////////////////////////////////////////// // shows a message box and cancel search if update is in process -BOOL CheckSearch() +bool CWeatherProto::CheckSearch() { if (UpdateListHead != nullptr) { MessageBox(nullptr, TranslateT("Please try again after weather update is completed."), TranslateT("Weather Protocol"), MB_OK | MB_ICONERROR); - return FALSE; + return false; } - return TRUE; + return true; } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/protocols/Weather/src/weather_contacts.cpp b/protocols/Weather/src/weather_contacts.cpp index 8db99359c0..3aaf44a1e3 100644 --- a/protocols/Weather/src/weather_contacts.cpp +++ b/protocols/Weather/src/weather_contacts.cpp @@ -46,7 +46,7 @@ INT_PTR CWeatherProto::ViewLog(WPARAM wParam, LPARAM lParam) { // see if the log path is set DBVARIANT dbv; - if (!g_plugin.getWString(wParam, "Log", &dbv)) { + if (!getWString(wParam, "Log", &dbv)) { if (dbv.pszVal[0] != 0) ShellExecute((HWND)lParam, L"open", dbv.pwszVal, L"", L"", SW_SHOW); db_free(&dbv); @@ -67,7 +67,7 @@ INT_PTR CWeatherProto::LoadForecast(WPARAM wParam, LPARAM) GetStationID(wParam, id, _countof(id)); if (id[0] != 0) { // check if the complte forecast URL is set. If it is not, display warning and quit - if (db_get_wstatic(wParam, MODULENAME, "InfoURL", loc2, _countof(loc2)) || loc2[0] == 0) { + if (db_get_wstatic(wParam, m_szModuleName, "InfoURL", loc2, _countof(loc2)) || loc2[0] == 0) { MessageBox(nullptr, TranslateT("The URL for complete forecast has not been set. You can set it from the Edit Settings dialog."), TranslateT("Weather Protocol"), MB_ICONINFORMATION); return 1; } @@ -87,7 +87,7 @@ INT_PTR CWeatherProto::WeatherMap(WPARAM wParam, LPARAM) GetStationID(wParam, id, _countof(id)); if (id[0] != 0) { // check if the weather map URL is set. If it is not, display warning and quit - if (db_get_wstatic(wParam, MODULENAME, "MapURL", loc2, _countof(loc2)) || loc2[0] == 0) { + if (db_get_wstatic(wParam, m_szModuleName, "MapURL", loc2, _countof(loc2)) || loc2[0] == 0) { MessageBox(nullptr, TranslateT("The URL for weather map has not been set. You can set it from the Edit Settings dialog."), TranslateT("Weather Protocol"), MB_ICONINFORMATION); return 1; } @@ -264,7 +264,7 @@ public: { // the button for getting station name from the internet // this function uses the ID search for add/find weather station - if (!CheckSearch()) + if (!m_proto->CheckSearch()) return; // don't download if update is in progress // get the weather update data using the string in the ID field @@ -387,14 +387,14 @@ public: // temporary disable the protocol while applying the change // start writing the new settings to database GetDlgItemText(m_hwnd, IDC_ID, str, _countof(str)); - g_plugin.setWString(hContact, "ID", str); + m_proto->setWString(hContact, "ID", str); if ((uint8_t)IsDlgButtonChecked(m_hwnd, IDC_DEFA)) { // if default station is set mir_wstrcpy(m_proto->opt.Default, str); m_proto->opt.DefStn = hContact; - g_plugin.setWString("Default", m_proto->opt.Default); + m_proto->setWString("Default", m_proto->opt.Default); } GetDlgItemText(m_hwnd, IDC_NAME, city, _countof(city)); - g_plugin.setWString(hContact, "Nick", city); + m_proto->setWString(hContact, "Nick", city); mir_snwprintf(str2, TranslateT("Current weather information for %s."), city); if ((uint8_t)IsDlgButtonChecked(m_hwnd, IDC_External)) { GetDlgItemText(m_hwnd, IDC_LOG, str, _countof(str)); @@ -409,7 +409,7 @@ public: m_proto->setWString(hContact, "MapURL", str); m_proto->setWord(hContact, "Status", ID_STATUS_OFFLINE); m_proto->setWord(hContact, "StatusIcon", -1); - AvatarDownloaded(hContact); + m_proto->AvatarDownloaded(hContact); m_proto->setWString(hContact, "About", str2); m_proto->setByte(hContact, "History", (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_Internal)); m_proto->setByte(hContact, "Overwrite", (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_Overwrite)); @@ -418,7 +418,7 @@ public: m_proto->setByte(hContact, "DAutoUpdate", (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_DAutoUpdate)); // re-enable the protocol and update the data for the station - g_plugin.setString(hContact, "LastCondition", "None"); + m_proto->setString(hContact, "LastCondition", "None"); m_proto->UpdateSingleStation(hContact, 0); } }; @@ -447,7 +447,7 @@ INT_PTR CWeatherProto::EditSettings(WPARAM wParam, LPARAM) bool CWeatherProto::OnContactDeleted(MCONTACT hContact, uint32_t) { - removeWindow(hContact); + RemoveFrameWindow(hContact); // exit this function if it is not default station ptrW tszID(getWStringA(hContact, "ID")); @@ -468,13 +468,13 @@ bool CWeatherProto::OnContactDeleted(MCONTACT hContact, uint32_t) if (mir_wstrcmp(opt.Default, tszID)) { wcsncpy_s(opt.Default, tszID, _TRUNCATE); opt.DefStn = cc; - ptrW tszNick(g_plugin.getWStringA(cc, "Nick")); + ptrW tszNick(getWStringA(cc, "Nick")); if (tszNick != NULL) { wchar_t str[255]; mir_snwprintf(str, TranslateT("%s is now the default weather station"), (wchar_t*)tszNick); MessageBox(nullptr, str, TranslateT("Weather Protocol"), MB_OK | MB_ICONINFORMATION); } - g_plugin.setWString("Default", opt.Default); + setWString("Default", opt.Default); return true; } } @@ -482,6 +482,6 @@ bool CWeatherProto::OnContactDeleted(MCONTACT hContact, uint32_t) // got here if no more weather station left opt.Default[0] = 0; // no default station opt.DefStn = NULL; - g_plugin.setWString("Default", opt.Default); + setWString("Default", opt.Default); return true; } diff --git a/protocols/Weather/src/weather_conv.cpp b/protocols/Weather/src/weather_conv.cpp index 7b1897834e..9cb2677099 100644 --- a/protocols/Weather/src/weather_conv.cpp +++ b/protocols/Weather/src/weather_conv.cpp @@ -444,7 +444,7 @@ void ConvertBackslashes(char *str) // dis = original string // return value = the modified string with space -> _T("%20" -char *GetSearchStr(char *dis) +char* GetSearchStr(char *dis) { char *pstr = dis; size_t len = mir_strlen(dis); @@ -466,7 +466,7 @@ char *GetSearchStr(char *dis) // dis = the string to parse // return value = the parsed string -wchar_t *GetDisplay(WEATHERINFO *w, const wchar_t *dis, wchar_t *str) +wchar_t* GetDisplay(WEATHERINFO *w, const wchar_t *dis, wchar_t *str) { wchar_t lpzDate[32], chr; char name[256], temp[2]; @@ -547,13 +547,6 @@ wchar_t *GetDisplay(WEATHERINFO *w, const wchar_t *dis, wchar_t *str) return str; } -wchar_t svcReturnText[MAX_TEXT_SIZE]; -INT_PTR GetDisplaySvcFunc(WPARAM wParam, LPARAM lParam) -{ - WEATHERINFO winfo = LoadWeatherInfo(wParam); - return (INT_PTR)GetDisplay(&winfo, (wchar_t*)lParam, svcReturnText); -} - ///////////////////////////////////////////////////////////////////////////////////////// // get service data module internal name // mod/id <- the mod part diff --git a/protocols/Weather/src/weather_data.cpp b/protocols/Weather/src/weather_data.cpp index 2ee99cda25..88c1572f43 100644 --- a/protocols/Weather/src/weather_data.cpp +++ b/protocols/Weather/src/weather_data.cpp @@ -30,10 +30,10 @@ saving individual weather data for a weather contact. // hContact = the current contact handle // return value = the string for station ID -void GetStationID(MCONTACT hContact, wchar_t *id, int idlen) +void CWeatherProto::GetStationID(MCONTACT hContact, wchar_t *id, int idlen) { // accessing the database - if (db_get_wstatic(hContact, MODULENAME, "ID", id, idlen)) + if (db_get_wstatic(hContact, m_szModuleName, "ID", id, idlen)) id[0] = 0; } @@ -42,7 +42,7 @@ void GetStationID(MCONTACT hContact, wchar_t *id, int idlen) // hContact = current contact handle // return value = the current weather information in WEATHERINFO struct -WEATHERINFO LoadWeatherInfo(MCONTACT hContact) +WEATHERINFO CWeatherProto::LoadWeatherInfo(MCONTACT hContact) { // obtaining values from the DB // assuming station ID must exist at all time, but others does not have to @@ -51,7 +51,7 @@ WEATHERINFO LoadWeatherInfo(MCONTACT hContact) winfo.hContact = hContact; GetStationID(hContact, winfo.id, _countof(winfo.id)); - if (db_get_wstatic(hContact, MODULENAME, "Nick", winfo.city, _countof(winfo.city))) + if (db_get_wstatic(hContact, m_szModuleName, "Nick", winfo.city, _countof(winfo.city))) wcsncpy(winfo.city, NODATA, _countof(winfo.city) - 1); if (db_get_wstatic(hContact, WEATHERCONDITION, "Update", winfo.update, _countof(winfo.update))) wcsncpy(winfo.update, NODATA, _countof(winfo.update) - 1); diff --git a/protocols/Weather/src/weather_mwin.cpp b/protocols/Weather/src/weather_mwin.cpp index d6ae726046..57b775c81b 100644 --- a/protocols/Weather/src/weather_mwin.cpp +++ b/protocols/Weather/src/weather_mwin.cpp @@ -140,11 +140,11 @@ static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara if (!data->haveAvatar) { picSize = GetSystemMetrics(SM_CXICON); - hIcon = GetStatusIconBig(data->hContact); + hIcon = data->ppro->GetStatusIconBig(data->hContact); } LOGFONT lfnt, lfnt1; - COLORREF clr = g_plugin.getDword("ColorMwinFrame", GetSysColor(COLOR_3DFACE)); + COLORREF clr = data->ppro->getDword("ColorMwinFrame", GetSysColor(COLOR_3DFACE)); COLORREF fntc = Font_GetW(_A2W(MODULENAME), LPGENW("Frame Font"), &lfnt); COLORREF fntc1 = Font_GetW(_A2W(MODULENAME), LPGENW("Frame Title Font"), &lfnt1); @@ -220,10 +220,17 @@ static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara return(TRUE); } -static void addWindow(MCONTACT hContact) +void UpdateMwinData(MCONTACT hContact) +{ + HWND hwnd = WindowList_Find(hMwinWindowList, hContact); + if (hwnd != nullptr) + RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); +} + +void CWeatherProto::AddFrameWindow(MCONTACT hContact) { DBVARIANT dbv; - if (g_plugin.getWString(hContact, "Nick", &dbv)) + if (getWString(hContact, "Nick", &dbv)) return; wchar_t winname[512]; @@ -231,7 +238,7 @@ static void addWindow(MCONTACT hContact) db_free(&dbv); HWND hWnd = CreateWindow(L"WeatherFrame", L"", WS_CHILD | WS_VISIBLE, - 0, 0, 10, 10, g_clistApi.hwndContactList, nullptr, g_plugin.getInst(), (void*)hContact); + 0, 0, 10, 10, g_clistApi.hwndContactList, nullptr, g_plugin.getInst(), (void *)hContact); WindowList_Add(hMwinWindowList, hWnd, hContact); CLISTFrame Frame = {}; @@ -244,35 +251,28 @@ static void addWindow(MCONTACT hContact) Frame.height = 32; int frameID = g_plugin.addFrame(&Frame); - g_plugin.setDword(hContact, "mwin", frameID); + setDword(hContact, "mwin", frameID); Contact::Hide(hContact); } -void removeWindow(MCONTACT hContact) +void CWeatherProto::RemoveFrameWindow(MCONTACT hContact) { - uint32_t frameId = g_plugin.getDword(hContact, "mwin"); + uint32_t frameId = getDword(hContact, "mwin"); WindowList_Remove(hMwinWindowList, WindowList_Find(hMwinWindowList, hContact)); CallService(MS_CLIST_FRAMES_REMOVEFRAME, frameId, 0); - g_plugin.setDword(hContact, "mwin", 0); + setDword(hContact, "mwin", 0); Contact::Hide(hContact, false); } -void UpdateMwinData(MCONTACT hContact) +INT_PTR CWeatherProto::Mwin_MenuClicked(WPARAM hContact, LPARAM) { - HWND hwnd = WindowList_Find(hMwinWindowList, hContact); - if (hwnd != nullptr) - RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); -} - -INT_PTR Mwin_MenuClicked(WPARAM wParam, LPARAM) -{ - BOOL addwnd = WindowList_Find(hMwinWindowList, wParam) == nullptr; - if (addwnd) - addWindow(wParam); + if (WindowList_Find(hMwinWindowList, hContact)) + RemoveFrameWindow(hContact); else - removeWindow(wParam); + AddFrameWindow(hContact); + return 0; } @@ -341,7 +341,7 @@ void CWeatherProto::InitMwin(void) for (auto &hContact : AccContacts()) if (g_plugin.getDword(hContact, "mwin")) - addWindow(hContact); + AddFrameWindow(hContact); hFontHook = HookEvent(ME_FONT_RELOAD, RedrawFrame); } diff --git a/protocols/Weather/src/weather_opt.cpp b/protocols/Weather/src/weather_opt.cpp index 5ee7e3353d..9dc6aafba2 100644 --- a/protocols/Weather/src/weather_opt.cpp +++ b/protocols/Weather/src/weather_opt.cpp @@ -376,9 +376,9 @@ public: for (auto &it : controls) { GetDlgItemText(m_hwnd, it.id, textstr, _countof(textstr)); if (!mir_wstrcmpi(textstr, GetDefaultText(it.c))) - g_plugin.delSetting(it.setting); + m_proto->delSetting(it.setting); else - g_plugin.setWString(it.setting, textstr); + m_proto->setWString(it.setting, textstr); } m_proto->SaveOptions(); @@ -406,7 +406,7 @@ public: case ID_MPREVIEW: { // show the preview in a message box, using the weather data from the default station - WEATHERINFO winfo = LoadWeatherInfo(m_proto->opt.DefStn); + WEATHERINFO winfo = m_proto->LoadWeatherInfo(m_proto->opt.DefStn); wchar_t buf[2] = { var.c, 0 }, str[4096]; GetDisplay(&winfo, buf, str); MessageBox(nullptr, str, TranslateT("Weather Protocol Text Preview"), MB_OK | MB_TOPMOST); @@ -459,14 +459,15 @@ int CWeatherProto::OptInit(WPARAM wParam, LPARAM) // plugin options odp.pDialog = new COptionsDlg(this); - odp.szTab.a = LPGEN("General"); + odp.szTab.w = LPGENW("General"); g_plugin.addOptions(wParam, &odp); // text options odp.pDialog = new COptionsTextDlg(this); - odp.szTab.a = LPGEN("Display"); + odp.szTab.w = LPGENW("Display"); g_plugin.addOptions(wParam, &odp); - InitPopupOptions(wParam); + if (m_bPopups) + InitPopupOptions(wParam); return 0; } diff --git a/protocols/Weather/src/weather_popup.cpp b/protocols/Weather/src/weather_popup.cpp index e9fa6bd427..567788c56e 100644 --- a/protocols/Weather/src/weather_popup.cpp +++ b/protocols/Weather/src/weather_popup.cpp @@ -34,7 +34,7 @@ static MCONTACT hPopupContact; int CWeatherProto::WPShowMessage(const wchar_t *lpzText, int kind) { - if (!g_plugin.bPopups) + if (!m_bPopups) return 0; if (kind == SM_WARNING) @@ -113,7 +113,7 @@ static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPA int CWeatherProto::WeatherPopup(MCONTACT hContact, bool bAlways) { // determine if the popup should display or not - if (g_plugin.bPopups && opt.UpdatePopup && (!opt.PopupOnChange || bAlways) && !g_plugin.getByte(hContact, "DPopUp")) { + if (m_bPopups && opt.UpdatePopup && (!opt.PopupOnChange || bAlways) && !getByte(hContact, "DPopUp")) { WEATHERINFO winfo = LoadWeatherInfo(hContact); // setup the popup @@ -281,7 +281,6 @@ public: DestroyMenu(hMenu); // other options - CheckDlgButton(m_hwnd, IDC_E, g_plugin.bPopups ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(m_hwnd, IDC_POP2, opt.AlertPopup ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(m_hwnd, IDC_POP1, opt.UpdatePopup ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(m_hwnd, IDC_CH, opt.PopupOnChange ? BST_CHECKED : BST_UNCHECKED); @@ -326,9 +325,9 @@ public: for (auto &it : controls) { GetDlgItemText(m_hwnd, it.id, textstr, _countof(textstr)); if (!mir_wstrcmpi(textstr, GetDefaultText(it.c))) - g_plugin.delSetting(it.setting); + m_proto->delSetting(it.setting); else - g_plugin.setWString(it.setting, textstr); + m_proto->setWString(it.setting, textstr); } // save the options, and update main menu diff --git a/protocols/Weather/src/weather_proto.cpp b/protocols/Weather/src/weather_proto.cpp index 235f62294e..98a011e099 100644 --- a/protocols/Weather/src/weather_proto.cpp +++ b/protocols/Weather/src/weather_proto.cpp @@ -20,23 +20,32 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. CWeatherProto::CWeatherProto(const char *protoName, const wchar_t *userName) : PROTO<CWeatherProto>(protoName, userName), m_impl(*this), - hUpdateMutex(CreateMutex(nullptr, FALSE, nullptr)) + m_bPopups(m_szModuleName, "UsePopup", true) { + m_hProtoIcon = g_plugin.getIconHandle(IDI_ICON); + + CreateProtoService(PS_GETAVATARINFO, &CWeatherProto::GetAvatarInfoSvc); + CreateProtoService(PS_GETADVANCEDSTATUSICON, &CWeatherProto::AdvancedStatusIconSvc); + HookProtoEvent(ME_OPT_INITIALISE, &CWeatherProto::OptInit); HookProtoEvent(ME_CLIST_DOUBLECLICKED, &CWeatherProto::BriefInfoEvt); HookProtoEvent(ME_CLIST_PREBUILDCONTACTMENU, &CWeatherProto::BuildContactMenu); InitMwin(); - // reset the weather data at startup for individual contacts - EraseAllInfo(); - // load options and set defaults LoadOptions(); + // reset the weather data at startup for individual contacts + EraseAllInfo(); + // menu items InitMenuItems(); + // popup initialization + CMStringW wszTitle(FORMAT, L"%s %s", m_tszUserName, TranslateT("notifications")); + g_plugin.addPopupOption(wszTitle, m_bPopups); + // netlib NETLIBUSER nlu = {}; nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_UNICODE; @@ -49,8 +58,6 @@ CWeatherProto::~CWeatherProto() { DestroyMwin(); DestroyUpdateList(); - - CloseHandle(hUpdateMutex); } void CWeatherProto::OnModulesLoaded() @@ -60,6 +67,23 @@ void CWeatherProto::OnModulesLoaded() // weather user detail HookProtoEvent(ME_USERINFO_INITIALISE, &CWeatherProto::UserInfoInit); + HookProtoEvent(ME_TTB_MODULELOADED, &CWeatherProto::OnToolbarLoaded); +} + +int CWeatherProto::OnToolbarLoaded(WPARAM, LPARAM) +{ + CMStringA szName(FORMAT, "%s/Enabled", m_szModuleName); + + TTBButton ttb = {}; + ttb.name = LPGEN("Enable/disable auto update"); + ttb.pszService = szName.GetBuffer(); + ttb.pszTooltipUp = LPGEN("Auto Update Enabled"); + ttb.pszTooltipDn = LPGEN("Auto Update Disabled"); + ttb.hIconHandleUp = g_plugin.getIconHandle(IDI_ICON); + ttb.hIconHandleDn = g_plugin.getIconHandle(IDI_DISABLED); + ttb.dwFlags = (getByte("AutoUpdate", 1) ? 0 : TTBBF_PUSHED) | TTBBF_ASPUSHBUTTON | TTBBF_VISIBLE; + hTBButton = g_plugin.addTTB(&ttb); + return 0; } void CWeatherProto::OnShutdown() @@ -67,10 +91,6 @@ void CWeatherProto::OnShutdown() m_impl.m_update.Stop(); SaveOptions(); // save options once more - - WindowList_Broadcast(hWindowList, WM_CLOSE, 0, 0); - WindowList_Broadcast(hDataWindowList, WM_CLOSE, 0, 0); - SendMessage(hWndSetup, WM_CLOSE, 0, 0); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -114,3 +134,37 @@ INT_PTR CWeatherProto::GetCaps(int type, MCONTACT) } return 0; } + +///////////////////////////////////////////////////////////////////////////////////////// +// nothing to do here because weather proto do not need to retrieve contact info form network +// so just return a 0 + +void CWeatherProto::AckThreadProc(void *param) +{ + Sleep(100); + + ProtoBroadcastAck((DWORD_PTR)param, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)1); +} + +int CWeatherProto::GetInfo(MCONTACT hContact, int) +{ + ForkThread(&CWeatherProto::AckThreadProc, (void *)hContact); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void __cdecl CWeatherProto::GetAwayMsgThread(void *arg) +{ + Sleep(100); + + MCONTACT hContact = (DWORD_PTR)arg; + ptrW wszStatus(db_get_wsa(hContact, "CList", "StatusMsg")); + ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, this, wszStatus); +} + +HANDLE CWeatherProto::GetAwayMsg(MCONTACT hContact) +{ + ForkThread(&CWeatherProto::GetAwayMsgThread, (void*)hContact); + return this; +} diff --git a/protocols/Weather/src/weather_svcs.cpp b/protocols/Weather/src/weather_svcs.cpp index 9c87328209..3fa8593138 100644 --- a/protocols/Weather/src/weather_svcs.cpp +++ b/protocols/Weather/src/weather_svcs.cpp @@ -30,29 +30,6 @@ static HGENMENU hEnableDisableMenu; extern VARSW g_pwszIconsName; -//============ MIRANDA PROTOCOL SERVICES ============ - -// protocol service function to get the icon of the protocol -INT_PTR WeatherLoadIcon(WPARAM wParam, LPARAM) -{ - return (LOWORD(wParam) == PLI_PROTOCOL) ? (INT_PTR)CopyIcon(g_plugin.getIcon(IDI_ICON)) : 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 @@ -76,7 +53,7 @@ static statusIcons[MAX_COND] = { L"Light", 130, ID_STATUS_INVISIBLE }, }; -INT_PTR WeatherGetAvatarInfo(WPARAM, LPARAM lParam) +INT_PTR CWeatherProto::GetAvatarInfoSvc(WPARAM, LPARAM lParam) { wchar_t szSearchPath[MAX_PATH]; GetModuleFileName(GetModuleHandle(nullptr), szSearchPath, _countof(szSearchPath)); @@ -88,7 +65,7 @@ INT_PTR WeatherGetAvatarInfo(WPARAM, LPARAM lParam) szSearchPath[0] = 0; PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam; - int iCond = g_plugin.getWord(pai->hContact, "StatusIcon", -1); + int iCond = getWord(pai->hContact, "StatusIcon", -1); if (iCond < 0 || iCond >= MAX_COND) return GAIR_NOAVATAR; @@ -107,34 +84,15 @@ INT_PTR WeatherGetAvatarInfo(WPARAM, LPARAM lParam) return GAIR_NOAVATAR; } -void AvatarDownloaded(MCONTACT hContact) +void CWeatherProto::AvatarDownloaded(MCONTACT hContact) { PROTO_AVATAR_INFORMATION ai = {}; ai.hContact = hContact; - if (WeatherGetAvatarInfo(GAIF_FORCE, (LPARAM)&ai) == GAIR_SUCCESS) - ProtoBroadcastAck(MODULENAME, hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai); + if (GetAvatarInfoSvc(GAIF_FORCE, (LPARAM)&ai) == GAIR_SUCCESS) + ProtoBroadcastAck(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; - ptrW wszStatus(db_get_wsa(hContact, "CList", "StatusMsg")); - ProtoBroadcastAck(MODULENAME, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, wszStatus); -} - -static INT_PTR WeatherGetAwayMsg(WPARAM, LPARAM lParam) -{ - CCSDATA* ccs = (CCSDATA*)lParam; - if (ccs == nullptr) - return 0; - - mir_forkthread(WeatherGetAwayMsgThread, (void*)ccs->hContact); - return 1; + ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -146,18 +104,18 @@ void ClearStatusIcons() it.clistIconId = 0; } -int MapCondToStatus(MCONTACT hContact) +int CWeatherProto::MapCondToStatus(MCONTACT hContact) { - int iCond = g_plugin.getWord(hContact, "StatusIcon", -1); + int iCond = getWord(hContact, "StatusIcon", -1); if (iCond < 0 || iCond >= MAX_COND) return ID_STATUS_OFFLINE; return statusIcons[iCond].status; } -HICON GetStatusIcon(MCONTACT hContact) +HICON CWeatherProto::GetStatusIcon(MCONTACT hContact) { - int iCond = g_plugin.getWord(hContact, "StatusIcon", -1); + int iCond = getWord(hContact, "StatusIcon", -1); if (iCond < 0 || iCond >= MAX_COND) return nullptr; @@ -168,9 +126,9 @@ HICON GetStatusIcon(MCONTACT hContact) return ImageList_GetIcon(Clist_GetImageList(), pIcon.clistIconId, ILD_NORMAL); } -HICON GetStatusIconBig(MCONTACT hContact) +HICON CWeatherProto::GetStatusIconBig(MCONTACT hContact) { - int iCond = g_plugin.getWord(hContact, "StatusIcon", -1); + int iCond = getWord(hContact, "StatusIcon", -1); if (iCond < 0 || iCond >= MAX_COND) return nullptr; @@ -180,12 +138,12 @@ HICON GetStatusIconBig(MCONTACT hContact) return hIcon; } -static INT_PTR WeatherAdvancedStatusIcon(WPARAM hContact, LPARAM) +INT_PTR CWeatherProto::AdvancedStatusIconSvc(WPARAM hContact, LPARAM) { if (!hContact || !g_plugin.hIconsDll) return -1; - int iCond = g_plugin.getWord(hContact, "StatusIcon", -1); + int iCond = getWord(hContact, "StatusIcon", -1); if (iCond < 0 || iCond >= MAX_COND) return -1; @@ -196,20 +154,8 @@ static INT_PTR WeatherAdvancedStatusIcon(WPARAM hContact, LPARAM) return MAKELONG(0, pIcon.clistIconId); } -//============ PROTOCOL INITIALIZATION ============ -// protocol services -void InitServices(void) -{ - CreateProtoServiceFunction(MODULENAME, PS_LOADICON, WeatherLoadIcon); - CreateProtoServiceFunction(MODULENAME, PS_GETINFO, WeatherGetInfo); - CreateProtoServiceFunction(MODULENAME, PS_GETAVATARINFO, WeatherGetAvatarInfo); - CreateProtoServiceFunction(MODULENAME, PS_GETAWAYMSG, WeatherGetAwayMsg); - CreateProtoServiceFunction(MODULENAME, PS_GETADVANCEDSTATUSICON, WeatherAdvancedStatusIcon); - - CreateProtoServiceFunction(MODULENAME, MS_WEATHER_GETDISPLAY, GetDisplaySvcFunc); -} - -//============ MENU INITIALIZATION ============ +///////////////////////////////////////////////////////////////////////////////////////// +// menus void CWeatherProto::UpdateMenu(BOOL State) { @@ -229,15 +175,18 @@ void CWeatherProto::UpdateMenu(BOOL State) CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)hTBButton, !State ? TTBST_PUSHED : 0); } +///////////////////////////////////////////////////////////////////////////////////////// // update the weather auto-update menu item when click on it + INT_PTR CWeatherProto::EnableDisableCmd(WPARAM wParam, LPARAM lParam) { UpdateMenu(wParam == TRUE ? (BOOL)lParam : !opt.CAutoUpdate); return 0; } +///////////////////////////////////////////////////////////////////////////////////////// // adding weather contact menus -// copied and modified form "modified MSN Protocol" + void CWeatherProto::InitMenuItems() { CMenuItem mi(&g_plugin); @@ -304,34 +253,34 @@ void CWeatherProto::InitMenuItems() 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); - CreateProtoService(MS_WEATHER_ENABLED, &CWeatherProto::EnableDisableCmd); mi.name.a = LPGEN("Enable/Disable Weather Update"); mi.hIcolibItem = g_plugin.getIconHandle(IDI_ICON); mi.position = 10100001; - mi.pszService = MS_WEATHER_ENABLED; + mi.pszService = "/EnableDisable"; hEnableDisableMenu = Menu_AddMainMenuItem(&mi); UpdateMenu(opt.AutoUpdate); + CreateProtoService(mi.pszService, &CWeatherProto::EnableDisableCmd); SET_UID(mi, 0x2b1c2054, 0x2991, 0x4025, 0x87, 0x73, 0xb6, 0xf7, 0x85, 0xac, 0xc7, 0x37); - CreateProtoService(MS_WEATHER_UPDATEALL, &CWeatherProto::UpdateAllInfo); mi.position = 20100001; mi.hIcolibItem = g_plugin.getIconHandle(IDI_UPDATE); mi.name.a = LPGEN("Update All Weather"); - mi.pszService = MS_WEATHER_UPDATEALL; + mi.pszService = "/UpdateAll"; Menu_AddMainMenuItem(&mi); + CreateProtoService(mi.pszService, &CWeatherProto::UpdateAllInfo); SET_UID(mi, 0x8234c00e, 0x788e, 0x424f, 0xbc, 0xc4, 0x2, 0xfd, 0x67, 0x58, 0x2d, 0x19); - CreateProtoService(MS_WEATHER_REFRESHALL, &CWeatherProto::UpdateAllRemove); mi.position = 20100002; mi.hIcolibItem = g_plugin.getIconHandle(IDI_UPDATE2); mi.name.a = LPGEN("Remove Old Data then Update All"); - mi.pszService = MS_WEATHER_REFRESHALL; + mi.pszService = "/RefreshAll"; Menu_AddMainMenuItem(&mi); + CreateProtoService(mi.pszService, &CWeatherProto::UpdateAllRemove); 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.pszService = "/mwin_menu"; + CreateProtoService(mi.pszService, &CWeatherProto::Mwin_MenuClicked); mi.position = -0x7FFFFFF0; mi.hIcolibItem = nullptr; mi.root = nullptr; diff --git a/protocols/Weather/src/weather_update.cpp b/protocols/Weather/src/weather_update.cpp index 54bf94c994..75f73a2039 100644 --- a/protocols/Weather/src/weather_update.cpp +++ b/protocols/Weather/src/weather_update.cpp @@ -26,8 +26,6 @@ menu items). #include "stdafx.h" -UPDATELIST *UpdateListHead = nullptr, *UpdateListTail = nullptr; - //============ RETRIEVE NEW WEATHER ============ // retrieve weather info and display / log them // hContact = current contact @@ -45,7 +43,7 @@ int CWeatherProto::UpdateWeather(MCONTACT hContact) // log to netlib log for debug purpose Netlib_LogfW(m_hNetlibUser, L"************************************************************************"); - int dbres = g_plugin.getWString(hContact, "Nick", &dbv); + int dbres = getWString(hContact, "Nick", &dbv); Netlib_LogfW(m_hNetlibUser, L"<-- Start update for station -->"); @@ -80,19 +78,19 @@ int CWeatherProto::UpdateWeather(MCONTACT hContact) // compare the old condition and determine if the weather had changed if (opt.UpdateOnlyConditionChanged) { // consider condition change - if (!g_plugin.getWString(hContact, "LastCondition", &dbv)) { + if (!getWString(hContact, "LastCondition", &dbv)) { if (mir_wstrcmpi(winfo.cond, dbv.pwszVal)) Ch = TRUE; // the weather condition is changed db_free(&dbv); } else Ch = TRUE; - if (!g_plugin.getWString(hContact, "LastTemperature", &dbv)) { + if (!getWString(hContact, "LastTemperature", &dbv)) { if (mir_wstrcmpi(winfo.temp, dbv.pwszVal)) Ch = TRUE; // the temperature is changed db_free(&dbv); } else Ch = TRUE; } else { // consider update time change - if (!g_plugin.getWString(hContact, "LastUpdate", &dbv)) { + if (!getWString(hContact, "LastUpdate", &dbv)) { if (mir_wstrcmpi(winfo.update, dbv.pwszVal)) Ch = TRUE; // the update time is changed db_free(&dbv); } @@ -102,32 +100,32 @@ int CWeatherProto::UpdateWeather(MCONTACT hContact) // have weather alert issued? dbres = db_get_ws(hContact, WEATHERCONDITION, "Alert", &dbv); if (!dbres && dbv.pwszVal[0] != 0) { - if (opt.AlertPopup && !g_plugin.getByte(hContact, "DPopUp") && Ch) { + if (opt.AlertPopup && !getByte(hContact, "DPopUp") && Ch) { // display alert popup CMStringW str(FORMAT, L"Alert for %s%c%s", winfo.city, 255, dbv.pwszVal); WPShowMessage(str, SM_WEATHERALERT); } // alert issued, set display to italic if (opt.MakeItalic) - g_plugin.setWord(hContact, "ApparentMode", ID_STATUS_OFFLINE); + setWord(hContact, "ApparentMode", ID_STATUS_OFFLINE); Skin_PlaySound("weatheralert"); } // alert dropped, set the display back to normal - else g_plugin.delSetting(hContact, "ApparentMode"); + else delSetting(hContact, "ApparentMode"); if (!dbres) db_free(&dbv); // backup current condition for checking if the weather is changed or not - g_plugin.setWString(hContact, "LastLog", winfo.update); - g_plugin.setWString(hContact, "LastCondition", winfo.cond); - g_plugin.setWString(hContact, "LastTemperature", winfo.temp); - g_plugin.setWString(hContact, "LastUpdate", winfo.update); + setWString(hContact, "LastLog", winfo.update); + setWString(hContact, "LastCondition", winfo.cond); + setWString(hContact, "LastTemperature", winfo.temp); + setWString(hContact, "LastUpdate", winfo.update); // display condition on contact list int iStatus = MapCondToStatus(winfo.hContact); if (opt.DisCondIcon && iStatus != ID_STATUS_OFFLINE) - g_plugin.setWord(hContact, "Status", ID_STATUS_ONLINE); + setWord(hContact, "Status", ID_STATUS_ONLINE); else - g_plugin.setWord(hContact, "Status", iStatus); + setWord(hContact, "Status", iStatus); AvatarDownloaded(hContact); GetDisplay(&winfo, GetTextValue('C'), str2); @@ -148,7 +146,7 @@ int CWeatherProto::UpdateWeather(MCONTACT hContact) db_set_ws(hContact, WEATHERCONDITION, "WeatherInfo", str2); // set the update tag - g_plugin.setByte(hContact, "IsUpdated", TRUE); + setByte(hContact, "IsUpdated", TRUE); // save current condition for default station to be displayed after the update int old_status = m_iStatus; @@ -164,11 +162,11 @@ int CWeatherProto::UpdateWeather(MCONTACT hContact) // play the sound event Skin_PlaySound("weatherupdated"); - if (g_plugin.getByte(hContact, "File")) { + if (getByte(hContact, "File")) { // external log - if (!g_plugin.getWString(hContact, "Log", &dbv)) { + if (!getWString(hContact, "Log", &dbv)) { // for the option for overwriting the file, delete old file first - if (g_plugin.getByte(hContact, "Overwrite")) + if (getByte(hContact, "Overwrite")) DeleteFile(dbv.pwszVal); // open the file and set point to the end of file @@ -183,14 +181,14 @@ int CWeatherProto::UpdateWeather(MCONTACT hContact) } } - if (g_plugin.getByte(hContact, "History")) { + if (getByte(hContact, "History")) { // internal log using history GetDisplay(&winfo, GetTextValue('H'), str2); T2Utf szMessage(str2); DBEVENTINFO dbei = {}; - dbei.szModule = MODULENAME; + dbei.szModule = m_szModuleName; dbei.iTimestamp = (uint32_t)time(0); dbei.flags = DBEF_READ | DBEF_UTF; dbei.eventType = EVENTTYPE_MESSAGE; @@ -227,42 +225,37 @@ void CWeatherProto::UpdateListAdd(MCONTACT hContact) newItem->hContact = hContact; newItem->next = nullptr; - WaitForSingleObject(hUpdateMutex, INFINITE); - - if (UpdateListTail == nullptr) UpdateListHead = newItem; - else UpdateListTail->next = newItem; + mir_cslock lck(m_csUpdate); + if (UpdateListTail == nullptr) + UpdateListHead = newItem; + else + UpdateListTail->next = newItem; UpdateListTail = newItem; - - ReleaseMutex(hUpdateMutex); } // get the first item from the update queue and remove it from the queue // return value = the contact for next update MCONTACT CWeatherProto::UpdateGetFirst() { - MCONTACT hContact = NULL; - - WaitForSingleObject(hUpdateMutex, INFINITE); + mir_cslock lck(m_csUpdate); + if (UpdateListHead == nullptr) + return 0; - if (UpdateListHead != nullptr) { - UPDATELIST *Item = UpdateListHead; + UPDATELIST *Item = UpdateListHead; - hContact = Item->hContact; - UpdateListHead = Item->next; - mir_free(Item); + MCONTACT hContact = Item->hContact; + UpdateListHead = Item->next; + mir_free(Item); - if (UpdateListHead == nullptr) - UpdateListTail = nullptr; - } - - ReleaseMutex(hUpdateMutex); + if (UpdateListHead == nullptr) + UpdateListTail = nullptr; return hContact; } void CWeatherProto::DestroyUpdateList(void) { - WaitForSingleObject(hUpdateMutex, INFINITE); + mir_cslock lck(m_csUpdate); // free the list one by one UPDATELIST *temp = UpdateListHead; @@ -271,10 +264,9 @@ void CWeatherProto::DestroyUpdateList(void) mir_free(temp); temp = UpdateListHead; } + // make sure the entire list is clear UpdateListTail = nullptr; - - ReleaseMutex(hUpdateMutex); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -283,20 +275,19 @@ void CWeatherProto::DestroyUpdateList(void) void CWeatherProto::UpdateThread(void *) { - WaitForSingleObject(hUpdateMutex, INFINITE); - if (ThreadRunning) { - ReleaseMutex(hUpdateMutex); - return; + { mir_cslock lck(m_csUpdate); + if (m_bThreadRunning) + return; + + m_bThreadRunning = true; // prevent 2 instance of this thread running } - ThreadRunning = TRUE; // prevent 2 instance of this thread running - ReleaseMutex(hUpdateMutex); // update weather by getting the first station from the queue until the queue is empty while (UpdateListHead != nullptr && !Miranda_IsTerminated()) UpdateWeather(UpdateGetFirst()); // exit the update thread - ThreadRunning = FALSE; + m_bThreadRunning = false; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -308,7 +299,7 @@ void CWeatherProto::UpdateAll(BOOL AutoUpdate, BOOL RemoveData) { // add all weather contact to the update queue list for (auto &hContact : AccContacts()) - if (!g_plugin.getByte(hContact, "AutoUpdate") || !AutoUpdate) { + if (!getByte(hContact, "AutoUpdate") || !AutoUpdate) { if (RemoveData) DBDataManage(hContact, WDBM_REMOVE, 0, 0); UpdateListAdd(hContact); @@ -316,7 +307,7 @@ void CWeatherProto::UpdateAll(BOOL AutoUpdate, BOOL RemoveData) // if it is not updating, then start the update thread process // if it is updating, the stations just added to the queue will get updated by the already-running process - if (!ThreadRunning) + if (!m_bThreadRunning) ForkThread(&CWeatherProto::UpdateThread); } @@ -333,7 +324,7 @@ INT_PTR CWeatherProto::UpdateSingleStation(WPARAM wParam, LPARAM) // if it is not updating, then start the update thread process // if it is updating, the stations just added to the queue will get // updated by the already-running process - if (!ThreadRunning) + if (!m_bThreadRunning) ForkThread(&CWeatherProto::UpdateThread); } @@ -353,7 +344,7 @@ INT_PTR CWeatherProto::UpdateSingleRemove(WPARAM wParam, LPARAM) // if it is not updating, then start the update thread process // if it is updating, the stations just added to the queue will get updated by the already-running process - if (!ThreadRunning) + if (!m_bThreadRunning) ForkThread(&CWeatherProto::UpdateThread); } @@ -365,7 +356,7 @@ INT_PTR CWeatherProto::UpdateSingleRemove(WPARAM wParam, LPARAM) INT_PTR CWeatherProto::UpdateAllInfo(WPARAM, LPARAM) { - if (!ThreadRunning) + if (!m_bThreadRunning) UpdateAll(FALSE, FALSE); return 0; } @@ -375,7 +366,7 @@ INT_PTR CWeatherProto::UpdateAllInfo(WPARAM, LPARAM) INT_PTR CWeatherProto::UpdateAllRemove(WPARAM, LPARAM) { - if (!ThreadRunning) + if (!m_bThreadRunning) UpdateAll(FALSE, TRUE); return 0; } @@ -585,7 +576,7 @@ int CWeatherProto::GetWeatherData(MCONTACT hContact) } // assign condition icon - g_plugin.setWord(hContact, "StatusIcon", cond); + setWord(hContact, "StatusIcon", cond); return 0; } @@ -595,7 +586,7 @@ int CWeatherProto::GetWeatherData(MCONTACT hContact) void CWeatherProto::DoUpdate() { // only run if it is not current updating and the auto update option is enabled - if (!ThreadRunning && opt.CAutoUpdate && !Miranda_IsTerminated() && m_iStatus == ID_STATUS_ONLINE) + if (!m_bThreadRunning && opt.CAutoUpdate && !Miranda_IsTerminated() && m_iStatus == ID_STATUS_ONLINE) UpdateAll(TRUE, FALSE); } @@ -604,7 +595,7 @@ void CWeatherProto::DoUpdate() void CWeatherProto::StartUpdate() { - ThreadRunning = false; + m_bThreadRunning = false; if (!Miranda_IsTerminated()) m_impl.m_update.Start(opt.UpdateTime * 60000); diff --git a/protocols/Weather/src/weather_userinfo.cpp b/protocols/Weather/src/weather_userinfo.cpp index d8e06bbde9..f24f600874 100644 --- a/protocols/Weather/src/weather_userinfo.cpp +++ b/protocols/Weather/src/weather_userinfo.cpp @@ -144,9 +144,9 @@ public: wchar_t str[4096]; // load weather information from the contact into the WEATHERINFO struct - WEATHERINFO winfo = LoadWeatherInfo(hContact); + WEATHERINFO winfo = m_proto->LoadWeatherInfo(hContact); // check if data exist. If not, display error message box - if (!g_plugin.getByte(hContact, "IsUpdated")) + if (!m_proto->getByte(hContact, "IsUpdated")) SetDlgItemTextW(m_hwnd, IDC_MTEXT, TranslateT("No information available.\r\nPlease update weather condition first.")); else { // set the display text and show the message box @@ -161,7 +161,7 @@ public: DBDataManage(hContact, WDBM_DETAILDISPLAY, (WPARAM)m_hwnd, 0); // set icons - HICON hIcon = GetStatusIconBig(hContact); + HICON hIcon = m_proto->GetStatusIconBig(hContact); DestroyIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_BIG, LPARAM(hIcon))); DestroyIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_SMALL, LPARAM(hIcon))); @@ -239,6 +239,7 @@ int CWeatherProto::BriefInfoEvt(WPARAM wParam, LPARAM) class WeatherUserInfoDlg : public CUserInfoPageDlg { CCtrlButton btnDetail; + CWeatherProto *ppro; public: WeatherUserInfoDlg() : @@ -251,13 +252,14 @@ public: bool OnInitDialog() override { SendDlgItemMessage(m_hwnd, IDC_MOREDETAIL, BUTTONSETASFLATBTN, TRUE, 0); + ppro = (CWeatherProto *)Proto_GetContactInstance(m_hContact); // load weather info for the contact wchar_t str[MAX_TEXT_SIZE]; - WEATHERINFO w = LoadWeatherInfo(m_hContact); + WEATHERINFO w = ppro->LoadWeatherInfo(m_hContact); SetDlgItemText(m_hwnd, IDC_INFO1, GetDisplay(&w, TranslateT("Current condition for %n"), str)); - SendDlgItemMessage(m_hwnd, IDC_INFOICON, STM_SETICON, (WPARAM)GetStatusIconBig(m_hContact), 0); + SendDlgItemMessage(m_hwnd, IDC_INFOICON, STM_SETICON, (WPARAM)ppro->GetStatusIconBig(m_hContact), 0); // bold and enlarge the current condition LOGFONT lf; @@ -297,7 +299,6 @@ public: { HWND hMoreDataDlg = WindowList_Find(hDataWindowList, m_hContact); if (hMoreDataDlg == nullptr) { - auto *ppro = (CWeatherProto*)Proto_GetContactInstance(m_hContact); auto *pDlg = new CBriefInfoDlg(ppro, m_hContact); pDlg->Create(); hMoreDataDlg = pDlg->GetHwnd(); @@ -314,7 +315,7 @@ public: int CWeatherProto::UserInfoInit(WPARAM wParam, LPARAM hContact) { USERINFOPAGE uip = {}; - uip.szTitle.a = MODULENAME; + uip.szTitle.a = m_szModuleName; uip.position = 100000000; uip.flags = ODPF_ICON; uip.dwInitParam = LPARAM(g_plugin.getIconHandle(IDI_ICON)); |