www.pudn.com > pueblo.zip > ChHtmMsg.cpp
/*----------------------------------------------------------------------------
_ _ _
/\ | | | (_)
/ \ _ __ __| |_ __ ___ _ __ ___ ___ __| |_ __ _
/ /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
/ ____ \| | | | (_| | | | (_) | | | | | | __/ (_| | | (_| |
/_/ \_\_| |_|\__,_|_| \___/|_| |_| |_|\___|\__,_|_|\__,_|
The contents of this file are subject to the Andromedia Public
License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.andromedia.com/APL/
Software distributed under the License is distributed on an
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Pueblo client code, released November 4, 1998.
The Initial Developer of the Original Code is Andromedia Incorporated.
Portions created by Andromedia are Copyright (C) 1998 Andromedia
Incorporated. All Rights Reserved.
Andromedia Incorporated 415.365.6700
818 Mission Street - 2nd Floor 415.365.6701 fax
San Francisco, CA 94103
Contributor(s):
--------------------------------------------------------------------------
Chaco team: Dan Greening, Glenn Crocker, Jim Doubek,
Coyote Lussier, Pritham Shetty.
Wrote and designed original codebase.
------------------------------------------------------------------------------
This file consists of the implementation of the ChHtmlView class.
----------------------------------------------------------------------------*/
// $Header: /home/cvs/chaco/api/ChHtmMsg.cpp,v 2.53 1996/09/12 18:32:59 pritham Exp $
#include "headers.h"
#include
#ifdef CH_UNIX
#include
#include
#include
#include
#include
#include
#include
#include
#else
#if !defined(CH_PUEBLO_PLUGIN)
#include "resource.h"
#else
#include "vwrres.h"
#endif
#endif
#include
#include "ChHtmlView.h"
#include
#include
#include
#include
#include "ChPlgInMgr.h"
#include
#include "ChHtmSym.h"
#include "ChHtmlParser.h"
#include "ChHTMLStream.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////////////////////////////////////////////////////////////////
// HTML Wnd native message handlers
#ifdef CH_MSW
BEGIN_MESSAGE_MAP(ChHtmlView, ChTxtWnd)
//{{AFX_MSG_MAP(ChHtmlView)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_SETCURSOR()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
//}}AFX_MSG_MAP
// ON_MESSAGE( WM_CHACO_HTTP_MSG, OnHTTPNotificaton )
END_MESSAGE_MAP()
#endif
#ifdef CH_UNIX
void ChHtmlView::OnLButtonUp( chuint32 nFlags, ChPoint& point )
#else
void ChHtmlView::OnLButtonUp( UINT nFlags, ChPoint point )
#endif
{
chparam userData;
#if defined( CH_VERBOSE )
{
cerr << "XXX ChHtmlView::OnLButtonUp" << endl;
}
#endif // defined( CH_VERBOSE )
ChPoint ptRel;
chint32 lStart = 0, lEnd = 0;
if ( IsSelectionEnabled() )
{
GetSel( lStart, lEnd );
}
if ( ( (lEnd - lStart) <= 1 ) &&
ChTxtWnd::PointOn( point.x, point.y, userData, &ptRel ) == ChTxtWnd::locHotspot )
{
GetFrameMgr()->OnViewSelectHotSpot( this, point.x, point.y, ptRel, userData );
}
ChTxtWnd::OnLButtonUp( nFlags, point );
}
#if defined( CH_MSW )
/*----------------------------------------------------------------------------
FUNCTION || ChHtmlView::OnMouseMove
------------------------------------------------------------------------------
OnMouseMove calls OnHotSpot if the mouse enters a new hotspot. This is called only
once. When the mouse moves out of the hotspot, OnHotSpot is called with 0 userData,
----------------------------------------------------------------------------*/
void ChHtmlView::OnMouseMove(UINT nFlags, CPoint point)
{
chparam userData;
static chparam lastHotSpot = 0;
int iMouseOn = ChTxtWnd::locUnknown;
if ( !( nFlags & MK_LBUTTON ) &&
(iMouseOn = ChTxtWnd::PointOn( point.x, point.y, userData )) == ChTxtWnd::locHotspot )
{
m_hCursor = m_hHTMLCursors[ cursorHotspot ];
::SetCursor( m_hHTMLCursors[ cursorHotspot ] );
if ( lastHotSpot != userData )
{
lastHotSpot = userData;
GetFrameMgr()->OnViewHotSpot( this, userData );
}
}
else
{
if ( lastHotSpot )
{
lastHotSpot = 0;
GetFrameMgr()->OnViewHotSpot( this, lastHotSpot );
}
if ( !IsSelectionEnabled() || ChTxtWnd::locUnknown == iMouseOn
|| ChTxtWnd::locObject == iMouseOn )
{
m_hCursor = m_hHTMLCursors[ cursorNormal ];
}
else if ( iMouseOn == ChTxtWnd::locText )
{
m_hCursor = m_hHTMLCursors[ cursorText ];
}
else
{
m_hCursor = NULL;
}
}
ChTxtWnd::OnMouseMove( nFlags, point );
}
BOOL ChHtmlView::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
{
if (m_hCursor)
{
::SetCursor( m_hCursor );
return true;
}
else
{
return ChTxtWnd::OnSetCursor( pWnd, nHitTest, message );
}
}
void ChHtmlView::OnSetFocus(CWnd* pOldWnd)
{
ChTxtWnd::OnSetFocus(pOldWnd);
// TODO: Add your message handler code here
// Notify my parent of focus change
if ( m_iEmbedMode == embedInternal )
{
GetFrameMgr()->SendMessage( WM_SETFOCUS,
(WPARAM)(pOldWnd ? pOldWnd->GetSafeHwnd() : 0) );
}
}
void ChHtmlView::OnKillFocus(CWnd* pNewWnd)
{
ChTxtWnd::OnKillFocus(pNewWnd);
// TODO: Add your message handler code here
// Notify my parent of focus change
GetFrameMgr()->SendMessage( WM_KILLFOCUS,
(WPARAM)(pNewWnd ? pNewWnd->GetSafeHwnd() : 0) );
}
void ChHtmlView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
GetFrameMgr()->OnRightMouseDown( point, GetFrameName() );
ChTxtWnd::OnRButtonDown(nFlags, point);
}
void ChHtmlView::OnRButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
GetFrameMgr()->OnRightMouseUp( point, GetFrameName() );
ChTxtWnd::OnRButtonUp(nFlags, point);
}
#endif // defined( CH_MSW )
/*----------------------------------------------------------------------------
Override this virtual member function if you need notification when the
HTML parser detects a prefetch tag in the document.
----------------------------------------------------------------------------*/
void ChHtmlView::OnPrefetch( ChHTMLPrefetch* pFetch, const string& strDocURL )
{
/* Call base class to perform the
prefetching */
if (ChUtil::GetSystemProperties() & CH_PROP_MULTITHREADED)
{
GetFrameMgr()->PrefetchURL( pFetch->GetHREF(), strDocURL );
}
}
/*----------------------------------------------------------------------------
FUNCTION || ChHtmlView::UpdateTextColor()
------------------------------------------------------------------------------
This method computes the location of the object on the canvas.
----------------------------------------------------------------------------*/
void ChHtmlView::UpdateTextColor( chuint32 luOldTextColor,
chuint32 luOldLinkColor,
chuint32 luOldVLinkColor,
chuint32 luOldPrefetchColor )
{
// Get the new colors
chuint32 luTextColor = GetSettings()->GetTextColor();
chuint32 luLinkColor = GetSettings()->GetLinkColor();
chuint32 luVLinkColor = GetSettings()->GetVistedLinkColor();
chuint32 luPrefetchColor = GetSettings()->GetPrefetchedLinkColor();
chuint32 luBackColor = GetSettings()->GetBackColor();
// find the first run using this object
pChStyleInfo pStyleUse = GetStyleTable();
pChRun pRun = GetRunTable();
// do we have any runs with hot spot in this line
chint32 lIndex = 0;
// skip all the object at the begining of the line
while( lIndex < GetRunCount() )
{
if ( pStyleUse[ pRun->lStyleIndex ].style.luStyle & ChTxtWnd::textHotSpot )
{
if ( luOldLinkColor == pStyleUse[ pRun->lStyleIndex ].style.lColor )
{
pStyleUse[ pRun->lStyleIndex ].style.lColor = luLinkColor;
}
else if ( luOldVLinkColor == pStyleUse[ pRun->lStyleIndex ].style.lColor )
{
pStyleUse[ pRun->lStyleIndex ].style.lColor = luVLinkColor;
}
else if ( luOldPrefetchColor == pStyleUse[ pRun->lStyleIndex ].style.lColor )
{
pStyleUse[ pRun->lStyleIndex ].style.lColor = luPrefetchColor;
}
}
else if ( luOldTextColor == pStyleUse[ pRun->lStyleIndex ].style.lColor )
{
pStyleUse[ pRun->lStyleIndex ].style.lColor = luTextColor;
}
++pRun;
++lIndex;
}
}
void ChHtmlView::UpdateFontChange( const string& strOldProportional, int iOldProportionalSize,
const string& strOldFixed, int iOldFixedSize )
{
string strNewFixed = GetSettings()->GetFixedFontName();
string strNewProportional = GetSettings()->GetProportionalFontName();
int iNewFixedSize = GetSettings()->GetFixedFontSize();
int iNewProportionalSize = GetSettings()->GetProportionalFontSize();
bool boolUpdateFixed = false;
bool boolUpdateProportional = false;
if ( iOldFixedSize != iNewFixedSize
|| strOldFixed != strNewFixed )
{
boolUpdateFixed = true;
}
if ( iOldProportionalSize != iNewProportionalSize
|| strOldProportional != strNewProportional )
{
boolUpdateProportional = true;
}
if ( !boolUpdateProportional && !boolUpdateFixed )
{
return;
}
// New font name and size
ChClientDC dc( this );
SetContext( &dc );
#if defined( CH_MSW )
pChFontInfo pFontTbl = ChTxtWnd::GetFontTable();
#endif // defined( CH_MSW )
/* Remap all the font names to new
font selected */
for (int i = 1; i < ChTxtWnd::GetFontCount(); i++)
{
#if defined( CH_MSW )
{
bool boolUpdate = false;
if ( pFontTbl[i].iUseCount <= 0 || pFontTbl[i].pFont == 0 )
{
continue;
}
if (boolUpdateProportional &&
!lstrcmpi( pFontTbl[i].fontInfo.lfFaceName, strOldProportional ))
{
int iSizeExtra;
lstrcpy( pFontTbl[i].fontInfo.lfFaceName, strNewProportional );
iSizeExtra = (-1 * pFontTbl[i].fontInfo.lfHeight) -
iOldProportionalSize;
pFontTbl[i].fontInfo.lfHeight = -1 * (iNewProportionalSize +
iSizeExtra);
boolUpdate = true;
}
else if (boolUpdateFixed &&
!lstrcmpi( pFontTbl[i].fontInfo.lfFaceName, strOldFixed ))
{
int iSizeExtra;
lstrcpy( pFontTbl[i].fontInfo.lfFaceName, strNewFixed );
iSizeExtra = (-1 * pFontTbl[i].fontInfo.lfHeight) -
iOldFixedSize;
pFontTbl[i].fontInfo.lfHeight = -1 * (iNewFixedSize + iSizeExtra);
boolUpdate = true;
}
if (boolUpdate)
{
CFont* pOldFont;
TEXTMETRIC textMetric;
// Delete the old font
delete pFontTbl[i].pFont;
pFontTbl[i].pFont = new ChFont;
pFontTbl[i].pFont->CreateFontIndirect( &pFontTbl[i].fontInfo );
pOldFont = GetContext()->SelectObject( pFontTbl[i].pFont );
GetContext()->GetTextMetrics( &textMetric );
GetContext()->SelectObject( pOldFont );
pChStyleInfo pStyle = GetStyleTable();
for ( int j = 0; j < GetStyleCount(); j++ )
{
if ( pStyle[j].style.iFontIndex == i )
{
pStyle[j].iFontHeight = textMetric.tmHeight +
textMetric.tmExternalLeading;
pStyle[j].iFontAscent = textMetric.tmAscent;
pStyle[j].iFontDescent = textMetric.tmDescent;
}
}
}
}
#else // defined( CH_MSW )
{
}
#endif // defined( CH_MSW )
}
if ( boolUpdateProportional || boolUpdateFixed )
{
/* Recompute the line table and
redraw */
ChTxtWnd::UpdateLineTable( 0, ChTxtWnd::GetTextCount(), vwUpdate );
InvalidateRect( 0 );
}
}
void ChHtmlView::UpdateColorChange( chuint32 luOldTextColor, chuint32 luOldLinkColor,
chuint32 luOldVLinkColor, chuint32 luOldPrefetchColor,
chuint32 luBackColor )
{
if (ChTxtWnd::m_defBkColor.GetSafeHandle())
{
ChTxtWnd::m_defBkColor.DeleteObject();
}
ChTxtWnd::m_defBkColor.CreateSolidBrush( GetSettings()->GetBackColor() );
// Map all the new colors
UpdateTextColor( luOldTextColor, luOldLinkColor, luOldVLinkColor,
luOldPrefetchColor );
if ( m_pParser )
{
m_pParser->UpdateColors( luOldTextColor, luBackColor );
}
if ( GetSafeHwnd() )
{
// Update all the text colors
InvalidateRect( NULL, true );
}
}
void ChHtmlView::RemapColors( int iNumColors,
chuint32* pluOldColor, chuint32* pluNewMap )
{
// find the first run using this object
pChStyleInfo pStyleUse = GetStyleTable();
pChRun pRun = GetRunTable();
// do we have any runs with hot spot in this line
chint32 lIndex = 0;
// skip all the object at the begining of the line
bool boolUpdate = false;
while( lIndex < GetRunCount() )
{
for ( int i = 0; i < iNumColors; i++ )
{
if ( pluOldColor[i] == (chuint32)pStyleUse[ pRun->lStyleIndex ].style.lColor )
{
pStyleUse[ pRun->lStyleIndex ].style.lColor = pluNewMap[i];
boolUpdate = true;
break;
}
}
++pRun;
++lIndex;
}
if ( boolUpdate && GetSafeHwnd() )
{
// Update all the text colors
InvalidateRect( NULL, true );
}
}
// Local Variables: ***
// tab-width:4 ***
// End: ***