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