xref: /aoo41x/main/sw/source/core/txtnode/txtatr2.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 #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