summaryrefslogtreecommitdiff
path: root/plugins/Scriver/src/chat/manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Scriver/src/chat/manager.cpp')
-rw-r--r--plugins/Scriver/src/chat/manager.cpp1400
1 files changed, 1400 insertions, 0 deletions
diff --git a/plugins/Scriver/src/chat/manager.cpp b/plugins/Scriver/src/chat/manager.cpp
new file mode 100644
index 0000000000..9573c920fa
--- /dev/null
+++ b/plugins/Scriver/src/chat/manager.cpp
@@ -0,0 +1,1400 @@
+/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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 "../commonheaders.h"
+#include "chat.h"
+
+extern TCHAR* pszActiveWndID ;
+extern char* pszActiveWndModule ;
+extern struct MM_INTERFACE mmi ;
+
+extern struct GlobalMessageData *g_dat;
+
+void LoadModuleIcons(MODULEINFO * mi);
+
+#define WINDOWS_COMMANDS_MAX 30
+#define STATUSICONCOUNT 6
+
+SESSION_INFO* m_WndList = 0;
+TABLIST * g_TabList = 0;
+MODULEINFO *m_ModList = 0;
+
+void SetActiveSession(const TCHAR* pszID, const char* pszModule)
+{
+ SESSION_INFO* si = SM_FindSession(pszID, pszModule);
+ if ( si )
+ SetActiveSessionEx(si);
+}
+
+void SetActiveSessionEx(SESSION_INFO* si)
+{
+ if ( si ) {
+ replaceStr( &pszActiveWndID, si->ptszID );
+ replaceStrA( &pszActiveWndModule, si->pszModule );
+} }
+
+SESSION_INFO* GetActiveSession( void )
+{
+ SESSION_INFO* si = SM_FindSession( pszActiveWndID, pszActiveWndModule );
+ if ( si )
+ return si;
+
+ return m_WndList;
+}
+
+//---------------------------------------------------
+// Session Manager functions
+//
+// Keeps track of all sessions and its windows
+//---------------------------------------------------
+
+SESSION_INFO* SM_AddSession( const TCHAR* pszID, const char* pszModule)
+{
+ if ( !pszID || !pszModule )
+ return NULL;
+
+ if ( !SM_FindSession(pszID, pszModule)) {
+ SESSION_INFO*node = (SESSION_INFO*) mir_alloc(sizeof(SESSION_INFO));
+ ZeroMemory(node, sizeof(SESSION_INFO));
+ node->ptszID = mir_tstrdup( pszID );
+ node->pszModule = mir_strdup( pszModule );
+ node->windowData.flags = CWDF_RTF_INPUT;
+
+ if (m_WndList == NULL) { // list is empty
+ m_WndList = node;
+ node->next = NULL;
+ }
+ else {
+ node->next = m_WndList;
+ m_WndList = node;
+ }
+ return node;
+ }
+ return NULL;
+}
+
+int SM_RemoveSession(const TCHAR* pszID, const char* pszModule, BOOL removeContact)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while (pTemp != NULL)
+ {
+ if (((!pszID && pTemp->iType != GCW_SERVER) || !lstrcmpi(pTemp->ptszID,pszID)) && !lstrcmpiA(pTemp->pszModule,pszModule)) // match
+ {
+ DWORD dw = pTemp->dwItemData;
+
+ if (pTemp->hWnd )
+ SendMessage(pTemp->hWnd, GC_EVENT_CONTROL+WM_USER+500, SESSION_TERMINATE, 0);
+
+ DoEventHook(pTemp->ptszID, pTemp->pszModule, GC_SESSION_TERMINATE, NULL, NULL, (DWORD)pTemp->dwItemData);
+
+ if (pLast == NULL)
+ m_WndList = pTemp->next;
+ else
+ pLast->next = pTemp->next;
+
+ UM_RemoveAll(&pTemp->pUsers);
+ TM_RemoveAll(&pTemp->pStatuses);
+ LM_RemoveAll(&pTemp->pLog, &pTemp->pLogEnd);
+ pTemp->iStatusCount = 0;
+ pTemp->nUsersInNicklist = 0;
+
+ if (pTemp->windowData.hContact)
+ {
+ CList_SetOffline(pTemp->windowData.hContact, pTemp->iType == GCW_CHATROOM?TRUE:FALSE);
+/* if (pTemp->iType != GCW_SERVER)
+ DBWriteContactSettingByte(pTemp->windowData.hContact, "CList", "Hidden", 1);*/
+ }
+ DBWriteContactSettingString(pTemp->windowData.hContact, pTemp->pszModule , "Topic", "");
+ DBWriteContactSettingString(pTemp->windowData.hContact, pTemp->pszModule, "StatusBar", "");
+ DBDeleteContactSetting(pTemp->windowData.hContact, "CList", "StatusMsg");
+
+ if (removeContact)
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)pTemp->windowData.hContact, 0);
+
+ mir_free( pTemp->pszModule );
+ mir_free( pTemp->ptszID );
+ mir_free( pTemp->ptszName );
+ mir_free( pTemp->ptszStatusbarText );
+ mir_free( pTemp->ptszTopic );
+ mir_free( pTemp->pszHeader );
+ mir_free( pTemp->pszID );
+ mir_free( pTemp->pszName );
+
+ // delete commands
+ tcmdlist_free(pTemp->windowData.cmdList);
+ mir_free(pTemp);
+ if (pszID)
+ return (int)dw;
+ if (pLast)
+ pTemp = pLast->next;
+ else
+ pTemp = m_WndList;
+ }
+ else
+ {
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ }
+ return FALSE;
+}
+
+SESSION_INFO* SM_FindSession(const TCHAR* pszID, const char* pszModule)
+{
+ SESSION_INFO *pTemp = m_WndList;
+
+ if ( !pszID || !pszModule )
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA(pTemp->pszModule,pszModule))
+ return pTemp;
+
+ pTemp = pTemp->next;
+ }
+ return NULL;
+}
+
+HWND SM_FindWindowByContact(HANDLE hContact)
+{
+ SESSION_INFO *pTemp = m_WndList;
+
+ while ( pTemp != NULL ) {
+ if ( pTemp->windowData.hContact == hContact)
+ return pTemp->hWnd;
+
+ pTemp = pTemp->next;
+ }
+ return NULL;
+}
+
+BOOL SM_SetOffline(const TCHAR* pszID, const char* pszModule)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while (pTemp != NULL)
+ {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA(pTemp->pszModule,pszModule))
+ {
+ UM_RemoveAll(&pTemp->pUsers);
+ pTemp->nUsersInNicklist = 0;
+ if (pTemp->iType != GCW_SERVER)
+ pTemp->bInitDone = FALSE;
+
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+BOOL SM_SetStatusEx( const TCHAR* pszID, const char* pszModule, const TCHAR* pszText, int flags )
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA(pTemp->pszModule,pszModule)) {
+ UM_SetStatusEx(pTemp->pUsers, pszText, flags);
+ if (pTemp->hWnd)
+ RedrawWindow(GetDlgItem(pTemp->hWnd, IDC_CHAT_LIST), NULL, NULL, RDW_INVALIDATE);
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+char SM_GetStatusIndicator(SESSION_INFO* si, USERINFO * ui)
+{
+ STATUSINFO * ti;
+ if (!ui || !si)
+ return '\0';
+
+ ti = TM_FindStatus(si->pStatuses, TM_WordToString(si->pStatuses, ui->Status));
+ if (ti)
+ {
+ if ((INT_PTR)ti->hIcon < STATUSICONCOUNT)
+ {
+ INT_PTR id = si->iStatusCount - (INT_PTR)ti->hIcon - 1;
+ if (id == 0)
+ return '\0';
+ if (id == 1)
+ return '+';
+ if (id == 2)
+ return '%';
+ if (id == 3)
+ return '@';
+ if (id == 4)
+ return '!';
+ if (id == 5)
+ return '*';
+ }
+ else
+ return '\0';
+ }
+ return '\0';
+}
+
+HICON SM_GetStatusIcon(SESSION_INFO* si, USERINFO * ui)
+{
+ STATUSINFO * ti;
+ if (!ui || !si)
+ return NULL;
+
+ ti = TM_FindStatus(si->pStatuses, TM_WordToString(si->pStatuses, ui->Status));
+ if (ti)
+ {
+ if ((INT_PTR)ti->hIcon < STATUSICONCOUNT)
+ {
+ INT_PTR id = si->iStatusCount - (INT_PTR)ti->hIcon - 1;
+ char name[128];
+ sprintf(name, "chat_status%d", id);
+ return GetCachedIcon(name);
+ }
+ else
+ return ti->hIcon;
+ }
+ return GetCachedIcon("chat_status0");
+}
+
+BOOL SM_AddEventToAllMatchingUID(GCEVENT * gce)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+ int bManyFix = 0;
+
+ while (pTemp != NULL) {
+ if ( !lstrcmpiA( pTemp->pszModule, gce->pDest->pszModule )) {
+ if ( UM_FindUser( pTemp->pUsers, gce->ptszUID )) {
+ if ( pTemp->bInitDone ) {
+ if ( SM_AddEvent(pTemp->ptszID, pTemp->pszModule, gce, FALSE ) && pTemp->hWnd && pTemp->bInitDone) {
+ SendMessage(pTemp->hWnd, GC_ADDLOG, 0, 0);
+ }
+ else if (pTemp->hWnd && pTemp->bInitDone) {
+ SendMessage(pTemp->hWnd, GC_REDRAWLOG2, 0, 0);
+ }
+ DoSoundsFlashPopupTrayStuff(pTemp, gce, FALSE, bManyFix);
+ bManyFix ++;
+ if ((gce->dwFlags & GCEF_ADDTOLOG) && g_Settings.LoggingEnabled)
+ LogToFile(pTemp, gce);
+ } } }
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return 0;
+}
+
+BOOL SM_AddEvent(const TCHAR* pszID, const char* pszModule, GCEVENT * gce, BOOL bIsHighlighted)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszID || !pszModule)
+ return TRUE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA(pTemp->pszModule,pszModule)) {
+ LOGINFO * li = LM_AddEvent(&pTemp->pLog, &pTemp->pLogEnd);
+ pTemp->iEventCount += 1;
+
+ li->iType = gce->pDest->iType;
+ li->ptszNick = mir_tstrdup( gce->ptszNick );
+ li->ptszText = mir_tstrdup( gce->ptszText );
+ li->ptszStatus = mir_tstrdup( gce->ptszStatus );
+ li->ptszUserInfo = mir_tstrdup( gce->ptszUserInfo );
+
+ li->bIsMe = gce->bIsMe;
+ li->time = gce->time;
+ li->bIsHighlighted = bIsHighlighted;
+
+ if (g_Settings.iEventLimit > 0 && pTemp->iEventCount > g_Settings.iEventLimit + 20) {
+ LM_TrimLog(&pTemp->pLog, &pTemp->pLogEnd, pTemp->iEventCount - g_Settings.iEventLimit);
+ pTemp->iEventCount = g_Settings.iEventLimit;
+ return FALSE;
+ }
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+USERINFO * SM_AddUser( SESSION_INFO * si, const TCHAR* pszUID, const TCHAR* pszNick, WORD wStatus)
+{
+ USERINFO * p = UM_AddUser( si->pStatuses, &si->pUsers, pszUID, pszNick, wStatus);
+ si->nUsersInNicklist++;
+ return p;
+}
+
+BOOL SM_MoveUser(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID)
+{
+ SESSION_INFO *pTemp = m_WndList;
+
+ if (!pszID || !pszModule || !pszUID)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ UM_SortUser( &pTemp->pUsers, pszUID );
+ return TRUE;
+ }
+ pTemp = pTemp->next;
+ }
+
+ return FALSE;
+}
+
+BOOL SM_RemoveUser(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule || !pszUID)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ DWORD dw;
+ USERINFO * ui = UM_FindUser(pTemp->pUsers, pszUID);
+ if ( ui ) {
+ pTemp->nUsersInNicklist--;
+
+ dw = UM_RemoveUser(&pTemp->pUsers, pszUID);
+
+ if (pTemp->hWnd)
+ SendMessage(pTemp->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+
+ if (pszID)
+ return TRUE;
+ } }
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return 0;
+}
+
+USERINFO * SM_GetUserFromIndex(const TCHAR* pszID, const char* pszModule, int index)
+{
+ SESSION_INFO *pTemp = m_WndList;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule ))
+ return UM_FindUserFromIndex( pTemp->pUsers, index );
+ pTemp = pTemp->next;
+ }
+
+ return NULL;
+}
+
+
+STATUSINFO * SM_AddStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszStatus)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszID || !pszModule )
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ STATUSINFO* ti = TM_AddStatus( &pTemp->pStatuses, pszStatus, &pTemp->iStatusCount );
+ if ( ti )
+ pTemp->iStatusCount++;
+ return ti;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return 0;
+}
+
+BOOL SM_GiveStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszStatus)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if ( !pszID || !pszModule )
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO * ui = UM_GiveStatus(pTemp->pUsers, pszUID, TM_StringToWord(pTemp->pStatuses, pszStatus));
+ if (ui) {
+ SM_MoveUser( pTemp->ptszID, pTemp->pszModule, ui->pszUID );
+ if ( pTemp->hWnd )
+ SendMessage(pTemp->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+ }
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return FALSE;
+}
+
+BOOL SM_SetContactStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, WORD wStatus)
+{
+ SESSION_INFO* pTemp = m_WndList, *pLast = NULL;
+
+ if ( !pszID || !pszModule )
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO * ui = UM_SetContactStatus(pTemp->pUsers, pszUID, wStatus);
+ if (ui) {
+ SM_MoveUser( pTemp->ptszID, pTemp->pszModule, ui->pszUID );
+ if ( pTemp->hWnd )
+ SendMessage(pTemp->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+ }
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return FALSE;
+}
+
+BOOL SM_TakeStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszStatus)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszID || !pszModule )
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO* ui = UM_TakeStatus(pTemp->pUsers, pszUID, TM_StringToWord(pTemp->pStatuses, pszStatus));
+ if ( ui ) {
+ SM_MoveUser(pTemp->ptszID, pTemp->pszModule, ui->pszUID);
+ if ( pTemp->hWnd )
+ SendMessage(pTemp->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+ }
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return FALSE;
+}
+LRESULT SM_SendMessage(const TCHAR* pszID, const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ while ( pTemp && pszModule ) {
+ if (( !pszID ||!lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ if ( pTemp->hWnd ) {
+ LRESULT i = SendMessage(pTemp->hWnd, msg, wParam, lParam);
+ if ( pszID )
+ return i;
+ }
+ if ( pszID )
+ return 0;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+BOOL SM_PostMessage(const TCHAR* pszID, const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszID || !pszModule)
+ return 0;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ if ( pTemp->hWnd )
+ return PostMessage(pTemp->hWnd, msg, wParam, lParam);
+
+ return FALSE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return FALSE;
+}
+
+BOOL SM_BroadcastMessage(const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAsync)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ while (pTemp != NULL)
+ {
+ if (!pszModule || !lstrcmpiA(pTemp->pszModule, pszModule))
+ {
+ if (pTemp->hWnd)
+ {
+ if (bAsync)
+ PostMessage(pTemp->hWnd, msg, wParam, lParam);
+ else
+ SendMessage(pTemp->hWnd, msg, wParam, lParam);
+ }
+
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+BOOL SM_SetStatus(const TCHAR* pszID, const char* pszModule, int wStatus)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ pTemp->wStatus = wStatus;
+
+ if ( pTemp->windowData.hContact ) {
+ if ( pTemp->iType != GCW_SERVER && wStatus != ID_STATUS_OFFLINE )
+ DBDeleteContactSetting(pTemp->windowData.hContact, "CList", "Hidden");
+
+ DBWriteContactSettingWord(pTemp->windowData.hContact, pTemp->pszModule, "Status", (WORD)wStatus);
+ }
+
+ PostMessage(pTemp->hWnd, GC_FIXTABICONS, 0, 0);
+
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+BOOL SM_SendUserMessage(const TCHAR* pszID, const char* pszModule, const TCHAR* pszText)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if ( !pszModule || !pszText )
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ if ( pTemp->iType == GCW_CHATROOM )
+ DoEventHook( pTemp->ptszID, pTemp->pszModule, GC_USER_MESSAGE, NULL, pszText, (LPARAM)NULL);
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+
+BOOL SM_ChangeUID(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszNewUID)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO* ui = UM_FindUser( pTemp->pUsers, pszUID );
+ if ( ui )
+ replaceStr( &ui->pszUID, pszNewUID );
+
+ if ( pszID )
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+
+BOOL SM_ChangeNick(const TCHAR* pszID, const char* pszModule, GCEVENT * gce)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO* ui = UM_FindUser(pTemp->pUsers, gce->ptszUID );
+ if ( ui ) {
+ replaceStr( &ui->pszNick, gce->ptszText);
+ SM_MoveUser( pTemp->ptszID, pTemp->pszModule, ui->pszUID );
+ if ( pTemp->hWnd )
+ SendMessage( pTemp->hWnd, GC_UPDATENICKLIST, 0, 0 );
+ }
+
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+BOOL SM_RemoveAll (void)
+{
+ while (m_WndList)
+ {
+ SESSION_INFO*pLast = m_WndList->next;
+
+ if (m_WndList->hWnd)
+ SendMessage(m_WndList->hWnd, GC_EVENT_CONTROL+WM_USER+500, SESSION_TERMINATE, 0);
+ DoEventHook(m_WndList->ptszID, m_WndList->pszModule, GC_SESSION_TERMINATE, NULL, NULL, (DWORD)m_WndList->dwItemData);
+ if (m_WndList->windowData.hContact)
+ CList_SetOffline(m_WndList->windowData.hContact, m_WndList->iType == GCW_CHATROOM?TRUE:FALSE);
+ DBWriteContactSettingString(m_WndList->windowData.hContact, m_WndList->pszModule , "Topic", "");
+ DBDeleteContactSetting(m_WndList->windowData.hContact, "CList", "StatusMsg");
+ DBWriteContactSettingString(m_WndList->windowData.hContact, m_WndList->pszModule, "StatusBar", "");
+
+ UM_RemoveAll(&m_WndList->pUsers);
+ TM_RemoveAll(&m_WndList->pStatuses);
+ LM_RemoveAll(&m_WndList->pLog, &m_WndList->pLogEnd);
+ m_WndList->iStatusCount = 0;
+ m_WndList->nUsersInNicklist = 0;
+
+ mir_free( m_WndList->pszModule );
+ mir_free( m_WndList->ptszID );
+ mir_free( m_WndList->ptszName );
+ mir_free( m_WndList->ptszStatusbarText );
+ mir_free( m_WndList->ptszTopic );
+ mir_free( m_WndList->pszHeader);
+ tcmdlist_free(m_WndList->windowData.cmdList);
+ mir_free(m_WndList);
+ m_WndList = pLast;
+ }
+ m_WndList = NULL;
+ return TRUE;
+}
+
+int SM_GetCount(const char* pszModule)
+{
+ SESSION_INFO* pTemp = m_WndList;
+ int count = 0;
+
+ while (pTemp != NULL)
+ {
+ if (!lstrcmpiA(pszModule, pTemp->pszModule))
+ count++;
+
+ pTemp = pTemp->next;
+ }
+ return count;
+}
+
+SESSION_INFO* SM_FindSessionByIndex(const char* pszModule, int iItem)
+{
+ SESSION_INFO* pTemp = m_WndList;
+ int count = 0;
+ while (pTemp != NULL)
+ {
+ if (!lstrcmpiA(pszModule, pTemp->pszModule))
+ {
+ if (iItem ==count)
+ return pTemp;
+ else
+ count++;
+ }
+
+ pTemp = pTemp->next;
+ }
+ return NULL;
+
+}
+
+char* SM_GetUsers(SESSION_INFO* si)
+{
+ SESSION_INFO* pTemp = m_WndList;
+ USERINFO* utemp = NULL;
+ char* p = NULL;
+ int alloced = 0;
+
+ if ( si == NULL )
+ return NULL;
+
+ while (pTemp != NULL) {
+ if ( si == pTemp ) {
+ if (( utemp = pTemp->pUsers ) == NULL )
+ return NULL;
+
+ break;
+ }
+ pTemp = pTemp->next;
+ }
+
+ do {
+ int pLen = lstrlenA(p), nameLen = lstrlen(utemp->pszUID);
+ if ( pLen + nameLen + 2 > alloced )
+ p = (char *)mir_realloc( p, alloced += 4096 );
+
+ WideCharToMultiByte( CP_ACP, 0, utemp->pszUID, -1, p + pLen, nameLen+1, 0, 0 );
+
+ lstrcpyA( p + pLen + nameLen, " " );
+ utemp = utemp->next;
+ }
+ while ( utemp != NULL );
+ return p;
+}
+
+
+SESSION_INFO* SM_FindSessionAutoComplete(const char* pszModule, SESSION_INFO* currSession, SESSION_INFO* prevSession, const TCHAR* pszOriginal, const TCHAR* pszCurrent)
+{
+ SESSION_INFO* pResult = NULL;
+ if (prevSession == NULL && my_strstri( currSession->ptszName, pszOriginal) == currSession->ptszName) {
+ pResult = currSession;
+ } else {
+ TCHAR* pszName = NULL;
+ SESSION_INFO* pTemp = m_WndList;
+ if (currSession == prevSession) {
+ pszCurrent = pszOriginal;
+ }
+ while (pTemp != NULL) {
+ if (pTemp != currSession && !lstrcmpiA(pszModule, pTemp->pszModule)) {
+ if ( my_strstri( pTemp->ptszName, pszOriginal) == pTemp->ptszName ) {
+ if ( prevSession != pTemp && lstrcmpi( pTemp->ptszName, pszCurrent ) > 0 && ( !pszName || lstrcmpi( pTemp->ptszName, pszName ) < 0)) {
+ pResult = pTemp;
+ pszName = pTemp->ptszName;
+ }
+ }
+ }
+ pTemp = pTemp->next;
+ }
+ }
+ return pResult;
+
+}
+
+
+//---------------------------------------------------
+// Module Manager functions
+//
+// Necessary to keep track of all modules
+// that has registered with the plugin
+//---------------------------------------------------
+
+MODULEINFO* MM_AddModule(const char* pszModule)
+{
+ if (!pszModule)
+ return NULL;
+ if (!MM_FindModule(pszModule))
+ {
+ MODULEINFO *node = (MODULEINFO*) mir_calloc(sizeof(MODULEINFO));
+
+ node->pszModule = mir_strdup(pszModule);
+
+ if (m_ModList == NULL) // list is empty
+ {
+ m_ModList = node;
+ }
+ else
+ {
+ node->next = m_ModList;
+ m_ModList = node;
+ }
+ return node;
+ }
+ return FALSE;
+}
+
+void MM_IconsChanged(void)
+{
+ MODULEINFO *pTemp = m_ModList;
+
+ while (pTemp != NULL)
+ {
+ if (pTemp->hOnlineTalkIcon)
+ DestroyIcon(pTemp->hOnlineTalkIcon);
+ if (pTemp->hOfflineTalkIcon)
+ DestroyIcon(pTemp->hOfflineTalkIcon);
+
+ LoadModuleIcons(pTemp);
+ pTemp = pTemp->next;
+ }
+ return;
+}
+void MM_FontsChanged(void)
+{
+ SESSION_INFO* pTemp = m_WndList;
+ SetIndentSize();
+ while (pTemp != NULL)
+ {
+ pTemp->pszHeader = Log_CreateRtfHeader(MM_FindModule(pTemp->pszModule), pTemp);
+ pTemp = pTemp->next;
+ }
+ return;
+}
+MODULEINFO* MM_FindModule(const char* pszModule)
+{
+ MODULEINFO *pTemp = m_ModList, *pLast = NULL;
+
+ if (!pszModule)
+ return NULL;
+
+ while (pTemp != NULL) {
+ if (lstrcmpiA(pTemp->pszModule,pszModule) == 0)
+ return pTemp;
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+// stupid thing..
+void MM_FixColors()
+{
+ MODULEINFO *pTemp = m_ModList;
+
+ while (pTemp != NULL)
+ {
+ CheckColorsInModule(pTemp->pszModule);
+ pTemp = pTemp->next;
+ }
+ return;
+}
+
+BOOL MM_RemoveAll (void)
+{
+ while (m_ModList != NULL)
+ {
+ MODULEINFO *pLast = m_ModList->next;
+ mir_free(m_ModList->pszModule);
+ mir_free(m_ModList->ptszModDispName);
+ mir_free(m_ModList->crColors);
+
+ if (m_ModList->hOnlineTalkIcon)
+ DestroyIcon(m_ModList->hOnlineTalkIcon);
+ if (m_ModList->hOfflineTalkIcon)
+ DestroyIcon(m_ModList->hOfflineTalkIcon);
+
+ mir_free(m_ModList);
+ m_ModList = pLast;
+ }
+ m_ModList = NULL;
+ return TRUE;
+}
+
+//---------------------------------------------------
+// Status manager functions
+//
+// Necessary to keep track of what user statuses
+// per window nicklist that is available
+//---------------------------------------------------
+
+STATUSINFO * TM_AddStatus(STATUSINFO** ppStatusList, const TCHAR* pszStatus, int* iCount)
+{
+ if (!ppStatusList || !pszStatus)
+ return NULL;
+
+ if ( !TM_FindStatus(*ppStatusList, pszStatus)) {
+ STATUSINFO *node = (STATUSINFO*) mir_alloc(sizeof(STATUSINFO));
+ ZeroMemory(node, sizeof(STATUSINFO));
+ replaceStr( &node->pszGroup, pszStatus );
+ node->hIcon = (HICON)(*iCount);
+ while ((INT_PTR)node->hIcon > STATUSICONCOUNT - 1)
+ node->hIcon--;
+
+ if (*ppStatusList == NULL) // list is empty
+ {
+ node->Status = 1;
+ *ppStatusList = node;
+ node->next = NULL;
+ }
+ else
+ {
+ node->Status = ppStatusList[0]->Status*2;
+ node->next = *ppStatusList;
+ *ppStatusList = node;
+ }
+ return node;
+
+ }
+ return FALSE;
+}
+
+STATUSINFO * TM_FindStatus(STATUSINFO* pStatusList, const TCHAR* pszStatus)
+{
+ STATUSINFO *pTemp = pStatusList, *pLast = NULL;
+
+ if (!pStatusList || !pszStatus)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( lstrcmpi(pTemp->pszGroup, pszStatus) == 0 )
+ return pTemp;
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+WORD TM_StringToWord(STATUSINFO* pStatusList, const TCHAR* pszStatus)
+{
+ STATUSINFO *pTemp = pStatusList, *pLast = NULL;
+
+ if (!pStatusList || !pszStatus)
+ return 0;
+
+ while (pTemp != NULL) {
+ if ( lstrcmpi( pTemp->pszGroup, pszStatus ) == 0 )
+ return pTemp->Status;
+
+ if ( pTemp->next == NULL )
+ return pStatusList->Status;
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+TCHAR* TM_WordToString(STATUSINFO* pStatusList, WORD Status)
+{
+ STATUSINFO *pTemp = pStatusList, *pLast = NULL;
+
+ if (!pStatusList)
+ return NULL;
+
+ while (pTemp != NULL) {
+ if (pTemp->Status&Status) {
+ Status -= pTemp->Status;
+ if (Status == 0)
+ return pTemp->pszGroup;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+BOOL TM_RemoveAll (STATUSINFO** ppStatusList)
+{
+
+ if (!ppStatusList)
+ return FALSE;
+
+ while (*ppStatusList != NULL)
+ {
+ STATUSINFO *pLast = ppStatusList[0]->next;
+ mir_free(ppStatusList[0]->pszGroup);
+ if ((INT_PTR)ppStatusList[0]->hIcon > 10)
+ DestroyIcon(ppStatusList[0]->hIcon);
+ mir_free(*ppStatusList);
+ *ppStatusList = pLast;
+ }
+ *ppStatusList = NULL;
+ return TRUE;
+}
+
+//---------------------------------------------------
+// User manager functions
+//
+// Necessary to keep track of the users
+// in a window nicklist
+//---------------------------------------------------
+
+
+static int UM_CompareItem(USERINFO * u1, const TCHAR* pszNick, WORD wStatus)
+{
+ int i;
+
+ WORD dw1 = u1->Status;
+ WORD dw2 = wStatus;
+
+ for (i=0; i<8; i++ )
+ {
+ if (( dw1 & 1 ) && !( dw2 & 1 ))
+ return -1;
+ if (( dw2 & 1 ) && !( dw1 & 1 ))
+ return 1;
+ if (( dw1 & 1 ) && ( dw2 & 1 ))
+ return lstrcmp( u1->pszNick, pszNick );
+
+ dw1 = dw1 >> 1;
+ dw2 = dw2 >> 1;
+ }
+ return lstrcmp( u1->pszNick, pszNick );
+
+}
+
+USERINFO * UM_SortUser(USERINFO** ppUserList, const TCHAR* pszUID)
+{
+ USERINFO * pTemp = *ppUserList, *pLast = NULL;
+ USERINFO * node = NULL;
+
+ if (!pTemp || !pszUID)
+ return NULL;
+
+ while(pTemp && lstrcmpi( pTemp->pszUID, pszUID)) {
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ if ( pTemp ) {
+ node = pTemp;
+ if (pLast)
+ pLast->next = pTemp->next;
+ else
+ *ppUserList = pTemp->next;
+ pTemp = *ppUserList;
+
+ pLast = NULL;
+
+ while ( pTemp && UM_CompareItem(pTemp, node->pszNick, node->Status ) <= 0) {
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ if (*ppUserList == NULL) { // list is empty
+ *ppUserList = node;
+ node->next = NULL;
+ }
+ else {
+ if ( pLast ) {
+ node->next = pTemp;
+ pLast->next = node;
+ }
+ else {
+ node->next = *ppUserList;
+ *ppUserList = node;
+ } }
+
+ return node;
+ }
+ return NULL;
+}
+
+USERINFO* UM_AddUser(STATUSINFO* pStatusList, USERINFO** ppUserList, const TCHAR* pszUID, const TCHAR* pszNick, WORD wStatus)
+{
+ USERINFO * pTemp = *ppUserList, *pLast = NULL;
+
+ if (!pStatusList || !ppUserList || !ppUserList)
+ return NULL;
+
+ while(pTemp && UM_CompareItem(pTemp, pszNick, wStatus) <= 0)
+ {
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ // if (!UM_FindUser(*ppUserList, pszUI, wStatus)
+ {
+ USERINFO *node = (USERINFO*) mir_alloc(sizeof(USERINFO));
+ ZeroMemory(node, sizeof(USERINFO));
+ replaceStr( &node->pszUID, pszUID );
+
+ if (*ppUserList == NULL) { // list is empty
+ *ppUserList = node;
+ node->next = NULL;
+ }
+ else {
+ if ( pLast ) {
+ node->next = pTemp;
+ pLast->next = node;
+ }
+ else {
+ node->next = *ppUserList;
+ *ppUserList = node;
+ } }
+
+ return node;
+ }
+ return NULL;
+}
+
+USERINFO* UM_FindUser(USERINFO* pUserList, const TCHAR* pszUID)
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+
+ if (!pUserList || !pszUID)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->pszUID, pszUID ))
+ return pTemp;
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+USERINFO* UM_FindUserFromIndex(USERINFO* pUserList, int index)
+{
+ int i = 0;
+ USERINFO *pTemp = pUserList;
+
+ if (!pUserList)
+ return NULL;
+
+ while (pTemp != NULL)
+ {
+ if (i == index)
+ {
+ return pTemp;
+ }
+ pTemp = pTemp->next;
+ i++;
+ }
+ return NULL;
+}
+
+USERINFO* UM_GiveStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status)
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+
+ if (!pUserList || !pszUID)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->pszUID, pszUID )) {
+ pTemp->Status |= status;
+ return pTemp;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+USERINFO* UM_SetContactStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status)
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+
+ if (!pUserList || !pszUID)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->pszUID, pszUID )) {
+ pTemp->ContactStatus = status;
+ return pTemp;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+BOOL UM_SetStatusEx(USERINFO* pUserList, const TCHAR* pszText, int flags )
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+ int bOnlyMe = ( flags & GC_SSE_ONLYLISTED ) != 0, bSetStatus = ( flags & GC_SSE_ONLINE ) != 0;
+ char cDelimiter = ( flags & GC_SSE_TABDELIMITED ) ? '\t' : ' ';
+
+ while (pTemp != NULL)
+ {
+ if ( !bOnlyMe )
+ pTemp->iStatusEx = 0;
+
+ if ( pszText != NULL ) {
+ TCHAR* s = (TCHAR *)_tcsstr( pszText, pTemp->pszUID );
+ if ( s ) {
+ pTemp->iStatusEx = 0;
+ if ( s == pszText || s[-1] == cDelimiter ) {
+ int len = lstrlen( pTemp->pszUID );
+ if ( s[len] == cDelimiter || s[len] == '\0' )
+ pTemp->iStatusEx = ( !bOnlyMe || bSetStatus ) ? 1 : 0;
+ } } }
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+USERINFO* UM_TakeStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status)
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+
+ if (!pUserList || !pszUID)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->pszUID, pszUID )) {
+ pTemp->Status &= ~status;
+ return pTemp;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+TCHAR* UM_FindUserAutoComplete(USERINFO* pUserList, const TCHAR* pszOriginal, const TCHAR* pszCurrent)
+{
+ TCHAR* pszName = NULL;
+ USERINFO *pTemp = pUserList;
+
+ if (!pUserList || !pszOriginal || !pszCurrent)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( my_strstri( pTemp->pszNick, pszOriginal) == pTemp->pszNick )
+ if ( lstrcmpi( pTemp->pszNick, pszCurrent ) > 0 && ( !pszName || lstrcmpi( pTemp->pszNick, pszName ) < 0))
+ pszName = pTemp->pszNick;
+
+ pTemp = pTemp->next;
+ }
+ return pszName;
+}
+
+BOOL UM_RemoveUser(USERINFO** ppUserList, const TCHAR* pszUID)
+{
+ USERINFO *pTemp = *ppUserList, *pLast = NULL;
+
+ if (!ppUserList || !pszUID)
+ return FALSE;
+
+ while (pTemp != NULL) {
+ if (!lstrcmpi( pTemp->pszUID, pszUID )) {
+ if (pLast == NULL)
+ *ppUserList = pTemp->next;
+ else
+ pLast->next = pTemp->next;
+ mir_free(pTemp->pszNick);
+ mir_free(pTemp->pszUID);
+ mir_free(pTemp);
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return FALSE;
+}
+
+BOOL UM_RemoveAll (USERINFO** ppUserList)
+{
+ if (!ppUserList)
+ return FALSE;
+
+ while (*ppUserList != NULL)
+ {
+ USERINFO *pLast = ppUserList[0]->next;
+ mir_free( ppUserList[0]->pszUID );
+ mir_free( ppUserList[0]->pszNick );
+ mir_free( *ppUserList );
+ *ppUserList = pLast;
+ }
+ *ppUserList = NULL;
+ return TRUE;
+}
+
+//---------------------------------------------------
+// Log manager functions
+//
+// Necessary to keep track of events
+// in a window log
+//---------------------------------------------------
+
+LOGINFO * LM_AddEvent(LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd)
+{
+
+ LOGINFO *node = NULL;
+
+ if (!ppLogListStart || !ppLogListEnd)
+ return NULL;
+
+ node = (LOGINFO*) mir_alloc(sizeof(LOGINFO));
+ ZeroMemory(node, sizeof(LOGINFO));
+
+
+ if (*ppLogListStart == NULL) // list is empty
+ {
+ *ppLogListStart = node;
+ *ppLogListEnd = node;
+ node->next = NULL;
+ node->prev = NULL;
+ }
+ else
+ {
+ ppLogListStart[0]->prev = node;
+ node->next = *ppLogListStart;
+ *ppLogListStart = node;
+ ppLogListStart[0]->prev=NULL;
+ }
+
+ return node;
+}
+
+BOOL LM_TrimLog(LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd, int iCount)
+{
+ LOGINFO *pTemp = *ppLogListEnd;
+ while (pTemp != NULL && iCount > 0) {
+ *ppLogListEnd = pTemp->prev;
+ if (*ppLogListEnd == NULL)
+ *ppLogListStart = NULL;
+
+ mir_free(pTemp->ptszNick);
+ mir_free(pTemp->ptszUserInfo);
+ mir_free(pTemp->ptszText);
+ mir_free(pTemp->ptszStatus);
+ mir_free(pTemp);
+ pTemp = *ppLogListEnd;
+ iCount--;
+ }
+ ppLogListEnd[0]->next = NULL;
+
+ return TRUE;
+}
+
+BOOL LM_RemoveAll (LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd)
+{
+ while ( *ppLogListStart != NULL ) {
+ LOGINFO *pLast = ppLogListStart[0]->next;
+ mir_free( ppLogListStart[0]->ptszText );
+ mir_free( ppLogListStart[0]->ptszNick );
+ mir_free( ppLogListStart[0]->ptszStatus );
+ mir_free( ppLogListStart[0]->ptszUserInfo );
+ mir_free( *ppLogListStart );
+ *ppLogListStart = pLast;
+ }
+ *ppLogListStart = NULL;
+ *ppLogListEnd = NULL;
+ return TRUE;
+}