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
SV_IMPL_REF(SwServerObject)46 SV_IMPL_REF( SwServerObject )
47
48 SwServerObject::~SwServerObject()
49 {
50 }
51
52
GetData(uno::Any & rData,const String & rMimeType,sal_Bool)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
SetData(const String &,const uno::Any &)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
SendDataChanged(const SwPosition & rPos)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
SendDataChanged(const SwPaM & rRange)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
IsLinkInServer(const SwBaseLink * pChkLnk) const212 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
SetNoServer()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
SetDdeBookmark(::sw::mark::IMark & rBookmark)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
SwDataChanged(const SwPaM & rPam,sal_uInt16 nTyp)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
SwDataChanged(SwDoc * pDc,const SwPosition & rPos,sal_uInt16 nTyp)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
~SwDataChanged()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