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