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