LibreOffice Module sw (master)  1
chpfld.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 #include <com/sun/star/text/ChapterFormat.hpp>
21 #include <osl/diagnose.h>
22 #include <doc.hxx>
23 #include <frame.hxx>
24 #include <rootfrm.hxx>
25 #include <txtfrm.hxx>
26 #include <pam.hxx>
27 #include <ndtxt.hxx>
28 #include <chpfld.hxx>
29 #include <expfld.hxx>
30 #include <unofldmid.h>
31 #include <numrule.hxx>
32 
33 using namespace ::com::sun::star;
34 
35 namespace
36 {
37 
38 OUString removeControlChars(const OUString& sIn)
39 {
40  OUStringBuffer aBuf(sIn);
41  aBuf = aBuf.replace('\n', ' ').replace('\t', ' ');
42  sal_Int32 nLen = aBuf.getLength();
43  for (sal_Int32 i = 0; i < nLen; ++i)
44  {
45  if (aBuf[i] < ' ')
46  {
47  sal_Int32 j = i+1;
48  while (j<nLen && aBuf[j]<' ') ++j;
49  aBuf.remove(i, j-i);
50  nLen = aBuf.getLength();
51  }
52  }
53  return aBuf.makeStringAndClear();
54 }
55 
56 }
57 
60 {
61 }
62 
63 std::unique_ptr<SwFieldType> SwChapterFieldType::Copy() const
64 {
65  return std::make_unique<SwChapterFieldType>();
66 }
67 
68 // chapter field
69 
71  : SwField(pTyp, nFormat)
72 {
73 }
74 
76 {
77  State const& rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
78  return rState.nLevel;
79 }
80 
81 // this is called from UI or from import filters, so override both states
83 {
84  m_State.nLevel = nLev;
85  m_StateRLHidden.nLevel = nLev;
86 }
87 
88 const OUString& SwChapterField::GetNumber(SwRootFrame const*const pLayout) const
89 {
90  State const& rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
91  return rState.sNumber;
92 }
93 
94 const OUString& SwChapterField::GetTitle(SwRootFrame const*const pLayout) const
95 {
96  State const& rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
97  return rState.sTitle;
98 }
99 
100 OUString SwChapterField::ExpandImpl(SwRootFrame const*const pLayout) const
101 {
102  State const& rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
103  switch( GetFormat() )
104  {
105  case CF_TITLE:
106  return rState.sTitle;
107  case CF_NUMBER:
108  return rState.sPre + rState.sNumber + rState.sPost;
109  case CF_NUM_TITLE:
110  return rState.sPre + rState.sNumber + rState.sPost + rState.sLabelFollowedBy + rState.sTitle;
112  return rState.sNumber + rState.sLabelFollowedBy + rState.sTitle;
113  }
114  // CF_NUMBER_NOPREPST
115  return rState.sNumber;
116 }
117 
118 std::unique_ptr<SwField> SwChapterField::Copy() const
119 {
120  std::unique_ptr<SwChapterField> pTmp(
121  new SwChapterField(static_cast<SwChapterFieldType*>(GetTyp()), GetFormat()));
122  pTmp->m_State = m_State;
123  pTmp->m_StateRLHidden = m_StateRLHidden;
124 
125  return std::unique_ptr<SwField>(pTmp.release());
126 }
127 
128 // #i53420#
130  const SwContentNode* pContentNode,
131  bool bSrchNum )
132 {
133  SwDoc& rDoc = const_cast<SwDoc&>(pContentNode->GetDoc());
134 
135  const SwTextNode* pTextNode = dynamic_cast<const SwTextNode*>(pContentNode);
136  if (!pTextNode || !rFrame.IsInDocBody())
137  {
138  SwPosition aDummyPos( rDoc.GetNodes().GetEndOfContent() );
139  pTextNode = GetBodyTextNode( rDoc, aDummyPos, rFrame );
140  }
141 
142  if ( pTextNode )
143  {
144  ChangeExpansion( *pTextNode, bSrchNum, rFrame.getRootFrame() );
145  }
146 }
147 
148 void SwChapterField::ChangeExpansion(const SwTextNode &rTextNd, bool bSrchNum,
149  SwRootFrame const*const pLayout)
150 {
151  State & rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
152  rState.sNumber.clear();
153  rState.sLabelFollowedBy.clear();
154  rState.sTitle.clear();
155  rState.sPost.clear();
156  rState.sPre.clear();
157 
158  SwDoc& rDoc = const_cast<SwDoc&>(rTextNd.GetDoc());
159  const SwTextNode *pTextNd = rTextNd.FindOutlineNodeOfLevel(rState.nLevel, pLayout);
160  if( !pTextNd )
161  return;
162 
163  if( bSrchNum )
164  {
165  const SwTextNode* pONd = pTextNd;
166  do {
167  if( pONd && pONd->GetTextColl() )
168  {
169  sal_uInt8 nPrevLvl = rState.nLevel;
170 
171  OSL_ENSURE( pONd->GetAttrOutlineLevel() >= 0 && pONd->GetAttrOutlineLevel() <= MAXLEVEL,
172  "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect." );
173  rState.nLevel = static_cast<sal_uInt8>(pONd->GetAttrOutlineLevel());
174 
175  if (nPrevLvl < rState.nLevel)
176  rState.nLevel = nPrevLvl;
177  else if( SVX_NUM_NUMBER_NONE != rDoc.GetOutlineNumRule()
178  ->Get( rState.nLevel ).GetNumberingType() )
179  {
180  pTextNd = pONd;
181  break;
182  }
183 
184  if (!rState.nLevel--)
185  break;
186  pONd = pTextNd->FindOutlineNodeOfLevel(rState.nLevel, pLayout);
187  }
188  else
189  break;
190  } while( true );
191  }
192 
193  // get the number without Pre-/Post-fixstrings
194 
195  if ( pTextNd->IsOutline() )
196  {
197  // correction of refactoring done by cws swnumtree:
198  // retrieve numbering string without prefix and suffix strings
199  // as stated in the above german comment.
200  rState.sNumber = pTextNd->GetNumString(false, MAXLEVEL, pLayout);
201 
202  SwNumRule* pRule( pTextNd->GetNumRule() );
203  if ( pTextNd->IsCountedInList() && pRule )
204  {
205  int nListLevel = pTextNd->GetActualListLevel();
206  if (nListLevel < 0)
207  nListLevel = 0;
208  if (nListLevel >= MAXLEVEL)
209  nListLevel = MAXLEVEL - 1;
210 
211  const SwNumFormat& rNFormat = pRule->Get(nListLevel);
212  rState.sPost = rNFormat.GetSuffix();
213  rState.sPre = rNFormat.GetPrefix();
214  rState.sLabelFollowedBy = removeControlChars(rNFormat.GetLabelFollowedByAsString());
215  }
216  }
217  else
218  {
219  rState.sNumber = "??";
220  }
221 
222  rState.sTitle = removeControlChars(sw::GetExpandTextMerged(pLayout,
223  *pTextNd, false, false, ExpandMode(0)));
224 }
225 
226 bool SwChapterField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
227 {
228  switch( nWhichId )
229  {
230  case FIELD_PROP_BYTE1:
231  rAny <<= static_cast<sal_Int8>(m_State.nLevel);
232  break;
233 
234  case FIELD_PROP_USHORT1:
235  {
236  sal_Int16 nRet;
237  switch( GetFormat() )
238  {
239  case CF_NUMBER: nRet = text::ChapterFormat::NUMBER; break;
240  case CF_TITLE: nRet = text::ChapterFormat::NAME; break;
241  case CF_NUMBER_NOPREPST:
242  nRet = text::ChapterFormat::DIGIT;
243  break;
245  nRet = text::ChapterFormat::NO_PREFIX_SUFFIX;
246  break;
247  case CF_NUM_TITLE:
248  default: nRet = text::ChapterFormat::NAME_NUMBER;
249  }
250  rAny <<= nRet;
251  }
252  break;
253 
254  default:
255  assert(false);
256  }
257  return true;
258 }
259 
260 bool SwChapterField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
261 {
262  bool bRet = true;
263  switch( nWhichId )
264  {
265  case FIELD_PROP_BYTE1:
266  {
267  sal_Int8 nTmp = 0;
268  rAny >>= nTmp;
269  if(nTmp >= 0 && nTmp < MAXLEVEL)
270  {
271  m_State.nLevel = nTmp;
272  m_StateRLHidden.nLevel = nTmp;
273  }
274  else
275  bRet = false;
276  break;
277  }
278 
279  case FIELD_PROP_USHORT1:
280  {
281  sal_Int16 nVal = 0;
282  rAny >>= nVal;
283  switch( nVal )
284  {
286  case text::ChapterFormat::NUMBER: SetFormat(CF_NUMBER); break;
287  case text::ChapterFormat::NO_PREFIX_SUFFIX:
289  break;
290  case text::ChapterFormat::DIGIT:
292  break;
293 
294  default: SetFormat(CF_NUM_TITLE);
295  }
296  }
297  break;
298 
299  default:
300  assert(false);
301  }
302  return bRet;
303 }
304 
305 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvxNumType GetNumberingType() const
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:240
Base class of the Writer layout elements.
Definition: frame.hxx:315
Marks a position in the document model.
Definition: pam.hxx:35
bool IsInDocBody() const
Definition: frame.hxx:944
bool IsOutline() const
Returns if this text node is an outline.
Definition: ndtxt.cxx:3985
sal_uInt32 GetFormat() const
Query parameters for dialog and for BASIC.
Definition: fldbas.hxx:397
signed char sal_Int8
const SwTextNode * GetBodyTextNode(const SwDoc &rDoc, SwPosition &rPos, const SwFrame &rFrame)
Forward declaration: get "BodyTextNode" for exp.fld in Fly's headers/footers/footnotes.
Definition: expfld.cxx:163
SVX_NUM_NUMBER_NONE
Base class of all fields.
Definition: fldbas.hxx:289
#define FIELD_PROP_USHORT1
Definition: unofldmid.h:31
Definition: doc.hxx:188
only chapter number without post-/prefix
Definition: chpfld.hxx:35
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:93
aBuf
void SetLevel(sal_uInt8)
Definition: chpfld.cxx:82
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4095
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4015
chapter number without post-/prefix and title
Definition: chpfld.hxx:36
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt16 nWhich) override
Definition: chpfld.cxx:260
virtual OUString ExpandImpl(SwRootFrame const *pLayout) const override
Definition: chpfld.cxx:100
const OUString & GetTitle(SwRootFrame const *pLayout=nullptr) const
Definition: chpfld.cxx:94
const OUString & GetPrefix() const
const OUString & GetSuffix() const
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:163
OUString GetExpandTextMerged(SwRootFrame const *const pLayout, SwTextNode const &rNode, bool const bWithNumber, bool const bWithSpacesForLevel, ExpandMode const i_mode)
number and title
Definition: chpfld.hxx:34
int i
SwDoc & GetDoc()
Definition: node.hxx:212
sal_uInt8 GetLevel(SwRootFrame const *pLayout=nullptr) const
Definition: chpfld.cxx:75
SwFieldIds
Definition: fldbas.hxx:44
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2807
void SetFormat(sal_uInt32 const nSet)
Definition: fldbas.hxx:303
#define FIELD_PROP_BYTE1
Definition: unofldmid.h:33
sal_uInt8 nLevel
Definition: chpfld.hxx:55
OUString GetLabelFollowedByAsString() const
SwFieldType * GetTyp() const
Definition: fldbas.hxx:392
only the chapter number
Definition: chpfld.hxx:32
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:79
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual std::unique_ptr< SwFieldType > Copy() const override
Definition: chpfld.cxx:63
ExpandMode
Some helpers for converting model strings to view strings.
const SwTextNode * FindOutlineNodeOfLevel(sal_uInt8 nLvl, SwRootFrame const *pLayout=nullptr) const
Definition: node.cxx:773
void ChangeExpansion(const SwFrame &, const SwContentNode *, bool bSrchNum=false)
Definition: chpfld.cxx:129
unsigned char sal_uInt8
bool IsCountedInList() const
Definition: ndtxt.cxx:4233
SwNodes & GetNodes()
Definition: doc.hxx:409
virtual std::unique_ptr< SwField > Copy() const override
Definition: chpfld.cxx:118
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:422
const OUString & GetNumber(SwRootFrame const *pLayout=nullptr) const
Definition: chpfld.cxx:88
State m_StateRLHidden
Definition: chpfld.hxx:64
OUString GetNumString(const bool _bInclPrefixAndSuffixStrings=true, const unsigned int _nRestrictToThisLevel=MAXLEVEL, SwRootFrame const *pLayout=nullptr) const
Returns outline of numbering string.
Definition: ndtxt.cxx:3115
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt16 nWhich) const override
Definition: chpfld.cxx:226
SwChapterField(SwChapterFieldType *, sal_uInt32 nFormat=0)
Definition: chpfld.cxx:70
SwRootFrame * getRootFrame()
Definition: frame.hxx:680
State m_State
Definition: chpfld.hxx:63
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1024
only the title
Definition: chpfld.hxx:33
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:844