xref: /aoo42x/main/sw/source/core/fields/chpfld.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <com/sun/star/text/ChapterFormat.hpp>
33 #include <doc.hxx>
34 #include <frame.hxx>		// SwChapterFieldType::ChangeExpansion()
35 #include <pam.hxx>			// fuer GetBodyTxtNode
36 #include <ndtxt.hxx>
37 #include <chpfld.hxx>
38 #include <expfld.hxx>		// fuer GetBodyTxtNode
39 #ifndef _UNOFLDMID_H
40 #include <unofldmid.h>
41 #endif
42 #include <numrule.hxx>
43 
44 using namespace ::com::sun::star;
45 
46 /*--------------------------------------------------------------------
47 	Beschreibung: SwChapterFieldType
48  --------------------------------------------------------------------*/
49 
50 
51 SwChapterFieldType::SwChapterFieldType()
52 	: SwFieldType( RES_CHAPTERFLD )
53 {
54 }
55 
56 
57 SwFieldType* SwChapterFieldType::Copy() const
58 {
59 	return new SwChapterFieldType();
60 }
61 
62 
63 /*--------------------------------------------------------------------
64 	Beschreibung: Kapittelfeld
65  --------------------------------------------------------------------*/
66 
67 
68 SwChapterField::SwChapterField(SwChapterFieldType* pTyp, sal_uInt32 nFmt)
69 	: SwField(pTyp, nFmt), nLevel( 0 )
70 {}
71 
72 
73 String SwChapterField::Expand() const
74 {
75 	String sStr( sNumber );
76 	switch( GetFormat() )
77 	{
78 		case CF_TITLE:		sStr = sTitle;	break;
79 
80 		case CF_NUMBER:
81 		case CF_NUM_TITLE:  sStr.Insert( sPre, 0 );
82 							sStr += sPost;
83 							if( CF_NUM_TITLE == GetFormat() )
84 								sStr += sTitle;
85 							break;
86 
87 		case CF_NUM_NOPREPST_TITLE:	sStr += sTitle;	break;
88 	}
89 	return sStr;
90 }
91 
92 
93 SwField* SwChapterField::Copy() const
94 {
95 	SwChapterField *pTmp =
96 		new SwChapterField((SwChapterFieldType*)GetTyp(), GetFormat());
97 	pTmp->nLevel = nLevel;
98 	pTmp->sTitle = sTitle;
99 	pTmp->sNumber = sNumber;
100 	pTmp->sPost = sPost;
101 	pTmp->sPre = sPre;
102 
103 	return pTmp;
104 }
105 
106 // --> OD 2008-02-14 #i53420#
107 //void SwChapterField::ChangeExpansion( const SwFrm* pFrm,
108 //                                      const SwTxtNode* pTxtNd,
109 //                                      sal_Bool bSrchNum )
110 //{
111 //    ASSERT( pFrm, "in welchem Frame stehe ich denn?" )
112 //    SwDoc* pDoc = (SwDoc*)pTxtNd->GetDoc();
113 //    SwPosition aPos( pDoc->GetNodes().GetEndOfContent() );
114 
115 //    if( pFrm->IsInDocBody() )
116 //        aPos.nNode = *pTxtNd;
117 //    else if( 0 == (pTxtNd = GetBodyTxtNode( *pDoc, aPos, *pFrm )) )
118 //        // kein TxtNode (Formatierung Kopf/Fusszeile)
119 //        return;
120 //    ChangeExpansion(*pTxtNd, bSrchNum);
121 //}
122 void SwChapterField::ChangeExpansion(const SwFrm* pFrm,
123                                       const SwCntntNode* pCntntNode,
124                                       sal_Bool bSrchNum )
125 {
126 	ASSERT( pFrm, "in welchem Frame stehe ich denn?" )
127     SwDoc* pDoc = (SwDoc*)pCntntNode->GetDoc();
128 
129     const SwTxtNode* pTxtNode = dynamic_cast<const SwTxtNode*>(pCntntNode);
130     if ( !pTxtNode || !pFrm->IsInDocBody() )
131     {
132         SwPosition aDummyPos( pDoc->GetNodes().GetEndOfContent() );
133         pTxtNode = GetBodyTxtNode( *pDoc, aDummyPos, *pFrm );
134     }
135 
136     if ( pTxtNode )
137     {
138         ChangeExpansion( *pTxtNode, bSrchNum );
139     }
140 }
141 // <--
142 
143 void SwChapterField::ChangeExpansion(const SwTxtNode &rTxtNd, sal_Bool bSrchNum)
144 {
145 	SwDoc* pDoc = (SwDoc*)rTxtNd.GetDoc();
146 	const SwTxtNode *pTxtNd = rTxtNd.FindOutlineNodeOfLevel( nLevel );
147 	if( pTxtNd )
148 	{
149 		if( bSrchNum )
150 		{
151 			const SwTxtNode* pONd = pTxtNd;
152 			do {
153 				if( pONd && pONd->GetTxtColl() )
154 				{
155 					sal_uInt8 nPrevLvl = nLevel;
156 
157 					// --> OD 2008-04-02 #refactorlists#
158 //                    nLevel = GetRealLevel( pONd->GetTxtColl()->
159 //                                            GetOutlineLevel() );
160                     //ASSERT( pONd->GetOutlineLevel() >= 0 && pONd->GetOutlineLevel() < MAXLEVEL,	//#outline level,zhaojianwei
161                     //        "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect -> please inform OD." );
162                     //nLevel = static_cast<sal_uInt8>(pONd->GetOutlineLevel());
163                     ASSERT( pONd->GetAttrOutlineLevel() >= 0 && pONd->GetAttrOutlineLevel() <= MAXLEVEL,
164                             "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect -> please inform OD." );
165                     nLevel = static_cast<sal_uInt8>(pONd->GetAttrOutlineLevel());							//<-end,zhaojianwei
166                     // <--
167 
168 					if( nPrevLvl < nLevel )
169 						nLevel = nPrevLvl;
170 					else if( SVX_NUM_NUMBER_NONE != pDoc->GetOutlineNumRule()
171 							->Get( nLevel ).GetNumberingType() )
172 					{
173 						pTxtNd = pONd;
174 						break;
175 					}
176 
177 					if( !nLevel-- )
178 						break;
179 					pONd = pTxtNd->FindOutlineNodeOfLevel( nLevel );
180 				}
181 				else
182 					break;
183 			} while( sal_True );
184 		}
185 
186 		// nur die Nummer besorgen, ohne Pre-/Post-fixstrings
187 
188         if ( pTxtNd->IsOutline() )
189         {
190             // --> OD 2005-11-17 #128041#
191             // correction of refactoring done by cws swnumtree:
192             // retrieve numbering string without prefix and suffix strings
193             // as stated in the above german comment.
194             sNumber = pTxtNd->GetNumString( false );
195             // <--
196 
197             SwNumRule* pRule( pTxtNd->GetNumRule() );
198             if ( pTxtNd->IsCountedInList() && pRule )
199             {
200                 const SwNumFmt& rNFmt = pRule->Get( static_cast<sal_uInt16>(pTxtNd->GetActualListLevel()) );
201                 sPost = rNFmt.GetSuffix();
202                 sPre = rNFmt.GetPrefix();
203             }
204             else
205                 sPost = aEmptyStr, sPre = aEmptyStr;
206         }
207         else
208         {
209             sPost = aEmptyStr;
210             sPre = aEmptyStr;
211             sNumber = String("??", RTL_TEXTENCODING_ASCII_US);
212         }
213 
214 		sTitle = pTxtNd->GetExpandTxt();
215 
216 		for( xub_StrLen i = 0; i < sTitle.Len(); ++i )
217 			if( ' ' > sTitle.GetChar( i ) )
218 				sTitle.Erase( i--, 1 );
219 	}
220 	else
221 	{
222 		sNumber = aEmptyStr;
223 		sTitle = aEmptyStr;
224 		sPost = aEmptyStr;
225 		sPre = aEmptyStr;
226 	}
227 }
228 
229 /*-----------------05.03.98 16:19-------------------
230 
231 --------------------------------------------------*/
232 sal_Bool SwChapterField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
233 {
234     switch( nWhichId )
235 	{
236 	case FIELD_PROP_BYTE1:
237 		rAny <<= (sal_Int8)nLevel;
238 		break;
239 
240 	case FIELD_PROP_USHORT1:
241 		{
242 			sal_Int16 nRet;
243 			switch( GetFormat() )
244 			{
245 				case CF_NUMBER:	nRet = text::ChapterFormat::NUMBER; break;
246 				case CF_TITLE:  nRet = text::ChapterFormat::NAME; break;
247 				case CF_NUMBER_NOPREPST:
248 					nRet = text::ChapterFormat::DIGIT;
249 				break;
250 				case CF_NUM_NOPREPST_TITLE:
251 					nRet = text::ChapterFormat::NO_PREFIX_SUFFIX;
252 				break;
253 				case CF_NUM_TITLE:
254 				default:		nRet = text::ChapterFormat::NAME_NUMBER;
255 			}
256 			rAny <<= nRet;
257 		}
258 		break;
259 
260 	default:
261 		DBG_ERROR("illegal property");
262 	}
263 	return sal_True;
264 }
265 /*-----------------05.03.98 16:19-------------------
266 
267 --------------------------------------------------*/
268 sal_Bool SwChapterField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
269 {
270 	sal_Bool bRet = sal_True;
271     switch( nWhichId )
272 	{
273 	case FIELD_PROP_BYTE1:
274     {
275 		sal_Int8 nTmp = 0;
276 		rAny >>= nTmp;
277 		if(nTmp >= 0 && nTmp < MAXLEVEL)
278 			nLevel = nTmp;
279 		else
280 			bRet = sal_False;
281 		break;
282     }
283 
284 	case FIELD_PROP_USHORT1:
285 		{
286 			sal_Int16 nVal = 0;
287 			rAny >>= nVal;
288 			switch( nVal )
289 			{
290 				case text::ChapterFormat::NAME:	SetFormat(CF_TITLE); break;
291 				case text::ChapterFormat::NUMBER:  SetFormat(CF_NUMBER); break;
292 				case text::ChapterFormat::NO_PREFIX_SUFFIX:
293 							SetFormat(CF_NUM_NOPREPST_TITLE);
294 				break;
295 				case text::ChapterFormat::DIGIT:
296 						SetFormat(CF_NUMBER_NOPREPST);
297 				break;
298 				//case text::ChapterFormat::NAME_NUMBER:
299 				default:		SetFormat(CF_NUM_TITLE);
300 			}
301 		}
302 		break;
303 
304 	default:
305 		DBG_ERROR("illegal property");
306 		bRet = sal_False;
307 	}
308 	return bRet;
309 }
310