/* Variables Plugin for Miranda-IM (www.miranda-im.org) Copyright 2003-2006 P. Boon 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 "variables.h" #include "m_trigger.h" #include "trigger_variables.h" #include "resource.h" extern HINSTANCE hInst; static TRG_VAR_CACHE *tvc = NULL; static int tvcCount = 0; static unsigned int stringChangeTimerID = 0; static int addToCache(DWORD triggerID) { /* triggerID must be in the DB */ DBVARIANT dbv; int i; for (i=0;i<tvcCount;i++) { if (tvc[i].triggerID == triggerID) { free(tvc[i].parsedText); MoveMemory(&tvc[i], &tvc[tvcCount-1], sizeof(TRG_VAR_CACHE)); tvcCount -= 1; } } if (!DBGetTriggerSettingTString(triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, &dbv)) { tvc = ( TRG_VAR_CACHE* )realloc(tvc, (tvcCount+1)*sizeof(TRG_VAR_CACHE)); if (tvc == NULL) { return -1; } tvc[tvcCount].triggerID = triggerID; tvc[tvcCount].parsedText = variables_parsedup(dbv.ptszVal, NULL, NULL); // it stays in our own mem space! if (tvc[tvcCount].parsedText == NULL) { return -1; } tvcCount += 1; DBFreeVariant(&dbv); } else { return -1; } return 0; } static int removeFromCache(DWORD triggerID) { int i; for (i=0;i<tvcCount;i++) { if (tvc[i].triggerID == triggerID) { free(tvc[i].parsedText); MoveMemory(&tvc[i], &tvc[tvcCount-1], sizeof(TRG_VAR_CACHE)); tvcCount -= 1; } } return 0; } static VOID CALLBACK checkStringsTimer(HWND hwnd,UINT message,UINT_PTR idEvent,DWORD dwTime) { int i; TCHAR *parsedText; REPORTINFO ri; TRIGGERDATA td; DBVARIANT dbv; DWORD triggerID; triggerID = 0; do { triggerID = (DWORD)CallService(MS_TRIGGER_FINDNEXTTRIGGERID, triggerID, (LPARAM)TRIGGERNAME); if (triggerID == 0) { continue; } for (i=0;i<tvcCount;i++) { if (triggerID != tvc[i].triggerID) { continue; } if (!DBGetTriggerSettingTString(tvc[i].triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, &dbv)) { parsedText = variables_parsedup(dbv.ptszVal, NULL, NULL); if (parsedText == NULL) { continue; } if (!_tcscmp(tvc[i].parsedText, parsedText)) { free(parsedText); continue; } else { ZeroMemory(&td, sizeof(td)); td.cbSize = sizeof(td); td.dFlags = DF_TEXT; td.tszText = parsedText; ZeroMemory(&ri, sizeof(REPORTINFO)); ri.cbSize = sizeof(REPORTINFO); ri.triggerID = tvc[i].triggerID; ri.pszName = TRIGGERNAME; ri.flags = TRG_PERFORM; ri.td = &td; CallService(MS_TRIGGER_REPORTEVENT, 0, (LPARAM)&ri); free(tvc[i].parsedText); tvc[i].parsedText = parsedText; } DBFreeVariant(&dbv); } } } while (triggerID != 0); } INT_PTR CALLBACK DlgProcOptsStringChange(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { DBVARIANT dbv; DWORD triggerID; TranslateDialogDefault(hwndDlg); triggerID = (DWORD)lParam; if (!DBGetTriggerSetting(triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, &dbv)) { SetDlgItemTextA(hwndDlg, IDC_FORMATTEXT, dbv.pszVal); DBFreeVariant(&dbv); } variables_skin_helpbutton(hwndDlg, IDC_SHOWHELP); break; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_SHOWHELP: { variables_showhelp(hwndDlg, IDC_FORMATTEXT, VHF_FULLDLG|VHF_SETLASTSUBJECT, NULL, NULL); break; } } break; case TM_ADDTRIGGER: { // wParam = trigger ID // lParam = (TRIGGERREGISTER *) DWORD triggerID; TCHAR *tszFormatText; triggerID = (DWORD)wParam; tszFormatText = Hlp_GetDlgItemText(hwndDlg, IDC_FORMATTEXT); if (tszFormatText != NULL) { DBWriteTriggerSettingTString(triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, tszFormatText); free(tszFormatText); } addToCache(triggerID); break; } case TM_DELTRIGGER: { // wParam = triggerID // lParam = (TRIGGEREGISTER *) may be 0 DWORD triggerID; REMOVETRIGGERSETTINGS rts; triggerID = (DWORD)wParam; removeFromCache(triggerID); rts.cbSize = sizeof(REMOVETRIGGERSETTINGS); rts.prefix = PREFIX_TRIGGERID; rts.id = triggerID; rts.hContact = NULL; rts.szModule = MODULENAME; CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&rts); break; } } return FALSE; } int initTriggerModule() { CONDITIONREGISTER cr; TRIGGERREGISTER tr; ACTIONREGISTER ar; int res; DWORD triggerID; log_debugA("Variables: initTriggerModule"); if (!ServiceExists(MS_TRIGGER_REGISTERTRIGGER)) { log_debugA("Variables: %s does not exist", MS_TRIGGER_REGISTERTRIGGER); return -1; } ZeroMemory(&tr, sizeof(tr)); tr.cbSize = sizeof(tr); tr.pszName = TRIGGERNAME; tr.hInstance = hInst; tr.pfnDlgProc = DlgProcOptsStringChange; tr.pszTemplate = MAKEINTRESOURCEA(IDD_TRG_STRINGCHANGE); tr.dFlags = DF_TEXT|DF_TCHAR; res = CallService(MS_TRIGGER_REGISTERTRIGGER, 0, (LPARAM)&tr); log_debugA("Variables: %s registered (%d)", TRIGGERNAME, res); ZeroMemory(&ar, sizeof(ACTIONREGISTER)); ar.cbSize = sizeof(ACTIONREGISTER); ar.pszName = "Variables: Parse string"; ar.hInstance = hInst; ar.pfnDlgProc = DlgProcOptsParseString; ar.pszTemplate = MAKEINTRESOURCEA(IDD_ACT_PARSESTRING); ar.actionFunction = ParseStringAction; ar.flags = ARF_FUNCTION|ARF_TCHAR; CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar); ZeroMemory(&cr, sizeof(CONDITIONREGISTER)); cr.cbSize = sizeof(CONDITIONREGISTER); cr.pszName = "Variables: Condition"; cr.hInstance = hInst; cr.pfnDlgProc = DlgProcOptsCondition; cr.pszTemplate = MAKEINTRESOURCEA(IDD_CND_PARSESTRING); cr.conditionFunction = ParseStringCondition; cr.flags = CRF_FUNCTION|CRF_TCHAR; CallService(MS_TRIGGER_REGISTERCONDITION, 0, (LPARAM)&cr); // fill cache triggerID = 0; do { triggerID = (DWORD)CallService(MS_TRIGGER_FINDNEXTTRIGGERID, triggerID, (LPARAM)TRIGGERNAME); if (triggerID == 0) { continue; } addToCache(triggerID); } while (triggerID != 0); stringChangeTimerID = SetTimer(NULL, 0, CHECKSTRINGDELAY, checkStringsTimer); return res; }