From c572cfe386adaa71c2a0ee2f6620f5cc2b94bd21 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 24 Aug 2020 20:16:11 +0300 Subject: Chat API: - unused function CHAT_MANAGER::AddEvent removed and made local; - "Mute" parameter is added to any chat, turning short/long blinking mode; - code optimization --- src/mir_app/src/chat.h | 9 ++-- src/mir_app/src/chat_clist.cpp | 97 ----------------------------------- src/mir_app/src/chat_manager.cpp | 1 - src/mir_app/src/chat_svc.cpp | 108 +++++++++++++++++++++++++++++++++++++-- src/mir_app/src/chat_tools.cpp | 86 ++++++++++++++++++++++++++----- 5 files changed, 182 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h index 2ac72235f9..1fe2bff454 100644 --- a/src/mir_app/src/chat.h +++ b/src/mir_app/src/chat.h @@ -25,12 +25,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#define CHATMODE_NORMAL 0 +#define CHATMODE_MUTE 1 +#define CHATMODE_UNMUTE 2 + void Srmm_CreateToolbarIcons(HWND hwndDlg, int flags); void Srmm_ProcessToolbarHotkey(MCONTACT hContact, INT_PTR iButtonFrom, HWND hwndDlg); class CLogWindow : public CSrmmLogWindow {}; -extern HGENMENU hJoinMenuItem, hLeaveMenuItem; extern HPLUGIN g_pChatPlugin; extern GlobalLogSettingsBase *g_Settings; extern int g_cbSession, g_cbModuleInfo, g_iFontMode; @@ -84,16 +87,12 @@ void UM_SortKeys(SESSION_INFO *si); void UM_SortUser(SESSION_INFO *si); // clist.c -BOOL AddEvent(MCONTACT hContact, HICON hIcon, MEVENT hEvent, int type, wchar_t* fmt, ...); MCONTACT AddRoom(const char *pszModule, const wchar_t *pszRoom, const wchar_t *pszDisplayName, int iType); MCONTACT FindRoom(const char *pszModule, const wchar_t *pszRoom); BOOL SetAllOffline(BOOL bHide, const char *pszModule); BOOL SetOffline(MCONTACT hContact, BOOL bHide); int RoomDoubleclicked(WPARAM wParam,LPARAM lParam); -INT_PTR JoinChat(WPARAM wParam, LPARAM lParam); -INT_PTR LeaveChat(WPARAM wParam, LPARAM lParam); -int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); // options.c void ChatOptionsInit(WPARAM wParam); diff --git a/src/mir_app/src/chat_clist.cpp b/src/mir_app/src/chat_clist.cpp index 208df541f7..63bef304be 100644 --- a/src/mir_app/src/chat_clist.cpp +++ b/src/mir_app/src/chat_clist.cpp @@ -115,103 +115,6 @@ int RoomDoubleclicked(WPARAM hContact, LPARAM) return 1; } -static INT_PTR EventDoubleclicked(WPARAM,LPARAM lParam) -{ - return RoomDoubleclicked((WPARAM)((CLISTEVENT*)lParam)->hContact, 0); -} - -INT_PTR JoinChat(WPARAM hContact, LPARAM lParam) -{ - if (hContact) { - char *szProto = Proto_GetBaseAccountName(hContact); - if (szProto) { - if (db_get_w(hContact, szProto, "Status", 0) == ID_STATUS_OFFLINE) - CallProtoService(szProto, PS_JOINCHAT, hContact, lParam); - else - RoomDoubleclicked(hContact, 0); - } - } - - return 0; -} - -INT_PTR LeaveChat(WPARAM hContact, LPARAM lParam) -{ - if (hContact) { - char *szProto = Proto_GetBaseAccountName(hContact); - if (szProto) - CallProtoService(szProto, PS_LEAVECHAT, hContact, lParam); - } - return 0; -} - -int PrebuildContactMenu(WPARAM hContact, LPARAM) -{ - if (hContact == 0) - return 0; - - bool bEnabledJoin = false, bEnabledLeave = false; - char *szProto = Proto_GetBaseAccountName(hContact); - if (szProto) { - // display this menu item only for chats - if (db_get_b(hContact, szProto, "ChatRoom", 0)) { - // still hide it for offline protos - if (Proto_GetStatus(szProto) != ID_STATUS_OFFLINE) { - if (db_get_w(hContact, szProto, "Status", 0) == ID_STATUS_OFFLINE) { - if (ProtoServiceExists(szProto, PS_JOINCHAT)) { - bEnabledJoin = true; - Menu_ModifyItem(hJoinMenuItem, LPGENW("&Join chat")); - } - } - else { - bEnabledJoin = true; - Menu_ModifyItem(hJoinMenuItem, LPGENW("&Open/close chat window")); - } - } - bEnabledLeave = ProtoServiceExists(szProto, PS_LEAVECHAT) != 0; - } - } - - Menu_ShowItem(hJoinMenuItem, bEnabledJoin); - Menu_ShowItem(hLeaveMenuItem, bEnabledLeave); - return 0; -} - -BOOL AddEvent(MCONTACT hContact, HICON hIcon, MEVENT hEvent, int type, wchar_t* fmt, ...) -{ - wchar_t szBuf[4096]; - - if (!fmt || !fmt[0] || mir_wstrlen(fmt) > 2000) - return FALSE; - - va_list marker; - va_start(marker, fmt); - mir_vsnwprintf(szBuf, _countof(szBuf), fmt, marker); - va_end(marker); - - CLISTEVENT cle = {}; - cle.hContact = hContact; - cle.hDbEvent = hEvent; - cle.flags = type | CLEF_UNICODE; - cle.hIcon = hIcon; - cle.pszService = "GChat/DblClickEvent"; - cle.szTooltip.w = TranslateW(szBuf); - - if (!ServiceExists(cle.pszService)) - CreateServiceFunction(cle.pszService, &EventDoubleclicked); - - if (type) { - if (!g_clistApi.pfnGetEvent(hContact, 0)) - g_clistApi.pfnAddEvent(&cle); - } - else { - if (g_clistApi.pfnGetEvent(hContact, 0)) - g_clistApi.pfnRemoveEvent(hContact, GC_FAKE_EVENT); - g_clistApi.pfnAddEvent(&cle); - } - return TRUE; -} - MCONTACT FindRoom(const char *pszModule, const wchar_t *pszRoom) { for (auto &hContact : Contacts(pszModule)) { diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp index 8be8100efb..5479e45d45 100644 --- a/src/mir_app/src/chat_manager.cpp +++ b/src/mir_app/src/chat_manager.cpp @@ -897,7 +897,6 @@ static void ResetApi() g_chatApi.SetOffline = ::SetOffline; g_chatApi.SetAllOffline = ::SetAllOffline; - g_chatApi.AddEvent = ::AddEvent; g_chatApi.FindRoom = ::FindRoom; g_chatApi.DoRtfToTags = ::DoRtfToTags; diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp index b09d4740ee..1814ee284b 100644 --- a/src/mir_app/src/chat_svc.cpp +++ b/src/mir_app/src/chat_svc.cpp @@ -28,7 +28,6 @@ INT_PTR SvcGetChatManager(WPARAM, LPARAM); #include "resource.h" mir_cs csChat; -HGENMENU hJoinMenuItem, hLeaveMenuItem; MWindowList g_hWindowList; HANDLE hevSendEvent, hevBuildMenuEvent; @@ -726,6 +725,79 @@ EXTERN_C MIR_APP_DLL(void) Chat_UpdateOptions() ///////////////////////////////////////////////////////////////////////////////////////// // module initialization +static HGENMENU hJoinMenuItem, hLeaveMenuItem, hMuteRootMenuItem, hMute0MenuItem, hMute1MenuItem, hMute2MenuItem; + +static INT_PTR JoinChat(WPARAM hContact, LPARAM lParam) +{ + if (hContact) { + char *szProto = Proto_GetBaseAccountName(hContact); + if (szProto) { + if (db_get_w(hContact, szProto, "Status", 0) == ID_STATUS_OFFLINE) + CallProtoService(szProto, PS_JOINCHAT, hContact, lParam); + else + RoomDoubleclicked(hContact, 0); + } + } + + return 0; +} + +static INT_PTR LeaveChat(WPARAM hContact, LPARAM lParam) +{ + if (hContact) { + char *szProto = Proto_GetBaseAccountName(hContact); + if (szProto) + CallProtoService(szProto, PS_LEAVECHAT, hContact, lParam); + } + return 0; +} + +static INT_PTR MuteChat(WPARAM hContact, LPARAM param) +{ + db_set_b(hContact, "SRMM", "MuteMode", param); + return 0; +} + +static int PrebuildContactMenu(WPARAM hContact, LPARAM) +{ + if (hContact == 0) + return 0; + + int iMuteMode = db_get_b(hContact, "SRMM", "MuteMode", CHATMODE_NORMAL); + bool bEnabledJoin = false, bEnabledLeave = false, bIsChat = false; + char *szProto = Proto_GetBaseAccountName(hContact); + if (szProto) { + // display this menu item only for chats + if (db_get_b(hContact, szProto, "ChatRoom", 0)) { + bIsChat = true; + // still hide it for offline protos + if (Proto_GetStatus(szProto) != ID_STATUS_OFFLINE) { + if (db_get_w(hContact, szProto, "Status", 0) == ID_STATUS_OFFLINE) { + if (ProtoServiceExists(szProto, PS_JOINCHAT)) { + bEnabledJoin = true; + Menu_ModifyItem(hJoinMenuItem, LPGENW("&Join chat")); + } + } + else { + bEnabledJoin = true; + Menu_ModifyItem(hJoinMenuItem, LPGENW("&Open/close chat window")); + } + } + bEnabledLeave = ProtoServiceExists(szProto, PS_LEAVECHAT) != 0; + } + } + + Menu_ShowItem(hJoinMenuItem, bEnabledJoin); + Menu_ShowItem(hLeaveMenuItem, bEnabledLeave); + Menu_ShowItem(hMuteRootMenuItem, bIsChat); + if (bIsChat) { + Menu_ModifyItem(hMute0MenuItem, 0, INVALID_HANDLE_VALUE, (iMuteMode == CHATMODE_NORMAL) ? CMIF_CHECKED : 0); + Menu_ModifyItem(hMute1MenuItem, 0, INVALID_HANDLE_VALUE, (iMuteMode == CHATMODE_MUTE) ? CMIF_CHECKED : 0); + Menu_ModifyItem(hMute2MenuItem, 0, INVALID_HANDLE_VALUE, (iMuteMode == CHATMODE_UNMUTE) ? CMIF_CHECKED : 0); + } + return 0; +} + static int ModulesLoaded(WPARAM, LPARAM) { LoadChatIcons(); @@ -735,7 +807,7 @@ static int ModulesLoaded(WPARAM, LPARAM) CMenuItem mi(&g_plugin); SET_UID(mi, 0x2bb76d5, 0x740d, 0x4fd2, 0x8f, 0xee, 0x7c, 0xa4, 0x5a, 0x74, 0x65, 0xa6); - mi.position = -2000090001; + mi.position = -2000090002; mi.flags = CMIF_DEFAULT; mi.hIcolibItem = Skin_GetIconHandle(SKINICON_CHAT_JOIN); mi.name.a = LPGEN("&Join chat"); @@ -744,7 +816,7 @@ static int ModulesLoaded(WPARAM, LPARAM) CreateServiceFunction(mi.pszService, JoinChat); SET_UID(mi, 0x72b7440b, 0xd2db, 0x4e22, 0xa6, 0xb1, 0x2, 0xd0, 0x96, 0xee, 0xad, 0x88); - mi.position = -2000090000; + mi.position = -2000090001; mi.hIcolibItem = Skin_GetIconHandle(SKINICON_CHAT_LEAVE); mi.flags = CMIF_NOTOFFLINE; mi.name.a = LPGEN("&Leave chat"); @@ -752,6 +824,36 @@ static int ModulesLoaded(WPARAM, LPARAM) hLeaveMenuItem = Menu_AddContactMenuItem(&mi); CreateServiceFunction(mi.pszService, LeaveChat); + SET_UID(mi, 0x1c16b08e, 0x923, 0x4321, 0x9e, 0x67, 0x3d, 0x69, 0x87, 0x37, 0xd9, 0x4a); + mi.position = -2000090000; + mi.hIcolibItem = 0; + mi.flags = 0; + mi.name.a = LPGEN("&Mute chat"); + mi.pszService = 0; + hMuteRootMenuItem = Menu_AddContactMenuItem(&mi); + + mi.root = hMuteRootMenuItem; + mi.position = 1; + mi.hIcolibItem = 0; + mi.flags = CMIF_SYSTEM; + mi.name.a = LPGEN("Default"); + mi.pszService = "GChat/MuteChat"; + hMute0MenuItem = Menu_AddContactMenuItem(&mi); + CreateServiceFunction(mi.pszService, MuteChat); + Menu_ConfigureItem(hMute0MenuItem, MCI_OPT_EXECPARAM, INT_PTR(CHATMODE_NORMAL)); + + mi.position = 2; + mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_OFF); + mi.name.a = LPGEN("Mute"); + hMute1MenuItem = Menu_AddContactMenuItem(&mi); + Menu_ConfigureItem(hMute1MenuItem, MCI_OPT_EXECPARAM, INT_PTR(CHATMODE_MUTE)); + + mi.position = 3; + mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_ON); + mi.name.a = LPGEN("Unmute"); + hMute2MenuItem = Menu_AddContactMenuItem(&mi); + Menu_ConfigureItem(hMute2MenuItem, MCI_OPT_EXECPARAM, INT_PTR(CHATMODE_UNMUTE)); + g_chatApi.SetAllOffline(TRUE, nullptr); return 0; } diff --git a/src/mir_app/src/chat_tools.cpp b/src/mir_app/src/chat_tools.cpp index 335ab64cbc..bf31f299c5 100644 --- a/src/mir_app/src/chat_tools.cpp +++ b/src/mir_app/src/chat_tools.cpp @@ -97,51 +97,111 @@ wchar_t* RemoveFormatting(const wchar_t *pszWord) return szTemp; } +///////////////////////////////////////////////////////////////////////////////////////// + +static INT_PTR EventDoubleclicked(WPARAM, LPARAM lParam) +{ + return RoomDoubleclicked((WPARAM)((CLISTEVENT *)lParam)->hContact, 0); +} + +static void AddEvent(MCONTACT hContact, HICON hIcon, int type, const wchar_t *pwszText) +{ + if (mir_wstrlen(pwszText) == 0) + return; + + CLISTEVENT cle = {}; + cle.hContact = hContact; + cle.hDbEvent = GC_FAKE_EVENT; + cle.flags = type | CLEF_UNICODE; + cle.hIcon = hIcon; + cle.pszService = "GChat/DblClickEvent"; + cle.szTooltip.w = pwszText; + + if (!ServiceExists(cle.pszService)) + CreateServiceFunction(cle.pszService, &EventDoubleclicked); + + if (type) { + if (!g_clistApi.pfnGetEvent(hContact, 0)) + g_clistApi.pfnAddEvent(&cle); + } + else { + if (g_clistApi.pfnGetEvent(hContact, 0)) + g_clistApi.pfnRemoveEvent(hContact, GC_FAKE_EVENT); + g_clistApi.pfnAddEvent(&cle); + } +} + BOOL DoTrayIcon(SESSION_INFO *si, GCEVENT *gce) { + HICON hIcon; + CMStringW wszText; + int iMuteMode = db_get_b(si->hContact, "SRMM", "MuteMode", CHATMODE_NORMAL); + switch (iMuteMode) { + case CHATMODE_MUTE: iMuteMode = CLEF_ONLYAFEW; break; + case CHATMODE_UNMUTE: iMuteMode = 0; break; + default: + iMuteMode = (gce->iType & GC_EVENT_HIGHLIGHT) ? 0 : CLEF_ONLYAFEW; + } + switch (gce->iType) { case GC_EVENT_MESSAGE | GC_EVENT_HIGHLIGHT: case GC_EVENT_ACTION | GC_EVENT_HIGHLIGHT: - g_chatApi.AddEvent(si->hContact, Skin_LoadIcon(SKINICON_EVENT_MESSAGE), GC_FAKE_EVENT, 0, TranslateT("%s wants your attention in %s"), gce->pszNick.w, si->ptszName); + hIcon = Skin_LoadIcon(SKINICON_EVENT_MESSAGE); + wszText.Format(TranslateT("%s wants your attention in %s"), gce->pszNick.w, si->ptszName); break; case GC_EVENT_MESSAGE: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_MESSAGE], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s speaks in %s"), gce->pszNick.w, si->ptszName); + hIcon = g_chatApi.hIcons[ICON_MESSAGE]; + wszText.Format(TranslateT("%s speaks in %s"), gce->pszNick.w, si->ptszName); break; case GC_EVENT_ACTION: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_ACTION], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s speaks in %s"), gce->pszNick.w, si->ptszName); + hIcon = g_chatApi.hIcons[ICON_ACTION]; + wszText.Format(TranslateT("%s speaks in %s"), gce->pszNick.w, si->ptszName); break; case GC_EVENT_JOIN: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_JOIN], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s has joined %s"), gce->pszNick.w, si->ptszName); + hIcon = g_chatApi.hIcons[ICON_JOIN]; + wszText.Format(TranslateT("%s has joined %s"), gce->pszNick.w, si->ptszName); break; case GC_EVENT_PART: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_PART], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s has left %s"), gce->pszNick.w, si->ptszName); + hIcon = g_chatApi.hIcons[ICON_PART]; + wszText.Format(TranslateT("%s has left %s"), gce->pszNick.w, si->ptszName); break; case GC_EVENT_QUIT: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_QUIT], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s has disconnected"), gce->pszNick.w); + hIcon = g_chatApi.hIcons[ICON_QUIT]; + wszText.Format(TranslateT("%s has disconnected"), gce->pszNick.w); break; case GC_EVENT_NICK: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_NICK], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s is now known as %s"), gce->pszNick.w, gce->pszText.w); + hIcon = g_chatApi.hIcons[ICON_NICK]; + wszText.Format(TranslateT("%s is now known as %s"), gce->pszNick.w, gce->pszText.w); break; case GC_EVENT_KICK: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_KICK], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s kicked %s from %s"), gce->pszStatus.w, gce->pszNick.w, si->ptszName); + hIcon = g_chatApi.hIcons[ICON_KICK]; + wszText.Format(TranslateT("%s kicked %s from %s"), gce->pszStatus.w, gce->pszNick.w, si->ptszName); break; case GC_EVENT_NOTICE: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_NOTICE], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("Notice from %s"), gce->pszNick.w); + hIcon = g_chatApi.hIcons[ICON_NOTICE]; + wszText.Format(TranslateT("Notice from %s"), gce->pszNick.w); break; case GC_EVENT_TOPIC: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_TOPIC], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("Topic change in %s"), si->ptszName); + hIcon = g_chatApi.hIcons[ICON_TOPIC]; + wszText.Format(TranslateT("Topic change in %s"), si->ptszName); break; case GC_EVENT_INFORMATION: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_INFO], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("Information in %s"), si->ptszName); + hIcon = g_chatApi.hIcons[ICON_INFO]; + wszText.Format(TranslateT("Information in %s"), si->ptszName); break; case GC_EVENT_ADDSTATUS: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_ADDSTATUS], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s enables '%s' status for %s in %s"), gce->pszText.w, gce->pszStatus.w, gce->pszNick.w, si->ptszName); + hIcon = g_chatApi.hIcons[ICON_ADDSTATUS]; + wszText.Format(TranslateT("%s enables '%s' status for %s in %s"), gce->pszText.w, gce->pszStatus.w, gce->pszNick.w, si->ptszName); break; case GC_EVENT_REMOVESTATUS: - g_chatApi.AddEvent(si->hContact, g_chatApi.hIcons[ICON_REMSTATUS], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s disables '%s' status for %s in %s"), gce->pszText.w, gce->pszStatus.w, gce->pszNick.w, si->ptszName); + hIcon = g_chatApi.hIcons[ICON_REMSTATUS]; + wszText.Format(TranslateT("%s disables '%s' status for %s in %s"), gce->pszText.w, gce->pszStatus.w, gce->pszNick.w, si->ptszName); break; + default: + return FALSE; } + AddEvent(si->hContact, hIcon, iMuteMode, wszText); return TRUE; } -- cgit v1.2.3