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