LibreOffice Module xmloff (master)  1
XMLTextNumRuleInfo.cxx
Go to the documentation of this file.
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 
21 #include <osl/diagnose.h>
22 #include <sal/log.hxx>
23 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include <com/sun/star/beans/PropertyValue.hpp>
25 #include <com/sun/star/container/XIndexReplace.hpp>
26 #include <com/sun/star/style/NumberingType.hpp>
27 #include <com/sun/star/text/XTextContent.hpp>
28 #include <com/sun/star/container/XNamed.hpp>
29 #include "XMLTextNumRuleInfo.hxx"
31 
32 
33 using namespace ::com::sun::star::uno;
34 using namespace ::com::sun::star::beans;
35 using namespace ::com::sun::star::container;
36 using namespace ::com::sun::star::style;
37 
38 // Complete refactoring of the class and enhancement of the class for lists.
40  : mnListStartValue( -1 )
41  , mnListLevel( 0 )
42  , mbIsNumbered( false )
43  , mbIsRestart( false )
44  , mnListLevelStartValue( -1 )
45  , mbOutlineStyleAsNormalListStyle( false )
46 {
47  Reset();
48 }
49 
50 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
52  const css::uno::Reference < css::text::XTextContent > & xTextContent,
53  const bool bOutlineStyleAsNormalListStyle,
54  const XMLTextListAutoStylePool& rListAutoPool,
55  const bool bExportTextNumberElement )
56 {
57  Reset();
58  // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
59  mbOutlineStyleAsNormalListStyle = bOutlineStyleAsNormalListStyle;
60 
61  Reference< XPropertySet > xPropSet( xTextContent, UNO_QUERY );
62  Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
63 
64  // check if this paragraph supports a numbering
65  if( !xPropSetInfo->hasPropertyByName( "NumberingLevel" ) )
66  return;
67 
68  if( xPropSet->getPropertyValue( "NumberingLevel" ) >>= mnListLevel )
69  {
70  if( xPropSetInfo->hasPropertyByName( "NumberingRules" ) )
71  {
72  xPropSet->getPropertyValue( "NumberingRules" ) >>= mxNumRules;
73  }
74  }
75  else
76  {
77  // in applications using the outliner we always have a numbering rule,
78  // so a void property no numbering
79  mnListLevel = 0;
80  }
81 
82  // Assertion saving writer document (#i97312#)
83  if ( mxNumRules.is() && mxNumRules->getCount() < 1 )
84  {
85  SAL_WARN("xmloff",
86  "<XMLTextNumRuleInfo::Set(..)> - numbering rules instance does not contain any numbering rule" );
87  Reset();
88  return;
89  }
90 
91  if ( mnListLevel < 0 )
92  {
93  SAL_WARN("xmloff",
94  "<XMLTextNumRuleInfo::Set(..)> - unexpected numbering level" );
95  Reset();
96  return;
97  }
98 
99  // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
100  bool bSuppressListStyle( false );
101  if ( mxNumRules.is() )
102  {
104  {
105  Reference<XPropertySet> xNumRulesProps(mxNumRules, UNO_QUERY);
106  if ( xNumRulesProps.is() &&
107  xNumRulesProps->getPropertySetInfo()->
108  hasPropertyByName( "NumberingIsOutline" ) )
109  {
110  bool bIsOutline = false;
111  xNumRulesProps->getPropertyValue( "NumberingIsOutline" ) >>= bIsOutline;
112  bSuppressListStyle = bIsOutline;
113  }
114  }
115  }
116 
117  if( mxNumRules.is() && !bSuppressListStyle )
118  {
119  // First try to find the numbering rules in the list auto style pool.
120  // If not found, the numbering rules instance has to be named.
121  msNumRulesName = rListAutoPool.Find( mxNumRules );
122  if ( msNumRulesName.isEmpty() )
123  {
124  Reference < XNamed > xNamed( mxNumRules, UNO_QUERY );
125  SAL_WARN_IF( !xNamed.is(), "xmloff",
126  "<XMLTextNumRuleInfo::Set(..)> - numbering rules instance have to be named. Serious defect." );
127  if( xNamed.is() )
128  {
129  msNumRulesName = xNamed->getName();
130  }
131  }
132  SAL_WARN_IF( msNumRulesName.isEmpty(), "xmloff",
133  "<XMLTextNumRuleInfo::Set(..)> - no name found for numbering rules instance. Serious defect." );
134 
135  if( xPropSetInfo->hasPropertyByName( "ListId" ) )
136  {
137  xPropSet->getPropertyValue( "ListId" ) >>= msListId;
138  }
139 
141  if( xPropSetInfo->hasPropertyByName( "ContinueingPreviousSubTree" ) )
142  {
143  xPropSet->getPropertyValue( "ContinueingPreviousSubTree" ) >>= mbContinueingPreviousSubTree;
144  }
145 
146  mbIsNumbered = true;
147  if( xPropSetInfo->hasPropertyByName( "NumberingIsNumber" ) )
148  {
149  if( !(xPropSet->getPropertyValue( "NumberingIsNumber" ) >>= mbIsNumbered ) )
150  {
151  OSL_FAIL( "numbered paragraph without number info" );
152  mbIsNumbered = false;
153  }
154  }
155 
156  if( mbIsNumbered )
157  {
158  if( xPropSetInfo->hasPropertyByName( "ParaIsNumberingRestart" ) )
159  {
160  xPropSet->getPropertyValue( "ParaIsNumberingRestart" ) >>= mbIsRestart;
161  }
162  if( xPropSetInfo->hasPropertyByName( "NumberingStartValue" ) )
163  {
164  xPropSet->getPropertyValue( "NumberingStartValue" ) >>= mnListStartValue;
165  }
166  }
167 
168  OSL_ENSURE( mnListLevel < mxNumRules->getCount(), "wrong num rule level" );
169  if( mnListLevel >= mxNumRules->getCount() )
170  {
171  Reset();
172  return;
173  }
174 
175  Sequence<PropertyValue> aProps;
176  mxNumRules->getByIndex( mnListLevel ) >>= aProps;
177 
178  auto pProp = std::find_if(std::cbegin(aProps), std::cend(aProps),
179  [](const PropertyValue& rProp) { return rProp.Name == "StartWith"; });
180  if (pProp != std::cend(aProps))
181  {
182  pProp->Value >>= mnListLevelStartValue;
183  }
184 
185  msListLabelString.clear();
186  if ( bExportTextNumberElement &&
187  xPropSetInfo->hasPropertyByName( "ListLabelString" ) )
188  {
189  xPropSet->getPropertyValue( "ListLabelString" ) >>= msListLabelString;
190  }
191 
192  // paragraph's list level range is [0..9] representing list levels [1..10]
193  ++mnListLevel;
194  }
195  else
196  {
197  mnListLevel = 0;
198  }
199 }
200 
202 {
203  bool bRet( true );
204  // Currently only the text documents support <ListId>.
205  if ( !rCmp.msListId.isEmpty() || !msListId.isEmpty() )
206  {
207  bRet = rCmp.msListId == msListId;
208  }
209  else
210  {
211  bRet = rCmp.msNumRulesName == msNumRulesName;
212  }
213 
214  return bRet;
215 }
216 
217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool BelongsToSameList(const XMLTextNumRuleInfo &rCmp) const
css::uno::Reference< css::container::XIndexReplace > mxNumRules
information about list and list style for a certain paragraph
void Set(const css::uno::Reference< css::text::XTextContent > &rTextContent, const bool bOutlineStyleAsNormalListStyle, const XMLTextListAutoStylePool &rListAutoPool, const bool bExportTextNumberElement)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
SAL_DLLPRIVATE sal_uInt32 Find(const XMLTextListAutoStylePoolEntry_Impl *pEntry) const