diff options
| -rw-r--r-- | plugins/MirandaG15/src/CAppletManager.cpp | 3699 | ||||
| -rw-r--r-- | plugins/MirandaG15/src/LCDFramework/CLCDList.h | 1886 | ||||
| -rw-r--r-- | plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.cpp | 902 | ||||
| -rw-r--r-- | protocols/Sametime/src/meanwhile/src/mpi/mpi.c | 9 | 
4 files changed, 3251 insertions, 3245 deletions
diff --git a/plugins/MirandaG15/src/CAppletManager.cpp b/plugins/MirandaG15/src/CAppletManager.cpp index 2ae86f175b..4248ae3fff 100644 --- a/plugins/MirandaG15/src/CAppletManager.cpp +++ b/plugins/MirandaG15/src/CAppletManager.cpp @@ -1,1849 +1,1850 @@ -#include "stdafx.h"
 -#include "CConfig.h"
 -#include "CAppletManager.h"
 -#include "m_system.h"
 -
 -// specifies how long contact status notifications are ignored after signon
 -#define PROTOCOL_NOTIFY_DELAY 1500
 -
 -//########################################################################
 -// functions
 -//########################################################################
 -
 -//************************************************************************
 -// returns the AppletManager's instance
 -//************************************************************************
 -CAppletManager *CAppletManager::GetInstance()
 -{
 -	return (CAppletManager*)CLCDOutputManager::GetInstance();
 -}
 -
 -//************************************************************************
 -// Constructor
 -//************************************************************************
 -CAppletManager::CAppletManager()
 -{
 -	m_uiTimer = NULL;
 -	m_pLastScreen = NULL;
 -
 -	
 -}
 -
 -//************************************************************************
 -// Destructor
 -//************************************************************************
 -CAppletManager::~CAppletManager()
 -{
 -
 -}
 -
 -//************************************************************************
 -// Initializes the AppletManager
 -//************************************************************************
 -bool CAppletManager::Initialize(tstring strAppletName)
 -{
 -	if(!CLCDOutputManager::Initialize(strAppletName))
 -		return false;
 -	
 -	GetLCDConnection()->Connect(CConfig::GetIntSetting(DEVICE));
 -
 -	// set the volumewheel hook
 -	SetVolumeWheelHook();
 -
 -	// initialize the screens
 -	m_NotificationScreen.Initialize();
 -	m_EventScreen.Initialize();
 -	m_ContactlistScreen.Initialize();
 -	m_ChatScreen.Initialize();
 -	m_CreditsScreen.Initialize();
 -	m_ScreensaverScreen.Initialize();
 -
 -	// add the screens to the list
 -	AddScreen(&m_NotificationScreen);
 -	AddScreen(&m_EventScreen);
 -	AddScreen(&m_ContactlistScreen);
 -	AddScreen(&m_ChatScreen);
 -	AddScreen(&m_CreditsScreen);
 -	AddScreen(&m_ScreensaverScreen);
 -
 -	// activate the event screen
 -	ActivateScreen(&m_EventScreen);
 -
 -	// hook the neccessary events
 -	m_hMIHookMessageWindowEvent = HookEvent(ME_MSG_WINDOWEVENT,CAppletManager::HookMessageWindowEvent);
 -	m_hMIHookEventAdded = HookEvent(ME_DB_EVENT_ADDED, CAppletManager::HookEventAdded);
 -	m_hMIHookStatusChanged  = HookEvent(ME_DB_CONTACT_SETTINGCHANGED,  CAppletManager::HookStatusChanged);
 -	m_hMIHookProtoAck =  HookEvent(ME_PROTO_ACK,  CAppletManager::HookProtoAck);
 -	m_hMIHookContactDeleted = HookEvent(ME_DB_CONTACT_DELETED,  CAppletManager::HookContactDeleted); 
 -	m_hMIHookContactAdded = HookEvent(ME_DB_CONTACT_ADDED,  CAppletManager::HookContactAdded);
 -	m_hMIHookSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED,CAppletManager::HookSettingChanged);
 -	m_hMIHookContactIsTyping = HookEvent(ME_PROTO_CONTACTISTYPING,CAppletManager::HookContactIsTyping);
 -	m_hMIHookChatEvent = HookEvent(ME_GC_HOOK_EVENT,CAppletManager::HookChatInbound);
 -	
 -	// enumerate protocols
 -	int iCount;
 -	int iProtoCount = 0;
 -	PROTOACCOUNT **ppAccounts;
 -	CProtocolData *pProtoData = NULL;
 -	CIRCConnection *pIRCConnection = NULL;
 -
 -	ProtoEnumAccounts(&iCount, &ppAccounts);
 -	for(int i=0;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,×tamp);
 -	pEvent->bTime = true;
 -	/*
 -	if(dbevent.eventType == EVENTTYPE_MESSAGE && dbevent.flags & DBEF_READ) {
 -		free(dbevent.pBlob);
 -		return false;
 -	}
 -	*/
 -	// Skip events from the user except for messages
 -	if(dbevent.eventType != EVENTTYPE_MESSAGE && (dbevent.flags & DBEF_SENT))
 -	{
 -		free(dbevent.pBlob);
 -		return false;
 -	}
 -	
 -	int msglen = 0;
 -
 -	tstring strName = CAppletManager::GetContactDisplayname(hContact,true);
 -	
 -	switch(dbevent.eventType) {
 -	case EVENTTYPE_MESSAGE:
 -		msglen = (int)strlen((char *) dbevent.pBlob) + 1;
 -		if (dbevent.flags & DBEF_UTF) {
 -			pEvent->strValue = Utf8_Decode((char*)dbevent.pBlob);
 -		} else if ((int) dbevent.cbBlob == msglen*3){
 -			pEvent->strValue =  (TCHAR *) & dbevent.pBlob[msglen];
 -		} else {
 -			pEvent->strValue = toTstring((char*)dbevent.pBlob);
 -		}
 -		pEvent->eType = (dbevent.flags & DBEF_SENT) ? EVENT_MSG_SENT:EVENT_MSG_RECEIVED;
 -		if(pEvent->eType == EVENT_MSG_RECEIVED)
 -		{	
 -			pEvent->dwFlags = MSG_UNREAD;
 -			if(CConfig::GetBoolSetting(NOTIFY_MESSAGES))
 -				pEvent->bNotification = true;
 -		}
 -
 -		pEvent->strDescription = strName + _T(": ") +pEvent->strValue;
 -		pEvent->strSummary = TranslateString(_T("New message from %s"),strName.c_str());
 -		break;
 -	case EVENTTYPE_URL:
 -		if(CConfig::GetBoolSetting(NOTIFY_URL))
 -			pEvent->bNotification = true;
 -
 -		pEvent->eType = EVENT_URL;
 -		pEvent->strDescription = TranslateString(_T("Incoming URL from %s"),strName.c_str());
 -		break;
 -	case EVENTTYPE_CONTACTS:
 -		if(CConfig::GetBoolSetting(NOTIFY_CONTACTS))
 -			pEvent->bNotification = true;
 -
 -		pEvent->strDescription = TranslateString(_T("Incoming contacts from %s"),strName.c_str());
 -		pEvent->eType = EVENT_CONTACTS;
 -		break;
 -	case EVENTTYPE_ADDED:
 -		if(CConfig::GetBoolSetting(NOTIFY_CONTACTS))
 -			pEvent->bNotification = true;
 -
 -		pEvent->strDescription = TranslateString(_T("You were added by %s"),strName.c_str());
 -		pEvent->eType = EVENT_ADDED;
 -		break;
 -	case EVENTTYPE_AUTHREQUEST:
 -		if(CConfig::GetBoolSetting(NOTIFY_CONTACTS))
 -			pEvent->bNotification = true;
 -
 -		pEvent->strDescription = TranslateString(_T("Incoming Authrequest!"));
 -		pEvent->eType = EVENT_AUTHREQUEST;
 -		break;
 -	case EVENTTYPE_FILE:
 -		if(CConfig::GetBoolSetting(NOTIFY_FILE))
 -			pEvent->bNotification = true;
 -
 -		pEvent->strDescription = TranslateString(_T("Incoming file from %s"),strName.c_str());
 -		pEvent->eType = EVENT_FILE;
 -		break;
 -	default:
 -		return false;
 -		break;
 -	}
 -
 -	if(CConfig::GetBoolSetting(NOTIFY_SHOWPROTO))
 -	{
 -		char *szProto = GetContactProto(pEvent->hContact);
 -		pEvent->strDescription = _T("(")+toTstring(szProto)+_T(") ") + pEvent->strDescription;
 -	}
 -
 -	// Clean up
 -	free(dbevent.pBlob);
 -	return true;
 -}
 -
 -//************************************************************************
 -// removes IRC formatting tags from the string
 -//************************************************************************
 -tstring CAppletManager::StripIRCFormatting(tstring strText)
 -{
 -	tstring::size_type end = 0, start = 0, i = 0;
 -	tstring strEntity = _T("");
 -	tstring strReplace = _T("");
 -	tstring::size_type len = strText.length();
 -
 -	while(i < strText.length())
 -	{
 -		start = strText.find(_T("%"),i);
 -		if(start != string::npos && start < strText.length() - 1)
 -		{
 -			strEntity = strText[start+1];
 -			if(strEntity == _T("%"))
 -			{
 -				strText.replace(start,2,_T("%"));
 -				i = start + 1;
 -			}
 -			/*
 -			else if(strEntity == _T("b") || strEntity == _T("B") || 
 -				strEntity == _T("i") || strEntity == _T("I") || 
 -				strEntity ==_T("u") || strEntity == _T("U") ||
 -				strEntity == _T("C") ||strEntity == _T("F"))
 -			{
 -				strText.erase(start,2);
 -				i = start;
 -			}
 -			*/
 -			else if(strEntity == _T("c") || strEntity == _T("f"))
 -			{
 -				strText.erase(start,4);			
 -				i = start;
 -			}
 -			else
 -			{
 -				strText.erase(start,2);
 -				i = start;
 -			}
 -		}
 -		else
 -			break;
 -	}
 -
 -	return strText;
 -}
 -
 -//************************************************************************
 -// returns the IRC connection class for the specified protocol
 -//************************************************************************
 -CIRCConnection *CAppletManager::GetIRCConnection(tstring strProtocol)
 -{
 -	vector<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,×tamp); +	pEvent->bTime = true; +	/* +	if(dbevent.eventType == EVENTTYPE_MESSAGE && dbevent.flags & DBEF_READ) { +		free(dbevent.pBlob); +		return false; +	} +	*/ +	// Skip events from the user except for messages +	if(dbevent.eventType != EVENTTYPE_MESSAGE && (dbevent.flags & DBEF_SENT)) +	{ +		free(dbevent.pBlob); +		return false; +	} +	 +	int msglen = 0; + +	tstring strName = CAppletManager::GetContactDisplayname(hContact,true); +	 +	switch(dbevent.eventType) { +	case EVENTTYPE_MESSAGE: +		msglen = (int)strlen((char *) dbevent.pBlob) + 1; +		if (dbevent.flags & DBEF_UTF) { +			pEvent->strValue = Utf8_Decode((char*)dbevent.pBlob); +		} else if ((int) dbevent.cbBlob == msglen*3){ +			pEvent->strValue =  (TCHAR *) & dbevent.pBlob[msglen]; +		} else { +			pEvent->strValue = toTstring((char*)dbevent.pBlob); +		} +		pEvent->eType = (dbevent.flags & DBEF_SENT) ? EVENT_MSG_SENT:EVENT_MSG_RECEIVED; +		if(pEvent->eType == EVENT_MSG_RECEIVED) +		{	 +			pEvent->dwFlags = MSG_UNREAD; +			if(CConfig::GetBoolSetting(NOTIFY_MESSAGES)) +				pEvent->bNotification = true; +		} + +		pEvent->strDescription = strName + _T(": ") +pEvent->strValue; +		pEvent->strSummary = TranslateString(_T("New message from %s"),strName.c_str()); +		break; +	case EVENTTYPE_URL: +		if(CConfig::GetBoolSetting(NOTIFY_URL)) +			pEvent->bNotification = true; + +		pEvent->eType = EVENT_URL; +		pEvent->strDescription = TranslateString(_T("Incoming URL from %s"),strName.c_str()); +		break; +	case EVENTTYPE_CONTACTS: +		if(CConfig::GetBoolSetting(NOTIFY_CONTACTS)) +			pEvent->bNotification = true; + +		pEvent->strDescription = TranslateString(_T("Incoming contacts from %s"),strName.c_str()); +		pEvent->eType = EVENT_CONTACTS; +		break; +	case EVENTTYPE_ADDED: +		if(CConfig::GetBoolSetting(NOTIFY_CONTACTS)) +			pEvent->bNotification = true; + +		pEvent->strDescription = TranslateString(_T("You were added by %s"),strName.c_str()); +		pEvent->eType = EVENT_ADDED; +		break; +	case EVENTTYPE_AUTHREQUEST: +		if(CConfig::GetBoolSetting(NOTIFY_CONTACTS)) +			pEvent->bNotification = true; + +		pEvent->strDescription = TranslateString(_T("Incoming Authrequest!")); +		pEvent->eType = EVENT_AUTHREQUEST; +		break; +	case EVENTTYPE_FILE: +		if(CConfig::GetBoolSetting(NOTIFY_FILE)) +			pEvent->bNotification = true; + +		pEvent->strDescription = TranslateString(_T("Incoming file from %s"),strName.c_str()); +		pEvent->eType = EVENT_FILE; +		break; +	default: +		return false; +		break; +	} + +	if(CConfig::GetBoolSetting(NOTIFY_SHOWPROTO)) +	{ +		char *szProto = GetContactProto(pEvent->hContact); +		pEvent->strDescription = _T("(")+toTstring(szProto)+_T(") ") + pEvent->strDescription; +	} + +	// Clean up +	free(dbevent.pBlob); +	return true; +} + +//************************************************************************ +// removes IRC formatting tags from the string +//************************************************************************ +tstring CAppletManager::StripIRCFormatting(tstring strText) +{ +	tstring::size_type end = 0, start = 0, i = 0; +	tstring strEntity = _T(""); +	tstring strReplace = _T(""); +	tstring::size_type len = strText.length(); + +	while(i < strText.length()) +	{ +		start = strText.find(_T("%"),i); +		if(start != string::npos && start < strText.length() - 1) +		{ +			strEntity = strText[start+1]; +			if(strEntity == _T("%")) +			{ +				strText.replace(start,2,_T("%")); +				i = start + 1; +			} +			/* +			else if(strEntity == _T("b") || strEntity == _T("B") ||  +				strEntity == _T("i") || strEntity == _T("I") ||  +				strEntity ==_T("u") || strEntity == _T("U") || +				strEntity == _T("C") ||strEntity == _T("F")) +			{ +				strText.erase(start,2); +				i = start; +			} +			*/ +			else if(strEntity == _T("c") || strEntity == _T("f")) +			{ +				strText.erase(start,4);			 +				i = start; +			} +			else +			{ +				strText.erase(start,2); +				i = start; +			} +		} +		else +			break; +	} + +	return strText; +} + +//************************************************************************ +// returns the IRC connection class for the specified protocol +//************************************************************************ +CIRCConnection *CAppletManager::GetIRCConnection(tstring strProtocol) +{ +	vector<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++;  | 
