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 32 #include <sot/storage.hxx> 33 #include <sfx2/linkmgr.hxx> 34 #include <com/sun/star/uno/Sequence.h> 35 #include <doc.hxx> 36 #include <swtypes.hxx> 37 #include <swserv.hxx> 38 #include <swbaslnk.hxx> 39 #include <mvsave.hxx> 40 #include <IMark.hxx> 41 #include <bookmrk.hxx> 42 #include <pam.hxx> 43 #include <shellio.hxx> 44 #ifndef _SWERROR_H 45 #include <swerror.h> 46 #endif 47 48 using namespace ::com::sun::star; 49 50 SV_IMPL_REF( SwServerObject ) 51 52 SwServerObject::~SwServerObject() 53 { 54 } 55 56 57 sal_Bool SwServerObject::GetData( uno::Any & rData, 58 const String & rMimeType, sal_Bool ) 59 { 60 sal_Bool bRet = sal_False; 61 WriterRef xWrt; 62 switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) ) 63 { 64 case FORMAT_STRING: 65 ::GetASCWriter( aEmptyStr, String(), xWrt ); 66 break; 67 68 case FORMAT_RTF: 69 // mba: no BaseURL for data exchange 70 ::GetRTFWriter( aEmptyStr, String(), xWrt ); 71 break; 72 } 73 74 if( xWrt.Is() ) 75 { 76 SwPaM* pPam = 0; 77 switch( eType ) 78 { 79 case BOOKMARK_SERVER: 80 if( CNTNT_TYPE.pBkmk->IsExpanded() ) 81 { 82 // Bereich aufspannen 83 pPam = new SwPaM( CNTNT_TYPE.pBkmk->GetMarkPos(), 84 CNTNT_TYPE.pBkmk->GetOtherMarkPos() ); 85 } 86 break; 87 88 case TABLE_SERVER: 89 pPam = new SwPaM( *CNTNT_TYPE.pTblNd, 90 *CNTNT_TYPE.pTblNd->EndOfSectionNode() ); 91 break; 92 93 case SECTION_SERVER: 94 pPam = new SwPaM( SwPosition( *CNTNT_TYPE.pSectNd ) ); 95 pPam->Move( fnMoveForward ); 96 pPam->SetMark(); 97 pPam->GetPoint()->nNode = *CNTNT_TYPE.pSectNd->EndOfSectionNode(); 98 pPam->Move( fnMoveBackward ); 99 break; 100 case NONE_SERVER: break; 101 } 102 103 if( pPam ) 104 { 105 // Stream anlegen 106 SvMemoryStream aMemStm( 65535, 65535 ); 107 SwWriter aWrt( aMemStm, *pPam, sal_False ); 108 if( !IsError( aWrt.Write( xWrt )) ) 109 { 110 aMemStm << '\0'; // append a zero char 111 rData <<= uno::Sequence< sal_Int8 >( 112 (sal_Int8*)aMemStm.GetData(), 113 aMemStm.Seek( STREAM_SEEK_TO_END ) ); 114 bRet = sal_True; 115 } 116 117 delete pPam; 118 } 119 } 120 return bRet; 121 } 122 123 124 sal_Bool SwServerObject::SetData( const String & , 125 const uno::Any& ) 126 { 127 // set new data into the "server" -> at first nothing to do 128 return sal_False; 129 } 130 131 132 void SwServerObject::SendDataChanged( const SwPosition& rPos ) 133 { 134 // ist an unseren Aenderungen jemand interessiert ? 135 if( HasDataLinks() ) 136 { 137 int bCall = sal_False; 138 const SwStartNode* pNd = 0; 139 switch( eType ) 140 { 141 case BOOKMARK_SERVER: 142 if( CNTNT_TYPE.pBkmk->IsExpanded() ) 143 { 144 bCall = CNTNT_TYPE.pBkmk->GetMarkStart() <= rPos 145 && rPos < CNTNT_TYPE.pBkmk->GetMarkEnd(); 146 } 147 break; 148 149 case TABLE_SERVER: pNd = CNTNT_TYPE.pTblNd; break; 150 case SECTION_SERVER: pNd = CNTNT_TYPE.pSectNd; break; 151 case NONE_SERVER: break; 152 } 153 if( pNd ) 154 { 155 sal_uLong nNd = rPos.nNode.GetIndex(); 156 bCall = pNd->GetIndex() < nNd && nNd < pNd->EndOfSectionIndex(); 157 } 158 159 if( bCall ) 160 { 161 // Recursionen erkennen und flaggen 162 IsLinkInServer( 0 ); 163 SvLinkSource::NotifyDataChanged(); 164 } 165 } 166 // sonst melden wir uns ab !! 167 // ????? JP 27.06.95: geht das so ???? 168 // else 169 // Closed(); 170 } 171 172 173 void SwServerObject::SendDataChanged( const SwPaM& rRange ) 174 { 175 // ist an unseren Aenderungen jemand interessiert ? 176 if( HasDataLinks() ) 177 { 178 int bCall = sal_False; 179 const SwStartNode* pNd = 0; 180 const SwPosition* pStt = rRange.Start(), *pEnd = rRange.End(); 181 switch( eType ) 182 { 183 case BOOKMARK_SERVER: 184 if(CNTNT_TYPE.pBkmk->IsExpanded()) 185 { 186 bCall = *pStt <= CNTNT_TYPE.pBkmk->GetMarkEnd() 187 && *pEnd > CNTNT_TYPE.pBkmk->GetMarkStart(); 188 } 189 break; 190 191 case TABLE_SERVER: pNd = CNTNT_TYPE.pTblNd; break; 192 case SECTION_SERVER: pNd = CNTNT_TYPE.pSectNd; break; 193 case NONE_SERVER: break; 194 } 195 if( pNd ) 196 { 197 // liegt der Start-Bereich im Node Bereich ? 198 bCall = pStt->nNode.GetIndex() < pNd->EndOfSectionIndex() && 199 pEnd->nNode.GetIndex() >= pNd->GetIndex(); 200 } 201 202 if( bCall ) 203 { 204 // Recursionen erkennen und flaggen 205 IsLinkInServer( 0 ); 206 SvLinkSource::NotifyDataChanged(); 207 } 208 } 209 // sonst melden wir uns ab !! 210 // ????? JP 27.06.95: geht das so ???? 211 // else 212 // Closed(); 213 } 214 215 216 sal_Bool SwServerObject::IsLinkInServer( const SwBaseLink* pChkLnk ) const 217 { 218 sal_uLong nSttNd = 0, nEndNd = 0; 219 xub_StrLen nStt = 0; 220 xub_StrLen nEnd = 0; 221 const SwNode* pNd = 0; 222 const SwNodes* pNds = 0; 223 224 switch( eType ) 225 { 226 case BOOKMARK_SERVER: 227 if( CNTNT_TYPE.pBkmk->IsExpanded() ) 228 { 229 const SwPosition* pStt = &CNTNT_TYPE.pBkmk->GetMarkStart(), 230 * pEnd = &CNTNT_TYPE.pBkmk->GetMarkEnd(); 231 232 nSttNd = pStt->nNode.GetIndex(); 233 nStt = pStt->nContent.GetIndex(); 234 nEndNd = pEnd->nNode.GetIndex(); 235 nEnd = pEnd->nContent.GetIndex(); 236 pNds = &pStt->nNode.GetNodes(); 237 } 238 break; 239 240 case TABLE_SERVER: pNd = CNTNT_TYPE.pTblNd; break; 241 case SECTION_SERVER: pNd = CNTNT_TYPE.pSectNd; break; 242 243 case SECTION_SERVER+1: 244 return sal_True; 245 } 246 247 if( pNd ) 248 { 249 nSttNd = pNd->GetIndex(); 250 nEndNd = pNd->EndOfSectionIndex(); 251 nStt = 0, nEnd = USHRT_MAX; 252 pNds = &pNd->GetNodes(); 253 } 254 255 if( nSttNd && nEndNd ) 256 { 257 // LinkManager besorgen: 258 const ::sfx2::SvBaseLinks& rLnks = pNds->GetDoc()->GetLinkManager().GetLinks(); 259 260 // um Rekursionen zu Verhindern: ServerType umsetzen! 261 SwServerObject::ServerModes eSave = eType; 262 if( !pChkLnk ) 263 // sowas sollte man nicht tun, wer weiss schon, wie gross ein enum ist 264 // ICC nimmt keinen int 265 // #41723# 266 // *((int*)&eType) = SECTION_SERVER+1; 267 ((SwServerObject*)this)->eType = NONE_SERVER; 268 for( sal_uInt16 n = rLnks.Count(); n; ) 269 { 270 const ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]); 271 if( pLnk && OBJECT_CLIENT_GRF != pLnk->GetObjType() && 272 pLnk->ISA( SwBaseLink ) && 273 !((SwBaseLink*)pLnk)->IsNoDataFlag() && 274 ((SwBaseLink*)pLnk)->IsInRange( nSttNd, nEndNd, nStt, nEnd )) 275 { 276 if( pChkLnk ) 277 { 278 if( pLnk == pChkLnk || 279 ((SwBaseLink*)pLnk)->IsRecursion( pChkLnk ) ) 280 return sal_True; 281 } 282 else if( ((SwBaseLink*)pLnk)->IsRecursion( (SwBaseLink*)pLnk ) ) 283 ((SwBaseLink*)pLnk)->SetNoDataFlag(); 284 } 285 } 286 if( !pChkLnk ) 287 // *((int*)&eType) = eSave; 288 ((SwServerObject*)this)->eType = eSave; 289 } 290 291 return sal_False; 292 } 293 294 void SwServerObject::SetNoServer() 295 { 296 if(eType == BOOKMARK_SERVER && CNTNT_TYPE.pBkmk) 297 { 298 ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(CNTNT_TYPE.pBkmk); 299 if(pDdeBookmark) 300 { 301 CNTNT_TYPE.pBkmk = 0, eType = NONE_SERVER; 302 pDdeBookmark->SetRefObject(NULL); 303 } 304 } 305 } 306 307 void SwServerObject::SetDdeBookmark( ::sw::mark::IMark& rBookmark) 308 { 309 ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(&rBookmark); 310 if(pDdeBookmark) 311 { 312 eType = BOOKMARK_SERVER; 313 CNTNT_TYPE.pBkmk = &rBookmark; 314 pDdeBookmark->SetRefObject(this); 315 } 316 else 317 OSL_ENSURE(false, 318 "SwServerObject::SetNoServer(..)" 319 " - setting an bookmark that is not DDE-capable"); 320 } 321 322 /* */ 323 324 325 SwDataChanged::SwDataChanged( const SwPaM& rPam, sal_uInt16 nTyp ) 326 : pPam( &rPam ), pPos( 0 ), pDoc( rPam.GetDoc() ), nType( nTyp ) 327 { 328 nNode = rPam.GetPoint()->nNode.GetIndex(); 329 nCntnt = rPam.GetPoint()->nContent.GetIndex(); 330 } 331 332 333 SwDataChanged::SwDataChanged( SwDoc* pDc, const SwPosition& rPos, sal_uInt16 nTyp ) 334 : pPam( 0 ), pPos( &rPos ), pDoc( pDc ), nType( nTyp ) 335 { 336 nNode = rPos.nNode.GetIndex(); 337 nCntnt = rPos.nContent.GetIndex(); 338 } 339 340 SwDataChanged::~SwDataChanged() 341 { 342 // JP 09.04.96: nur wenn das Layout vorhanden ist ( also waehrend der 343 // Eingabe) 344 if( pDoc->GetCurrentViewShell() ) //swmod 071108//swmod 071225 345 { 346 const ::sfx2::SvLinkSources& rServers = pDoc->GetLinkManager().GetServers(); 347 348 for( sal_uInt16 nCnt = rServers.Count(); nCnt; ) 349 { 350 ::sfx2::SvLinkSourceRef refObj( rServers[ --nCnt ] ); 351 // noch jemand am Object interessiert ? 352 if( refObj->HasDataLinks() && refObj->ISA( SwServerObject )) 353 { 354 SwServerObject& rObj = *(SwServerObject*)&refObj; 355 if( pPos ) 356 rObj.SendDataChanged( *pPos ); 357 else 358 rObj.SendDataChanged( *pPam ); 359 } 360 361 // sollte jetzt gar keine Verbindung mehr bestehen 362 if( !refObj->HasDataLinks() ) 363 { 364 // dann raus aus der Liste (Object bleibt aber bestehen!) 365 // falls es noch da ist !! 366 if( nCnt < rServers.Count() && &refObj == rServers[ nCnt ] ) 367 pDoc->GetLinkManager().RemoveServer( nCnt, 1 ); 368 } 369 } 370 } 371 } 372