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