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