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