BOOL checkOpenWindow(MCONTACT hContact) { if (bFlashIfMsgOpen && !bFlashIfMsgWinNotTop) return TRUE; BOOL focus, found = CheckMsgWnd(hContact, &focus); if (!found && bMetaProtoEnabled) found = CheckMsgWnd(db_mc_getMeta(hContact), &focus); if (!found) return TRUE; if (bFlashIfMsgOpen && !focus) return TRUE; return FALSE; }
BOOL checkOpenWindow(MCONTACT hContact) { if (bFlashIfMsgOpen && !bFlashIfMsgWinNotTop) return TRUE; BOOL focus, found = CheckMsgWnd(hContact, &focus); if (!found && bMetaProtoEnabled) { MCONTACT hMetaContact = (MCONTACT)db_get_dw(hContact, META_PROTO, "Handle", 0); if (hMetaContact && db_mc_getMeta(hContact) == hMetaContact) found = CheckMsgWnd(hMetaContact, &focus); } if (!found) return TRUE; if (bFlashIfMsgOpen && !focus) return TRUE; return FALSE; }
// called when an event is added to the DB int CheckNewEvents(WPARAM wparam,LPARAM lparam) { DBEVENTINFO dbei={0}; WORD mode,status; dbei.cbBlob=0; dbei.cbSize=sizeof(dbei); CallService(MS_DB_EVENT_GET,(WPARAM)lparam,(LPARAM)&dbei); if(dbei.eventType!=EVENTTYPE_MESSAGE && dbei.eventType!=EVENTTYPE_FILE && dbei.eventType!=EVENTTYPE_URL && dbei.eventType!=EVENTTYPE_ADDED && dbei.eventType!=EVENTTYPE_AUTHREQUEST) return 0; if(dbei.flags&DBEF_SENT) return 0; mode=DBGetContactSettingWord(NULL,MODULE,"ModeFlag",NOTIFY_MSG|NOTIFY_URL|NOTIFY_FILE|NOTIFY_AUTH|NOTIFY_ADDED|DISMISS_AWAY|DISMISS_NA|DISMISS_DND); if(dbei.eventType==EVENTTYPE_MESSAGE && !(mode&NOTIFY_MSG)) return 0; if(dbei.eventType==EVENTTYPE_URL && !(mode&NOTIFY_URL)) return 0; if(dbei.eventType==EVENTTYPE_FILE && !(mode&NOTIFY_FILE)) return 0; if(dbei.eventType==EVENTTYPE_AUTHREQUEST && !(mode&NOTIFY_AUTH)) return 0; if(dbei.eventType==EVENTTYPE_ADDED && !(mode&NOTIFY_ADDED)) return 0; status=(WORD)CallProtoService(dbei.szModule,PS_GETSTATUS,0,0); switch(status){ case ID_STATUS_ONLINE: if(mode&DISMISS_ONLINE) return 0; break; case ID_STATUS_AWAY: if(mode&DISMISS_AWAY) return 0; break; case ID_STATUS_NA: if(mode&DISMISS_NA) return 0; break; case ID_STATUS_OCCUPIED: if(mode&DISMISS_OCCUPIED) return 0; break; case ID_STATUS_DND: if(mode&DISMISS_DND) return 0; break; case ID_STATUS_FREECHAT: if(mode&DISMISS_FREE) return 0; break; case ID_STATUS_INVISIBLE: if(mode&DISMISS_INVIS) return 0; break; case ID_STATUS_ONTHEPHONE: if(mode&DISMISS_PHONE) return 0; break; case ID_STATUS_OUTTOLUNCH: if(mode&DISMISS_LUNCH) return 0; break; default: return 0; } dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)lparam,0); dbei.pBlob=(PBYTE)malloc(dbei.cbBlob); CallService(MS_DB_EVENT_GET,(WPARAM)lparam,(LPARAM)&dbei); switch(dbei.eventType){ case EVENTTYPE_MESSAGE: if(DBGetContactSettingByte(NULL,"SRMsg","AutoPopup",0) && !(mode&NOTIFY_ALWAYS)) break; if(CheckMsgWnd(wparam) && !(mode&NOTIFY_ALWAYS)) break; WindowRequest((HANDLE)wparam,EVENTTYPE_MESSAGE,SKINICON_EVENT_MESSAGE,(HANDLE)lparam); break; case EVENTTYPE_URL: WindowRequest((HANDLE)wparam,EVENTTYPE_URL,SKINICON_EVENT_URL,(HANDLE)lparam); break; case EVENTTYPE_FILE: WindowRequest((HANDLE)wparam,EVENTTYPE_FILE,SKINICON_EVENT_FILE,(HANDLE)lparam); break; case EVENTTYPE_AUTHREQUEST: WindowRequest((HANDLE)wparam,EVENTTYPE_AUTHREQUEST,SKINICON_OTHER_MIRANDA,(HANDLE)lparam); break; case EVENTTYPE_ADDED: WindowRequest((HANDLE)wparam,EVENTTYPE_ADDED,SKINICON_OTHER_MIRANDA,(HANDLE)lparam); break; } free(dbei.pBlob); return 0; }
int ProcessStatusMessage(DBCONTACTWRITESETTING *cws, MCONTACT hContact) { STATUSMSGINFO smi; bool bEnablePopup = true, bEnableSound = true; char *szProto = GetContactProto(hContact); smi.proto = szProto; smi.hContact = hContact; smi.compare = CompareStatusMsg(&smi, cws, "LastStatusMsg"); if (smi.compare == COMPARE_SAME) goto skip_notify; if (cws->value.type == DBVT_DELETED) db_unset(hContact, "UserOnline", "LastStatusMsg"); else db_set(hContact, "UserOnline", "LastStatusMsg", &cws->value); //don't show popup when mradio connecting and disconnecting if (_stricmp(szProto, "mRadio") == 0 && !cws->value.type == DBVT_DELETED) { wchar_t buf[MAX_PATH]; mir_snwprintf(buf, L" (%s)", TranslateT("connecting")); T2Utf pszUtf(buf); mir_snwprintf(buf, L" (%s)", TranslateT("aborting")); T2Utf pszUtf2(buf); mir_snwprintf(buf, L" (%s)", TranslateT("playing")); T2Utf pszUtf3(buf); if (_stricmp(cws->value.pszVal, pszUtf) == 0 || _stricmp(cws->value.pszVal, pszUtf2) == 0 || _stricmp(cws->value.pszVal, pszUtf3) == 0) goto skip_notify; } // check per-contact ignored events if (db_get_b(hContact, MODULE, "EnableSMsgNotify", 1) == 0) bEnableSound = bEnablePopup = false; // we're offline or just connecting int myStatus = Proto_GetStatus(szProto); if (myStatus == ID_STATUS_OFFLINE) goto skip_notify; char dbSetting[64]; mir_snprintf(dbSetting, "%s_enabled", szProto); // this proto is not set for status message notifications if (db_get_b(NULL, MODULE, dbSetting, 1) == 0) goto skip_notify; mir_snprintf(dbSetting, "%d", IDC_CHK_STATUS_MESSAGE); // status message change notifications are disabled if (db_get_b(NULL, MODULE, dbSetting, 1) == 0) goto skip_notify; if (SkipHiddenContact(hContact)) goto skip_notify; // check if our status isn't on autodisable list if (opt.AutoDisable) { char statusIDs[12], statusIDp[12]; mir_snprintf(statusIDs, "s%d", myStatus); mir_snprintf(statusIDp, "p%d", myStatus); bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : bEnableSound; bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : bEnablePopup; } // check flags if ((!(templates.PopupSMsgFlags & NOTIFY_REMOVE_MESSAGE) && (smi.compare == COMPARE_DEL)) || (!(templates.PopupSMsgFlags & NOTIFY_NEW_MESSAGE) && (smi.compare == COMPARE_DIFF))) bEnablePopup = false; if (db_get_b(0, MODULE, szProto, 1) == 0 && !opt.PSMsgOnConnect) bEnablePopup = false; if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) { // cut message if needed wchar_t *copyText = nullptr; if (opt.PSMsgTruncate && (opt.PSMsgLen > 0) && smi.newstatusmsg && (mir_wstrlen(smi.newstatusmsg) > opt.PSMsgLen)) { wchar_t buff[MAX_TEXT_LEN + 3]; copyText = mir_wstrdup(smi.newstatusmsg); wcsncpy(buff, smi.newstatusmsg, opt.PSMsgLen); buff[opt.PSMsgLen] = 0; mir_wstrcat(buff, L"..."); replaceStrW(smi.newstatusmsg, buff); } wchar_t *str; if (smi.compare == COMPARE_DEL) { char protoname[MAX_PATH]; mir_snprintf(protoname, "%s_TPopupSMsgRemoved", szProto); DBVARIANT dbVar = { 0 }; if (db_get_ws(NULL, MODULE, protoname, &dbVar)) { str = GetStr(&smi, DEFAULT_POPUP_SMSGREMOVED); } else { str = GetStr(&smi, dbVar.ptszVal); db_free(&dbVar); } } else { char protoname[MAX_PATH]; mir_snprintf(protoname, "%s_TPopupSMsgChanged", szProto); DBVARIANT dbVar = { 0 }; if (db_get_ws(NULL, MODULE, protoname, &dbVar)) { str = GetStr(&smi, DEFAULT_POPUP_SMSGCHANGED); } else { str = GetStr(&smi, dbVar.ptszVal); db_free(&dbVar); } } ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, db_get_w(hContact, szProto, "Status", ID_STATUS_ONLINE)), ID_STATUS_STATUSMSG, str); mir_free(str); if (copyText) { mir_free(smi.newstatusmsg); smi.newstatusmsg = copyText; } } if (opt.BlinkIcon && opt.BlinkIcon_ForMsgs && !opt.TempDisabled) { HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, db_get_w(hContact, szProto, "Status", ID_STATUS_ONLINE)) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE); wchar_t str[256]; mir_snwprintf(str, TranslateT("%s changed status message to %s"), Clist_GetContactDisplayName(hContact), smi.newstatusmsg); BlinkIcon(hContact, hIcon, str); } if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) { if (smi.compare == COMPARE_DEL) PlayChangeSound(hContact, StatusListEx[ID_STATUS_SMSGREMOVED].lpzSkinSoundName); else PlayChangeSound(hContact, StatusListEx[ID_STATUS_SMSGCHANGED].lpzSkinSoundName); } BOOL bEnableLog = opt.SMsgLogToDB && db_get_b(hContact, MODULE, "EnableSMsgLogging", 1); if (bEnableLog && (!opt.SMsgLogToDB_WinOpen || CheckMsgWnd(hContact))) LogSMsgToDB(&smi, smi.compare == COMPARE_DEL ? templates.LogSMsgRemoved : templates.LogSMsgChanged); if (opt.SMsgLogToFile && db_get_b(hContact, MODULE, "EnableSMsgLogging", 1)) { wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN]; GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime)); GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate)); wchar_t *str; if (smi.compare == COMPARE_DEL) str = GetStr(&smi, templates.LogSMsgRemoved); else str = GetStr(&smi, templates.LogSMsgChanged); mir_snwprintf(stzText, L"%s, %s. %s %s\r\n", stzDate, stzTime, Clist_GetContactDisplayName(hContact), str); LogToFile(stzText); mir_free(str); } skip_notify: replaceStrW(smi.newstatusmsg, nullptr); replaceStrW(smi.oldstatusmsg, nullptr); return 1; }
int ContactStatusChanged(MCONTACT hContact, WORD oldStatus, WORD newStatus) { if (opt.LogToDB && (!opt.LogToDB_WinOpen || CheckMsgWnd(hContact))) { wchar_t stzStatusText[MAX_SECONDLINE] = { 0 }; GetStatusText(hContact, newStatus, oldStatus, stzStatusText); T2Utf blob(stzStatusText); DBEVENTINFO dbei = {}; dbei.cbBlob = (DWORD)mir_strlen(blob) + 1; dbei.pBlob = (PBYTE)blob; dbei.eventType = EVENTTYPE_STATUSCHANGE; dbei.flags = DBEF_READ | DBEF_UTF; dbei.timestamp = (DWORD)time(0); dbei.szModule = MODULE; MEVENT hDBEvent = db_event_add(hContact, &dbei); if (opt.LogToDB_WinOpen && opt.LogToDB_Remove) { DBEVENT *dbevent = (DBEVENT *)mir_alloc(sizeof(DBEVENT)); dbevent->hContact = hContact; dbevent->hDBEvent = hDBEvent; eventListStatus.insert(dbevent); } } bool bEnablePopup = true, bEnableSound = true; char *szProto = GetContactProto(hContact); int myStatus = Proto_GetStatus(szProto); if (!mir_strcmp(szProto, META_PROTO)) { //this contact is Meta MCONTACT hSubContact = db_mc_getMostOnline(hContact); char *szSubProto = GetContactProto(hSubContact); if (szSubProto == nullptr) return 0; if (newStatus == ID_STATUS_OFFLINE) { // read last online proto for metacontact if exists, // to avoid notifying when meta went offline but default contact's proto still online DBVARIANT dbv; if (!db_get_s(hContact, szProto, "LastOnline", &dbv)) { szSubProto = NEWSTR_ALLOCA(dbv.pszVal); db_free(&dbv); } } else db_set_s(hContact, szProto, "LastOnline", szSubProto); if (db_get_b(0, MODULE, szSubProto, 1) == 0) return 0; szProto = szSubProto; } else { if (myStatus == ID_STATUS_OFFLINE || db_get_b(0, MODULE, szProto, 1) == 0) return 0; } if (!opt.FromOffline || oldStatus != ID_STATUS_OFFLINE) { // Either it wasn't a change from Offline or we didn't enable that. char buff[8]; mir_snprintf(buff, "%d", newStatus); if (db_get_b(0, MODULE, buff, 1) == 0) return 0; // "Notify when a contact changes to one of..." is unchecked } if (SkipHiddenContact(hContact)) return 0; // check if that proto from which we received statuschange notification, isn't in autodisable list if (opt.AutoDisable) { char statusIDs[12], statusIDp[12]; mir_snprintf(statusIDs, "s%d", myStatus); mir_snprintf(statusIDp, "p%d", myStatus); bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : TRUE; bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : TRUE; } if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) { int wStatus = Proto_GetStatus(szProto); wchar_t str[MAX_SECONDLINE] = { 0 }; if (opt.ShowStatus) GetStatusText(hContact, newStatus, oldStatus, str); if (opt.ReadAwayMsg && wStatus != ID_STATUS_INVISIBLE && StatusHasAwayMessage(szProto, newStatus)) db_set_ws(hContact, MODULE, "LastPopupText", str); PLUGINDATA *pdp = (PLUGINDATA *)mir_calloc(sizeof(PLUGINDATA)); pdp->oldStatus = oldStatus; pdp->newStatus = newStatus; pdp->hAwayMsgHook = nullptr; pdp->hAwayMsgProcess = nullptr; ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, newStatus), newStatus, str, pdp); } if (opt.BlinkIcon && !opt.TempDisabled) { HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, newStatus) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE); wchar_t str[256]; mir_snwprintf(str, TranslateT("%s is now %s"), Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText); BlinkIcon(hContact, hIcon, str); } if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) { if (oldStatus == ID_STATUS_OFFLINE) PlayChangeSound(hContact, StatusListEx[ID_STATUS_FROMOFFLINE].lpzSkinSoundName); else PlayChangeSound(hContact, StatusList[Index(newStatus)].lpzSkinSoundName); } if (opt.LogToFile) { wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN]; GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime)); GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate)); mir_snwprintf(stzText, TranslateT("%s, %s. %s changed status to %s (was %s)\r\n"), stzDate, stzTime, Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText, StatusList[Index(oldStatus)].lpzStandardText); LogToFile(stzText); } return 0; }
int HookedNewEvent(WPARAM hContact, LPARAM lParam) { //are popups currently enabled? if (pluginOptions.bDisable) return 0; //get DBEVENTINFO without pBlob DBEVENTINFO dbe = { sizeof(dbe) }; db_event_get((HANDLE)lParam, &dbe); //do not show popups for sub-contacts if (hContact && db_mc_isSub(hContact)) return 0; //custom database event types if (ServiceExists(MS_DB_EVENT_GETTYPE)) { DBEVENTTYPEDESCR *pei = (DBEVENTTYPEDESCR*)CallService(MS_DB_EVENT_GETTYPE, (WPARAM)dbe.szModule, (LPARAM)dbe.eventType); // ignore events according to flags if (pei && 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) { // JK, only message event, do not influence others if (pluginOptions.bHideSend && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1) { PLUGIN_DATA *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)) PopupUpdate(hContact, (HANDLE)lParam); else PopupShow(&pluginOptions, hContact, (HANDLE)lParam, (UINT)dbe.eventType); return 0; }