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_xmloff.hxx" 30 #include "XMLIndexMarkExport.hxx" 31 #include <tools/debug.hxx> 32 #include <rtl/ustring.hxx> 33 #include <rtl/ustrbuf.hxx> 34 #include <com/sun/star/beans/XPropertySet.hpp> 35 #include <com/sun/star/beans/XPropertySetInfo.hpp> 36 #include <xmloff/xmltoken.hxx> 37 #include "xmloff/xmlnmspe.hxx" 38 #include <xmloff/xmlexp.hxx> 39 #include <xmloff/xmluconv.hxx> 40 41 42 using namespace ::xmloff::token; 43 44 using ::rtl::OUString; 45 using ::rtl::OUStringBuffer; 46 using ::com::sun::star::beans::XPropertySet; 47 using ::com::sun::star::beans::XPropertySetInfo; 48 using ::com::sun::star::uno::Reference; 49 using ::com::sun::star::uno::Any; 50 51 52 53 XMLIndexMarkExport::XMLIndexMarkExport( 54 SvXMLExport& rExp, 55 XMLTextParagraphExport& rParaExp) 56 : sLevel(RTL_CONSTASCII_USTRINGPARAM("Level")) 57 , sUserIndexName(RTL_CONSTASCII_USTRINGPARAM("UserIndexName")) 58 , sPrimaryKey(RTL_CONSTASCII_USTRINGPARAM("PrimaryKey")) 59 , sSecondaryKey(RTL_CONSTASCII_USTRINGPARAM("SecondaryKey")) 60 , sDocumentIndexMark(RTL_CONSTASCII_USTRINGPARAM("DocumentIndexMark")) 61 , sIsStart(RTL_CONSTASCII_USTRINGPARAM("IsStart")) 62 , sIsCollapsed(RTL_CONSTASCII_USTRINGPARAM("IsCollapsed")) 63 , sAlternativeText(RTL_CONSTASCII_USTRINGPARAM("AlternativeText")) 64 , sTextReading(RTL_CONSTASCII_USTRINGPARAM("TextReading")) 65 , sPrimaryKeyReading(RTL_CONSTASCII_USTRINGPARAM("PrimaryKeyReading")) 66 , sSecondaryKeyReading(RTL_CONSTASCII_USTRINGPARAM("SecondaryKeyReading")) 67 , sMainEntry(RTL_CONSTASCII_USTRINGPARAM("IsMainEntry")) 68 , rExport(rExp) 69 , rParaExport(rParaExp) 70 { 71 } 72 73 const enum XMLTokenEnum lcl_pTocMarkNames[] = 74 { XML_TOC_MARK, XML_TOC_MARK_START, XML_TOC_MARK_END }; 75 const enum XMLTokenEnum lcl_pUserIndexMarkName[] = 76 { XML_USER_INDEX_MARK, 77 XML_USER_INDEX_MARK_START, XML_USER_INDEX_MARK_END }; 78 const enum XMLTokenEnum lcl_pAlphaIndexMarkName[] = 79 { XML_ALPHABETICAL_INDEX_MARK, 80 XML_ALPHABETICAL_INDEX_MARK_START, 81 XML_ALPHABETICAL_INDEX_MARK_END }; 82 83 84 XMLIndexMarkExport::~XMLIndexMarkExport() 85 { 86 } 87 88 void XMLIndexMarkExport::ExportIndexMark( 89 const Reference<XPropertySet> & rPropSet, 90 sal_Bool bAutoStyles) 91 { 92 /// index marks have no styles! 93 if (!bAutoStyles) 94 { 95 const enum XMLTokenEnum * pElements = NULL; 96 sal_Int8 nElementNo = -1; 97 98 // get index mark 99 Any aAny; 100 aAny = rPropSet->getPropertyValue(sDocumentIndexMark); 101 Reference<XPropertySet> xIndexMarkPropSet; 102 aAny >>= xIndexMarkPropSet; 103 104 // common: handling of start, end, collapsed entries and 105 // alternative text 106 107 // collapsed/alternative text entry? 108 aAny = rPropSet->getPropertyValue(sIsCollapsed); 109 if (*(sal_Bool *)aAny.getValue()) 110 { 111 // collapsed entry: needs alternative text 112 nElementNo = 0; 113 114 aAny = xIndexMarkPropSet->getPropertyValue(sAlternativeText); 115 OUString sTmp; 116 aAny >>= sTmp; 117 DBG_ASSERT(sTmp.getLength() > 0, 118 "collapsed index mark without alternative text"); 119 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STRING_VALUE, sTmp); 120 } 121 else 122 { 123 // start and end entries: has ID 124 aAny = rPropSet->getPropertyValue(sIsStart); 125 nElementNo = *(sal_Bool *)aAny.getValue() ? 1 : 2; 126 127 // generate ID 128 OUStringBuffer sBuf; 129 GetID(sBuf, xIndexMarkPropSet); 130 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_ID, 131 sBuf.makeStringAndClear()); 132 } 133 134 // distinguish between TOC, user, alphab. index marks by 135 // asking for specific properties 136 // Export attributes for -mark-start and -mark elements, 137 // but not for -mark-end 138 Reference<XPropertySetInfo> xPropertySetInfo = 139 xIndexMarkPropSet->getPropertySetInfo(); 140 if (xPropertySetInfo->hasPropertyByName(sUserIndexName)) 141 { 142 // user index mark 143 pElements = lcl_pUserIndexMarkName; 144 if (nElementNo != 2) 145 { 146 ExportUserIndexMarkAttributes(xIndexMarkPropSet); 147 } 148 } 149 else if (xPropertySetInfo->hasPropertyByName(sPrimaryKey)) 150 { 151 // alphabetical index mark 152 pElements = lcl_pAlphaIndexMarkName; 153 if (nElementNo != 2) 154 { 155 ExportAlphabeticalIndexMarkAttributes(xIndexMarkPropSet); 156 } 157 } 158 else 159 { 160 // table of content: 161 pElements = lcl_pTocMarkNames; 162 if (nElementNo != 2) 163 { 164 ExportTOCMarkAttributes(xIndexMarkPropSet); 165 } 166 } 167 168 // export element 169 DBG_ASSERT(pElements != NULL, "illegal element array"); 170 DBG_ASSERT(nElementNo >= 0, "illegal name array index"); 171 DBG_ASSERT(nElementNo <= 2, "illegal name array index"); 172 173 if ((pElements != NULL) && (nElementNo != -1)) 174 { 175 SvXMLElementExport aElem(rExport, 176 XML_NAMESPACE_TEXT, 177 pElements[nElementNo], 178 sal_False, sal_False); 179 } 180 } 181 } 182 183 void XMLIndexMarkExport::ExportTOCMarkAttributes( 184 const Reference<XPropertySet> & rPropSet) 185 { 186 // outline level 187 sal_Int16 nLevel = 0; 188 Any aAny = rPropSet->getPropertyValue(sLevel); 189 aAny >>= nLevel; 190 OUStringBuffer sBuf; 191 SvXMLUnitConverter::convertNumber(sBuf, (sal_Int32)nLevel + 1); 192 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_OUTLINE_LEVEL, 193 sBuf.makeStringAndClear()); 194 } 195 196 void lcl_ExportPropertyString( SvXMLExport& rExport, 197 const Reference<XPropertySet> & rPropSet, 198 const OUString sProperty, 199 XMLTokenEnum eToken, 200 Any& rAny ) 201 { 202 rAny = rPropSet->getPropertyValue( sProperty ); 203 204 OUString sValue; 205 if( rAny >>= sValue ) 206 { 207 if( sValue.getLength() > 0 ) 208 { 209 rExport.AddAttribute( XML_NAMESPACE_TEXT, eToken, sValue ); 210 } 211 } 212 } 213 214 void lcl_ExportPropertyBool( SvXMLExport& rExport, 215 const Reference<XPropertySet> & rPropSet, 216 const OUString sProperty, 217 XMLTokenEnum eToken, 218 Any& rAny ) 219 { 220 rAny = rPropSet->getPropertyValue( sProperty ); 221 222 sal_Bool bValue = sal_Bool(); 223 if( rAny >>= bValue ) 224 { 225 if( bValue ) 226 { 227 rExport.AddAttribute( XML_NAMESPACE_TEXT, eToken, XML_TRUE ); 228 } 229 } 230 } 231 232 void XMLIndexMarkExport::ExportUserIndexMarkAttributes( 233 const Reference<XPropertySet> & rPropSet) 234 { 235 // name of user index 236 // (unless it's the default index; then it has no name) 237 Any aAny; 238 lcl_ExportPropertyString( rExport, rPropSet, sUserIndexName, XML_INDEX_NAME, aAny ); 239 240 // additionally export outline level; just reuse ExportTOCMarkAttributes 241 ExportTOCMarkAttributes( rPropSet ); 242 } 243 244 void XMLIndexMarkExport::ExportAlphabeticalIndexMarkAttributes( 245 const Reference<XPropertySet> & rPropSet) 246 { 247 // primary and secondary keys (if available) 248 Any aAny; 249 lcl_ExportPropertyString( rExport, rPropSet, sTextReading, XML_STRING_VALUE_PHONETIC, aAny ); 250 lcl_ExportPropertyString( rExport, rPropSet, sPrimaryKey, XML_KEY1, aAny ); 251 lcl_ExportPropertyString( rExport, rPropSet, sPrimaryKeyReading, XML_KEY1_PHONETIC, aAny ); 252 lcl_ExportPropertyString( rExport, rPropSet, sSecondaryKey, XML_KEY2, aAny ); 253 lcl_ExportPropertyString( rExport, rPropSet, sSecondaryKeyReading, XML_KEY2_PHONETIC, aAny ); 254 lcl_ExportPropertyBool( rExport, rPropSet, sMainEntry, XML_MAIN_ENTRY, aAny ); 255 } 256 257 void XMLIndexMarkExport::GetID( 258 OUStringBuffer& sBuf, 259 const Reference<XPropertySet> & rPropSet) 260 { 261 static const sal_Char sPrefix[] = "IMark"; 262 263 // HACK: use address of object to form identifier 264 sal_Int64 nId = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(rPropSet.get())); 265 sBuf.appendAscii(sPrefix, sizeof(sPrefix)-1); 266 sBuf.append(nId); 267 } 268