xref: /trunk/main/sw/source/core/txtnode/txtatr2.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 #include <hintids.hxx>
32 #include <hints.hxx>
33 #include <sfx2/objsh.hxx>
34 #include <editeng/xmlcnitm.hxx>
35 #include <editeng/twolinesitem.hxx>
36 #include <txtinet.hxx>
37 #include <txtatr.hxx>
38 #include <fchrfmt.hxx>
39 #include <fmtinfmt.hxx>
40 #include <charfmt.hxx>
41 #include <ndtxt.hxx>        // SwCharFmt, SwTxtNode
42 #include <poolfmt.hxx>      // RES_POOLCHR_INET_...
43 #include <doc.hxx>          // SwDoc
44 #include <fmtruby.hxx>
45 #include <fmtmeta.hxx>
46 
47 
48 TYPEINIT1(SwTxtINetFmt,SwClient);
49 TYPEINIT1(SwTxtRuby,SwClient);
50 
51 
52 /*************************************************************************
53  *                      class SwTxtCharFmt
54  *************************************************************************/
55 
56 SwTxtCharFmt::SwTxtCharFmt( SwFmtCharFmt& rAttr,
57                     xub_StrLen nStt, xub_StrLen nEnde )
58     : SwTxtAttrEnd( rAttr, nStt, nEnde )
59     , m_pTxtNode( 0 )
60     , m_nSortNumber( 0 )
61 {
62     rAttr.pTxtAttr = this;
63     SetCharFmtAttr( sal_True );
64 }
65 
66 SwTxtCharFmt::~SwTxtCharFmt( )
67 {
68 }
69 
70 void SwTxtCharFmt::ModifyNotification( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
71 {
72     sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
73     ASSERT(  isCHRATR(nWhich) || (RES_OBJECTDYING == nWhich)
74              || (RES_ATTRSET_CHG == nWhich) || (RES_FMT_CHG == nWhich),
75         "SwTxtCharFmt::Modify(): unknown Modify");
76 
77     if ( m_pTxtNode )
78     {
79         SwUpdateAttr aUpdateAttr( *GetStart(), *GetEnd(), nWhich );
80         m_pTxtNode->ModifyNotification( &aUpdateAttr, &aUpdateAttr );
81     }
82 }
83 
84 bool SwTxtCharFmt::GetInfo( SfxPoolItem& rInfo ) const
85 {
86     if ( RES_AUTOFMT_DOCNODE != rInfo.Which() || !m_pTxtNode ||
87         &m_pTxtNode->GetNodes() != static_cast<SwAutoFmtGetDocNode&>(rInfo).pNodes )
88     {
89         return true;
90     }
91 
92     static_cast<SwAutoFmtGetDocNode&>(rInfo).pCntntNode = m_pTxtNode;
93     return false;
94 }
95 
96 
97 /*************************************************************************
98  *                        class SwTxtAttrNesting
99  *************************************************************************/
100 
101 SwTxtAttrNesting::SwTxtAttrNesting( SfxPoolItem & i_rAttr,
102             const xub_StrLen i_nStart, const xub_StrLen i_nEnd )
103     : SwTxtAttrEnd( i_rAttr, i_nStart, i_nEnd )
104 {
105     SetDontExpand( true );  // never expand this attribute
106     // lock the expand flag: simple guarantee that nesting will not be
107     // invalidated by expand operations
108     SetLockExpandFlag( true );
109     SetDontExpandStartAttr( true );
110     SetNesting( true );
111 }
112 
113 SwTxtAttrNesting::~SwTxtAttrNesting()
114 {
115 }
116 
117 
118 /*************************************************************************
119  *                      class SwTxtINetFmt
120  *************************************************************************/
121 
122 SwTxtINetFmt::SwTxtINetFmt( SwFmtINetFmt& rAttr,
123                             xub_StrLen nStart, xub_StrLen nEnd )
124     : SwTxtAttrNesting( rAttr, nStart, nEnd )
125     , SwClient( 0 )
126     , m_pTxtNode( 0 )
127     , m_bVisited( false )
128     , m_bVisitedValid( false )
129 {
130     rAttr.pTxtAttr  = this;
131     SetCharFmtAttr( true );
132 }
133 
134 SwTxtINetFmt::~SwTxtINetFmt( )
135 {
136 }
137 
138 SwCharFmt* SwTxtINetFmt::GetCharFmt()
139 {
140     const SwFmtINetFmt& rFmt = SwTxtAttrEnd::GetINetFmt();
141     SwCharFmt* pRet = NULL;
142 
143     if( rFmt.GetValue().Len() )
144     {
145         const SwDoc* pDoc = GetTxtNode().GetDoc();
146         if( !IsVisitedValid() )
147         {
148             SetVisited( pDoc->IsVisitedURL( rFmt.GetValue() ) );
149             SetVisitedValid( true );
150         }
151         sal_uInt16 nId;
152         const String& rStr = IsVisited() ? rFmt.GetVisitedFmt()
153                                            : rFmt.GetINetFmt();
154         if( rStr.Len() )
155             nId = IsVisited() ? rFmt.GetVisitedFmtId() : rFmt.GetINetFmtId();
156         else
157             nId = static_cast<sal_uInt16>(IsVisited() ? RES_POOLCHR_INET_VISIT : RES_POOLCHR_INET_NORMAL);
158 
159         // JP 10.02.2000, Bug 72806: dont modify the doc for getting the
160         //      correct charstyle.
161         sal_Bool bResetMod = !pDoc->IsModified();
162         Link aOle2Lnk;
163         if( bResetMod )
164         {
165             aOle2Lnk = pDoc->GetOle2Link();
166             ((SwDoc*)pDoc)->SetOle2Link( Link() );
167         }
168 
169         pRet = IsPoolUserFmt( nId )
170                 ? ((SwDoc*)pDoc)->FindCharFmtByName( rStr )
171                 : ((SwDoc*)pDoc)->GetCharFmtFromPool( nId );
172 
173         if( bResetMod )
174         {
175             ((SwDoc*)pDoc)->ResetModified();
176             ((SwDoc*)pDoc)->SetOle2Link( aOle2Lnk );
177         }
178     }
179 
180     if( pRet )
181         pRet->Add( this );
182     else if( GetRegisteredIn() )
183         GetRegisteredInNonConst()->Remove( this );
184 
185     return pRet;
186 }
187 
188 void SwTxtINetFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
189 {
190     sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
191     ASSERT(  isCHRATR(nWhich) || (RES_OBJECTDYING == nWhich)
192              || (RES_ATTRSET_CHG == nWhich) || (RES_FMT_CHG == nWhich),
193         "SwTxtINetFmt::Modify(): unknown Modify");
194 
195     if ( m_pTxtNode )
196     {
197         SwUpdateAttr aUpdateAttr( *GetStart(), *GetEnd(), nWhich );
198         m_pTxtNode->ModifyNotification( &aUpdateAttr, &aUpdateAttr );
199     }
200 }
201 
202     // erfrage vom Modify Informationen
203 sal_Bool SwTxtINetFmt::GetInfo( SfxPoolItem& rInfo ) const
204 {
205     if ( RES_AUTOFMT_DOCNODE != rInfo.Which() || !m_pTxtNode ||
206         &m_pTxtNode->GetNodes() != static_cast<SwAutoFmtGetDocNode&>(rInfo).pNodes )
207     {
208         return sal_True;
209     }
210 
211     static_cast<SwAutoFmtGetDocNode&>(rInfo).pCntntNode = m_pTxtNode;
212     return sal_False;
213 }
214 
215 sal_Bool SwTxtINetFmt::IsProtect( ) const
216 {
217     return m_pTxtNode && m_pTxtNode->IsProtect();
218 }
219 
220 /*************************************************************************
221  *                      class SwTxtRuby
222  *************************************************************************/
223 
224 SwTxtRuby::SwTxtRuby( SwFmtRuby& rAttr,
225                       xub_StrLen nStart, xub_StrLen nEnd )
226     : SwTxtAttrNesting( rAttr, nStart, nEnd )
227     , SwClient( 0 )
228     , m_pTxtNode( 0 )
229 {
230     rAttr.pTxtAttr  = this;
231 }
232 
233 SwTxtRuby::~SwTxtRuby()
234 {
235 }
236 
237 void SwTxtRuby::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
238 {
239     sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
240     ASSERT(  isCHRATR(nWhich) || (RES_OBJECTDYING == nWhich)
241              || (RES_ATTRSET_CHG == nWhich) || (RES_FMT_CHG == nWhich),
242         "SwTxtRuby::Modify(): unknown Modify");
243 
244     if ( m_pTxtNode )
245     {
246         SwUpdateAttr aUpdateAttr( *GetStart(), *GetEnd(), nWhich );
247         m_pTxtNode->ModifyNotification( &aUpdateAttr, &aUpdateAttr );
248     }
249 }
250 
251 sal_Bool SwTxtRuby::GetInfo( SfxPoolItem& rInfo ) const
252 {
253     if( RES_AUTOFMT_DOCNODE != rInfo.Which() || !m_pTxtNode ||
254         &m_pTxtNode->GetNodes() != static_cast<SwAutoFmtGetDocNode&>(rInfo).pNodes )
255     {
256         return sal_True;
257     }
258 
259     static_cast<SwAutoFmtGetDocNode&>(rInfo).pCntntNode = m_pTxtNode;
260     return sal_False;
261 }
262 
263 SwCharFmt* SwTxtRuby::GetCharFmt()
264 {
265     const SwFmtRuby& rFmt = SwTxtAttrEnd::GetRuby();
266     SwCharFmt* pRet = 0;
267 
268     if( rFmt.GetText().Len() )
269     {
270         const SwDoc* pDoc = GetTxtNode().GetDoc();
271         const String& rStr = rFmt.GetCharFmtName();
272         sal_uInt16 nId = RES_POOLCHR_RUBYTEXT;
273         if ( rStr.Len() )
274             nId = rFmt.GetCharFmtId();
275 
276         // JP 10.02.2000, Bug 72806: dont modify the doc for getting the
277         //              correct charstyle.
278         sal_Bool bResetMod = !pDoc->IsModified();
279         Link aOle2Lnk;
280         if( bResetMod )
281         {
282             aOle2Lnk = pDoc->GetOle2Link();
283             ((SwDoc*)pDoc)->SetOle2Link( Link() );
284         }
285 
286         pRet = IsPoolUserFmt( nId )
287                 ? ((SwDoc*)pDoc)->FindCharFmtByName( rStr )
288                 : ((SwDoc*)pDoc)->GetCharFmtFromPool( nId );
289 
290         if( bResetMod )
291         {
292             ((SwDoc*)pDoc)->ResetModified();
293             ((SwDoc*)pDoc)->SetOle2Link( aOle2Lnk );
294         }
295     }
296 
297     if( pRet )
298         pRet->Add( this );
299     else if( GetRegisteredIn() )
300         GetRegisteredInNonConst()->Remove( this );
301 
302     return pRet;
303 }
304 
305 
306 /*************************************************************************
307  *                        class SwTxtMeta
308  *************************************************************************/
309 
310 SwTxtMeta *
311 SwTxtMeta::CreateTxtMeta(
312     ::sw::MetaFieldManager & i_rTargetDocManager,
313     SwTxtNode *const i_pTargetTxtNode,
314     SwFmtMeta & i_rAttr,
315     xub_StrLen const i_nStart, xub_StrLen const i_nEnd, bool const i_bIsCopy)
316 {
317     if (COPY == i_bIsCopy)
318     {   // i_rAttr is already cloned, now call DoCopy to copy the sw::Meta
319         OSL_ENSURE(i_pTargetTxtNode, "cannot copy Meta without target node");
320         i_rAttr.DoCopy(i_rTargetDocManager, *i_pTargetTxtNode);
321     }
322     SwTxtMeta *const pTxtMeta(new SwTxtMeta(i_rAttr, i_nStart, i_nEnd));
323     return pTxtMeta;
324 }
325 
326 SwTxtMeta::SwTxtMeta( SwFmtMeta & i_rAttr,
327         const xub_StrLen i_nStart, const xub_StrLen i_nEnd )
328     : SwTxtAttrNesting( i_rAttr, i_nStart, i_nEnd )
329 {
330     i_rAttr.SetTxtAttr( this );
331     SetHasDummyChar(true);
332 }
333 
334 SwTxtMeta::~SwTxtMeta()
335 {
336     SwFmtMeta & rFmtMeta( static_cast<SwFmtMeta &>(GetAttr()) );
337     if (rFmtMeta.GetTxtAttr() == this)
338     {
339         rFmtMeta.SetTxtAttr(0);
340     }
341 }
342 
343 void SwTxtMeta::ChgTxtNode(SwTxtNode * const pNode)
344 {
345     SwFmtMeta & rFmtMeta( static_cast<SwFmtMeta &>(GetAttr()) );
346     if (rFmtMeta.GetTxtAttr() == this)
347     {
348         rFmtMeta.NotifyChangeTxtNode(pNode);
349     }
350 }
351 
352