From a5574d24bc8c0e94c8880c75f0fd27d08d30b98b Mon Sep 17 00:00:00 2001 From: Rozhuk Ivan Date: Sat, 29 Nov 2014 20:36:41 +0000 Subject: MirandaG15: code cleanup. git-svn-id: http://svn.miranda-ng.org/main/trunk@11162 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MirandaG15/src/CAppletManager.cpp | 3699 ++++++++++---------- plugins/MirandaG15/src/LCDFramework/CLCDList.h | 1886 +++++----- .../src/LCDFramework/CLCDOutputManager.cpp | 902 ++--- protocols/Sametime/src/meanwhile/src/mpi/mpi.c | 9 +- 4 files changed, 3251 insertions(+), 3245 deletions(-) diff --git a/plugins/MirandaG15/src/CAppletManager.cpp b/plugins/MirandaG15/src/CAppletManager.cpp index 2ae86f175b..4248ae3fff 100644 --- a/plugins/MirandaG15/src/CAppletManager.cpp +++ b/plugins/MirandaG15/src/CAppletManager.cpp @@ -1,1849 +1,1850 @@ -#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); - m_hMIHookChatEvent = HookEvent(ME_GC_HOOK_EVENT,CAppletManager::HookChatInbound); - - // enumerate protocols - int iCount; - int iProtoCount = 0; - PROTOACCOUNT **ppAccounts; - CProtocolData *pProtoData = NULL; - CIRCConnection *pIRCConnection = NULL; - - ProtoEnumAccounts(&iCount, &ppAccounts); - for(int i=0;itype != 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); - UnhookEvent(m_hMIHookChatEvent); - - // unhook all irc protocols, and delete the classes - vector::iterator iter = m_vIRCConnections.begin(); - while(iter != m_vIRCConnections.end()) - { - 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(vector::size_type 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_s(out, SIZEOF(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 (vector::size_type 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 != (BOOL)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 != 0; - } - - 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(MCONTACT 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(MCONTACT hContact,bool bShortened) -{ - if(!bShortened || !CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF)) - return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, hContact, GCDNF_TCHAR); - - tstring strNick = GetContactDisplayname(hContact,false); - if(strNick.length() > (tstring::size_type)CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) - return strNick.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("..."); - - return strNick; -} - -//************************************************************************ -// returns the contacts group -//************************************************************************ -tstring CAppletManager::GetContactGroup(MCONTACT 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 = GetContactProto(pEvent->hContact); - if(szProto == NULL || !CConfig::GetProtocolNotificationFilter(toTstring(szProto))) - pEvent->bNotification = false; - } - pEvent->bLog = pEvent->bNotification; - - if(db_mc_isSub(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(MCONTACT hContact) { - char* szProto = GetContactProto(hContact); - 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(MCONTACT hContact,bool bIsUnicode) -{ - char *szProto = GetContactProto(hContact); - - if(szProto == NULL) - return NULL; - - return PSS_MESSAGE; -} - -//************************************************************************ -// updates all pending message jobs -//************************************************************************ -void CAppletManager::UpdateMessageJobs() -{ - list::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::iterator iter = m_MessageJobs.begin(); - while(iter != m_MessageJobs.end()) - { - if((*iter) == pJob) - { - char *szProto = GetContactProto(pJob->hContact); - 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::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; - } - } -} - -//************************************************************************ -// sends typing notifications to the specified contact -//************************************************************************ -void CAppletManager::SendTypingNotification(MCONTACT hContact,bool bEnable) -{ - 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 = GetContactProto(hContact); - if (!szProto) - return; - - DWORD typeCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0); - if (!(typeCaps & PF4_SUPPORTTYPING)) - return; - - DWORD protoStatus = CallProtoService(szProto, PS_GETSTATUS, 0, 0); - if (protoStatus < ID_STATUS_ONLINE) - return; - - DWORD protoCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); - 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, hContact, bEnable ? PROTOTYPE_SELFTYPING_ON : PROTOTYPE_SELFTYPING_OFF); -} - -//************************************************************************ -// sends a message to the specified contact -//************************************************************************ -HANDLE CAppletManager::SendMessageToContact(MCONTACT hContact,tstring strMessage) -{ - tstring strAscii = _A2T(toNarrowString(strMessage).c_str()); - int bufSize = lstrlen(strAscii.c_str())+1; - SMessageJob *pJob = new SMessageJob(); - pJob->dwTimestamp = GetTickCount(); - pJob->hContact = hContact; - - char *szProto = GetContactProto(hContact); - tstring strProto = toTstring(szProto); - - CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(strProto); - - if(pIRCCon && db_get_b(hContact, szProto, "ChatRoom", 0) != 0) - { - GCDEST gcd = { szProto, 0, GC_EVENT_SENDMESSAGE }; - - DBVARIANT dbv; - if (!db_get_ts(hContact, szProto, "Nick", &dbv)) - gcd.ptszID = dbv.ptszVal; - else - return NULL; - - tstring strID = tstring(gcd.ptszID) + _T(" - ") + tstring(_A2T(toNarrowString(pIRCCon->strNetwork).c_str())); - gcd.ptszID = (LPTSTR)strID.c_str(); - - GCEVENT gce = { sizeof(gce), &gcd }; - gce.ptszStatus = _T(""); - gce.ptszText = (LPTSTR)strAscii.c_str(); - 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; - szMsgUtf = mir_utf8encodeW( strMessage.c_str()); - - pJob->iBufferSize = (int)strlen(szMsgUtf)+1; - pJob->pcBuffer = (char *)malloc(pJob->iBufferSize); - pJob->dwFlags = PREF_UTF; - - memcpy(pJob->pcBuffer,szMsgUtf,pJob->iBufferSize); - mir_free(szMsgUtf); - } else { - bIsUnicode = !IsUnicodeAscii(strMessage.c_str(),lstrlen(strMessage.c_str())); - 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(MCONTACT 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(MCONTACT hContact,HANDLE hEvent) -{ - db_event_markRead(hContact, hEvent); - CallService(MS_CLIST_REMOVEEVENT, hContact, (LPARAM)hEvent); -} - -//************************************************************************ -// translates the given database event -//************************************************************************ -bool CAppletManager::TranslateDBEvent(CEvent *pEvent,WPARAM wParam, LPARAM lParam) -{ - MCONTACT hContact = 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,×tamp); - 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 = (int)strlen((char *) dbevent.pBlob) + 1; - 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); - } - 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 = GetContactProto(pEvent->hContact); - 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, i = 0; - tstring strEntity = _T(""); - tstring strReplace = _T(""); - tstring::size_type len = strText.length(); - - 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::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) -{ - CIRCConnection *pIRCCon = new CIRCConnection(); - pIRCCon->strProtocol = strProtocol; - pIRCCon->strNetwork = _T(""); - - m_vIRCConnections.push_back(pIRCCon); - - return pIRCCon; -} - -//************************************************************************ -// returns the history class for the specified IRC channel -//************************************************************************ -CIRCHistory *CAppletManager::GetIRCHistory(MCONTACT hContact) -{ - list::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::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(MCONTACT hContact) -{ - list::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(MCONTACT hContact,tstring strChannel) -{ - char *szProto = GetContactProto(hContact); - 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 event\n")); - - TRACE(_T("<< [%s:%s] event %04X\n"),toTstring(gcd->pszModule).c_str(), gcd->ptszID, gcd->iType); - - // get the matching irc connection entry - CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(toTstring(gcd->pszModule)); - if(!pIRCCon) - { - TRACE(_T("<< [%s] 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() > (tstring::size_type)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::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() > (tstring::size_type)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::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() > (tstring::size_type)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() > (tstring::size_type)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 != 0); - 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::iterator iter = CAppletManager::GetInstance()->m_LIRCHistorys.begin(); - list::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) -{ - MCONTACT hContact = 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 = wParam; - int iStatus = cws->value.wVal; - Event.iValue = iStatus; - - int iOldStatus = CAppletManager::GetInstance()->m_ContactlistScreen.GetContactStatus(Event.hContact); - - char *szProto = GetContactProto(Event.hContact); - 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 || (DWORD)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::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 = 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 = 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 hContact,LPARAM lParam) -{ - DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING*)lParam; - - CEvent Event; - Event.hContact = hContact; - - 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) { - if(dbcws->value.type == DBVT_UTF8) - Event.strValue = Utf8_Decode(dbcws->value.pszVal); - else - Event.strValue = toTstring(dbcws->value.pszVal); - } - else { - char *szProto = GetContactProto(Event.hContact); - 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(hContact,"CList","Hidden",0); - } - else if(!lstrcmpA(dbcws->szSetting,"Group")) { - Event.eType = EVENT_CONTACT_GROUP; - DBVARIANT dbv; - int res = db_get_ts(hContact, "CList", "Group", &dbv); - if(!res) - Event.strValue = dbv.ptszVal; - db_free(&dbv); - } - else return 0; - } - else return 0; - - CAppletManager::GetInstance()->HandleEvent(&Event); - return 0; -} +#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); + m_hMIHookChatEvent = HookEvent(ME_GC_HOOK_EVENT,CAppletManager::HookChatInbound); + + // enumerate protocols + int iCount; + int iProtoCount = 0; + PROTOACCOUNT **ppAccounts; + CProtocolData *pProtoData = NULL; + CIRCConnection *pIRCConnection = NULL; + + ProtoEnumAccounts(&iCount, &ppAccounts); + for(int i=0;itype != 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); + UnhookEvent(m_hMIHookChatEvent); + + // unhook all irc protocols, and delete the classes + vector::iterator iter = m_vIRCConnections.begin(); + while(iter != m_vIRCConnections.end()) + { + 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(vector::size_type 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_s(out, SIZEOF(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 (vector::size_type 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 != (BOOL)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 != 0; + } + + 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(MCONTACT 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(MCONTACT hContact,bool bShortened) +{ + if(!bShortened || !CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF)) + return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, hContact, GCDNF_TCHAR); + + tstring strNick = GetContactDisplayname(hContact,false); + if(strNick.length() > (tstring::size_type)CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + return strNick.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("..."); + + return strNick; +} + +//************************************************************************ +// returns the contacts group +//************************************************************************ +tstring CAppletManager::GetContactGroup(MCONTACT 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 = GetContactProto(pEvent->hContact); + if(szProto == NULL || !CConfig::GetProtocolNotificationFilter(toTstring(szProto))) + pEvent->bNotification = false; + } + pEvent->bLog = pEvent->bNotification; + + if(db_mc_isSub(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(MCONTACT hContact) { + char* szProto = GetContactProto(hContact); + 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(MCONTACT hContact,bool bIsUnicode) +{ + char *szProto = GetContactProto(hContact); + + if(szProto == NULL) + return NULL; + + return PSS_MESSAGE; +} + +//************************************************************************ +// updates all pending message jobs +//************************************************************************ +void CAppletManager::UpdateMessageJobs() +{ + list::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::iterator iter = m_MessageJobs.begin(); + while(iter != m_MessageJobs.end()) + { + if((*iter) == pJob) + { + char *szProto = GetContactProto(pJob->hContact); + 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::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; + } + } +} + +//************************************************************************ +// sends typing notifications to the specified contact +//************************************************************************ +void CAppletManager::SendTypingNotification(MCONTACT hContact,bool bEnable) +{ + 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 = GetContactProto(hContact); + if (!szProto) + return; + + DWORD typeCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0); + if (!(typeCaps & PF4_SUPPORTTYPING)) + return; + + DWORD protoStatus = CallProtoService(szProto, PS_GETSTATUS, 0, 0); + if (protoStatus < ID_STATUS_ONLINE) + return; + + DWORD protoCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); + 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, hContact, bEnable ? PROTOTYPE_SELFTYPING_ON : PROTOTYPE_SELFTYPING_OFF); +} + +//************************************************************************ +// sends a message to the specified contact +//************************************************************************ +HANDLE CAppletManager::SendMessageToContact(MCONTACT hContact,tstring strMessage) +{ + tstring strAscii = _A2T(toNarrowString(strMessage).c_str()); + int bufSize = lstrlen(strAscii.c_str())+1; + SMessageJob *pJob = new SMessageJob(); + pJob->dwTimestamp = GetTickCount(); + pJob->hContact = hContact; + + char *szProto = GetContactProto(hContact); + tstring strProto = toTstring(szProto); + + CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(strProto); + + if(pIRCCon && db_get_b(hContact, szProto, "ChatRoom", 0) != 0) + { + GCDEST gcd = { szProto, 0, GC_EVENT_SENDMESSAGE }; + + DBVARIANT dbv; + if (!db_get_ts(hContact, szProto, "Nick", &dbv)) + gcd.ptszID = dbv.ptszVal; + else + return NULL; + + tstring strID = tstring(gcd.ptszID) + _T(" - ") + tstring(_A2T(toNarrowString(pIRCCon->strNetwork).c_str())); + gcd.ptszID = (LPTSTR)strID.c_str(); + + GCEVENT gce = { sizeof(gce), &gcd }; + gce.ptszStatus = _T(""); + gce.ptszText = (LPTSTR)strAscii.c_str(); + 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; + szMsgUtf = mir_utf8encodeW( strMessage.c_str()); + + pJob->iBufferSize = (int)strlen(szMsgUtf)+1; + pJob->pcBuffer = (char *)malloc(pJob->iBufferSize); + pJob->dwFlags = PREF_UTF; + + memcpy(pJob->pcBuffer,szMsgUtf,pJob->iBufferSize); + mir_free(szMsgUtf); + } else { + bIsUnicode = !IsUnicodeAscii(strMessage.c_str(),lstrlen(strMessage.c_str())); + 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(MCONTACT 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(MCONTACT hContact,HANDLE hEvent) +{ + db_event_markRead(hContact, hEvent); + CallService(MS_CLIST_REMOVEEVENT, hContact, (LPARAM)hEvent); +} + +//************************************************************************ +// translates the given database event +//************************************************************************ +bool CAppletManager::TranslateDBEvent(CEvent *pEvent,WPARAM wParam, LPARAM lParam) +{ + MCONTACT hContact = 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,×tamp); + 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 = (int)strlen((char *) dbevent.pBlob) + 1; + 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); + } + 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 = GetContactProto(pEvent->hContact); + 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, i = 0; + tstring strEntity = _T(""); + tstring strReplace = _T(""); + tstring::size_type len = strText.length(); + + 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::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) +{ + CIRCConnection *pIRCCon = new CIRCConnection(); + pIRCCon->strProtocol = strProtocol; + pIRCCon->strNetwork = _T(""); + + m_vIRCConnections.push_back(pIRCCon); + + return pIRCCon; +} + +//************************************************************************ +// returns the history class for the specified IRC channel +//************************************************************************ +CIRCHistory *CAppletManager::GetIRCHistory(MCONTACT hContact) +{ + list::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::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(MCONTACT hContact) +{ + list::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(MCONTACT hContact,tstring strChannel) +{ + char *szProto = GetContactProto(hContact); + 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; + + if (gce == NULL || gcd == NULL) + TRACE(_T("<< [%s] skipping invalid event\n")); + gcd = (GCDEST*)gce->pDest; + + TRACE(_T("<< [%s:%s] event %04X\n"),toTstring(gcd->pszModule).c_str(), gcd->ptszID, gcd->iType); + + // get the matching irc connection entry + CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(toTstring(gcd->pszModule)); + if(!pIRCCon) + { + TRACE(_T("<< [%s] connection not found, skipping event\n"),toTstring(gcd->pszModule).c_str()); + return 0; + } + + // fetch the network name + if(gcd->iType == GC_EVENT_CHANGESESSIONAME) + { + if (gcd->ptszID && !_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() > (tstring::size_type)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::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() > (tstring::size_type)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::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() > (tstring::size_type)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() > (tstring::size_type)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 != 0); + 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::iterator iter = CAppletManager::GetInstance()->m_LIRCHistorys.begin(); + list::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) +{ + MCONTACT hContact = 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 = wParam; + int iStatus = cws->value.wVal; + Event.iValue = iStatus; + + int iOldStatus = CAppletManager::GetInstance()->m_ContactlistScreen.GetContactStatus(Event.hContact); + + char *szProto = GetContactProto(Event.hContact); + 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 || (DWORD)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::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 = 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 = 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 hContact,LPARAM lParam) +{ + DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING*)lParam; + + CEvent Event; + Event.hContact = hContact; + + 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) { + if(dbcws->value.type == DBVT_UTF8) + Event.strValue = Utf8_Decode(dbcws->value.pszVal); + else + Event.strValue = toTstring(dbcws->value.pszVal); + } + else { + char *szProto = GetContactProto(Event.hContact); + 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(hContact,"CList","Hidden",0); + } + else if(!lstrcmpA(dbcws->szSetting,"Group")) { + Event.eType = EVENT_CONTACT_GROUP; + DBVARIANT dbv; + int res = db_get_ts(hContact, "CList", "Group", &dbv); + if(!res) + Event.strValue = dbv.ptszVal; + db_free(&dbv); + } + else return 0; + } + else return 0; + + CAppletManager::GetInstance()->HandleEvent(&Event); + return 0; +} diff --git a/plugins/MirandaG15/src/LCDFramework/CLCDList.h b/plugins/MirandaG15/src/LCDFramework/CLCDList.h index ae019fe914..80a6b246cf 100644 --- a/plugins/MirandaG15/src/LCDFramework/CLCDList.h +++ b/plugins/MirandaG15/src/LCDFramework/CLCDList.h @@ -1,943 +1,945 @@ -#ifndef _CLCDLIST_H_ -#define _CLCDLIST_H_ - -#include "CLCDTextObject.h" -#include "CLCDBar.h" -#include - - -enum EListEntryType { ROOT = 0,CONTAINER = 1,ITEM = 2}; - -template class CListEntry -{ -public: - CListEntry(CListEntry *pParent) - { - m_iIndex = -1; - m_iEntryCount = 0; - m_Position = NULL; - m_pParent = pParent; - if(pParent == NULL) - { - m_iLevel = 0; - m_eType = ROOT; - m_pRoot = this; - } - else - m_iLevel = m_pParent->GetLevel()+1; - } - - virtual ~CListEntry() - { - - } - - int GetLevel() - { - return m_iLevel; - } - - virtual CListEntry *GetNextEntry() - { - if(m_pParent == NULL) - return NULL; - - return m_pParent->GetNextEntry(this); - } - - virtual CListEntry *GetPreviousEntry() - { - if(m_pParent == NULL) - return NULL; - - return m_pParent->GetPreviousEntry(this); - } - - virtual CListEntry *GetNextEntry(CListEntry *pEntry) - { - return NULL; - } - - virtual CListEntry *GetPreviousEntry(CListEntry *pEntry) - { - return NULL; - } - - EListEntryType GetType() - { - return m_eType; - } - - int GetEntryCount() - { - return m_iEntryCount; - } - - virtual void UpdateEntryCount() - { - m_iEntryCount = 0; - } - - void SetRoot(CListEntry* pRoot) - { - m_pRoot = pRoot; - } - - virtual void DeleteItem(T Entry) - { - } - - virtual void DeleteGroup(G Group) - { - } - - CListEntry *GetPosition() - { - return m_Position; - } - - virtual void SetPosition(CListEntry *pPosition) - { - m_Position = pPosition; - } - - CListEntry *GetParent() - { - return m_pParent; - } - - int GetIndex() - { - return m_iIndex; - } - - void SetIndex(int iIndex) - { - m_iIndex = iIndex; - } - -protected: - int m_iIndex; - int m_iEntryCount; - int m_iLevel; - EListEntryType m_eType; - CListEntry *m_pParent; - CListEntry *m_pRoot; - CListEntry *m_Position; -}; - -template class CListItem : public CListEntry -{ -public: - CListItem(CListEntry *pParent,T Entry) : CListEntry(pParent) - { - m_Item = Entry; - m_eType = ITEM; - } - - ~CListItem() - { - m_pRoot->DeleteItem(GetItemData()); - } - - T GetItemData() - { - return m_Item; - } -private: - T m_Item; -}; - -template class CListContainer : public CListEntry -{ -public: - typedef typename list* >::iterator iterator; - - typename list* >::iterator end() - { - return m_Entrys.end(); - } - - typename list* >::iterator begin() - { - return m_Entrys.begin(); - } - - typename list* >::size_type size() - { - return m_Entrys.size(); - } - - bool empty() - { - bool b = m_Entrys.empty(); - return m_Entrys.empty(); - } - - CListContainer(CListEntry *pParent) : CListEntry(pParent) - { - if(m_pParent != NULL) - { - m_eType = CONTAINER; - m_bOpen = false; - } - else - m_bOpen = true; - } - - ~CListContainer() - { - if(m_pRoot != NULL) { - m_pRoot->DeleteGroup(GetGroupData()); - } - Clear(); - } - - void Clear() - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListItem *pItem = NULL; - CListContainer *pContainer = NULL; - - while(iter != m_Entrys.end()) - { - delete *iter; - if(m_pRoot && m_pRoot->GetPosition() == *iter) - { - if(GetType() == ROOT) - m_pRoot->SetPosition(NULL); - else - m_pRoot->SetPosition(this); - } - - iter++; - } - m_Entrys.clear(); - } - - void SetGroupData(G GroupData) - { - m_GroupData = GroupData; - } - - bool IsEmpty() - { - return m_Entrys.empty(); - } - - CListEntry *GetLastOwnEntry() - { - if(m_Entrys.empty()) - return NULL; - - return *(--m_Entrys.end()); - } - - CListEntry *GetLastEntry() - { - if(!m_Entrys.empty()) - { - - CListEntry *pEntry = *(--m_Entrys.end()); - if(pEntry->GetType() == ITEM || !((CListContainer*)pEntry)->IsOpen() || ((CListContainer*)pEntry)->IsEmpty()) - return pEntry; - return ((CListContainer*)pEntry)->GetLastEntry(); - } - return NULL; - } - - CListEntry *GetFirstEntry() - { - if(!m_Entrys.empty()) - return *(m_Entrys.begin()); - return NULL; - } - - CListEntry *GetNextEntry() - { - if(!IsOpen() || m_Entrys.empty()) - { - if(!m_pParent) - return NULL; - return m_pParent->GetNextEntry(this); - } - - return *m_Entrys.begin(); - } - - CListEntry *GetNextEntry(CListEntry *pEntry) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - while(iter != m_Entrys.end()) - { - if((CListEntry*)(*iter) == pEntry) - { - if(++iter == m_Entrys.end()) - { - if(m_pParent == NULL) - return NULL; - return m_pParent->GetNextEntry(this); - } - else - return *iter; - } - iter++; - } - return NULL; - } - - CListEntry *GetPreviousEntry(CListEntry *pEntry) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - - while(iter != m_Entrys.end()) - { - if((CListEntry*)(*iter) == pEntry) - { - if(iter == m_Entrys.begin()) - { - if(m_pParent == NULL) - return NULL; - return this; - } - else - { - iter--; - if((*iter)->GetType() == CONTAINER) - { - CListContainer* pContainer = (CListContainer*)*iter; - if(pContainer->IsOpen() && !pContainer->IsEmpty()) - return pContainer->GetLastEntry(); - } - return *iter; - } - } - iter++; - } - return NULL; - } - - virtual CListItem *InsertItem(iterator _Where,T Entry) - { - CListItem *pItem = new CListItem(this,Entry); - pItem->SetRoot(m_pRoot); - m_Entrys.insert(_Where,pItem); - - m_pRoot->UpdateEntryCount(); - - return pItem; - } - - virtual CListContainer *InsertGroup(iterator _Where,G Group) - { - CListContainer *pGroup = new CListContainer(this); - pGroup->SetGroupData(Group); - pGroup->SetRoot(m_pRoot); - m_Entrys.insert(_Where,(CListEntry*)pGroup); - - m_pRoot->UpdateEntryCount(); - - return pGroup; - } - - virtual CListItem * AddItem(T Entry) - { - return InsertItem(end(),Entry); - } - - virtual CListContainer * AddGroup(G Group) - { - return InsertGroup(end(),Group); - } - - - - virtual void RemoveGroup(G Group) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListContainer *pContainer = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == CONTAINER) - { - pContainer = (CListContainer*)(*iter); - if(pContainer->GetGroupData() == Group) - { - pContainer->Clear(); - if(m_pRoot && m_pRoot->GetPosition() == *iter) - { - CListEntry *pPosition = (*iter)->GetPreviousEntry(); - if(!pPosition) - pPosition = (*iter)->GetNextEntry(); - m_pRoot->SetPosition(pPosition); - } - delete *iter; - m_Entrys.erase(iter); - m_pRoot->UpdateEntryCount(); - return; - } - } - iter++; - } - } - - virtual void RemoveItem(T Entry) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListItem *pItem = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == ITEM) - { - pItem = (CListItem*)(*iter); - if(pItem->GetItemData() == Entry) - { - if(m_pRoot && m_pRoot->GetPosition() == *iter) - { - CListEntry *pPosition = (*iter)->GetPreviousEntry(); - if(!pPosition) - pPosition = (*iter)->GetNextEntry(); - m_pRoot->SetPosition(pPosition); - } - delete *iter; - - m_Entrys.erase(iter); - m_pRoot->UpdateEntryCount(); - return; - } - } - iter++; - } - } - - CListContainer *GetGroup(G Group) - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListContainer *pContainer = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == CONTAINER) - { - pContainer = (CListContainer*)(*iter); - if(pContainer->GetGroupData() == Group) - return pContainer; - } - iter++; - } - return NULL; - } - - G GetGroupData() - { - return m_GroupData; - } - - bool IsOpen() - { - return m_bOpen; - } - - void ToggleOpen() - { - m_bOpen = !m_bOpen; - - m_pRoot->UpdateEntryCount(); - if(m_pRoot) - m_pRoot->SetPosition(this); - } - - void SetOpen(bool bOpen = true) - { - if(bOpen == m_bOpen) - return; - - m_bOpen = bOpen; - - m_pRoot->UpdateEntryCount(); - if(m_pRoot) - m_pRoot->SetPosition(this); - } - - void CollapseAll() - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListContainer* pContainer = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == CONTAINER) - { - pContainer = (CListContainer*)(*iter); - pContainer->CollapseAll(); - pContainer->SetOpen(false); - } - iter++; - } - } - - void ExpandAll() - { - list< CListEntry* >::iterator iter = m_Entrys.begin(); - CListContainer* pContainer = NULL; - while(iter != m_Entrys.end()) - { - if((*iter)->GetType() == CONTAINER) - { - pContainer = (CListContainer*)(*iter); - pContainer->ExpandAll(); - pContainer->SetOpen(true); - } - iter++; - } - } - - void UpdateEntryCount() - { - m_iEntryCount = 0; - - int iIndex = GetIndex()+1; - - if(!IsOpen()) - return; - - list< CListEntry* >::iterator iter = m_Entrys.begin(); - while(iter != m_Entrys.end()) - { - (*iter)->SetIndex(iIndex+m_iEntryCount); - (*iter)->UpdateEntryCount(); - m_iEntryCount += 1+(*iter)->GetEntryCount(); - - iter++; - } - - if(GetType() == ROOT) - { - if(GetPosition() == NULL && !m_Entrys.empty()) - SetPosition(*m_Entrys.begin()); - else - SetPosition(GetPosition()); - } - } - - template - void sort(_Pr3 _Pred) { - m_Entrys.sort(_Pred); - UpdateEntryCount(); - m_pRoot->SetPosition(m_pRoot->GetPosition()); - } - -private: - typename list< CListEntry* > m_Entrys; - G m_GroupData; - bool m_bOpen; -}; - - -template class CLCDList : public CLCDTextObject, public CListContainer -{ -friend CListContainer; -friend CListItem; -public: - //************************************************************************ - // Constructor - //************************************************************************ - CLCDList() : CListContainer(NULL) - { - m_pScrollbar = NULL; - m_iIndention = 10; - m_iColumns = 1; - m_bDrawTreeLines = true; - m_iEntryHeight = 10; - } - - //************************************************************************ - // Destructor - //************************************************************************ - ~CLCDList() - { - } - - //************************************************************************ - // Initializes the list - //************************************************************************ - bool Initialize() - { - if(!CLCDTextObject::Initialize()) - return false; - - return true; - } - - //************************************************************************ - // Deinitializes the list - //************************************************************************ - bool Shutdown() - { - if(!CLCDTextObject::Shutdown()) - return false; - - Clear(); - - return true; - } - - //************************************************************************ - // updates the list - //************************************************************************ - bool Update() - { - if(!CLCDTextObject::Update()) - return false; - - return true; - } - - //************************************************************************ - // draws the list - //************************************************************************ - bool Draw(CLCDGfx *pGfx) - { - if(!CLCDTextObject::Draw(pGfx)) - return false; - - SelectObject(pGfx->GetHDC(),m_hFont); - - POINT ptPrevViewportOrg = { 0, 0 }; - HRGN hRgn = NULL; - int iHeight = 0,iLimit=0; - int iYOffset = 0, iXOffset=0; - int iColWidth = (GetWidth()- (m_iColumns-1)*3)/m_iColumns; - int iSpace = GetHeight() - (GetHeight()/m_iEntryHeight)*m_iEntryHeight; - int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; - - int iEntriesDrawn = 0; - CListEntry *pPosition = m_Position; - - // if nothing is selected, skip drawing - if(pPosition == NULL) - return true; - - bool bDrawGroup = false; - bool bSelected = false; - - // calculate the start offset - - if(m_iStartIndex < pPosition->GetIndex()) - { - while(pPosition && pPosition->GetIndex() != m_iStartIndex) - pPosition = pPosition->GetPreviousEntry(); - } - - if(m_iStartIndex > 0 && pPosition->GetIndex() > 0) - pPosition = pPosition->GetPreviousEntry(); - - for(int iCol = 0;iColGetIndex() < m_iStartIndex) - iHeight -= m_iEntryHeight-iSpace; - else if(GetEntryCount() >= (iPerPage/m_iColumns) +1) - iHeight = iSpace; - } - - // bottom selection - while(pPosition != NULL ) - { - iYOffset = iHeight; - - bSelected = m_Position == pPosition; - bDrawGroup = pPosition->GetType() == CONTAINER; - - // ~~~~~~~~~~~~~~~~~~~~~~ - // Draw tree lines - // ~~~~~~~~~~~~~~~~~~~~~~ - - // set the clip region for the entry - int iClipHeight = m_iEntryHeight; - if(GetOrigin().y+iYOffset+iClipHeight > GetOrigin().y + GetHeight()) - iClipHeight = GetHeight() - iYOffset; - - pGfx->SetClipRegion(GetOrigin().x+iXOffset,GetOrigin().y+iYOffset, - iColWidth, iClipHeight); - - // offset the control at its origin so entry use (0,0) - SetViewportOrgEx(pGfx->GetHDC(), - GetOrigin().x+iXOffset, - GetOrigin().y+iYOffset, - &ptPrevViewportOrg); - - if(m_bDrawTreeLines) - { - for(int i=1;iGetLevel();i++) - { - if(i == pPosition->GetLevel()-1) - { - // - - pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2,i*m_iIndention,m_iEntryHeight/2); - // | - if(pPosition == ((CListContainer*)pPosition->GetParent())->GetLastOwnEntry()) - pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2); - // | - // | - else - pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); - } - else - { - CListEntry *pPosition2 = pPosition; - for(int j = pPosition->GetLevel();j>i+1;j--) - pPosition2 = pPosition2->GetParent(); - // | - // | - if(pPosition2 != ((CListContainer*)pPosition2->GetParent())->GetLastOwnEntry()) - pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); - } - } - } - - // ~~~~~~~~~~~~~~~~~~~~~~ - // Draw the entry - // ~~~~~~~~~~~~~~~~~~~~~~ - pGfx->SetClipRegion(GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, - GetOrigin().y+iYOffset, - iColWidth-(pPosition->GetLevel()-1)*m_iIndention, - iClipHeight); - // set the offset - SetViewportOrgEx(pGfx->GetHDC(), - GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, - GetOrigin().y+iYOffset, - &ptPrevViewportOrg); - - // draw the entry - if(!bDrawGroup) - DrawEntry(pGfx,((CListItem*)pPosition)->GetItemData(),bSelected); - else - // draw the group - DrawGroup(pGfx,((CListContainer*)pPosition)->GetGroupData(),((CListContainer*)pPosition)->IsOpen(),bSelected); - - // ~~~~~~~~~~~~~~~~~~~~~~ - - if(pPosition->GetIndex() >= m_iStartIndex && iHeight + m_iEntryHeight <= GetHeight()) - iEntriesDrawn++; - - iHeight += m_iEntryHeight; - pPosition = pPosition->GetNextEntry(); - - if(iHeight >= GetHeight()) - break; - } - if(iCol != m_iColumns-1) - { - pGfx->SetClipRegion(GetOrigin().x, - GetOrigin().y, - GetWidth(), - GetHeight()); - // set the offset - SetViewportOrgEx(pGfx->GetHDC(), - GetOrigin().x, - GetOrigin().y, - &ptPrevViewportOrg); - - pGfx->DrawLine(iCol*3 + iColWidth + 1,0,iCol*3 + iColWidth + 1,GetHeight()); - } - iXOffset += 3 + iColWidth; - } - - if(m_pScrollbar) - { - m_pScrollbar->ScrollTo(m_iStartIndex); - m_pScrollbar->SetSliderSize(iEntriesDrawn); - } - return true; - } - - - void SetPosition(CListEntry *pEntry) - { - CListContainer::SetPosition(pEntry); - - if(pEntry == NULL) - return; - - int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; - m_iStartIndex = pEntry->GetIndex(); - if(m_iStartIndex + (iPerPage-1) > GetEntryCount()-1) - m_iStartIndex = (GetEntryCount()-1)-(iPerPage-1); - if(m_iStartIndex < 0) - m_iStartIndex = 0; - } - - //************************************************************************ - // scrolls up - //************************************************************************ - bool ScrollUp() - { - if(m_Position != NULL) - { - CListEntry *pEntry = m_Position->GetPreviousEntry(); - if(pEntry != NULL) - { - m_Position = pEntry; - - int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; - if(m_Position->GetIndex() < m_iStartIndex) - m_iStartIndex--; - return true; - } - } - return false; - } - - //************************************************************************ - // scrolls down - //************************************************************************ - bool ScrollDown() - { - if(m_Position != NULL) - { - CListEntry *pEntry = m_Position->GetNextEntry(); - if(pEntry != NULL) - { - m_Position = pEntry; - - int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; - if(m_Position->GetIndex() >= m_iStartIndex + iPerPage) - m_iStartIndex++; - return true; - } - } - return false; - } - - //************************************************************************ - // returns the selected list entry - //************************************************************************ - CListEntry *GetSelectedEntry() - { - return m_Position; - } - - //************************************************************************ - // associates a scrollbar with the list - //************************************************************************ - void SetScrollbar(CLCDBar *pScrollbar) - { - m_pScrollbar = pScrollbar; - if(m_pScrollbar) - { - m_pScrollbar->SetRange(0,m_iEntryCount-1); - m_pScrollbar->ScrollTo(m_Position != NULL?m_Position->GetIndex():0); - - m_pScrollbar->SetAlignment(TOP); - } - } - - //************************************************************************ - // sets the group indention in pixels - //************************************************************************ - void SetIndention(int iIndention) - { - m_iIndention = iIndention; - } - - //************************************************************************ - // sets the lists entry height - //************************************************************************ - void SetEntryHeight(int iEntryHeight) - { - m_iEntryHeight = iEntryHeight; - } - - //************************************************************************ - // returns the lists entry height - //************************************************************************ - int GetEntryHeight() - { - return m_iEntryHeight; - } - - //************************************************************************ - // enables/disables drawing of treelines - //************************************************************************ - void SetDrawTreeLines(bool bDraw) - { - m_bDrawTreeLines = bDraw; - } - - //************************************************************************ - // sets the amount of columns the list uses - //************************************************************************ - void SetColumns(int iColumns) - { - if(m_iColumns == iColumns) - return; - m_iColumns = iColumns; - SetPosition(GetPosition()); - } -protected: - //************************************************************************ - // called when the lists size has changed - //************************************************************************ - void OnSizeChanged() - { - SetPosition(GetPosition()); - } - - //************************************************************************ - // updates the list's entry count - //************************************************************************ - void UpdateEntryCount() - { - CListContainer::UpdateEntryCount(); - if(m_pScrollbar) - { - m_pScrollbar->SetRange(0,m_iEntryCount-1); - if(GetPosition() != NULL) - m_pScrollbar->ScrollTo(GetPosition()->GetIndex()); - } - } - - //************************************************************************ - // Called to delete the specified entry - //************************************************************************ - virtual void DeleteEntry(T Entry) - { - - } - - //************************************************************************ - // Called to delete the specified group - //************************************************************************ - virtual void DeleteGroup(G Group) - { - - } - - //************************************************************************ - // Called to draw the specified entry - //************************************************************************ - virtual void DrawEntry(CLCDGfx *pGfx,T Entry, bool bSelected) - { - } - - //************************************************************************ - // Called to draw the specified entry - //************************************************************************ - virtual void DrawGroup(CLCDGfx *pGfx,G Group, bool bOpen, bool bSelected) - { - } - - - -protected: - int m_iStartIndex; - int m_iColumns; - - bool m_bDrawTreeLines; - int m_iIndention; - int m_iEntryHeight; - CLCDBar *m_pScrollbar; -}; - +#ifndef _CLCDLIST_H_ +#define _CLCDLIST_H_ + +#include "CLCDTextObject.h" +#include "CLCDBar.h" +#include + + +enum EListEntryType { ROOT = 0,CONTAINER = 1,ITEM = 2}; + +template class CListEntry +{ +public: + CListEntry(CListEntry *pParent) + { + m_iIndex = -1; + m_iEntryCount = 0; + m_Position = NULL; + m_pParent = pParent; + if(pParent == NULL) + { + m_iLevel = 0; + m_eType = ROOT; + m_pRoot = this; + } + else + m_iLevel = m_pParent->GetLevel()+1; + } + + virtual ~CListEntry() + { + + } + + int GetLevel() + { + return m_iLevel; + } + + virtual CListEntry *GetNextEntry() + { + if(m_pParent == NULL) + return NULL; + + return m_pParent->GetNextEntry(this); + } + + virtual CListEntry *GetPreviousEntry() + { + if(m_pParent == NULL) + return NULL; + + return m_pParent->GetPreviousEntry(this); + } + + virtual CListEntry *GetNextEntry(CListEntry *pEntry) + { + return NULL; + } + + virtual CListEntry *GetPreviousEntry(CListEntry *pEntry) + { + return NULL; + } + + EListEntryType GetType() + { + return m_eType; + } + + int GetEntryCount() + { + return m_iEntryCount; + } + + virtual void UpdateEntryCount() + { + m_iEntryCount = 0; + } + + void SetRoot(CListEntry* pRoot) + { + m_pRoot = pRoot; + } + + virtual void DeleteItem(T Entry) + { + } + + virtual void DeleteGroup(G Group) + { + } + + CListEntry *GetPosition() + { + return m_Position; + } + + virtual void SetPosition(CListEntry *pPosition) + { + m_Position = pPosition; + } + + CListEntry *GetParent() + { + return m_pParent; + } + + int GetIndex() + { + return m_iIndex; + } + + void SetIndex(int iIndex) + { + m_iIndex = iIndex; + } + +protected: + int m_iIndex; + int m_iEntryCount; + int m_iLevel; + EListEntryType m_eType; + CListEntry *m_pParent; + CListEntry *m_pRoot; + CListEntry *m_Position; +}; + +template class CListItem : public CListEntry +{ +public: + CListItem(CListEntry *pParent,T Entry) : CListEntry(pParent) + { + m_Item = Entry; + m_eType = ITEM; + } + + ~CListItem() + { + m_pRoot->DeleteItem(GetItemData()); + } + + T GetItemData() + { + return m_Item; + } +private: + T m_Item; +}; + +template class CListContainer : public CListEntry +{ +public: + typedef typename list* >::iterator iterator; + + typename list* >::iterator end() + { + return m_Entrys.end(); + } + + typename list* >::iterator begin() + { + return m_Entrys.begin(); + } + + typename list* >::size_type size() + { + return m_Entrys.size(); + } + + bool empty() + { + bool b = m_Entrys.empty(); + return m_Entrys.empty(); + } + + CListContainer(CListEntry *pParent) : CListEntry(pParent) + { + if(m_pParent != NULL) + { + m_eType = CONTAINER; + m_bOpen = false; + } + else + m_bOpen = true; + } + + ~CListContainer() + { + if(m_pRoot != NULL) { + m_pRoot->DeleteGroup(GetGroupData()); + } + Clear(); + } + + void Clear() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListItem *pItem = NULL; + CListContainer *pContainer = NULL; + + while(iter != m_Entrys.end()) + { + delete *iter; + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + if(GetType() == ROOT) + m_pRoot->SetPosition(NULL); + else + m_pRoot->SetPosition(this); + } + + iter++; + } + m_Entrys.clear(); + } + + void SetGroupData(G GroupData) + { + m_GroupData = GroupData; + } + + bool IsEmpty() + { + return m_Entrys.empty(); + } + + CListEntry *GetLastOwnEntry() + { + if(m_Entrys.empty()) + return NULL; + + return *(--m_Entrys.end()); + } + + CListEntry *GetLastEntry() + { + if(!m_Entrys.empty()) + { + + CListEntry *pEntry = *(--m_Entrys.end()); + if(pEntry->GetType() == ITEM || !((CListContainer*)pEntry)->IsOpen() || ((CListContainer*)pEntry)->IsEmpty()) + return pEntry; + return ((CListContainer*)pEntry)->GetLastEntry(); + } + return NULL; + } + + CListEntry *GetFirstEntry() + { + if(!m_Entrys.empty()) + return *(m_Entrys.begin()); + return NULL; + } + + CListEntry *GetNextEntry() + { + if(!IsOpen() || m_Entrys.empty()) + { + if(!m_pParent) + return NULL; + return m_pParent->GetNextEntry(this); + } + + return *m_Entrys.begin(); + } + + CListEntry *GetNextEntry(CListEntry *pEntry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + while(iter != m_Entrys.end()) + { + if((CListEntry*)(*iter) == pEntry) + { + if(++iter == m_Entrys.end()) + { + if(m_pParent == NULL) + return NULL; + return m_pParent->GetNextEntry(this); + } + else + return *iter; + } + iter++; + } + return NULL; + } + + CListEntry *GetPreviousEntry(CListEntry *pEntry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + + while(iter != m_Entrys.end()) + { + if((CListEntry*)(*iter) == pEntry) + { + if(iter == m_Entrys.begin()) + { + if(m_pParent == NULL) + return NULL; + return this; + } + else + { + iter--; + if((*iter)->GetType() == CONTAINER) + { + CListContainer* pContainer = (CListContainer*)*iter; + if(pContainer->IsOpen() && !pContainer->IsEmpty()) + return pContainer->GetLastEntry(); + } + return *iter; + } + } + iter++; + } + return NULL; + } + + virtual CListItem *InsertItem(iterator _Where,T Entry) + { + CListItem *pItem = new CListItem(this,Entry); + pItem->SetRoot(m_pRoot); + m_Entrys.insert(_Where,pItem); + + m_pRoot->UpdateEntryCount(); + + return pItem; + } + + virtual CListContainer *InsertGroup(iterator _Where,G Group) + { + CListContainer *pGroup = new CListContainer(this); + pGroup->SetGroupData(Group); + pGroup->SetRoot(m_pRoot); + m_Entrys.insert(_Where,(CListEntry*)pGroup); + + m_pRoot->UpdateEntryCount(); + + return pGroup; + } + + virtual CListItem * AddItem(T Entry) + { + return InsertItem(end(),Entry); + } + + virtual CListContainer * AddGroup(G Group) + { + return InsertGroup(end(),Group); + } + + + + virtual void RemoveGroup(G Group) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer *pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + if(pContainer->GetGroupData() == Group) + { + pContainer->Clear(); + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + CListEntry *pPosition = (*iter)->GetPreviousEntry(); + if(!pPosition) + pPosition = (*iter)->GetNextEntry(); + m_pRoot->SetPosition(pPosition); + } + delete *iter; + m_Entrys.erase(iter); + m_pRoot->UpdateEntryCount(); + return; + } + } + iter++; + } + } + + virtual void RemoveItem(T Entry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListItem *pItem = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == ITEM) + { + pItem = (CListItem*)(*iter); + if(pItem->GetItemData() == Entry) + { + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + CListEntry *pPosition = (*iter)->GetPreviousEntry(); + if(!pPosition) + pPosition = (*iter)->GetNextEntry(); + m_pRoot->SetPosition(pPosition); + } + delete *iter; + + m_Entrys.erase(iter); + m_pRoot->UpdateEntryCount(); + return; + } + } + iter++; + } + } + + CListContainer *GetGroup(G Group) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer *pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + if(pContainer->GetGroupData() == Group) + return pContainer; + } + iter++; + } + return NULL; + } + + G GetGroupData() + { + return m_GroupData; + } + + bool IsOpen() + { + return m_bOpen; + } + + void ToggleOpen() + { + m_bOpen = !m_bOpen; + + if (m_pRoot) { + m_pRoot->UpdateEntryCount(); + m_pRoot->SetPosition(this); + } + } + + void SetOpen(bool bOpen = true) + { + if(bOpen == m_bOpen) + return; + + m_bOpen = bOpen; + + if (m_pRoot) { + m_pRoot->UpdateEntryCount(); + m_pRoot->SetPosition(this); + } + } + + void CollapseAll() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer* pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + pContainer->CollapseAll(); + pContainer->SetOpen(false); + } + iter++; + } + } + + void ExpandAll() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer* pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + pContainer->ExpandAll(); + pContainer->SetOpen(true); + } + iter++; + } + } + + void UpdateEntryCount() + { + m_iEntryCount = 0; + + int iIndex = GetIndex()+1; + + if(!IsOpen()) + return; + + list< CListEntry* >::iterator iter = m_Entrys.begin(); + while(iter != m_Entrys.end()) + { + (*iter)->SetIndex(iIndex+m_iEntryCount); + (*iter)->UpdateEntryCount(); + m_iEntryCount += 1+(*iter)->GetEntryCount(); + + iter++; + } + + if(GetType() == ROOT) + { + if(GetPosition() == NULL && !m_Entrys.empty()) + SetPosition(*m_Entrys.begin()); + else + SetPosition(GetPosition()); + } + } + + template + void sort(_Pr3 _Pred) { + m_Entrys.sort(_Pred); + UpdateEntryCount(); + m_pRoot->SetPosition(m_pRoot->GetPosition()); + } + +private: + typename list< CListEntry* > m_Entrys; + G m_GroupData; + bool m_bOpen; +}; + + +template class CLCDList : public CLCDTextObject, public CListContainer +{ +friend CListContainer; +friend CListItem; +public: + //************************************************************************ + // Constructor + //************************************************************************ + CLCDList() : CListContainer(NULL) + { + m_pScrollbar = NULL; + m_iIndention = 10; + m_iColumns = 1; + m_bDrawTreeLines = true; + m_iEntryHeight = 10; + } + + //************************************************************************ + // Destructor + //************************************************************************ + ~CLCDList() + { + } + + //************************************************************************ + // Initializes the list + //************************************************************************ + bool Initialize() + { + if(!CLCDTextObject::Initialize()) + return false; + + return true; + } + + //************************************************************************ + // Deinitializes the list + //************************************************************************ + bool Shutdown() + { + if(!CLCDTextObject::Shutdown()) + return false; + + Clear(); + + return true; + } + + //************************************************************************ + // updates the list + //************************************************************************ + bool Update() + { + if(!CLCDTextObject::Update()) + return false; + + return true; + } + + //************************************************************************ + // draws the list + //************************************************************************ + bool Draw(CLCDGfx *pGfx) + { + if(!CLCDTextObject::Draw(pGfx)) + return false; + + SelectObject(pGfx->GetHDC(),m_hFont); + + POINT ptPrevViewportOrg = { 0, 0 }; + HRGN hRgn = NULL; + int iHeight = 0,iLimit=0; + int iYOffset = 0, iXOffset=0; + int iColWidth = (GetWidth()- (m_iColumns-1)*3)/m_iColumns; + int iSpace = GetHeight() - (GetHeight()/m_iEntryHeight)*m_iEntryHeight; + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + + int iEntriesDrawn = 0; + CListEntry *pPosition = m_Position; + + // if nothing is selected, skip drawing + if(pPosition == NULL) + return true; + + bool bDrawGroup = false; + bool bSelected = false; + + // calculate the start offset + + if(m_iStartIndex < pPosition->GetIndex()) + { + while(pPosition && pPosition->GetIndex() != m_iStartIndex) + pPosition = pPosition->GetPreviousEntry(); + } + + if(m_iStartIndex > 0 && pPosition->GetIndex() > 0) + pPosition = pPosition->GetPreviousEntry(); + + for(int iCol = 0;iColGetIndex() < m_iStartIndex) + iHeight -= m_iEntryHeight-iSpace; + else if(GetEntryCount() >= (iPerPage/m_iColumns) +1) + iHeight = iSpace; + } + + // bottom selection + while(pPosition != NULL ) + { + iYOffset = iHeight; + + bSelected = m_Position == pPosition; + bDrawGroup = pPosition->GetType() == CONTAINER; + + // ~~~~~~~~~~~~~~~~~~~~~~ + // Draw tree lines + // ~~~~~~~~~~~~~~~~~~~~~~ + + // set the clip region for the entry + int iClipHeight = m_iEntryHeight; + if(GetOrigin().y+iYOffset+iClipHeight > GetOrigin().y + GetHeight()) + iClipHeight = GetHeight() - iYOffset; + + pGfx->SetClipRegion(GetOrigin().x+iXOffset,GetOrigin().y+iYOffset, + iColWidth, iClipHeight); + + // offset the control at its origin so entry use (0,0) + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x+iXOffset, + GetOrigin().y+iYOffset, + &ptPrevViewportOrg); + + if(m_bDrawTreeLines) + { + for(int i=1;iGetLevel();i++) + { + if(i == pPosition->GetLevel()-1) + { + // - + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2,i*m_iIndention,m_iEntryHeight/2); + // | + if(pPosition == ((CListContainer*)pPosition->GetParent())->GetLastOwnEntry()) + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2); + // | + // | + else + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); + } + else + { + CListEntry *pPosition2 = pPosition; + for(int j = pPosition->GetLevel();j>i+1;j--) + pPosition2 = pPosition2->GetParent(); + // | + // | + if(pPosition2 != ((CListContainer*)pPosition2->GetParent())->GetLastOwnEntry()) + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); + } + } + } + + // ~~~~~~~~~~~~~~~~~~~~~~ + // Draw the entry + // ~~~~~~~~~~~~~~~~~~~~~~ + pGfx->SetClipRegion(GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, + GetOrigin().y+iYOffset, + iColWidth-(pPosition->GetLevel()-1)*m_iIndention, + iClipHeight); + // set the offset + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, + GetOrigin().y+iYOffset, + &ptPrevViewportOrg); + + // draw the entry + if(!bDrawGroup) + DrawEntry(pGfx,((CListItem*)pPosition)->GetItemData(),bSelected); + else + // draw the group + DrawGroup(pGfx,((CListContainer*)pPosition)->GetGroupData(),((CListContainer*)pPosition)->IsOpen(),bSelected); + + // ~~~~~~~~~~~~~~~~~~~~~~ + + if(pPosition->GetIndex() >= m_iStartIndex && iHeight + m_iEntryHeight <= GetHeight()) + iEntriesDrawn++; + + iHeight += m_iEntryHeight; + pPosition = pPosition->GetNextEntry(); + + if(iHeight >= GetHeight()) + break; + } + if(iCol != m_iColumns-1) + { + pGfx->SetClipRegion(GetOrigin().x, + GetOrigin().y, + GetWidth(), + GetHeight()); + // set the offset + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x, + GetOrigin().y, + &ptPrevViewportOrg); + + pGfx->DrawLine(iCol*3 + iColWidth + 1,0,iCol*3 + iColWidth + 1,GetHeight()); + } + iXOffset += 3 + iColWidth; + } + + if(m_pScrollbar) + { + m_pScrollbar->ScrollTo(m_iStartIndex); + m_pScrollbar->SetSliderSize(iEntriesDrawn); + } + return true; + } + + + void SetPosition(CListEntry *pEntry) + { + CListContainer::SetPosition(pEntry); + + if(pEntry == NULL) + return; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + m_iStartIndex = pEntry->GetIndex(); + if(m_iStartIndex + (iPerPage-1) > GetEntryCount()-1) + m_iStartIndex = (GetEntryCount()-1)-(iPerPage-1); + if(m_iStartIndex < 0) + m_iStartIndex = 0; + } + + //************************************************************************ + // scrolls up + //************************************************************************ + bool ScrollUp() + { + if(m_Position != NULL) + { + CListEntry *pEntry = m_Position->GetPreviousEntry(); + if(pEntry != NULL) + { + m_Position = pEntry; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + if(m_Position->GetIndex() < m_iStartIndex) + m_iStartIndex--; + return true; + } + } + return false; + } + + //************************************************************************ + // scrolls down + //************************************************************************ + bool ScrollDown() + { + if(m_Position != NULL) + { + CListEntry *pEntry = m_Position->GetNextEntry(); + if(pEntry != NULL) + { + m_Position = pEntry; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + if(m_Position->GetIndex() >= m_iStartIndex + iPerPage) + m_iStartIndex++; + return true; + } + } + return false; + } + + //************************************************************************ + // returns the selected list entry + //************************************************************************ + CListEntry *GetSelectedEntry() + { + return m_Position; + } + + //************************************************************************ + // associates a scrollbar with the list + //************************************************************************ + void SetScrollbar(CLCDBar *pScrollbar) + { + m_pScrollbar = pScrollbar; + if(m_pScrollbar) + { + m_pScrollbar->SetRange(0,m_iEntryCount-1); + m_pScrollbar->ScrollTo(m_Position != NULL?m_Position->GetIndex():0); + + m_pScrollbar->SetAlignment(TOP); + } + } + + //************************************************************************ + // sets the group indention in pixels + //************************************************************************ + void SetIndention(int iIndention) + { + m_iIndention = iIndention; + } + + //************************************************************************ + // sets the lists entry height + //************************************************************************ + void SetEntryHeight(int iEntryHeight) + { + m_iEntryHeight = iEntryHeight; + } + + //************************************************************************ + // returns the lists entry height + //************************************************************************ + int GetEntryHeight() + { + return m_iEntryHeight; + } + + //************************************************************************ + // enables/disables drawing of treelines + //************************************************************************ + void SetDrawTreeLines(bool bDraw) + { + m_bDrawTreeLines = bDraw; + } + + //************************************************************************ + // sets the amount of columns the list uses + //************************************************************************ + void SetColumns(int iColumns) + { + if(m_iColumns == iColumns) + return; + m_iColumns = iColumns; + SetPosition(GetPosition()); + } +protected: + //************************************************************************ + // called when the lists size has changed + //************************************************************************ + void OnSizeChanged() + { + SetPosition(GetPosition()); + } + + //************************************************************************ + // updates the list's entry count + //************************************************************************ + void UpdateEntryCount() + { + CListContainer::UpdateEntryCount(); + if(m_pScrollbar) + { + m_pScrollbar->SetRange(0,m_iEntryCount-1); + if(GetPosition() != NULL) + m_pScrollbar->ScrollTo(GetPosition()->GetIndex()); + } + } + + //************************************************************************ + // Called to delete the specified entry + //************************************************************************ + virtual void DeleteEntry(T Entry) + { + + } + + //************************************************************************ + // Called to delete the specified group + //************************************************************************ + virtual void DeleteGroup(G Group) + { + + } + + //************************************************************************ + // Called to draw the specified entry + //************************************************************************ + virtual void DrawEntry(CLCDGfx *pGfx,T Entry, bool bSelected) + { + } + + //************************************************************************ + // Called to draw the specified entry + //************************************************************************ + virtual void DrawGroup(CLCDGfx *pGfx,G Group, bool bOpen, bool bSelected) + { + } + + + +protected: + int m_iStartIndex; + int m_iColumns; + + bool m_bDrawTreeLines; + int m_iIndention; + int m_iEntryHeight; + CLCDBar *m_pScrollbar; +}; + #endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.cpp index e1cc493a16..e21a125906 100644 --- a/plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.cpp +++ b/plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.cpp @@ -1,451 +1,453 @@ -#include "stdafx.h" - -#include "CLCDGfx.h" -#include "CLCDObject.h" -#include "CLCDScreen.h" - -#include "CLCDConnection.h" -#include "CLCDConnectionLogitech.h" -#include "CLCDOutputManager.h" -#include - -CLCDOutputManager *CLCDOutputManager::m_pInstance = NULL; - -//************************************************************************ -// Constructor -//************************************************************************ -CLCDOutputManager::CLCDOutputManager() -{ - ASSERT(m_pInstance == NULL); - - m_pInstance = this; - m_strAppletName = _T(""); - m_pbButtonStates = NULL; - m_pActiveScreen = NULL; - m_bInitialized = false; - - m_dwButtonRepeatDelay = 300; - m_dwLastUpdate = 0; -} - -//************************************************************************ -// Destructor -//************************************************************************ -CLCDOutputManager::~CLCDOutputManager() -{ - m_pInstance = NULL; -} - -//************************************************************************ -// Gets the OutputManager Instance -//************************************************************************ -CLCDOutputManager* CLCDOutputManager::GetInstance() -{ - ASSERT(m_pInstance != NULL); - - return m_pInstance; -} - -//************************************************************************ -// returns the active lcdconnection -//************************************************************************ -CLCDConnection *CLCDOutputManager::GetLCDConnection() -{ - ASSERT(m_pLcdConnection != NULL); - return m_pLcdConnection; -} - -//************************************************************************ -// returns the active scren -//************************************************************************ -CLCDScreen *CLCDOutputManager::GetActiveScreen() -{ - return m_pActiveScreen; -} - -//************************************************************************ -// Initializes the OutputManager -//************************************************************************ -bool CLCDOutputManager::Initialize(tstring strAppletName,bool bAutostart, bool bConfigDialog) -{ - srand ( time(NULL) ); - - InitDebug(); - - m_strAppletName = strAppletName; - - m_pGfx = new CLCDGfx(); - - m_pLcdConnection = new CLCDConnectionLogitech(); - if(!m_pLcdConnection->Initialize(m_strAppletName,bAutostart,bConfigDialog)) - return false; - - - m_bInitialized = true; - - m_dwLastUpdate = GetTickCount(); - return true; -} - -//************************************************************************ -// return wether the Outputmanager is initialized -//************************************************************************ -bool CLCDOutputManager::IsInitialized() -{ - return m_bInitialized; -} - -//************************************************************************ -// Deinitializes the Outputmanager -//************************************************************************ -bool CLCDOutputManager::Shutdown() -{ - ASSERT(NULL != m_pLcdConnection); - ASSERT(NULL != m_pGfx); - - // Shutdown all screens - vector::iterator iter = m_Screens.begin(); - while(iter != m_Screens.end()) - { - (*(iter))->Shutdown(); - iter++; - } - - m_pLcdConnection->Shutdown(); - - - delete m_pLcdConnection; - - UnInitDebug(); - m_bInitialized = false; - return true; -} - -//************************************************************************ -// called by CLCDConnection when connected to a device -//************************************************************************ -void CLCDOutputManager::OnDeviceConnected() { - InitializeGfxObject(); - OnConnectionChanged(CONNECTED); -} - -//************************************************************************ -// called by CLCDConnection when disconnected from a device -//************************************************************************ -void CLCDOutputManager::OnDeviceDisconnected() { - DeinitializeGfxObject(); - OnConnectionChanged(DISCONNECTED); -} - -//************************************************************************ -// Initializes the CGfx Object -//************************************************************************ -void CLCDOutputManager::InitializeGfxObject() { - if(m_pGfx->IsInitialized()) - return; - - TRACE(_T("CLCDOutputManager::UpdateGfxObject(): initializing CLCDGfx\n")); - SIZE size; - size = m_pLcdConnection->GetDisplaySize(); - - m_pGfx->Initialize(size.cx,size.cy,m_pLcdConnection->GetColorCount(), m_pLcdConnection->GetPixelBuffer()); - - int iButtonCount = m_pLcdConnection->GetButtonCount(); - - m_pbButtonStates = (bool*)malloc(sizeof(bool)*iButtonCount); - m_pdwButtonRepeatTimers = (DWORD*)malloc(sizeof(DWORD)*iButtonCount); - m_pdwButtonRepeatStarts = (DWORD*)malloc(sizeof(DWORD)*iButtonCount); - for(int i=0;i::iterator iter = m_Screens.begin(); - while(iter != m_Screens.end()) - { - (*(iter))->OnSizeChanged(); - iter++; - } - - OnLCDConnected(); -} - -//************************************************************************ -// Deinitializes the CGfx Object -//************************************************************************ -void CLCDOutputManager::DeinitializeGfxObject() { - if(!m_pGfx->IsInitialized()) - return; - - TRACE(_T("CLCDOutputManager::UpdateGfxObject(): shutting down CLCDGfx\n")); - - m_pGfx->Shutdown(); - free(m_pbButtonStates); - free(m_pdwButtonRepeatTimers); - free(m_pdwButtonRepeatStarts); - - OnLCDDisconnected(); -} - -//************************************************************************ -// Update all Screens & draw -//************************************************************************ -bool CLCDOutputManager::Update() -{ - ASSERT(m_bInitialized); - - DWORD dwElapsed = GetTickCount() - m_dwLastUpdate; - - // Update the active screen - if(m_pActiveScreen != NULL) - { - m_pActiveScreen->Update(); - // Check if the active screen has expired - if(m_pActiveScreen->HasExpired()) - { - // Call event handlers - DeactivateScreen(); - return true; - } - } - - // Update - m_pLcdConnection->Update(); - - // skip button checking and drawing if there is no connection to a device - if(!m_pLcdConnection || m_pLcdConnection->GetConnectionState() != CONNECTED) - return true; - - - // Handle buttons - bool bState = false; - int iId = 0; - for(int i = 0; i< m_pLcdConnection->GetButtonCount();i++) - { - // get current state - bState = m_pLcdConnection->GetButtonState(i); - // handle input event - if(bState != m_pbButtonStates[i]) - { - iId = m_pLcdConnection->GetButtonId(i); - if(bState) { - OnLCDButtonDown(iId); - } else { - OnLCDButtonUp(iId); - } - m_pdwButtonRepeatStarts[i] = GetTickCount(); - m_pdwButtonRepeatTimers[i] = m_pdwButtonRepeatStarts[i] + m_dwButtonRepeatDelay; - } - // check if repeat event should be sent - else if(bState && m_pdwButtonRepeatTimers[i] <= GetTickCount()) - { - iId = m_pLcdConnection->GetButtonId(i); - - // reduce the delay by 5% per second - DWORD dwNewDelay = m_dwButtonRepeatDelay - ((float)m_dwButtonRepeatDelay * 0.05 * (GetTickCount() - m_pdwButtonRepeatStarts[i]) / 250); - // delay may not be less than 25% of the original value - if(dwNewDelay < m_dwButtonRepeatDelay * 0.25) - dwNewDelay = m_dwButtonRepeatDelay * 0.25; - - m_pdwButtonRepeatTimers[i] = GetTickCount() + dwNewDelay; - - OnLCDButtonRepeated(iId); - } - // save the current state - m_pbButtonStates[i] = bState; - } - - // Draw - - if(m_pActiveScreen != NULL && m_pGfx->IsInitialized()) - { - m_pGfx->BeginDraw(); - m_pGfx->ClearScreen(); - m_pActiveScreen->Draw(m_pGfx); - m_pGfx->EndDraw(); - - m_pLcdConnection->SetAlert(m_pActiveScreen->GetAlert()); - m_pLcdConnection->Draw(); - } - else - m_pLcdConnection->HideApplet(); - - m_dwLastUpdate = GetTickCount(); - return true; -} - -//************************************************************************ -// Deactivates the active screen -//************************************************************************ -bool CLCDOutputManager::DeactivateScreen() -{ - if(m_pActiveScreen == NULL) - return false; - - CLCDScreen *pActiveScreen = m_pActiveScreen; - m_pActiveScreen = NULL; - - if(pActiveScreen->HasExpired()) - { - pActiveScreen->OnExpiration(); - OnScreenExpired(pActiveScreen); - } - else - { - OnScreenDeactivated(pActiveScreen); - pActiveScreen->OnDeactivation(); - } - return true; -} - -//************************************************************************ -// Activates the specified screen -//************************************************************************ -bool CLCDOutputManager::ActivateScreen(CLCDScreen *pScreen) -{ - if(m_pActiveScreen == pScreen) - return false; - - // If another screen is currently active, deactivate it - if(m_pActiveScreen != NULL) - DeactivateScreen(); - - m_pActiveScreen = pScreen; - m_pActiveScreen->OnActivation(); - return true; -} - -//************************************************************************ -// Adds a screen to the managers list -//************************************************************************ -bool CLCDOutputManager::AddScreen(CLCDScreen *pScreen) -{ - // Check if the screen is already managed - vector::iterator iter = m_Screens.begin(); - while(iter != m_Screens.end()) - { - if(*(iter) == pScreen) - return false; - iter++; - } - - m_Screens.push_back(pScreen); - return true; -} - -//************************************************************************ -// Removes a screen from the managers list -//************************************************************************ -bool CLCDOutputManager::RemoveScreen(CLCDScreen *pScreen) -{ - if(m_Screens.empty()) - return false; - - // Find the screen and remove it from the list of managed screens - vector::iterator iter = m_Screens.begin(); - while(iter != m_Screens.end()) - { - if(*(iter) == pScreen) - { - m_Screens.erase(iter); - return true; - } - iter++; - } - return false; -} - -//************************************************************************ -// starts a screen transition -//************************************************************************ -void CLCDOutputManager::StartTransition(ETransitionType eTransition,LPRECT rect) -{ - m_pGfx->StartTransition(eTransition,rect); -} - -//************************************************************************ -// specifies the button repeat delay -//************************************************************************ -void CLCDOutputManager::SetButtonRepeatDelay(DWORD dwDelay) -{ - m_dwButtonRepeatDelay = dwDelay; -} - -//************************************************************************ -// Called when a screen has been deactivated -//************************************************************************ -void CLCDOutputManager::OnScreenDeactivated(CLCDScreen *pScreen) -{ -} - -//************************************************************************ -// Called when a screen has expired -//************************************************************************ -void CLCDOutputManager::OnScreenExpired(CLCDScreen *pScreen) -{ -} - -//************************************************************************ -// Called when an LCD button is repeated -//************************************************************************ -void CLCDOutputManager::OnLCDButtonRepeated(int iButton) -{ - if(m_pActiveScreen) { - m_pActiveScreen->OnLCDButtonRepeated(iButton); - } -} - -//************************************************************************ -// Called when an LCD button is pressed -//************************************************************************ -void CLCDOutputManager::OnLCDButtonDown(int iButton) -{ - if(m_pActiveScreen) - m_pActiveScreen->OnLCDButtonDown(iButton); -} - -//************************************************************************ -// Called when an LCD button is released -//************************************************************************ -void CLCDOutputManager::OnLCDButtonUp(int iButton) -{ - if(m_pActiveScreen) - m_pActiveScreen->OnLCDButtonUp(iButton); -} - -//************************************************************************ -// Called when the connection state has changed -//************************************************************************ -void CLCDOutputManager::OnConnectionChanged(int iConnectionState) -{ -} - -//************************************************************************ -// Called when the LCD has been plugged in -//************************************************************************ -void CLCDOutputManager::OnLCDConnected() -{ -} - -//************************************************************************ -// Called when the LCD has been unplugged -//************************************************************************ -void CLCDOutputManager::OnLCDDisconnected() -{ -} - -//************************************************************************ -// Called by the LCDManager to open a config dialog -//************************************************************************ -DWORD WINAPI CLCDOutputManager::configDialogCallback(IN int connection,IN const PVOID pContext) { - return CLCDOutputManager::GetInstance()->OnConfigDialogRequest(connection,pContext); -} -//************************************************************************ -// Called when a config dialog is requested -//************************************************************************ -DWORD CLCDOutputManager::OnConfigDialogRequest(int connection, const PVOID pContext) { - return 0; +#include "stdafx.h" + +#include "CLCDGfx.h" +#include "CLCDObject.h" +#include "CLCDScreen.h" + +#include "CLCDConnection.h" +#include "CLCDConnectionLogitech.h" +#include "CLCDOutputManager.h" +#include + +CLCDOutputManager *CLCDOutputManager::m_pInstance = NULL; + +//************************************************************************ +// Constructor +//************************************************************************ +CLCDOutputManager::CLCDOutputManager() +{ + ASSERT(m_pInstance == NULL); + + m_pInstance = this; + m_strAppletName = _T(""); + m_pbButtonStates = NULL; + m_pActiveScreen = NULL; + m_bInitialized = false; + + m_dwButtonRepeatDelay = 300; + m_dwLastUpdate = 0; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CLCDOutputManager::~CLCDOutputManager() +{ + m_pInstance = NULL; +} + +//************************************************************************ +// Gets the OutputManager Instance +//************************************************************************ +CLCDOutputManager* CLCDOutputManager::GetInstance() +{ + ASSERT(m_pInstance != NULL); + + return m_pInstance; +} + +//************************************************************************ +// returns the active lcdconnection +//************************************************************************ +CLCDConnection *CLCDOutputManager::GetLCDConnection() +{ + ASSERT(m_pLcdConnection != NULL); + return m_pLcdConnection; +} + +//************************************************************************ +// returns the active scren +//************************************************************************ +CLCDScreen *CLCDOutputManager::GetActiveScreen() +{ + return m_pActiveScreen; +} + +//************************************************************************ +// Initializes the OutputManager +//************************************************************************ +bool CLCDOutputManager::Initialize(tstring strAppletName,bool bAutostart, bool bConfigDialog) +{ + srand ( time(NULL) ); + + InitDebug(); + + m_strAppletName = strAppletName; + + m_pGfx = new CLCDGfx(); + + m_pLcdConnection = new CLCDConnectionLogitech(); + if(!m_pLcdConnection->Initialize(m_strAppletName,bAutostart,bConfigDialog)) + return false; + + + m_bInitialized = true; + + m_dwLastUpdate = GetTickCount(); + return true; +} + +//************************************************************************ +// return wether the Outputmanager is initialized +//************************************************************************ +bool CLCDOutputManager::IsInitialized() +{ + return m_bInitialized; +} + +//************************************************************************ +// Deinitializes the Outputmanager +//************************************************************************ +bool CLCDOutputManager::Shutdown() +{ + ASSERT(NULL != m_pLcdConnection); + ASSERT(NULL != m_pGfx); + + // Shutdown all screens + vector::iterator iter = m_Screens.begin(); + while(iter != m_Screens.end()) + { + (*(iter))->Shutdown(); + iter++; + } + + m_pLcdConnection->Shutdown(); + + + delete m_pLcdConnection; + + UnInitDebug(); + m_bInitialized = false; + return true; +} + +//************************************************************************ +// called by CLCDConnection when connected to a device +//************************************************************************ +void CLCDOutputManager::OnDeviceConnected() { + InitializeGfxObject(); + OnConnectionChanged(CONNECTED); +} + +//************************************************************************ +// called by CLCDConnection when disconnected from a device +//************************************************************************ +void CLCDOutputManager::OnDeviceDisconnected() { + DeinitializeGfxObject(); + OnConnectionChanged(DISCONNECTED); +} + +//************************************************************************ +// Initializes the CGfx Object +//************************************************************************ +void CLCDOutputManager::InitializeGfxObject() { + if(m_pGfx->IsInitialized()) + return; + + TRACE(_T("CLCDOutputManager::UpdateGfxObject(): initializing CLCDGfx\n")); + SIZE size; + size = m_pLcdConnection->GetDisplaySize(); + + m_pGfx->Initialize(size.cx,size.cy,m_pLcdConnection->GetColorCount(), m_pLcdConnection->GetPixelBuffer()); + + int iButtonCount = m_pLcdConnection->GetButtonCount(); + + m_pbButtonStates = (bool*)malloc(sizeof(bool)*iButtonCount); + m_pdwButtonRepeatTimers = (DWORD*)malloc(sizeof(DWORD)*iButtonCount); + m_pdwButtonRepeatStarts = (DWORD*)malloc(sizeof(DWORD)*iButtonCount); + for(int i=0;i::iterator iter = m_Screens.begin(); + while(iter != m_Screens.end()) + { + (*(iter))->OnSizeChanged(); + iter++; + } + + OnLCDConnected(); +} + +//************************************************************************ +// Deinitializes the CGfx Object +//************************************************************************ +void CLCDOutputManager::DeinitializeGfxObject() { + if(!m_pGfx->IsInitialized()) + return; + + TRACE(_T("CLCDOutputManager::UpdateGfxObject(): shutting down CLCDGfx\n")); + + m_pGfx->Shutdown(); + free(m_pbButtonStates); + free(m_pdwButtonRepeatTimers); + free(m_pdwButtonRepeatStarts); + + OnLCDDisconnected(); +} + +//************************************************************************ +// Update all Screens & draw +//************************************************************************ +bool CLCDOutputManager::Update() +{ + ASSERT(m_bInitialized); + + DWORD dwElapsed = GetTickCount() - m_dwLastUpdate; + + // Update the active screen + if(m_pActiveScreen != NULL) + { + m_pActiveScreen->Update(); + // Check if the active screen has expired + if(m_pActiveScreen->HasExpired()) + { + // Call event handlers + DeactivateScreen(); + return true; + } + } + + if(!m_pLcdConnection) + return true; + // Update + m_pLcdConnection->Update(); + + // skip button checking and drawing if there is no connection to a device + if(m_pLcdConnection->GetConnectionState() != CONNECTED) + return true; + + + // Handle buttons + bool bState = false; + int iId = 0; + for(int i = 0; i < m_pLcdConnection->GetButtonCount(); i ++) + { + // get current state + bState = m_pLcdConnection->GetButtonState(i); + // handle input event + if(bState != m_pbButtonStates[i]) + { + iId = m_pLcdConnection->GetButtonId(i); + if(bState) { + OnLCDButtonDown(iId); + } else { + OnLCDButtonUp(iId); + } + m_pdwButtonRepeatStarts[i] = GetTickCount(); + m_pdwButtonRepeatTimers[i] = m_pdwButtonRepeatStarts[i] + m_dwButtonRepeatDelay; + } + // check if repeat event should be sent + else if(bState && m_pdwButtonRepeatTimers[i] <= GetTickCount()) + { + iId = m_pLcdConnection->GetButtonId(i); + + // reduce the delay by 5% per second + DWORD dwNewDelay = m_dwButtonRepeatDelay - ((float)m_dwButtonRepeatDelay * 0.05 * (GetTickCount() - m_pdwButtonRepeatStarts[i]) / 250); + // delay may not be less than 25% of the original value + if(dwNewDelay < m_dwButtonRepeatDelay * 0.25) + dwNewDelay = m_dwButtonRepeatDelay * 0.25; + + m_pdwButtonRepeatTimers[i] = GetTickCount() + dwNewDelay; + + OnLCDButtonRepeated(iId); + } + // save the current state + m_pbButtonStates[i] = bState; + } + + // Draw + + if(m_pActiveScreen != NULL && m_pGfx->IsInitialized()) + { + m_pGfx->BeginDraw(); + m_pGfx->ClearScreen(); + m_pActiveScreen->Draw(m_pGfx); + m_pGfx->EndDraw(); + + m_pLcdConnection->SetAlert(m_pActiveScreen->GetAlert()); + m_pLcdConnection->Draw(); + } + else + m_pLcdConnection->HideApplet(); + + m_dwLastUpdate = GetTickCount(); + return true; +} + +//************************************************************************ +// Deactivates the active screen +//************************************************************************ +bool CLCDOutputManager::DeactivateScreen() +{ + if(m_pActiveScreen == NULL) + return false; + + CLCDScreen *pActiveScreen = m_pActiveScreen; + m_pActiveScreen = NULL; + + if(pActiveScreen->HasExpired()) + { + pActiveScreen->OnExpiration(); + OnScreenExpired(pActiveScreen); + } + else + { + OnScreenDeactivated(pActiveScreen); + pActiveScreen->OnDeactivation(); + } + return true; +} + +//************************************************************************ +// Activates the specified screen +//************************************************************************ +bool CLCDOutputManager::ActivateScreen(CLCDScreen *pScreen) +{ + if(m_pActiveScreen == pScreen) + return false; + + // If another screen is currently active, deactivate it + if(m_pActiveScreen != NULL) + DeactivateScreen(); + + m_pActiveScreen = pScreen; + m_pActiveScreen->OnActivation(); + return true; +} + +//************************************************************************ +// Adds a screen to the managers list +//************************************************************************ +bool CLCDOutputManager::AddScreen(CLCDScreen *pScreen) +{ + // Check if the screen is already managed + vector::iterator iter = m_Screens.begin(); + while(iter != m_Screens.end()) + { + if(*(iter) == pScreen) + return false; + iter++; + } + + m_Screens.push_back(pScreen); + return true; +} + +//************************************************************************ +// Removes a screen from the managers list +//************************************************************************ +bool CLCDOutputManager::RemoveScreen(CLCDScreen *pScreen) +{ + if(m_Screens.empty()) + return false; + + // Find the screen and remove it from the list of managed screens + vector::iterator iter = m_Screens.begin(); + while(iter != m_Screens.end()) + { + if(*(iter) == pScreen) + { + m_Screens.erase(iter); + return true; + } + iter++; + } + return false; +} + +//************************************************************************ +// starts a screen transition +//************************************************************************ +void CLCDOutputManager::StartTransition(ETransitionType eTransition,LPRECT rect) +{ + m_pGfx->StartTransition(eTransition,rect); +} + +//************************************************************************ +// specifies the button repeat delay +//************************************************************************ +void CLCDOutputManager::SetButtonRepeatDelay(DWORD dwDelay) +{ + m_dwButtonRepeatDelay = dwDelay; +} + +//************************************************************************ +// Called when a screen has been deactivated +//************************************************************************ +void CLCDOutputManager::OnScreenDeactivated(CLCDScreen *pScreen) +{ +} + +//************************************************************************ +// Called when a screen has expired +//************************************************************************ +void CLCDOutputManager::OnScreenExpired(CLCDScreen *pScreen) +{ +} + +//************************************************************************ +// Called when an LCD button is repeated +//************************************************************************ +void CLCDOutputManager::OnLCDButtonRepeated(int iButton) +{ + if(m_pActiveScreen) { + m_pActiveScreen->OnLCDButtonRepeated(iButton); + } +} + +//************************************************************************ +// Called when an LCD button is pressed +//************************************************************************ +void CLCDOutputManager::OnLCDButtonDown(int iButton) +{ + if(m_pActiveScreen) + m_pActiveScreen->OnLCDButtonDown(iButton); +} + +//************************************************************************ +// Called when an LCD button is released +//************************************************************************ +void CLCDOutputManager::OnLCDButtonUp(int iButton) +{ + if(m_pActiveScreen) + m_pActiveScreen->OnLCDButtonUp(iButton); +} + +//************************************************************************ +// Called when the connection state has changed +//************************************************************************ +void CLCDOutputManager::OnConnectionChanged(int iConnectionState) +{ +} + +//************************************************************************ +// Called when the LCD has been plugged in +//************************************************************************ +void CLCDOutputManager::OnLCDConnected() +{ +} + +//************************************************************************ +// Called when the LCD has been unplugged +//************************************************************************ +void CLCDOutputManager::OnLCDDisconnected() +{ +} + +//************************************************************************ +// Called by the LCDManager to open a config dialog +//************************************************************************ +DWORD WINAPI CLCDOutputManager::configDialogCallback(IN int connection,IN const PVOID pContext) { + return CLCDOutputManager::GetInstance()->OnConfigDialogRequest(connection,pContext); +} +//************************************************************************ +// Called when a config dialog is requested +//************************************************************************ +DWORD CLCDOutputManager::OnConfigDialogRequest(int connection, const PVOID pContext) { + return 0; } \ No newline at end of file diff --git a/protocols/Sametime/src/meanwhile/src/mpi/mpi.c b/protocols/Sametime/src/meanwhile/src/mpi/mpi.c index 1a33e98525..29626c80a2 100644 --- a/protocols/Sametime/src/meanwhile/src/mpi/mpi.c +++ b/protocols/Sametime/src/meanwhile/src/mpi/mpi.c @@ -1643,11 +1643,11 @@ mw_mp_err mw_mp_exptmod(mw_mp_int *a, mw_mp_int *b, mw_mp_int *m, mw_mp_int *c) { mw_mp_int s, x, mu; mw_mp_err res; - mw_mp_digit d, *db = DIGITS(b); + mw_mp_digit d, *db; mw_mp_size ub = USED(b); - /// Miranda NG adaptation start - MSVC - ///int dig, bit; - int bit; + /// Miranda NG adaptation start - MSVC + ///int dig, bit; + int bit; mw_mp_size dig; /// Miranda NG adaptation end @@ -1673,6 +1673,7 @@ mw_mp_err mw_mp_exptmod(mw_mp_int *a, mw_mp_int *b, mw_mp_int *m, mw_mp_int *c) goto CLEANUP; /* Loop over digits of b in ascending order, except highest order */ + db = DIGITS(b); for(dig = 0; dig < (ub - 1); dig++) { d = *db++; -- cgit v1.2.3