summaryrefslogtreecommitdiff
path: root/plugins/MirandaG15/src/CAppletManager.cpp
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2013-10-29 18:17:04 +0000
committerRobert Pösel <robyer@seznam.cz>2013-10-29 18:17:04 +0000
commit4d01f5f5096cb4d22c4a7ba17cc82977c7f5f19b (patch)
tree9353d79ddff12a1c2ced3e300d61a516f2572fb5 /plugins/MirandaG15/src/CAppletManager.cpp
parent2307fd7414d16d4ff936607a215e9a2ca0294741 (diff)
Adopted MirandaG15 plugin
First compilable version and 32-bit only. git-svn-id: http://svn.miranda-ng.org/main/trunk@6681 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirandaG15/src/CAppletManager.cpp')
-rw-r--r--plugins/MirandaG15/src/CAppletManager.cpp1960
1 files changed, 1960 insertions, 0 deletions
diff --git a/plugins/MirandaG15/src/CAppletManager.cpp b/plugins/MirandaG15/src/CAppletManager.cpp
new file mode 100644
index 0000000000..8eb965f0a3
--- /dev/null
+++ b/plugins/MirandaG15/src/CAppletManager.cpp
@@ -0,0 +1,1960 @@
+#include "stdafx.h"
+#include "CConfig.h"
+#include "CAppletManager.h"
+#include "m_system.h"
+
+// specifies how long contact status notifications are ignored after signon
+#define PROTOCOL_NOTIFY_DELAY 1500
+
+//########################################################################
+// functions
+//########################################################################
+
+//************************************************************************
+// returns the AppletManager's instance
+//************************************************************************
+CAppletManager *CAppletManager::GetInstance()
+{
+ return (CAppletManager*)CLCDOutputManager::GetInstance();
+}
+
+//************************************************************************
+// Constructor
+//************************************************************************
+CAppletManager::CAppletManager()
+{
+ m_uiTimer = NULL;
+ m_pLastScreen = NULL;
+
+
+}
+
+//************************************************************************
+// Destructor
+//************************************************************************
+CAppletManager::~CAppletManager()
+{
+
+}
+
+//************************************************************************
+// Initializes the AppletManager
+//************************************************************************
+bool CAppletManager::Initialize(tstring strAppletName)
+{
+ if(!CLCDOutputManager::Initialize(strAppletName))
+ return false;
+
+ GetLCDConnection()->Connect(CConfig::GetIntSetting(DEVICE));
+
+ // set the volumewheel hook
+ SetVolumeWheelHook();
+
+ // initialize the screens
+ m_NotificationScreen.Initialize();
+ m_EventScreen.Initialize();
+ m_ContactlistScreen.Initialize();
+ m_ChatScreen.Initialize();
+ m_CreditsScreen.Initialize();
+ m_ScreensaverScreen.Initialize();
+
+ // add the screens to the list
+ AddScreen(&m_NotificationScreen);
+ AddScreen(&m_EventScreen);
+ AddScreen(&m_ContactlistScreen);
+ AddScreen(&m_ChatScreen);
+ AddScreen(&m_CreditsScreen);
+ AddScreen(&m_ScreensaverScreen);
+
+ // activate the event screen
+ ActivateScreen(&m_EventScreen);
+
+ // hook the neccessary events
+ m_hMIHookMessageWindowEvent = HookEvent(ME_MSG_WINDOWEVENT,CAppletManager::HookMessageWindowEvent);
+ m_hMIHookEventAdded = HookEvent(ME_DB_EVENT_ADDED, CAppletManager::HookEventAdded);
+ m_hMIHookStatusChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, CAppletManager::HookStatusChanged);
+ m_hMIHookProtoAck = HookEvent(ME_PROTO_ACK, CAppletManager::HookProtoAck);
+ m_hMIHookContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, CAppletManager::HookContactDeleted);
+ m_hMIHookContactAdded = HookEvent(ME_DB_CONTACT_ADDED, CAppletManager::HookContactAdded);
+ m_hMIHookSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED,CAppletManager::HookSettingChanged);
+ m_hMIHookContactIsTyping = HookEvent(ME_PROTO_CONTACTISTYPING,CAppletManager::HookContactIsTyping);
+
+ // enumerate protocols
+ int iCount;
+ int iProtoCount = 0;
+ PROTOACCOUNT **ppAccounts;
+ CProtocolData *pProtoData = NULL;
+ CIRCConnection *pIRCConnection = NULL;
+
+ CallService(MS_PROTO_ENUMACCOUNTS,(WPARAM)&iCount,(LPARAM)&ppAccounts);
+ for(int i=0;i<iCount;i++)
+ {
+ /**if(ppProtocolDescriptor[i]->type != PROTOTYPE_PROTOCOL)
+ continue;**/
+ if (ppAccounts[i]->bIsEnabled == 0)
+ continue;
+
+ iProtoCount++;
+ pProtoData = new CProtocolData();
+ pProtoData->iStatus = ID_STATUS_OFFLINE;
+ pProtoData->strProtocol = toTstring(ppAccounts[i]->szModuleName);
+ pProtoData->lTimeStamp = 0;
+
+ // try to create an irc connection for that protocol (will fail if it is no irc protocol)
+ pIRCConnection = CreateIRCConnection(pProtoData->strProtocol);
+
+ m_vProtocolData.push_back(pProtoData);
+ }
+
+ // load status bitmaps
+ m_ahStatusBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_OFFLINE),
+ IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_ONLINE),
+ IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_AWAY),
+ IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_NA),
+ IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[4] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_OCCUPIED),
+ IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[5] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_DND),
+ IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[6] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_INVISIBLE),
+ IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[7] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_FFC),
+ IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ // Load event bitmaps
+ m_ahEventBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_MSG),
+ IMAGE_BITMAP,6, 6, LR_MONOCHROME);
+ m_ahEventBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_CON),
+ IMAGE_BITMAP,6, 6, LR_MONOCHROME);
+ m_ahEventBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_USER),
+ IMAGE_BITMAP,6, 6, LR_MONOCHROME);
+ m_ahEventBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_INFO),
+ IMAGE_BITMAP,6, 6, LR_MONOCHROME);
+
+ m_ahLargeEventBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_MSG_LARGE),
+ IMAGE_BITMAP,8, 8, LR_MONOCHROME);
+ m_ahLargeEventBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_CON_LARGE),
+ IMAGE_BITMAP,8, 8, LR_MONOCHROME);
+ m_ahLargeEventBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_USER_LARGE),
+ IMAGE_BITMAP,8, 8, LR_MONOCHROME);
+ m_ahLargeEventBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_INFO_LARGE),
+ IMAGE_BITMAP,8, 8, LR_MONOCHROME);
+
+
+ // start the update timer
+ m_uiTimer = SetTimer(0,0,1000/10,CAppletManager::UpdateTimer);
+
+
+
+ return true;
+}
+
+//************************************************************************
+// Deinitializes the AppletManager
+//************************************************************************
+bool CAppletManager::Shutdown()
+{
+ if(!IsInitialized())
+ return false;
+
+ // stop the update timer
+ KillTimer(0,m_uiTimer);
+
+ // delete status bitmaps
+ for(int i=0;i<8;i++)
+ DeleteObject(m_ahStatusBitmaps[i]);
+
+ // delete event bitmaps
+ for(int i=0;i<8;i++)
+ {
+ DeleteObject(m_ahLargeEventBitmaps[i]);
+ DeleteObject(m_ahEventBitmaps[i]);
+ }
+
+ // unhook the events
+ UnhookEvent(m_hMIHookMessageWindowEvent);
+ UnhookEvent(m_hMIHookEventAdded);
+ UnhookEvent(m_hMIHookStatusChanged);
+ UnhookEvent(m_hMIHookProtoAck);
+ UnhookEvent(m_hMIHookContactDeleted);
+ UnhookEvent(m_hMIHookContactAdded);
+ UnhookEvent(m_hMIHookSettingChanged);
+
+ // unhook all irc protocols, and delete the classes
+ vector<CIRCConnection*>::iterator iter = m_vIRCConnections.begin();
+ while(iter != m_vIRCConnections.end())
+ {
+ UnhookEvent((*iter)->hEventHook);
+ delete *iter;
+ iter++;
+ }
+ m_vIRCConnections.clear();
+
+ // Deinitialize the screens
+ m_NotificationScreen.Shutdown();
+ m_EventScreen.Shutdown();
+ m_ContactlistScreen.Shutdown();
+ m_ChatScreen.Shutdown();
+ m_CreditsScreen.Shutdown();
+ m_ScreensaverScreen.Shutdown();
+
+ // deinitialize the configuration manager
+ CConfig::Shutdown();
+
+ // delete the protocol information
+ CProtocolData *pProtoData;
+ for(int i=0;i<m_vProtocolData.size();i++)
+ {
+ pProtoData = m_vProtocolData[i];
+ delete pProtoData;
+ }
+ m_vProtocolData.clear();
+
+ // deinitialize the outputmanager
+ if(!CLCDOutputManager::Shutdown())
+ return false;
+ return true;
+}
+
+//************************************************************************
+// Translates the specified string, and inserts the parameters
+//************************************************************************
+tstring CAppletManager::TranslateString(TCHAR *szString,...)
+{
+ TCHAR out[1024];
+ TCHAR *szTranslatedString = TranslateTS(szString);
+
+ va_list body;
+ va_start(body, szString);
+ _vstprintf(out, szTranslatedString, body);
+ va_end(body);
+ return out;
+}
+
+//************************************************************************
+// checks if the patched IRC protocol is in place
+//************************************************************************
+bool CAppletManager::IsIRCHookEnabled()
+{
+ if(m_vIRCConnections.size() == NULL)
+ return false;
+ return true;
+}
+
+//************************************************************************
+// returns the informations structure for the specified protocol
+//************************************************************************
+CProtocolData* CAppletManager::GetProtocolData(tstring strProtocol)
+{
+ for(int i=0;i<m_vProtocolData.size();i++)
+ {
+ if(m_vProtocolData[i]->strProtocol == strProtocol)
+ return m_vProtocolData[i];
+ }
+ return NULL;
+}
+
+//************************************************************************
+// Updates the AppletManager
+//************************************************************************
+bool CAppletManager::Update()
+{
+ if(!CLCDOutputManager::Update())
+ return false;
+
+ // Update Messagejobs
+ UpdateMessageJobs();
+
+ // Screensaver detection
+ BOOL bActive = false;
+ SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &bActive, 0);
+ if(bActive != m_bScreensaver)
+ {
+ if(CConfig::GetBoolSetting(SCREENSAVER_LOCK)) {
+ if(!m_bScreensaver) {
+ ActivateScreensaverScreen();
+ } else {
+ ActivateEventScreen();
+ }
+ }
+ if(CConfig::GetBoolSetting(CONTROL_BACKLIGHTS)) {
+ if(GetLCDConnection() &&
+ GetLCDConnection()->GetConnectionType() == TYPE_LOGITECH)
+ {
+ CLCDConnectionLogitech *pLCDConnection = (CLCDConnectionLogitech*)GetLCDConnection();
+
+ // Screensaver starts
+ if(!m_bScreensaver)
+ {
+ m_G15LightStatus = pLCDConnection->GetLightStatus();
+ pLCDConnection->SetLCDBacklight(LCD_OFF);
+ pLCDConnection->SetKBDBacklight(KBD_OFF);
+ pLCDConnection->SetMKeyLight(0,0,0,0);
+ }
+ // Screensaver ends
+ else
+ {
+ SG15LightStatus currentStatus = pLCDConnection->GetLightStatus();
+
+ if(currentStatus.eLCDBrightness == LCD_OFF)
+ pLCDConnection->SetLCDBacklight(m_G15LightStatus.eLCDBrightness);
+ if(currentStatus.eKBDBrightness == KBD_OFF)
+ pLCDConnection->SetKBDBacklight(m_G15LightStatus.eKBDBrightness);
+ if(!currentStatus.bMRKey && !currentStatus.bMKey[0] && !currentStatus.bMKey[1]
+ && !currentStatus.bMKey[2])
+ pLCDConnection->SetMKeyLight(m_G15LightStatus.bMKey[0],m_G15LightStatus.bMKey[1],m_G15LightStatus.bMKey[2],m_G15LightStatus.bMRKey);
+ }
+ }
+ }
+ m_bScreensaver = bActive;
+ }
+
+ return true;
+}
+
+//************************************************************************
+// Called when the active screen has expired
+//************************************************************************
+void CAppletManager::OnScreenExpired(CLCDScreen *pScreen)
+{
+ // If the notification screen has expired, activate the last active screen
+ if(pScreen == (CLCDScreen*)&m_NotificationScreen)
+ {
+ ActivateScreen(m_pLastScreen);
+ if(CConfig::GetBoolSetting(TRANSITIONS))
+ m_pGfx->StartTransition();
+ }
+}
+
+//************************************************************************
+// the update timer's callback function
+//************************************************************************
+VOID CALLBACK CAppletManager::UpdateTimer(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)
+{
+ CAppletManager::GetInstance()->Update();
+}
+
+//************************************************************************
+// applies the volumewheel setting
+//************************************************************************
+void CAppletManager::SetVolumeWheelHook()
+{
+ // Set the volumewheel hook
+ if(GetLCDConnection() && GetLCDConnection()->GetConnectionType() == TYPE_LOGITECH)
+ {
+ CLCDConnectionLogitech *pLCDConnection = (CLCDConnectionLogitech*)GetLCDConnection();
+ if(pLCDConnection->GetConnectionState() == CONNECTED)
+ pLCDConnection->SetVolumeWheelHook(CConfig::GetBoolSetting(HOOK_VOLUMEWHEEL));
+ }
+}
+
+//************************************************************************
+// Called when the connection state has changed
+//************************************************************************
+void CAppletManager::OnConnectionChanged(int iConnectionState)
+{
+ if(iConnectionState == CONNECTED)
+ {
+ SetVolumeWheelHook();
+ }
+ CConfig::OnConnectionChanged();
+}
+
+//************************************************************************
+// called when the plugin's configuration has changed
+//************************************************************************
+void CAppletManager::OnConfigChanged()
+{
+ GetLCDConnection()->Connect(CConfig::GetIntSetting(DEVICE));
+
+ m_pGfx->StartTransition(TRANSITION_MORPH);
+
+ // Set the volumewheel hook
+ SetVolumeWheelHook();
+ // send the event to all screens
+ m_NotificationScreen.OnConfigChanged();
+ m_ChatScreen.OnConfigChanged();
+ m_EventScreen.OnConfigChanged();
+ m_ContactlistScreen.OnConfigChanged();
+ m_CreditsScreen.OnConfigChanged();
+}
+//************************************************************************
+// activate a screen
+//************************************************************************
+void CAppletManager::ActivateScreen(CScreen *pScreen) {
+ if(GetActiveScreen() && GetActiveScreen() != &m_NotificationScreen) {
+ m_pLastScreen = (CScreen*)GetActiveScreen();
+ }
+
+ CLCDOutputManager::ActivateScreen(pScreen);
+}
+
+//************************************************************************
+// activates the previous screen
+//************************************************************************
+void CAppletManager::ActivatePreviousScreen() {
+ if(m_pLastScreen) {
+ ActivateScreen(m_pLastScreen);
+ }
+}
+
+//************************************************************************
+// activates the credits screen
+//************************************************************************
+void CAppletManager::ActivateScreensaverScreen()
+{
+ m_ScreensaverScreen.Reset();
+ ActivateScreen(&m_ScreensaverScreen);
+}
+
+//************************************************************************
+// activates the credits screen
+//************************************************************************
+void CAppletManager::ActivateCreditsScreen()
+{
+ m_CreditsScreen.Reset();
+ ActivateScreen(&m_CreditsScreen);
+}
+
+//************************************************************************
+// activates the event screen
+//************************************************************************
+void CAppletManager::ActivateEventScreen()
+{
+ m_ChatScreen.SetContact(NULL);
+ ActivateScreen(&m_EventScreen);
+
+ if(CConfig::GetBoolSetting(TRANSITIONS))
+ m_pGfx->StartTransition();
+}
+
+//************************************************************************
+// activates the contactlist screen
+//************************************************************************
+void CAppletManager::ActivateCListScreen()
+{
+ m_ChatScreen.SetContact(NULL);
+ m_ContactlistScreen.ResetPosition();
+ ActivateScreen(&m_ContactlistScreen);
+
+ if(CConfig::GetBoolSetting(TRANSITIONS))
+ m_pGfx->StartTransition();
+}
+
+//************************************************************************
+// activates the chat screen
+//************************************************************************
+bool CAppletManager::ActivateChatScreen(HANDLE hContact)
+{
+ if(!m_ChatScreen.SetContact(hContact))
+ return false;
+
+ m_ContactlistScreen.OnSessionOpened(hContact);
+ ActivateScreen(&m_ChatScreen);
+
+ if(CConfig::GetBoolSetting(TRANSITIONS))
+ m_pGfx->StartTransition();
+ return true;
+}
+
+//************************************************************************
+// returns the contacts displayname
+//************************************************************************
+tstring CAppletManager::GetContactDisplayname(HANDLE hContact,bool bShortened)
+{
+ if(!bShortened || !CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF))
+ return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR);
+
+ tstring strNick = GetContactDisplayname(hContact,false);
+ if(strNick.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET))
+ return strNick.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("...");
+
+ return strNick;
+}
+
+//************************************************************************
+// returns the contacts group
+//************************************************************************
+tstring CAppletManager::GetContactGroup(HANDLE hContact)
+{
+ DBVARIANT dbv;
+ int res = db_get_ts(hContact, "CList", "Group", &dbv);
+
+ tstring strGroup = _T("");
+ if(!res)
+ strGroup = dbv.ptszVal;
+
+ db_free(&dbv);
+ return strGroup;
+}
+
+//************************************************************************
+// returns the bitmap for the specified event
+//************************************************************************
+HBITMAP CAppletManager::GetEventBitmap(EventType eType, bool bLarge)
+{
+ switch(eType)
+ {
+ case EVENT_MSG_RECEIVED:
+ case EVENT_MSG_SENT:
+ case EVENT_IRC_RECEIVED:
+ case EVENT_IRC_SENT:
+ if(bLarge)
+ return m_ahLargeEventBitmaps[0];
+ else
+ return m_ahEventBitmaps[0];
+ case EVENT_PROTO_STATUS:
+ case EVENT_PROTO_CONNECTED:
+ case EVENT_PROTO_DISCONNECTED:
+ if(bLarge)
+ return m_ahLargeEventBitmaps[1];
+ else
+ return m_ahEventBitmaps[1];
+ case EVENT_STATUS:
+ case EVENT_SIGNED_ON:
+ case EVENT_SIGNED_OFF:
+ if(bLarge)
+ return m_ahLargeEventBitmaps[2];
+ else
+ return m_ahEventBitmaps[2];
+ default:
+ if(bLarge)
+ return m_ahLargeEventBitmaps[3];
+ else
+ return m_ahEventBitmaps[3];
+ }
+}
+
+//************************************************************************
+// returns the bitmap for the specified status
+//************************************************************************
+HBITMAP CAppletManager::GetStatusBitmap(int iStatus)
+{
+ switch(iStatus)
+ {
+ case ID_STATUS_OFFLINE:
+ return m_ahStatusBitmaps[0];
+ case ID_STATUS_ONLINE:
+ return m_ahStatusBitmaps[1];
+ case ID_STATUS_NA:
+ return m_ahStatusBitmaps[3];
+ case ID_STATUS_OCCUPIED:
+ return m_ahStatusBitmaps[4];
+ case ID_STATUS_DND:
+ return m_ahStatusBitmaps[5];
+ case ID_STATUS_INVISIBLE:
+ return m_ahStatusBitmaps[6];
+ case ID_STATUS_FREECHAT:
+ return m_ahStatusBitmaps[7];
+ case ID_STATUS_AWAY:
+ default:
+ return m_ahStatusBitmaps[2];
+ }
+}
+//************************************************************************
+// returns a formatted timestamp string
+//************************************************************************
+tstring CAppletManager::GetFormattedTimestamp(tm *tm_time)
+{
+ time_t now;
+ tm tm_now;
+ time(&now);
+ localtime_s(&tm_now,&now);
+
+ TCHAR buffer[128];
+ setlocale( LC_ALL, "" );
+
+ if(tm_time->tm_mday != tm_now.tm_mday || tm_time->tm_mon != tm_now.tm_mon)
+ {
+ if(CConfig::GetBoolSetting(TIMESTAMP_SECONDS))
+ _tcsftime(buffer,128,_T("[%x %H:%M:%S]"),tm_time);
+ else
+ _tcsftime(buffer,128,_T("[%x %H:%M]"),tm_time);
+ }
+ else
+ {
+ if(CConfig::GetBoolSetting(TIMESTAMP_SECONDS))
+ _tcsftime(buffer,128,_T("[%H:%M:%S]"),tm_time);
+ else
+ _tcsftime(buffer,128,_T("[%H:%M]"),tm_time);
+ }
+
+ return toTstring(buffer);
+}
+
+//************************************************************************
+// called to process the specified event
+//************************************************************************
+void CAppletManager::HandleEvent(CEvent *pEvent)
+{
+ TRACE(_T("<< Event: %i\n"),(int)pEvent->eType);
+
+ // check if the event's timestamp needs to be set
+ if(!pEvent->bTime)
+ {
+ time_t now;
+ time(&now);
+ localtime_s(&pEvent->Time,&now);
+ }
+ // check wether the event needs notification
+
+ // check for protocol filters
+ if(pEvent->hContact != NULL && pEvent->eType != EVENT_CONTACT_ADDED)
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pEvent->hContact, 0);
+ if(szProto == NULL || !CConfig::GetProtocolNotificationFilter(toTstring(szProto)))
+ pEvent->bNotification = false;
+ }
+ pEvent->bLog = pEvent->bNotification;
+
+ if(CAppletManager::IsSubContact(pEvent->hContact))
+ {
+ pEvent->bLog = false;
+ pEvent->bNotification = false;
+ }
+
+ // if the applet is in foreground, skip notifications for the chatsession contact
+ if(pEvent->hContact && GetLCDConnection()->IsForeground() && pEvent->hContact == m_ChatScreen.GetContact() &&
+ (!m_ChatScreen.IsInputActive() || !CConfig::GetBoolSetting(NOTIFY_NO_SKIP_REPLY)))
+ {
+ if(pEvent->eType == EVENT_STATUS && CConfig::GetBoolSetting(NOTIFY_SKIP_STATUS))
+ pEvent->bNotification = false;
+ if( pEvent->eType == EVENT_SIGNED_ON && CConfig::GetBoolSetting(NOTIFY_SKIP_SIGNON))
+ pEvent->bNotification = false;
+ if(pEvent->eType == EVENT_SIGNED_OFF && CConfig::GetBoolSetting(NOTIFY_SKIP_SIGNOFF))
+ pEvent->bNotification = false;
+ if((pEvent->eType == EVENT_IRC_RECEIVED || pEvent->eType == EVENT_MSG_RECEIVED) && CConfig::GetBoolSetting(NOTIFY_SKIP_MESSAGES))
+ pEvent->bNotification = false;
+ }
+
+ // send the event to all screens
+ m_NotificationScreen.OnEventReceived(pEvent);
+ m_ChatScreen.OnEventReceived(pEvent);
+ m_EventScreen.OnEventReceived(pEvent);
+ m_ContactlistScreen.OnEventReceived(pEvent);
+
+ // activate notification screen if neccessary (and screensaverscreen is not active)
+ if(pEvent->bNotification)
+ {
+ if(GetActiveScreen() != (CLCDScreen*)&m_NotificationScreen && GetActiveScreen() != (CLCDScreen*)&m_ScreensaverScreen)
+ {
+ m_NotificationScreen.SetAlert(true);
+ m_NotificationScreen.SetExpiration(CConfig::GetIntSetting(NOTIFY_DURATION)*1000);
+ ActivateScreen(&m_NotificationScreen);
+
+ if(GetLCDConnection()->IsForeground() && CConfig::GetBoolSetting(TRANSITIONS))
+ m_pGfx->StartTransition();
+ }
+ }
+}
+
+bool CAppletManager::IsUtfSendAvailable(HANDLE hContact) {
+ char* szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if ( szProto == NULL )
+ return FALSE;
+
+ return ( CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDUTF ) ? TRUE : FALSE;
+}
+
+//************************************************************************
+// returns the contacts message service name
+//************************************************************************
+char *CAppletManager::GetMessageServiceName(HANDLE hContact,bool bIsUnicode)
+{
+ if(g_bUnicode) {
+ char szServiceName[100];
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+
+ if(szProto == NULL)
+ return NULL;
+
+ if (!bIsUnicode)
+ return PSS_MESSAGE;
+
+ _snprintf(szServiceName, sizeof(szServiceName), "%s%sW", szProto, PSS_MESSAGE);
+ if (ServiceExists(szServiceName))
+ return PSS_MESSAGE "W";
+ } else {
+ return PSS_MESSAGE;
+ }
+}
+
+//************************************************************************
+// updates all pending message jobs
+//************************************************************************
+void CAppletManager::UpdateMessageJobs()
+{
+ list<SMessageJob*>::iterator iter = m_MessageJobs.begin();
+ while(iter != m_MessageJobs.end())
+ {
+ // TODO: Fertigstellen
+ if((*iter)->dwTimestamp + 15*1000 < GetTickCount())
+ {
+ CEvent Event;
+
+ Event.eType = EVENT_MESSAGE_ACK;
+ Event.hValue = (*iter)->hEvent;
+ Event.hContact = (*iter)->hContact;
+ Event.iValue = ACKRESULT_FAILED;
+ Event.strValue = TranslateString(_T("Timeout: No response from contact/server"));
+
+ HandleEvent(&Event);
+
+ SMessageJob *pJob = *iter;
+ m_MessageJobs.erase(iter);
+ free(pJob->pcBuffer);
+ delete(pJob);
+ break;
+ }
+ iter++;
+ }
+}
+
+//************************************************************************
+// adds a message job to the list
+//************************************************************************
+void CAppletManager::AddMessageJob(SMessageJob *pJob)
+{
+ m_MessageJobs.push_back(pJob);
+}
+
+//************************************************************************
+// finishes a message job
+//************************************************************************
+void CAppletManager::FinishMessageJob(SMessageJob *pJob)
+{
+ list<SMessageJob*>::iterator iter = m_MessageJobs.begin();
+ while(iter != m_MessageJobs.end())
+ {
+ if((*iter) == pJob)
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pJob->hContact, 0);
+ tstring strProto = toTstring(szProto);
+ CIRCConnection *pIRCCon = GetIRCConnection(strProto);
+
+ // Only add the message to the history if the contact isn't an irc chatroom
+ if(!(pIRCCon && db_get_b(pJob->hContact, szProto, "ChatRoom", 0) != 0))
+ {
+ // Add the message to the database
+ DBEVENTINFO dbei = { 0 };
+ dbei.cbSize = sizeof(dbei);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_SENT;
+ dbei.szModule = szProto;
+ dbei.timestamp = time(NULL);
+ // Check if protocoll is valid
+ if(dbei.szModule == NULL)
+ return;
+
+ if(pJob->dwFlags & PREF_UTF) {
+ dbei.flags |= DBEF_UTF;
+ }
+
+ dbei.cbBlob = pJob->iBufferSize;
+ dbei.pBlob = (PBYTE) pJob->pcBuffer;
+
+ db_event_add(pJob->hContact, &dbei);
+ }
+ SMessageJob *pJob = *iter;
+ m_MessageJobs.erase(iter);
+ free(pJob->pcBuffer);
+ delete(pJob);
+ return;
+ }
+ }
+}
+
+//************************************************************************
+// cancels a message job
+//************************************************************************
+void CAppletManager::CancelMessageJob(SMessageJob *pJob)
+{
+ list<SMessageJob*>::iterator iter = m_MessageJobs.begin();
+ while(iter != m_MessageJobs.end())
+ {
+ if((*iter) == pJob)
+ {
+ SMessageJob *pJob = *iter;
+ m_MessageJobs.erase(iter);
+ free(pJob->pcBuffer);
+ delete(pJob);
+ return;
+ }
+ }
+}
+
+//************************************************************************
+// returns wether or not a contact is a subcontact
+//************************************************************************
+bool CAppletManager::IsSubContact(HANDLE hContact)
+{
+ if(!db_get_b(0, "MetaContacts", "Enabled", 1))
+ return false;
+ bool bIsSubcontact = db_get_b(hContact,"MetaContacts","IsSubcontact",0);
+ return bIsSubcontact;
+ // HANDLE hMetaContact = (HANDLE)CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, NULL);
+ // return hMetaContact != NULL;
+}
+
+//************************************************************************
+// sends typing notifications to the specified contact
+//************************************************************************
+void CAppletManager::SendTypingNotification(HANDLE hContact,bool bEnable)
+{
+ DWORD protoStatus;
+ DWORD protoCaps;
+ DWORD typeCaps;
+
+ if (!hContact)
+ return;
+
+ // Don't send to protocols who don't support typing
+ // Don't send to users who are unchecked in the typing notification options
+ // Don't send to protocols that are offline
+ // Don't send to users who are not visible and
+ // Don't send to users who are not on the visible list when you are in invisible mode.
+ if (!db_get_b(hContact, "SRMsg", "SupportTyping", db_get_b(NULL, "SRMsg", "DefaultTyping", 1)))
+ return;
+
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (!szProto)
+ return;
+
+ protoStatus = CallProtoService(szProto, PS_GETSTATUS, 0, 0);
+ protoCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0);
+ typeCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0);
+
+ if (!(typeCaps & PF4_SUPPORTTYPING))
+ return;
+ if (protoStatus < ID_STATUS_ONLINE)
+ return;
+ if (protoCaps & PF1_VISLIST && db_get_w(hContact, szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE)
+ return;
+ if (protoCaps & PF1_INVISLIST && protoStatus == ID_STATUS_INVISIBLE && db_get_w(hContact, szProto, "ApparentMode", 0) != ID_STATUS_ONLINE)
+ return;
+ if (db_get_b(hContact, "CList", "NotOnList", 0)
+ && !db_get_b(NULL, "SRMsg", "UnknownTyping", 1))
+ return;
+ // End user check
+ CallService(MS_PROTO_SELFISTYPING, (WPARAM) hContact, bEnable?PROTOTYPE_SELFTYPING_ON:PROTOTYPE_SELFTYPING_OFF);
+}
+
+//************************************************************************
+// sends a message to the specified contact
+//************************************************************************
+HANDLE CAppletManager::SendMessageToContact(HANDLE hContact,tstring strMessage)
+{
+ string strAscii = toNarrowString(strMessage);
+ int bufSize = lstrlenA(strAscii.c_str())+1;
+ SMessageJob *pJob = new SMessageJob();
+ pJob->dwTimestamp = GetTickCount();
+ pJob->hContact = hContact;
+
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ tstring strProto = toTstring(szProto);
+
+ CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(strProto);
+
+ if(pIRCCon && db_get_b(hContact, szProto, "ChatRoom", 0) != 0)
+ {
+ GCDEST gcd = {0};
+ GCEVENT gce = {0};
+
+ DBVARIANT dbv;
+ if (!db_get((HANDLE)hContact, szProto, "Nick", &dbv) && dbv.type == DBVT_ASCIIZ )
+ gcd.pszID = dbv.pszVal;
+ else
+ return NULL;
+
+ string strID = string(gcd.pszID) + " - " + toNarrowString(pIRCCon->strNetwork).c_str();
+ gcd.pszID = (char*)strID.c_str();
+ gcd.pszModule = szProto;
+ gcd.iType = GC_EVENT_SENDMESSAGE;
+
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ gce.pszStatus = "";
+ // gce.bAddToLog = true;
+ gce.pszUserInfo = NULL;
+
+ gce.pszText = (char *)strAscii.c_str();
+
+ gce.dwItemData = NULL;
+ gce.time = time(NULL);
+ gce.bIsMe = true;
+
+ CallService(MS_GC_EVENT, NULL, (LPARAM) &gce);
+
+ pJob->hEvent = NULL;
+ }
+ else
+ {
+ DWORD pref = 0;
+ bool bIsUnicode = false;
+ if(CAppletManager::IsUtfSendAvailable(pJob->hContact)) {
+ pref = PREF_UTF;
+ char* szMsgUtf = NULL;
+ #if defined( _UNICODE )
+ szMsgUtf = mir_utf8encodeW( strMessage.c_str());
+ #else
+ int codepage = CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 );
+ szMsgUtf = mir_utf8encodecp(strMessage.c_str(), codepage);
+ #endif
+
+ pJob->iBufferSize = strlen(szMsgUtf)+1;
+ pJob->pcBuffer = (char *)malloc(pJob->iBufferSize);
+ pJob->dwFlags = PREF_UTF;
+
+ memcpy(pJob->pcBuffer,szMsgUtf,pJob->iBufferSize);
+ mir_free(szMsgUtf);
+ } else {
+
+#ifdef _UNICODE
+ bIsUnicode = !IsUnicodeAscii(strMessage.c_str(),lstrlen(strMessage.c_str()));
+#endif
+ if(bIsUnicode) {
+ pref = PREF_UNICODE;
+ pJob->iBufferSize = bufSize * (sizeof(TCHAR) + 1);
+ } else {
+ pJob->iBufferSize = bufSize;
+ }
+ pJob->pcBuffer = (char *)malloc(pJob->iBufferSize);
+ memcpy(pJob->pcBuffer,strAscii.c_str(),bufSize);
+
+ if(bIsUnicode) {
+ memcpy(&pJob->pcBuffer[bufSize],strMessage.c_str(),bufSize*sizeof(TCHAR));
+ }
+ }
+ char *szService = CAppletManager::GetMessageServiceName(pJob->hContact,bIsUnicode);
+
+ if(szService == NULL)
+ {
+ free(pJob->pcBuffer);
+ pJob->pcBuffer == NULL;
+ return NULL;
+ }
+ pJob->hEvent = (HANDLE) CallContactService(pJob->hContact, szService , pref, (LPARAM)pJob->pcBuffer );
+ CAppletManager::GetInstance()->AddMessageJob(pJob);
+ }
+
+
+ return pJob->hEvent;
+}
+
+//************************************************************************
+// check if a contacts message window is opened
+//************************************************************************
+bool CAppletManager::IsMessageWindowOpen(HANDLE hContact)
+{
+ MessageWindowInputData mwid;
+ mwid.cbSize = sizeof(MessageWindowInputData);
+ mwid.hContact = hContact;
+ mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+
+ MessageWindowData mwd;
+ mwd.cbSize = sizeof(MessageWindowData);
+ CallService(MS_MSG_GETWINDOWDATA,(WPARAM)&mwid,(LPARAM)&mwd);
+ if(mwd.uState & MSG_WINDOW_STATE_EXISTS)
+ return true;
+ return false;
+}
+
+//************************************************************************
+// marks the given message as read
+//************************************************************************
+void CAppletManager::MarkMessageAsRead(HANDLE hContact,HANDLE hEvent)
+{
+ db_event_markRead(hContact, hEvent);
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hEvent);
+}
+
+//************************************************************************
+// translates the given database event
+//************************************************************************
+bool CAppletManager::TranslateDBEvent(CEvent *pEvent,WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ HANDLE hdbevent = (HANDLE)lParam;
+
+
+ // Create struct for dbevent
+ DBEVENTINFO dbevent;
+ ZeroMemory(&dbevent, sizeof(dbevent));
+ //dbevent.flags |= PREF_UNICODE;
+ dbevent.cbSize = sizeof(dbevent);
+ dbevent.cbBlob = db_event_getBlobSize(hdbevent);
+ if(dbevent.cbBlob == -1) // hdbevent is invalid
+ {
+ return false;
+ }
+ dbevent.pBlob = (PBYTE)malloc(dbevent.cbBlob);
+ if(db_event_get(hdbevent, &dbevent) != 0)
+ {
+ free(dbevent.pBlob);
+ return false;
+ }
+
+ pEvent->dwFlags = dbevent.flags;
+ pEvent->hContact = hContact;
+ pEvent->hValue = hdbevent;
+
+ time_t timestamp = (time_t)dbevent.timestamp;
+ localtime_s(&pEvent->Time,&timestamp);
+ pEvent->bTime = true;
+ /*
+ if(dbevent.eventType == EVENTTYPE_MESSAGE && dbevent.flags & DBEF_READ) {
+ free(dbevent.pBlob);
+ return false;
+ }
+ */
+ // Skip events from the user except for messages
+ if(dbevent.eventType != EVENTTYPE_MESSAGE && (dbevent.flags & DBEF_SENT))
+ {
+ free(dbevent.pBlob);
+ return false;
+ }
+
+ int msglen = 0;
+
+ tstring strName = CAppletManager::GetContactDisplayname(hContact,true);
+
+ switch(dbevent.eventType)
+ {
+ case EVENTTYPE_MESSAGE:
+ msglen = strlen((char *) dbevent.pBlob) + 1;
+#ifdef _UNICODE
+ if (dbevent.flags & DBEF_UTF) {
+ pEvent->strValue = Utf8_Decode((char*)dbevent.pBlob);
+ } else if ((int) dbevent.cbBlob == msglen*3){
+ pEvent->strValue = (TCHAR *) & dbevent.pBlob[msglen];
+ } else {
+ pEvent->strValue = toTstring((char*)dbevent.pBlob);
+ }
+#else
+ pEvent->strValue = toTstring((char*)dbevent.pBlob);
+#endif
+ pEvent->eType = (dbevent.flags & DBEF_SENT) ? EVENT_MSG_SENT:EVENT_MSG_RECEIVED;
+ if(pEvent->eType == EVENT_MSG_RECEIVED)
+ {
+ pEvent->dwFlags = MSG_UNREAD;
+ if(CConfig::GetBoolSetting(NOTIFY_MESSAGES))
+ pEvent->bNotification = true;
+ }
+
+ pEvent->strDescription = strName + _T(": ") +pEvent->strValue;
+ pEvent->strSummary = TranslateString(_T("New message from %s"),strName.c_str());
+ break;
+ case EVENTTYPE_URL:
+ if(CConfig::GetBoolSetting(NOTIFY_URL))
+ pEvent->bNotification = true;
+
+ pEvent->eType = EVENT_URL;
+ pEvent->strDescription = TranslateString(_T("Incoming URL from %s"),strName.c_str());
+ break;
+ case EVENTTYPE_CONTACTS:
+ if(CConfig::GetBoolSetting(NOTIFY_CONTACTS))
+ pEvent->bNotification = true;
+
+ pEvent->strDescription = TranslateString(_T("Incoming contacts from %s"),strName.c_str());
+ pEvent->eType = EVENT_CONTACTS;
+ break;
+ case EVENTTYPE_ADDED:
+ if(CConfig::GetBoolSetting(NOTIFY_CONTACTS))
+ pEvent->bNotification = true;
+
+ pEvent->strDescription = TranslateString(_T("You were added by %s"),strName.c_str());
+ pEvent->eType = EVENT_ADDED;
+ break;
+ case EVENTTYPE_AUTHREQUEST:
+ if(CConfig::GetBoolSetting(NOTIFY_CONTACTS))
+ pEvent->bNotification = true;
+
+ pEvent->strDescription = TranslateString(_T("Incoming Authrequest!"));
+ pEvent->eType = EVENT_AUTHREQUEST;
+ break;
+ case EVENTTYPE_FILE:
+ if(CConfig::GetBoolSetting(NOTIFY_FILE))
+ pEvent->bNotification = true;
+
+ pEvent->strDescription = TranslateString(_T("Incoming file from %s"),strName.c_str());
+ pEvent->eType = EVENT_FILE;
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ if(CConfig::GetBoolSetting(NOTIFY_SHOWPROTO))
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pEvent->hContact, 0);
+ pEvent->strDescription = _T("(")+toTstring(szProto)+_T(") ") + pEvent->strDescription;
+ }
+
+ // Clean up
+ free(dbevent.pBlob);
+ return true;
+}
+
+//************************************************************************
+// removes IRC formatting tags from the string
+//************************************************************************
+tstring CAppletManager::StripIRCFormatting(tstring strText)
+{
+ tstring::size_type End=0,Start=0;
+ tstring strEntity = _T("");
+ tstring strReplace = _T("");
+ tstring::size_type len = strText.length();
+
+ int i = 0;
+ while(i < strText.length())
+ {
+ Start = strText.find(_T("%"),i);
+ if(Start != string::npos && Start < strText.length() - 1)
+ {
+ strEntity = strText[Start+1];
+ if(strEntity == _T("%"))
+ {
+ strText.replace(Start,2,_T("%"));
+ i = Start +1;
+ }
+ /*
+ else if(strEntity == _T("b") || strEntity == _T("B") ||
+ strEntity == _T("i") || strEntity == _T("I") ||
+ strEntity ==_T("u") || strEntity == _T("U") ||
+ strEntity == _T("C") ||strEntity == _T("F"))
+ {
+ strText.erase(Start,2);
+ i = Start;
+ }
+ */
+ else if(strEntity == _T("c") || strEntity == _T("f"))
+ {
+ strText.erase(Start,4);
+ i = Start;
+ }
+ else
+ {
+ strText.erase(Start,2);
+ i = Start;
+ }
+ }
+ else
+ break;
+ }
+
+ return strText;
+}
+
+//************************************************************************
+// returns the IRC connection class for the specified protocol
+//************************************************************************
+CIRCConnection *CAppletManager::GetIRCConnection(tstring strProtocol)
+{
+ vector<CIRCConnection*>::iterator iter = m_vIRCConnections.begin();
+ while(iter != m_vIRCConnections.end())
+ {
+ if((*iter)->strProtocol == strProtocol)
+ return *iter;
+ iter++;
+ }
+ return NULL;
+}
+
+//************************************************************************
+// creates the IRC connection class for the specified protocol
+//************************************************************************
+CIRCConnection *CAppletManager::CreateIRCConnection(tstring strProtocol)
+{
+ char buffer[128];
+ sprintf(buffer,"%s/HookableEvents",toNarrowString(strProtocol).c_str());
+
+ // try to hook the events
+ HANDLE hEventHook = HookEvent(buffer,CAppletManager::HookChatInbound);
+ // if the hook could not be established, the protocol is not an IRC instance
+ if(!hEventHook)
+ return NULL;
+
+ TRACE(_T("Patched IRC-Connection found: %s\n"),strProtocol.c_str());
+ CIRCConnection *pIRCCon = new CIRCConnection();
+ pIRCCon->strProtocol = strProtocol;
+ pIRCCon->hEventHook = hEventHook;
+ pIRCCon->strNetwork = _T("");
+
+ m_vIRCConnections.push_back(pIRCCon);
+
+ return pIRCCon;
+}
+
+//************************************************************************
+// returns the history class for the specified IRC channel
+//************************************************************************
+CIRCHistory *CAppletManager::GetIRCHistory(HANDLE hContact)
+{
+ list<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
+ while(iter != m_LIRCHistorys.end())
+ {
+ if((*iter)->hContact == hContact)
+ return *iter;
+ iter++;
+ }
+ return NULL;
+}
+
+CIRCHistory *CAppletManager::GetIRCHistoryByName(tstring strProtocol,tstring strChannel)
+{
+ list<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
+ while(iter != m_LIRCHistorys.end())
+ {
+ if((*iter)->strChannel == strChannel && (*iter)->strProtocol == strProtocol)
+ return *iter;
+ iter++;
+ }
+ return NULL;
+}
+
+//************************************************************************
+// deletes the history class for the specified IRC channel
+//************************************************************************
+void CAppletManager::DeleteIRCHistory(HANDLE hContact)
+{
+ list<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
+ while(iter != m_LIRCHistorys.end())
+ {
+ if((*iter)->hContact == hContact)
+ {
+ CIRCHistory *pHistory = *iter;
+ pHistory->LMessages.clear();
+ pHistory->LUsers.clear();
+
+ m_LIRCHistorys.erase(iter);
+
+ delete pHistory;
+
+ return;
+ }
+ iter++;
+ }
+}
+
+//************************************************************************
+// creates a history class for the specified IRC channel
+//************************************************************************
+CIRCHistory *CAppletManager::CreateIRCHistory(HANDLE hContact,tstring strChannel)
+{
+ char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(!szProto)
+ return NULL;
+
+ CIRCHistory *pHistory = GetIRCHistoryByName(toTstring(szProto),strChannel);
+ if(pHistory)
+ {
+ pHistory->hContact = hContact;
+ return pHistory;
+ }
+
+ pHistory = new CIRCHistory();
+ pHistory->hContact = hContact;
+ pHistory->strChannel = strChannel;
+ pHistory->strProtocol = toTstring(szProto);
+
+ m_LIRCHistorys.push_back(pHistory);
+
+ return pHistory;
+}
+
+CIRCHistory *CAppletManager::CreateIRCHistoryByName(tstring strProtocol,tstring strChannel)
+{
+ CIRCHistory *pHistory = GetIRCHistoryByName(strProtocol,strChannel);
+ if(pHistory)
+ return pHistory;
+
+ pHistory = new CIRCHistory();
+ pHistory->hContact = NULL;
+ pHistory->strChannel = strChannel;
+ pHistory->strProtocol = strProtocol;
+
+ m_LIRCHistorys.push_back(pHistory);
+
+ return pHistory;
+}
+
+//########################################################################
+// hook functions
+//########################################################################
+
+//************************************************************************
+// inbound chat event hook function
+//************************************************************************
+int CAppletManager::HookChatInbound(WPARAM wParam,LPARAM lParam)
+{
+ GCEVENT *gce = (GCEVENT*)lParam;
+ GCDEST *gcd = (GCDEST*)gce->pDest;
+
+ if(gce == NULL || gcd == NULL)
+ TRACE(_T("<< [%s] skipping invalid IRC event\n"));
+
+ TRACE(_T("<< [%s:%s] IRC event %04X\n"),toTstring(gcd->pszModule).c_str(),toTstring(gcd->pszID).c_str(),gcd->iType);
+
+ // get the matching irc connection entry
+ CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(toTstring(gcd->pszModule));
+ if(!pIRCCon)
+ {
+ TRACE(_T("<< [%s] IRC connection not found, skipping event\n"),toTstring(gcd->pszModule).c_str());
+ return 0;
+ }
+
+ // fetch the network name
+ if(gcd->iType == GC_EVENT_CHANGESESSIONAME)
+ {
+ if(!_tcsicmp(gcd->ptszID,_T("Network log")))
+ {
+ pIRCCon->strNetwork = toTstring(gce->ptszText);
+ TRACE(_T("\t Found network identifier: %s\n"),pIRCCon->strNetwork.c_str());
+ return 0;
+ }
+ }
+
+ CEvent Event;
+ if(gce->bIsMe)
+ Event.eType = EVENT_IRC_SENT;
+ else
+ Event.eType = EVENT_IRC_RECEIVED;
+ Event.iValue = gcd->iType;
+ Event.hValue = (HANDLE)lParam;
+
+ CIRCHistory *pHistory = NULL;
+ if(gcd->ptszID)
+ {
+ tstring strChannel = toTstring(gcd->ptszID);
+ tstring::size_type pos = strChannel.find('-');
+ if(pos != tstring::npos)
+ strChannel = strChannel.substr(0,pos-1);
+ else
+ {
+ if(_tcsicmp(gcd->ptszID,_T("Network log")))
+ TRACE(_T("\t WARNING: ignoring unknown event!\n"));
+ return 0;
+ }
+ pHistory = CAppletManager::GetInstance()->GetIRCHistoryByName(pIRCCon->strProtocol,strChannel);
+ if(!pHistory)
+ {
+ if(gcd->iType == GC_EVENT_JOIN)
+ {
+ pHistory = CAppletManager::GetInstance()->CreateIRCHistoryByName(pIRCCon->strProtocol,strChannel);
+ if(pHistory)
+ pHistory->LUsers.push_back(toTstring(gce->ptszNick));
+ }
+ return 0;
+ }
+ Event.hContact = pHistory->hContact;
+ }
+ else if(gcd->iType != GC_EVENT_INFORMATION)
+ {
+ TRACE(_T("\t WARNING: ignoring unknown event!\n"));
+ return 0;
+ }
+ else
+ Event.hContact = NULL;
+
+ // Ignore events from hidden chatrooms, except for join events
+ if(gcd->ptszID != NULL && db_get_b(Event.hContact,"CList","Hidden",0))
+ {
+ if(gcd->iType == GC_EVENT_JOIN && pHistory)
+ pHistory->LUsers.push_back(toTstring(gce->ptszNick));
+
+ TRACE(_T("\t Chatroom is hidden, skipping event!\n"));
+ return 0;
+ }
+
+ tstring strText = StripIRCFormatting(toTstring(gce->ptszText));
+ tstring strNick = toTstring(gce->ptszNick);
+ tstring strStatus = toTstring(gce->ptszStatus);
+
+ if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strNick.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET))
+ strNick = strNick.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("...");
+
+ TRACE(_T("\t Handling event...\t"));
+
+ switch(gcd->iType)
+ {
+ case GC_EVENT_INFORMATION:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_CHANNEL))
+ Event.bNotification = true;
+
+ if(strText.find(_T("CTCP")) == 0)
+ Event.strValue = _T("--> ") + strText;
+ else
+ Event.strValue = strText;
+
+ break;
+ case GC_EVENT_ACTION:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_EMOTES))
+ Event.bNotification = true;
+ Event.strValue = strNick + _T(" ") + strText;
+ break;
+ case GC_EVENT_MESSAGE:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_MESSAGES))
+ Event.bNotification = true;
+ Event.strValue = strNick + _T(": ") + strText;
+ break;
+ case GC_EVENT_JOIN:
+ // Add the user to the list
+ pHistory->LUsers.push_back(toTstring(gce->ptszNick));
+
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
+ Event.bNotification = true;
+ // Skip join event for user
+ if(gce->bIsMe)
+ return 0;
+ Event.strValue = TranslateString(_T("%s has joined the channel"),strNick.c_str());
+
+ break;
+ case GC_EVENT_PART:
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
+ Event.bNotification = true;
+ tstring strFullNick = toTstring(gce->ptszNick);
+ Event.strValue = TranslateString(strText.empty()?_T("%s has left"):_T("%s has left: %s"),strNick.c_str(),strText.c_str());
+ if(pHistory)
+ {
+ // Remove the user from the list
+ list<tstring>::iterator iter = pHistory->LUsers.begin();
+ while(iter != pHistory->LUsers.end())
+ {
+ if((*iter) == strFullNick)
+ {
+ pHistory->LUsers.erase(iter);
+ break;
+ }
+ iter++;
+ }
+ }
+ break;
+ }
+ case GC_EVENT_QUIT:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
+ Event.bNotification = true;
+ Event.strValue = TranslateString(strText.empty()?_T("%s has disconnected"):_T("%s has disconnected: %s"),strNick.c_str(),strText.c_str());
+ break;
+ case GC_EVENT_KICK:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
+ Event.bNotification = true;
+ Event.strValue = TranslateString(_T("%s has kicked %s: %s"),strStatus.c_str(),strNick.c_str(),strText.c_str());
+ break;
+ case GC_EVENT_NICK:
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
+ Event.bNotification = true;
+ tstring strFullNick = toTstring(gce->ptszNick);
+
+ if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strText.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET))
+ strText = strText.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("...");
+
+ Event.strValue = TranslateString(_T("%s is now known as %s"),strNick.c_str(),strText.c_str());
+ if(pHistory)
+ {
+ // change the nick in the userlist
+ list<tstring>::iterator iter = pHistory->LUsers.begin();
+ while(iter != pHistory->LUsers.end())
+ {
+ if((*iter) == strFullNick)
+ (*iter) = strText;
+ iter++;
+ }
+ }
+ break;
+ }
+ case GC_EVENT_NOTICE:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_NOTICES))
+ Event.bNotification = true;
+ Event.strValue = TranslateString(_T("Notice from %s: %s"),strNick.c_str(),strText.c_str());
+ break;
+ case GC_EVENT_TOPIC:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_CHANNEL))
+ Event.bNotification = true;
+ Event.strValue = TranslateString(_T("Topic is now '%s' (set by %s)"),strText.c_str(),strNick.c_str());
+ break;
+ case GC_EVENT_ADDSTATUS:
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_STATUS))
+ Event.bNotification = true;
+ tstring strNick2 = toTstring(gce->ptszStatus);
+ if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strNick2.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET))
+ strNick2 = strNick2.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("...");
+
+ Event.strValue = TranslateString(_T("%s enables '%s' for %s"),strText.c_str(),strNick2.c_str(),strNick.c_str());
+ break;
+ }
+ case GC_EVENT_REMOVESTATUS:
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_STATUS))
+ Event.bNotification = true;
+ tstring strNick2 = toTstring(gce->ptszStatus);
+ if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strNick2.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET))
+ strNick2 = strNick2.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("...");
+
+ Event.strValue = TranslateString(_T("%s disables '%s' for %s"),strText.c_str(),strNick2.c_str(),strNick.c_str());
+ break;
+ }
+ default:
+ TRACE(_T("OK!\n"));
+ return 0;
+ }
+ if(gce->bIsMe || gcd->ptszID == NULL)
+ Event.bNotification = false;
+
+ // set the event's timestamp
+ Event.bTime = true;
+ time_t now;
+ time(&now);
+ localtime_s(&Event.Time,&now);
+
+ SIRCMessage IRCMsg;
+ IRCMsg.bIsMe = gce->bIsMe;
+ IRCMsg.strMessage = Event.strValue;
+ IRCMsg.Time = Event.Time;
+
+ if(pHistory)
+ {
+ pHistory->LMessages.push_back(IRCMsg);
+
+ // Limit the size to the session logsize
+ if(pHistory->LMessages.size() > CConfig::GetIntSetting(SESSION_LOGSIZE))
+ pHistory->LMessages.pop_front();
+ }
+ else if(gce->ptszNick && gcd->iType == GC_EVENT_QUIT)
+ {
+ tstring strNick = toTstring(gce->ptszNick);
+
+ if(!CAppletManager::GetInstance()->m_LIRCHistorys.empty())
+ {
+ list<CIRCHistory*>::iterator iter = CAppletManager::GetInstance()->m_LIRCHistorys.begin();
+ list<tstring>::iterator nickiter;
+ while(iter != CAppletManager::GetInstance()->m_LIRCHistorys.end())
+ {
+ nickiter = (*iter)->LUsers.begin();
+ while(nickiter != (*iter)->LUsers.end())
+ {
+ if((*nickiter) == strNick)
+ {
+ (*iter)->LMessages.push_back(IRCMsg);
+ // Limit the size to the session logsize
+ if((*iter)->LMessages.size() > CConfig::GetIntSetting(SESSION_LOGSIZE))
+ (*iter)->LMessages.pop_front();
+
+ (*iter)->LUsers.erase(nickiter);
+
+ Event.hContact = (*iter)->hContact;
+ tstring strName = CAppletManager::GetContactDisplayname((*iter)->hContact,true);
+ Event.strDescription = strName + _T(" - ")+Event.strValue;
+ Event.strSummary = _T("(") + toTstring(gcd->pszModule) + _T(") ")+strName;
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+ break;
+ }
+ nickiter++;
+ }
+ iter++;
+ }
+ }
+ TRACE(_T("OK!\n"));
+ return 0;
+ }
+ else if(gcd->ptszID != NULL)
+ {
+ TRACE(_T("OK!\n"));
+ return 0;
+ }
+
+ if(pHistory)
+ {
+ tstring strChannel = pHistory->strChannel;
+ if(CConfig::GetBoolSetting(NOTIFY_CHANNELCUTOFF) && strNick.length() > CConfig::GetIntSetting(NOTIFY_CHANNELCUTOFF_OFFSET)) {
+ strChannel = strChannel.erase(CConfig::GetIntSetting(NOTIFY_CHANNELCUTOFF_OFFSET)) + _T("...");
+ }
+ Event.strDescription = strChannel + _T(" - ")+Event.strValue;
+ Event.strSummary = _T("(") + toTstring(gcd->pszModule) + _T(") ")+pHistory->strChannel;
+ }
+ else
+ Event.strDescription = Event.strValue;
+
+ TRACE(_T("OK!\n"));
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+
+ return 0;
+}
+
+//************************************************************************
+// message window event hook function
+//************************************************************************
+int CAppletManager::HookMessageWindowEvent(WPARAM wParam, LPARAM lParam)
+{
+ MessageWindowEventData *mwed = (MessageWindowEventData*)lParam;
+ CEvent Event;
+
+ Event.eType = EVENT_MESSAGEWINDOW;
+ Event.hContact = mwed->hContact;
+ Event.iValue = mwed->uType;
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+
+ return 0;
+}
+
+
+//************************************************************************
+// contact typing notification hook function
+//************************************************************************
+int CAppletManager::HookContactIsTyping(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ int iState = (int)lParam;
+
+ CEvent Event;
+
+ Event.eType = EVENT_TYPING_NOTIFICATION;
+ Event.hContact = hContact;
+ Event.iValue = iState;
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+ return 0;
+}
+
+//************************************************************************
+// new event hook function
+//************************************************************************
+int CAppletManager::HookEventAdded(WPARAM wParam, LPARAM lParam)
+{
+ CEvent Event;
+
+ if(CAppletManager::TranslateDBEvent(&Event,wParam,lParam))
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+
+ return 0;
+}
+
+//************************************************************************
+// contact status change hook function
+//************************************************************************
+int CAppletManager::HookStatusChanged(WPARAM wParam, LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
+
+ if ((wParam == 0) || (strcmp(cws->szSetting,"Status") != NULL))
+ return 0;
+
+
+ // Prepare message and append to queue
+ CEvent Event;
+ Event.hContact = (HANDLE)wParam;
+ int iStatus = cws->value.wVal;
+ Event.iValue = iStatus;
+
+ int iOldStatus = CAppletManager::GetInstance()->m_ContactlistScreen.GetContactStatus(Event.hContact);
+
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)Event.hContact, 0);
+ tstring strProto = toTstring(szProto);
+
+ CProtocolData *pProtocolData = CAppletManager::GetInstance()->GetProtocolData(toTstring(szProto));
+ if(pProtocolData == NULL)
+ return false;
+
+ // Fetch the contacts name
+ tstring strName = CAppletManager::GetContactDisplayname(Event.hContact,true);
+
+ // Get status String
+ Event.strValue = toTstring((char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, 0));
+
+ // check if this is an irc protocol
+ CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(strProto);
+
+ // Contact signed on
+ if(iOldStatus == ID_STATUS_OFFLINE && iStatus != ID_STATUS_OFFLINE)
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_SIGNOFF))
+ Event.bNotification = true;
+
+ Event.eType = EVENT_SIGNED_ON;
+ if(pIRCCon && db_get_b(Event.hContact, szProto, "ChatRoom", 0) != 0)
+ {
+ Event.strDescription = TranslateString(_T("Joined %s"),strName.c_str());
+
+ DBVARIANT dbv;
+ if (db_get_ts(Event.hContact, szProto, "Nick", &dbv))
+ return 0;
+ CAppletManager::GetInstance()->CreateIRCHistory(Event.hContact,dbv.ptszVal);
+ db_free(&dbv);
+ }
+ else
+ Event.strDescription = TranslateString(_T("%s signed on (%s)"),strName.c_str(),Event.strValue.c_str());
+ }
+ // Contact signed off
+ else if(iStatus == ID_STATUS_OFFLINE && iOldStatus != ID_STATUS_OFFLINE)
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_SIGNON))
+ Event.bNotification = true;
+
+ Event.eType = EVENT_SIGNED_OFF;
+ if(pIRCCon && db_get_b(Event.hContact, szProto, "ChatRoom", 0) != 0)
+ {
+ Event.strDescription = TranslateString(_T("Left %s"),strName.c_str());
+ // delete IRC-Channel history
+ CAppletManager::GetInstance()->DeleteIRCHistory(Event.hContact);
+ }
+ else
+ Event.strDescription = TranslateString(_T("%s signed off"),strName.c_str());
+ }
+ // Contact changed status
+ else if(iStatus != iOldStatus)
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_STATUS))
+ Event.bNotification = true;
+
+ Event.eType = EVENT_STATUS;
+ Event.strDescription = TranslateString(_T("%s is now %s"),strName.c_str(),Event.strValue.c_str());
+ }
+ // ignore remaining events
+ else
+ return 0;
+
+ if(CConfig::GetBoolSetting(NOTIFY_SHOWPROTO))
+ Event.strDescription = _T("(")+strProto+_T(") ") + Event.strDescription;
+
+
+
+ Event.strSummary = TranslateString(_T("Contactlist event"));
+
+ // Block notifications after connecting/disconnecting
+ if(pProtocolData->iStatus == ID_STATUS_OFFLINE ||
+ pProtocolData->lTimeStamp + PROTOCOL_NOTIFY_DELAY > GetTickCount())
+ Event.bNotification = false;
+
+ //CAppletManager::GetInstance()->ActivateNotificationScreen(&Event);
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+
+ return 0;
+}
+
+//************************************************************************
+// protocoll ack hook function
+//************************************************************************
+int CAppletManager::HookProtoAck(WPARAM wParam, LPARAM lParam)
+{
+ ACKDATA *pAck = (ACKDATA *) lParam;
+
+ if(lParam == 0)
+ return 0;
+
+ // Prepare message and append to queue
+ CEvent Event;
+
+ // Message job handling
+ if(pAck->type == ACKTYPE_MESSAGE)
+ {
+ list<SMessageJob*>::iterator iter = CAppletManager::GetInstance()->m_MessageJobs.begin();
+ while(iter != CAppletManager::GetInstance()->m_MessageJobs.end())
+ {
+ if((*iter)->hEvent == pAck->hProcess && (*iter)->hContact == pAck->hContact)
+ {
+ Event.eType = EVENT_MESSAGE_ACK;
+ Event.hValue = pAck->hProcess;
+ Event.hContact = pAck->hContact;
+ Event.iValue = pAck->result;
+ if(pAck->lParam != 0)
+ Event.strValue = toTstring((char*)pAck->lParam);
+ else
+ Event.strValue = _T("");
+
+ if(Event.iValue == ACKRESULT_SUCCESS)
+ CAppletManager::GetInstance()->FinishMessageJob((*iter));
+ else
+ CAppletManager::GetInstance()->CancelMessageJob((*iter));
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+
+ return 0;
+ }
+ iter++;
+ }
+ }
+ // protocol status changes
+ else if(pAck->type == ACKTYPE_STATUS && pAck->result == ACKRESULT_SUCCESS)
+ {
+ int iOldStatus = (int)pAck->hProcess;
+ int iNewStatus = pAck->lParam;
+
+ tstring strProto = toTstring(pAck->szModule);
+
+ // ignore metacontacts status changes
+ if(toLower(strProto) == _T("metacontacts"))
+ return 0;
+
+ CProtocolData *pProtoData = CAppletManager::GetInstance()->GetProtocolData(strProto);
+ if(pProtoData == NULL)
+ return 0;
+
+ if(iNewStatus == ID_STATUS_CONNECTING)
+ return 0;
+
+ if(iNewStatus == ID_STATUS_OFFLINE)
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_PROTO_SIGNOFF))
+ Event.bNotification = true;
+ Event.eType = EVENT_PROTO_DISCONNECTED;
+ }
+ else if(iNewStatus != ID_STATUS_OFFLINE && iOldStatus == ID_STATUS_CONNECTING)
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_PROTO_SIGNON))
+ Event.bNotification = true;
+ Event.eType = EVENT_PROTO_CONNECTED;
+ }
+ else
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_PROTO_STATUS))
+ Event.bNotification = true;
+ Event.eType = EVENT_PROTO_STATUS;
+ }
+
+ // Skip connecting status
+ if(iNewStatus == ID_STATUS_CONNECTING)
+ return 0;
+
+ pProtoData->iStatus = iNewStatus;
+
+ Event.iValue = iNewStatus;
+ Event.strValue = strProto;
+
+ // set the event description / summary
+ tstring strStatus = toTstring((char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iNewStatus, 0));
+ Event.strDescription = _T("(") + Event.strValue + _T(") ")+ TranslateString(_T("You are now %s"),strStatus.c_str());
+ Event.strSummary = TranslateString(_T("Protocol status change"));
+
+ if(Event.eType != EVENT_PROTO_STATUS)
+ pProtoData->lTimeStamp = GetTickCount();
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+ //CAppletManager::GetInstance()->ActivateNotificationScreen(&Event);
+ }
+
+ return 0;
+}
+
+//************************************************************************
+// contact added hook function
+//************************************************************************
+int CAppletManager::HookContactAdded(WPARAM wParam, LPARAM lParam)
+{
+ CEvent Event;
+ Event.eType = EVENT_CONTACT_ADDED;
+ Event.hContact = (HANDLE)wParam;
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+ return 0;
+}
+
+//************************************************************************
+// contact deleted hook function
+//************************************************************************
+int CAppletManager::HookContactDeleted(WPARAM wParam, LPARAM lParam)
+{
+ CEvent Event;
+ Event.eType = EVENT_CONTACT_DELETED;
+ Event.hContact = (HANDLE)wParam;
+ Event.bNotification = CConfig::GetBoolSetting(NOTIFY_CONTACTS);
+ Event.bLog = Event.bNotification;
+
+ tstring strName = CAppletManager::GetContactDisplayname(Event.hContact,true);
+
+ Event.strDescription = TranslateString(_T("%s was deleted from contactlist!"),strName.c_str());
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+ return 0;
+}
+
+//************************************************************************
+// setting changed hook function
+//************************************************************************
+int CAppletManager::HookSettingChanged(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING*)lParam;
+
+ CEvent Event;
+ Event.hContact = (HANDLE)wParam;
+
+ if(!lstrcmpA(dbcws->szModule,"MetaContacts"))
+ {
+ //if(!lstrcmpA(dbcws->szSetting,"Enabled")) {
+ // CAppletManager::GetInstance()->OnConfigChanged();
+ // return 0;
+ //} else
+ if(!lstrcmpA(dbcws->szSetting,"IsSubcontact")) {
+ Event.eType = EVENT_CONTACT_GROUP;
+ DBVARIANT dbv;
+ int res = db_get_ts((HANDLE)wParam, "CList", "Group", &dbv);
+ if(!res)
+ Event.strValue = dbv.ptszVal;
+ db_free(&dbv);
+ } else {
+ return 0;
+ }
+ }
+ else if(!lstrcmpA(dbcws->szSetting,"Nick") || !lstrcmpA(dbcws->szSetting,"MyHandle"))
+ {
+ DBVARIANT dbv={0};
+ // if the protocol nick has changed, check if a custom handle is set
+ if(!lstrcmpA(dbcws->szSetting,"Nick"))
+ {
+ if (!db_get_ts(Event.hContact, "CList", "MyHandle", &dbv))
+ {
+ // handle found, ignore this event
+ if(dbv.pszVal && strlen(dbv.pszVal)>0)
+ return 0;
+ }
+ db_free(&dbv);
+ }
+
+ Event.eType = EVENT_CONTACT_NICK;
+ if(dbcws->value.type != DBVT_DELETED && dbcws->value.pszVal && strlen(dbcws->value.pszVal)>0)
+ {
+#ifdef _UNICODE
+ if(dbcws->value.type == DBVT_UTF8)
+ Event.strValue = Utf8_Decode(dbcws->value.pszVal);
+ else
+#endif
+ Event.strValue = toTstring(dbcws->value.pszVal);
+ }
+ else
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)Event.hContact, 0);
+ if (db_get_ts(Event.hContact, szProto, "Nick", &dbv))
+ return 0;
+ Event.strValue = dbv.ptszVal;
+ db_free(&dbv);
+ }
+ }
+ else if(!lstrcmpA(dbcws->szModule,"CList"))
+ {
+ if(!lstrcmpA(dbcws->szSetting,"Hidden"))
+ {
+ Event.eType = EVENT_CONTACT_HIDDEN;
+ Event.iValue = db_get_b((HANDLE)wParam,"CList","Hidden",0);
+ }
+ else if(!lstrcmpA(dbcws->szSetting,"Group"))
+ {
+ Event.eType = EVENT_CONTACT_GROUP;
+ DBVARIANT dbv;
+ int res = db_get_ts((HANDLE)wParam, "CList", "Group", &dbv);
+ if(!res)
+ Event.strValue = dbv.ptszVal;
+ db_free(&dbv);
+ }
+ else
+ return 0;
+ }
+ else
+ return 0;
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+ return 0;
+} \ No newline at end of file