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.replace('\n', ' '));
41  sal_Int32 nLen = aBuf.getLength();
42  for (sal_Int32 i = 0; i < nLen; ++i)
43  {
44  if (aBuf[i] < ' ')
45  {
46  sal_Int32 j = i+1;
47  while (j<nLen && aBuf[j]<' ') ++j;
48  aBuf.remove(i, j-i);
49  nLen = aBuf.getLength();
50  }
51  }
52  return aBuf.makeStringAndClear();
53 }
54 
55 }
56 
59 {
60 }
61 
62 std::unique_ptr<SwFieldType> SwChapterFieldType::Copy() const
63 {
64  return std::make_unique<SwChapterFieldType>();
65 }
66 
67 // chapter field
68 
70  : SwField(pTyp, nFormat)
71 {
72 }
73 
75 {
76  State const& rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
77  return rState.nLevel;
78 }
79 
80 // this is called from UI or from import filters, so override both states
82 {
83  m_State.nLevel = nLev;
84  m_StateRLHidden.nLevel = nLev;
85 }
86 
87 const OUString& SwChapterField::GetNumber(SwRootFrame const*const pLayout) const
88 {
89  State const& rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
90  return rState.sNumber;
91 }
92 
93 const OUString& SwChapterField::GetTitle(SwRootFrame const*const pLayout) const
94 {
95  State const& rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
96  return rState.sTitle;
97 }
98 
99 OUString SwChapterField::ExpandImpl(SwRootFrame const*const pLayout) const
100 {
101  State const& rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
102  switch( GetFormat() )
103  {
104  case CF_TITLE:
105  return rState.sTitle;
106  case CF_NUMBER:
107  return rState.sPre + rState.sNumber + rState.sPost;
108  case CF_NUM_TITLE:
109  return rState.sPre + rState.sNumber + rState.sPost + rState.sTitle;
111  return rState.sNumber + rState.sTitle;
112  }
113  // CF_NUMBER_NOPREPST
114  return rState.sNumber;
115 }
116 
117 std::unique_ptr<SwField> SwChapterField::Copy() const
118 {
119  std::unique_ptr<SwChapterField> pTmp(
120  new SwChapterField(static_cast<SwChapterFieldType*>(GetTyp()), GetFormat()));
121  pTmp->m_State = m_State;
122  pTmp->m_StateRLHidden = m_StateRLHidden;
123 
124  return std::unique_ptr<SwField>(pTmp.release());
125 }
126 
127 // #i53420#
129  const SwContentNode* pContentNode,
130  bool bSrchNum )
131 {
132  SwDoc& rDoc = const_cast<SwDoc&>(pContentNode->GetDoc());
133 
134  const SwTextNode* pTextNode = dynamic_cast<const SwTextNode*>(pContentNode);
135  if (!pTextNode || !rFrame.IsInDocBody())
136  {
137  SwPosition aDummyPos( rDoc.GetNodes().GetEndOfContent() );
138  pTextNode = GetBodyTextNode( rDoc, aDummyPos, rFrame );
139  }
140 
141  if ( pTextNode )
142  {
143  ChangeExpansion( *pTextNode, bSrchNum, rFrame.getRootFrame() );
144  }
145 }
146 
147 void SwChapterField::ChangeExpansion(const SwTextNode &rTextNd, bool bSrchNum,
148  SwRootFrame const*const pLayout)
149 {
150  State & rState(pLayout && pLayout->IsHideRedlines() ? m_StateRLHidden : m_State);
151  rState.sNumber.clear();
152  rState.sTitle.clear();
153  rState.sPost.clear();
154  rState.sPre.clear();
155 
156  SwDoc& rDoc = const_cast<SwDoc&>(rTextNd.GetDoc());
157  const SwTextNode *pTextNd = rTextNd.FindOutlineNodeOfLevel(rState.nLevel, pLayout);
158  if( !pTextNd )
159  return;
160 
161  if( bSrchNum )
162  {
163  const SwTextNode* pONd = pTextNd;
164  do {
165  if( pONd && pONd->GetTextColl() )
166  {
167  sal_uInt8 nPrevLvl = rState.nLevel;
168 
169  OSL_ENSURE( pONd->GetAttrOutlineLevel() >= 0 && pONd->GetAttrOutlineLevel() <= MAXLEVEL,
170  "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect." );
171  rState.nLevel = static_cast<sal_uInt8>(pONd->GetAttrOutlineLevel());
172 
173  if (nPrevLvl < rState.nLevel)
174  rState.nLevel = nPrevLvl;
175  else if( SVX_NUM_NUMBER_NONE != rDoc.GetOutlineNumRule()
176  ->Get( rState.nLevel ).GetNumberingType() )
177  {
178  pTextNd = pONd;
179  break;
180  }
181 
182  if (!rState.nLevel--)
183  break;
184  pONd = pTextNd->FindOutlineNodeOfLevel(rState.nLevel, pLayout);
185  }
186  else
187  break;
188  } while( true );
189  }
190 
191  // get the number without Pre-/Post-fixstrings
192 
193  if ( pTextNd->IsOutline() )
194  {
195  // correction of refactoring done by cws swnumtree:
196  // retrieve numbering string without prefix and suffix strings
197  // as stated in the above german comment.
198  rState.sNumber = pTextNd->GetNumString(false, MAXLEVEL, pLayout);
199 
200  SwNumRule* pRule( pTextNd->GetNumRule() );
201  if ( pTextNd->IsCountedInList() && pRule )
202  {
203  int nListLevel = pTextNd->GetActualListLevel();
204  if (nListLevel < 0)
205  nListLevel = 0;
206  if (nListLevel >= MAXLEVEL)
207  nListLevel = MAXLEVEL - 1;
208 
209  const SwNumFormat& rNFormat = pRule->Get(nListLevel);
210  rState.sPost = rNFormat.GetSuffix();
211  rState.sPre = rNFormat.GetPrefix();
212  }
213  }
214  else
215  {
216  rState.sNumber = "??";
217  }
218 
219  rState.sTitle = removeControlChars(sw::GetExpandTextMerged(pLayout,
220  *pTextNd, false, false, ExpandMode(0)));
221 }
222 
223 bool SwChapterField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
224 {
225  switch( nWhichId )
226  {
227  case FIELD_PROP_BYTE1:
228  rAny <<= static_cast<sal_Int8>(m_State.nLevel);
229  break;
230 
231  case FIELD_PROP_USHORT1:
232  {
233  sal_Int16 nRet;
234  switch( GetFormat() )
235  {
236  case CF_NUMBER: nRet = text::ChapterFormat::NUMBER; break;
237  case CF_TITLE: nRet = text::ChapterFormat::NAME; break;
238  case CF_NUMBER_NOPREPST:
239  nRet = text::ChapterFormat::DIGIT;
240  break;
242  nRet = text::ChapterFormat::NO_PREFIX_SUFFIX;
243  break;
244  case CF_NUM_TITLE:
245  default: nRet = text::ChapterFormat::NAME_NUMBER;
246  }
247  rAny <<= nRet;
248  }
249  break;
250 
251  default:
252  assert(false);
253  }
254  return true;
255 }
256 
257 bool SwChapterField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
258 {
259  bool bRet = true;
260  switch( nWhichId )
261  {
262  case FIELD_PROP_BYTE1:
263  {
264  sal_Int8 nTmp = 0;
265  rAny >>= nTmp;
266  if(nTmp >= 0 && nTmp < MAXLEVEL)
267  {
268  m_State.nLevel = nTmp;
269  m_StateRLHidden.nLevel = nTmp;
270  }
271  else
272  bRet = false;
273  break;
274  }
275 
276  case FIELD_PROP_USHORT1:
277  {
278  sal_Int16 nVal = 0;
279  rAny >>= nVal;
280  switch( nVal )
281  {
283  case text::ChapterFormat::NUMBER: SetFormat(CF_NUMBER); break;
284  case text::ChapterFormat::NO_PREFIX_SUFFIX:
286  break;
287  case text::ChapterFormat::DIGIT:
289  break;
290 
291  default: SetFormat(CF_NUM_TITLE);
292  }
293  }
294  break;
295 
296  default:
297  assert(false);
298  }
299  return bRet;
300 }
301 
302 /* 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:313
Marks a position in the document model.
Definition: pam.hxx:35
bool IsInDocBody() const
Definition: frame.hxx:939
bool IsOutline() const
Returns if this text node is an outline.
Definition: ndtxt.cxx:3977
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:187
only chapter number without post-/prefix
Definition: chpfld.hxx:35
aBuf
void SetLevel(sal_uInt8)
Definition: chpfld.cxx:81
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:4091
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4007
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:257
virtual OUString ExpandImpl(SwRootFrame const *pLayout) const override
Definition: chpfld.cxx:99
const OUString & GetTitle(SwRootFrame const *pLayout=nullptr) const
Definition: chpfld.cxx:93
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
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:74
SwFieldIds
Definition: fldbas.hxx:44
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2798
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
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:62
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:128
unsigned char sal_uInt8
bool IsCountedInList() const
Definition: ndtxt.cxx:4229
SwNodes & GetNodes()
Definition: doc.hxx:408
virtual std::unique_ptr< SwField > Copy() const override
Definition: chpfld.cxx:117
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:420
const OUString & GetNumber(SwRootFrame const *pLayout=nullptr) const
Definition: chpfld.cxx:87
State m_StateRLHidden
Definition: chpfld.hxx:63
OUString GetNumString(const bool _bInclPrefixAndSuffixStrings=true, const unsigned int _nRestrictToThisLevel=MAXLEVEL, SwRootFrame const *pLayout=nullptr) const
Returns outline of numbering string.
Definition: ndtxt.cxx:3106
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt16 nWhich) const override
Definition: chpfld.cxx:223
SwChapterField(SwChapterFieldType *, sal_uInt32 nFormat=0)
Definition: chpfld.cxx:69
SwRootFrame * getRootFrame()
Definition: frame.hxx:677
State m_State
Definition: chpfld.hxx:62
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1025
only the title
Definition: chpfld.hxx:33
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:845