1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/container/XIndexReplace.hpp>
21 #include <com/sun/star/style/XStyle.hpp>
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <xmloff/xmlimp.hxx>
24 #include <xmloff/namespacemap.hxx>
25 #include <xmloff/xmlnamespace.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include "XMLTextListItemContext.hxx"
28 #include "XMLTextListBlockContext.hxx"
29 #include <txtlists.hxx>
30 #include <sal/log.hxx>
33 using namespace ::com::sun::star
;
34 using namespace ::com::sun::star::uno
;
35 using namespace ::com::sun::star::container
;
36 using namespace ::com::sun::star::style
;
37 using namespace ::com::sun::star::beans
;
38 using namespace ::xmloff::token
;
41 // OD 2008-05-07 #refactorlists#
42 // add optional parameter <bRestartNumberingAtSubList> and its handling
43 XMLTextListBlockContext::XMLTextListBlockContext(
45 XMLTextImportHelper
& rTxtImp
,
46 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
47 const bool bRestartNumberingAtSubList
)
48 : SvXMLImportContext( rImport
)
49 , mrTxtImport( rTxtImp
)
51 , mbRestartNumbering( false )
52 , mbSetDefaults( false )
54 static constexpr OUString s_PropNameDefaultListId
= u
"DefaultListId"_ustr
;
56 // get the parent list block context (if any); this is a bit ugly...
57 XMLTextListBlockContext
* pLB(nullptr);
58 XMLTextListItemContext
* pLI(nullptr);
59 XMLNumberedParaContext
* pNP(nullptr);
60 rTxtImp
.GetTextListHelper().ListContextTop(pLB
, pLI
, pNP
);
61 mxParentListBlock
= pLB
;
63 // Inherit style name from parent list, as well as the flags whether
64 // numbering must be restarted and formats have to be created.
65 OUString sParentListStyleName
;
66 if( mxParentListBlock
.is() )
68 XMLTextListBlockContext
*pParent
= mxParentListBlock
.get();
69 msListStyleName
= pParent
->msListStyleName
;
70 sParentListStyleName
= msListStyleName
;
71 mxNumRules
= pParent
->GetNumRules();
72 mnLevel
= pParent
->GetLevel() + 1;
73 mbRestartNumbering
= pParent
->IsRestartNumbering() ||
74 bRestartNumberingAtSubList
;
75 mbSetDefaults
= pParent
->mbSetDefaults
;
76 msListId
= pParent
->GetListId();
77 msContinueListId
= pParent
->GetContinueListId();
80 bool bIsContinueNumberingAttributePresent( false );
81 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
83 switch( aIter
.getToken() )
85 case XML_ELEMENT(XML
, XML_ID
):
86 //FIXME: there is no UNO API for lists
87 // xml:id is also the list ID (#i92221#)
88 if ( mnLevel
== 0 ) // root <list> element
90 msListId
= aIter
.toString();
93 case XML_ELEMENT(TEXT
, XML_CONTINUE_NUMBERING
):
94 mbRestartNumbering
= !IsXMLToken(aIter
, XML_TRUE
);
95 bIsContinueNumberingAttributePresent
= true;
97 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
98 msListStyleName
= aIter
.toString();
100 case XML_ELEMENT(TEXT
, XML_CONTINUE_LIST
):
101 if ( mnLevel
== 0 ) // root <list> element
103 msContinueListId
= aIter
.toString();
107 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
111 // Remember this list block.
112 mrTxtImport
.GetTextListHelper().PushListContext( this );
115 mxNumRules
= XMLTextListsHelper::MakeNumRule(GetImport(), mxNumRules
,
116 sParentListStyleName
, msListStyleName
,
117 mnLevel
, &mbRestartNumbering
, &mbSetDefaults
);
118 if( !mxNumRules
.is() )
121 if ( mnLevel
!= 0 ) // root <list> element
124 XMLTextListsHelper
& rTextListsHelper( mrTxtImport
.GetTextListHelper() );
125 // Inconsistent behavior regarding lists (#i92811#)
126 OUString sListStyleDefaultListId
;
128 uno::Reference
< beans::XPropertySet
> xNumRuleProps( mxNumRules
, UNO_QUERY
);
129 if ( xNumRuleProps
.is() )
131 uno::Reference
< beans::XPropertySetInfo
> xNumRulePropSetInfo(
132 xNumRuleProps
->getPropertySetInfo());
133 if (xNumRulePropSetInfo
.is() &&
134 xNumRulePropSetInfo
->hasPropertyByName(
135 s_PropNameDefaultListId
))
137 xNumRuleProps
->getPropertyValue(s_PropNameDefaultListId
)
138 >>= sListStyleDefaultListId
;
139 SAL_WARN_IF( sListStyleDefaultListId
.isEmpty(), "xmloff",
140 "no default list id found at numbering rules instance. Serious defect." );
144 if ( msListId
.isEmpty() ) // no text:id property found
147 sal_Int32
nBuild( 0 );
148 const bool bBuildIdFound
= GetImport().getBuildIds( nUPD
, nBuild
);
149 if ( rImport
.IsTextDocInOOoFileFormat() ||
150 ( bBuildIdFound
&& nUPD
== 680 ) )
152 /* handling former documents written by OpenOffice.org:
153 use default list id of numbering rules instance, if existing
156 if ( !sListStyleDefaultListId
.isEmpty() )
158 msListId
= sListStyleDefaultListId
;
159 if ( !bIsContinueNumberingAttributePresent
&&
160 !mbRestartNumbering
&&
161 rTextListsHelper
.IsListProcessed( msListId
) )
163 mbRestartNumbering
= true;
167 if ( msListId
.isEmpty() )
169 // generate a new list id for the list
170 msListId
= rTextListsHelper
.GenerateNewListId();
174 if ( bIsContinueNumberingAttributePresent
&& !mbRestartNumbering
&&
175 msContinueListId
.isEmpty() )
177 const OUString
& Last( rTextListsHelper
.GetLastProcessedListId() );
178 if ( rTextListsHelper
.GetListStyleOfLastProcessedList() == msListStyleName
179 && Last
!= msListId
)
181 msContinueListId
= Last
;
185 bool bContinueNumbering
= bIsContinueNumberingAttributePresent
&& !mbRestartNumbering
;
186 if (msContinueListId
.isEmpty() && bContinueNumbering
&& GetImport().IsMSO())
188 // No "continue list" id, but continue numbering was requested. Connect to the last list of
189 // the same list style in the Word case, even if there was a different list in the meantime.
190 msContinueListId
= rTextListsHelper
.GetLastIdOfStyleName(msListStyleName
);
193 if ( !msContinueListId
.isEmpty() )
195 if ( !rTextListsHelper
.IsListProcessed( msContinueListId
) )
197 msContinueListId
.clear();
201 // search continue list chain for master list and
202 // continue the master list.
204 rTextListsHelper
.GetContinueListIdOfProcessedList( msContinueListId
);
205 while ( !sTmpStr
.isEmpty() )
207 msContinueListId
= sTmpStr
;
210 rTextListsHelper
.GetContinueListIdOfProcessedList( msContinueListId
);
215 if ( !rTextListsHelper
.IsListProcessed( msListId
) )
217 // Inconsistent behavior regarding lists (#i92811#)
218 rTextListsHelper
.KeepListAsProcessed(
219 msListId
, msListStyleName
, msContinueListId
,
220 sListStyleDefaultListId
);
223 catch (uno::Exception
&)
225 // pop ourselves if anything goes wrong to avoid use-after-free
226 rTxtImp
.GetTextListHelper().PopListContext();
231 XMLTextListBlockContext::~XMLTextListBlockContext()
235 void XMLTextListBlockContext::endFastElement(sal_Int32
)
237 // Numbering has not to be restarted if it has been restarted within
239 XMLTextListBlockContext
*pParent
= mxParentListBlock
.get();
242 pParent
->mbRestartNumbering
= mbRestartNumbering
;
245 // Restore current list block.
246 mrTxtImport
.GetTextListHelper().PopListContext();
248 // Any paragraph following the list within the same list item must not
250 mrTxtImport
.GetTextListHelper().SetListItem( nullptr );
253 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLTextListBlockContext::createFastChildContext(
255 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
257 SvXMLImportContext
*pContext
= nullptr;
259 bool bHeader
= false;
262 case XML_ELEMENT(TEXT
, XML_LIST_HEADER
):
265 case XML_ELEMENT(TEXT
, XML_LIST_ITEM
):
266 pContext
= new XMLTextListItemContext( GetImport(), mrTxtImport
,
267 xAttrList
, bHeader
);
270 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */