1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "layoutparse.hxx" 25 26 #define STRING( str ) String( str, RTL_TEXTENCODING_UTF8 ) 27 #define BSTRING( str ) ByteString( str, RTL_TEXTENCODING_UTF8 ) 28 29 LayoutXMLFile::LayoutXMLFile( bool mergeMode ) 30 : XMLFile() 31 , mMergeMode( mergeMode ) 32 { 33 } 34 35 void 36 LayoutXMLFile::SearchL10NElements( XMLParentNode* pCur, int ) 37 { 38 if ( !pCur ) 39 pCur = this; 40 41 /* Recurse int children, SearchL10NElements does not do that for us. */ 42 if ( XMLChildNodeList* lst = pCur->GetChildList() ) 43 for ( sal_uLong i = 0; i < lst->Count(); i++ ) 44 if ( lst->GetObject( i )->GetNodeType() == XML_NODE_TYPE_ELEMENT ) 45 HandleElement( ( XMLElement* )lst->GetObject( i ) ); 46 else if ( lst->GetObject( i )->GetNodeType() == XML_NODE_TYPE_COMMENT ) 47 lst->Remove( i-- ); 48 } 49 50 std::vector<XMLAttribute*> 51 interestingAttributes( XMLAttributeList* lst ) 52 { 53 std::vector<XMLAttribute*> interesting; 54 if ( lst ) 55 for ( sal_uLong i = 0; i < lst->Count(); i++ ) 56 if ( lst->GetObject( i )->Equals( STRING( "id" ) ) ) 57 interesting.insert( interesting.begin(), lst->GetObject( i ) ); 58 else if ( ! BSTRING( *lst->GetObject( i ) ).CompareTo( "_", 1 ) ) 59 interesting.push_back( lst->GetObject( i ) ); 60 return interesting; 61 } 62 63 void 64 LayoutXMLFile::HandleElement( XMLElement* element ) 65 { 66 std::vector<XMLAttribute*> interesting = interestingAttributes( element->GetAttributeList() ); 67 68 if ( interesting.size() ) 69 { 70 std::vector<XMLAttribute*>::iterator i = interesting.begin(); 71 72 ByteString id = BSTRING( (*i++)->GetValue() ); 73 74 if ( mMergeMode ) 75 InsertL10NElement( id, element ); 76 else 77 for ( ; i != interesting.end(); ++i ) 78 { 79 ByteString attributeId = id; 80 ByteString value = BSTRING( ( *i )->GetValue() ); 81 XMLElement *e = new XMLElement( *element ); 82 e->RemoveAndDeleteAllChilds(); 83 /* Copy translatable text to CONTENT. */ 84 //new XMLData( STRING( ( *i )->GetValue() ), e, true ); 85 new XMLData( STRING( value ), e, true ); 86 attributeId += BSTRING ( **i ); 87 InsertL10NElement( attributeId, e ); 88 } 89 } 90 91 SearchL10NElements( (XMLParentNode*) element ); 92 } 93 94 void LayoutXMLFile::InsertL10NElement( ByteString const& id, XMLElement* element ) 95 { 96 ByteString const language = "en-US"; 97 LangHashMap* languageMap = 0; 98 XMLHashMap::iterator pos = XMLStrings->find( id ); 99 if ( pos != XMLStrings->end() ) 100 { 101 languageMap = pos->second; 102 fprintf( stderr, "error:%s:duplicate translation found, id=%s\n", 103 id.GetBuffer(), BSTRING( sFileName ).GetBuffer() ); 104 exit( 1 ); 105 } 106 else 107 { 108 languageMap = new LangHashMap(); 109 XMLStrings->insert( XMLHashMap::value_type( id , languageMap ) ); 110 order.push_back( id ); 111 } 112 (*languageMap)[ language ] = element; 113 } 114 115 sal_Bool LayoutXMLFile::Write( ByteString &aFilename ) 116 { 117 118 if ( aFilename.Len() ) 119 { 120 ofstream aFStream( aFilename.GetBuffer() , ios::out | ios::trunc ); 121 if ( !aFStream ) 122 fprintf( stderr, "ERROR: cannot open file:%s\n", aFilename.GetBuffer() ); 123 else 124 { 125 XMLFile::Write( aFStream ); 126 aFStream.close(); 127 return true; 128 } 129 } 130 return false; 131 } 132