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 #include <tools/debug.hxx>
27 #include <com/sun/star/container/XNameContainer.hpp>
28 #include <com/sun/star/container/XIndexReplace.hpp>
29 #include <com/sun/star/style/XStyle.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <xmloff/xmlimp.hxx>
32 #include <xmloff/xmlnumi.hxx>
33 #include <xmloff/nmspmap.hxx>
34 #include "xmloff/xmlnmspe.hxx"
35 #include <xmloff/xmltoken.hxx>
36 #include "XMLTextListItemContext.hxx"
37 #include "XMLTextListBlockContext.hxx"
38 #include "txtlists.hxx"
39
40 using ::rtl::OUString;
41 using ::rtl::OUStringBuffer;
42
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::uno;
45 using namespace ::com::sun::star::container;
46 using namespace ::com::sun::star::style;
47 using namespace ::com::sun::star::beans;
48 using namespace ::xmloff::token;
49
50 TYPEINIT1( XMLTextListBlockContext, SvXMLImportContext );
51
52 // OD 2008-05-07 #refactorlists#
53 // add optional parameter <bRestartNumberingAtSubList> and its handling
XMLTextListBlockContext(SvXMLImport & rImport,XMLTextImportHelper & rTxtImp,sal_uInt16 nPrfx,const OUString & rLName,const Reference<xml::sax::XAttributeList> & xAttrList,const sal_Bool bRestartNumberingAtSubList)54 XMLTextListBlockContext::XMLTextListBlockContext(
55 SvXMLImport& rImport,
56 XMLTextImportHelper& rTxtImp,
57 sal_uInt16 nPrfx,
58 const OUString& rLName,
59 const Reference< xml::sax::XAttributeList > & xAttrList,
60 const sal_Bool bRestartNumberingAtSubList )
61 : SvXMLImportContext( rImport, nPrfx, rLName )
62 , mrTxtImport( rTxtImp )
63 // --> OD 2008-04-22 #refactorlists#
64 , msListStyleName()
65 // <--
66 , mxParentListBlock( )
67 , mnLevel( 0 )
68 // --> OD 2008-05-07 #refactorlists#
69 //, mbRestartNumbering( sal_True )
70 , mbRestartNumbering( sal_False )
71 // <--
72 , mbSetDefaults( sal_False )
73 // --> OD 2008-04-22 #refactorlists#
74 , msListId()
75 , msContinueListId()
76 // <--
77 {
78 static ::rtl::OUString s_PropNameDefaultListId(
79 RTL_CONSTASCII_USTRINGPARAM("DefaultListId"));
80 {
81 // get the parent list block context (if any); this is a bit ugly...
82 XMLTextListBlockContext * pLB(0);
83 XMLTextListItemContext * pLI(0);
84 XMLNumberedParaContext * pNP(0);
85 rTxtImp.GetTextListHelper().ListContextTop(pLB, pLI, pNP);
86 mxParentListBlock = pLB;
87 }
88 // Inherit style name from parent list, as well as the flags whether
89 // numbering must be restarted and formats have to be created.
90 OUString sParentListStyleName;
91 // --> OD 2008-11-27 #158694#
92 sal_Bool bParentRestartNumbering( sal_False );
93 // <--
94 if( mxParentListBlock.Is() )
95 {
96 XMLTextListBlockContext *pParent =
97 (XMLTextListBlockContext *)&mxParentListBlock;
98 msListStyleName = pParent->GetListStyleName();
99 sParentListStyleName = msListStyleName;
100 mxNumRules = pParent->GetNumRules();
101 mnLevel = pParent->GetLevel() + 1;
102 // --> OD 2008-05-07 #refactorlists#
103 // mbRestartNumbering = pParent->IsRestartNumbering();
104 mbRestartNumbering = pParent->IsRestartNumbering() ||
105 bRestartNumberingAtSubList;
106 // <--
107 // --> OD 2008-11-27 #158694#
108 bParentRestartNumbering = pParent->IsRestartNumbering();
109 // <--
110 mbSetDefaults = pParent->mbSetDefaults;
111 // --> OD 2008-04-22 #refactorlists#
112 msListId = pParent->GetListId();
113 msContinueListId = pParent->GetContinueListId();
114 // <--
115 }
116
117 const SvXMLTokenMap& rTokenMap = mrTxtImport.GetTextListBlockAttrTokenMap();
118
119 // --> OD 2008-05-07 #refactorlists#
120 bool bIsContinueNumberingAttributePresent( false );
121 // <--
122 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
123 for( sal_Int16 i=0; i < nAttrCount; i++ )
124 {
125 const OUString& rAttrName = xAttrList->getNameByIndex( i );
126 const OUString& rValue = xAttrList->getValueByIndex( i );
127
128 OUString aLocalName;
129 sal_uInt16 nPrefix =
130 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
131 &aLocalName );
132 switch( rTokenMap.Get( nPrefix, aLocalName ) )
133 {
134 case XML_TOK_TEXT_LIST_BLOCK_XMLID:
135 sXmlId = rValue;
136 //FIXME: there is no UNO API for lists
137 // --> OD 2008-07-31 #i92221# - xml:id is also the list ID
138 if ( mnLevel == 0 ) // root <list> element
139 {
140 msListId = rValue;
141 }
142 // <--
143 break;
144 case XML_TOK_TEXT_LIST_BLOCK_CONTINUE_NUMBERING:
145 mbRestartNumbering = !IsXMLToken(rValue, XML_TRUE);
146 // --> OD 2008-05-07 #refactorlists#
147 bIsContinueNumberingAttributePresent = true;
148 // <--
149 break;
150 case XML_TOK_TEXT_LIST_BLOCK_STYLE_NAME:
151 msListStyleName = rValue;
152 break;
153 // --> OD 2008-04-22 #refactorlists#
154 case XML_TOK_TEXT_LIST_BLOCK_CONTINUE_LIST:
155 if ( mnLevel == 0 ) // root <list> element
156 {
157 msContinueListId = rValue;
158 }
159 break;
160 }
161 }
162
163 mxNumRules = XMLTextListsHelper::MakeNumRule(GetImport(), mxNumRules,
164 sParentListStyleName, msListStyleName,
165 mnLevel, &mbRestartNumbering, &mbSetDefaults );
166 if( !mxNumRules.is() )
167 return;
168
169 // --> OD 2008-04-23 #refactorlists#
170 if ( mnLevel == 0 ) // root <list> element
171 {
172 XMLTextListsHelper& rTextListsHelper( mrTxtImport.GetTextListHelper() );
173 // --> OD 2008-08-15 #i92811#
174 ::rtl::OUString sListStyleDefaultListId;
175 {
176 uno::Reference< beans::XPropertySet > xNumRuleProps( mxNumRules, UNO_QUERY );
177 if ( xNumRuleProps.is() )
178 {
179 uno::Reference< beans::XPropertySetInfo > xNumRulePropSetInfo(
180 xNumRuleProps->getPropertySetInfo());
181 if (xNumRulePropSetInfo.is() &&
182 xNumRulePropSetInfo->hasPropertyByName(
183 s_PropNameDefaultListId))
184 {
185 xNumRuleProps->getPropertyValue(s_PropNameDefaultListId)
186 >>= sListStyleDefaultListId;
187 DBG_ASSERT( sListStyleDefaultListId.getLength() != 0,
188 "no default list id found at numbering rules instance. Serious defect -> please inform OD." );
189 }
190 }
191 }
192 // <--
193 if ( msListId.getLength() == 0 ) // no text:id property found
194 {
195 sal_Int32 nUPD( 0 );
196 sal_Int32 nBuild( 0 );
197 const bool bBuildIdFound = GetImport().getBuildIds( nUPD, nBuild );
198 if ( rImport.IsTextDocInOOoFileFormat() ||
199 ( bBuildIdFound && nUPD == 680 ) )
200 {
201 // handling former documents written by OpenOffice.org:
202 // use default list id of numbering rules instance, if existing
203 // --> OD 2008-08-15 #i92811#
204 if ( sListStyleDefaultListId.getLength() != 0 )
205 {
206 msListId = sListStyleDefaultListId;
207 if ( !bIsContinueNumberingAttributePresent &&
208 !mbRestartNumbering &&
209 rTextListsHelper.IsListProcessed( msListId ) )
210 {
211 mbRestartNumbering = sal_True;
212 }
213 }
214 // <--
215 }
216 if ( msListId.getLength() == 0 )
217 {
218 // generate a new list id for the list
219 msListId = rTextListsHelper.GenerateNewListId();
220 }
221 }
222
223 if ( bIsContinueNumberingAttributePresent && !mbRestartNumbering &&
224 msContinueListId.getLength() == 0 )
225 {
226 ::rtl::OUString Last( rTextListsHelper.GetLastProcessedListId() );
227 if ( rTextListsHelper.GetListStyleOfLastProcessedList() == msListStyleName
228 && Last != msListId )
229 {
230 msContinueListId = Last;
231 }
232 }
233
234 if ( msContinueListId.getLength() > 0 )
235 {
236 if ( !rTextListsHelper.IsListProcessed( msContinueListId ) )
237 {
238 msContinueListId = ::rtl::OUString();
239 }
240 else
241 {
242 // search continue list chain for master list and
243 // continue the master list.
244 ::rtl::OUString sTmpStr =
245 rTextListsHelper.GetContinueListIdOfProcessedList( msContinueListId );
246 while ( sTmpStr.getLength() > 0 )
247 {
248 msContinueListId = sTmpStr;
249
250 sTmpStr =
251 rTextListsHelper.GetContinueListIdOfProcessedList( msContinueListId );
252 }
253 }
254 }
255
256 if ( !rTextListsHelper.IsListProcessed( msListId ) )
257 {
258 // --> OD 2008-08-15 #i92811#
259 rTextListsHelper.KeepListAsProcessed(
260 msListId, msListStyleName, msContinueListId,
261 sListStyleDefaultListId );
262 // <--
263 }
264 }
265 // <--
266
267 // Remember this list block.
268 mrTxtImport.GetTextListHelper().PushListContext( this );
269 }
270
~XMLTextListBlockContext()271 XMLTextListBlockContext::~XMLTextListBlockContext()
272 {
273 }
274
EndElement()275 void XMLTextListBlockContext::EndElement()
276 {
277 // Numbering has not to be restarted if it has been restarted within
278 // a child list.
279 XMLTextListBlockContext *pParent =
280 (XMLTextListBlockContext *)&mxParentListBlock;
281 if( pParent )
282 {
283 pParent->mbRestartNumbering = mbRestartNumbering;
284 }
285
286 // Restore current list block.
287 mrTxtImport.GetTextListHelper().PopListContext();
288
289 // Any paragraph following the list within the same list item must not
290 // be numbered.
291 mrTxtImport.GetTextListHelper().SetListItem( 0 );
292 }
293
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const Reference<xml::sax::XAttributeList> & xAttrList)294 SvXMLImportContext *XMLTextListBlockContext::CreateChildContext(
295 sal_uInt16 nPrefix,
296 const OUString& rLocalName,
297 const Reference< xml::sax::XAttributeList > & xAttrList )
298 {
299 SvXMLImportContext *pContext = 0;
300
301 const SvXMLTokenMap& rTokenMap =
302 mrTxtImport.GetTextListBlockElemTokenMap();
303 sal_Bool bHeader = sal_False;
304 switch( rTokenMap.Get( nPrefix, rLocalName ) )
305 {
306 case XML_TOK_TEXT_LIST_HEADER:
307 bHeader = sal_True;
308 case XML_TOK_TEXT_LIST_ITEM:
309 pContext = new XMLTextListItemContext( GetImport(), mrTxtImport,
310 nPrefix, rLocalName,
311 xAttrList, bHeader );
312 break;
313 }
314
315 if( !pContext )
316 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
317
318 return pContext;
319 }
320
321 // --> OD 2008-04-22 #refactorlists#
GetListId() const322 const ::rtl::OUString& XMLTextListBlockContext::GetListId() const
323 {
324 return msListId;
325 }
326
GetContinueListId() const327 const ::rtl::OUString& XMLTextListBlockContext::GetContinueListId() const
328 {
329 return msContinueListId;
330 }
331 // <--
332
333