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 #include <tools/debug.hxx> 32 #include <com/sun/star/beans/XPropertySet.hpp> 33 #include <com/sun/star/beans/PropertyValue.hpp> 34 #include <com/sun/star/container/XIndexReplace.hpp> 35 #include <com/sun/star/style/NumberingType.hpp> 36 #include <com/sun/star/container/XNamed.hpp> 37 #include "XMLTextNumRuleInfo.hxx" 38 // --> OD 2008-04-25 #refactorlists# 39 #include "xmloff/XMLTextListAutoStylePool.hxx" 40 // <-- 41 42 using ::rtl::OUString; 43 44 using namespace ::com::sun::star::uno; 45 using namespace ::com::sun::star::beans; 46 using namespace ::com::sun::star::container; 47 using namespace ::com::sun::star::style; 48 49 // --> OD 2008-05-08 #refactorlists# 50 // Complete refactoring of the class and enhancement of the class for lists. 51 XMLTextNumRuleInfo::XMLTextNumRuleInfo() 52 : msNumberingRules(RTL_CONSTASCII_USTRINGPARAM("NumberingRules")) 53 , msNumberingLevel(RTL_CONSTASCII_USTRINGPARAM("NumberingLevel")) 54 , msNumberingStartValue(RTL_CONSTASCII_USTRINGPARAM("NumberingStartValue")) 55 , msParaIsNumberingRestart(RTL_CONSTASCII_USTRINGPARAM("ParaIsNumberingRestart")) 56 , msNumberingIsNumber(RTL_CONSTASCII_USTRINGPARAM("NumberingIsNumber")) 57 , msNumberingIsOutline(RTL_CONSTASCII_USTRINGPARAM("NumberingIsOutline")) 58 , msPropNameListId(RTL_CONSTASCII_USTRINGPARAM("ListId")) 59 , msPropNameStartWith(RTL_CONSTASCII_USTRINGPARAM("StartWith")) 60 // --> OD 2008-11-26 #158694# 61 , msContinueingPreviousSubTree(RTL_CONSTASCII_USTRINGPARAM("ContinueingPreviousSubTree")) 62 , msListLabelStringProp(RTL_CONSTASCII_USTRINGPARAM("ListLabelString")) 63 // <-- 64 , mxNumRules() 65 , msNumRulesName() 66 , msListId() 67 , mnListStartValue( -1 ) 68 , mnListLevel( 0 ) 69 , mbIsNumbered( sal_False ) 70 , mbIsRestart( sal_False ) 71 , mnListLevelStartValue( -1 ) 72 , mbOutlineStyleAsNormalListStyle( sal_False ) 73 { 74 Reset(); 75 } 76 77 // --> OD 2006-09-27 #i69627# 78 void XMLTextNumRuleInfo::Set( 79 const ::com::sun::star::uno::Reference < 80 ::com::sun::star::text::XTextContent > & xTextContent, 81 const sal_Bool bOutlineStyleAsNormalListStyle, 82 const XMLTextListAutoStylePool& rListAutoPool, 83 // --> OD 2008-11-26 #158694# 84 const sal_Bool bExportTextNumberElement ) 85 // <-- 86 { 87 Reset(); 88 // --> OD 2006-09-27 #i69627# 89 mbOutlineStyleAsNormalListStyle = bOutlineStyleAsNormalListStyle; 90 // <-- 91 92 Reference< XPropertySet > xPropSet( xTextContent, UNO_QUERY ); 93 Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); 94 95 // check if this paragraph supports a numbering 96 if( !xPropSetInfo->hasPropertyByName( msNumberingLevel ) ) 97 return; 98 99 if( xPropSet->getPropertyValue( msNumberingLevel ) >>= mnListLevel ) 100 { 101 if( xPropSetInfo->hasPropertyByName( msNumberingRules ) ) 102 { 103 xPropSet->getPropertyValue( msNumberingRules ) >>= mxNumRules; 104 } 105 } 106 else 107 { 108 // in applications using the outliner we always have a numbering rule, 109 // so a void property no numbering 110 mnListLevel = 0; 111 } 112 113 // --> OD 2008-12-17 #i97312# 114 if ( mxNumRules.is() && mxNumRules->getCount() < 1 ) 115 { 116 DBG_ASSERT( false, 117 "<XMLTextNumRuleInfo::Set(..)> - numbering rules instance does not contain any numbering rule" ); 118 Reset(); 119 return; 120 } 121 // <-- 122 123 // --> OD 2010-01-13 #b6912256# 124 if ( mnListLevel < 0 ) 125 { 126 DBG_ASSERT( false, 127 "<XMLTextNumRuleInfo::Set(..)> - unexpected numbering level" ); 128 Reset(); 129 return; 130 } 131 132 // --> OD 2006-09-27 #i69627# 133 bool bSuppressListStyle( false ); 134 if ( mxNumRules.is() ) 135 { 136 if ( !mbOutlineStyleAsNormalListStyle ) 137 { 138 sal_Bool bIsOutline = sal_False; 139 Reference<XPropertySet> xNumRulesProps(mxNumRules, UNO_QUERY); 140 if ( xNumRulesProps.is() && 141 xNumRulesProps->getPropertySetInfo()-> 142 hasPropertyByName( msNumberingIsOutline ) ) 143 { 144 xNumRulesProps->getPropertyValue( msNumberingIsOutline ) >>= bIsOutline; 145 bSuppressListStyle = bIsOutline ? true : false; 146 } 147 } 148 } 149 150 if( mxNumRules.is() && !bSuppressListStyle ) 151 // <-- 152 { 153 // First try to find the numbering rules in the list auto style pool. 154 // If not found, the numbering rules instance has to be named. 155 msNumRulesName = rListAutoPool.Find( mxNumRules ); 156 if ( msNumRulesName.getLength() == 0 ) 157 { 158 Reference < XNamed > xNamed( mxNumRules, UNO_QUERY ); 159 DBG_ASSERT( xNamed.is(), 160 "<XMLTextNumRuleInfo::Set(..)> - numbering rules instance have to be named. Serious defect -> please inform OD." ); 161 if( xNamed.is() ) 162 { 163 msNumRulesName = xNamed->getName(); 164 } 165 } 166 DBG_ASSERT( msNumRulesName.getLength() > 0, 167 "<XMLTextNumRuleInfo::Set(..)> - no name found for numbering rules instance. Serious defect -> please inform OD." ); 168 169 if( xPropSetInfo->hasPropertyByName( msPropNameListId ) ) 170 { 171 xPropSet->getPropertyValue( msPropNameListId ) >>= msListId; 172 } 173 174 // --> OD 2008-11-26 #158694# 175 mbContinueingPreviousSubTree = sal_False; 176 if( xPropSetInfo->hasPropertyByName( msContinueingPreviousSubTree ) ) 177 { 178 xPropSet->getPropertyValue( msContinueingPreviousSubTree ) >>= mbContinueingPreviousSubTree; 179 } 180 // <-- 181 182 mbIsNumbered = sal_True; 183 if( xPropSetInfo->hasPropertyByName( msNumberingIsNumber ) ) 184 { 185 if( !(xPropSet->getPropertyValue( msNumberingIsNumber ) >>= mbIsNumbered ) ) 186 { 187 OSL_ENSURE( false, "numbered paragraph without number info" ); 188 mbIsNumbered = sal_False; 189 } 190 } 191 192 if( mbIsNumbered ) 193 { 194 if( xPropSetInfo->hasPropertyByName( msParaIsNumberingRestart ) ) 195 { 196 xPropSet->getPropertyValue( msParaIsNumberingRestart ) >>= mbIsRestart; 197 } 198 if( xPropSetInfo->hasPropertyByName( msNumberingStartValue ) ) 199 { 200 xPropSet->getPropertyValue( msNumberingStartValue ) >>= mnListStartValue; 201 } 202 } 203 204 OSL_ENSURE( mnListLevel < mxNumRules->getCount(), "wrong num rule level" ); 205 if( mnListLevel >= mxNumRules->getCount() ) 206 { 207 Reset(); 208 return; 209 } 210 211 Sequence<PropertyValue> aProps; 212 mxNumRules->getByIndex( mnListLevel ) >>= aProps; 213 214 const PropertyValue* pPropArray = aProps.getConstArray(); 215 sal_Int32 nCount = aProps.getLength(); 216 for( sal_Int32 i=0; i<nCount; i++ ) 217 { 218 const PropertyValue& rProp = pPropArray[i]; 219 220 if ( rProp.Name == msPropNameStartWith ) 221 { 222 rProp.Value >>= mnListLevelStartValue; 223 break; 224 } 225 } 226 227 // --> OD 2008-11-26 #158694# 228 msListLabelString = ::rtl::OUString(); 229 if ( bExportTextNumberElement && 230 xPropSetInfo->hasPropertyByName( msListLabelStringProp ) ) 231 { 232 xPropSet->getPropertyValue( msListLabelStringProp ) >>= msListLabelString; 233 } 234 // <-- 235 236 // paragraph's list level range is [0..9] representing list levels [1..10] 237 ++mnListLevel; 238 } 239 else 240 { 241 mnListLevel = 0; 242 } 243 } 244 245 sal_Bool XMLTextNumRuleInfo::BelongsToSameList( const XMLTextNumRuleInfo& rCmp ) const 246 { 247 sal_Bool bRet( sal_True ); 248 // Currently only the text documents support <ListId>. 249 if ( rCmp.msListId.getLength() > 0 || 250 msListId.getLength() > 0 ) 251 { 252 bRet = rCmp.msListId == msListId; 253 } 254 else 255 { 256 bRet = HasSameNumRules( rCmp ); 257 } 258 259 return bRet; 260 } 261 // <-- 262