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