Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

RichDocument.cpp

Go to the documentation of this file.
00001 //
00002 // RichDocument.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "RichDocument.h"
00025 #include "RichElement.h"
00026 #include "XML.h"
00027 
00028 #ifdef _DEBUG
00029 #undef THIS_FILE
00030 static char THIS_FILE[]=__FILE__;
00031 #define new DEBUG_NEW
00032 #endif
00033 
00034 
00036 // CRichDocument construction
00037 
00038 CRichDocument::CRichDocument() : m_szMargin( 8, 8 )
00039 {
00040         m_nCookie               = 0;
00041         m_crBackground  = RGB( 255, 255, 255 );
00042         m_crText                = RGB( 0, 0, 0 );
00043         m_crLink                = RGB( 0, 0, 255 );
00044         m_crHover               = RGB( 255, 0, 0 );
00045         m_crHeading             = RGB( 0x80, 0, 0 );
00046 }
00047 
00048 CRichDocument::~CRichDocument()
00049 {
00050         Clear();
00051 }
00052 
00054 // CRichDocument element access
00055 
00056 POSITION CRichDocument::GetIterator() const
00057 {
00058         return m_pElements.GetHeadPosition();
00059 }
00060 
00061 CRichElement* CRichDocument::GetNext(POSITION& pos) const
00062 {
00063         return (CRichElement*)m_pElements.GetNext( pos );
00064 }
00065 
00066 CRichElement* CRichDocument::GetPrev(POSITION& pos) const
00067 {
00068         return (CRichElement*)m_pElements.GetPrev( pos );
00069 }
00070 
00071 int CRichDocument::GetCount() const
00072 {
00073         return m_pElements.GetCount();
00074 }
00075 
00076 POSITION CRichDocument::Find(CRichElement* pElement) const
00077 {
00078         return m_pElements.Find( pElement );
00079 }
00080 
00082 // CRichDocument element modification
00083 
00084 CRichElement* CRichDocument::Add(CRichElement* pElement, POSITION posBefore)
00085 {
00086         CSingleLock pLock( &m_pSection, TRUE );
00087         
00088         if ( posBefore )
00089                 m_pElements.InsertBefore( posBefore, pElement );
00090         else
00091                 m_pElements.AddTail( pElement );
00092 
00093         pElement->m_pDocument = this;
00094         m_nCookie++;
00095 
00096         return pElement;
00097 }
00098 
00099 CRichElement* CRichDocument::Add(int nType, LPCTSTR pszText, LPCTSTR pszLink, DWORD nFlags, int nGroup, POSITION posBefore)
00100 {
00101         CRichElement* pElement = new CRichElement( nType, pszText, pszLink, nFlags, nGroup );
00102         return Add( pElement, posBefore );
00103 }
00104 
00105 void CRichDocument::Remove(CRichElement* pElement)
00106 {
00107         CSingleLock pLock( &m_pSection, TRUE );
00108         
00109         if ( POSITION pos = m_pElements.Find( pElement ) )
00110         {
00111                 m_pElements.RemoveAt( pos );
00112                 pElement->m_pDocument = NULL;
00113                 m_nCookie++;
00114         }
00115 }
00116 
00117 void CRichDocument::ShowGroup(int nGroup, BOOL bShow)
00118 {
00119         CSingleLock pLock( &m_pSection, TRUE );
00120         
00121         for ( POSITION pos = GetIterator() ; pos ; )
00122         {
00123                 CRichElement* pElement = GetNext( pos );
00124                 if ( pElement->m_nGroup == nGroup ) pElement->Show( bShow );
00125         }
00126 }
00127 
00128 void CRichDocument::ShowGroupRange(int nMin, int nMax, BOOL bShow)
00129 {
00130         CSingleLock pLock( &m_pSection, TRUE );
00131         
00132         for ( POSITION pos = GetIterator() ; pos ; )
00133         {
00134                 CRichElement* pElement = GetNext( pos );
00135                 if ( pElement->m_nGroup >= nMin && pElement->m_nGroup <= nMax )
00136                         pElement->Show( bShow );
00137         }
00138 }
00139 
00140 void CRichDocument::SetModified()
00141 {
00142         m_nCookie++;
00143 }
00144 
00145 void CRichDocument::Clear()
00146 {
00147         CSingleLock pLock( &m_pSection, TRUE );
00148         
00149         for ( POSITION pos = GetIterator() ; pos ; )
00150         {
00151                 delete GetNext( pos );
00152         }
00153 
00154         m_pElements.RemoveAll();
00155         m_nCookie++;
00156 }
00157 
00159 // CRichDocument font construction
00160 
00161 void CRichDocument::CreateFonts(LPCTSTR pszFaceName, int nSize)
00162 {
00163         CSingleLock pLock( &m_pSection, TRUE );
00164         
00165         if ( m_fntNormal.m_hObject ) m_fntNormal.DeleteObject();
00166         
00167         m_fntNormal.CreateFont( -nSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
00168                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
00169                 DEFAULT_PITCH|FF_DONTCARE, pszFaceName );
00170         
00171         if ( m_fntBold.m_hObject ) m_fntBold.DeleteObject();
00172         
00173         m_fntBold.CreateFont( -nSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
00174                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
00175                 DEFAULT_PITCH|FF_DONTCARE, pszFaceName );
00176         
00177         if ( m_fntItalic.m_hObject ) m_fntItalic.DeleteObject();
00178         
00179         m_fntItalic.CreateFont( -nSize, 0, 0, 0, FW_NORMAL, TRUE, FALSE, FALSE,
00180                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
00181                 DEFAULT_PITCH|FF_DONTCARE, pszFaceName );
00182         
00183         if ( m_fntUnder.m_hObject ) m_fntUnder.DeleteObject();
00184         
00185         m_fntUnder.CreateFont( -nSize, 0, 0, 0, FW_NORMAL, FALSE, TRUE, FALSE,
00186                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
00187                 DEFAULT_PITCH|FF_DONTCARE, pszFaceName );
00188         
00189         if ( m_fntBoldUnder.m_hObject ) m_fntBoldUnder.DeleteObject();
00190         
00191         m_fntBoldUnder.CreateFont( -nSize, 0, 0, 0, FW_BOLD, FALSE, TRUE, FALSE,
00192                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
00193                 DEFAULT_PITCH|FF_DONTCARE, pszFaceName );
00194         
00195         if ( m_fntHeading.m_hObject ) m_fntHeading.DeleteObject();
00196         
00197         m_fntHeading.CreateFont( -( nSize + 6 ), 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, FALSE,
00198                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
00199                 DEFAULT_PITCH|FF_DONTCARE, pszFaceName );
00200 }
00201 
00203 // CRichDocument XML Load
00204 
00205 BOOL CRichDocument::LoadXML(CXMLElement* pBase, CMapStringToPtr* pMap, int nGroup)
00206 {
00207         CSingleLock pLock( &m_pSection, TRUE );
00208         
00209         if ( pBase == NULL ) return FALSE;
00210         
00211         CString strTemp;
00212         
00213         if ( pBase->IsNamed( _T("document") ) )
00214         {
00215                 strTemp = pBase->GetAttributeValue( _T("fontFace") );
00216                 if ( strTemp.GetLength() ) CreateFonts( strTemp );
00217                 
00218                 LoadXMLColour( pBase, _T("crBackground"), &m_crBackground );
00219                 LoadXMLColour( pBase, _T("crText"), &m_crText );
00220                 LoadXMLColour( pBase, _T("crLink"), &m_crLink );
00221                 LoadXMLColour( pBase, _T("crHover"), &m_crHover );
00222                 LoadXMLColour( pBase, _T("crHeading"), &m_crHeading );
00223                 
00224                 strTemp = pBase->GetAttributeValue( _T("leftMargin") );
00225                 if ( strTemp.GetLength() ) _stscanf( strTemp, _T("%i"), &m_szMargin.cx );
00226                 strTemp = pBase->GetAttributeValue( _T("topMargin") );
00227                 if ( strTemp.GetLength() ) _stscanf( strTemp, _T("%i"), &m_szMargin.cy );
00228         }
00229         
00230         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
00231         {
00232                 CXMLElement* pXML               = pBase->GetNextElement( pos );
00233                 CRichElement* pElement  = NULL;
00234                 
00235                 if ( pXML->IsNamed( _T("text") ) )
00236                 {
00237                         pElement = new CRichElement( retText );
00238                 }
00239                 else if ( pXML->IsNamed( _T("link") ) )
00240                 {
00241                         pElement = new CRichElement( retLink );
00242                 }
00243                 else if ( pXML->IsNamed( _T("heading") ) )
00244                 {
00245                         pElement = new CRichElement( retHeading );
00246                 }
00247                 else if ( pXML->IsNamed( _T("newline") ) )
00248                 {
00249                         pElement = new CRichElement( retNewline );
00250                         
00251                         strTemp = pXML->GetAttributeValue( _T("gap") );
00252                         
00253                         if ( strTemp.GetLength() )
00254                         {
00255                                 pElement->m_sText = strTemp;
00256                                 strTemp = pXML->GetAttributeValue( _T("indent") );
00257                                 if ( strTemp.GetLength() ) pElement->m_sText += '.' + strTemp;
00258                         }
00259                         else
00260                         {
00261                                 strTemp = pXML->GetAttributeValue( _T("indent") );
00262                                 if ( strTemp.GetLength() ) pElement->m_sText = _T("0.") + strTemp;
00263                         }
00264                 }
00265                 else if ( pXML->IsNamed( _T("gap") ) )
00266                 {
00267                         pElement = new CRichElement( retGap );
00268                         
00269                         strTemp = pXML->GetAttributeValue( _T("size") );
00270                         if ( strTemp ) pElement->m_sText = strTemp;
00271                 }
00272                 else if ( pXML->IsNamed( _T("bitmap") ) )
00273                 {
00274                         pElement = new CRichElement( retBitmap );
00275                 }
00276                 else if ( pXML->IsNamed( _T("icon") ) )
00277                 {
00278                         pElement = new CRichElement( retIcon );
00279                 }
00280                 else if ( pXML->IsNamed( _T("anchor") ) )
00281                 {
00282                         pElement = new CRichElement( retAnchor );
00283                 }
00284                 else if ( pXML->IsNamed( _T("para") ) )
00285                 {
00286                         Add( pElement = new CRichElement( retAlign,
00287                                 pXML->GetAttributeValue( _T("align") ) ) );
00288                         
00289                         if ( pXML->GetElementCount() )
00290                         {
00291                                 if ( ! LoadXML( pXML, pMap, nGroup ) ) return FALSE;
00292                                 if ( pElement->m_sText.CompareNoCase( _T("left") ) )
00293                                 {
00294                                         Add( new CRichElement( retAlign, _T("left") ) );
00295                                 }
00296                         }
00297                         
00298                         continue;
00299                 }
00300                 else if ( pXML->IsNamed( _T("group") ) )
00301                 {
00302                         int nSubGroup = 0;
00303                         if ( _stscanf( pXML->GetAttributeValue( _T("id") ), _T("%i"), &nSubGroup ) != 1 )
00304                                 return FALSE;
00305                         if ( ! LoadXML( pXML, pMap, nSubGroup ) ) return FALSE;
00306                         continue;
00307                 }
00308                 else if ( pXML->IsNamed( _T("styles") ) )
00309                 {
00310                         if ( ! LoadXMLStyles( pXML ) ) return FALSE;
00311                 }
00312                 else
00313                 {
00314                         return FALSE;
00315                 }
00316                 
00317                 if ( pElement == NULL ) continue;
00318                 
00319                 strTemp = pXML->GetValue();
00320                 if ( strTemp.GetLength() ) pElement->m_sText = strTemp;
00321                 
00322                 pElement->m_nGroup = nGroup;
00323                 strTemp = pXML->GetAttributeValue( _T("group") );
00324                 if ( strTemp.GetLength() ) _stscanf( strTemp, _T("%i"), &pElement->m_nGroup );
00325                 
00326                 strTemp = pXML->GetAttributeValue( _T("format") );
00327                 CharLower( strTemp.GetBuffer() );
00328                 strTemp.ReleaseBuffer();
00329                 if ( strTemp.Find( 'b' ) >= 0 ) pElement->m_nFlags |= retfBold;
00330                 if ( strTemp.Find( 'i' ) >= 0 ) pElement->m_nFlags |= retfItalic;
00331                 if ( strTemp.Find( 'u' ) >= 0 ) pElement->m_nFlags |= retfUnderline;
00332                 
00333                 strTemp = pXML->GetAttributeValue( _T("align") );
00334                 CharLower( strTemp.GetBuffer() );
00335                 strTemp.ReleaseBuffer(); 
00336                 if ( strTemp == _T("middle") ) pElement->m_nFlags |= retfMiddle;
00337                 
00338                 strTemp = pXML->GetAttributeValue( _T("colour") );
00339                 if ( strTemp.GetLength() == 6 )
00340                 {
00341                         pElement->m_nFlags |= retfColour;
00342                         LoadXMLColour( pXML, _T("colour"), &pElement->m_cColour );
00343                 }
00344                 
00345                 if ( pElement->m_nType == retIcon )
00346                 {
00347                         strTemp = pXML->GetAttributeValue( _T("command") );
00348                         if ( strTemp.GetLength() )
00349                         {
00350                                 pElement->m_nType = retCmdIcon;
00351                                 pElement->m_sText = strTemp;
00352                         }
00353                 }
00354                 
00355                 if ( pElement->m_nType == retIcon || pElement->m_nType == retBitmap || pElement->m_nType == retAnchor )
00356                 {
00357                         strTemp = pXML->GetAttributeValue( _T("res") );
00358                         if ( strTemp.GetLength() ) pElement->m_sText = strTemp;
00359                         strTemp = pXML->GetAttributeValue( _T("path") );
00360                         if ( strTemp.GetLength() ) pElement->m_sText = strTemp;
00361                         
00362                         strTemp = pXML->GetAttributeValue( _T("width") );
00363                         if ( strTemp.GetLength() )
00364                         {
00365                                 if ( pElement->m_sText.GetLength() ) pElement->m_sText += '.';
00366                                 pElement->m_sText += strTemp;
00367                                 strTemp = pXML->GetAttributeValue( _T("height") );
00368                                 if ( strTemp.GetLength() ) pElement->m_sText += '.' + strTemp;
00369                         }
00370                 }
00371                 
00372                 pElement->m_sLink = pXML->GetAttributeValue( _T("target") );
00373                 
00374                 if ( pMap )
00375                 {
00376                         strTemp = pXML->GetAttributeValue( _T("id") );
00377                         if ( strTemp.GetLength() ) pMap->SetAt( strTemp, pElement );
00378                 }
00379                 
00380                 Add( pElement );
00381         }
00382         
00383         return TRUE;
00384 }
00385 
00386 BOOL CRichDocument::LoadXMLStyles(CXMLElement* pParent)
00387 {
00388         for ( POSITION pos = pParent->GetElementIterator() ; pos ; )
00389         {
00390                 CXMLElement* pXML = pParent->GetNextElement( pos );
00391                 if ( ! pXML->IsNamed( _T("style") ) ) continue;
00392                 
00393                 CString strName = pXML->GetAttributeValue( _T("name") );
00394                 CharLower( strName.GetBuffer() );
00395                 strName.ReleaseBuffer();
00396                 
00397                 CString strFontFace = theApp.m_sDefaultFont;
00398                 int nFontSize = theApp.m_nDefaultFontSize + 1;
00399                 int nFontWeight = FW_BOLD;
00400                 
00401                 if ( CXMLElement* pFont = pXML->GetElementByName( _T("font") ) )
00402                 {
00403                         strFontFace = pFont->GetAttributeValue( _T("face") );
00404                         CString strTemp = pFont->GetAttributeValue( _T("size") );
00405                         _stscanf( strTemp, _T("%i"), &nFontSize );
00406                         strTemp = pFont->GetAttributeValue( _T("weight") );
00407                         _stscanf( strTemp, _T("%i"), &nFontWeight );
00408                 }
00409                 
00410                 CXMLElement* pColours = pXML->GetElementByName( _T("colours") );
00411                 if ( pColours == NULL ) pColours = pXML;
00412                 
00413                 if ( strName == _T("default") || strName.IsEmpty() )
00414                 {
00415                         LoadXMLColour( pColours, _T("text"), &m_crText );
00416                         LoadXMLColour( pColours, _T("link"), &m_crLink );
00417                         LoadXMLColour( pColours, _T("hover"), &m_crHover );
00418                         CreateFonts( strFontFace, nFontSize );
00419                 }
00420                 else if ( strName == _T("heading") )
00421                 {
00422                         LoadXMLColour( pColours, _T("text"), &m_crHeading );
00423                         
00424                         if ( m_fntHeading.m_hObject ) m_fntHeading.DeleteObject();
00425                         m_fntHeading.CreateFont( -nFontSize, 0, 0, 0, nFontWeight, FALSE, FALSE, FALSE,
00426                                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
00427                                 DEFAULT_PITCH|FF_DONTCARE, strFontFace );
00428                 }
00429         }
00430         
00431         return TRUE;
00432 }
00433 
00434 BOOL CRichDocument::LoadXMLColour(CXMLElement* pXML, LPCTSTR pszName, COLORREF* pColour)
00435 {
00436         CString str = pXML->GetAttributeValue( pszName );
00437         if ( str.GetLength() != 6 ) return FALSE;
00438         
00439         int nRed, nGreen, nBlue;
00440         
00441         if ( _stscanf( str.Mid( 0, 2 ), _T("%x"), &nRed ) != 1 ) return FALSE;
00442         if ( _stscanf( str.Mid( 2, 2 ), _T("%x"), &nGreen ) != 1 ) return FALSE;
00443         if ( _stscanf( str.Mid( 4, 2 ), _T("%x"), &nBlue ) != 1 ) return FALSE;
00444         
00445         *pColour = RGB( nRed, nGreen, nBlue );
00446         
00447         return TRUE;
00448 }

Generated on Thu Dec 15 10:39:47 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2