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