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