xref: /trunk/main/sw/source/core/doc/swserv.cxx (revision efeef26f)
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