BOOL JabberDBCheckIsTransportedContact(const TCHAR* jid, HANDLE hContact)
{
	// check if transport is already set
	if ( !jid || !hContact )
		return FALSE;

	// strip domain part from jid
	TCHAR* domain  = _tcschr(( TCHAR* )jid, '@' );
	BOOL   isAgent = (domain == NULL) ? TRUE : FALSE;
	if ( domain!=NULL )
		domain = NEWTSTR_ALLOCA(domain+1);
	else
      domain = NEWTSTR_ALLOCA(jid);

	TCHAR* resourcepos = _tcschr( domain, '/' );
	if ( resourcepos != NULL )
		*resourcepos = '\0';
	
	if ( jabberTransports.getIndex( domain ) == -1 )
	{
		if (isAgent)
		{
			jabberTransports.insert( _tcsdup(domain) );	
			JSetByte( hContact, "IsTransport", 1 );
		}
		else
			return FALSE;
	}
	JSetStringT( hContact, "Transport", domain );
	JSetByte( hContact, "IsTransported", 1 );
	PushIconLibRegistration( domain );
	return TRUE;
}
Ejemplo n.º 2
0
int CVkProto::OnChatEvent(WPARAM, LPARAM lParam)
{
	GCHOOK *gch = (GCHOOK*)lParam;
	if (gch == NULL)
		return 0;

	if (lstrcmpiA(gch->pDest->pszModule, m_szModuleName))
		return 0;

	CVkChatInfo *cc = GetChatById(gch->pDest->ptszID);
	if (cc == NULL)
		return 0;

	switch (gch->pDest->iType) {
	case GC_USER_MESSAGE:
		if (m_bOnline && lstrlen(gch->ptszText) > 0) {
			TCHAR *buf = NEWTSTR_ALLOCA(gch->ptszText);
			rtrimt(buf);
			UnEscapeChatTags(buf);
			
			Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.send.json", true, &CVkProto::OnSendChatMsg)
				<< INT_PARAM("type", 1) << INT_PARAM("chat_id", cc->m_chatid) << TCHAR_PARAM("message", buf));
		}

	case GC_USER_LOGMENU:
		LogMenuHook(cc, gch);
		break;

	case GC_USER_NICKLISTMENU:
		NickMenuHook(cc, gch);
		break;
	}
	return 0;
}
Ejemplo n.º 3
0
void CJabberDlgBookmarks::OpenBookmark()
{
	int iItem = m_lvBookmarks.GetNextItem(-1, LVNI_SELECTED);
	if (iItem < 0) return;

	TCHAR *address = (TCHAR *)m_lvBookmarks.GetItemData(iItem);
	if (address == NULL) return;

	JABBER_LIST_ITEM *item = m_proto->ListGetItemPtr(LIST_BOOKMARK, address);
	if (item == NULL) return;

	if (!mir_tstrcmpi(item->type, _T("conference"))) {
		m_lvBookmarks.SetItemState(iItem, 0, LVIS_SELECTED); // Unselect the item

		/* some hack for using bookmark to transport not under XEP-0048 */
		if (!_tcschr(item->jid, _T('@')))
			//the room name is not provided let consider that it is transport and send request to registration
			m_proto->RegisterAgent(NULL, item->jid);
		else {
			TCHAR *room = NEWTSTR_ALLOCA(item->jid);
			TCHAR *server = _tcschr(room, _T('@'));
			*(server++) = 0;

			if (item->nick && *item->nick)
				m_proto->GroupchatJoinRoom(server, room, item->nick, item->password);
			else
				m_proto->GroupchatJoinRoom(server, room, ptrT(JabberNickFromJID(m_proto->m_szJabberJID)), item->password);
		}
	}
	else Utils_OpenUrlT(item->jid);
}
Ejemplo n.º 4
0
void CJabberDlgGcJoin::OnBtnOk(CCtrlButton*)
{
	TCHAR text[128];
	GetDlgItemText(m_hwnd, IDC_SERVER, text, _countof(text));
	TCHAR *server = NEWTSTR_ALLOCA(text), *room;

	m_proto->ComboAddRecentString(m_hwnd, IDC_SERVER, "joinWnd_rcSvr", server);

	GetDlgItemText(m_hwnd, IDC_ROOM, text, _countof(text));
	room = NEWTSTR_ALLOCA(text);

	GetDlgItemText(m_hwnd, IDC_NICK, text, _countof(text));
	TCHAR *nick = NEWTSTR_ALLOCA(text);

	GetDlgItemText(m_hwnd, IDC_PASSWORD, text, _countof(text));
	TCHAR *password = NEWTSTR_ALLOCA(text);
	m_proto->GroupchatJoinRoom(server, room, nick, password);
}
Ejemplo n.º 5
0
int fnFindRowByText(HWND hwnd, struct ClcData *dat, const TCHAR *text, int prefixOk)
{
	ClcGroup *group = &dat->list;
	int testlen = lstrlen(text);

	group->scanIndex = 0;
	for (;;) {
		if (group->scanIndex == group->cl.count) {
			group = group->parent;
			if (group == NULL)
				break;
			group->scanIndex++;
			continue;
		}
		if (group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER) {
			bool show;
			if (dat->filterSearch) {
				TCHAR *lowered_szText = CharLowerW(NEWTSTR_ALLOCA(group->cl.items[group->scanIndex]->szText));
				TCHAR *lowered_text = CharLowerW(NEWTSTR_ALLOCA(text));
				show = _tcsstr(lowered_szText, lowered_text) != NULL;
			}
			else show = ((prefixOk && !_tcsnicmp(text, group->cl.items[group->scanIndex]->szText, testlen)) || (!prefixOk && !lstrcmpi(text, group->cl.items[group->scanIndex]->szText)));

			if (show) {
				ClcGroup *contactGroup = group;
				int contactScanIndex = group->scanIndex;
				for (; group; group = group->parent)
					cli.pfnSetGroupExpand(hwnd, dat, group, 1);
				return cli.pfnGetRowsPriorTo(&dat->list, contactGroup, contactScanIndex);
			}
			if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
				if (!(dat->exStyle & CLS_EX_QUICKSEARCHVISONLY) || group->cl.items[group->scanIndex]->group->expanded) {
					group = group->cl.items[group->scanIndex]->group;
					group->scanIndex = 0;
					continue;
				}
			}
		}
		group->scanIndex++;
	}
	return -1;
}
Ejemplo n.º 6
0
MIR_CORE_DLL(void) ReloadLangpack(TCHAR *pszStr)
{
	if (pszStr == NULL)
		pszStr = NEWTSTR_ALLOCA(langPack.tszFileName);

	UnloadLangPackModule();
	LoadLangPack(pszStr);
	Langpack_SortDuplicates();

	NotifyEventHooks(hevChanged, 0, 0);
}
Ejemplo n.º 7
0
void CLuaOptions::LoadScripts()
{
	for (int i = 0; i < g_mLua->Scripts.getCount(); i++)
	{
		CMLuaScript *script = g_mLua->Scripts[i];
		TCHAR *fileName = NEWTSTR_ALLOCA(script->GetFileName());
		int iItem = m_scripts.AddItem(fileName, -1, (LPARAM)script);
		if (db_get_b(NULL, MODULE, _T2A(fileName), 1))
			m_scripts.SetCheckState(iItem, TRUE);
		m_scripts.SetItem(iItem, 1, TranslateT("Open"), 0);
	}
}
Ejemplo n.º 8
0
BOOL CJabberProto::DBCheckIsTransportedContact(const TCHAR *jid, HANDLE hContact)
{
	// check if transport is already set
	if (!jid || !hContact)
		return FALSE;

	// strip domain part from jid
	TCHAR *domain  = _tcschr((TCHAR*)jid, '@');
	BOOL   isAgent = (domain == NULL) ? TRUE : FALSE;
	BOOL   isTransported = FALSE;
	if (domain != NULL)
		domain = NEWTSTR_ALLOCA(domain+1);
	else
		domain = NEWTSTR_ALLOCA(jid);

	TCHAR *resourcepos = _tcschr(domain, '/');
	if (resourcepos != NULL)
		*resourcepos = '\0';

	for (int i=0; i < SIZEOF(TransportProtoTable); i++)
		if (MatchMask(domain, TransportProtoTable[i].mask)) {
			GetTransportStatusIconIndex(GetTransportProtoID(domain), ID_STATUS_OFFLINE);
			isTransported = TRUE;
			break;
		}

	if (m_lstTransports.getIndex(domain) == -1 && isAgent) {
		m_lstTransports.insert( mir_tstrdup(domain));
		setByte(hContact, "IsTransport", 1);
	}

	if (isTransported) {
		setTString(hContact, "Transport", domain);
		setByte(hContact, "IsTransported", 1);
	}
	return isTransported;
}
Ejemplo n.º 9
0
static int MO_RegisterIcon(TMO_IntMenuItem *pmi, void*)
{
	TCHAR *uname = (pmi->UniqName) ? mir_a2t(pmi->UniqName) : mir_tstrdup(pmi->CustomName),
		*descr = GetMenuItemText(pmi);

	if (!uname && !descr)
		return FALSE;

	if (!pmi->hIcolibItem) {
		HICON hIcon = ImageList_GetIcon(pmi->parent->m_hMenuIcons, pmi->iconId, 0);

		TCHAR sectionName[256];
		mir_sntprintf(sectionName, LPGENT("Menu icons") _T("/%s"), TranslateTS(pmi->parent->ptszDisplayName));

		char iconame[256];
		mir_snprintf(iconame, "genmenu_%s_%s", pmi->parent->pszName, uname && *uname ? uname : descr);

		// remove '&'
		if (descr) {
			descr = NEWTSTR_ALLOCA(descr);

			for (TCHAR *p = descr; *p; p++) {
				if ((p = _tcschr(p, '&')) == NULL)
					break;

				memmove(p, p + 1, sizeof(TCHAR)*(mir_tstrlen(p + 1) + 1));
				if (*p == '\0')
					p++;
			}
		}

		SKINICONDESC sid = { 0 };
		sid.flags = SIDF_TCHAR;
		sid.section.t = sectionName;
		sid.pszName = iconame;
		sid.description.t = descr;
		sid.hDefaultIcon = hIcon;
		pmi->hIcolibItem = IcoLib_AddIcon(&sid, 0);

		Safe_DestroyIcon(hIcon);
		if (hIcon = IcoLib_GetIcon(iconame)) {
			ImageList_ReplaceIcon(pmi->parent->m_hMenuIcons, pmi->iconId, hIcon);
			IcoLib_ReleaseIcon(hIcon);
		}
	}

	mir_free(uname);
	return FALSE;
}
Ejemplo n.º 10
0
bool hasMobileClient(MCONTACT hContact, LPARAM lParam)
{
	char *proto = GetContactProto(hContact);

	DBVARIANT dbv;
	if (!db_get_ts(hContact, proto, "MirVer", &dbv)) {
		TCHAR *client = _tcslwr(NEWTSTR_ALLOCA(dbv.ptszVal));
		db_free(&dbv);

		for (size_t i = 0; i < SIZEOF(clients); i++)
			if (_tcsstr(client, clients[i]))
				return true;
	}
	return false;
}
Ejemplo n.º 11
0
	void fillData(const TCHAR *jid)
	{
		TCHAR *room, *server, *nick = NULL;
		room = NEWTSTR_ALLOCA(jid);
		server = _tcschr(room, _T('@'));
		if (server) {
			*server++ = 0;
			nick = _tcschr(server, _T('/'));
			if (nick) *nick++ = 0;
		}
		else {
			server = room;
			room = NULL;
		}

		fillData(room, server, nick);
	}
Ejemplo n.º 12
0
MCONTACT CJabberProto::DBCreateContact(const TCHAR *jid, const TCHAR *nick, BOOL temporary, BOOL stripResource)
{
	if (jid == NULL || jid[0]=='\0')
		return NULL;

	TCHAR *s = NEWTSTR_ALLOCA(jid);
	TCHAR *q = NULL, *p;
	// strip resource if present
	if ((p = _tcschr(s, '@')) != NULL)
		if ((q = _tcschr(p, '/')) != NULL)
			*q = '\0';

	if (!stripResource && q != NULL)	// so that resource is not stripped
		*q = '/';

	// We can't use JabberHContactFromJID() here because of the stripResource option
	size_t len = _tcslen(s);
	for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) {
		ptrT jid( getTStringA(hContact, "jid"));
		if (jid == NULL)
			continue;

		TCHAR *p = jid;
		if (p && _tcslen(p) >= len && (p[len]=='\0'||p[len]=='/') && !_tcsnicmp(p, s, len))
			return hContact;
	}

	MCONTACT hNewContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
	CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hNewContact, (LPARAM)m_szModuleName);
	setTString(hNewContact, "jid", s);
	if (nick != NULL && *nick != '\0')
		setTString(hNewContact, "Nick", nick);
	if (temporary)
		db_set_b(hNewContact, "CList", "NotOnList", 1);
	else
		SendGetVcard(s);
	debugLog(_T("Create Jabber contact jid=%s, nick=%s"), s, nick);
	DBCheckIsTransportedContact(s,hNewContact);
	return hNewContact;
}
Ejemplo n.º 13
0
// enumerate all plugins that had valid DatabasePluginInfo()
static int tryCreateDatabase(const TCHAR* ptszProfile)
{
	TCHAR* tszProfile = NEWTSTR_ALLOCA(ptszProfile);
	CreatePathToFileT(tszProfile);

	for (int i=0; i < arDbPlugins.getCount(); i++) {
		DATABASELINK* p = arDbPlugins[i];

		int err = p->makeDatabase(tszProfile);
		if (err == ERROR_SUCCESS) {
			g_bDbCreated = true;
			MIDatabase *pDb = p->Load(tszProfile);
			if (pDb != NULL) {
				fillProfileName(tszProfile);
				currDblink = p;
				db_setCurrent(currDb = pDb);
				return 0;
			}
			return 1;
		}
	}
	return 1;
}
Ejemplo n.º 14
0
BOOL IsHighlighted(SESSION_INFO *si, GCEVENT *gce)
{
	if (!g_Settings->bHighlightEnabled || !g_Settings->pszHighlightWords || !gce || !si || !si->pMe)
		return FALSE;

	if (gce->ptszText == NULL)
		return FALSE;

	TCHAR *buf = RemoveFormatting(NEWTSTR_ALLOCA(gce->ptszText));

	int iStart = 0;
	CMString tszHighlightWords(g_Settings->pszHighlightWords);

	while (true) {
		CMString tszToken = tszHighlightWords.Tokenize(_T("\t "), iStart);
		if (iStart == -1)
			break;

		// replace %m with the users nickname
		if (tszToken == _T("%m"))
			tszToken = si->pMe->pszNick;

		if (tszToken.Find('*') == -1)
			tszToken = '*' + tszToken + '*';

		// time to get the next/first word in the incoming text string
		for (const TCHAR *p = buf; *p != '\0'; p += _tcscspn(p, _T(" "))) {
			p += _tcsspn(p, _T(" "));

			// compare the words, using wildcards
			if (wildcmpit(p, tszToken))
				return TRUE;
		}
	}

	return FALSE;
}
Ejemplo n.º 15
0
static BOOL MatchMask(const TCHAR *name, const TCHAR *mask)
{
	if (!mask || !name)
		return mask == name;

	if (*mask != '|')
		return WildComparei(name, mask);

	TCHAR *temp = NEWTSTR_ALLOCA(mask);
	for (int e=1; mask[e] != '\0'; e++) {
		int s = e;
		while (mask[e] != '\0' && mask[e] != '|')
			e++;

		temp[e]= 0;
		if (WildComparei(name, temp+s))
			return TRUE;

		if (mask[e] == 0)
			return FALSE;
	}

	return FALSE;
}
Ejemplo n.º 16
0
/*
*	Get the text for specified lines
*/
int Cache_GetLineText(
	ClcCacheEntry *pdnce, int type, LPTSTR text, int text_size, TCHAR *variable_text, BOOL xstatus_has_priority,
	BOOL show_status_if_no_away, BOOL show_listening_if_no_away, BOOL use_name_and_message_for_xstatus,
	BOOL pdnce_time_show_only_if_different)
{
	if (text == NULL)
		return TEXT_EMPTY;
	text[0] = '\0';

	switch (type) {
	case TEXT_STATUS:
		if (GetStatusName(text, text_size, pdnce, xstatus_has_priority) == -1 && use_name_and_message_for_xstatus) {
			DBVARIANT dbv = { 0 };

			// Try to get XStatusMsg
			if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusMsg", &dbv)) {
				if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0) {
					TCHAR *tmp = NEWTSTR_ALLOCA(text);
					mir_sntprintf(text, text_size, _T("%s: %s"), tmp, dbv.ptszVal);
					CopySkipUnprintableChars(text, text, text_size - 1);
				}
				db_free(&dbv);
			}
		}

		return TEXT_STATUS;

	case TEXT_NICKNAME:
		if (pdnce->hContact && pdnce->m_cache_cszProto) {
			DBVARIANT dbv = { 0 };
			if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "Nick", &dbv)) {
				mir_tstrncpy(text, dbv.ptszVal, text_size);
				db_free(&dbv);
				CopySkipUnprintableChars(text, text, text_size - 1);
			}
		}

		return TEXT_NICKNAME;

	case TEXT_STATUS_MESSAGE:
		if (GetStatusMessage(text, text_size, pdnce, xstatus_has_priority) == -1 && use_name_and_message_for_xstatus) {
			DBVARIANT dbv = { 0 };

			// Try to get XStatusName
			if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) {
				if (dbv.pszVal != NULL && dbv.pszVal[0] != 0) {
					TCHAR *tmp = NEWTSTR_ALLOCA(text);
					mir_sntprintf(text, text_size, _T("%s: %s"), dbv.pszVal, tmp);
				}
				CopySkipUnprintableChars(text, text, text_size - 1);
				db_free(&dbv);
			}
		}
		else if (use_name_and_message_for_xstatus && xstatus_has_priority) {
			DBVARIANT dbv = { 0 };
			// Try to get XStatusName
			if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) {
				if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0)
					mir_tstrncpy(text, dbv.ptszVal, text_size);
				CopySkipUnprintableChars(text, text, text_size - 1);
				db_free(&dbv);
			}
		}

		if (text[0] == '\0') {
			if (show_listening_if_no_away) {
				Cache_GetLineText(pdnce, TEXT_LISTENING_TO, text, text_size, variable_text, xstatus_has_priority, 0, 0, use_name_and_message_for_xstatus, pdnce_time_show_only_if_different);
				if (text[0] != '\0')
					return TEXT_LISTENING_TO;
			}

			if (show_status_if_no_away) {
				//re-request status if no away
				return Cache_GetLineText(pdnce, TEXT_STATUS, text, text_size, variable_text, xstatus_has_priority, 0, 0, use_name_and_message_for_xstatus, pdnce_time_show_only_if_different);
			}
		}
		return TEXT_STATUS_MESSAGE;

	case TEXT_LISTENING_TO:
		GetListeningTo(text, text_size, pdnce);
		return TEXT_LISTENING_TO;

	case TEXT_TEXT:
	{
		TCHAR *tmp = variables_parsedup(variable_text, pdnce->tszName, pdnce->hContact);
		mir_tstrncpy(text, tmp, text_size);
		mir_free(tmp);
		CopySkipUnprintableChars(text, text, text_size - 1);
	}
	return TEXT_TEXT;

	case TEXT_CONTACT_TIME:
		if (pdnce->hTimeZone) {
			// Get pdnce time
			text[0] = 0;
			TimeZone_PrintDateTime(pdnce->hTimeZone, _T("t"), text, text_size, 0);
		}

		return TEXT_CONTACT_TIME;
	}

	return TEXT_EMPTY;
}
Ejemplo n.º 17
0
//mir_free() the return value
static char* CreateRTFFromDbEvent(SrmmWindowData *dat, MCONTACT hContact, MEVENT hDbEvent, struct LogStreamData *streamData)
{
	int showColon = 0;

	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.cbBlob = db_event_getBlobSize(hDbEvent);
	if (dbei.cbBlob == -1)
		return NULL;

	dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob);
	db_event_get(hDbEvent, &dbei);
	if (!DbEventIsShown(&dbei)) {
		mir_free(dbei.pBlob);
		return NULL;
	}
	if (!(dbei.flags & DBEF_SENT) && (dbei.eventType == EVENTTYPE_MESSAGE || DbEventIsForMsgWindow(&dbei))) {
		db_event_markRead(hContact, hDbEvent);
		pcli->pfnRemoveEvent(hContact, hDbEvent);
	}
	else if (dbei.eventType == EVENTTYPE_JABBER_CHATSTATES || dbei.eventType == EVENTTYPE_JABBER_PRESENCE) {
		db_event_markRead(hContact, hDbEvent);
	}

	CMStringA buffer;
	if (!dat->bIsAutoRTL && !streamData->isEmpty)
		buffer.Append("\\par");

	if (dbei.flags & DBEF_RTL) {
		buffer.Append("\\rtlpar");
		dat->bIsAutoRTL = TRUE;
	}
	else buffer.Append("\\ltrpar");

	streamData->isEmpty = 0;

	if (dat->bIsAutoRTL) {
		if (dbei.flags & DBEF_RTL)
			buffer.Append("\\ltrch\\rtlch");
		else
			buffer.Append("\\rtlch\\ltrch");
	}

	if (g_dat.flags & SMF_SHOWICONS) {
		int i = ((dbei.eventType == EVENTTYPE_MESSAGE) ? ((dbei.flags & DBEF_SENT) ? LOGICON_MSG_OUT : LOGICON_MSG_IN): LOGICON_MSG_NOTICE);
		
		buffer.Append("\\f0\\fs14");
		buffer.Append(pLogIconBmpBits[i]);
	}

	if (g_dat.flags & SMF_SHOWTIME) {
		const TCHAR* szFormat;
		TCHAR str[64];

		if (g_dat.flags & SMF_SHOWSECS)
			szFormat = g_dat.flags & SMF_SHOWDATE ? _T("d s") : _T("s");
		else
			szFormat = g_dat.flags & SMF_SHOWDATE ? _T("d t") : _T("t");

		TimeZone_PrintTimeStamp(NULL, dbei.timestamp, szFormat, str, _countof(str), 0);

		buffer.AppendFormat(" %s ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYTIME : MSGFONTID_YOURTIME));
		AppendToBufferWithRTF(buffer, str);
		showColon = 1;
	}

	if (!(g_dat.flags & SMF_HIDENAMES) && dbei.eventType != EVENTTYPE_JABBER_CHATSTATES && dbei.eventType != EVENTTYPE_JABBER_PRESENCE) {
		TCHAR *szName;
		CONTACTINFO ci = { 0 };

		if (dbei.flags & DBEF_SENT) {
			ci.cbSize = sizeof(ci);
			ci.szProto = dbei.szModule;
			ci.dwFlag = CNF_DISPLAY | CNF_TCHAR;
			if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) {
				// CNF_DISPLAY always returns a string type
				szName = ci.pszVal;
			}
			else
				// Shouldn't happen?
				szName = mir_tstrdup(TranslateT("Me"));
		}
		else szName = pcli->pfnGetContactDisplayName(hContact, 0);

		buffer.AppendFormat(" %s ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYNAME : MSGFONTID_YOURNAME));
		AppendToBufferWithRTF(buffer, szName);
		showColon = 1;
		if (ci.pszVal)
			mir_free(ci.pszVal);
	}

	if (showColon)
		buffer.AppendFormat("%s :", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYCOLON : MSGFONTID_YOURCOLON));

	TCHAR *msg, *szName;
	switch (dbei.eventType) {
	case EVENTTYPE_JABBER_CHATSTATES:
	case EVENTTYPE_JABBER_PRESENCE:
		if (dbei.flags & DBEF_SENT) {
			CONTACTINFO ci = { sizeof(ci) };
			ci.hContact = NULL;
			ci.szProto = dbei.szModule;
			ci.dwFlag = CNF_DISPLAY | CNF_TCHAR;

			// CNF_DISPLAY always returns a string type
			if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)& ci))
				szName = NEWTSTR_ALLOCA(ci.pszVal);
			else
				szName = _T("");

			mir_free(ci.pszVal);
		}
		else szName = pcli->pfnGetContactDisplayName(hContact, 0);

		buffer.AppendFormat(" %s ", SetToStyle(MSGFONTID_NOTICE));
		AppendToBufferWithRTF(buffer, szName);
		AppendToBufferWithRTF(buffer, _T(" "));

		msg = DbGetEventTextT(&dbei, CP_ACP);
		if (msg) {
			AppendToBufferWithRTF(buffer, msg);
			mir_free(msg);
		}
		break;

	case EVENTTYPE_FILE:
		{
			char* filename = (char*)dbei.pBlob + sizeof(DWORD);
			char* descr = filename + mir_strlen(filename) + 1;
			
			ptrT ptszFileName(DbGetEventStringT(&dbei, filename));
			buffer.AppendFormat(" %s ", SetToStyle(MSGFONTID_NOTICE));
			AppendToBufferWithRTF(buffer, (dbei.flags & DBEF_SENT) ? TranslateT("File sent") : TranslateT("File received"));
			buffer.Append(": ");
			AppendToBufferWithRTF(buffer, ptszFileName);

			if (*descr != 0) {
				ptrT ptszDescr(DbGetEventStringT(&dbei, descr));
				buffer.Append(" (");
				AppendToBufferWithRTF(buffer, ptszDescr);
				buffer.Append(")");
			}
		}
		break;

	case EVENTTYPE_MESSAGE:
	default:
		msg = DbGetEventTextT(&dbei, CP_ACP);
		buffer.AppendFormat(" %s ", SetToStyle((dbei.eventType == EVENTTYPE_MESSAGE) ? ((dbei.flags & DBEF_SENT) ? MSGFONTID_MYMSG : MSGFONTID_YOURMSG) : MSGFONTID_NOTICE));
		AppendToBufferWithRTF(buffer, msg);
		mir_free(msg);
	}

	if (dat->bIsAutoRTL)
		buffer.Append("\\par");

	mir_free(dbei.pBlob);
	return buffer.Detach();
}
Ejemplo n.º 18
0
int CMsnProto::MSN_GCEventHook(WPARAM, LPARAM lParam)
{
	GCHOOK *gch = (GCHOOK*)lParam;
	if (!gch)
		return 1;

	if (_stricmp(gch->pDest->pszModule, m_szModuleName)) return 0;

	switch (gch->pDest->iType) {
	case GC_SESSION_TERMINATE:
		{
			GCThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID);
			if (thread != NULL) {
				m_arGCThreads.remove(thread);
				for (int i = 0; i < thread->mJoinedContacts.getCount(); i++)
					delete thread->mJoinedContacts[i];
				delete thread;
			}
		}
		break;

	case GC_USER_MESSAGE:
		if (gch->ptszText && gch->ptszText[0]) {
			GCThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID);
			if (thread) {
				TCHAR* pszMsg = UnEscapeChatTags(NEWTSTR_ALLOCA(gch->ptszText));
				rtrimt(pszMsg); // remove the ending linebreak
				msnNsThread->sendMessage('N', thread->szEmail, thread->netId, UTF8(pszMsg), 0);

				DBVARIANT dbv;
				int bError = getTString("Nick", &dbv);

				GCDEST gcd = { m_szModuleName, gch->pDest->ptszID, GC_EVENT_MESSAGE };
				GCEVENT gce = { sizeof(gce), &gcd };
				gce.dwFlags = GCEF_ADDTOLOG;
				gce.ptszNick = bError ? _T("") : dbv.ptszVal;
				gce.ptszUID = mir_a2t(MyOptions.szEmail);
				gce.time = time(NULL);
				gce.ptszText = gch->ptszText;
				gce.bIsMe = TRUE;
				CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);

				mir_free((void*)gce.ptszUID);
				if (!bError)
					db_free(&dbv);
			}
		}
		break;

	case GC_USER_CHANMGR:
		DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat,
			LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this)));
		break;

	case GC_USER_PRIVMESS:
		{
			char *email = mir_t2a(gch->ptszUID);
			MCONTACT hContact = MSN_HContactFromEmail(email);
			CallService(MS_MSG_SENDMESSAGE, hContact, 0);
			mir_free(email);
		}
		break;

	case GC_USER_LOGMENU:
		switch (gch->dwData) {
		case 10:
			DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat,
				LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this)));
			break;

		case 20:
			MSN_KillChatSession(gch->pDest->ptszID);
			break;
		}
		break;

	case GC_USER_NICKLISTMENU:
		MCONTACT hContact = MSN_HContactFromEmail(_T2A(gch->ptszUID));

		switch (gch->dwData) {
		case 10:
			CallService(MS_USERINFO_SHOWDIALOG, hContact, 0);
			break;

		case 20:
			CallService(MS_HISTORY_SHOWCONTACTHISTORY, hContact, 0);
			break;

		case 30:
			MSN_Kickuser(gch);
			break;

		case 110:
			MSN_KillChatSession(gch->pDest->ptszID);
			break;

		case 40:
			const TCHAR *pszRole = MSN_GCGetRole(MSN_GetThreadByChatId(gch->pDest->ptszID), _T2A(gch->ptszUID));
			MSN_Promoteuser(gch, (pszRole && !mir_tstrcmp(pszRole, _T("admin"))) ? "user" : "admin");
			break;
		}
		break;
	}

	return 0;
}
Ejemplo n.º 19
0
/*
	MS_VARS_GETCONTACTFROMSTRING
*/
int getContactFromString(CONTACTSINFO *ci)
{
	/* service to retrieve a contact's HANDLE from a given string */
	if (ci == NULL)
		return -1;

	TCHAR *tszContact;
	if (ci->flags & CI_UNICODE)
		tszContact = NEWTSTR_ALLOCA(ci->tszContact);
	else {
		WCHAR* tmp = mir_a2t(ci->szContact);
		tszContact = NEWTSTR_ALLOCA(tmp);
		mir_free(tmp);
	}
	if ((tszContact == NULL) || (_tcslen(tszContact) == 0))
		return -1;

	ci->hContacts = NULL;
	int count = 0;
	/* search the cache */
	{
		mir_cslock lck(csContactCache);
		for (int i=0; i < cacheSize; i++) {
			if ((!_tcscmp(cce[i].tszContact, tszContact)) && (ci->flags == cce[i].flags)) {
				/* found in cache */
				ci->hContacts = (MCONTACT*)mir_alloc(sizeof(MCONTACT));
				if (ci->hContacts == NULL)
					return -1;

				ci->hContacts[0] = cce[i].hContact;
				return 1;
			}
		}
	}

	/* contact was not in cache, do a search */
	for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact))
	{
		TCHAR *szFind = NULL;
		BOOL bMatch = FALSE;

		// <_HANDLE_:hContact>
		size_t size = _tcslen(_T(PROTOID_HANDLE)) + 36;
		szFind = (TCHAR *)mir_alloc(size * sizeof(TCHAR));
		if (szFind != NULL)
		{
			mir_sntprintf(szFind, size, _T("<%s:%p>"), _T(PROTOID_HANDLE), hContact);
			if (!_tcsncmp(tszContact, szFind, _tcslen(tszContact)))
				bMatch = TRUE;

			mir_free(szFind);
		}

		char *szProto = GetContactProto(hContact);
		if (szProto == NULL)
			continue;

		// <proto:id> (exact)
		if ((ci->flags & CI_PROTOID) && !bMatch)
		{
			TCHAR *cInfo = getContactInfoT(CNF_UNIQUEID, hContact);
			if (cInfo)
			{
				size_t size = _tcslen(cInfo) + strlen(szProto) + 4;
				szFind = (TCHAR *)mir_alloc(size * sizeof(TCHAR));
				if (szFind != NULL) {
					mir_sntprintf(szFind, size, _T("<%S:%s>"), szProto, cInfo);
					mir_free(cInfo);
					if (!_tcsncmp(tszContact, szFind, _tcslen(tszContact)))
						bMatch = TRUE;
					mir_free(szFind);
				}
			}
		}
		// id (exact)
		if ((ci->flags & CI_UNIQUEID) && (!bMatch)) {
			szFind = getContactInfoT(CNF_UNIQUEID, hContact);
			if (szFind != NULL) {
				if (!_tcscmp(tszContact, szFind))
					bMatch = TRUE;
				mir_free(szFind);
			}
		}
		// nick (not exact)
		if ((ci->flags & CI_NICK) && (!bMatch)) {
			szFind = getContactInfoT(CNF_NICK, hContact);
			if (szFind != NULL) {
				if (!_tcscmp(tszContact, szFind))
					bMatch = TRUE;
				mir_free(szFind);
			}
		}
		// list name (not exact)
		if ((ci->flags & CI_LISTNAME) && (!bMatch)) {
			szFind = getContactInfoT(CNF_DISPLAY, hContact);
			if (szFind != NULL) {
				if (!_tcscmp(tszContact, szFind))
					bMatch = TRUE;
				mir_free(szFind);
			}
		}
		// firstname (exact)
		if ((ci->flags & CI_FIRSTNAME) && (!bMatch)) {
			szFind = getContactInfoT(CNF_FIRSTNAME, hContact);
			if (szFind != NULL) {
				if (!_tcscmp(tszContact, szFind))
					bMatch = TRUE;
				mir_free(szFind);
			}
		}
		// lastname (exact)
		if ((ci->flags & CI_LASTNAME) && (!bMatch)) {
			szFind = getContactInfoT(CNF_LASTNAME, hContact);
			if (szFind != NULL) {
				if (!_tcscmp(tszContact, szFind))
					bMatch = TRUE;
				mir_free(szFind);
			}
		}
		// email (exact)
		if ((ci->flags & CI_EMAIL) && (!bMatch)) {
			szFind = getContactInfoT(CNF_EMAIL, hContact);
			if (szFind != NULL) {
				if (!_tcscmp(tszContact, szFind))
					bMatch = TRUE;
				mir_free(szFind);
			}
		}
		// CNF_ (exact)
		if ((ci->flags & CI_CNFINFO) && (!bMatch)) {
			szFind = getContactInfoT((BYTE)(ci->flags&~(CI_CNFINFO|CI_TCHAR)), hContact);
			if (szFind != NULL) {
				if (!_tcscmp(tszContact, szFind))
					bMatch = TRUE;
				mir_free(szFind);
			}
		}
		if (bMatch) {
			ci->hContacts = (MCONTACT*)mir_realloc(ci->hContacts, (count + 1)*sizeof(MCONTACT));
			if (ci->hContacts == NULL)
				return -1;

			ci->hContacts[count] = hContact;
			count += 1;
		}
	}

	if (count == 1) { /* cache the found result */
		mir_cslock lck(csContactCache);
		cce = (CONTACTCE*)mir_realloc(cce, (cacheSize+1)*sizeof(CONTACTCE));
		if (cce != NULL) {
			cce[cacheSize].hContact = ci->hContacts[0];
			cce[cacheSize].flags = ci->flags;
			cce[cacheSize].tszContact = mir_tstrdup(tszContact);
			if (cce[cacheSize].tszContact != NULL)
				cacheSize += 1;
		}
	}

	return count;
}
Ejemplo n.º 20
0
int CMsnProto::MSN_GCEventHook(WPARAM, LPARAM lParam) 
{
	GCHOOK *gch = (GCHOOK*) lParam;
	if (!gch)
		return 1;

	if (_stricmp(gch->pDest->pszModule, m_szModuleName)) return 0;

	switch (gch->pDest->iType) 
	{
		case GC_SESSION_TERMINATE: 
		{
 			ThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID);
			if (thread != NULL) 
				thread->sendTerminate();
			break;
		}

		case GC_USER_MESSAGE:
			if (gch->ptszText && gch->ptszText[0]) 
			{
				ThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID);
				if (thread)
				{
					rtrim(gch->ptszText); // remove the ending linebreak
					TCHAR* pszMsg = UnEscapeChatTags(NEWTSTR_ALLOCA(gch->ptszText));
					thread->sendMessage('N', NULL, NETID_MSN, UTF8(pszMsg), 0);

					DBVARIANT dbv;
					int bError = getTString("Nick", &dbv);

					GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_MESSAGE };
					gcd.ptszID = gch->pDest->ptszID;

					GCEVENT gce = {0};
					gce.cbSize = sizeof(GCEVENT);
					gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG;
					gce.pDest = &gcd;
					gce.ptszNick = bError ? _T("") : dbv.ptszVal;
					gce.ptszUID = mir_a2t(MyOptions.szEmail);
					gce.time = time(NULL);
					gce.ptszText = gch->ptszText;
					gce.bIsMe = TRUE;
					CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);

					mir_free((void*)gce.ptszUID);
					if (!bError)
						MSN_FreeVariant(&dbv);
				}
			}
			break;

		case GC_USER_CHANMGR: 
			DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat, 
				LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this)));
			break;

		case GC_USER_PRIVMESS: 
		{
			char *email = mir_t2a(gch->ptszUID);
			HANDLE hContact = MSN_HContactFromEmail(email);
			MSN_CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0);
			mir_free(email);
			break;
		}

		case GC_USER_LOGMENU:
			switch(gch->dwData) 
			{
			case 10: 
				DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat, 
					LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this)));
				break;

			case 20:
				MSN_KillChatSession(gch->pDest->ptszID);
				break;
			}
			break;

		case GC_USER_NICKLISTMENU: 
		{
			char *email = mir_t2a(gch->ptszUID);
			HANDLE hContact = MSN_HContactFromEmail(email);
			mir_free(email);

			switch(gch->dwData) 
			{
			case 10:
				MSN_CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0);
				break;

			case 20:
				MSN_CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)hContact, 0);
				break;

			case 110:
				MSN_KillChatSession(gch->pDest->ptszID);
				break;
			}
			break;
		}
/*	haven't implemented in chat.dll
		case GC_USER_TYPNOTIFY: 
		{
			int chatID = atoi(p);
			ThreadData* thread = MSN_GetThreadByContact((HANDLE)-chatID);
			for (int j=0; j < thread->mJoinedCount; j++) 
			{
				if ((long)thread->mJoinedContacts[j] > 0)
					CallService(MS_PROTO_SELFISTYPING, (WPARAM) thread->mJoinedContacts[j], (LPARAM) PROTOTYPE_SELFTYPING_ON);
			}
			break;
		}
*/
	}

	return 0;
}
Ejemplo n.º 21
0
void fnRebuildEntireList(HWND hwnd, struct ClcData *dat)
{
	DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
	ClcGroup *group;

	dat->list.expanded = 1;
	dat->list.hideOffline = db_get_b(NULL, "CLC", "HideOfflineRoot", 0) && style&CLS_USEGROUPS;
	dat->list.cl.count = dat->list.cl.limit = 0;
	dat->selection = -1;

	for (int i = 1;; i++) {
		DWORD groupFlags;
		TCHAR *szGroupName = cli.pfnGetGroupName(i, &groupFlags);
		if (szGroupName == NULL)
			break;
		cli.pfnAddGroup(hwnd, dat, szGroupName, groupFlags, i, 0);
	}

	for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) {
		if (style & CLS_SHOWHIDDEN || !db_get_b(hContact, "CList", "Hidden", 0)) {
			DBVARIANT dbv;
			if (db_get_ts(hContact, "CList", "Group", &dbv))
				group = &dat->list;
			else {
				group = cli.pfnAddGroup(hwnd, dat, dbv.ptszVal, (DWORD) - 1, 0, 0);
				if (group == NULL && style & CLS_SHOWHIDDEN) group = &dat->list;
				mir_free(dbv.ptszVal);
			}

			if (group != NULL) {
				group->totalMembers++;

				if (dat->filterSearch && dat->szQuickSearch[0] != '\0') {
					TCHAR *name = cli.pfnGetContactDisplayName(hContact, 0);
					TCHAR *lowered_name = CharLowerW(NEWTSTR_ALLOCA(name));
					TCHAR *lowered_search = CharLowerW(NEWTSTR_ALLOCA(dat->szQuickSearch));

					if (_tcsstr(lowered_name, lowered_search))
						cli.pfnAddContactToGroup(dat, group, hContact);
				}
				else if (!(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline)) {
					char *szProto = GetContactProto(hContact);
					if (szProto == NULL) {
						if (!cli.pfnIsHiddenMode(dat, ID_STATUS_OFFLINE))
							cli.pfnAddContactToGroup(dat, group, hContact);
					}
					else if (!cli.pfnIsHiddenMode(dat, db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE)))
						cli.pfnAddContactToGroup(dat, group, hContact);
				}
				else cli.pfnAddContactToGroup(dat, group, hContact);
			}
		}
	}

	if (style & CLS_HIDEEMPTYGROUPS) {
		group = &dat->list;
		group->scanIndex = 0;
		for (;;) {
			if (group->scanIndex == group->cl.count) {
				group = group->parent;
				if (group == NULL)
					break;
			}
			else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
				if (group->cl.items[group->scanIndex]->group->cl.count == 0) {
					group = cli.pfnRemoveItemFromGroup(hwnd, group, group->cl.items[group->scanIndex], 0);
				}
				else {
					group = group->cl.items[group->scanIndex]->group;
					group->scanIndex = 0;
				}
				continue;
			}
			group->scanIndex++;
		}
	}

	cli.pfnSortCLC(hwnd, dat, 0);
	cli.pfnSetAllExtraIcons(0);
}
Ejemplo n.º 22
0
void ShowPopup(XSTATUSCHANGE *xsc)
{
	DBVARIANT dbv;
	char szSetting[64];

	POPUPDATAT ppd = {0};
	ppd.lchContact = xsc->hContact;

	switch(xsc->type) {
	case TYPE_JABBER_MOOD:
	case TYPE_JABBER_ACTIVITY:
		mir_snprintf(szSetting, SIZEOF(szSetting), "%s/%s/%s", xsc->szProto, (xsc->type == TYPE_JABBER_MOOD) ? "mood" : "activity", "icon");
		if (!db_get_s(xsc->hContact, "AdvStatus", szSetting, &dbv)) {
			ppd.lchIcon = Skin_GetIcon(dbv.pszVal);
			db_free(&dbv);
		}
		break;

	case TYPE_ICQ_XSTATUS:
		{
			int statusId = db_get_b(xsc->hContact, xsc->szProto, "XStatusId", 0);
			ppd.lchIcon = (HICON)CallProtoService(xsc->szProto, PS_GETCUSTOMSTATUSICON, statusId, LR_SHARED);
		}
	}

	if (ppd.lchIcon == NULL)
		ppd.lchIcon = LoadSkinnedProtoIcon(xsc->szProto, db_get_w(xsc->hContact, xsc->szProto, "Status", ID_STATUS_ONLINE));

	switch (opt.Colors) {
	case POPUP_COLOR_OWN:
		ppd.colorBack = db_get_dw(0, MODULE, "40081bg", COLOR_BG_AVAILDEFAULT);
		ppd.colorText = db_get_dw(0, MODULE, "40081tx", COLOR_TX_DEFAULT);
		break;
	case POPUP_COLOR_WINDOWS:
		ppd.colorBack = GetSysColor(COLOR_BTNFACE);
		ppd.colorText = GetSysColor(COLOR_WINDOWTEXT);
		break;
	case POPUP_COLOR_POPUP:
		ppd.colorBack = ppd.colorText = 0;
		break;
	}

	TCHAR *ptszGroup = NULL;
	TCHAR *ptszNick = (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)xsc->hContact, GSMDF_TCHAR);
	if (opt.ShowGroup) { //add group name to popup title
		if (!db_get_ts(xsc->hContact, "CList", "Group", &dbv)) {
			ptszGroup = NEWTSTR_ALLOCA(dbv.ptszVal);
			db_free(&dbv);
		}
	}

	if (ptszGroup)
		mir_sntprintf(ppd.lptzContactName, SIZEOF(ppd.lptzContactName),_T("%s (%s)"), ptszNick, ptszGroup);
	else
		_tcsncpy(ppd.lptzContactName, ptszNick, SIZEOF(ppd.lptzContactName));

	// cut message if needed
	if (opt.PTruncateMsg && (opt.PMsgLen > 0) && xsc->stzText && (_tcslen(xsc->stzText) > opt.PMsgLen)) {
		TCHAR buff[MAX_TEXT_LEN + 3];
		_tcsncpy(buff, xsc->stzText, opt.PMsgLen);
		buff[opt.PMsgLen] = 0;
		_tcscat(buff, _T("..."));
		mir_free(xsc->stzText);
		xsc->stzText = mir_tstrdup(buff);
	}

	TCHAR *Template = _T("");
	switch (xsc->action) {
	case NOTIFY_NEW_XSTATUS:
		Template = templates.PopupNewXstatus; break;
	case NOTIFY_NEW_MESSAGE:
		Template = templates.PopupNewMsg; break;
	case NOTIFY_REMOVE:
		Template = templates.PopupRemove; break;
	case NOTIFY_OPENING_ML:
		Template = templates.LogOpening; break;
	}

	TCHAR stzPopupText[2*MAX_TEXT_LEN];
	ReplaceVars(xsc, Template, templates.PopupDelimiter, stzPopupText);
	_tcsncpy(ppd.lptzText, stzPopupText, SIZEOF(ppd.lptzText));
	ppd.lptzText[SIZEOF(ppd.lptzText) - 1] = 0;

	ppd.PluginWindowProc = (WNDPROC)PopupDlgProc;
	ppd.iSeconds = opt.PopupTimeout;
	PUAddPopupT(&ppd);
}
Ejemplo n.º 23
0
int __fastcall CLVM_GetContactHiddenStatus(MCONTACT hContact, char *szProto, ClcData *dat)
{
	int dbHidden = db_get_b(hContact, "CList", "Hidden", 0);		// default hidden state, always respect it.
	int filterResult = 1;
	int searchResult = 0;
	DBVARIANT dbv = { 0 };
	char szTemp[64];
	TCHAR szGroupMask[256];
	DWORD dwLocalMask;
	ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(hContact);
	// always hide subcontacts (but show them on embedded contact lists)

	if (dat != NULL && dat->IsMetaContactsEnabled && db_mc_isSub(hContact))
		return -1; //subcontact
	if (pdnce && pdnce->isUnknown && dat != NULL && !dat->force_in_dialog)
		return 1; //'Unknown Contact'
	if (dat != NULL && dat->filterSearch && pdnce && pdnce->tszName) {
		// search filtering
		TCHAR *lowered_name = CharLowerW(NEWTSTR_ALLOCA(pdnce->tszName));
		TCHAR *lowered_search = CharLowerW(NEWTSTR_ALLOCA(dat->szQuickSearch));
		searchResult = _tcsstr(lowered_name, lowered_search) ? 0 : 1;
	}
	if (pdnce && g_CluiData.bFilterEffective && dat != NULL && !dat->force_in_dialog) {
		if (szProto == NULL)
			szProto = GetContactProto(hContact);
		// check stickies first (priority), only if we really have stickies defined (CLVM_STICKY_CONTACTS is set).
		if (g_CluiData.bFilterEffective & CLVM_STICKY_CONTACTS) {
			if ((dwLocalMask = db_get_dw(hContact, CLVM_MODULE, g_CluiData.current_viewmode, 0)) != 0) {
				if (g_CluiData.bFilterEffective & CLVM_FILTER_STICKYSTATUS) {
					WORD wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE);
					return !((1 << (wStatus - ID_STATUS_OFFLINE)) & HIWORD(dwLocalMask)) | searchResult;
				}
				return 0 | searchResult;
			}
		}
		// check the proto, use it as a base filter result for all further checks
		if (g_CluiData.bFilterEffective & CLVM_FILTER_PROTOS) {
			mir_snprintf(szTemp, "%s|", szProto);
			filterResult = strstr(g_CluiData.protoFilter, szTemp) ? 1 : 0;
		}
		if (g_CluiData.bFilterEffective & CLVM_FILTER_GROUPS) {
			if (!db_get_ts(hContact, "CList", "Group", &dbv)) {
				mir_sntprintf(szGroupMask, _T("%s|"), &dbv.ptszVal[0]);
				filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? (filterResult | (_tcsstr(g_CluiData.groupFilter, szGroupMask) ? 1 : 0)) : (filterResult & (_tcsstr(g_CluiData.groupFilter, szGroupMask) ? 1 : 0));
				mir_free(dbv.ptszVal);
			}
			else if (g_CluiData.filterFlags & CLVM_INCLUDED_UNGROUPED)
				filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 1;
			else
				filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 0;
		}
		if (g_CluiData.bFilterEffective & CLVM_FILTER_STATUS) {
			WORD wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE);
			filterResult = (g_CluiData.filterFlags & CLVM_GROUPSTATUS_OP) ? ((filterResult | ((1 << (wStatus - ID_STATUS_OFFLINE)) & g_CluiData.statusMaskFilter ? 1 : 0))) : (filterResult & ((1 << (wStatus - ID_STATUS_OFFLINE)) & g_CluiData.statusMaskFilter ? 1 : 0));
		}
		if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG) {
			if (pdnce->dwLastMsgTime != -1) {
				DWORD now = g_CluiData.t_now;
				now -= g_CluiData.lastMsgFilter;
				if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG_OLDERTHAN)
					filterResult = filterResult & (pdnce->dwLastMsgTime < now);
				else if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG_NEWERTHAN)
					filterResult = filterResult & (pdnce->dwLastMsgTime > now);
			}
		}
		return (dbHidden | !filterResult | searchResult);
	}

	return dbHidden | searchResult;
}
Ejemplo n.º 24
0
INT_PTR CJabberDlgGcJoin::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_DELETEITEM:
		{
			LPDELETEITEMSTRUCT lpdis = (LPDELETEITEMSTRUCT)lParam;
			if (lpdis->CtlID != IDC_ROOM)
				break;

			RoomInfo *info = (RoomInfo *)lpdis->itemData;
			mir_free(info->line1);
			mir_free(info->line2);
			mir_free(info);
		}
		break;

	case WM_MEASUREITEM:
		{
			LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam;
			if (lpmis->CtlID != IDC_ROOM)
				break;

			lpmis->itemHeight = 2 * sttTextLineHeight;
			if (lpmis->itemID == -1)
				lpmis->itemHeight = sttTextLineHeight - 1;

		}
		break;

	case WM_DRAWITEM:
		{
			LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
			if (lpdis->CtlID != IDC_ROOM)
				break;

			RoomInfo *info = (RoomInfo *)SendDlgItemMessage(m_hwnd, IDC_ROOM, CB_GETITEMDATA, lpdis->itemID, 0);
			COLORREF clLine1, clBack;

			if (lpdis->itemState & ODS_SELECTED) {
				FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT));
				clBack = GetSysColor(COLOR_HIGHLIGHT);
				clLine1 = GetSysColor(COLOR_HIGHLIGHTTEXT);
			}
			else {
				FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_WINDOW));
				clBack = GetSysColor(COLOR_WINDOW);
				clLine1 = GetSysColor(COLOR_WINDOWTEXT);
			}
			COLORREF clLine2 = RGB(
				GetRValue(clLine1) * 0.66 + GetRValue(clBack) * 0.34,
				GetGValue(clLine1) * 0.66 + GetGValue(clBack) * 0.34,
				GetBValue(clLine1) * 0.66 + GetBValue(clBack) * 0.34);

			SetBkMode(lpdis->hDC, TRANSPARENT);

			RECT rc = lpdis->rcItem;
			rc.bottom -= (rc.bottom - rc.top) / 2;
			rc.left += 20;
			SetTextColor(lpdis->hDC, clLine1);
			DrawText(lpdis->hDC, info->line1, -1, &rc, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS);

			rc = lpdis->rcItem;
			rc.top += (rc.bottom - rc.top) / 2;
			rc.left += 20;
			SetTextColor(lpdis->hDC, clLine2);
			DrawText(lpdis->hDC, info->line2, -1, &rc, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS);

			DrawIconEx(lpdis->hDC, lpdis->rcItem.left + 1, lpdis->rcItem.top + 1, m_proto->LoadIconEx("group"), 16, 16, 0, NULL, DI_NORMAL);
			switch (info->overlay) {
			case RoomInfo::ROOM_WAIT:
				DrawIconEx(lpdis->hDC, lpdis->rcItem.left + 1, lpdis->rcItem.top + 1, m_proto->LoadIconEx("disco_progress"), 16, 16, 0, NULL, DI_NORMAL);
				break;
			case RoomInfo::ROOM_FAIL:
				DrawIconEx(lpdis->hDC, lpdis->rcItem.left + 1, lpdis->rcItem.top + 1, m_proto->LoadIconEx("disco_fail"), 16, 16, 0, NULL, DI_NORMAL);
				break;
			case RoomInfo::ROOM_BOOKMARK:
				DrawIconEx(lpdis->hDC, lpdis->rcItem.left + 1, lpdis->rcItem.top + 1, m_proto->LoadIconEx("disco_ok"), 16, 16, 0, NULL, DI_NORMAL);
				break;
			}
		}
		break;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDC_SERVER:
			switch (HIWORD(wParam)) {
			case CBN_EDITCHANGE:
			case CBN_SELCHANGE:
				{
					int iqid = GetWindowLongPtr(GetDlgItem(m_hwnd, IDC_ROOM), GWLP_USERDATA);
					if (iqid) {
						m_proto->m_iqManager.ExpireIq(iqid);
						SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_ROOM), GWLP_USERDATA, 0);
					}
					SendDlgItemMessage(m_hwnd, IDC_ROOM, CB_RESETCONTENT, 0, 0);
				}
				break;
			}
			break;

		case IDC_ROOM:
			switch (HIWORD(wParam)) {
			case CBN_DROPDOWN:
				if (!SendDlgItemMessage(m_hwnd, IDC_ROOM, CB_GETCOUNT, 0, 0)) {
					int iqid = GetWindowLongPtr(GetDlgItem(m_hwnd, IDC_ROOM), GWLP_USERDATA);
					if (iqid) {
						m_proto->m_iqManager.ExpireIq(iqid);
						SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_ROOM), GWLP_USERDATA, 0);
					}

					SendDlgItemMessage(m_hwnd, IDC_ROOM, CB_RESETCONTENT, 0, 0);

					int len = GetWindowTextLength(GetDlgItem(m_hwnd, IDC_SERVER)) + 1;
					TCHAR *server = (TCHAR*)_alloca(len * sizeof(TCHAR));
					GetDlgItemText(m_hwnd, IDC_SERVER, server, len);

					if (*server) {
						sttRoomListAppend(GetDlgItem(m_hwnd, IDC_ROOM), RoomInfo::ROOM_WAIT, TranslateT("Loading..."), TranslateT("Please wait for room list to download."), _T(""));

						CJabberIqInfo *pInfo = m_proto->AddIQ(&CJabberProto::OnIqResultDiscovery, JABBER_IQ_TYPE_GET, server, 0, -1, (void*)GetDlgItem(m_hwnd, IDC_ROOM));
						pInfo->SetTimeout(30000);
						XmlNodeIq iq(pInfo);
						iq << XQUERY(JABBER_FEAT_DISCO_ITEMS);
						m_proto->m_ThreadInfo->send(iq);

						SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_ROOM), GWLP_USERDATA, pInfo->GetIqId());
					}
					else
						sttRoomListAppend(GetDlgItem(m_hwnd, IDC_ROOM), RoomInfo::ROOM_FAIL,
						TranslateT("Jabber Error"),
						TranslateT("Please specify group chat directory first."),
						_T(""));
				}
				break;
			}
			break;

		case IDC_BOOKMARKS:
			{
				HMENU hMenu = CreatePopupMenu();

				LISTFOREACH(i, m_proto, LIST_BOOKMARK)
				{
					JABBER_LIST_ITEM *item = 0;
					if (item = m_proto->ListGetItemPtrFromIndex(i))
						if (!mir_tstrcmp(item->type, _T("conference")))
							AppendMenu(hMenu, MF_STRING, (UINT_PTR)item, item->name);
				}
				AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
				AppendMenu(hMenu, MF_STRING, (UINT_PTR)-1, TranslateT("Bookmarks..."));
				AppendMenu(hMenu, MF_STRING, (UINT_PTR)0, TranslateT("Cancel"));

				RECT rc; GetWindowRect(GetDlgItem(m_hwnd, IDC_BOOKMARKS), &rc);
				CheckDlgButton(m_hwnd, IDC_BOOKMARKS, BST_CHECKED);
				int res = TrackPopupMenu(hMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, m_hwnd, NULL);
				CheckDlgButton(m_hwnd, IDC_BOOKMARKS, BST_UNCHECKED);
				DestroyMenu(hMenu);

				if (res == -1)
					m_proto->OnMenuHandleBookmarks(0, 0);
				else if (res) {
					JABBER_LIST_ITEM *item = (JABBER_LIST_ITEM *)res;
					TCHAR *room = NEWTSTR_ALLOCA(item->jid);
					if (room) {
						TCHAR *server = _tcschr(room, _T('@'));
						if (server) {
							*server++ = 0;

							SendMessage(m_hwnd, WM_COMMAND, MAKEWPARAM(IDC_SERVER, CBN_EDITCHANGE), (LPARAM)GetDlgItem(m_hwnd, IDC_SERVER));

							SetDlgItemText(m_hwnd, IDC_SERVER, server);
							SetDlgItemText(m_hwnd, IDC_ROOM, room);
							SetDlgItemText(m_hwnd, IDC_NICK, item->nick);
							SetDlgItemText(m_hwnd, IDC_PASSWORD, item->password);
						}
					}
				}
			}
			break;

		case IDC_RECENT1:
		case IDC_RECENT2:
		case IDC_RECENT3:
		case IDC_RECENT4:
		case IDC_RECENT5:
			JabberGcRecentInfo info(m_proto, LOWORD(wParam) - IDC_RECENT1);
			info.fillForm(m_hwnd);
			if (GetAsyncKeyState(VK_CONTROL))
				break;

			OnBtnOk(NULL);
			Close();
		}
		break;

	case WM_JABBER_CHECK_ONLINE:
		if (!m_proto->m_bJabberOnline)
			EndDialog(m_hwnd, 0);
		break;
	}
Ejemplo n.º 25
0
int cliFindRowByText(HWND hwnd, ClcData *dat, const TCHAR *text, int prefixOk)
{
	ClcGroup *group = &dat->list;
	int testlen = (int)mir_tstrlen(text);
	ClcContact *contact = NULL;
	int SubCount = 0;

	group->scanIndex = 0;
	for (;;) {
		if (group->scanIndex == group->cl.count) {
			group = group->parent;
			if (group == NULL)
				break;
			group->scanIndex++;
			continue;
		}
		contact = group->cl.items[group->scanIndex];
		if (contact->type != CLCIT_DIVIDER) {
			bool found;
			if (dat->filterSearch) {
				TCHAR *lowered_szText = CharLowerW(NEWTSTR_ALLOCA(contact->szText));
				TCHAR *lowered_text = CharLowerW(NEWTSTR_ALLOCA(text));
				found = _tcsstr(lowered_szText, lowered_text) != NULL;
			}
			else found = (prefixOk && !_tcsnicmp(text, contact->szText, testlen)) || (!prefixOk && !mir_tstrcmpi(text, contact->szText));

			if (found) {
				ClcGroup *contactGroup = group;
				int contactScanIndex = group->scanIndex;
				for (; group; group = group->parent)
					pcli->pfnSetGroupExpand(hwnd, dat, group, 1);
				return pcli->pfnGetRowsPriorTo(&dat->list, contactGroup, contactScanIndex + SubCount);
			}
			if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
				if (!(dat->exStyle & CLS_EX_QUICKSEARCHVISONLY) || group->cl.items[group->scanIndex]->group->expanded) {
					group = group->cl.items[group->scanIndex]->group;
					group->scanIndex = 0;
					SubCount = 0;
					continue;
				}
			}
		}
		if (contact->type == CLCIT_CONTACT && contact->SubAllocated) {
			if (!(dat->exStyle & CLS_EX_QUICKSEARCHVISONLY) || contact->SubExpanded) {
				int i = 0;
				for (i = 0; i < contact->SubAllocated; i++) {
					ClcContact *subcontact = &(contact->subcontacts[i]);

					bool found;
					if (dat->filterSearch) {
						TCHAR *lowered_szText = CharLowerW(NEWTSTR_ALLOCA(subcontact->szText));
						TCHAR *lowered_text = CharLowerW(NEWTSTR_ALLOCA(text));
						found = _tcsstr(lowered_szText, lowered_text) != NULL;
					}
					else found = (prefixOk && !_tcsnicmp(text, subcontact->szText, testlen)) || (!prefixOk && !mir_tstrcmpi(text, subcontact->szText));

					if (found) {
						ClcGroup *contactGroup = group;
						int contactScanIndex = group->scanIndex;
						for (; group; group = group->parent)
							pcli->pfnSetGroupExpand(hwnd, dat, group, 1);
						if (!contact->SubExpanded)
							ExpandMetaContact(hwnd, contact, dat, 1);
						return pcli->pfnGetRowsPriorTo(&dat->list, contactGroup, contactScanIndex + SubCount + i + 1);
					}
				}
			}
		}
		if (contact->type == CLCIT_CONTACT && contact->SubAllocated && contact->SubExpanded)
			SubCount += contact->SubAllocated;
		group->scanIndex++;
	}
	return -1;
}
Ejemplo n.º 26
0
static INT_PTR ServiceParseMsnimLink(WPARAM, LPARAM lParam)
{
    if (lParam == 0) return 1; /* sanity check */

    TCHAR *arg = (TCHAR*)lParam;

    /* skip leading prefix */
    arg = _tcschr(arg, ':');
    if (arg == NULL) return 1; /* parse failed */

    for (++arg; *arg == '/'; ++arg) {}

    arg = NEWTSTR_ALLOCA(arg);

    if (g_Instances.getCount() == 0) return 0;

    CMsnProto *proto = &g_Instances[0];
    for (int i = 0; i < g_Instances.getCount(); ++i) {
        if (g_Instances[i].m_iStatus > ID_STATUS_OFFLINE) {
            proto = &g_Instances[i];
            break;
        }
    }
    if (proto == NULL) return 1;


    /* add a contact to the list */
    if (_tcsnicmp(arg, _T("add?"), 4) == 0) {
        arg += 4;

        TCHAR *email;
        MCONTACT hContact = GetContact(arg, &email, proto);
        if (email == NULL) return 1;

        /* does not yet check if email is current user */
        if (hContact == NULL) {
            PROTOSEARCHRESULT psr = { sizeof(psr) };
            psr.flags = PSR_TCHAR;
            psr.nick.t = email;
            psr.email.t = email;

            ADDCONTACTSTRUCT acs = { 0 };
            acs.handleType = HANDLE_SEARCHRESULT;
            acs.szProto = proto->m_szModuleName;
            acs.psr = &psr;
            CallService(MS_ADDCONTACT_SHOW, 0, (LPARAM)&acs);
        }
        return 0;
    }
    /* send a message to a contact */
    /* "voice" and "video" not yet implemented, perform same action as "chat" */
    else if (_tcsnicmp(arg, _T("chat?"), 5) == 0) {
        arg += 5;

        MCONTACT hContact = GetContact(arg, NULL, proto);

        if (hContact != NULL) {
            CallService(MS_MSG_SENDMESSAGE, hContact, 0);
            return 0;
        }
    }
    else if (_tcsnicmp(arg, _T("voice?"), 6) == 0) {
        arg += 6;

        MCONTACT hContact = GetContact(arg, NULL, proto);

        if (hContact != NULL) {
            CallService(MS_MSG_SENDMESSAGE, hContact, 0);
            return 0;
        }
    }
    else if (_tcsnicmp(arg, _T("video?"), 6) == 0) {
        arg += 6;

        MCONTACT hContact = GetContact(arg, NULL, proto);

        if (hContact != NULL) {
            CallService(MS_MSG_SENDMESSAGE, hContact, 0);
            return 0;
        }
    }
    return 1; /* parse failed */
}
Ejemplo n.º 27
0
int CMUCHighlight::match(const GCEVENT *pgce, const SESSION_INFO *psi, DWORD dwFlags)
{
	int result = 0, nResult = 0;

	if (pgce == 0 || m_Valid == false)
		return 0;

	if ((m_dwFlags & MATCH_TEXT) && (dwFlags & MATCH_TEXT) && (m_fHighlightMe || m_iTextPatterns > 0) && psi != 0) {
		TCHAR	*p = NEWTSTR_ALLOCA(pci->RemoveFormatting(pgce->ptszText));
		CharLower(p);

		TCHAR	*tszMe = ((psi && psi->pMe) ? NEWTSTR_ALLOCA(psi->pMe->pszNick) : 0);
		if (tszMe)
			CharLower(tszMe);

		if (m_fHighlightMe && tszMe) {
			result = wcsstr(p, tszMe) ? MATCH_TEXT : 0;
			if (0 == m_iTextPatterns)
				goto skip_textpatterns;
		}

		while (p && !result) {
			while (*p && (*p == ' ' || *p == ',' || *p == '.' || *p == ':' || *p == ';' || *p == '?' || *p == '!'))
				p++;

			if (*p == 0)
				break;

			TCHAR *p1 = p;
			while (*p1 && *p1 != ' ' && *p1 != ',' && *p1 != '.' && *p1 != ':' && *p1 != ';' && *p1 != '?' && *p1 != '!')
				p1++;

			if (*p1)
				*p1 = 0;
			else
				p1 = 0;

			for (UINT i = 0; i < m_iTextPatterns && !result; i++)
				result = wildcmpt(p, m_TextPatterns[i]) ? MATCH_TEXT : 0;

			if (p1) {
				*p1 = ' ';
				p = p1 + 1;
			}
			else p = 0;
		}
	}

skip_textpatterns:

	// optionally, match the nickname against the list of nicks to highlight
	if ((m_dwFlags & MATCH_NICKNAME) && (dwFlags & MATCH_NICKNAME) && pgce->ptszNick && m_iNickPatterns > 0) {
		for (UINT i = 0; i < m_iNickPatterns && !nResult; i++) {
			if (pgce->ptszNick)
				nResult = wildcmpt(pgce->ptszNick, m_NickPatterns[i]) ? MATCH_NICKNAME : 0;
			if ((m_dwFlags & MATCH_UIN) && pgce->ptszUserInfo)
				nResult = wildcmpt(pgce->ptszUserInfo, m_NickPatterns[i]) ? MATCH_NICKNAME : 0;
		}
	}

	return(result | nResult);
}
Ejemplo n.º 28
0
	void list_OnGetTip(CCtrlListView::TEventInfo *evt)
	{
		if (auto pTip = evt->nmlvit) {
			TCHAR profilename[MAX_PATH], tszFullPath[MAX_PATH];
			struct _stat statbuf;
			m_profileList.GetItemText(pTip->iItem, 0, profilename, _countof(profilename));
			mir_sntprintf(tszFullPath, _countof(tszFullPath), _T("%s\\%s\\%s.dat"), m_pd->ptszProfileDir, profilename, profilename);
			_tstat(tszFullPath, &statbuf);
			mir_sntprintf(pTip->pszText, pTip->cchTextMax, _T("%s\n%s: %s\n%s: %s"), tszFullPath, TranslateT("Created"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_ctime))), TranslateT("Modified"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_mtime))));
		}
	}
Ejemplo n.º 29
0
void CJabberProto::OnIqResultDiscovery(HXML iqNode, CJabberIqInfo *pInfo)
{
	if (!iqNode || !pInfo)
		return;

	HWND hwndList = (HWND)pInfo->GetUserData();
	SendMessage(hwndList, CB_SHOWDROPDOWN, FALSE, 0);
	SendMessage(hwndList, CB_RESETCONTENT, 0, 0);

	if (pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT) {
		HXML query = XmlGetChild(iqNode, "query");
		if (query == NULL) {
			sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL,
				TranslateT("Jabber Error"),
				TranslateT("Failed to retrieve room list from server."),
				_T(""));
		}
		else {
			bool found = false;
			HXML item;
			for (int i = 1; item = XmlGetNthChild(query, _T("item"), i); i++) {
				const TCHAR *jid = XmlGetAttrValue(item, _T("jid"));
				TCHAR *name = NEWTSTR_ALLOCA(jid);
				if (name) {
					if (TCHAR *p = _tcschr(name, _T('@')))
						*p = 0;
				}
				else name = _T("");

				sttRoomListAppend(hwndList,
					ListGetItemPtr(LIST_BOOKMARK, jid) ? RoomInfo::ROOM_BOOKMARK : RoomInfo::ROOM_DEFAULT,
					XmlGetAttrValue(item, _T("name")),
					jid, name);

				found = true;
			}

			if (!found) {
				sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL,
					TranslateT("Jabber Error"),
					TranslateT("No rooms available on server."),
					_T(""));
			}
		}
	}
	else if (pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR) {
		HXML errorNode = XmlGetChild(iqNode, "error");
		TCHAR *str = JabberErrorMsg(errorNode);
		sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL,
			TranslateT("Jabber Error"),
			str,
			_T(""));
		mir_free(str);
	}
	else
		sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL,
			TranslateT("Jabber Error"),
			TranslateT("Room list request timed out."),
			_T(""));

	SendMessage(hwndList, CB_SHOWDROPDOWN, TRUE, 0);
}
static BOOL CALLBACK JabberGroupchatJoinDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
	TCHAR text[128];
	TCHAR* p;

	switch ( msg ) {
	case WM_INITDIALOG:
		{
			// lParam is the room JID ( room@server ) in UTF-8
			hwndJabberJoinGroupchat = hwndDlg;
			TranslateDialogDefault( hwndDlg );
			if ( lParam ){
				_tcsncpy( text, ( TCHAR* )lParam, SIZEOF( text ));
				if (( p = _tcschr( text, '@' )) != NULL ) {
					*p = '\0';
					// Need to save room name in UTF-8 in case the room codepage is different
					// from the local code page
					TCHAR* room = mir_tstrdup( text );
					SetWindowLong( hwndDlg, GWL_USERDATA, ( LONG ) room );
					SetDlgItemText( hwndDlg, IDC_ROOM, room );
					SetDlgItemText( hwndDlg, IDC_SERVER, p+1 );
				}
				else SetDlgItemText( hwndDlg, IDC_SERVER, text );
			}

			DBVARIANT dbv;
			if ( !JGetStringT( NULL, "Nick", &dbv )) {
				SetDlgItemText( hwndDlg, IDC_NICK, dbv.ptszVal );
				JFreeVariant( &dbv );
			}
			else {
				TCHAR* nick = JabberNickFromJID( jabberJID );
				SetDlgItemText( hwndDlg, IDC_NICK, nick );
				mir_free( nick );
		}	}
		return TRUE;

	case WM_COMMAND:
		switch ( LOWORD( wParam )) {
		case IDC_ROOM:
			if (( HWND )lParam==GetFocus() && HIWORD( wParam )==EN_CHANGE ) {
				// Change in IDC_ROOM field is detected,
				// invalidate the saved UTF-8 room name if any
				char* str = ( char* )GetWindowLong( hwndDlg, GWL_USERDATA );
				if ( str != NULL ) {
					mir_free( str );
					SetWindowLong( hwndDlg, GWL_USERDATA, ( LONG ) NULL );
			}	}
			break;
		case IDOK:
			{
				GetDlgItemText( hwndDlg, IDC_SERVER, text, SIZEOF( text ));
				TCHAR* server = NEWTSTR_ALLOCA( text ), *room;

				if (( room=( TCHAR* )GetWindowLong( hwndDlg, GWL_USERDATA )) != NULL )
					room = NEWTSTR_ALLOCA( room );
				else {
					GetDlgItemText( hwndDlg, IDC_ROOM, text, SIZEOF( text ));
					room = NEWTSTR_ALLOCA( text );
				}

				GetDlgItemText( hwndDlg, IDC_NICK, text, SIZEOF( text ));
				TCHAR* nick = NEWTSTR_ALLOCA( text );

				GetDlgItemText( hwndDlg, IDC_PASSWORD, text, SIZEOF( text ));
				TCHAR* password = NEWTSTR_ALLOCA( text );
				JabberGroupchatJoinRoom( server, room, nick, password );
			}
			// fall through
		case IDCANCEL:
			EndDialog( hwndDlg, 0 );
			break;
		}
		break;
	case WM_JABBER_CHECK_ONLINE:
		if ( !jabberOnline ) EndDialog( hwndDlg, 0 );
		break;
	case WM_DESTROY:
		{
			char* str = ( char* )GetWindowLong( hwndDlg, GWL_USERDATA );
			if ( str != NULL )
				mir_free( str );

			hwndJabberJoinGroupchat = NULL;
		}
		break;
	}
	return FALSE;
}