From de83ac2ff7e90537efc0153adedf2f700b4e7880 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 25 Jun 2012 09:28:02 +0000 Subject: neweventnotify added - needs adaptation to the new API git-svn-id: http://svn.miranda-ng.org/main/trunk@629 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/NewEventNotify/!changelog.txt | 27 + plugins/NewEventNotify/main.c | 322 +++++++++ plugins/NewEventNotify/menuitem.c | 80 +++ plugins/NewEventNotify/neweventnotify.h | 244 +++++++ plugins/NewEventNotify/neweventnotify.sln | 26 + plugins/NewEventNotify/neweventnotify.vcxproj | 262 +++++++ .../NewEventNotify/neweventnotify.vcxproj.filters | 55 ++ plugins/NewEventNotify/options.c | 341 ++++++++++ plugins/NewEventNotify/popup.c | 752 +++++++++++++++++++++ plugins/NewEventNotify/res/popup.ico | Bin 0 -> 894 bytes plugins/NewEventNotify/res/popup_no.ico | Bin 0 -> 894 bytes plugins/NewEventNotify/resource.h | 75 ++ plugins/NewEventNotify/resource.rc | 198 ++++++ plugins/NewEventNotify/utils.c | 543 +++++++++++++++ 14 files changed, 2925 insertions(+) create mode 100644 plugins/NewEventNotify/!changelog.txt create mode 100644 plugins/NewEventNotify/main.c create mode 100644 plugins/NewEventNotify/menuitem.c create mode 100644 plugins/NewEventNotify/neweventnotify.h create mode 100644 plugins/NewEventNotify/neweventnotify.sln create mode 100644 plugins/NewEventNotify/neweventnotify.vcxproj create mode 100644 plugins/NewEventNotify/neweventnotify.vcxproj.filters create mode 100644 plugins/NewEventNotify/options.c create mode 100644 plugins/NewEventNotify/popup.c create mode 100644 plugins/NewEventNotify/res/popup.ico create mode 100644 plugins/NewEventNotify/res/popup_no.ico create mode 100644 plugins/NewEventNotify/resource.h create mode 100644 plugins/NewEventNotify/resource.rc create mode 100644 plugins/NewEventNotify/utils.c (limited to 'plugins/NewEventNotify') diff --git a/plugins/NewEventNotify/!changelog.txt b/plugins/NewEventNotify/!changelog.txt new file mode 100644 index 0000000000..5c755ee40c --- /dev/null +++ b/plugins/NewEventNotify/!changelog.txt @@ -0,0 +1,27 @@ +0.2.2.4 +- support for unicode file events + +0.2.2.3 +- fixed possible crash during processing of custom events without preview + +0.2.2.2 +- fixed possible crash when processing system history events + +0.2.2.1 +- fixed possible crash with older Miranda IM + +0.2.2.0 +- minor fixes for popup merging +- improved popup for contacts event +- added support for custom database events (e.g. no more "Unknown event" for Jabber presence events) + +0.2.1.0 +- support for Message Dialog API +- fixed Auth events preview +- several other fixes & improvements + +0.2.0.0 +- support for new UTF-8 format of messages +- full Unicode support (2in1) +- new Miranda plug-in API +- some other fixes & tweaks diff --git a/plugins/NewEventNotify/main.c b/plugins/NewEventNotify/main.c new file mode 100644 index 0000000000..c35a7907c1 --- /dev/null +++ b/plugins/NewEventNotify/main.c @@ -0,0 +1,322 @@ +/* + Name: NewEventNotify - Plugin for Miranda IM + File: main.c - Main DLL procedures + Version: 0.2.2.2 + Description: Notifies you about some events + Author: jokusoftware, + Date: 18.07.02 13:59 / Update: 22.10.07 19:56 + Copyright: (C) 2002 Starzinger Michael + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "neweventnotify.h" +#include +#include +#include +#include +//needed for ICQEVENTTYPE_* (Webpager & Emailexpress) +#include +//needed for reply instead of read +#include +#include +#include + +#include + +#include +#include + +int g_IsSrmmServiceAvail = 0; +int g_IsSrmmWindowAPI = 0; +int g_UnicodeCore = 0; + +extern PLUGIN_DATA* PopUpList[20]; + +//--------------------------- +//---Some global variables for the plugin + +struct MM_INTERFACE mmi; + +HINSTANCE hInst; +PLUGIN_OPTIONS pluginOptions; +PLUGINLINK *pluginLink; +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + "NewEventNotify", + PLUGIN_MAKE_VERSION(0, VER_MAJOR, VER_MINOR, VER_BUILD), + "Notifies you when you receive a message, url, file or any other event by displaying a popup. Uses the PopUp-Plugin by hrk. " + "Original plugin was written by icebreaker, modified by Prezes and some " + "bugfixes were made by vj, vlko, Nightwish, TheLeech and others. More fixes & updates by Joe @ Whale", + "icebreaker, Prezes, vj, vlko, Joe @ Whale", + "jokusoftware@miranda-im.org", + "GNU GPL", + "http://addons.miranda-im.org/details.php?action=viewfile&id=3637", + 0, + 0, + {0x3503D584, 0x6234, 0x4BEF, {0xA5, 0x53, 0x6C, 0x1B, 0x9C, 0xD4, 0x71, 0xF2 } } // {3503D584-6234-4BEF-A553-6C1B9CD471F2} +}; + +//--------------------------- +//---Hooks + +//---Handles to my hooks, needed to unhook them again +HANDLE hHookedInit; +HANDLE hHookedOpt; +HANDLE hHookedNewEvent; +HANDLE hHookedDeletedEvent; + +//---Called when a new event is added to the database +int HookedNewEvent(WPARAM wParam, LPARAM lParam) +//wParam: contact-handle +//lParam: dbevent-handle +{ + HANDLE hContact = (HANDLE)wParam; + DBEVENTINFO dbe = {0}; + PLUGIN_DATA* pdata; + DBEVENTTYPEDESCR* pei; + + //are popups currently enabled? + if (pluginOptions.bDisable) + return 0; + + //get DBEVENTINFO without pBlob + dbe.cbSize = sizeof(dbe); + CallService(MS_DB_EVENT_GET, (WPARAM)lParam, (LPARAM)&dbe); + + // Nightwish (no popups for RSS contacts at all...) + if (pluginOptions.bNoRSS) + { + if (dbe.szModule != NULL) { + if (!strncmp(dbe.szModule, "RSS", 3)) + return 0; + } + } + + //do not show popups for sub-contacts + if (hContact && ServiceExists(MS_MC_GETMETACONTACT) && CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, 0)) + return 0; + + //is it an event info about online/offline status user + if (dbe.eventType == 25368) + return 0; + + //custom database event types + if (ServiceExists(MS_DB_EVENT_GETTYPE)) + { + pei = (DBEVENTTYPEDESCR*)CallService(MS_DB_EVENT_GETTYPE, (WPARAM)dbe.szModule, (LPARAM)dbe.eventType); + if (pei && pei->cbSize >= DBEVENTTYPEDESCR_SIZE) + { // ignore events according to flags + if (pei->flags & DETF_NONOTIFY) + return 0; + } + } + + //if event was allready read don't show it + if (pluginOptions.bReadCheck && (dbe.flags & DBEF_READ)) + return 0; + + //is it an event sent by the user? -> don't show + if (dbe.flags & DBEF_SENT) + { + if (pluginOptions.bHideSend && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1) + { // JK, only message event, do not influence others + pdata = PopUpList[NumberPopupData(hContact, EVENTTYPE_MESSAGE)]; + PopupAct(pdata->hWnd, MASK_DISMISS, pdata); // JK, only dismiss, i.e. do not kill event (e.g. file transfer) + } + return 0; + } + //which status do we have, are we allowed to post popups? + //UNDER CONSTRUCTION!!! + CallService(MS_CLIST_GETSTATUSMODE, 0, 0); /// TODO: JK: ???? + + if (dbe.eventType == EVENTTYPE_MESSAGE && (pluginOptions.bMsgWindowCheck && hContact && CheckMsgWnd(hContact))) + return 0; + + //is another popup for this contact already present? -> merge message popups if enabled + if (dbe.eventType == EVENTTYPE_MESSAGE && (pluginOptions.bMergePopup && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1)) + { // JK, only merge with message events, do not mess with others + PopupUpdate(hContact, (HANDLE)lParam); + } + else + { //now finally show a popup + PopupShow(&pluginOptions, hContact, (HANDLE)lParam, (UINT)dbe.eventType); + } + return 0; +} + +//---Called when all the modules are loaded +int HookedInit(WPARAM wParam, LPARAM lParam) +{ + hHookedNewEvent = HookEvent(ME_DB_EVENT_ADDED, HookedNewEvent); + // Plugin sweeper support + if (ServiceExists("PluginSweeper/Add")) + CallService("PluginSweeper/Add", (WPARAM)MODULE, (LPARAM)MODULE); + + if (ServiceExists(MS_MSG_GETWINDOWDATA)) + g_IsSrmmWindowAPI = 1; + else + g_IsSrmmWindowAPI = 0; + + if (ServiceExists(MS_MSG_MOD_MESSAGEDIALOGOPENED)) + g_IsSrmmServiceAvail = 1; + else + g_IsSrmmServiceAvail = 0; + + return 0; +} + +//---Called when an options dialog has to be created +int HookedOptions(WPARAM wParam, LPARAM lParam) +{ + OptionsAdd(hInst, wParam); + + return 0; +} + +//--------------------------- +//---Exported Functions + +PLUGININFOEX* handleMirandaPluginInfo(DWORD mirandaVersion) +{ + if (mirandaVersion >= PLUGIN_MAKE_VERSION(0, 3, 3, 0)) + { // Are we running under Unicode Windows version ? + if ((GetVersion() & 0x80000000) == 0) + { + pluginInfo.flags = 1; // UNICODE_AWARE + } + return &pluginInfo; + } + else + return NULL; +} + +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + pluginInfo.cbSize = sizeof(PLUGININFOEX); + + return handleMirandaPluginInfo(mirandaVersion); +} + +static const MUUID interfaces[] = {MIID_EVENTNOTIFY, MIID_LAST}; +__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink = link; + hHookedInit = HookEvent(ME_SYSTEM_MODULESLOADED, HookedInit); + hHookedOpt = HookEvent(ME_OPT_INITIALISE, HookedOptions); + + mir_getMMI(&mmi); + + InitI18N(); + + { // Are we running under unicode Miranda core ? + char szVer[MAX_PATH]; + + CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer); + _strlwr(szVer); // make sure it is lowercase + g_UnicodeCore = (strstr(szVer, "unicode") != NULL); + } + + OptionsInit(&pluginOptions); + pluginOptions.hInst = hInst; + + if (pluginOptions.bMenuitem) + MenuitemInit(!pluginOptions.bDisable); + + return 0; +} + +int __declspec(dllexport) Unload(void) +{ + UnhookEvent(hHookedNewEvent); + UnhookEvent(hHookedOpt); + UnhookEvent(hHookedInit); + return 0; +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + hInst=hinstDLL; + return TRUE; +} + +//------------------------------------- +//---Check Window Message function + +// Took this snippet of code from "EventNotify" by micron-x, thx *g* +// checks if the message-dialog window is already opened +// return values: +// 0 - No window found +// 1 - Split-mode window found +// 2 - Single-mode window found + +int CheckMsgWnd(HANDLE hContact) +{ + if (g_IsSrmmWindowAPI) { + MessageWindowData mwd; + MessageWindowInputData mwid; + mwid.cbSize = sizeof(MessageWindowInputData); + mwid.hContact = hContact; + mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; + mwd.cbSize = sizeof(MessageWindowData); + mwd.hContact = hContact; + if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM) &mwid, (LPARAM) &mwd)) { + if (mwd.hwndWindow != NULL && (mwd.uState & MSG_WINDOW_STATE_EXISTS)) return 1; + } + } + if (g_IsSrmmServiceAvail) { // use the service provided by tabSRMM + if (CallService(MS_MSG_MOD_MESSAGEDIALOGOPENED, (WPARAM)hContact, 0)) + return 1; + else + return 0; + } + else + { // old way: find it by using the window class & title + char newtitle[256]; + char *szProto,*szStatus,*contactName; + + szProto= (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact,0); + contactName= (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact,0); + szStatus= (char*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, szProto?DBGetContactSettingWord(hContact,szProto,"Status",ID_STATUS_OFFLINE):ID_STATUS_OFFLINE,0); + + // vj: This code was added by preeze and it does not work: + // vlko: it maybe work with other plugins + _snprintf(newtitle,sizeof(newtitle),"%s (%s)",contactName,szStatus); + if(FindWindow("TMsgWindow",newtitle)) + return 2; + + _snprintf(newtitle,sizeof(newtitle),"[%s (%s)]",contactName,szStatus); + if(FindWindow("TfrmContainer",newtitle)) + return 1; + + // vj: I have restored this code from original plugin's source: (NewEventNotify 0.0.4) + _snprintf(newtitle,sizeof(newtitle),"%s (%s): %s",contactName,szStatus,Translate("Message Session")); + if(FindWindow("#32770",newtitle)) // JK, this works for old SRMMs (1.0.4.x) and for mine SRMMJ + return 1; + + _snprintf(newtitle,sizeof(newtitle),"%s (%s): %s",contactName,szStatus,Translate("Message Received")); + if(FindWindow("#32770",newtitle)) + return 2; + + return 0; + } +} + + diff --git a/plugins/NewEventNotify/menuitem.c b/plugins/NewEventNotify/menuitem.c new file mode 100644 index 0000000000..e0839e6dea --- /dev/null +++ b/plugins/NewEventNotify/menuitem.c @@ -0,0 +1,80 @@ +/* + Name: NewEventNotify - Plugin for Miranda IM + File: menuitem.c - Manages item(s) in the Miranda Menu + Version: 0.0.4 + Description: Notifies you about some events + Author: icebreaker, + Date: 22.07.02 19:56 / Update: 24.07.02 01:39 + Copyright: (C) 2002 Starzinger Michael + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "neweventnotify.h" +#include + + +CLISTMENUITEM menuitem; +HANDLE hMenuitemNotify; +BOOL bNotify; + +static int MenuitemNotifyCmd(WPARAM wParam,LPARAM lParam) +{ + bNotify = !bNotify; + MenuitemUpdate(bNotify); + + //write changes to options->bDisable and into database + Opt_DisableNEN(!bNotify); + + return 0; +} + +int MenuitemUpdate(BOOL bStatus) +{ + WCHAR tmp[MAX_PATH]; + + //menuitem.flags = CMIM_FLAGS | (bStatus ? CMIF_CHECKED : 0); + menuitem.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(bStatus ? IDI_ENABLED : IDI_DISABLED)); + menuitem.ptszName = NENTranslateT(bStatus ? MENUITEM_DISABLE : MENUITEM_ENABLE, tmp); + menuitem.flags = CMIM_ICON | CMIM_NAME | CMIF_KEEPUNTRANSLATED; + if (g_UnicodeCore) + menuitem.flags |= CMIF_UNICODE; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuitemNotify, (LPARAM)&menuitem); + + return 0; +} + +int MenuitemInit(BOOL bStatus) +{ + WCHAR tmp[MAX_PATH]; + + CreateServiceFunction(MS_NEN_MENUNOTIFY, MenuitemNotifyCmd); + + ZeroMemory(&menuitem, sizeof(menuitem)); + menuitem.cbSize = sizeof(CLISTMENUITEM); + menuitem.position = 1; + menuitem.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ENABLED)); + menuitem.ptszPopupName = NENTranslateT("PopUps", tmp); + menuitem.pszService = MS_NEN_MENUNOTIFY; + menuitem.flags = CMIF_KEEPUNTRANSLATED; + if (g_UnicodeCore) + menuitem.flags |= CMIF_UNICODE; + hMenuitemNotify = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&menuitem); + + bNotify = bStatus; + MenuitemUpdate(bNotify); + + return 0; +} diff --git a/plugins/NewEventNotify/neweventnotify.h b/plugins/NewEventNotify/neweventnotify.h new file mode 100644 index 0000000000..cf1fed29c0 --- /dev/null +++ b/plugins/NewEventNotify/neweventnotify.h @@ -0,0 +1,244 @@ +/* + Name: NewEventNotify - Plugin for Miranda IM + File: neweventnotify.h - Main Header File + Version: 0.2.2.2 + Description: Notifies you about some events + Author: icebreaker, + Date: 18.07.02 13:59 / Update: 16.09.02 17:45 + Copyright: (C) 2002 Starzinger Michael + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//--------------------------- +//---Includes +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NONSTDC_NO_DEPRECATE + +#include +#include +#include +#include "resource.h" +#include +#include +#include +#include +#include + +//VERY_PUBLIC Begin ... will be moved to m_neweventnotify.h +#define MS_NEN_MENUNOTIFY "NewEventNotify/MenuitemNotifyCommand" +//VERY_PUBLIC End + +#define MS_MSG_MOD_MESSAGEDIALOGOPENED "SRMsg_MOD/MessageDialogOpened" + +//--------------------------- +//---Definitions + +#define MODULE "NewEventNotify" +#define VER_MAJOR 2 +#define VER_MINOR 2 +#define VER_BUILD 3 +#define MAX_POPUPS 20 + +#define DEFAULT_COLBACK RGB(255,255,128) +#define DEFAULT_COLTEXT RGB(0,0,0) +#define DEFAULT_MASKNOTIFY (MASK_MESSAGE|MASK_URL|MASK_FILE|MASK_OTHER) +#define DEFAULT_MASKACTL (MASK_OPEN|MASK_REMOVE|MASK_DISMISS) +#define DEFAULT_MASKACTR (MASK_REMOVE|MASK_DISMISS) +#define DEFAULT_MASKACTE (MASK_DISMISS) +#define DEFAULT_DELAY -1 + +#define MASK_MESSAGE 0x0001 +#define MASK_URL 0x0002 +#define MASK_FILE 0x0004 +#define MASK_OTHER 0x0008 + +#define MASK_DISMISS 0x0001 +#define MASK_OPEN 0x0002 +#define MASK_REMOVE 0x0004 + +#define SETTING_LIFETIME_MIN 1 +#define SETTING_LIFETIME_MAX 60 +#define SETTING_LIFETIME_DEFAULT 20 + +#define MAX_DATASIZE 24 + +#ifndef WM_MOUSEWHEEL + #define WM_MOUSEWHEEL 0x020A +#endif +#define TIMER_TO_ACTION 50685 + +//Entries in the database, don't translate +#define OPT_DISABLE "Disabled" +#define OPT_PREVIEW "Preview" +#define OPT_MENUITEM "MenuItem" +#define OPT_COLDEFAULT_MESSAGE "DefaultColorMsg" +#define OPT_COLBACK_MESSAGE "ColorBackMsg" +#define OPT_COLTEXT_MESSAGE "ColorTextMsg" +#define OPT_COLDEFAULT_URL "DefaultColorUrl" +#define OPT_COLBACK_URL "ColorBackUrl" +#define OPT_COLTEXT_URL "ColorTextUrl" +#define OPT_COLDEFAULT_FILE "DefaultColorFile" +#define OPT_COLBACK_FILE "ColorBackFile" +#define OPT_COLTEXT_FILE "ColorTextFile" +#define OPT_COLDEFAULT_OTHERS "DefaultColorOthers" +#define OPT_COLBACK_OTHERS "ColorBackOthers" +#define OPT_COLTEXT_OTHERS "ColorTextOthers" +#define OPT_MASKNOTIFY "Notify" +#define OPT_MASKACTL "ActionLeft" +#define OPT_MASKACTR "ActionRight" +#define OPT_MASKACTTE "ActionTimeExpires" +#define OPT_MSGWINDOWCHECK "WindowCheck" +#define OPT_MSGREPLYWINDOW "ReplyWindow" +#define OPT_MERGEPOPUP "MergePopup" +#define OPT_DELAY_MESSAGE "DelayMessage" +#define OPT_DELAY_URL "DelayUrl" +#define OPT_DELAY_FILE "DelayFile" +#define OPT_DELAY_OTHERS "DelayOthers" +#define OPT_SHOW_DATE "ShowDate" +#define OPT_SHOW_TIME "ShowTime" +#define OPT_SHOW_HEADERS "ShowHeaders" +#define OPT_NUMBER_MSG "NumberMsg" +#define OPT_SHOW_ON "ShowOldOrNew" +#define OPT_HIDESEND "HideSend" +#define OPT_NORSS "NoRSSAnnounces" +#define OPT_READCHECK "ReadCheck" +//--------------------------- +//---Translateable Strings + +#define POPUP_COMMENT_MESSAGE "Message" +#define POPUP_COMMENT_URL "URL" +#define POPUP_COMMENT_FILE "File" +#define POPUP_COMMENT_CONTACTS "Contacts" +#define POPUP_COMMENT_ADDED "You were added!" +#define POPUP_COMMENT_AUTH "Requests your authorisation" +#define POPUP_COMMENT_WEBPAGER "ICQ Web pager" +#define POPUP_COMMENT_EMAILEXP "ICQ Email express" +#define POPUP_COMMENT_OTHER "Unknown Event" + +#define OPTIONS_GROUP "PopUps" +#define OPTIONS_TITLE "Event Notify" + +#define MENUITEM_NAME "Notify of new events" + +#define MENUITEM_ENABLE "Enable new event notification" +#define MENUITEM_DISABLE "Disable new event notification" + +//--------------------------- +//---Structures + +typedef struct PLUGIN_OPTIONS_struct +{ + HINSTANCE hInst; + BOOL bDisable; + BOOL bPreview; + BOOL bMenuitem; + BOOL bDefaultColorMsg; + BOOL bDefaultColorUrl; + BOOL bDefaultColorFile; + BOOL bDefaultColorOthers; + COLORREF colBackMsg; + COLORREF colTextMsg; + COLORREF colBackUrl; + COLORREF colTextUrl; + COLORREF colBackFile; + COLORREF colTextFile; + COLORREF colBackOthers; + COLORREF colTextOthers; + UINT maskNotify; + UINT maskActL; + UINT maskActR; + UINT maskActTE; + BOOL bMsgWindowCheck; + BOOL bMsgReplyWindow; + int iDelayMsg; + int iDelayUrl; + int iDelayFile; + int iDelayOthers; + int iDelayDefault; + BOOL bMergePopup; + BOOL bShowDate; + BOOL bShowTime; + BOOL bShowHeaders; + BYTE iNumberMsg; + BOOL bShowON; + BOOL bHideSend; + BOOL bNoRSS; + BOOL bReadCheck; +} PLUGIN_OPTIONS; + +typedef struct EVENT_DATA_EX{ + HANDLE hEvent; + int number; + struct EVENT_DATA_EX* next; + struct EVENT_DATA_EX* prev; +} EVENT_DATA_EX; + +typedef struct PLUGIN_DATA_struct { + UINT eventType; + HANDLE hContact; + PLUGIN_OPTIONS* pluginOptions; + HWND hWnd; + int isUnicode; + struct EVENT_DATA_EX* firstEventData; + struct EVENT_DATA_EX* firstShowEventData; + struct EVENT_DATA_EX* lastEventData; + long countEvent; + long iSeconds; + int iLock; +} PLUGIN_DATA; + +//--------------------------- +//---Global Variables +extern int g_UnicodeCore; + +//--------------------------- +//---External Procedure Definitions + +int PopupShow(PLUGIN_OPTIONS* pluginOptions, HANDLE hContact, HANDLE hEvent, UINT eventType); +int PopupUpdate(HANDLE hContact, HANDLE hEvent); +int PopupPreview(PLUGIN_OPTIONS* pluginOptions); +int PopupAct(HWND hWnd, UINT mask, PLUGIN_DATA* pdata); +int OptionsInit(PLUGIN_OPTIONS* pluginOptions); +int OptionsAdd(HINSTANCE hInst, WPARAM addInfo); +int Opt_DisableNEN(BOOL Status); +int MenuitemInit(BOOL bStatus); +int MenuitemUpdate(BOOL bStatus); +int NumberPopupData(HANDLE hContact, int eventType); +int CheckMsgWnd(HANDLE hContact); + +extern HINSTANCE hInst; + +// utils.c +BOOL __fastcall NENGetSettingBool(char* szSetting, BOOL bDef); +int __fastcall NENWriteSettingBool(char* szSetting, BOOL bValue); + +size_t __fastcall strlennull(const char *string); + +size_t __fastcall strlenT(const TCHAR *string); +TCHAR* __fastcall strdupT(const TCHAR *string); +TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src); +TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len); +TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src); +int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...); + + +TCHAR* __fastcall NENTranslateT(const char* src, const WCHAR* unibuf); + +void InitI18N(void); +TCHAR* ansi_to_tchar(const char* string); +char* tchar_to_ansi(const TCHAR* src); +TCHAR* utf8_to_tchar(const unsigned char* utf); + diff --git a/plugins/NewEventNotify/neweventnotify.sln b/plugins/NewEventNotify/neweventnotify.sln new file mode 100644 index 0000000000..5561371ed7 --- /dev/null +++ b/plugins/NewEventNotify/neweventnotify.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NewEventNotify", "neweventnotify.vcxproj", "{2E0A2793-94C3-82E7-2AB0-FD421816CFBF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Debug|Win32.Build.0 = Debug|Win32 + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Debug|x64.ActiveCfg = Debug|x64 + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Debug|x64.Build.0 = Debug|x64 + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|Win32.ActiveCfg = Release|Win32 + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|Win32.Build.0 = Release|Win32 + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|x64.ActiveCfg = Release|x64 + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/plugins/NewEventNotify/neweventnotify.vcxproj b/plugins/NewEventNotify/neweventnotify.vcxproj new file mode 100644 index 0000000000..ea2c4b1c0f --- /dev/null +++ b/plugins/NewEventNotify/neweventnotify.vcxproj @@ -0,0 +1,262 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + NewEventNotify + {2E0A2793-94C3-82E7-2AB0-FD421816CFBF} + + + + DynamicLibrary + false + MultiByte + true + + + DynamicLibrary + false + MultiByte + true + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + true + + + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + + + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + false + + + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + false + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + true + EditAndContinue + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;NEWEVENTNOTIFY_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Debug\neweventnotify.tlb + true + Win32 + + + 0x0415 + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + + + true + true + true + Console + $(IntDir)$(TargetName).lib + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + ProgramDatabase + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;_DEBUG;_WINDOWS;_USRDLL;NEWEVENTNOTIFY_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Debug\neweventnotify.tlb + true + + + 0x0415 + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + + + true + true + true + Console + $(IntDir)$(TargetName).lib + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + MultiThreadedDLL + OnlyExplicitInline + true + true + Full + true + Level3 + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;NEWEVENTNOTIFY_EXPORTS;%(PreprocessorDefinitions) + Size + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Release\neweventnotify.tlb + true + Win32 + + + 0x0415 + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + + + true + true + true + Console + $(IntDir)$(TargetName).lib + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + true + true + + + + + MultiThreadedDLL + OnlyExplicitInline + true + true + Full + true + Level3 + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;NDEBUG;_WINDOWS;_USRDLL;NEWEVENTNOTIFY_EXPORTS;%(PreprocessorDefinitions) + Size + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Release\neweventnotify.tlb + true + + + 0x0415 + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + + + true + true + true + Console + $(IntDir)$(TargetName).lib + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + true + true + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/NewEventNotify/neweventnotify.vcxproj.filters b/plugins/NewEventNotify/neweventnotify.vcxproj.filters new file mode 100644 index 0000000000..2d5c4ce16b --- /dev/null +++ b/plugins/NewEventNotify/neweventnotify.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + {9ef49dc7-0734-4983-885c-80a6a3486d38} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {5000bf0b-4ec4-4cd8-888f-ddbe3547d4ce} + h;hpp;hxx;hm;inl + + + {c05ab58e-cc3b-43f7-a29e-3612a41ff815} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/NewEventNotify/options.c b/plugins/NewEventNotify/options.c new file mode 100644 index 0000000000..ba96e10fda --- /dev/null +++ b/plugins/NewEventNotify/options.c @@ -0,0 +1,341 @@ +/* + Name: NewEventNotify - Plugin for Miranda IM + File: options.c - Manages Option Dialogs and Settings + Version: 0.0.4 + Description: Notifies you about some events + Author: icebreaker, + Date: 22.07.02 13:06 / Update: 16.09.02 17:45 + Copyright: (C) 2002 Starzinger Michael + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "neweventnotify.h" +#include +#include + +PLUGIN_OPTIONS* options; +BOOL bWmNotify; + +int OptionsRead(void) +{ + options->bDisable = NENGetSettingBool(OPT_DISABLE, FALSE); + options->bPreview = NENGetSettingBool(OPT_PREVIEW, TRUE); + options->bMenuitem = NENGetSettingBool(OPT_MENUITEM, FALSE); + options->bDefaultColorMsg = NENGetSettingBool(OPT_COLDEFAULT_MESSAGE, FALSE); + options->bDefaultColorUrl = NENGetSettingBool(OPT_COLDEFAULT_URL, FALSE); + options->bDefaultColorFile = NENGetSettingBool(OPT_COLDEFAULT_FILE, FALSE); + options->bDefaultColorOthers = NENGetSettingBool(OPT_COLDEFAULT_OTHERS, FALSE); + options->colBackMsg = (COLORREF)DBGetContactSettingDword(NULL, MODULE, OPT_COLBACK_MESSAGE, DEFAULT_COLBACK); + options->colTextMsg = (COLORREF)DBGetContactSettingDword(NULL, MODULE, OPT_COLTEXT_MESSAGE, DEFAULT_COLTEXT); + options->colBackUrl = (COLORREF)DBGetContactSettingDword(NULL, MODULE, OPT_COLBACK_URL, DEFAULT_COLBACK); + options->colTextUrl = (COLORREF)DBGetContactSettingDword(NULL, MODULE, OPT_COLTEXT_URL, DEFAULT_COLTEXT); + options->colBackFile = (COLORREF)DBGetContactSettingDword(NULL, MODULE, OPT_COLBACK_FILE, DEFAULT_COLBACK); + options->colTextFile = (COLORREF)DBGetContactSettingDword(NULL, MODULE, OPT_COLTEXT_FILE, DEFAULT_COLTEXT); + options->colBackOthers = (COLORREF)DBGetContactSettingDword(NULL, MODULE, OPT_COLBACK_OTHERS, DEFAULT_COLBACK); + options->colTextOthers = (COLORREF)DBGetContactSettingDword(NULL, MODULE, OPT_COLTEXT_OTHERS, DEFAULT_COLTEXT); + options->maskNotify = (UINT)DBGetContactSettingByte(NULL, MODULE, OPT_MASKNOTIFY, DEFAULT_MASKNOTIFY); + options->maskActL = (UINT)DBGetContactSettingByte(NULL, MODULE, OPT_MASKACTL, DEFAULT_MASKACTL); + options->maskActR = (UINT)DBGetContactSettingByte(NULL, MODULE, OPT_MASKACTR, DEFAULT_MASKACTR); + options->maskActTE = (UINT)DBGetContactSettingByte(NULL, MODULE, OPT_MASKACTTE, DEFAULT_MASKACTE); + options->bMsgWindowCheck = NENGetSettingBool(OPT_MSGWINDOWCHECK, TRUE); + options->bMsgReplyWindow = NENGetSettingBool(OPT_MSGREPLYWINDOW, FALSE); + options->bMergePopup = NENGetSettingBool(OPT_MERGEPOPUP, TRUE); + options->iDelayMsg = (int)DBGetContactSettingDword(NULL, MODULE, OPT_DELAY_MESSAGE, DEFAULT_DELAY); + options->iDelayUrl = (int)DBGetContactSettingDword(NULL, MODULE, OPT_DELAY_URL, DEFAULT_DELAY); + options->iDelayFile = (int)DBGetContactSettingDword(NULL, MODULE, OPT_DELAY_FILE, DEFAULT_DELAY); + options->iDelayOthers = (int)DBGetContactSettingDword(NULL, MODULE, OPT_DELAY_OTHERS, DEFAULT_DELAY); + options->iDelayDefault = (int)DBGetContactSettingRangedWord(NULL, "PopUp", "Seconds", SETTING_LIFETIME_DEFAULT, SETTING_LIFETIME_MIN, SETTING_LIFETIME_MAX); + options->bShowDate = NENGetSettingBool(OPT_SHOW_DATE, TRUE); + options->bShowTime = NENGetSettingBool(OPT_SHOW_TIME, TRUE); + options->bShowHeaders = NENGetSettingBool(OPT_SHOW_HEADERS, TRUE); + options->iNumberMsg = (BYTE)DBGetContactSettingByte(NULL, MODULE, OPT_NUMBER_MSG, TRUE); + options->bShowON = NENGetSettingBool(OPT_SHOW_ON, TRUE); + options->bHideSend = NENGetSettingBool(OPT_HIDESEND, TRUE); + options->bNoRSS = NENGetSettingBool(OPT_NORSS, FALSE); + options->bReadCheck = NENGetSettingBool(OPT_READCHECK, FALSE); + return 0; +} + +int OptionsWrite(void) +{ + NENWriteSettingBool(OPT_DISABLE, options->bDisable); + NENWriteSettingBool(OPT_PREVIEW, options->bPreview); + NENWriteSettingBool(OPT_MENUITEM, options->bMenuitem); + NENWriteSettingBool(OPT_COLDEFAULT_MESSAGE, options->bDefaultColorMsg); + NENWriteSettingBool(OPT_COLDEFAULT_URL, options->bDefaultColorUrl); + NENWriteSettingBool(OPT_COLDEFAULT_FILE, options->bDefaultColorFile); + NENWriteSettingBool(OPT_COLDEFAULT_OTHERS, options->bDefaultColorOthers); + DBWriteContactSettingDword(NULL, MODULE, OPT_COLBACK_MESSAGE, (DWORD)options->colBackMsg); + DBWriteContactSettingDword(NULL, MODULE, OPT_COLTEXT_MESSAGE, (DWORD)options->colTextMsg); + DBWriteContactSettingDword(NULL, MODULE, OPT_COLBACK_URL, (DWORD)options->colBackUrl); + DBWriteContactSettingDword(NULL, MODULE, OPT_COLTEXT_URL, (DWORD)options->colTextUrl); + DBWriteContactSettingDword(NULL, MODULE, OPT_COLBACK_FILE, (DWORD)options->colBackFile); + DBWriteContactSettingDword(NULL, MODULE, OPT_COLTEXT_FILE, (DWORD)options->colTextFile); + DBWriteContactSettingDword(NULL, MODULE, OPT_COLBACK_OTHERS, (DWORD)options->colBackOthers); + DBWriteContactSettingDword(NULL, MODULE, OPT_COLTEXT_OTHERS, (DWORD)options->colTextOthers); + DBWriteContactSettingByte(NULL, MODULE, OPT_MASKNOTIFY, (BYTE)options->maskNotify); + DBWriteContactSettingByte(NULL, MODULE, OPT_MASKACTL, (BYTE)options->maskActL); + DBWriteContactSettingByte(NULL, MODULE, OPT_MASKACTR, (BYTE)options->maskActR); + DBWriteContactSettingByte(NULL, MODULE, OPT_MASKACTTE, (BYTE)options->maskActTE); + NENWriteSettingBool(OPT_MSGWINDOWCHECK, options->bMsgWindowCheck); + NENWriteSettingBool(OPT_MSGREPLYWINDOW, options->bMsgReplyWindow); + NENWriteSettingBool(OPT_MERGEPOPUP, options->bMergePopup); + DBWriteContactSettingDword(NULL, MODULE, OPT_DELAY_MESSAGE, (DWORD)options->iDelayMsg); + DBWriteContactSettingDword(NULL, MODULE, OPT_DELAY_URL, (DWORD)options->iDelayUrl); + DBWriteContactSettingDword(NULL, MODULE, OPT_DELAY_FILE, (DWORD)options->iDelayFile); + DBWriteContactSettingDword(NULL, MODULE, OPT_DELAY_OTHERS, (DWORD)options->iDelayOthers); + NENWriteSettingBool(OPT_SHOW_DATE, options->bShowDate); + NENWriteSettingBool(OPT_SHOW_TIME, options->bShowTime); + NENWriteSettingBool(OPT_SHOW_HEADERS, options->bShowHeaders); + DBWriteContactSettingByte(NULL, MODULE, OPT_NUMBER_MSG, (BYTE)options->iNumberMsg); + NENWriteSettingBool(OPT_SHOW_ON, options->bShowON); + NENWriteSettingBool(OPT_HIDESEND, options->bHideSend); + NENWriteSettingBool(OPT_NORSS, options->bNoRSS); + NENWriteSettingBool(OPT_READCHECK, options->bReadCheck); + return 0; +} + +static void SetCheckBoxState(HWND hWnd, int iCtrl, BOOL bState) +{ + CheckDlgButton(hWnd, iCtrl, bState ? BST_CHECKED : BST_UNCHECKED); +} + +static void EnableDlgItem(HWND hWnd, int iCtrl, BOOL bEnable) +{ + EnableWindow(GetDlgItem(hWnd, iCtrl), bEnable); +} + +static void UpdateOptionsDlgItemsState(HWND hWnd) +{ + //disable color picker when using default colors + EnableDlgItem(hWnd, IDC_COLBACK_MESSAGE, !options->bDefaultColorMsg); + EnableDlgItem(hWnd, IDC_COLTEXT_MESSAGE, !options->bDefaultColorMsg); + EnableDlgItem(hWnd, IDC_COLBACK_URL, !options->bDefaultColorUrl); + EnableDlgItem(hWnd, IDC_COLTEXT_URL, !options->bDefaultColorUrl); + EnableDlgItem(hWnd, IDC_COLBACK_FILE, !options->bDefaultColorFile); + EnableDlgItem(hWnd, IDC_COLTEXT_FILE, !options->bDefaultColorFile); + EnableDlgItem(hWnd, IDC_COLBACK_OTHERS, !options->bDefaultColorOthers); + EnableDlgItem(hWnd, IDC_COLTEXT_OTHERS, !options->bDefaultColorOthers); + //disable merge messages options when is not using + EnableDlgItem(hWnd, IDC_CHKSHOWDATE, options->bMergePopup); + EnableDlgItem(hWnd, IDC_CHKSHOWTIME, options->bMergePopup); + EnableDlgItem(hWnd, IDC_CHKSHOWHEADERS, options->bMergePopup); + EnableDlgItem(hWnd, IDC_CMDEDITHEADERS, options->bMergePopup && options->bShowHeaders); + EnableDlgItem(hWnd, IDC_NUMBERMSG, options->bMergePopup); + EnableDlgItem(hWnd, IDC_LBNUMBERMSG, options->bMergePopup); + EnableDlgItem(hWnd, IDC_RDNEW, options->bMergePopup && options->iNumberMsg); + EnableDlgItem(hWnd, IDC_RDOLD, options->bMergePopup && options->iNumberMsg); + //disable delay textbox when infinite is checked + EnableDlgItem(hWnd, IDC_DELAY_MESSAGE, options->iDelayMsg != -1); + EnableDlgItem(hWnd, IDC_DELAY_URL, options->iDelayUrl != -1); + EnableDlgItem(hWnd, IDC_DELAY_FILE, options->iDelayFile != -1); + EnableDlgItem(hWnd, IDC_DELAY_OTHERS, options->iDelayOthers != -1); +} + +static BOOL CALLBACK OptionsDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + TranslateDialogDefault(hWnd); + //make dialog represent the current options + bWmNotify = TRUE; + SendDlgItemMessage(hWnd, IDC_COLBACK_MESSAGE, CPM_SETCOLOUR, 0, options->colBackMsg); + SendDlgItemMessage(hWnd, IDC_COLTEXT_MESSAGE, CPM_SETCOLOUR, 0, options->colTextMsg); + SendDlgItemMessage(hWnd, IDC_COLBACK_URL, CPM_SETCOLOUR, 0, options->colBackUrl); + SendDlgItemMessage(hWnd, IDC_COLTEXT_URL, CPM_SETCOLOUR, 0, options->colTextUrl); + SendDlgItemMessage(hWnd, IDC_COLBACK_FILE, CPM_SETCOLOUR, 0, options->colBackFile); + SendDlgItemMessage(hWnd, IDC_COLTEXT_FILE, CPM_SETCOLOUR, 0, options->colTextFile); + SendDlgItemMessage(hWnd, IDC_COLBACK_OTHERS, CPM_SETCOLOUR, 0, options->colBackOthers); + SendDlgItemMessage(hWnd, IDC_COLTEXT_OTHERS, CPM_SETCOLOUR, 0, options->colTextOthers); + SetCheckBoxState(hWnd, IDC_CHKDEFAULTCOL_MESSAGE, options->bDefaultColorMsg); + SetCheckBoxState(hWnd, IDC_CHKDEFAULTCOL_URL, options->bDefaultColorUrl); + SetCheckBoxState(hWnd, IDC_CHKDEFAULTCOL_FILE, options->bDefaultColorFile); + SetCheckBoxState(hWnd, IDC_CHKDEFAULTCOL_OTHERS, options->bDefaultColorOthers); + SetCheckBoxState(hWnd, IDC_CHKMENUITEM, options->bMenuitem); + SetCheckBoxState(hWnd, IDC_CHKDISABLE, options->bDisable); + SetCheckBoxState(hWnd, IDC_CHKPREVIEW, options->bPreview); + SetCheckBoxState(hWnd, IDC_CHKMERGEPOPUP, options->bMergePopup); + SetCheckBoxState(hWnd, IDC_CHKNOTIFY_MESSAGE, options->maskNotify & MASK_MESSAGE); + SetCheckBoxState(hWnd, IDC_CHKNOTIFY_URL, options->maskNotify & MASK_URL); + SetCheckBoxState(hWnd, IDC_CHKNOTIFY_FILE, options->maskNotify & MASK_FILE); + SetCheckBoxState(hWnd, IDC_CHKNOTIFY_OTHER, options->maskNotify & MASK_OTHER); + SetCheckBoxState(hWnd, IDC_CHKACTL_DISMISS, options->maskActL & MASK_DISMISS); + SetCheckBoxState(hWnd, IDC_CHKACTL_OPEN, options->maskActL & MASK_OPEN); + SetCheckBoxState(hWnd, IDC_CHKACTL_REMOVE, options->maskActL & MASK_REMOVE); + SetCheckBoxState(hWnd, IDC_CHKACTR_DISMISS, options->maskActR & MASK_DISMISS); + SetCheckBoxState(hWnd, IDC_CHKACTR_OPEN, options->maskActR & MASK_OPEN); + SetCheckBoxState(hWnd, IDC_CHKACTR_REMOVE, options->maskActR & MASK_REMOVE); + SetCheckBoxState(hWnd, IDC_CHKACTTE_DISMISS, options->maskActTE & MASK_DISMISS); + SetCheckBoxState(hWnd, IDC_CHKACTTE_OPEN, options->maskActTE & MASK_OPEN); + SetCheckBoxState(hWnd, IDC_CHKACTTE_REMOVE, options->maskActTE & MASK_REMOVE); + SetCheckBoxState(hWnd, IDC_CHKWINDOWCHECK, options->bMsgWindowCheck); + SetCheckBoxState(hWnd, IDC_CHKREPLYWINDOW, options->bMsgReplyWindow); + SetCheckBoxState(hWnd, IDC_CHKSHOWDATE, options->bShowDate); + SetCheckBoxState(hWnd, IDC_CHKSHOWTIME, options->bShowTime); + SetCheckBoxState(hWnd, IDC_CHKSHOWHEADERS, options->bShowHeaders); + SetCheckBoxState(hWnd, IDC_RDNEW, !options->bShowON); + SetCheckBoxState(hWnd, IDC_RDOLD, options->bShowON); + SetCheckBoxState(hWnd, IDC_CHKHIDESEND, options->bHideSend); + SetCheckBoxState(hWnd, IDC_SUPRESSRSS, options->bNoRSS); + SetCheckBoxState(hWnd, IDC_READCHECK, options->bReadCheck); + SetCheckBoxState(hWnd, IDC_CHKINFINITE_MESSAGE, options->iDelayMsg == -1); + SetCheckBoxState(hWnd, IDC_CHKINFINITE_URL, options->iDelayUrl == -1); + SetCheckBoxState(hWnd, IDC_CHKINFINITE_FILE, options->iDelayFile == -1); + SetCheckBoxState(hWnd, IDC_CHKINFINITE_OTHERS, options->iDelayOthers == -1); + SetDlgItemInt(hWnd, IDC_DELAY_MESSAGE, options->iDelayMsg != -1?options->iDelayMsg:0, TRUE); + SetDlgItemInt(hWnd, IDC_DELAY_URL, options->iDelayUrl != -1?options->iDelayUrl:0, TRUE); + SetDlgItemInt(hWnd, IDC_DELAY_FILE, options->iDelayFile != -1?options->iDelayFile:0, TRUE); + SetDlgItemInt(hWnd, IDC_DELAY_OTHERS, options->iDelayOthers != -1?options->iDelayOthers:0, TRUE); + SetDlgItemInt(hWnd, IDC_NUMBERMSG, options->iNumberMsg, FALSE); + //update items' states + UpdateOptionsDlgItemsState(hWnd); + bWmNotify = FALSE; + return TRUE; + + case WM_COMMAND: + if (!bWmNotify) + { + switch (LOWORD(wParam)) + { + case IDC_PREVIEW: + PopupPreview(options); + break; + default: + //update options + options->maskNotify = (IsDlgButtonChecked(hWnd, IDC_CHKNOTIFY_MESSAGE)?MASK_MESSAGE:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKNOTIFY_URL)?MASK_URL:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKNOTIFY_FILE)?MASK_FILE:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKNOTIFY_OTHER)?MASK_OTHER:0); + options->maskActL = (IsDlgButtonChecked(hWnd, IDC_CHKACTL_DISMISS)?MASK_DISMISS:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKACTL_OPEN)?MASK_OPEN:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKACTL_REMOVE)?MASK_REMOVE:0); + options->maskActR = (IsDlgButtonChecked(hWnd, IDC_CHKACTR_DISMISS)?MASK_DISMISS:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKACTR_OPEN)?MASK_OPEN:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKACTR_REMOVE)?MASK_REMOVE:0); + options->maskActTE = (IsDlgButtonChecked(hWnd, IDC_CHKACTTE_DISMISS)?MASK_DISMISS:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKACTTE_OPEN)?MASK_OPEN:0) | + (IsDlgButtonChecked(hWnd, IDC_CHKACTTE_REMOVE)?MASK_REMOVE:0); + options->bDefaultColorMsg = IsDlgButtonChecked(hWnd, IDC_CHKDEFAULTCOL_MESSAGE); + options->bDefaultColorUrl = IsDlgButtonChecked(hWnd, IDC_CHKDEFAULTCOL_URL); + options->bDefaultColorFile = IsDlgButtonChecked(hWnd, IDC_CHKDEFAULTCOL_FILE); + options->bDefaultColorOthers = IsDlgButtonChecked(hWnd, IDC_CHKDEFAULTCOL_OTHERS); + options->bMenuitem = IsDlgButtonChecked(hWnd, IDC_CHKMENUITEM); + options->bDisable = IsDlgButtonChecked(hWnd, IDC_CHKDISABLE); + options->bPreview = IsDlgButtonChecked(hWnd, IDC_CHKPREVIEW); + options->iDelayMsg = IsDlgButtonChecked(hWnd, IDC_CHKINFINITE_MESSAGE)?-1:(DWORD)GetDlgItemInt(hWnd, IDC_DELAY_MESSAGE, NULL, FALSE); + options->iDelayUrl = IsDlgButtonChecked(hWnd, IDC_CHKINFINITE_URL)?-1:(DWORD)GetDlgItemInt(hWnd, IDC_DELAY_URL, NULL, FALSE); + options->iDelayFile = IsDlgButtonChecked(hWnd, IDC_CHKINFINITE_FILE)?-1:(DWORD)GetDlgItemInt(hWnd, IDC_DELAY_FILE, NULL, FALSE); + options->iDelayOthers = IsDlgButtonChecked(hWnd, IDC_CHKINFINITE_OTHERS)?-1:(DWORD)GetDlgItemInt(hWnd, IDC_DELAY_OTHERS, NULL, FALSE); + options->bMergePopup = IsDlgButtonChecked(hWnd, IDC_CHKMERGEPOPUP); + options->bMsgWindowCheck = IsDlgButtonChecked(hWnd, IDC_CHKWINDOWCHECK); + options->bMsgReplyWindow = IsDlgButtonChecked(hWnd, IDC_CHKREPLYWINDOW); + options->bShowDate = IsDlgButtonChecked(hWnd, IDC_CHKSHOWDATE); + options->bShowTime = IsDlgButtonChecked(hWnd, IDC_CHKSHOWTIME); + options->bShowHeaders = IsDlgButtonChecked(hWnd, IDC_CHKSHOWHEADERS); + options->bShowON = IsDlgButtonChecked(hWnd, IDC_RDOLD); + options->bShowON = !IsDlgButtonChecked(hWnd, IDC_RDNEW); + options->bHideSend = IsDlgButtonChecked(hWnd, IDC_CHKHIDESEND); + options->iNumberMsg = GetDlgItemInt(hWnd, IDC_NUMBERMSG, NULL, FALSE); + options->bNoRSS = IsDlgButtonChecked(hWnd, IDC_SUPRESSRSS); + options->bReadCheck = IsDlgButtonChecked(hWnd, IDC_READCHECK); + //update items' states + UpdateOptionsDlgItemsState(hWnd); + if (HIWORD(wParam) == CPN_COLOURCHANGED) + { + options->colBackMsg = SendDlgItemMessage(hWnd, IDC_COLBACK_MESSAGE, CPM_GETCOLOUR, 0, 0); + options->colTextMsg = SendDlgItemMessage(hWnd, IDC_COLTEXT_MESSAGE, CPM_GETCOLOUR, 0, 0); + options->colBackUrl = SendDlgItemMessage(hWnd, IDC_COLBACK_URL, CPM_GETCOLOUR, 0, 0); + options->colTextUrl = SendDlgItemMessage(hWnd, IDC_COLTEXT_URL, CPM_GETCOLOUR, 0, 0); + options->colBackFile = SendDlgItemMessage(hWnd, IDC_COLBACK_FILE, CPM_GETCOLOUR, 0, 0); + options->colTextFile = SendDlgItemMessage(hWnd, IDC_COLTEXT_FILE, CPM_GETCOLOUR, 0, 0); + options->colBackOthers = SendDlgItemMessage(hWnd, IDC_COLBACK_OTHERS, CPM_GETCOLOUR, 0, 0); + options->colTextOthers = SendDlgItemMessage(hWnd, IDC_COLTEXT_OTHERS, CPM_GETCOLOUR, 0, 0); + } + //send changes to menuitem + MenuitemUpdate(!options->bDisable); + //enable "Apply" button + SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); + break; + } + } + break; + + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + OptionsWrite(); + break; + + case PSN_RESET: + OptionsRead(); + + //maybe something changed with the menuitem + MenuitemUpdate(!options->bDisable); + break; + } + break; + + default: + break; + } + return FALSE; +} + +int OptionsAdd(HINSTANCE hInst, WPARAM addInfo) +{ + OPTIONSDIALOGPAGE odp; + WCHAR wsTitle[MAX_PATH]; + WCHAR wsGroup[MAX_PATH]; + +// if (ServiceExists(MS_POPUP_ADDPOPUP)) { +// do we need this dialog if popup.dll is not there??? + + odp.cbSize = sizeof(odp); +// odp.position = 100000000; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT); + odp.ptszTitle = NENTranslateT(OPTIONS_TITLE, wsTitle); + odp.ptszGroup = NENTranslateT(OPTIONS_GROUP, wsGroup); +// odp.groupPosition = 910000000; + odp.flags = ODPF_BOLDGROUPS; + if (g_UnicodeCore) odp.flags |= ODPF_UNICODE; + odp.pfnDlgProc = OptionsDlgProc; + CallService(MS_OPT_ADDPAGE, addInfo, (LPARAM)&odp); + + return 0; +} + +int OptionsInit(PLUGIN_OPTIONS* pluginOptions) +{ + options = pluginOptions; + + OptionsRead(); + + return 0; +} + +int Opt_DisableNEN(BOOL Status) +{ + options->bDisable = Status; + OptionsWrite(); // JK: really necessary to write everything here ???? + + //BUG! + //Update options dialog if open! + + return 0; +} diff --git a/plugins/NewEventNotify/popup.c b/plugins/NewEventNotify/popup.c new file mode 100644 index 0000000000..3ba52fded7 --- /dev/null +++ b/plugins/NewEventNotify/popup.c @@ -0,0 +1,752 @@ +/* + Name: NewEventNotify - Plugin for Miranda IM + File: popup.c - Displays a popup using the popup-plugin by hrk + Version: 2.2.3 + Description: Notifies you about some events + Author: icebreaker, + Date: 21.07.02 15:46 / Update: 16.09.02 17:45 + Copyright: (C) 2002 Starzinger Michael + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "neweventnotify.h" +#include +#include +#include +#include +//needed for ICQEVENTTYPE_* (Webpager & Emailexpress) +#include +#include +//needed for reply instead of read +#include +#include +#include +#include + +#define SIZEOF(X) (sizeof(X)/(g_UnicodeCore?sizeof(WCHAR):sizeof(char))) + +extern int g_IsServiceAvail; + +static int PopupCount = 0; + +PLUGIN_DATA* PopUpList[MAX_POPUPS]; + +/* +TIME NowTime() +{ + time_t actTime; + TIME endTime; + time(&actTime); + strftime(endTime.time,sizeof(endTime.time), "%H:%M", localtime(&actTime)); + strftime(endTime.date,sizeof(endTime.date), "%Y.%m.%d", localtime(&actTime)); + strftime(endTime.all,sizeof(endTime.all), "%Y.%m.%d %H:%M", localtime(&actTime)); + return endTime; +} +*/ + +int NumberPopupData(HANDLE hContact, int eventType) +{ + int n; + + for (n=0;nhContact == hContact) && (PopUpList[n]->iLock == 0) && (eventType == -1 || PopUpList[n]->eventType == (UINT)eventType)) + return n; + } + return -1; +} + + + +static int FindPopupData(PLUGIN_DATA* pdata) +{ + int n; + + for (n=0;niLock = 1; + eventData = pdata->firstEventData; + while (eventData) + { + if (eventData->next) + { + eventData = eventData->next; + free(eventData->prev); + eventData->prev = NULL; + } + else + { + free(eventData); + eventData = NULL; + } + } + pdata->lastEventData = pdata->firstEventData = pdata->firstShowEventData = NULL; + // remove from popup list if present + if (FindPopupData(pdata) != -1) + PopUpList[FindPopupData(pdata)] = NULL; +} + + + +int PopupAct(HWND hWnd, UINT mask, PLUGIN_DATA* pdata) +{ + EVENT_DATA_EX* eventData; + + if (mask & MASK_OPEN) + { + if (pdata) + { + // do MS_MSG_SENDMESSAGE instead if wanted to reply and not read! + if (pdata->pluginOptions->bMsgReplyWindow && pdata->eventType == EVENTTYPE_MESSAGE) + { + CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)pdata->hContact, (LPARAM)NULL); // JK, use core (since 0.3.3+) + } + else + { + CLISTEVENT* cle; + int idx = 0; + + eventData = pdata->firstEventData; + if (eventData) + { + do { //try to find the correct clist event //JK + cle = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, (WPARAM)pdata->hContact, idx); + if (cle && cle->hDbEvent == eventData->hEvent) + { + if (ServiceExists(cle->pszService)) + CallServiceSync(cle->pszService, (WPARAM)NULL, (LPARAM)cle); // JK, use core (since 0.3.3+) + break; + } + idx++; + } while (cle); + } + } + } + } + + if (mask & MASK_REMOVE) + { + if (pdata) + { + eventData = pdata->firstEventData; + pdata->iLock = 1; + while (eventData) + { + CallService(MS_CLIST_REMOVEEVENT, (WPARAM)pdata->hContact, (LPARAM)eventData->hEvent); + CallService(MS_DB_EVENT_MARKREAD, (WPARAM)pdata->hContact, (LPARAM)eventData->hEvent); + eventData = eventData->next; + } + FreePopupEventData(pdata); + } + } + + if (mask & MASK_DISMISS) + { + KillTimer(hWnd, TIMER_TO_ACTION); + FreePopupEventData(pdata); + PUDeletePopUp(hWnd); + } + + return 0; +} + +static BOOL CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + PLUGIN_DATA* pdata = NULL; + + pdata = (PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, (LPARAM)pdata); + if (!pdata) return FALSE; + + switch (message) + { + case WM_COMMAND: + PopupAct(hWnd, pdata->pluginOptions->maskActL, pdata); + break; + case WM_CONTEXTMENU: + PopupAct(hWnd, pdata->pluginOptions->maskActR, pdata); + break; + case UM_FREEPLUGINDATA: + PopupCount--; + free(pdata); + return TRUE; + case UM_INITPOPUP: + pdata->hWnd = hWnd; + SetTimer(hWnd, TIMER_TO_ACTION, pdata->iSeconds * 1000, NULL); + break; + case WM_MOUSEWHEEL: + if ((short)HIWORD(wParam) > 0 && pdata->firstShowEventData->prev && + (pdata->pluginOptions->bShowON || pdata->firstShowEventData->number >= pdata->pluginOptions->iNumberMsg)) + { + pdata->firstShowEventData = pdata->firstShowEventData->prev; + PopupUpdate(pdata->hContact, NULL); + } + if ((short)HIWORD(wParam) < 0 && pdata->firstShowEventData->next && + (!pdata->pluginOptions->bShowON || pdata->countEvent - pdata->firstShowEventData->number >= pdata->pluginOptions->iNumberMsg)) + { + pdata->firstShowEventData = pdata->firstShowEventData->next; + PopupUpdate(pdata->hContact, NULL); + } + break; + case WM_SETCURSOR: + SetFocus(hWnd); + break; + case WM_TIMER: + if (wParam != TIMER_TO_ACTION) + break; + PopupAct(hWnd, pdata->pluginOptions->maskActTE, pdata); + break; + default: + break; + } + if (g_UnicodeCore) + return DefWindowProcW(hWnd, message, wParam, lParam); + else + return DefWindowProcA(hWnd, message, wParam, lParam); +} + +static TCHAR* event_to_tchar(char* pBlob, DWORD flags) +{ + if (flags & DBEF_UTF) + return utf8_to_tchar(pBlob); + else + return ansi_to_tchar(pBlob); +} + +static TCHAR* GetEventPreview(DBEVENTINFO *dbei) +{ + TCHAR* comment1 = NULL; + TCHAR* comment2 = NULL; + TCHAR* commentFix = NULL; + + //now get text + switch (dbei->eventType) + { + case EVENTTYPE_MESSAGE: + { + if (dbei->pBlob) + { + if (dbei->flags & DBEF_UTF) + { // utf-8 in blob + comment1 = utf8_to_tchar(dbei->pBlob); + } + else if (dbei->cbBlob == (strlennull(dbei->pBlob)+1)*(sizeof(WCHAR)+1)) + { // wchar in blob (the old hack) + if (g_UnicodeCore) + comment1 = strdupT((TCHAR*)(dbei->pBlob + strlennull(dbei->pBlob) + 1)); + else + comment1 = strdupT((TCHAR*)dbei->pBlob); + } + else + comment1 = ansi_to_tchar(dbei->pBlob); + } + commentFix = POPUP_COMMENT_MESSAGE; + break; + } + + case EVENTTYPE_URL: + // url + if (dbei->pBlob) comment2 = ansi_to_tchar(dbei->pBlob); + // comment + if (dbei->pBlob) comment1 = ansi_to_tchar(dbei->pBlob + strlennull(dbei->pBlob) + 1); + commentFix = POPUP_COMMENT_URL; + break; + + case EVENTTYPE_FILE: + // filenames + if (dbei->pBlob) comment2 = event_to_tchar(dbei->pBlob + 4, dbei->flags); + // description + if (dbei->pBlob) comment1 = event_to_tchar(dbei->pBlob + strlennull(dbei->pBlob + 4) + 1, dbei->flags); + commentFix = POPUP_COMMENT_FILE; + break; + +//blob format is: +//ASCIIZ nick +//ASCIIZ UID + case EVENTTYPE_CONTACTS: + if (dbei->pBlob) + { // count contacts in event + char* pcBlob = dbei->pBlob; + char* pcEnd = dbei->pBlob + dbei->cbBlob; + int nContacts; + TCHAR szBuf[512]; + WCHAR szTmp[512]; + + for (nContacts = 1; ; nContacts++) + { // Nick + pcBlob += strlennull(pcBlob) + 1; + // UIN + pcBlob += strlennull(pcBlob) + 1; + // check for end of contacts + if (pcBlob >= pcEnd) + break; + } + if (g_UnicodeCore) + { + _snwprintf((WCHAR*)szBuf, SIZEOF(szBuf), (WCHAR*)NENTranslateT("Received %d contacts.", szTmp), nContacts); + ((WCHAR*)szBuf)[255] = 0; + } + else + _snprintfT(szBuf, SIZEOF(szBuf), NENTranslateT("Received %d contacts.", szTmp), nContacts); + comment1 = strdupT(szBuf); + } + commentFix = POPUP_COMMENT_CONTACTS; + break; + +//blob format is: +//DWORD numeric uin (ICQ only afaik) +//DWORD HANDLE to contact +//ASCIIZ nick (or text UID) +//ASCIIZ first name +//ASCIIZ last name +//ASCIIZ email (or YID) + case EVENTTYPE_ADDED: + if (dbei->pBlob) + { + char szUin[16]; + TCHAR szBuf[2048]; + TCHAR* szNick = NULL; + char *pszNick = dbei->pBlob + 8; + char *pszFirst = pszNick + strlennull(pszNick) + 1; + char *pszLast = pszFirst + strlennull(pszFirst) + 1; + char *pszEmail = pszLast + strlennull(pszLast) + 1; + + _snprintf(szUin, 16, "%d", *((DWORD*)dbei->pBlob)); + if (strlennull(pszNick) > 0) + szNick = event_to_tchar(pszNick, dbei->flags); + else if (strlennull(pszEmail) > 0) + szNick = event_to_tchar(pszEmail, dbei->flags); + else if (*((DWORD*)dbei->pBlob) > 0) + szNick = ansi_to_tchar(szUin); + + if (szNick) + { + strcpyT(szBuf, szNick); + strcatT(szBuf, NENTranslateT(" added you to the contact list", (WCHAR*)szBuf + strlenT(szBuf) + 1)); + free(szNick); + comment1 = strdupT(szBuf); + } + } + commentFix = POPUP_COMMENT_ADDED; + break; + + case EVENTTYPE_AUTHREQUEST: + if (dbei->pBlob) + { + char szUin[16]; + TCHAR szBuf[2048]; + TCHAR* szNick = NULL; + char *pszNick = dbei->pBlob + 8; + char *pszFirst = pszNick + strlennull(pszNick) + 1; + char *pszLast = pszFirst + strlennull(pszFirst) + 1; + char *pszEmail = pszLast + strlennull(pszLast) + 1; + + _snprintf(szUin, 16, "%d", *((DWORD*)dbei->pBlob)); + if (strlennull(pszNick) > 0) + szNick = event_to_tchar(pszNick, dbei->flags); + else if (strlennull(pszEmail) > 0) + szNick = event_to_tchar(pszEmail, dbei->flags); + else if (*((DWORD*)dbei->pBlob) > 0) + szNick = ansi_to_tchar(szUin); + + if (szNick) + { + strcpyT(szBuf, szNick); + strcatT(szBuf, NENTranslateT(" requested authorization", (WCHAR*)szBuf + strlenT(szBuf) + 1)); + free(szNick); + comment1 = strdupT(szBuf); + } + } + commentFix = POPUP_COMMENT_AUTH; + break; + +//blob format is: +//ASCIIZ text, usually "Sender IP: xxx.xxx.xxx.xxx\r\n%s" +//ASCIIZ from name +//ASCIIZ from e-mail + case ICQEVENTTYPE_WEBPAGER: + if (dbei->pBlob) comment1 = ansi_to_tchar(dbei->pBlob); +// if (dbei->pBlob) comment1 = dbei->pBlob + strlennull(comment2) + 1; + commentFix = POPUP_COMMENT_WEBPAGER; + break; + +//blob format is: +//ASCIIZ text, usually of the form "Subject: %s\r\n%s" +//ASCIIZ from name +//ASCIIZ from e-mail + case ICQEVENTTYPE_EMAILEXPRESS: + if (dbei->pBlob) comment1 = ansi_to_tchar(dbei->pBlob); +// if (dbei->pBlob) comment1 = dbei->pBlob + strlennull(comment2) + 1; + commentFix = POPUP_COMMENT_EMAILEXP; + break; + + default: + { + if (ServiceExists(MS_DB_EVENT_GETTYPE)) + { + DBEVENTTYPEDESCR* pei = (DBEVENTTYPEDESCR*)CallService(MS_DB_EVENT_GETTYPE, (WPARAM)dbei->szModule, (LPARAM)dbei->eventType); + if (pei && pei->cbSize >= DBEVENTTYPEDESCR_SIZE_V1) + { // support for custom database event types + if (dbei->pBlob) + { // preview requested + DBEVENTGETTEXT svc = {dbei, g_UnicodeCore ? DBVT_WCHAR : DBVT_ASCIIZ, CP_ACP}; + TCHAR *pet = (TCHAR*)CallService(MS_DB_EVENT_GETTEXT, 0, (LPARAM)&svc); + if (pet) + { // we've got event text, move to our memory space + comment1 = strdupT(pet); + mir_free(pet); + } + } + commentFix = pei->descr; + } + else + commentFix = POPUP_COMMENT_OTHER; + } + else + commentFix = POPUP_COMMENT_OTHER; + + break; + } + } + + if (strlenT(comment1) > 0) + { + free(comment2); + return comment1; + } + if (strlenT(comment2) > 0) + { + free(comment1); + return comment2; + } + free(comment1); + free(comment2); + + { + WCHAR tmp[MAX_PATH]; + + return strdupT(NENTranslateT(commentFix, tmp)); + } +} + +int PopupShow(PLUGIN_OPTIONS* pluginOptions, HANDLE hContact, HANDLE hEvent, UINT eventType) +{ + POPUPDATAEX puda; + POPUPDATAW pudw; + PLUGIN_DATA* pdata; + DBEVENTINFO dbe = {0}; + EVENT_DATA_EX* eventData; + TCHAR* sampleEvent; + long iSeconds; + + //there has to be a maximum number of popups shown at the same time + if (PopupCount >= MAX_POPUPS) + return 2; + + //check if we should report this kind of event + //get the prefered icon as well + //CHANGE: iSeconds is -1 because I use my timer to hide popup + pudw.iSeconds = -1; + + switch (eventType) + { + case EVENTTYPE_MESSAGE: + if (!(pluginOptions->maskNotify&MASK_MESSAGE)) return 1; + pudw.lchIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); + pudw.colorBack = pluginOptions->bDefaultColorMsg ? 0 : pluginOptions->colBackMsg; + pudw.colorText = pluginOptions->bDefaultColorMsg ? 0 : pluginOptions->colTextMsg; + iSeconds = pluginOptions->iDelayMsg; + sampleEvent = "This is a sample message event :-)"; + break; + case EVENTTYPE_URL: + if (!(pluginOptions->maskNotify&MASK_URL)) return 1; + pudw.lchIcon = LoadSkinnedIcon(SKINICON_EVENT_URL); + pudw.colorBack = pluginOptions->bDefaultColorUrl ? 0 : pluginOptions->colBackUrl; + pudw.colorText = pluginOptions->bDefaultColorUrl ? 0 : pluginOptions->colTextUrl; + iSeconds = pluginOptions->iDelayUrl; + sampleEvent = "This is a sample URL event ;-)"; + break; + case EVENTTYPE_FILE: + if (!(pluginOptions->maskNotify&MASK_FILE)) return 1; + pudw.lchIcon = LoadSkinnedIcon(SKINICON_EVENT_FILE); + pudw.colorBack = pluginOptions->bDefaultColorFile ? 0 : pluginOptions->colBackFile; + pudw.colorText = pluginOptions->bDefaultColorFile ? 0 : pluginOptions->colTextFile; + iSeconds = pluginOptions->iDelayFile; + sampleEvent = "This is a sample file event :-D"; + break; + default: + if (!(pluginOptions->maskNotify&MASK_OTHER)) return 1; + pudw.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + pudw.colorBack = pluginOptions->bDefaultColorOthers ? 0 : pluginOptions->colBackOthers; + pudw.colorText = pluginOptions->bDefaultColorOthers ? 0 : pluginOptions->colTextOthers; + iSeconds = pluginOptions->iDelayOthers; + sampleEvent = "This is a sample other event ;-D"; + break; + } + + //get DBEVENTINFO with pBlob if preview is needed (when is test then is off) + dbe.cbSize = sizeof(dbe); + + if ((pluginOptions->bPreview || eventType == EVENTTYPE_ADDED || eventType == EVENTTYPE_AUTHREQUEST) && hEvent) + { + dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hEvent, 0); + dbe.pBlob = (PBYTE)malloc(dbe.cbBlob); + } + if (hEvent) + CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&dbe); + + eventData = (EVENT_DATA_EX*)malloc(sizeof(EVENT_DATA_EX)); + eventData->hEvent = hEvent; + eventData->number = 1; + eventData->next = NULL; + eventData->prev = NULL; + + // retrieve correct hContact for AUTH events + if (dbe.pBlob && (eventType == EVENTTYPE_ADDED || eventType == EVENTTYPE_AUTHREQUEST)) + hContact = *((PHANDLE)(dbe.pBlob + sizeof(DWORD))); + + // set plugin_data ... will be usable within PopupDlgProc + pdata = (PLUGIN_DATA*)malloc(sizeof(PLUGIN_DATA)); + pdata->eventType = eventType; + pdata->hContact = hContact; + pdata->pluginOptions = pluginOptions; + pdata->countEvent = 1; + pdata->iLock = 0; + pdata->iSeconds = (iSeconds > 0) ? iSeconds : pluginOptions->iDelayDefault; + pdata->firstEventData = pdata->firstShowEventData = pdata->lastEventData = eventData; + + // finally create the popup + pudw.lchContact = hContact; + pudw.PluginWindowProc = (WNDPROC)PopupDlgProc; + pudw.PluginData = pdata; + + // if hContact is NULL, && hEvent is NULL then popup is only Test + if ((hContact == NULL) && (hEvent == NULL)) + { + strncpyT((TCHAR*)pudw.lptzContactName, NENTranslateT("Plugin Test", pudw.lpwzContactName), MAX_CONTACTNAME); + strncpyT((TCHAR*)pudw.lptzText, NENTranslateT(sampleEvent, pudw.lpwzText), MAX_SECONDLINE); + } + else + { // get the needed event data + TCHAR* szEventPreview; + + strncpyT((TCHAR*)pudw.lptzContactName, (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, g_UnicodeCore ? GCDNF_UNICODE : 0), MAX_CONTACTNAME); + szEventPreview = GetEventPreview(&dbe); + strncpyT((TCHAR*)pudw.lptzText, szEventPreview, MAX_SECONDLINE); + free(szEventPreview); + } + + PopupCount++; + + PopUpList[NumberPopupData(NULL, -1)] = pdata; + // send data to popup plugin + + if (g_UnicodeCore && ServiceExists(MS_POPUP_ADDPOPUPW)) + { + pdata->isUnicode = 1; + if (CallService(MS_POPUP_ADDPOPUPW, (WPARAM)&pudw, 0) < 0) + { // popup creation failed, release popupdata + FreePopupEventData(pdata); + free(pdata); + } + } + else // convert to ansi + { + pdata->isUnicode = 0; + puda.iSeconds = pudw.iSeconds; + puda.lchIcon = pudw.lchIcon; + puda.colorBack = pudw.colorBack; + puda.colorText = pudw.colorText; + puda.lchContact = pudw.lchContact; + puda.PluginWindowProc = pudw.PluginWindowProc; + puda.PluginData = pudw.PluginData; + { + char* szAnsi; + + szAnsi = tchar_to_ansi((TCHAR*)pudw.lptzContactName); + if (szAnsi) + strncpy(puda.lpzContactName, szAnsi, MAX_CONTACTNAME); + else + strcpy(puda.lpzContactName, ""); + free(szAnsi); + szAnsi = tchar_to_ansi((TCHAR*)pudw.lptzText); + if (szAnsi) + strncpy(puda.lpzText, szAnsi, MAX_SECONDLINE); + else + strcpy(puda.lpzText, ""); + free(szAnsi); + } + if (CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&puda, 0) < 0) + { // popup creation failed, release popupdata + FreePopupEventData(pdata); + free(pdata); + } + } + if (dbe.pBlob) + free(dbe.pBlob); + + return 0; +} + + +int PopupUpdate(HANDLE hContact, HANDLE hEvent) +{ + PLUGIN_DATA* pdata; + DBEVENTINFO dbe = {0}; + EVENT_DATA_EX* eventData; + TCHAR lpzText[MAX_SECONDLINE*2] = "\0\0"; + char timestamp[MAX_DATASIZE] = ""; + char formatTime[MAX_DATASIZE] = ""; + int iEvent = 0; + int doReverse = 0; + + // merge only message popups + pdata = (PLUGIN_DATA*)PopUpList[NumberPopupData(hContact, EVENTTYPE_MESSAGE)]; + + if (hEvent) + { + pdata->countEvent++; + + pdata->lastEventData->next = malloc(sizeof(EVENT_DATA_EX)); + pdata->lastEventData->next->prev = pdata->lastEventData; + pdata->lastEventData = pdata->lastEventData->next; + pdata->lastEventData->hEvent = hEvent; + pdata->lastEventData->number = pdata->lastEventData->prev->number + 1; + pdata->lastEventData->next = NULL; + if (!pdata->pluginOptions->bShowON && pdata->countEvent > pdata->pluginOptions->iNumberMsg && pdata->pluginOptions->iNumberMsg) + pdata->firstShowEventData = pdata->firstShowEventData->next; + //re-init timer delay + KillTimer(pdata->hWnd, TIMER_TO_ACTION); + SetTimer(pdata->hWnd, TIMER_TO_ACTION, pdata->iSeconds * 1000, NULL); + } + + if (pdata->pluginOptions->bShowHeaders) + { + WCHAR tmp[MAX_PATH]; + + _snprintfT(lpzText, SIZEOF(lpzText), "[b]%s %d[/b]\n", NENTranslateT("Number of new message: ", tmp), pdata->countEvent); + } + + doReverse = pdata->pluginOptions->bShowON; + + if ((pdata->firstShowEventData != pdata->firstEventData && doReverse) || + (pdata->firstShowEventData != pdata->lastEventData && !doReverse)) + _snprintfT(lpzText, SIZEOF(lpzText), "%s...\n", lpzText); + + + //take the active event as starting one + eventData = pdata->firstShowEventData; + + while (TRUE) + { + if (iEvent) + { + if (doReverse) + { + eventData = eventData->next; + } + else + { + eventData = eventData->prev; + } + } + iEvent++; + //get DBEVENTINFO with pBlob if preview is needed (when is test then is off) + dbe.cbSize = sizeof(dbe); + dbe.pBlob = NULL; + dbe.cbBlob = 0; + if (pdata->pluginOptions->bPreview && eventData->hEvent) + { + dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)eventData->hEvent, 0); + dbe.pBlob = (PBYTE)malloc(dbe.cbBlob); + } + if (eventData->hEvent) + CallService(MS_DB_EVENT_GET, (WPARAM)eventData->hEvent, (LPARAM)&dbe); + if (pdata->pluginOptions->bShowDate || pdata->pluginOptions->bShowTime) + { + strncpy(formatTime,"",sizeof(formatTime)); + if (pdata->pluginOptions->bShowDate) + strncpy(formatTime, "%Y.%m.%d ", sizeof(formatTime)); + if (pdata->pluginOptions->bShowTime) + strncat(formatTime, "%H:%M", sizeof(formatTime)); + strftime(timestamp,sizeof(timestamp), formatTime, localtime(&dbe.timestamp)); + if (g_UnicodeCore) + _snprintfT(lpzText, SIZEOF(lpzText), "%s[b][i]%S[/i][/b]\n", lpzText, timestamp); + else + _snprintfT(lpzText, SIZEOF(lpzText), "%s[b][i]%s[/i][/b]\n", lpzText, timestamp); + } + { // prepare event preview + TCHAR* szEventPreview = GetEventPreview(&dbe); + + _snprintfT(lpzText, SIZEOF(lpzText), "%s%s", lpzText, szEventPreview); + free(szEventPreview); + } + if (dbe.pBlob) + free(dbe.pBlob); + if (doReverse) + { + if ((iEvent >= pdata->pluginOptions->iNumberMsg && pdata->pluginOptions->iNumberMsg) || !eventData->next) + break; + } + else + { + if ((iEvent >= pdata->pluginOptions->iNumberMsg && pdata->pluginOptions->iNumberMsg) || !eventData->prev) + break; + } + + _snprintfT(lpzText, SIZEOF(lpzText), "%s\n", lpzText); + } + if ((doReverse && eventData->next) || (!doReverse && eventData->prev)) + { + _snprintfT(lpzText, SIZEOF(lpzText), "%s\n...", lpzText); + } + if (pdata->isUnicode) + { + CallService(MS_POPUP_CHANGETEXTW, (WPARAM)pdata->hWnd, (LPARAM)lpzText); + } + else + { + char* szAnsi = tchar_to_ansi(lpzText); + CallService(MS_POPUP_CHANGETEXT, (WPARAM)pdata->hWnd, (LPARAM)szAnsi); + free(szAnsi); + } + return 0; +} + +int PopupPreview(PLUGIN_OPTIONS* pluginOptions) +{ + PopupShow(pluginOptions, NULL, NULL, EVENTTYPE_MESSAGE); + PopupShow(pluginOptions, NULL, NULL, EVENTTYPE_URL); + PopupShow(pluginOptions, NULL, NULL, EVENTTYPE_FILE); + PopupShow(pluginOptions, NULL, NULL, -1); + + return 0; +} + diff --git a/plugins/NewEventNotify/res/popup.ico b/plugins/NewEventNotify/res/popup.ico new file mode 100644 index 0000000000..89b1dc9771 Binary files /dev/null and b/plugins/NewEventNotify/res/popup.ico differ diff --git a/plugins/NewEventNotify/res/popup_no.ico b/plugins/NewEventNotify/res/popup_no.ico new file mode 100644 index 0000000000..4c0c78a05a Binary files /dev/null and b/plugins/NewEventNotify/res/popup_no.ico differ diff --git a/plugins/NewEventNotify/resource.h b/plugins/NewEventNotify/resource.h new file mode 100644 index 0000000000..1146a3bfab --- /dev/null +++ b/plugins/NewEventNotify/resource.h @@ -0,0 +1,75 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDD_OPT 101 +#define IDI_ENABLED 106 +#define IDI_ICON2 107 +#define IDI_DISABLED 107 +#define IDC_PREVIEW 1000 +#define IDC_CHKNOTIFY_MESSAGE 1001 +#define IDC_CHKNOTIFY_URL 1002 +#define IDC_CHKNOTIFY_FILE 1003 +#define IDC_CHKNOTIFY_OTHER 1004 +#define IDC_CHKMENUITEM 1005 +#define IDC_CHKDISABLE 1006 +#define IDC_CHKACTL_DISMISS 1007 +#define IDC_CHKACTL_OPEN 1008 +#define IDC_CHKACTL_REMOVE 1009 +#define IDC_CHKACTR_DISMISS 1010 +#define IDC_CHKACTR_OPEN 1011 +#define IDC_CHKACTR_REMOVE 1012 +#define IDC_CHKWINDOWCHECK 1013 +#define IDC_CHKREPLYWINDOW 1014 +#define IDC_CHKPREVIEW 1015 +#define IDC_CHKINFINITE 1016 +#define IDC_CHKHIDESEND 1016 +#define IDC_CHKDEFAULTCOL_MESSAGE 1017 +#define IDC_COLBACK_MESSAGE 1018 +#define IDC_COLTEXT_MESSAGE 1019 +#define IDC_CHKDEFAULTCOL_URL 1020 +#define IDC_COLBACK_URL 1021 +#define IDC_COLTEXT_URL 1022 +#define IDC_CHKDEFAULTCOL_FILE 1023 +#define IDC_COLBACK_FILE 1024 +#define IDC_COLTEXT_FILE 1025 +#define IDC_CHKDEFAULTCOL_OTHERS 1026 +#define IDC_COLBACK_OTHERS 1027 +#define IDC_COLTEXT_OTHERS 1028 +#define IDC_MERGEPOPUP 1029 +#define IDC_CHKINFINITE_MESSAGE 1029 +#define IDC_CHKMERGEPOPUP 1030 +#define IDC_DELAY_MESSAGE 1031 +#define IDC_DELAY_URL 1032 +#define IDC_DELAY_FILE 1033 +#define IDC_DELAY_OTHERS 1034 +#define IDC_NUMBERMSG 1035 +#define IDC_CHKSHOWDATE 1036 +#define IDC_CHKSHOWTIME 1037 +#define IDC_CHKSHOWHEADERS 1038 +#define IDC_RDNEW 1039 +#define IDC_RDOLD 1040 +#define IDC_LBNUMBERMSG 1041 +#define IDC_CHKINFINITE_URL 1042 +#define IDC_CHKINFINITE_FILE 1043 +#define IDC_CHKINFINITE_OTHERS 1044 +#define IDC_CHKMERGEPOPUP2 1045 +#define IDC_SUPRESSRSS 1045 +#define IDC_TESTFORREAD 1046 +#define IDC_READCHECK 1046 +#define IDC_CMDEDITHEADERS 1047 +#define IDC_CHKACTTE_DISMISS 1049 +#define IDC_CHKACTTE_OPEN 1050 +#define IDC_CHKACTTE_REMOVE 1051 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1048 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/NewEventNotify/resource.rc b/plugins/NewEventNotify/resource.rc new file mode 100644 index 0000000000..8e18c89ae5 --- /dev/null +++ b/plugins/NewEventNotify/resource.rc @@ -0,0 +1,198 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT DIALOGEX 0, 0, 314, 252 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + GROUPBOX "General Options",IDC_STATIC,6,2,199,43 + CONTROL "Show entry in the PopUps menu",IDC_CHKMENUITEM,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,11,190,10 + CONTROL "Temporarily disable Event Popups",IDC_CHKDISABLE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,21,190,10 + CONTROL "Show Preview of Event in Popup",IDC_CHKPREVIEW,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,31,190,10 + GROUPBOX "Popup Options",IDC_STATIC,6,45,199,75 + LTEXT "Message",IDC_STATIC,11,65,44,13 + LTEXT "URL",IDC_STATIC,11,78,44,13 + LTEXT "File",IDC_STATIC,11,91,44,13 + LTEXT "Others",IDC_STATIC,12,104,44,13 + LTEXT "Text",IDC_STATIC,56,54,23,8 + CONTROL "",IDC_COLTEXT_MESSAGE,"ColourPicker",WS_TABSTOP,56,65, + 24,13 + CONTROL "",IDC_COLTEXT_URL,"ColourPicker",WS_TABSTOP,56,77,24,13 + CONTROL "",IDC_COLTEXT_FILE,"ColourPicker",WS_TABSTOP,56,89,24, + 13 + CONTROL "",IDC_COLTEXT_OTHERS,"ColourPicker",WS_TABSTOP,56,101, + 24,13 + LTEXT "Background",IDC_STATIC,86,54,44,8 + CONTROL "",IDC_COLBACK_MESSAGE,"ColourPicker",WS_TABSTOP,86,65, + 24,13 + CONTROL "",IDC_COLBACK_URL,"ColourPicker",WS_TABSTOP,86,77,24,13 + CONTROL "",IDC_COLBACK_FILE,"ColourPicker",WS_TABSTOP,86,89,24, + 13 + CONTROL "",IDC_COLBACK_OTHERS,"ColourPicker",WS_TABSTOP,86,101, + 24,13 + CONTROL "",IDC_CHKDEFAULTCOL_MESSAGE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,133,65,11,10 + CONTROL "",IDC_CHKDEFAULTCOL_URL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,133,78,11,10 + CONTROL "",IDC_CHKDEFAULTCOL_FILE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,133,91,11,10 + CONTROL "",IDC_CHKDEFAULTCOL_OTHERS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,133,103,11,10 + CTEXT "Time to expires",IDC_STATIC,144,52,48,10 + EDITTEXT IDC_DELAY_MESSAGE,155,62,26,13,ES_AUTOHSCROLL | + ES_NUMBER + EDITTEXT IDC_DELAY_URL,155,75,26,13,ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_DELAY_FILE,155,88,26,13,ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_DELAY_OTHERS,155,101,26,13,ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "",IDC_CHKINFINITE_MESSAGE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,185,65,11,10 + CONTROL "",IDC_CHKINFINITE_URL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,185,78,11,10 + CONTROL "",IDC_CHKINFINITE_FILE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,185,91,11,10 + CONTROL "",IDC_CHKINFINITE_OTHERS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,185,103,11,10 + GROUPBOX "Notify me of ...",IDC_STATIC,208,2,100,56 + CONTROL "Message",IDC_CHKNOTIFY_MESSAGE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,212,11,90,10 + CONTROL "URL",IDC_CHKNOTIFY_URL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,212,22,90,10 + CONTROL "File",IDC_CHKNOTIFY_FILE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,212,33,90,10 + CONTROL "Others",IDC_CHKNOTIFY_OTHER,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,212,44,90,10 + GROUPBOX "Left Click Actions",IDC_STATIC,208,58,100,44 + CONTROL "Dismiss Popup",IDC_CHKACTL_DISMISS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,212,67,90,10 + CONTROL "Open Event",IDC_CHKACTL_OPEN,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,212,78,90,10 + CONTROL "Dismiss Event",IDC_CHKACTL_REMOVE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,212,89,90,10 + GROUPBOX "Right Click Actions",IDC_STATIC,208,102,100,44 + CONTROL "Dismiss Popup",IDC_CHKACTR_DISMISS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,212,111,90,10 + CONTROL "Open Event",IDC_CHKACTR_OPEN,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,212,122,90,10 + CONTROL "Dismiss Event",IDC_CHKACTR_REMOVE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,212,133,90,10 + GROUPBOX "Time Expires Actions",IDC_STATIC,208,147,100,44 + CONTROL "Dismiss Popup",IDC_CHKACTTE_DISMISS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,212,156,90,10 + CONTROL "Open Event",IDC_CHKACTTE_OPEN,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,212,167,90,10 + CONTROL "Dismiss Event",IDC_CHKACTTE_REMOVE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,212,178,90,10 + GROUPBOX "Message-Event only",IDC_STATIC,6,120,199,131 + CONTROL "Don't show Popup when Message-Dialog is already open", + IDC_CHKWINDOWCHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 10,129,192,10 + CONTROL "Hide Popup when sending new message",IDC_CHKHIDESEND, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,138,192,10 + CONTROL "Open Reply-Dialog instead of reading the Message", + IDC_CHKREPLYWINDOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 10,147,192,10 + CONTROL "Merge popups from one user",IDC_CHKMERGEPOPUP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,157,192,10 + PUSHBUTTON "Preview",IDC_PREVIEW,228,204,60,12 + CONTROL "Show Date",IDC_CHKSHOWDATE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,20,166,84,10 + CONTROL "Show Time",IDC_CHKSHOWTIME,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,20,176,84,10 + CONTROL "Show Headers",IDC_CHKSHOWHEADERS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,20,186,84,10 + LTEXT "Number of begin shown messages",IDC_LBNUMBERMSG,20,195, + 143,8 + EDITTEXT IDC_NUMBERMSG,171,192,26,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Last message display first",IDC_RDNEW,"Button", + BS_AUTORADIOBUTTON,19,205,107,9 + CONTROL "Last message display last",IDC_RDOLD,"Button", + BS_AUTORADIOBUTTON,19,216,111,9 + PUSHBUTTON "Edit",IDC_CMDEDITHEADERS,107,185,36,11 + CONTROL "No popups for RSS contacts",IDC_SUPRESSRSS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,227,192,10 + CONTROL "No popups for read messages",IDC_READCHECK,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,237,192,10 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPT, DIALOG + BEGIN + LEFTMARGIN, 0 + RIGHTMARGIN, 308 + VERTGUIDE, 10 + TOPMARGIN, 0 + BOTTOMMARGIN, 252 + HORZGUIDE, 250 + END +END +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ENABLED ICON "res\\popup.ico" +IDI_DISABLED ICON "res\\popup_no.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + diff --git a/plugins/NewEventNotify/utils.c b/plugins/NewEventNotify/utils.c new file mode 100644 index 0000000000..2e8abb08a3 --- /dev/null +++ b/plugins/NewEventNotify/utils.c @@ -0,0 +1,543 @@ +/* + Name: NewEventNotify - Plugin for Miranda IM + File: utils.c - Utility functions for Unicode support & other tiny stuff + Version: 2.2.0 + Description: Notifies you when you receive a message + Author: Joe @ Whale, + Date: 05.07.07 13:04 + Copyright: (C) 2007-2008 Joe @ Whale + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "neweventnotify.h" + + +BOOL __fastcall NENGetSettingBool(char* szSetting, BOOL bDef) +{ + return (BOOL)DBGetContactSettingByte(NULL, MODULE, szSetting, bDef); +} + +int __fastcall NENWriteSettingBool(char* szSetting, BOOL bValue) +{ + return DBWriteContactSettingByte(NULL, MODULE, szSetting, (BYTE)bValue); +} + +/* a strlen() that likes NULL */ +size_t __fastcall strlennull(const char *string) +{ + if (string) + return strlen(string); + + return 0; +} + +size_t __fastcall strlenT(const TCHAR *string) +{ + if (string) + { + if (g_UnicodeCore) + return wcslen((WCHAR*)string); + else + return strlen((char*)string); + } + return 0; +} + +TCHAR* __fastcall strdupT(const TCHAR *string) +{ + if (string) + { + if (g_UnicodeCore) + return (TCHAR*)wcsdup((WCHAR*)string); + else + return (TCHAR*)strdup((char*)string); + } + return NULL; +} + +TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcscpy((WCHAR*)dest, (WCHAR*)src); + else + return (TCHAR*)strcpy((char*)dest, (char*)src); + } + return dest; +} + +TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcsncpy((WCHAR*)dest, (WCHAR*)src, len); + else + return (TCHAR*)strncpy((char*)dest, (char*)src, len); + } + return dest; +} + +TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcscat((WCHAR*)dest, (WCHAR*)src); + else + return (TCHAR*)strcat((char*)dest, (char*)src); + } + return dest; +} + +int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...) +{ + va_list va; + int len; + + va_start(va, fmt); + if (g_UnicodeCore) + { + TCHAR* wfmt = ansi_to_tchar(fmt); + + len = _vsnwprintf((WCHAR*)buffer, count-1, (WCHAR*)wfmt, va); + ((WCHAR*)buffer)[count-1] = 0; + free(wfmt); + } + else + { + len = _vsnprintf((char*)buffer, count-1, fmt, va); + ((char*)buffer)[count-1] = 0; + } + va_end(va); + return len; +} + +TCHAR* __fastcall NENTranslateT(const char* src, const WCHAR* unibuf) +{ // this takes Ascii strings only!!! + char* szRes = NULL; + + if (!strlennull(src)) + { // for the case of empty strings + return ""; + } + + if (g_UnicodeCore) + { // we give WCHAR + WCHAR *unicode; + int wchars, err; + + wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, + strlennull(src), NULL, 0); + + if (wchars == 0) return NULL; // Failure + + unicode = (WCHAR*)unibuf; + if (!unicode) + unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); + + unicode[wchars] = 0; + + err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, + strlennull(src), unicode, wchars); + if (err != wchars) return NULL; // Failure + + return (TCHAR*)TranslateW(unicode); + } + else + return (TCHAR*)Translate(src); +} + +static BOOL bHasCP_UTF8 = FALSE; + + +void InitI18N(void) +{ + CPINFO CPInfo; + + + bHasCP_UTF8 = GetCPInfo(CP_UTF8, &CPInfo); +} + + +// Scans a string encoded in UTF-8 to verify that it contains +// only valid sequences. It will return 1 if the string contains +// only legitimate encoding sequences; otherwise it will return 0; +// From 'Secure Programming Cookbook', John Viega & Matt Messier, 2003 +int UTF8_IsValid(const unsigned char* pszInput) +{ + int nb, i; + const unsigned char* c = pszInput; + + if (!pszInput) return 0; + + for (c = pszInput; *c; c += (nb + 1)) + { + if (!(*c & 0x80)) + nb = 0; + else if ((*c & 0xc0) == 0x80) return 0; + else if ((*c & 0xe0) == 0xc0) nb = 1; + else if ((*c & 0xf0) == 0xe0) nb = 2; + else if ((*c & 0xf8) == 0xf0) nb = 3; + else if ((*c & 0xfc) == 0xf8) nb = 4; + else if ((*c & 0xfe) == 0xfc) nb = 5; + + for (i = 1; i<=nb; i++) // we this forward, do not cross end of string + if ((*(c + i) & 0xc0) != 0x80) + return 0; + } + + return 1; +} + + +/* + * The following UTF8 routines are + * + * Copyright (C) 2001 Peter Harris + * Copyright (C) 2001 Edmund Grimley Evans + * + * under a GPL license + * + * -------------------------------------------------------------- + * Convert a string between UTF-8 and the locale's charset. + * Invalid bytes are replaced by '#', and characters that are + * not available in the target encoding are replaced by '?'. + * + * If the locale's charset is not set explicitly then it is + * obtained using nl_langinfo(CODESET), where available, the + * environment variable CHARSET, or assumed to be US-ASCII. + * + * Return value of conversion functions: + * + * -1 : memory allocation failed + * 0 : data was converted exactly + * 1 : valid data was converted approximately (using '?') + * 2 : input was invalid (but still converted, using '#') + * 3 : unknown encoding (but still converted, using '?') + */ + + + +/* + * Convert a string between UTF-8 and the locale's charset. + */ +unsigned char *make_utf8_string(const wchar_t *unicode) +{ + int size = 0; + int index = 0; + int out_index = 0; + unsigned char* out; + unsigned short c; + + if (!unicode) return NULL; + + /* first calculate the size of the target string */ + c = unicode[index++]; + while (c) + { + if (c < 0x0080) + size += 1; + else if (c < 0x0800) + size += 2; + else + size += 3; + c = unicode[index++]; + } + + out = (unsigned char*)malloc(size + 1); + if (out == NULL) + return NULL; + index = 0; + + c = unicode[index++]; + while (c) + { + if (c < 0x080) + { + out[out_index++] = (unsigned char)c; + } + else if (c < 0x800) + { + out[out_index++] = 0xc0 | (c >> 6); + out[out_index++] = 0x80 | (c & 0x3f); + } + else + { + out[out_index++] = 0xe0 | (c >> 12); + out[out_index++] = 0x80 | ((c >> 6) & 0x3f); + out[out_index++] = 0x80 | (c & 0x3f); + } + c = unicode[index++]; + } + out[out_index] = 0x00; + + return out; +} + + + +WCHAR *make_unicode_string(const unsigned char *utf8) +{ + int size = 0, index = 0, out_index = 0; + wchar_t *out; + unsigned char c; + + if (!utf8) return NULL; + + /* first calculate the size of the target string */ + c = utf8[index++]; + while (c) + { + if ((c & 0x80) == 0) + { + index += 0; + } + else if ((c & 0xe0) == 0xe0) + { + index += 2; + } + else + { + index += 1; + } + size += 1; + c = utf8[index++]; + } + + out = (wchar_t*)malloc((size + 1) * sizeof(wchar_t)); + if (out == NULL) + return NULL; + index = 0; + + c = utf8[index++]; + while (c) + { + if((c & 0x80) == 0) + { + out[out_index++] = c; + } + else if((c & 0xe0) == 0xe0) + { + out[out_index] = (c & 0x1F) << 12; + c = utf8[index++]; + out[out_index] |= (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } + else + { + out[out_index] = (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } + c = utf8[index++]; + } + out[out_index] = 0; + + return out; +} + + + +int utf8_encode(const char *from, char **to) +{ + wchar_t *unicode; + int wchars, err; + + + wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, + strlennull(from), NULL, 0); + + if (wchars == 0) + { +// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); + return -1; + } + + unicode = (wchar_t*)_alloca((wchars + 1) * sizeof(unsigned short)); + unicode[wchars] = 0; + + err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, + strlennull(from), unicode, wchars); + if(err != wchars) + { +// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); + return -1; + } + + /* On NT-based windows systems, we could use WideCharToMultiByte(), but + * MS doesn't actually have a consistent API across win32. + */ + *to = make_utf8_string(unicode); + + return 0; +} + + + +// Returns 0 on error, 1 on success +int utf8_decode(const char *from, char **to) +{ + int nResult = 0; + +// _ASSERTE(!(*to)); // You passed a non-zero pointer, make sure it doesnt point to unfreed memory + + // Validate the string + if (!UTF8_IsValid(from)) + return 0; + + // Use the native conversion routines when available + if (bHasCP_UTF8) + { + WCHAR *wszTemp = NULL; + int inlen = strlennull(from); + + wszTemp = (WCHAR *)_alloca(sizeof(WCHAR) * (inlen + 1)); + + // Convert the UTF-8 string to UCS + if (MultiByteToWideChar(CP_UTF8, 0, from, -1, wszTemp, inlen + 1)) + { + // Convert the UCS string to local ANSI codepage + *to = (char*)malloc(inlen+1); + if (WideCharToMultiByte(CP_ACP, 0, wszTemp, -1, *to, inlen+1, NULL, NULL)) + { + nResult = 1; + } + else + { + free(*to); + } + } + } + else + { + wchar_t *unicode; + int chars; + int err; + + unicode = make_unicode_string(from); + if (unicode == NULL) + { +// fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); + return 0; + } + + chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + + if(chars == 0) + { +// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); + free(unicode); + return 0; + } + + *to = (char*)malloc((chars + 1)*sizeof(unsigned char)); + if(*to == NULL) + { +// fprintf(stderr, "Out of memory processing string to local charset\n"); + free(unicode); + return 0; + } + + err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); + if (err != chars) + { +// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); + free(unicode); + free(*to); + return 0; + } + + free(unicode); + + nResult = 1; + } + + return nResult; +} + + + +TCHAR* ansi_to_tchar(const char* src) +{ + if (g_UnicodeCore) + { + WCHAR *unicode; + int wchars, err; + + wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, strlennull(src), NULL, 0); + + if (wchars == 0) return NULL; // Failure + + unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); + unicode[wchars] = 0; + + err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, strlennull(src), unicode, wchars); + if (err != wchars) + { + free(unicode); + return NULL; // Failure + } + + return (TCHAR*)unicode; + } + else + return strdupT((TCHAR*)src); +} + +char* tchar_to_ansi(const TCHAR* src) +{ + if (g_UnicodeCore) + { + char *ansi; + int chars; + int err; + + chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, NULL, 0, NULL, NULL); + + if (chars == 0) return NULL; // Failure + + ansi = (char*)malloc((chars + 1)*sizeof(char)); + if (ansi == NULL) return NULL; // Failure + + err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, ansi, chars, NULL, NULL); + if (err != chars) + { + free(ansi); + return NULL; + } + return ansi; + } + else + return (char*)strdupT(src); +} + +TCHAR* utf8_to_tchar(const unsigned char* utf) +{ + if (g_UnicodeCore) + return (TCHAR*)make_unicode_string(utf); + else + { + char* szAnsi = NULL; + + if (utf8_decode(utf, &szAnsi)) + return (TCHAR*)szAnsi; + else + return NULL; // Failure + } +} \ No newline at end of file -- cgit v1.2.3