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 31 #ifndef _XMLOFF_TXTPARAE_HXX 32 #include <xmloff/txtparae.hxx> 33 #endif 34 #include <tools/debug.hxx> 35 #include <rtl/ustring.hxx> 36 #include <rtl/ustrbuf.hxx> 37 38 #include <vector> 39 40 41 #include <com/sun/star/lang/XServiceInfo.hpp> 42 #include <com/sun/star/container/XIndexReplace.hpp> 43 44 #include <com/sun/star/beans/XPropertySet.hpp> 45 #include <com/sun/star/beans/PropertyValue.hpp> 46 #include <com/sun/star/beans/PropertyValues.hpp> 47 #include <com/sun/star/beans/PropertyState.hpp> 48 #include <com/sun/star/text/XText.hpp> 49 #include <com/sun/star/text/XTextSection.hpp> 50 #include <com/sun/star/text/SectionFileLink.hpp> 51 #include <com/sun/star/container/XNamed.hpp> 52 #include <com/sun/star/text/XDocumentIndex.hpp> 53 #include "xmloff/xmlnmspe.hxx" 54 #include <xmloff/families.hxx> 55 #include <xmloff/xmluconv.hxx> 56 #include <xmloff/nmspmap.hxx> 57 #include <xmloff/xmlexp.hxx> 58 #include <xmloff/xmltkmap.hxx> 59 #include "XMLTextNumRuleInfo.hxx" 60 #include "XMLSectionExport.hxx" 61 #include "XMLRedlineExport.hxx" 62 #ifndef _XMLOFF_MULTIPROPERTYSETHELPER_HXX 63 #include "MultiPropertySetHelper.hxx" 64 #endif 65 66 using namespace ::com::sun::star; 67 using namespace ::com::sun::star::text; 68 using namespace ::com::sun::star::uno; 69 using namespace ::std; 70 71 using ::rtl::OUString; 72 using ::rtl::OUStringBuffer; 73 using ::com::sun::star::beans::XPropertySet; 74 using ::com::sun::star::beans::PropertyValue; 75 using ::com::sun::star::beans::PropertyValues; 76 using ::com::sun::star::beans::PropertyState; 77 using ::com::sun::star::container::XIndexReplace; 78 using ::com::sun::star::container::XNamed; 79 using ::com::sun::star::lang::XServiceInfo; 80 81 Reference<XText> lcl_findXText(const Reference<XTextSection>& rSect) 82 { 83 Reference<XText> xText; 84 85 Reference<XTextContent> xTextContent(rSect, UNO_QUERY); 86 if (xTextContent.is()) 87 { 88 xText.set(xTextContent->getAnchor()->getText()); 89 } 90 91 return xText; 92 } 93 94 void XMLTextParagraphExport::exportListAndSectionChange( 95 Reference<XTextSection> & rPrevSection, 96 const Reference<XTextContent> & rNextSectionContent, 97 const XMLTextNumRuleInfo& rPrevRule, 98 const XMLTextNumRuleInfo& rNextRule, 99 sal_Bool bAutoStyles) 100 { 101 Reference<XTextSection> xNextSection; 102 103 // first: get current XTextSection 104 Reference<XPropertySet> xPropSet(rNextSectionContent, UNO_QUERY); 105 if (xPropSet.is()) 106 { 107 if (xPropSet->getPropertySetInfo()->hasPropertyByName(sTextSection)) 108 { 109 xPropSet->getPropertyValue(sTextSection) >>= xNextSection; 110 } 111 // else: no current section 112 } 113 114 exportListAndSectionChange(rPrevSection, xNextSection, 115 rPrevRule, rNextRule, bAutoStyles); 116 } 117 118 void XMLTextParagraphExport::exportListAndSectionChange( 119 Reference<XTextSection> & rPrevSection, 120 MultiPropertySetHelper& rPropSetHelper, 121 sal_Int16 nTextSectionId, 122 const Reference<XTextContent> & rNextSectionContent, 123 const XMLTextNumRuleInfo& rPrevRule, 124 const XMLTextNumRuleInfo& rNextRule, 125 sal_Bool bAutoStyles) 126 { 127 Reference<XTextSection> xNextSection; 128 129 // first: get current XTextSection 130 Reference<XPropertySet> xPropSet(rNextSectionContent, UNO_QUERY); 131 if (xPropSet.is()) 132 { 133 if( !rPropSetHelper.checkedProperties() ) 134 rPropSetHelper.hasProperties( xPropSet->getPropertySetInfo() ); 135 if( rPropSetHelper.hasProperty( nTextSectionId )) 136 { 137 xNextSection.set(rPropSetHelper.getValue( nTextSectionId , xPropSet, 138 sal_True ), uno::UNO_QUERY); 139 } 140 // else: no current section 141 } 142 143 exportListAndSectionChange(rPrevSection, xNextSection, 144 rPrevRule, rNextRule, bAutoStyles); 145 } 146 147 void XMLTextParagraphExport::exportListAndSectionChange( 148 Reference<XTextSection> & rPrevSection, 149 const Reference<XTextSection> & rNextSection, 150 const XMLTextNumRuleInfo& rPrevRule, 151 const XMLTextNumRuleInfo& rNextRule, 152 sal_Bool bAutoStyles) 153 { 154 // old != new? -> maybe we have to start or end a new section 155 if (rPrevSection != rNextSection) 156 { 157 // a new section started, or an old one gets closed! 158 159 // close old list 160 XMLTextNumRuleInfo aEmptyNumRuleInfo; 161 if ( !bAutoStyles ) 162 exportListChange(rPrevRule, aEmptyNumRuleInfo); 163 164 // Build stacks of old and new sections 165 // Sections on top of mute sections should not be on the stack 166 vector< Reference<XTextSection> > aOldStack; 167 Reference<XTextSection> aCurrent(rPrevSection); 168 while(aCurrent.is()) 169 { 170 // if we have a mute section, ignore all its children 171 // (all previous ones) 172 if (pSectionExport->IsMuteSection(aCurrent)) 173 aOldStack.clear(); 174 175 aOldStack.push_back(aCurrent); 176 aCurrent.set(aCurrent->getParentSection()); 177 } 178 179 vector< Reference<XTextSection> > aNewStack; 180 aCurrent.set(rNextSection); 181 sal_Bool bMute = sal_False; 182 while(aCurrent.is()) 183 { 184 // if we have a mute section, ignore all its children 185 // (all previous ones) 186 if (pSectionExport->IsMuteSection(aCurrent)) 187 { 188 aNewStack.clear(); 189 bMute = sal_True; 190 } 191 192 aNewStack.push_back(aCurrent); 193 aCurrent.set(aCurrent->getParentSection()); 194 } 195 196 // compare the two stacks 197 vector<Reference<XTextSection> > ::reverse_iterator aOld = 198 aOldStack.rbegin(); 199 vector<Reference<XTextSection> > ::reverse_iterator aNew = 200 aNewStack.rbegin(); 201 // compare bottom sections and skip equal section 202 while ( (aOld != aOldStack.rend()) && 203 (aNew != aNewStack.rend()) && 204 (*aOld) == (*aNew) ) 205 { 206 ++aOld; 207 ++aNew; 208 } 209 210 // close all elements of aOld ... 211 // (order: newest to oldest) 212 if (aOld != aOldStack.rend()) 213 { 214 vector<Reference<XTextSection> > ::iterator aOldForward( 215 aOldStack.begin()); 216 while ((aOldForward != aOldStack.end()) && 217 (*aOldForward != *aOld)) 218 { 219 if ( !bAutoStyles && (NULL != pRedlineExport) ) 220 pRedlineExport->ExportStartOrEndRedline(*aOldForward, 221 sal_False); 222 pSectionExport->ExportSectionEnd(*aOldForward, bAutoStyles); 223 ++aOldForward; 224 } 225 if (aOldForward != aOldStack.end()) 226 { 227 if ( !bAutoStyles && (NULL != pRedlineExport) ) 228 pRedlineExport->ExportStartOrEndRedline(*aOldForward, 229 sal_False); 230 pSectionExport->ExportSectionEnd(*aOldForward, bAutoStyles); 231 } 232 } 233 234 // ...then open all of aNew 235 // (order: oldest to newest) 236 while (aNew != aNewStack.rend()) 237 { 238 if ( !bAutoStyles && (NULL != pRedlineExport) ) 239 pRedlineExport->ExportStartOrEndRedline(*aNew, sal_True); 240 pSectionExport->ExportSectionStart(*aNew, bAutoStyles); 241 ++aNew; 242 } 243 244 // start new list 245 if ( !bAutoStyles && !bMute ) 246 exportListChange(aEmptyNumRuleInfo, rNextRule); 247 } 248 else 249 { 250 // list change, if sections have not changed 251 if ( !bAutoStyles ) 252 exportListChange(rPrevRule, rNextRule); 253 } 254 255 // save old section (old numRule gets saved in calling method) 256 rPrevSection.set(rNextSection); 257 } 258 259