1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_shell.hxx" 30 #include "internal/contentreader.hxx" 31 #include "dummytag.hxx" 32 #include "simpletag.hxx" 33 #include "autostyletag.hxx" 34 35 #include "assert.h" 36 37 /** constructor. 38 */ 39 CContentReader::CContentReader( const std::string& DocumentName, LocaleSet_t const & DocumentLocale ): 40 CBaseReader( DocumentName ) 41 { 42 try 43 { 44 m_DefaultLocale = DocumentLocale; 45 Initialize( DOC_CONTENT_NAME ); 46 } 47 catch(xml_parser_exception& 48 #if OSL_DEBUG_LEVEL > 0 49 ex 50 #endif 51 ) 52 { 53 ENSURE(false, ex.what()); 54 } 55 catch(...) 56 { 57 ENSURE(false, "Unknown error"); 58 } 59 } 60 61 CContentReader::CContentReader( void* stream, LocaleSet_t const & DocumentLocale, zlib_filefunc_def* fa ) : 62 CBaseReader( stream, fa ) 63 { 64 try 65 { 66 m_DefaultLocale = DocumentLocale; 67 Initialize( DOC_CONTENT_NAME ); 68 } 69 catch(xml_parser_exception& 70 #if OSL_DEBUG_LEVEL > 0 71 ex 72 #endif 73 ) 74 { 75 ENSURE(false, ex.what()); 76 } 77 catch(...) 78 { 79 ENSURE(false, "Unknown error"); 80 } 81 } 82 83 84 /** destructor. 85 */ 86 87 CContentReader::~CContentReader( void ) 88 { 89 } 90 91 /*********************** helper functions ***********************/ 92 93 /** choose an appropriate tag reader 94 */ 95 96 ITag* CContentReader::chooseTagReader( const std::wstring& tag_name, const XmlTagAttributes_t& XmlAttributes ) 97 { 98 if (( tag_name == CONTENT_TEXT_A )||( tag_name == CONTENT_TEXT_P )|| 99 ( tag_name == CONTENT_TEXT_SPAN ) ||( tag_name == CONTENT_TEXT_H )|| 100 ( tag_name == CONTENT_TEXT_SEQUENCE ) ||( tag_name == CONTENT_TEXT_BOOKMARK_REF )|| 101 ( tag_name == CONTENT_TEXT_INDEX_TITLE_TEMPLATE ) ) 102 return new CSimpleTag(XmlAttributes); 103 else if ( tag_name == CONTENT_STYLE_STYLE ) 104 { 105 // if style:style | style:name is exist,, fill the style field, otherwise do nothing; 106 if ( XmlAttributes.find(CONTENT_STYLE_STYLE_NAME) != XmlAttributes.end()) 107 return new CAutoStyleTag(XmlAttributes); 108 else 109 return new CDummyTag(); 110 } 111 else if ( ( tag_name == CONTENT_STYLE_PROPERTIES ) || ( tag_name == CONTENT_TEXT_STYLE_PROPERTIES ) ) 112 { 113 assert( !m_TagBuilderStack.empty() ); 114 115 //here we presume that if CONTENT_STYLE_PROPERTIES tag is present, it just follow CONTENT_STYLE_STYLE; 116 ITag* pTagBuilder = m_TagBuilderStack.top(); 117 pTagBuilder->addAttributes( XmlAttributes ); 118 119 return new CDummyTag(); 120 } 121 else 122 return new CDummyTag(); 123 } 124 125 /** get style of the current content. 126 */ 127 ::std::wstring CContentReader::getCurrentContentStyle( void ) 128 { 129 assert( !m_TagBuilderStack.empty() ); 130 ITag* pTagBuilder = m_TagBuilderStack.top(); 131 132 return ( pTagBuilder->getTagAttribute(CONTENT_TEXT_STYLENAME) ); 133 } 134 135 /** add chunk into Chunk Buffer. 136 */ 137 void CContentReader::addChunk( LocaleSet_t const & Locale, Content_t const & Content ) 138 { 139 if ( Content == EMPTY_STRING ) 140 return; 141 142 if ( ( ( m_ChunkBuffer.empty() ) || ( m_ChunkBuffer.back().first != Locale ) ) && 143 ( ( Content != SPACE ) && ( Content != LF ) ) ) 144 { 145 // if met a new locale, add a blank new chunk; 146 Chunk_t Chunk; 147 Chunk.first = Locale; 148 Chunk.second = EMPTY_STRING; 149 m_ChunkBuffer.push_back( Chunk ); 150 } 151 152 if ( !m_ChunkBuffer.empty() ) 153 m_ChunkBuffer.back().second += Content; 154 } 155 156 /** get a style's locale field. 157 */ 158 159 LocaleSet_t const & CContentReader::getLocale( const StyleName_t Style ) 160 { 161 if ( m_StyleMap.empty() ) 162 return m_DefaultLocale; 163 164 StyleLocaleMap_t :: const_iterator style_Iter; 165 166 if ( ( style_Iter = m_StyleMap.find( Style ) ) == m_StyleMap.end( ) ) 167 return m_DefaultLocale; 168 else 169 return style_Iter->second; 170 171 } 172 173 /*********************** event handler functions ***********************/ 174 175 //------------------------------ 176 // start_element occurs when a tag is start 177 //------------------------------ 178 179 void CContentReader::start_element( 180 const std::wstring& /*raw_name*/, 181 const std::wstring& local_name, 182 const XmlTagAttributes_t& attributes) 183 { 184 //get appropriate Xml Tag Builder using MetaInfoBuilderFactory; 185 ITag* pTagBuilder = chooseTagReader( local_name,attributes ); 186 assert( pTagBuilder != NULL ); 187 pTagBuilder->startTag( ); 188 m_TagBuilderStack.push( pTagBuilder ); 189 190 } 191 192 //------------------------------ 193 // end_element occurs when a tag is closed 194 //------------------------------ 195 196 void CContentReader::end_element(const std::wstring& /*raw_name*/, const std::wstring& local_name) 197 { 198 assert( !m_TagBuilderStack.empty() ); 199 ITag* pTagBuilder = m_TagBuilderStack.top(); 200 201 if ( local_name == CONTENT_STYLE_STYLE ) 202 { 203 StyleLocalePair_t StyleLocalePair = static_cast<CAutoStyleTag * >( pTagBuilder)->getStyleLocalePair(); 204 if ( ( static_cast<CAutoStyleTag * >( pTagBuilder)->isFull() ) && ( StyleLocalePair.second != m_DefaultLocale ) ) 205 m_StyleMap.insert( StyleLocalePair ); 206 } 207 if (( local_name == CONTENT_TEXT_A )||( local_name == CONTENT_TEXT_SPAN ) || 208 ( local_name == CONTENT_TEXT_SEQUENCE )||( local_name == CONTENT_TEXT_BOOKMARK_REF )) 209 addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( SPACE ) ); 210 if ((( local_name == CONTENT_TEXT_P )||( local_name == CONTENT_TEXT_H ) || 211 ( local_name == CONTENT_TEXT_INDEX_TITLE_TEMPLATE ) )&& 212 ( EMPTY_STRING != pTagBuilder->getTagContent( ) ) ) 213 addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( LF ) ); 214 215 m_TagBuilderStack.pop(); 216 pTagBuilder->endTag(); 217 delete pTagBuilder; 218 219 } 220 221 //------------------------------ 222 // characters occurs when receiving characters 223 //------------------------------ 224 225 void CContentReader::characters( const std::wstring& character ) 226 { 227 if ( character.length() > 0 && !HasOnlySpaces( character ) ) 228 { 229 addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( character ) ); 230 231 ITag* pTagBuilder = m_TagBuilderStack.top(); 232 pTagBuilder->addCharacters( character ); 233 } 234 } 235 236