summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRozhuk Ivan <rozhuk.im@gmail.com>2014-11-29 20:36:41 +0000
committerRozhuk Ivan <rozhuk.im@gmail.com>2014-11-29 20:36:41 +0000
commita5574d24bc8c0e94c8880c75f0fd27d08d30b98b (patch)
tree362540cc48ae27617199a503e9f52d80e15c6033
parentf73897a8ca83abe24a15016808790e01d061cb36 (diff)
MirandaG15: code cleanup.
git-svn-id: http://svn.miranda-ng.org/main/trunk@11162 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--plugins/MirandaG15/src/CAppletManager.cpp3699
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDList.h1886
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.cpp902
-rw-r--r--protocols/Sametime/src/meanwhile/src/mpi/mpi.c9
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;i<iCount;i++)
- {
- /**if(ppProtocolDescriptor[i]->type != PROTOTYPE_PROTOCOL)
- continue;**/
- if (ppAccounts[i]->bIsEnabled == 0)
- continue;
-
- iProtoCount++;
- pProtoData = new CProtocolData();
- pProtoData->iStatus = ID_STATUS_OFFLINE;
- pProtoData->strProtocol = toTstring(ppAccounts[i]->szModuleName);
- pProtoData->lTimeStamp = 0;
-
- // try to create an irc connection for that protocol (will fail if it is no irc protocol)
- pIRCConnection = CreateIRCConnection(pProtoData->strProtocol);
-
- m_vProtocolData.push_back(pProtoData);
- }
-
- // load status bitmaps
- m_ahStatusBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_OFFLINE),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
- m_ahStatusBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_ONLINE),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
- m_ahStatusBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_AWAY),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
- m_ahStatusBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_NA),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
- m_ahStatusBitmaps[4] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_OCCUPIED),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
- m_ahStatusBitmaps[5] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_DND),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
- m_ahStatusBitmaps[6] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_INVISIBLE),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
- m_ahStatusBitmaps[7] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_FFC),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
- // Load event bitmaps
- m_ahEventBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_MSG),IMAGE_BITMAP,6, 6, LR_MONOCHROME);
- m_ahEventBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_CON),IMAGE_BITMAP,6, 6, LR_MONOCHROME);
- m_ahEventBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_USER),IMAGE_BITMAP,6, 6, LR_MONOCHROME);
- m_ahEventBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_INFO),IMAGE_BITMAP,6, 6, LR_MONOCHROME);
-
- m_ahLargeEventBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_MSG_LARGE),IMAGE_BITMAP,8, 8, LR_MONOCHROME);
- m_ahLargeEventBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_CON_LARGE),IMAGE_BITMAP,8, 8, LR_MONOCHROME);
- m_ahLargeEventBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_USER_LARGE),IMAGE_BITMAP,8, 8, LR_MONOCHROME);
- m_ahLargeEventBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_INFO_LARGE),IMAGE_BITMAP,8, 8, LR_MONOCHROME);
-
- // start the update timer
- m_uiTimer = SetTimer(0,0,1000/10,CAppletManager::UpdateTimer);
-
- return true;
-}
-
-//************************************************************************
-// Deinitializes the AppletManager
-//************************************************************************
-bool CAppletManager::Shutdown()
-{
- if(!IsInitialized())
- return false;
-
- // stop the update timer
- KillTimer(0,m_uiTimer);
-
- // delete status bitmaps
- for(int i=0;i<8;i++)
- DeleteObject(m_ahStatusBitmaps[i]);
-
- // delete event bitmaps
- for(int i=0;i<8;i++)
- {
- DeleteObject(m_ahLargeEventBitmaps[i]);
- DeleteObject(m_ahEventBitmaps[i]);
- }
-
- // unhook the events
- UnhookEvent(m_hMIHookMessageWindowEvent);
- UnhookEvent(m_hMIHookEventAdded);
- UnhookEvent(m_hMIHookStatusChanged);
- UnhookEvent(m_hMIHookProtoAck);
- UnhookEvent(m_hMIHookContactDeleted);
- UnhookEvent(m_hMIHookContactAdded);
- UnhookEvent(m_hMIHookSettingChanged);
- UnhookEvent(m_hMIHookChatEvent);
-
- // unhook all irc protocols, and delete the classes
- vector<CIRCConnection*>::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<CProtocolData*>::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<CProtocolData*>::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<SMessageJob*>::iterator iter = m_MessageJobs.begin();
- while(iter != m_MessageJobs.end())
- {
- // TODO: Fertigstellen
- if((*iter)->dwTimestamp + 15*1000 < GetTickCount())
- {
- CEvent Event;
-
- Event.eType = EVENT_MESSAGE_ACK;
- Event.hValue = (*iter)->hEvent;
- Event.hContact = (*iter)->hContact;
- Event.iValue = ACKRESULT_FAILED;
- Event.strValue = TranslateString(_T("Timeout: No response from contact/server"));
-
- HandleEvent(&Event);
-
- SMessageJob *pJob = *iter;
- m_MessageJobs.erase(iter);
- free(pJob->pcBuffer);
- delete(pJob);
- break;
- }
- iter++;
- }
-}
-
-//************************************************************************
-// adds a message job to the list
-//************************************************************************
-void CAppletManager::AddMessageJob(SMessageJob *pJob)
-{
- m_MessageJobs.push_back(pJob);
-}
-
-//************************************************************************
-// finishes a message job
-//************************************************************************
-void CAppletManager::FinishMessageJob(SMessageJob *pJob)
-{
- list<SMessageJob*>::iterator iter = m_MessageJobs.begin();
- while(iter != m_MessageJobs.end())
- {
- if((*iter) == pJob)
- {
- char *szProto = 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<SMessageJob*>::iterator iter = m_MessageJobs.begin();
- while(iter != m_MessageJobs.end())
- {
- if((*iter) == pJob)
- {
- SMessageJob *pJob = *iter;
- m_MessageJobs.erase(iter);
- free(pJob->pcBuffer);
- delete(pJob);
- return;
- }
- }
-}
-
-//************************************************************************
-// 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,&timestamp);
- pEvent->bTime = true;
- /*
- if(dbevent.eventType == EVENTTYPE_MESSAGE && dbevent.flags & DBEF_READ) {
- free(dbevent.pBlob);
- return false;
- }
- */
- // Skip events from the user except for messages
- if(dbevent.eventType != EVENTTYPE_MESSAGE && (dbevent.flags & DBEF_SENT))
- {
- free(dbevent.pBlob);
- return false;
- }
-
- int msglen = 0;
-
- tstring strName = CAppletManager::GetContactDisplayname(hContact,true);
-
- switch(dbevent.eventType) {
- case EVENTTYPE_MESSAGE:
- msglen = (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<CIRCConnection*>::iterator iter = m_vIRCConnections.begin();
- while(iter != m_vIRCConnections.end())
- {
- if((*iter)->strProtocol == strProtocol)
- return *iter;
- iter++;
- }
- return NULL;
-}
-
-//************************************************************************
-// creates the IRC connection class for the specified protocol
-//************************************************************************
-CIRCConnection *CAppletManager::CreateIRCConnection(tstring strProtocol)
-{
- 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<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
- while(iter != m_LIRCHistorys.end())
- {
- if((*iter)->hContact == hContact)
- return *iter;
- iter++;
- }
- return NULL;
-}
-
-CIRCHistory *CAppletManager::GetIRCHistoryByName(tstring strProtocol,tstring strChannel)
-{
- list<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
- while(iter != m_LIRCHistorys.end())
- {
- if((*iter)->strChannel == strChannel && (*iter)->strProtocol == strProtocol)
- return *iter;
- iter++;
- }
- return NULL;
-}
-
-//************************************************************************
-// deletes the history class for the specified IRC channel
-//************************************************************************
-void CAppletManager::DeleteIRCHistory(MCONTACT hContact)
-{
- list<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
- while(iter != m_LIRCHistorys.end())
- {
- if((*iter)->hContact == hContact)
- {
- CIRCHistory *pHistory = *iter;
- pHistory->LMessages.clear();
- pHistory->LUsers.clear();
-
- m_LIRCHistorys.erase(iter);
-
- delete pHistory;
-
- return;
- }
- iter++;
- }
-}
-
-//************************************************************************
-// creates a history class for the specified IRC channel
-//************************************************************************
-CIRCHistory *CAppletManager::CreateIRCHistory(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<tstring>::iterator iter = pHistory->LUsers.begin();
- while(iter != pHistory->LUsers.end())
- {
- if((*iter) == strFullNick)
- {
- pHistory->LUsers.erase(iter);
- break;
- }
- iter++;
- }
- }
- break;
- }
- case GC_EVENT_QUIT:
- if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
- Event.bNotification = true;
- Event.strValue = TranslateString(strText.empty()?_T("%s has disconnected"):_T("%s has disconnected: %s"),strNick.c_str(),strText.c_str());
- break;
- case GC_EVENT_KICK:
- if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
- Event.bNotification = true;
- Event.strValue = TranslateString(_T("%s has kicked %s: %s"),strStatus.c_str(),strNick.c_str(),strText.c_str());
- break;
- case GC_EVENT_NICK:
- {
- if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
- Event.bNotification = true;
- tstring strFullNick = toTstring(gce->ptszNick);
-
- if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strText.length() > (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<tstring>::iterator iter = pHistory->LUsers.begin();
- while(iter != pHistory->LUsers.end())
- {
- if((*iter) == strFullNick)
- (*iter) = strText;
- iter++;
- }
- }
- break;
- }
- case GC_EVENT_NOTICE:
- if(CConfig::GetBoolSetting(NOTIFY_IRC_NOTICES))
- Event.bNotification = true;
- Event.strValue = TranslateString(_T("Notice from %s: %s"),strNick.c_str(),strText.c_str());
- break;
- case GC_EVENT_TOPIC:
- if(CConfig::GetBoolSetting(NOTIFY_IRC_CHANNEL))
- Event.bNotification = true;
- Event.strValue = TranslateString(_T("Topic is now '%s' (set by %s)"),strText.c_str(),strNick.c_str());
- break;
- case GC_EVENT_ADDSTATUS:
- {
- if(CConfig::GetBoolSetting(NOTIFY_IRC_STATUS))
- Event.bNotification = true;
- tstring strNick2 = toTstring(gce->ptszStatus);
- if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strNick2.length() > (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<CIRCHistory*>::iterator iter = CAppletManager::GetInstance()->m_LIRCHistorys.begin();
- list<tstring>::iterator nickiter;
- while(iter != CAppletManager::GetInstance()->m_LIRCHistorys.end())
- {
- nickiter = (*iter)->LUsers.begin();
- while(nickiter != (*iter)->LUsers.end())
- {
- if((*nickiter) == strNick)
- {
- (*iter)->LMessages.push_back(IRCMsg);
- // Limit the size to the session logsize
- if((*iter)->LMessages.size() > CConfig::GetIntSetting(SESSION_LOGSIZE))
- (*iter)->LMessages.pop_front();
-
- (*iter)->LUsers.erase(nickiter);
-
- Event.hContact = (*iter)->hContact;
- tstring strName = CAppletManager::GetContactDisplayname((*iter)->hContact,true);
- Event.strDescription = strName + _T(" - ")+Event.strValue;
- Event.strSummary = _T("(") + toTstring(gcd->pszModule) + _T(") ")+strName;
- CAppletManager::GetInstance()->HandleEvent(&Event);
- break;
- }
- nickiter++;
- }
- iter++;
- }
- }
- TRACE(_T("OK!\n"));
- return 0;
- }
- else if(gcd->ptszID != NULL)
- {
- TRACE(_T("OK!\n"));
- return 0;
- }
-
- if(pHistory)
- {
- tstring strChannel = pHistory->strChannel;
- if(CConfig::GetBoolSetting(NOTIFY_CHANNELCUTOFF) && strNick.length() > CConfig::GetIntSetting(NOTIFY_CHANNELCUTOFF_OFFSET)) {
- strChannel = strChannel.erase(CConfig::GetIntSetting(NOTIFY_CHANNELCUTOFF_OFFSET)) + _T("...");
- }
- Event.strDescription = strChannel + _T(" - ")+Event.strValue;
- Event.strSummary = _T("(") + toTstring(gcd->pszModule) + _T(") ")+pHistory->strChannel;
- }
- else
- Event.strDescription = Event.strValue;
-
- TRACE(_T("OK!\n"));
-
- CAppletManager::GetInstance()->HandleEvent(&Event);
-
- return 0;
-}
-
-//************************************************************************
-// message window event hook function
-//************************************************************************
-int CAppletManager::HookMessageWindowEvent(WPARAM wParam, LPARAM lParam)
-{
- MessageWindowEventData *mwed = (MessageWindowEventData*)lParam;
- CEvent Event;
-
- Event.eType = EVENT_MESSAGEWINDOW;
- Event.hContact = mwed->hContact;
- Event.iValue = mwed->uType;
-
- CAppletManager::GetInstance()->HandleEvent(&Event);
-
- return 0;
-}
-
-
-//************************************************************************
-// contact typing notification hook function
-//************************************************************************
-int CAppletManager::HookContactIsTyping(WPARAM wParam, LPARAM lParam)
-{
- 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<SMessageJob*>::iterator iter = CAppletManager::GetInstance()->m_MessageJobs.begin();
- while(iter != CAppletManager::GetInstance()->m_MessageJobs.end())
- {
- if((*iter)->hEvent == pAck->hProcess && (*iter)->hContact == pAck->hContact)
- {
- Event.eType = EVENT_MESSAGE_ACK;
- Event.hValue = pAck->hProcess;
- Event.hContact = pAck->hContact;
- Event.iValue = pAck->result;
- if(pAck->lParam != 0)
- Event.strValue = toTstring((char*)pAck->lParam);
- else
- Event.strValue = _T("");
-
- if(Event.iValue == ACKRESULT_SUCCESS)
- CAppletManager::GetInstance()->FinishMessageJob((*iter));
- else
- CAppletManager::GetInstance()->CancelMessageJob((*iter));
-
- CAppletManager::GetInstance()->HandleEvent(&Event);
-
- return 0;
- }
- iter++;
- }
- }
- // protocol status changes
- else if(pAck->type == ACKTYPE_STATUS && pAck->result == ACKRESULT_SUCCESS)
- {
- int iOldStatus = (int)pAck->hProcess;
- int iNewStatus = pAck->lParam;
-
- tstring strProto = toTstring(pAck->szModule);
-
- // ignore metacontacts status changes
- if(toLower(strProto) == _T("metacontacts"))
- return 0;
-
- CProtocolData *pProtoData = CAppletManager::GetInstance()->GetProtocolData(strProto);
- if(pProtoData == NULL)
- return 0;
-
- if(iNewStatus == ID_STATUS_CONNECTING)
- return 0;
-
- if(iNewStatus == ID_STATUS_OFFLINE)
- {
- if(CConfig::GetBoolSetting(NOTIFY_PROTO_SIGNOFF))
- Event.bNotification = true;
- Event.eType = EVENT_PROTO_DISCONNECTED;
- }
- else if(iNewStatus != ID_STATUS_OFFLINE && iOldStatus == ID_STATUS_CONNECTING)
- {
- if(CConfig::GetBoolSetting(NOTIFY_PROTO_SIGNON))
- Event.bNotification = true;
- Event.eType = EVENT_PROTO_CONNECTED;
- }
- else
- {
- if(CConfig::GetBoolSetting(NOTIFY_PROTO_STATUS))
- Event.bNotification = true;
- Event.eType = EVENT_PROTO_STATUS;
- }
-
- // Skip connecting status
- if(iNewStatus == ID_STATUS_CONNECTING)
- return 0;
-
- pProtoData->iStatus = iNewStatus;
-
- Event.iValue = iNewStatus;
- Event.strValue = strProto;
-
- // set the event description / summary
- tstring strStatus = toTstring((char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iNewStatus, 0));
- Event.strDescription = _T("(") + Event.strValue + _T(") ")+ TranslateString(_T("You are now %s"),strStatus.c_str());
- Event.strSummary = TranslateString(_T("Protocol status change"));
-
- if(Event.eType != EVENT_PROTO_STATUS)
- pProtoData->lTimeStamp = GetTickCount();
-
- CAppletManager::GetInstance()->HandleEvent(&Event);
- //CAppletManager::GetInstance()->ActivateNotificationScreen(&Event);
- }
-
- return 0;
-}
-
-//************************************************************************
-// contact added hook function
-//************************************************************************
-int CAppletManager::HookContactAdded(WPARAM wParam, LPARAM lParam)
-{
- CEvent Event;
- Event.eType = EVENT_CONTACT_ADDED;
- Event.hContact = 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;i<iCount;i++)
+ {
+ /**if(ppProtocolDescriptor[i]->type != PROTOTYPE_PROTOCOL)
+ continue;**/
+ if (ppAccounts[i]->bIsEnabled == 0)
+ continue;
+
+ iProtoCount++;
+ pProtoData = new CProtocolData();
+ pProtoData->iStatus = ID_STATUS_OFFLINE;
+ pProtoData->strProtocol = toTstring(ppAccounts[i]->szModuleName);
+ pProtoData->lTimeStamp = 0;
+
+ // try to create an irc connection for that protocol (will fail if it is no irc protocol)
+ pIRCConnection = CreateIRCConnection(pProtoData->strProtocol);
+
+ m_vProtocolData.push_back(pProtoData);
+ }
+
+ // load status bitmaps
+ m_ahStatusBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_OFFLINE),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_ONLINE),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_AWAY),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_NA),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[4] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_OCCUPIED),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[5] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_DND),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[6] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_INVISIBLE),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ m_ahStatusBitmaps[7] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_FFC),IMAGE_BITMAP,5, 5, LR_MONOCHROME);
+ // Load event bitmaps
+ m_ahEventBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_MSG),IMAGE_BITMAP,6, 6, LR_MONOCHROME);
+ m_ahEventBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_CON),IMAGE_BITMAP,6, 6, LR_MONOCHROME);
+ m_ahEventBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_USER),IMAGE_BITMAP,6, 6, LR_MONOCHROME);
+ m_ahEventBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_INFO),IMAGE_BITMAP,6, 6, LR_MONOCHROME);
+
+ m_ahLargeEventBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_MSG_LARGE),IMAGE_BITMAP,8, 8, LR_MONOCHROME);
+ m_ahLargeEventBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_CON_LARGE),IMAGE_BITMAP,8, 8, LR_MONOCHROME);
+ m_ahLargeEventBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_USER_LARGE),IMAGE_BITMAP,8, 8, LR_MONOCHROME);
+ m_ahLargeEventBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_INFO_LARGE),IMAGE_BITMAP,8, 8, LR_MONOCHROME);
+
+ // start the update timer
+ m_uiTimer = SetTimer(0,0,1000/10,CAppletManager::UpdateTimer);
+
+ return true;
+}
+
+//************************************************************************
+// Deinitializes the AppletManager
+//************************************************************************
+bool CAppletManager::Shutdown()
+{
+ if(!IsInitialized())
+ return false;
+
+ // stop the update timer
+ KillTimer(0,m_uiTimer);
+
+ // delete status bitmaps
+ for(int i=0;i<8;i++)
+ DeleteObject(m_ahStatusBitmaps[i]);
+
+ // delete event bitmaps
+ for(int i=0;i<8;i++)
+ {
+ DeleteObject(m_ahLargeEventBitmaps[i]);
+ DeleteObject(m_ahEventBitmaps[i]);
+ }
+
+ // unhook the events
+ UnhookEvent(m_hMIHookMessageWindowEvent);
+ UnhookEvent(m_hMIHookEventAdded);
+ UnhookEvent(m_hMIHookStatusChanged);
+ UnhookEvent(m_hMIHookProtoAck);
+ UnhookEvent(m_hMIHookContactDeleted);
+ UnhookEvent(m_hMIHookContactAdded);
+ UnhookEvent(m_hMIHookSettingChanged);
+ UnhookEvent(m_hMIHookChatEvent);
+
+ // unhook all irc protocols, and delete the classes
+ vector<CIRCConnection*>::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<CProtocolData*>::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<CProtocolData*>::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<SMessageJob*>::iterator iter = m_MessageJobs.begin();
+ while(iter != m_MessageJobs.end())
+ {
+ // TODO: Fertigstellen
+ if((*iter)->dwTimestamp + 15*1000 < GetTickCount())
+ {
+ CEvent Event;
+
+ Event.eType = EVENT_MESSAGE_ACK;
+ Event.hValue = (*iter)->hEvent;
+ Event.hContact = (*iter)->hContact;
+ Event.iValue = ACKRESULT_FAILED;
+ Event.strValue = TranslateString(_T("Timeout: No response from contact/server"));
+
+ HandleEvent(&Event);
+
+ SMessageJob *pJob = *iter;
+ m_MessageJobs.erase(iter);
+ free(pJob->pcBuffer);
+ delete(pJob);
+ break;
+ }
+ iter++;
+ }
+}
+
+//************************************************************************
+// adds a message job to the list
+//************************************************************************
+void CAppletManager::AddMessageJob(SMessageJob *pJob)
+{
+ m_MessageJobs.push_back(pJob);
+}
+
+//************************************************************************
+// finishes a message job
+//************************************************************************
+void CAppletManager::FinishMessageJob(SMessageJob *pJob)
+{
+ list<SMessageJob*>::iterator iter = m_MessageJobs.begin();
+ while(iter != m_MessageJobs.end())
+ {
+ if((*iter) == pJob)
+ {
+ char *szProto = 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<SMessageJob*>::iterator iter = m_MessageJobs.begin();
+ while(iter != m_MessageJobs.end())
+ {
+ if((*iter) == pJob)
+ {
+ SMessageJob *pJob = *iter;
+ m_MessageJobs.erase(iter);
+ free(pJob->pcBuffer);
+ delete(pJob);
+ return;
+ }
+ }
+}
+
+//************************************************************************
+// 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,&timestamp);
+ pEvent->bTime = true;
+ /*
+ if(dbevent.eventType == EVENTTYPE_MESSAGE && dbevent.flags & DBEF_READ) {
+ free(dbevent.pBlob);
+ return false;
+ }
+ */
+ // Skip events from the user except for messages
+ if(dbevent.eventType != EVENTTYPE_MESSAGE && (dbevent.flags & DBEF_SENT))
+ {
+ free(dbevent.pBlob);
+ return false;
+ }
+
+ int msglen = 0;
+
+ tstring strName = CAppletManager::GetContactDisplayname(hContact,true);
+
+ switch(dbevent.eventType) {
+ case EVENTTYPE_MESSAGE:
+ msglen = (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<CIRCConnection*>::iterator iter = m_vIRCConnections.begin();
+ while(iter != m_vIRCConnections.end())
+ {
+ if((*iter)->strProtocol == strProtocol)
+ return *iter;
+ iter++;
+ }
+ return NULL;
+}
+
+//************************************************************************
+// creates the IRC connection class for the specified protocol
+//************************************************************************
+CIRCConnection *CAppletManager::CreateIRCConnection(tstring strProtocol)
+{
+ 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<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
+ while(iter != m_LIRCHistorys.end())
+ {
+ if((*iter)->hContact == hContact)
+ return *iter;
+ iter++;
+ }
+ return NULL;
+}
+
+CIRCHistory *CAppletManager::GetIRCHistoryByName(tstring strProtocol,tstring strChannel)
+{
+ list<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
+ while(iter != m_LIRCHistorys.end())
+ {
+ if((*iter)->strChannel == strChannel && (*iter)->strProtocol == strProtocol)
+ return *iter;
+ iter++;
+ }
+ return NULL;
+}
+
+//************************************************************************
+// deletes the history class for the specified IRC channel
+//************************************************************************
+void CAppletManager::DeleteIRCHistory(MCONTACT hContact)
+{
+ list<CIRCHistory*>::iterator iter = m_LIRCHistorys.begin();
+ while(iter != m_LIRCHistorys.end())
+ {
+ if((*iter)->hContact == hContact)
+ {
+ CIRCHistory *pHistory = *iter;
+ pHistory->LMessages.clear();
+ pHistory->LUsers.clear();
+
+ m_LIRCHistorys.erase(iter);
+
+ delete pHistory;
+
+ return;
+ }
+ iter++;
+ }
+}
+
+//************************************************************************
+// creates a history class for the specified IRC channel
+//************************************************************************
+CIRCHistory *CAppletManager::CreateIRCHistory(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<tstring>::iterator iter = pHistory->LUsers.begin();
+ while(iter != pHistory->LUsers.end())
+ {
+ if((*iter) == strFullNick)
+ {
+ pHistory->LUsers.erase(iter);
+ break;
+ }
+ iter++;
+ }
+ }
+ break;
+ }
+ case GC_EVENT_QUIT:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
+ Event.bNotification = true;
+ Event.strValue = TranslateString(strText.empty()?_T("%s has disconnected"):_T("%s has disconnected: %s"),strNick.c_str(),strText.c_str());
+ break;
+ case GC_EVENT_KICK:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
+ Event.bNotification = true;
+ Event.strValue = TranslateString(_T("%s has kicked %s: %s"),strStatus.c_str(),strNick.c_str(),strText.c_str());
+ break;
+ case GC_EVENT_NICK:
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS))
+ Event.bNotification = true;
+ tstring strFullNick = toTstring(gce->ptszNick);
+
+ if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strText.length() > (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<tstring>::iterator iter = pHistory->LUsers.begin();
+ while(iter != pHistory->LUsers.end())
+ {
+ if((*iter) == strFullNick)
+ (*iter) = strText;
+ iter++;
+ }
+ }
+ break;
+ }
+ case GC_EVENT_NOTICE:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_NOTICES))
+ Event.bNotification = true;
+ Event.strValue = TranslateString(_T("Notice from %s: %s"),strNick.c_str(),strText.c_str());
+ break;
+ case GC_EVENT_TOPIC:
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_CHANNEL))
+ Event.bNotification = true;
+ Event.strValue = TranslateString(_T("Topic is now '%s' (set by %s)"),strText.c_str(),strNick.c_str());
+ break;
+ case GC_EVENT_ADDSTATUS:
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_IRC_STATUS))
+ Event.bNotification = true;
+ tstring strNick2 = toTstring(gce->ptszStatus);
+ if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strNick2.length() > (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<CIRCHistory*>::iterator iter = CAppletManager::GetInstance()->m_LIRCHistorys.begin();
+ list<tstring>::iterator nickiter;
+ while(iter != CAppletManager::GetInstance()->m_LIRCHistorys.end())
+ {
+ nickiter = (*iter)->LUsers.begin();
+ while(nickiter != (*iter)->LUsers.end())
+ {
+ if((*nickiter) == strNick)
+ {
+ (*iter)->LMessages.push_back(IRCMsg);
+ // Limit the size to the session logsize
+ if((*iter)->LMessages.size() > CConfig::GetIntSetting(SESSION_LOGSIZE))
+ (*iter)->LMessages.pop_front();
+
+ (*iter)->LUsers.erase(nickiter);
+
+ Event.hContact = (*iter)->hContact;
+ tstring strName = CAppletManager::GetContactDisplayname((*iter)->hContact,true);
+ Event.strDescription = strName + _T(" - ")+Event.strValue;
+ Event.strSummary = _T("(") + toTstring(gcd->pszModule) + _T(") ")+strName;
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+ break;
+ }
+ nickiter++;
+ }
+ iter++;
+ }
+ }
+ TRACE(_T("OK!\n"));
+ return 0;
+ }
+ else if(gcd->ptszID != NULL)
+ {
+ TRACE(_T("OK!\n"));
+ return 0;
+ }
+
+ if(pHistory)
+ {
+ tstring strChannel = pHistory->strChannel;
+ if(CConfig::GetBoolSetting(NOTIFY_CHANNELCUTOFF) && strNick.length() > CConfig::GetIntSetting(NOTIFY_CHANNELCUTOFF_OFFSET)) {
+ strChannel = strChannel.erase(CConfig::GetIntSetting(NOTIFY_CHANNELCUTOFF_OFFSET)) + _T("...");
+ }
+ Event.strDescription = strChannel + _T(" - ")+Event.strValue;
+ Event.strSummary = _T("(") + toTstring(gcd->pszModule) + _T(") ")+pHistory->strChannel;
+ }
+ else
+ Event.strDescription = Event.strValue;
+
+ TRACE(_T("OK!\n"));
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+
+ return 0;
+}
+
+//************************************************************************
+// message window event hook function
+//************************************************************************
+int CAppletManager::HookMessageWindowEvent(WPARAM wParam, LPARAM lParam)
+{
+ MessageWindowEventData *mwed = (MessageWindowEventData*)lParam;
+ CEvent Event;
+
+ Event.eType = EVENT_MESSAGEWINDOW;
+ Event.hContact = mwed->hContact;
+ Event.iValue = mwed->uType;
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+
+ return 0;
+}
+
+
+//************************************************************************
+// contact typing notification hook function
+//************************************************************************
+int CAppletManager::HookContactIsTyping(WPARAM wParam, LPARAM lParam)
+{
+ 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<SMessageJob*>::iterator iter = CAppletManager::GetInstance()->m_MessageJobs.begin();
+ while(iter != CAppletManager::GetInstance()->m_MessageJobs.end())
+ {
+ if((*iter)->hEvent == pAck->hProcess && (*iter)->hContact == pAck->hContact)
+ {
+ Event.eType = EVENT_MESSAGE_ACK;
+ Event.hValue = pAck->hProcess;
+ Event.hContact = pAck->hContact;
+ Event.iValue = pAck->result;
+ if(pAck->lParam != 0)
+ Event.strValue = toTstring((char*)pAck->lParam);
+ else
+ Event.strValue = _T("");
+
+ if(Event.iValue == ACKRESULT_SUCCESS)
+ CAppletManager::GetInstance()->FinishMessageJob((*iter));
+ else
+ CAppletManager::GetInstance()->CancelMessageJob((*iter));
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+
+ return 0;
+ }
+ iter++;
+ }
+ }
+ // protocol status changes
+ else if(pAck->type == ACKTYPE_STATUS && pAck->result == ACKRESULT_SUCCESS)
+ {
+ int iOldStatus = (int)pAck->hProcess;
+ int iNewStatus = pAck->lParam;
+
+ tstring strProto = toTstring(pAck->szModule);
+
+ // ignore metacontacts status changes
+ if(toLower(strProto) == _T("metacontacts"))
+ return 0;
+
+ CProtocolData *pProtoData = CAppletManager::GetInstance()->GetProtocolData(strProto);
+ if(pProtoData == NULL)
+ return 0;
+
+ if(iNewStatus == ID_STATUS_CONNECTING)
+ return 0;
+
+ if(iNewStatus == ID_STATUS_OFFLINE)
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_PROTO_SIGNOFF))
+ Event.bNotification = true;
+ Event.eType = EVENT_PROTO_DISCONNECTED;
+ }
+ else if(iNewStatus != ID_STATUS_OFFLINE && iOldStatus == ID_STATUS_CONNECTING)
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_PROTO_SIGNON))
+ Event.bNotification = true;
+ Event.eType = EVENT_PROTO_CONNECTED;
+ }
+ else
+ {
+ if(CConfig::GetBoolSetting(NOTIFY_PROTO_STATUS))
+ Event.bNotification = true;
+ Event.eType = EVENT_PROTO_STATUS;
+ }
+
+ // Skip connecting status
+ if(iNewStatus == ID_STATUS_CONNECTING)
+ return 0;
+
+ pProtoData->iStatus = iNewStatus;
+
+ Event.iValue = iNewStatus;
+ Event.strValue = strProto;
+
+ // set the event description / summary
+ tstring strStatus = toTstring((char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iNewStatus, 0));
+ Event.strDescription = _T("(") + Event.strValue + _T(") ")+ TranslateString(_T("You are now %s"),strStatus.c_str());
+ Event.strSummary = TranslateString(_T("Protocol status change"));
+
+ if(Event.eType != EVENT_PROTO_STATUS)
+ pProtoData->lTimeStamp = GetTickCount();
+
+ CAppletManager::GetInstance()->HandleEvent(&Event);
+ //CAppletManager::GetInstance()->ActivateNotificationScreen(&Event);
+ }
+
+ return 0;
+}
+
+//************************************************************************
+// contact added hook function
+//************************************************************************
+int CAppletManager::HookContactAdded(WPARAM wParam, LPARAM lParam)
+{
+ CEvent Event;
+ Event.eType = EVENT_CONTACT_ADDED;
+ Event.hContact = 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 <math.h>
-
-
-enum EListEntryType { ROOT = 0,CONTAINER = 1,ITEM = 2};
-
-template <class T, class G = tstring> class CListEntry
-{
-public:
- CListEntry(CListEntry<T,G> *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<T,G> *GetNextEntry()
- {
- if(m_pParent == NULL)
- return NULL;
-
- return m_pParent->GetNextEntry(this);
- }
-
- virtual CListEntry<T,G> *GetPreviousEntry()
- {
- if(m_pParent == NULL)
- return NULL;
-
- return m_pParent->GetPreviousEntry(this);
- }
-
- virtual CListEntry<T,G> *GetNextEntry(CListEntry<T,G> *pEntry)
- {
- return NULL;
- }
-
- virtual CListEntry<T,G> *GetPreviousEntry(CListEntry<T,G> *pEntry)
- {
- return NULL;
- }
-
- EListEntryType GetType()
- {
- return m_eType;
- }
-
- int GetEntryCount()
- {
- return m_iEntryCount;
- }
-
- virtual void UpdateEntryCount()
- {
- m_iEntryCount = 0;
- }
-
- void SetRoot(CListEntry<T,G>* pRoot)
- {
- m_pRoot = pRoot;
- }
-
- virtual void DeleteItem(T Entry)
- {
- }
-
- virtual void DeleteGroup(G Group)
- {
- }
-
- CListEntry<T,G> *GetPosition()
- {
- return m_Position;
- }
-
- virtual void SetPosition(CListEntry<T,G> *pPosition)
- {
- m_Position = pPosition;
- }
-
- CListEntry<T,G> *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<T,G> *m_pParent;
- CListEntry<T,G> *m_pRoot;
- CListEntry<T,G> *m_Position;
-};
-
-template <class T, class G = tstring> class CListItem : public CListEntry<T,G>
-{
-public:
- CListItem(CListEntry<T,G> *pParent,T Entry) : CListEntry<T,G>(pParent)
- {
- m_Item = Entry;
- m_eType = ITEM;
- }
-
- ~CListItem()
- {
- m_pRoot->DeleteItem(GetItemData());
- }
-
- T GetItemData()
- {
- return m_Item;
- }
-private:
- T m_Item;
-};
-
-template <class T, class G = tstring> class CListContainer : public CListEntry<T,G>
-{
-public:
- typedef typename list<CListEntry<T,G>* >::iterator iterator;
-
- typename list<CListEntry<T,G>* >::iterator end()
- {
- return m_Entrys.end();
- }
-
- typename list<CListEntry<T,G>* >::iterator begin()
- {
- return m_Entrys.begin();
- }
-
- typename list<CListEntry<T,G>* >::size_type size()
- {
- return m_Entrys.size();
- }
-
- bool empty()
- {
- bool b = m_Entrys.empty();
- return m_Entrys.empty();
- }
-
- CListContainer(CListEntry<T,G> *pParent) : CListEntry<T,G>(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<T,G>* >::iterator iter = m_Entrys.begin();
- CListItem<T,G> *pItem = NULL;
- CListContainer<T,G> *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<T,G> *GetLastOwnEntry()
- {
- if(m_Entrys.empty())
- return NULL;
-
- return *(--m_Entrys.end());
- }
-
- CListEntry<T,G> *GetLastEntry()
- {
- if(!m_Entrys.empty())
- {
-
- CListEntry<T,G> *pEntry = *(--m_Entrys.end());
- if(pEntry->GetType() == ITEM || !((CListContainer<T,G>*)pEntry)->IsOpen() || ((CListContainer<T,G>*)pEntry)->IsEmpty())
- return pEntry;
- return ((CListContainer<T,G>*)pEntry)->GetLastEntry();
- }
- return NULL;
- }
-
- CListEntry<T,G> *GetFirstEntry()
- {
- if(!m_Entrys.empty())
- return *(m_Entrys.begin());
- return NULL;
- }
-
- CListEntry<T,G> *GetNextEntry()
- {
- if(!IsOpen() || m_Entrys.empty())
- {
- if(!m_pParent)
- return NULL;
- return m_pParent->GetNextEntry(this);
- }
-
- return *m_Entrys.begin();
- }
-
- CListEntry<T,G> *GetNextEntry(CListEntry<T,G> *pEntry)
- {
- list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
- while(iter != m_Entrys.end())
- {
- if((CListEntry<T,G>*)(*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<T,G> *GetPreviousEntry(CListEntry<T,G> *pEntry)
- {
- list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
-
- while(iter != m_Entrys.end())
- {
- if((CListEntry<T,G>*)(*iter) == pEntry)
- {
- if(iter == m_Entrys.begin())
- {
- if(m_pParent == NULL)
- return NULL;
- return this;
- }
- else
- {
- iter--;
- if((*iter)->GetType() == CONTAINER)
- {
- CListContainer<T,G>* pContainer = (CListContainer<T,G>*)*iter;
- if(pContainer->IsOpen() && !pContainer->IsEmpty())
- return pContainer->GetLastEntry();
- }
- return *iter;
- }
- }
- iter++;
- }
- return NULL;
- }
-
- virtual CListItem<T,G> *InsertItem(iterator _Where,T Entry)
- {
- CListItem<T,G> *pItem = new CListItem<T,G>(this,Entry);
- pItem->SetRoot(m_pRoot);
- m_Entrys.insert(_Where,pItem);
-
- m_pRoot->UpdateEntryCount();
-
- return pItem;
- }
-
- virtual CListContainer<T,G> *InsertGroup(iterator _Where,G Group)
- {
- CListContainer<T,G> *pGroup = new CListContainer<T,G>(this);
- pGroup->SetGroupData(Group);
- pGroup->SetRoot(m_pRoot);
- m_Entrys.insert(_Where,(CListEntry<T,G>*)pGroup);
-
- m_pRoot->UpdateEntryCount();
-
- return pGroup;
- }
-
- virtual CListItem<T,G> * AddItem(T Entry)
- {
- return InsertItem(end(),Entry);
- }
-
- virtual CListContainer<T,G> * AddGroup(G Group)
- {
- return InsertGroup(end(),Group);
- }
-
-
-
- virtual void RemoveGroup(G Group)
- {
- list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
- CListContainer<T,G> *pContainer = NULL;
- while(iter != m_Entrys.end())
- {
- if((*iter)->GetType() == CONTAINER)
- {
- pContainer = (CListContainer<T,G>*)(*iter);
- if(pContainer->GetGroupData() == Group)
- {
- pContainer->Clear();
- if(m_pRoot && m_pRoot->GetPosition() == *iter)
- {
- CListEntry<T,G> *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<T,G>* >::iterator iter = m_Entrys.begin();
- CListItem<T,G> *pItem = NULL;
- while(iter != m_Entrys.end())
- {
- if((*iter)->GetType() == ITEM)
- {
- pItem = (CListItem<T,G>*)(*iter);
- if(pItem->GetItemData() == Entry)
- {
- if(m_pRoot && m_pRoot->GetPosition() == *iter)
- {
- CListEntry<T,G> *pPosition = (*iter)->GetPreviousEntry();
- if(!pPosition)
- pPosition = (*iter)->GetNextEntry();
- m_pRoot->SetPosition(pPosition);
- }
- delete *iter;
-
- m_Entrys.erase(iter);
- m_pRoot->UpdateEntryCount();
- return;
- }
- }
- iter++;
- }
- }
-
- CListContainer<T,G> *GetGroup(G Group)
- {
- list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
- CListContainer<T,G> *pContainer = NULL;
- while(iter != m_Entrys.end())
- {
- if((*iter)->GetType() == CONTAINER)
- {
- pContainer = (CListContainer<T,G>*)(*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<T,G>* >::iterator iter = m_Entrys.begin();
- CListContainer<T,G>* pContainer = NULL;
- while(iter != m_Entrys.end())
- {
- if((*iter)->GetType() == CONTAINER)
- {
- pContainer = (CListContainer<T,G>*)(*iter);
- pContainer->CollapseAll();
- pContainer->SetOpen(false);
- }
- iter++;
- }
- }
-
- void ExpandAll()
- {
- list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
- CListContainer<T,G>* pContainer = NULL;
- while(iter != m_Entrys.end())
- {
- if((*iter)->GetType() == CONTAINER)
- {
- pContainer = (CListContainer<T,G>*)(*iter);
- pContainer->ExpandAll();
- pContainer->SetOpen(true);
- }
- iter++;
- }
- }
-
- void UpdateEntryCount()
- {
- m_iEntryCount = 0;
-
- int iIndex = GetIndex()+1;
-
- if(!IsOpen())
- return;
-
- list< CListEntry<T,G>* >::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<class _Pr3>
- void sort(_Pr3 _Pred) {
- m_Entrys.sort(_Pred);
- UpdateEntryCount();
- m_pRoot->SetPosition(m_pRoot->GetPosition());
- }
-
-private:
- typename list< CListEntry<T,G>* > m_Entrys;
- G m_GroupData;
- bool m_bOpen;
-};
-
-
-template <class T, class G = tstring> class CLCDList : public CLCDTextObject, public CListContainer<T,G>
-{
-friend CListContainer<T,G>;
-friend CListItem<T,G>;
-public:
- //************************************************************************
- // Constructor
- //************************************************************************
- CLCDList() : CListContainer<T,G>(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<T,G> *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;iCol<m_iColumns;iCol++)
- {
- iHeight = 0;
- if(iCol == 0)
- {
- if(pPosition->GetIndex() < 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;i<pPosition->GetLevel();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<T,G>*)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<T,G> *pPosition2 = pPosition;
- for(int j = pPosition->GetLevel();j>i+1;j--)
- pPosition2 = pPosition2->GetParent();
- // |
- // |
- if(pPosition2 != ((CListContainer<T,G>*)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<T,G>*)pPosition)->GetItemData(),bSelected);
- else
- // draw the group
- DrawGroup(pGfx,((CListContainer<T,G>*)pPosition)->GetGroupData(),((CListContainer<T,G>*)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<T,G> *pEntry)
- {
- CListContainer<T,G>::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<T,G> *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<T,G> *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<T,G> *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<T,G>::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 <math.h>
+
+
+enum EListEntryType { ROOT = 0,CONTAINER = 1,ITEM = 2};
+
+template <class T, class G = tstring> class CListEntry
+{
+public:
+ CListEntry(CListEntry<T,G> *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<T,G> *GetNextEntry()
+ {
+ if(m_pParent == NULL)
+ return NULL;
+
+ return m_pParent->GetNextEntry(this);
+ }
+
+ virtual CListEntry<T,G> *GetPreviousEntry()
+ {
+ if(m_pParent == NULL)
+ return NULL;
+
+ return m_pParent->GetPreviousEntry(this);
+ }
+
+ virtual CListEntry<T,G> *GetNextEntry(CListEntry<T,G> *pEntry)
+ {
+ return NULL;
+ }
+
+ virtual CListEntry<T,G> *GetPreviousEntry(CListEntry<T,G> *pEntry)
+ {
+ return NULL;
+ }
+
+ EListEntryType GetType()
+ {
+ return m_eType;
+ }
+
+ int GetEntryCount()
+ {
+ return m_iEntryCount;
+ }
+
+ virtual void UpdateEntryCount()
+ {
+ m_iEntryCount = 0;
+ }
+
+ void SetRoot(CListEntry<T,G>* pRoot)
+ {
+ m_pRoot = pRoot;
+ }
+
+ virtual void DeleteItem(T Entry)
+ {
+ }
+
+ virtual void DeleteGroup(G Group)
+ {
+ }
+
+ CListEntry<T,G> *GetPosition()
+ {
+ return m_Position;
+ }
+
+ virtual void SetPosition(CListEntry<T,G> *pPosition)
+ {
+ m_Position = pPosition;
+ }
+
+ CListEntry<T,G> *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<T,G> *m_pParent;
+ CListEntry<T,G> *m_pRoot;
+ CListEntry<T,G> *m_Position;
+};
+
+template <class T, class G = tstring> class CListItem : public CListEntry<T,G>
+{
+public:
+ CListItem(CListEntry<T,G> *pParent,T Entry) : CListEntry<T,G>(pParent)
+ {
+ m_Item = Entry;
+ m_eType = ITEM;
+ }
+
+ ~CListItem()
+ {
+ m_pRoot->DeleteItem(GetItemData());
+ }
+
+ T GetItemData()
+ {
+ return m_Item;
+ }
+private:
+ T m_Item;
+};
+
+template <class T, class G = tstring> class CListContainer : public CListEntry<T,G>
+{
+public:
+ typedef typename list<CListEntry<T,G>* >::iterator iterator;
+
+ typename list<CListEntry<T,G>* >::iterator end()
+ {
+ return m_Entrys.end();
+ }
+
+ typename list<CListEntry<T,G>* >::iterator begin()
+ {
+ return m_Entrys.begin();
+ }
+
+ typename list<CListEntry<T,G>* >::size_type size()
+ {
+ return m_Entrys.size();
+ }
+
+ bool empty()
+ {
+ bool b = m_Entrys.empty();
+ return m_Entrys.empty();
+ }
+
+ CListContainer(CListEntry<T,G> *pParent) : CListEntry<T,G>(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<T,G>* >::iterator iter = m_Entrys.begin();
+ CListItem<T,G> *pItem = NULL;
+ CListContainer<T,G> *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<T,G> *GetLastOwnEntry()
+ {
+ if(m_Entrys.empty())
+ return NULL;
+
+ return *(--m_Entrys.end());
+ }
+
+ CListEntry<T,G> *GetLastEntry()
+ {
+ if(!m_Entrys.empty())
+ {
+
+ CListEntry<T,G> *pEntry = *(--m_Entrys.end());
+ if(pEntry->GetType() == ITEM || !((CListContainer<T,G>*)pEntry)->IsOpen() || ((CListContainer<T,G>*)pEntry)->IsEmpty())
+ return pEntry;
+ return ((CListContainer<T,G>*)pEntry)->GetLastEntry();
+ }
+ return NULL;
+ }
+
+ CListEntry<T,G> *GetFirstEntry()
+ {
+ if(!m_Entrys.empty())
+ return *(m_Entrys.begin());
+ return NULL;
+ }
+
+ CListEntry<T,G> *GetNextEntry()
+ {
+ if(!IsOpen() || m_Entrys.empty())
+ {
+ if(!m_pParent)
+ return NULL;
+ return m_pParent->GetNextEntry(this);
+ }
+
+ return *m_Entrys.begin();
+ }
+
+ CListEntry<T,G> *GetNextEntry(CListEntry<T,G> *pEntry)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ while(iter != m_Entrys.end())
+ {
+ if((CListEntry<T,G>*)(*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<T,G> *GetPreviousEntry(CListEntry<T,G> *pEntry)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+
+ while(iter != m_Entrys.end())
+ {
+ if((CListEntry<T,G>*)(*iter) == pEntry)
+ {
+ if(iter == m_Entrys.begin())
+ {
+ if(m_pParent == NULL)
+ return NULL;
+ return this;
+ }
+ else
+ {
+ iter--;
+ if((*iter)->GetType() == CONTAINER)
+ {
+ CListContainer<T,G>* pContainer = (CListContainer<T,G>*)*iter;
+ if(pContainer->IsOpen() && !pContainer->IsEmpty())
+ return pContainer->GetLastEntry();
+ }
+ return *iter;
+ }
+ }
+ iter++;
+ }
+ return NULL;
+ }
+
+ virtual CListItem<T,G> *InsertItem(iterator _Where,T Entry)
+ {
+ CListItem<T,G> *pItem = new CListItem<T,G>(this,Entry);
+ pItem->SetRoot(m_pRoot);
+ m_Entrys.insert(_Where,pItem);
+
+ m_pRoot->UpdateEntryCount();
+
+ return pItem;
+ }
+
+ virtual CListContainer<T,G> *InsertGroup(iterator _Where,G Group)
+ {
+ CListContainer<T,G> *pGroup = new CListContainer<T,G>(this);
+ pGroup->SetGroupData(Group);
+ pGroup->SetRoot(m_pRoot);
+ m_Entrys.insert(_Where,(CListEntry<T,G>*)pGroup);
+
+ m_pRoot->UpdateEntryCount();
+
+ return pGroup;
+ }
+
+ virtual CListItem<T,G> * AddItem(T Entry)
+ {
+ return InsertItem(end(),Entry);
+ }
+
+ virtual CListContainer<T,G> * AddGroup(G Group)
+ {
+ return InsertGroup(end(),Group);
+ }
+
+
+
+ virtual void RemoveGroup(G Group)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListContainer<T,G> *pContainer = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == CONTAINER)
+ {
+ pContainer = (CListContainer<T,G>*)(*iter);
+ if(pContainer->GetGroupData() == Group)
+ {
+ pContainer->Clear();
+ if(m_pRoot && m_pRoot->GetPosition() == *iter)
+ {
+ CListEntry<T,G> *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<T,G>* >::iterator iter = m_Entrys.begin();
+ CListItem<T,G> *pItem = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == ITEM)
+ {
+ pItem = (CListItem<T,G>*)(*iter);
+ if(pItem->GetItemData() == Entry)
+ {
+ if(m_pRoot && m_pRoot->GetPosition() == *iter)
+ {
+ CListEntry<T,G> *pPosition = (*iter)->GetPreviousEntry();
+ if(!pPosition)
+ pPosition = (*iter)->GetNextEntry();
+ m_pRoot->SetPosition(pPosition);
+ }
+ delete *iter;
+
+ m_Entrys.erase(iter);
+ m_pRoot->UpdateEntryCount();
+ return;
+ }
+ }
+ iter++;
+ }
+ }
+
+ CListContainer<T,G> *GetGroup(G Group)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListContainer<T,G> *pContainer = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == CONTAINER)
+ {
+ pContainer = (CListContainer<T,G>*)(*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<T,G>* >::iterator iter = m_Entrys.begin();
+ CListContainer<T,G>* pContainer = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == CONTAINER)
+ {
+ pContainer = (CListContainer<T,G>*)(*iter);
+ pContainer->CollapseAll();
+ pContainer->SetOpen(false);
+ }
+ iter++;
+ }
+ }
+
+ void ExpandAll()
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListContainer<T,G>* pContainer = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == CONTAINER)
+ {
+ pContainer = (CListContainer<T,G>*)(*iter);
+ pContainer->ExpandAll();
+ pContainer->SetOpen(true);
+ }
+ iter++;
+ }
+ }
+
+ void UpdateEntryCount()
+ {
+ m_iEntryCount = 0;
+
+ int iIndex = GetIndex()+1;
+
+ if(!IsOpen())
+ return;
+
+ list< CListEntry<T,G>* >::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<class _Pr3>
+ void sort(_Pr3 _Pred) {
+ m_Entrys.sort(_Pred);
+ UpdateEntryCount();
+ m_pRoot->SetPosition(m_pRoot->GetPosition());
+ }
+
+private:
+ typename list< CListEntry<T,G>* > m_Entrys;
+ G m_GroupData;
+ bool m_bOpen;
+};
+
+
+template <class T, class G = tstring> class CLCDList : public CLCDTextObject, public CListContainer<T,G>
+{
+friend CListContainer<T,G>;
+friend CListItem<T,G>;
+public:
+ //************************************************************************
+ // Constructor
+ //************************************************************************
+ CLCDList() : CListContainer<T,G>(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<T,G> *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;iCol<m_iColumns;iCol++)
+ {
+ iHeight = 0;
+ if(iCol == 0)
+ {
+ if(pPosition->GetIndex() < 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;i<pPosition->GetLevel();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<T,G>*)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<T,G> *pPosition2 = pPosition;
+ for(int j = pPosition->GetLevel();j>i+1;j--)
+ pPosition2 = pPosition2->GetParent();
+ // |
+ // |
+ if(pPosition2 != ((CListContainer<T,G>*)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<T,G>*)pPosition)->GetItemData(),bSelected);
+ else
+ // draw the group
+ DrawGroup(pGfx,((CListContainer<T,G>*)pPosition)->GetGroupData(),((CListContainer<T,G>*)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<T,G> *pEntry)
+ {
+ CListContainer<T,G>::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<T,G> *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<T,G> *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<T,G> *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<T,G>::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 <time.h>
-
-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<CLCDScreen*>::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<iButtonCount;i++)
- {
- m_pbButtonStates[i] = false;
- m_pdwButtonRepeatTimers[i] = 0;
- m_pdwButtonRepeatStarts[i] = 0;
- }
-
- // Update all screens sizes
- vector<CLCDScreen*>::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<CLCDScreen*>::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<CLCDScreen*>::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 <time.h>
+
+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<CLCDScreen*>::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<iButtonCount;i++)
+ {
+ m_pbButtonStates[i] = false;
+ m_pdwButtonRepeatTimers[i] = 0;
+ m_pdwButtonRepeatStarts[i] = 0;
+ }
+
+ // Update all screens sizes
+ vector<CLCDScreen*>::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<CLCDScreen*>::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<CLCDScreen*>::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++;