xref: /trunk/main/sw/source/core/fields/chpfld.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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