Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sot/storage.hxx>
21 : #include <sfx2/linkmgr.hxx>
22 : #include <com/sun/star/uno/Sequence.h>
23 : #include <doc.hxx>
24 : #include <swtypes.hxx>
25 : #include <swserv.hxx>
26 : #include <swbaslnk.hxx>
27 : #include <mvsave.hxx>
28 : #include <IMark.hxx>
29 : #include <bookmrk.hxx>
30 : #include <pam.hxx>
31 : #include <shellio.hxx>
32 : #include <swerror.h>
33 :
34 : using namespace ::com::sun::star;
35 :
36 : SV_IMPL_REF( SwServerObject )
37 :
38 0 : SwServerObject::~SwServerObject()
39 : {
40 0 : }
41 :
42 :
43 0 : sal_Bool SwServerObject::GetData( uno::Any & rData,
44 : const String & rMimeType, sal_Bool )
45 : {
46 0 : sal_Bool bRet = sal_False;
47 0 : WriterRef xWrt;
48 0 : switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
49 : {
50 : case FORMAT_STRING:
51 0 : ::GetASCWriter( aEmptyStr, String(), xWrt );
52 0 : break;
53 :
54 : case FORMAT_RTF:
55 : // mba: no BaseURL for data exchange
56 0 : ::GetRTFWriter( aEmptyStr, String(), xWrt );
57 0 : break;
58 : }
59 :
60 0 : if( xWrt.Is() )
61 : {
62 0 : SwPaM* pPam = 0;
63 0 : switch( eType )
64 : {
65 : case BOOKMARK_SERVER:
66 0 : if( CNTNT_TYPE.pBkmk->IsExpanded() )
67 : {
68 : // Span area
69 0 : pPam = new SwPaM( CNTNT_TYPE.pBkmk->GetMarkPos(),
70 0 : CNTNT_TYPE.pBkmk->GetOtherMarkPos() );
71 : }
72 0 : break;
73 :
74 : case TABLE_SERVER:
75 : pPam = new SwPaM( *CNTNT_TYPE.pTblNd,
76 0 : *CNTNT_TYPE.pTblNd->EndOfSectionNode() );
77 0 : break;
78 :
79 : case SECTION_SERVER:
80 0 : pPam = new SwPaM( SwPosition( *CNTNT_TYPE.pSectNd ) );
81 0 : pPam->Move( fnMoveForward );
82 0 : pPam->SetMark();
83 0 : pPam->GetPoint()->nNode = *CNTNT_TYPE.pSectNd->EndOfSectionNode();
84 0 : pPam->Move( fnMoveBackward );
85 0 : break;
86 0 : case NONE_SERVER: break;
87 : }
88 :
89 0 : if( pPam )
90 : {
91 : // Create stream
92 0 : SvMemoryStream aMemStm( 65535, 65535 );
93 0 : SwWriter aWrt( aMemStm, *pPam, sal_False );
94 0 : if( !IsError( aWrt.Write( xWrt )) )
95 : {
96 0 : aMemStm << '\0'; // append a zero char
97 : rData <<= uno::Sequence< sal_Int8 >(
98 0 : (sal_Int8*)aMemStm.GetData(),
99 0 : aMemStm.Seek( STREAM_SEEK_TO_END ) );
100 0 : bRet = sal_True;
101 : }
102 :
103 0 : delete pPam;
104 : }
105 : }
106 0 : return bRet;
107 : }
108 :
109 :
110 0 : sal_Bool SwServerObject::SetData( const String & ,
111 : const uno::Any& )
112 : {
113 : // set new data into the "server" -> at first nothing to do
114 0 : return sal_False;
115 : }
116 :
117 :
118 0 : void SwServerObject::SendDataChanged( const SwPosition& rPos )
119 : {
120 : // Is someone interested in our changes?
121 0 : if( HasDataLinks() )
122 : {
123 0 : int bCall = sal_False;
124 0 : const SwStartNode* pNd = 0;
125 0 : switch( eType )
126 : {
127 : case BOOKMARK_SERVER:
128 0 : if( CNTNT_TYPE.pBkmk->IsExpanded() )
129 : {
130 0 : bCall = CNTNT_TYPE.pBkmk->GetMarkStart() <= rPos
131 0 : && rPos < CNTNT_TYPE.pBkmk->GetMarkEnd();
132 : }
133 0 : break;
134 :
135 0 : case TABLE_SERVER: pNd = CNTNT_TYPE.pTblNd; break;
136 0 : case SECTION_SERVER: pNd = CNTNT_TYPE.pSectNd; break;
137 0 : case NONE_SERVER: break;
138 : }
139 0 : if( pNd )
140 : {
141 0 : sal_uLong nNd = rPos.nNode.GetIndex();
142 0 : bCall = pNd->GetIndex() < nNd && nNd < pNd->EndOfSectionIndex();
143 : }
144 :
145 0 : if( bCall )
146 : {
147 : // Recognize recursions and flag them
148 0 : IsLinkInServer( 0 );
149 0 : SvLinkSource::NotifyDataChanged();
150 : }
151 : }
152 0 : }
153 :
154 :
155 0 : void SwServerObject::SendDataChanged( const SwPaM& rRange )
156 : {
157 : // Is someone interested in our changes?
158 0 : if( HasDataLinks() )
159 : {
160 0 : int bCall = sal_False;
161 0 : const SwStartNode* pNd = 0;
162 0 : const SwPosition* pStt = rRange.Start(), *pEnd = rRange.End();
163 0 : switch( eType )
164 : {
165 : case BOOKMARK_SERVER:
166 0 : if(CNTNT_TYPE.pBkmk->IsExpanded())
167 : {
168 0 : bCall = *pStt <= CNTNT_TYPE.pBkmk->GetMarkEnd()
169 0 : && *pEnd > CNTNT_TYPE.pBkmk->GetMarkStart();
170 : }
171 0 : break;
172 :
173 0 : case TABLE_SERVER: pNd = CNTNT_TYPE.pTblNd; break;
174 0 : case SECTION_SERVER: pNd = CNTNT_TYPE.pSectNd; break;
175 0 : case NONE_SERVER: break;
176 : }
177 0 : if( pNd )
178 : {
179 : // Is the start area within the node area?
180 0 : bCall = pStt->nNode.GetIndex() < pNd->EndOfSectionIndex() &&
181 0 : pEnd->nNode.GetIndex() >= pNd->GetIndex();
182 : }
183 :
184 0 : if( bCall )
185 : {
186 : // Recognize recursions and flag them
187 0 : IsLinkInServer( 0 );
188 0 : SvLinkSource::NotifyDataChanged();
189 : }
190 : }
191 0 : }
192 :
193 :
194 0 : sal_Bool SwServerObject::IsLinkInServer( const SwBaseLink* pChkLnk ) const
195 : {
196 0 : sal_uLong nSttNd = 0, nEndNd = 0;
197 0 : xub_StrLen nStt = 0;
198 0 : xub_StrLen nEnd = 0;
199 0 : const SwNode* pNd = 0;
200 0 : const SwNodes* pNds = 0;
201 :
202 0 : switch( eType )
203 : {
204 : case BOOKMARK_SERVER:
205 0 : if( CNTNT_TYPE.pBkmk->IsExpanded() )
206 : {
207 0 : const SwPosition* pStt = &CNTNT_TYPE.pBkmk->GetMarkStart(),
208 0 : * pEnd = &CNTNT_TYPE.pBkmk->GetMarkEnd();
209 :
210 0 : nSttNd = pStt->nNode.GetIndex();
211 0 : nStt = pStt->nContent.GetIndex();
212 0 : nEndNd = pEnd->nNode.GetIndex();
213 0 : nEnd = pEnd->nContent.GetIndex();
214 0 : pNds = &pStt->nNode.GetNodes();
215 : }
216 0 : break;
217 :
218 0 : case TABLE_SERVER: pNd = CNTNT_TYPE.pTblNd; break;
219 0 : case SECTION_SERVER: pNd = CNTNT_TYPE.pSectNd; break;
220 :
221 : case SECTION_SERVER+1:
222 0 : return sal_True;
223 : }
224 :
225 0 : if( pNd )
226 : {
227 0 : nSttNd = pNd->GetIndex();
228 0 : nEndNd = pNd->EndOfSectionIndex();
229 0 : nStt = 0, nEnd = USHRT_MAX;
230 0 : pNds = &pNd->GetNodes();
231 : }
232 :
233 0 : if( nSttNd && nEndNd )
234 : {
235 : // Get LinkManager
236 0 : const ::sfx2::SvBaseLinks& rLnks = pNds->GetDoc()->GetLinkManager().GetLinks();
237 :
238 : // To avoid recursions: convert ServerType!
239 0 : SwServerObject::ServerModes eSave = eType;
240 0 : if( !pChkLnk )
241 0 : ((SwServerObject*)this)->eType = NONE_SERVER;
242 0 : for( sal_uInt16 n = rLnks.size(); n; )
243 : {
244 0 : const ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]);
245 0 : if( pLnk && OBJECT_CLIENT_GRF != pLnk->GetObjType() &&
246 0 : pLnk->ISA( SwBaseLink ) &&
247 0 : !((SwBaseLink*)pLnk)->IsNoDataFlag() &&
248 0 : ((SwBaseLink*)pLnk)->IsInRange( nSttNd, nEndNd, nStt, nEnd ))
249 : {
250 0 : if( pChkLnk )
251 : {
252 0 : if( pLnk == pChkLnk ||
253 0 : ((SwBaseLink*)pLnk)->IsRecursion( pChkLnk ) )
254 0 : return sal_True;
255 : }
256 0 : else if( ((SwBaseLink*)pLnk)->IsRecursion( (SwBaseLink*)pLnk ) )
257 0 : ((SwBaseLink*)pLnk)->SetNoDataFlag();
258 : }
259 : }
260 0 : if( !pChkLnk )
261 : // *((int*)&eType) = eSave;
262 0 : ((SwServerObject*)this)->eType = eSave;
263 : }
264 :
265 0 : return sal_False;
266 : }
267 :
268 0 : void SwServerObject::SetNoServer()
269 : {
270 0 : if(eType == BOOKMARK_SERVER && CNTNT_TYPE.pBkmk)
271 : {
272 0 : ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(CNTNT_TYPE.pBkmk);
273 0 : if(pDdeBookmark)
274 : {
275 0 : CNTNT_TYPE.pBkmk = 0, eType = NONE_SERVER;
276 0 : pDdeBookmark->SetRefObject(NULL);
277 : }
278 : }
279 0 : }
280 :
281 0 : void SwServerObject::SetDdeBookmark( ::sw::mark::IMark& rBookmark)
282 : {
283 0 : ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(&rBookmark);
284 0 : if(pDdeBookmark)
285 : {
286 0 : eType = BOOKMARK_SERVER;
287 0 : CNTNT_TYPE.pBkmk = &rBookmark;
288 0 : pDdeBookmark->SetRefObject(this);
289 : }
290 : else
291 : OSL_FAIL("SwServerObject::SetNoServer(..)"
292 : " - setting an bookmark that is not DDE-capable");
293 0 : }
294 :
295 :
296 :
297 132232 : SwDataChanged::SwDataChanged( const SwPaM& rPam )
298 132232 : : pPam( &rPam ), pPos( 0 ), pDoc( rPam.GetDoc() )
299 : {
300 132232 : nNode = rPam.GetPoint()->nNode.GetIndex();
301 132232 : nCntnt = rPam.GetPoint()->nContent.GetIndex();
302 132232 : }
303 :
304 :
305 540 : SwDataChanged::SwDataChanged( SwDoc* pDc, const SwPosition& rPos )
306 540 : : pPam( 0 ), pPos( &rPos ), pDoc( pDc )
307 : {
308 540 : nNode = rPos.nNode.GetIndex();
309 540 : nCntnt = rPos.nContent.GetIndex();
310 540 : }
311 :
312 132772 : SwDataChanged::~SwDataChanged()
313 : {
314 : // JP 09.04.96: Only if the Layout is available (thus during input)
315 132772 : if( pDoc->GetCurrentViewShell() ) //swmod 071108//swmod 071225
316 : {
317 2 : const ::sfx2::SvLinkSources& rServers = pDoc->GetLinkManager().GetServers();
318 :
319 2 : ::sfx2::SvLinkSources aTemp(rServers);
320 2 : for( ::sfx2::SvLinkSources::const_iterator it = aTemp.begin(); it != aTemp.end(); ++it )
321 : {
322 0 : ::sfx2::SvLinkSourceRef refObj( *it );
323 : // Any one else interested in the Object?
324 0 : if( refObj->HasDataLinks() && refObj->ISA( SwServerObject ))
325 : {
326 0 : SwServerObject& rObj = *(SwServerObject*)&refObj;
327 0 : if( pPos )
328 0 : rObj.SendDataChanged( *pPos );
329 : else
330 0 : rObj.SendDataChanged( *pPam );
331 : }
332 :
333 : // We shouldn't have a connection anymore
334 0 : if( !refObj->HasDataLinks() )
335 : {
336 : // Then remove from the list
337 0 : pDoc->GetLinkManager().RemoveServer( *it );
338 : }
339 2 : }
340 : }
341 132772 : }
342 :
343 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|