Line data Source code
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 <doc.hxx>
22 : #include <frame.hxx>
23 : #include <pam.hxx>
24 : #include <ndtxt.hxx>
25 : #include <chpfld.hxx>
26 : #include <expfld.hxx>
27 : #include <unofldmid.h>
28 : #include <numrule.hxx>
29 :
30 : using namespace ::com::sun::star;
31 :
32 : namespace
33 : {
34 :
35 0 : OUString removeControlChars(const OUString& sIn)
36 : {
37 0 : OUStringBuffer aBuf(sIn.replace('\n', ' '));
38 0 : sal_Int32 nLen = aBuf.getLength();
39 0 : for (sal_Int32 i = 0; i < nLen; ++i)
40 : {
41 0 : if (aBuf[i] < ' ')
42 : {
43 0 : sal_Int32 j = i+1;
44 0 : while (j<nLen && aBuf[j]<' ') ++j;
45 0 : aBuf.remove(i, j-i);
46 0 : nLen = aBuf.getLength();
47 : }
48 : }
49 0 : return aBuf.makeStringAndClear();
50 : }
51 :
52 : }
53 :
54 5064 : SwChapterFieldType::SwChapterFieldType()
55 5064 : : SwFieldType( RES_CHAPTERFLD )
56 : {
57 5064 : }
58 :
59 0 : SwFieldType* SwChapterFieldType::Copy() const
60 : {
61 0 : return new SwChapterFieldType();
62 : }
63 :
64 : // chapter field
65 :
66 4 : SwChapterField::SwChapterField(SwChapterFieldType* pTyp, sal_uInt32 nFmt)
67 4 : : SwField(pTyp, nFmt), nLevel( 0 )
68 4 : {}
69 :
70 0 : OUString SwChapterField::Expand() const
71 : {
72 0 : switch( GetFormat() )
73 : {
74 : case CF_TITLE:
75 0 : return sTitle;
76 : case CF_NUMBER:
77 0 : return sPre + sNumber + sPost;
78 : case CF_NUM_TITLE:
79 0 : return sPre + sNumber + sPost + sTitle;
80 : case CF_NUM_NOPREPST_TITLE:
81 0 : return sNumber + sTitle;
82 : }
83 : // CF_NUMBER_NOPREPST
84 0 : return sNumber;
85 : }
86 :
87 0 : SwField* SwChapterField::Copy() const
88 : {
89 : SwChapterField *pTmp =
90 0 : new SwChapterField((SwChapterFieldType*)GetTyp(), GetFormat());
91 0 : pTmp->nLevel = nLevel;
92 0 : pTmp->sTitle = sTitle;
93 0 : pTmp->sNumber = sNumber;
94 0 : pTmp->sPost = sPost;
95 0 : pTmp->sPre = sPre;
96 :
97 0 : return pTmp;
98 : }
99 :
100 : // #i53420#
101 0 : void SwChapterField::ChangeExpansion(const SwFrm* pFrm,
102 : const SwCntntNode* pCntntNode,
103 : bool bSrchNum )
104 : {
105 : OSL_ENSURE( pFrm, "In which frame am I?" );
106 0 : SwDoc* pDoc = (SwDoc*)pCntntNode->GetDoc();
107 :
108 0 : const SwTxtNode* pTxtNode = dynamic_cast<const SwTxtNode*>(pCntntNode);
109 0 : if ( !pTxtNode || !pFrm->IsInDocBody() )
110 : {
111 0 : SwPosition aDummyPos( pDoc->GetNodes().GetEndOfContent() );
112 0 : pTxtNode = GetBodyTxtNode( *pDoc, aDummyPos, *pFrm );
113 : }
114 :
115 0 : if ( pTxtNode )
116 : {
117 0 : ChangeExpansion( *pTxtNode, bSrchNum );
118 : }
119 0 : }
120 :
121 0 : void SwChapterField::ChangeExpansion(const SwTxtNode &rTxtNd, bool bSrchNum)
122 : {
123 0 : sNumber = OUString();
124 0 : sTitle = OUString();
125 0 : sPost = OUString();
126 0 : sPre = OUString();
127 :
128 0 : SwDoc* pDoc = (SwDoc*)rTxtNd.GetDoc();
129 0 : const SwTxtNode *pTxtNd = rTxtNd.FindOutlineNodeOfLevel( nLevel );
130 0 : if( pTxtNd )
131 : {
132 0 : if( bSrchNum )
133 : {
134 0 : const SwTxtNode* pONd = pTxtNd;
135 : do {
136 0 : if( pONd && pONd->GetTxtColl() )
137 : {
138 0 : sal_uInt8 nPrevLvl = nLevel;
139 :
140 : OSL_ENSURE( pONd->GetAttrOutlineLevel() >= 0 && pONd->GetAttrOutlineLevel() <= MAXLEVEL,
141 : "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect -> please inform OD." );
142 0 : nLevel = static_cast<sal_uInt8>(pONd->GetAttrOutlineLevel());
143 :
144 0 : if( nPrevLvl < nLevel )
145 0 : nLevel = nPrevLvl;
146 0 : else if( SVX_NUM_NUMBER_NONE != pDoc->GetOutlineNumRule()
147 0 : ->Get( nLevel ).GetNumberingType() )
148 : {
149 0 : pTxtNd = pONd;
150 0 : break;
151 : }
152 :
153 0 : if( !nLevel-- )
154 0 : break;
155 0 : pONd = pTxtNd->FindOutlineNodeOfLevel( nLevel );
156 : }
157 : else
158 0 : break;
159 0 : } while( true );
160 : }
161 :
162 : // get the number without Pre-/Post-fixstrings
163 :
164 0 : if ( pTxtNd->IsOutline() )
165 : {
166 : // correction of refactoring done by cws swnumtree:
167 : // retrieve numbering string without prefix and suffix strings
168 : // as stated in the above german comment.
169 0 : sNumber = pTxtNd->GetNumString( false );
170 :
171 0 : SwNumRule* pRule( pTxtNd->GetNumRule() );
172 0 : if ( pTxtNd->IsCountedInList() && pRule )
173 : {
174 0 : int nListLevel = pTxtNd->GetActualListLevel();
175 0 : if (nListLevel < 0)
176 0 : nListLevel = 0;
177 0 : if (nListLevel >= MAXLEVEL)
178 0 : nListLevel = MAXLEVEL - 1;
179 :
180 0 : const SwNumFmt& rNFmt = pRule->Get(nListLevel);
181 0 : sPost = rNFmt.GetSuffix();
182 0 : sPre = rNFmt.GetPrefix();
183 : }
184 : }
185 : else
186 : {
187 0 : sNumber = "??";
188 : }
189 :
190 0 : sTitle = removeControlChars(pTxtNd->GetExpandTxt(0, -1, false, false, false, false));
191 :
192 : }
193 0 : }
194 :
195 0 : bool SwChapterField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
196 : {
197 0 : switch( nWhichId )
198 : {
199 : case FIELD_PROP_BYTE1:
200 0 : rAny <<= (sal_Int8)nLevel;
201 0 : break;
202 :
203 : case FIELD_PROP_USHORT1:
204 : {
205 : sal_Int16 nRet;
206 0 : switch( GetFormat() )
207 : {
208 0 : case CF_NUMBER: nRet = text::ChapterFormat::NUMBER; break;
209 0 : case CF_TITLE: nRet = text::ChapterFormat::NAME; break;
210 : case CF_NUMBER_NOPREPST:
211 0 : nRet = text::ChapterFormat::DIGIT;
212 0 : break;
213 : case CF_NUM_NOPREPST_TITLE:
214 0 : nRet = text::ChapterFormat::NO_PREFIX_SUFFIX;
215 0 : break;
216 : case CF_NUM_TITLE:
217 0 : default: nRet = text::ChapterFormat::NAME_NUMBER;
218 : }
219 0 : rAny <<= nRet;
220 : }
221 0 : break;
222 :
223 : default:
224 : OSL_FAIL("illegal property");
225 : }
226 0 : return true;
227 : }
228 :
229 0 : bool SwChapterField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
230 : {
231 0 : bool bRet = true;
232 0 : switch( nWhichId )
233 : {
234 : case FIELD_PROP_BYTE1:
235 : {
236 0 : sal_Int8 nTmp = 0;
237 0 : rAny >>= nTmp;
238 0 : if(nTmp >= 0 && nTmp < MAXLEVEL)
239 0 : nLevel = nTmp;
240 : else
241 0 : bRet = false;
242 0 : break;
243 : }
244 :
245 : case FIELD_PROP_USHORT1:
246 : {
247 0 : sal_Int16 nVal = 0;
248 0 : rAny >>= nVal;
249 0 : switch( nVal )
250 : {
251 0 : case text::ChapterFormat::NAME: SetFormat(CF_TITLE); break;
252 0 : case text::ChapterFormat::NUMBER: SetFormat(CF_NUMBER); break;
253 : case text::ChapterFormat::NO_PREFIX_SUFFIX:
254 0 : SetFormat(CF_NUM_NOPREPST_TITLE);
255 0 : break;
256 : case text::ChapterFormat::DIGIT:
257 0 : SetFormat(CF_NUMBER_NOPREPST);
258 0 : break;
259 :
260 0 : default: SetFormat(CF_NUM_TITLE);
261 : }
262 : }
263 0 : break;
264 :
265 : default:
266 : OSL_FAIL("illegal property");
267 0 : bRet = false;
268 : }
269 0 : return bRet;
270 270 : }
271 :
272 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|