xref: /trunk/main/sw/source/core/fields/chpfld.cxx (revision d83e2ff7)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include <com/sun/star/text/ChapterFormat.hpp>
29 #include <doc.hxx>
30 #include <frame.hxx>		// SwChapterFieldType::ChangeExpansion()
31 #include <pam.hxx>			// fuer GetBodyTxtNode
32 #include <ndtxt.hxx>
33 #include <chpfld.hxx>
34 #include <expfld.hxx>		// fuer GetBodyTxtNode
35 #ifndef _UNOFLDMID_H
36 #include <unofldmid.h>
37 #endif
38 #include <numrule.hxx>
39 
40 using namespace ::com::sun::star;
41 
42 /*--------------------------------------------------------------------
43 	Beschreibung: SwChapterFieldType
44  --------------------------------------------------------------------*/
45 
46 
SwChapterFieldType()47 SwChapterFieldType::SwChapterFieldType()
48 	: SwFieldType( RES_CHAPTERFLD )
49 {
50 }
51 
52 
Copy() const53 SwFieldType* SwChapterFieldType::Copy() const
54 {
55 	return new SwChapterFieldType();
56 }
57 
58 
59 /*--------------------------------------------------------------------
60 	Beschreibung: Kapittelfeld
61  --------------------------------------------------------------------*/
62 
63 
SwChapterField(SwChapterFieldType * pTyp,sal_uInt32 nFmt)64 SwChapterField::SwChapterField(SwChapterFieldType* pTyp, sal_uInt32 nFmt)
65 	: SwField(pTyp, nFmt), nLevel( 0 )
66 {}
67 
68 
Expand() const69 String SwChapterField::Expand() const
70 {
71 	String sStr( sNumber );
72 	switch( GetFormat() )
73 	{
74 		case CF_TITLE:		sStr = sTitle;	break;
75 
76 		case CF_NUMBER:
77 		case CF_NUM_TITLE:  sStr.Insert( sPre, 0 );
78 							sStr += sPost;
79 							if( CF_NUM_TITLE == GetFormat() )
80 								sStr += sTitle;
81 							break;
82 
83 		case CF_NUM_NOPREPST_TITLE:	sStr += sTitle;	break;
84 	}
85 	return sStr;
86 }
87 
88 
Copy() const89 SwField* SwChapterField::Copy() const
90 {
91 	SwChapterField *pTmp =
92 		new SwChapterField((SwChapterFieldType*)GetTyp(), GetFormat());
93 	pTmp->nLevel = nLevel;
94 	pTmp->sTitle = sTitle;
95 	pTmp->sNumber = sNumber;
96 	pTmp->sPost = sPost;
97 	pTmp->sPre = sPre;
98 
99 	return pTmp;
100 }
101 
102 // --> OD 2008-02-14 #i53420#
103 //void SwChapterField::ChangeExpansion( const SwFrm* pFrm,
104 //                                      const SwTxtNode* pTxtNd,
105 //                                      sal_Bool bSrchNum )
106 //{
107 //    ASSERT( pFrm, "in welchem Frame stehe ich denn?" )
108 //    SwDoc* pDoc = (SwDoc*)pTxtNd->GetDoc();
109 //    SwPosition aPos( pDoc->GetNodes().GetEndOfContent() );
110 
111 //    if( pFrm->IsInDocBody() )
112 //        aPos.nNode = *pTxtNd;
113 //    else if( 0 == (pTxtNd = GetBodyTxtNode( *pDoc, aPos, *pFrm )) )
114 //        // kein TxtNode (Formatierung Kopf/Fusszeile)
115 //        return;
116 //    ChangeExpansion(*pTxtNd, bSrchNum);
117 //}
ChangeExpansion(const SwFrm * pFrm,const SwCntntNode * pCntntNode,sal_Bool bSrchNum)118 void SwChapterField::ChangeExpansion(const SwFrm* pFrm,
119                                       const SwCntntNode* pCntntNode,
120                                       sal_Bool bSrchNum )
121 {
122 	ASSERT( pFrm, "in welchem Frame stehe ich denn?" )
123     SwDoc* pDoc = (SwDoc*)pCntntNode->GetDoc();
124 
125     const SwTxtNode* pTxtNode = dynamic_cast<const SwTxtNode*>(pCntntNode);
126     if ( !pTxtNode || !pFrm->IsInDocBody() )
127     {
128         SwPosition aDummyPos( pDoc->GetNodes().GetEndOfContent() );
129         pTxtNode = GetBodyTxtNode( *pDoc, aDummyPos, *pFrm );
130     }
131 
132     if ( pTxtNode )
133     {
134         ChangeExpansion( *pTxtNode, bSrchNum );
135     }
136 }
137 // <--
138 
ChangeExpansion(const SwTxtNode & rTxtNd,sal_Bool bSrchNum)139 void SwChapterField::ChangeExpansion(const SwTxtNode &rTxtNd, sal_Bool bSrchNum)
140 {
141 	//i120759,this function is for both the reference chapter field and normal chapter field
142 	//bSrchNum can distinguish the two types,to the latter type,the outline num rule is must...
143 	sNumber = aEmptyStr;
144 	sTitle = aEmptyStr;
145 	sPost = aEmptyStr;
146 	sPre = aEmptyStr;
147 	//The reference chapter field of normal num rule will be handled in this code segment
148 	if (bSrchNum && !rTxtNd.IsOutline())
149 	{
150 		SwNumRule* pRule(rTxtNd.GetNumRule());
151 		if (rTxtNd.IsCountedInList() && pRule)
152 		{
153 			sNumber = rTxtNd.GetNumString(false);
154 			const SwNumFmt& rNFmt = pRule->Get(static_cast<unsigned short>(rTxtNd.GetActualListLevel()));
155 			sPost = rNFmt.GetSuffix();
156 			sPre = rNFmt.GetPrefix();
157 		}
158 		else
159 		{
160 			sNumber = String("??", RTL_TEXTENCODING_ASCII_US);
161 		}
162 		sTitle = rTxtNd.GetExpandTxt();
163 
164 		for( xub_StrLen i = 0; i < sTitle.Len(); ++i )
165 			if( ' ' > sTitle.GetChar( i ) )
166 				sTitle.Erase( i--, 1 );
167 	}else
168 	{
169 	//End
170 	SwDoc* pDoc = (SwDoc*)rTxtNd.GetDoc();
171 	const SwTxtNode *pTxtNd = rTxtNd.FindOutlineNodeOfLevel( nLevel );
172 	if( pTxtNd )
173 	{
174 		if( bSrchNum )
175 		{
176 			const SwTxtNode* pONd = pTxtNd;
177 			do {
178 				if( pONd && pONd->GetTxtColl() )
179 				{
180 					sal_uInt8 nPrevLvl = nLevel;
181 
182 					// --> OD 2008-04-02 #refactorlists#
183 //                    nLevel = GetRealLevel( pONd->GetTxtColl()->
184 //                                            GetOutlineLevel() );
185                     //ASSERT( pONd->GetOutlineLevel() >= 0 && pONd->GetOutlineLevel() < MAXLEVEL,	//#outline level,zhaojianwei
186                     //        "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect -> please inform OD." );
187                     //nLevel = static_cast<sal_uInt8>(pONd->GetOutlineLevel());
188                     ASSERT( pONd->GetAttrOutlineLevel() >= 0 && pONd->GetAttrOutlineLevel() <= MAXLEVEL,
189                             "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect -> please inform OD." );
190                     nLevel = static_cast<sal_uInt8>(pONd->GetAttrOutlineLevel());							//<-end,zhaojianwei
191                     // <--
192 
193 					if( nPrevLvl < nLevel )
194 						nLevel = nPrevLvl;
195 					else if( SVX_NUM_NUMBER_NONE != pDoc->GetOutlineNumRule()
196 							->Get( nLevel ).GetNumberingType() )
197 					{
198 						pTxtNd = pONd;
199 						break;
200 					}
201 
202 					if( !nLevel-- )
203 						break;
204 					pONd = pTxtNd->FindOutlineNodeOfLevel( nLevel );
205 				}
206 				else
207 					break;
208 			} while( sal_True );
209 		}
210 
211 		// nur die Nummer besorgen, ohne Pre-/Post-fixstrings
212 
213         if ( pTxtNd->IsOutline() )
214         {
215             // --> OD 2005-11-17 #128041#
216             // correction of refactoring done by cws swnumtree:
217             // retrieve numbering string without prefix and suffix strings
218             // as stated in the above german comment.
219             sNumber = pTxtNd->GetNumString( false );
220             // <--
221 
222             SwNumRule* pRule( pTxtNd->GetNumRule() );
223             if ( pTxtNd->IsCountedInList() && pRule )
224             {
225                 const SwNumFmt& rNFmt = pRule->Get( static_cast<sal_uInt16>(pTxtNd->GetActualListLevel()) );
226                 sPost = rNFmt.GetSuffix();
227                 sPre = rNFmt.GetPrefix();
228             }
229         }
230         else
231         {
232             sNumber = String("??", RTL_TEXTENCODING_ASCII_US);
233         }
234 
235 		sTitle = pTxtNd->GetExpandTxt();
236 
237 		for( xub_StrLen i = 0; i < sTitle.Len(); ++i )
238 			if( ' ' > sTitle.GetChar( i ) )
239 				sTitle.Erase( i--, 1 );
240 	}
241 	}
242 }
243 
244 /*-----------------05.03.98 16:19-------------------
245 
246 --------------------------------------------------*/
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const247 sal_Bool SwChapterField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
248 {
249     switch( nWhichId )
250 	{
251 	case FIELD_PROP_BYTE1:
252 		rAny <<= (sal_Int8)nLevel;
253 		break;
254 
255 	case FIELD_PROP_USHORT1:
256 		{
257 			sal_Int16 nRet;
258 			switch( GetFormat() )
259 			{
260 				case CF_NUMBER:	nRet = text::ChapterFormat::NUMBER; break;
261 				case CF_TITLE:  nRet = text::ChapterFormat::NAME; break;
262 				case CF_NUMBER_NOPREPST:
263 					nRet = text::ChapterFormat::DIGIT;
264 				break;
265 				case CF_NUM_NOPREPST_TITLE:
266 					nRet = text::ChapterFormat::NO_PREFIX_SUFFIX;
267 				break;
268 				case CF_NUM_TITLE:
269 				default:		nRet = text::ChapterFormat::NAME_NUMBER;
270 			}
271 			rAny <<= nRet;
272 		}
273 		break;
274 
275 	default:
276 		DBG_ERROR("illegal property");
277 	}
278 	return sal_True;
279 }
280 /*-----------------05.03.98 16:19-------------------
281 
282 --------------------------------------------------*/
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)283 sal_Bool SwChapterField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
284 {
285 	sal_Bool bRet = sal_True;
286     switch( nWhichId )
287 	{
288 	case FIELD_PROP_BYTE1:
289     {
290 		sal_Int8 nTmp = 0;
291 		rAny >>= nTmp;
292 		if(nTmp >= 0 && nTmp < MAXLEVEL)
293 			nLevel = nTmp;
294 		else
295 			bRet = sal_False;
296 		break;
297     }
298 
299 	case FIELD_PROP_USHORT1:
300 		{
301 			sal_Int16 nVal = 0;
302 			rAny >>= nVal;
303 			switch( nVal )
304 			{
305 				case text::ChapterFormat::NAME:	SetFormat(CF_TITLE); break;
306 				case text::ChapterFormat::NUMBER:  SetFormat(CF_NUMBER); break;
307 				case text::ChapterFormat::NO_PREFIX_SUFFIX:
308 							SetFormat(CF_NUM_NOPREPST_TITLE);
309 				break;
310 				case text::ChapterFormat::DIGIT:
311 						SetFormat(CF_NUMBER_NOPREPST);
312 				break;
313 				//case text::ChapterFormat::NAME_NUMBER:
314 				default:		SetFormat(CF_NUM_TITLE);
315 			}
316 		}
317 		break;
318 
319 	default:
320 		DBG_ERROR("illegal property");
321 		bRet = sal_False;
322 	}
323 	return bRet;
324 }
325