⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 messageitem.cpp

📁 Simple Jabber Client for Symbian Platform
💻 CPP
字号:
/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *  Jabber
 *  Copyright (C) 2004 Xie Tian Lu  http://sabber.jabberstudio.org/
 */

#include "MessageItem.h"

#include <string.h>
#include "osaux.h"
#include "iconset.h"
#include "listboxicon.h"

#define KRgbSendItem		TRgb( 0x0d287b )
#define KRgbRecvItem		TRgb( 0x000000 )

CMessageItem* CMessageItem::CreateMessageItem( char* from, char* to, char* body, TBool recv )
{
	CMessageItem* inst = new CMessageItem();
	if ( from ) {
	#ifdef HEAP_ALLOC
		char*	t, f[ 128 ];
		strcpy( f, from );
		if ( t = strstr( from, "/" ) )
			*t = 0;
		inst->iFrom = new char[ strlen( f ) + 1 ];
		strcpy( inst->iFrom, f );
	#else
		strcpy( inst->iFrom, from );
	#endif
	}
	if ( to ) {
	#ifdef HEAP_ALLOC
		inst->iTo = new char[ strlen( to ) + 1 ];
		strcpy( inst->iTo,   to );
	#else
		strcpy( inst->iTo,   to );
	#endif
	}
	if ( body ) {
	#ifdef HEAP_ALLOC
		inst->iBody = new char[ strlen( body ) + 1 ];
		strcpy( inst->iBody, body );
	#else
		strcpy( inst->iBody, body );
	#endif
	}
	inst->iReceived = recv;
	if ( !inst->iReceived )
		inst->iRead = ETrue;

	return inst;
}

CMessageItem::CMessageItem() 
: iViewLine( -1 )
#ifdef HEAP_ALLOC
, iFrom( 0 ), iTo( 0 ), iBody( 0 ), iIconSet( 0 )
#endif
{
}

CMessageItem::~CMessageItem()
{
#ifdef HEAP_ALLOC
	delete[] iBody;
	delete[] iTo;
	delete[] iFrom;
	iBody = 0;
	iTo   = 0;
	iFrom = 0;
#endif
}

TInt CMessageItem::LineNum()
{
	return 1;
}

TInt CMessageItem::ViewLineNum()
{
	if ( iViewLine < 0 )
		return 0;

	return iViewLine;
}

void CMessageItem::ItemDraw( CWindowGc* gc, const TRect& aBox, TInt aItemHeight )
{
}

void CMessageItem::ItemDraw( CWindowGc* gc, const TRect& aBox, TInt aItemHeight, CFont* aFont )
{
	if ( iViewLine < 0 )
		CalcViewLineNum( aFont );

	DrawText( gc, aBox, aItemHeight, aFont );
	DrawIcon( gc, aBox );
}

void CMessageItem::DrawIcon( CWindowGc* gc, const TRect& aBox )
{
	if ( !iIconSet )
		return;

	int x = aBox.iTl.iX + 4;
	int y = aBox.iTl.iY;

	if ( iRead )
		iIconSet->DrawIcon( *gc, EMsgRead,   x, y );
	else
		iIconSet->DrawIcon( *gc, EMsgUnread, x, y );
}

void CMessageItem::DrawText( CWindowGc* gc, const TRect& aBox, TInt aItemHeight, CFont* aFont )
{
	int			lines = (aBox.iBr.iY-aBox.iTl.iY) / aItemHeight;
	TInt		l, r, y;
	TBuf<60>	abuf;
	char		from[ 128 ], *t;

	if ( iReceived )
		gc->SetPenColor( KRgbRecvItem );
	else
		gc->SetPenColor( KRgbSendItem );

	strcpy( from, iFrom );
	if ( t = strstr( from, "@" ) )
		*t = 0;
	CUtil::UTF82Unicode( abuf, from );
	
	if ( 0 ) //if ( iTime.Length() > 0 ) 
	{
		abuf.Append( ' ' );
		abuf.Append( '(' );
		abuf.Append( iTime );
		abuf.Append( ')' );
		abuf.Append( ' ' );
	}

	abuf.Append( ' ' );

	gc->UseFont( aFont );
	y = aBox.iTl.iY + 15;
	l = aBox.iTl.iX + 28;
	r = aBox.iBr.iX - 2;
	gc->DrawText( abuf, TPoint( l, y ) );
	l += aFont->MeasureText( abuf );

	DrawContent( gc, lines, aBox.iTl.iX + 28, r, l, y, aItemHeight, aFont );

}

void CMessageItem::DrawContent( CWindowGc* gc, int lines, 
							   int l, int r, int x, int y, 
							   int aItemHeight, CFont* aFont )
{
	TInt		pos = 0;
	TBuf<1024>	ibuf;
	CUtil::UTF82Unicode( ibuf, iBody );	
	for ( int j = 0; j < lines && pos < ibuf.Length(); j++ )
	{	
		DrawOneLine( gc, aFont, ibuf, pos, x, r, y, aItemHeight );
		x = l;
		y += aItemHeight;
	}
}


void CMessageItem::SetTimeStamp( TDesC& aStamp )
{
	iTime.Copy( aStamp );
}

void CMessageItem::SetIconSet( CIconSet* aSet )
{
	iIconSet = aSet;
}

char* CMessageItem::GetDest() 
{
	if ( iReceived )
		return iFrom;
	else
		return iTo;
}

TBool CMessageItem::IsReceived()
{
	return iReceived;
}

char* CMessageItem::GetFrom()
{
	return iFrom;
}

char* CMessageItem::GetTo()
{
	return iTo;
}

TDesC& CMessageItem::GetTimeStamp()
{
	return iTime;
}

void CMessageItem::CalcViewLineNum( CFont* aFont )
{
	int			lines = 3;
	TInt		pos = 0;
	TInt		j, l, r, y;
	TBuf<60>	abuf;
	TBuf<1024>	ibuf;
	char*		t, from[ 128 ];
	
	strcpy( from, iFrom );
	if ( t = strstr( from, "@" ) )
		*t = 0;
	CUtil::UTF82Unicode( abuf, from );
	
	//time
	if ( 0 ) //if ( iTime.Length() > 0 ) 
	{
		abuf.Append( ' ' );
		abuf.Append( '(' );
		abuf.Append( iTime );
		abuf.Append( ')' );
	}

	abuf.Append( ' ' );

	l = 28;
	r = 172;
	l += aFont->MeasureText( abuf );

	CUtil::UTF82Unicode( ibuf, iBody );
	for ( j = 0; j < lines && pos < ibuf.Length(); j++ )
	{	
		FillOneLine( ibuf, pos, l, r, aFont );
		l = 28;
		r = 172;
	}

	iViewLine = j - 1;
}

void CMessageItem::FillOneLine( const TDesC& txt, TInt& pos, TInt left, TInt right, CFont* font )
{
	TInt		begin;
	TInt		end;
	TInt		len;
	TInt		wline;
	TInt		wword;
	TBool		occupied;
	TBuf< 80 >	line;
	TBuf< 40 >	word;
	char		tword[ 128 ];

	begin = pos;
	len = 0;
	occupied = EFalse;

	do {
		line.Append( word );
		end = begin + len;
		begin = end;
		word.Zero();
		
		wline = font->MeasureText( line );

		GetNextWord( txt, begin, word );
		CUtil::Unicode2UTF8( tword, word );
		{
			len = word.Length();
			if ( len == 0 )
				break;

			wword = font->MeasureText( word );
			if ( wword + left > right ) {
				if ( occupied || line.Length() > 0 )
					break;				
				line.Zero();
				
				do {
					line.Append( txt[ end++ ] );
					wline = font->MeasureText( line );
				} while ( wline + left < right );
				pos = end;
				return;
			}
		}
	} while (  wline + wword + left < right );

	pos = end;
}

void CMessageItem::DrawOneLine( 
							  CWindowGc* gc, 
							  const CFont* font, 
							  const TDesC& txt, TInt& pos, 
							  TInt left, TInt right, 
							  TInt y, TInt height )
{
	TInt		begin;
	TInt		end;
	TInt		len;
	TInt		wline;
	TInt		wword;
	TBool		occupied;
	TBuf< 80 >	line;
	TBuf< 40 >	word;

	begin = pos;
	len = 0;
	occupied = EFalse;

	do {
		line.Append( word );
		end = begin + len;
		begin = end;
		word.Zero();
		
		wline = font->MeasureText( line );

		GetNextWord( txt, begin, word );
		{
			len = word.Length();
			if ( len == 0 )
				break;

			wword = font->MeasureText( word );
			if ( wword + left > right ) {
				if ( occupied || line.Length() > 0 )
					break;				
				line.Zero();
				
				do {
					line.Append( txt[ end++ ] );
					wline = font->MeasureText( line );
				} while ( wline + left < right );
				gc->DrawText( line, TPoint( left, y ) );
				pos = end;
				return;
			}
		}
	} while (  wline + wword + left < right );

	gc->DrawText( line, TPoint( left, y ) );
	pos = end;

}

/**
 * Get a word from text at given postion
 * parameter
 * @txt	 --
 * @pos  --
 * @word -- descriptor to keep regular word
 * return:
 *   emot icon inst if the word matches an emotion icon
 *   NULL otherwise, and the word is saved in word
 */
TInt CMessageItem::GetNextWord( const TDesC& txt, TInt pos, TDes& word )
{
	if ( pos >= txt.Length() )
		return 0;

	if ( txt[ pos ] & 0xff00 ) {		// Chinese char
		if ( txt[ pos ] == 0x2029 ) {
			word.Append( ' ' );
		} else {
			word.Append( txt[ pos ] );
		}
		pos++;
	} else {
		while ( pos < txt.Length() && CUtil::IsChar( txt[ pos ] ) ) {			
			word.Append( txt[ pos ] );
			pos++;
			if ( word.Length() >= word.MaxLength() )
				return 0;
		}
		if ( pos >= txt.Length() )
			return 0;

		if ( txt[ pos ] == '\r' || txt[ pos ] == '\n' ) {
			word.Append( ' ' );
		} else {
			word.Append( txt[ pos ] );
		}
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -