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