LibreOffice Module sw (master)  1
swserv.cxx
Go to the documentation of this file.
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 <sot/exchange.hxx>
22 #include <sfx2/linkmgr.hxx>
23 #include <com/sun/star/uno/Sequence.h>
24 #include <doc.hxx>
27 #include <swtypes.hxx>
28 #include <swserv.hxx>
29 #include <swbaslnk.hxx>
30 #include <mvsave.hxx>
31 #include <IMark.hxx>
32 #include <bookmrk.hxx>
33 #include <pam.hxx>
34 #include <shellio.hxx>
35 #include <swerror.h>
36 
37 using namespace ::com::sun::star;
38 
40 {
41 }
42 
44  const OUString & rMimeType, bool )
45 {
46  bool bRet = false;
47  WriterRef xWrt;
48  switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
49  {
50  case SotClipboardFormatId::STRING:
51  ::GetASCWriter( OUString(), OUString(), xWrt );
52  break;
53 
54  case SotClipboardFormatId::RTF:
55  case SotClipboardFormatId::RICHTEXT:
56  // mba: no BaseURL for data exchange
57  ::GetRTFWriter( OUString(), OUString(), xWrt );
58  break;
59  default: break;
60  }
61 
62  if( xWrt.is() )
63  {
64  SwPaM* pPam = nullptr;
65  switch( m_eType )
66  {
67  case BOOKMARK_SERVER:
68  if( m_CNTNT_TYPE.pBkmk->IsExpanded() )
69  {
70  // Span area
71  pPam = new SwPaM( m_CNTNT_TYPE.pBkmk->GetMarkPos(),
72  m_CNTNT_TYPE.pBkmk->GetOtherMarkPos() );
73  }
74  break;
75 
76  case TABLE_SERVER:
77  pPam = new SwPaM( *m_CNTNT_TYPE.pTableNd,
78  *m_CNTNT_TYPE.pTableNd->EndOfSectionNode() );
79  break;
80 
81  case SECTION_SERVER:
82  pPam = new SwPaM( SwPosition( *m_CNTNT_TYPE.pSectNd ) );
83  pPam->Move( fnMoveForward );
84  pPam->SetMark();
85  pPam->GetPoint()->nNode = *m_CNTNT_TYPE.pSectNd->EndOfSectionNode();
86  pPam->Move( fnMoveBackward );
87  break;
88  case NONE_SERVER: break;
89  }
90 
91  if( pPam )
92  {
93  // Create stream
94  SvMemoryStream aMemStm( 65535, 65535 );
95  SwWriter aWrt( aMemStm, *pPam, false );
96  if( !aWrt.Write( xWrt ).IsError() )
97  {
98  aMemStm.WriteChar( '\0' ); // append a zero char
99  rData <<= uno::Sequence< sal_Int8 >(
100  static_cast<sal_Int8 const *>(aMemStm.GetData()),
101  aMemStm.Tell() );
102  bRet = true;
103  }
104  delete pPam;
105  }
106  }
107  return bRet;
108 }
109 
111 {
112  // Is someone interested in our changes?
113  if( HasDataLinks() )
114  {
115  bool bCall = false;
116  const SwStartNode* pNd = nullptr;
117  switch( m_eType )
118  {
119  case BOOKMARK_SERVER:
120  if( m_CNTNT_TYPE.pBkmk->IsExpanded() )
121  {
122  bCall = m_CNTNT_TYPE.pBkmk->GetMarkStart() <= rPos
123  && rPos < m_CNTNT_TYPE.pBkmk->GetMarkEnd();
124  }
125  break;
126 
127  case TABLE_SERVER: pNd = m_CNTNT_TYPE.pTableNd; break;
128  case SECTION_SERVER: pNd = m_CNTNT_TYPE.pSectNd; break;
129  case NONE_SERVER: break;
130  }
131  if( pNd )
132  {
133  sal_uLong nNd = rPos.nNode.GetIndex();
134  bCall = pNd->GetIndex() < nNd && nNd < pNd->EndOfSectionIndex();
135  }
136 
137  if( bCall )
138  {
139  // Recognize recursions and flag them
140  IsLinkInServer( nullptr );
141  SvLinkSource::NotifyDataChanged();
142  }
143  }
144 }
145 
147 {
148  // Is someone interested in our changes?
149  if( HasDataLinks() )
150  {
151  bool bCall = false;
152  const SwStartNode* pNd = nullptr;
153  const SwPosition* pStt = rRange.Start(), *pEnd = rRange.End();
154  switch( m_eType )
155  {
156  case BOOKMARK_SERVER:
157  if(m_CNTNT_TYPE.pBkmk->IsExpanded())
158  {
159  bCall = *pStt <= m_CNTNT_TYPE.pBkmk->GetMarkEnd()
160  && *pEnd > m_CNTNT_TYPE.pBkmk->GetMarkStart();
161  }
162  break;
163 
164  case TABLE_SERVER: pNd = m_CNTNT_TYPE.pTableNd; break;
165  case SECTION_SERVER: pNd = m_CNTNT_TYPE.pSectNd; break;
166  case NONE_SERVER: break;
167  }
168  if( pNd )
169  {
170  // Is the start area within the node area?
171  bCall = pStt->nNode.GetIndex() < pNd->EndOfSectionIndex() &&
172  pEnd->nNode.GetIndex() >= pNd->GetIndex();
173  }
174 
175  if( bCall )
176  {
177  // Recognize recursions and flag them
178  IsLinkInServer( nullptr );
179  SvLinkSource::NotifyDataChanged();
180  }
181  }
182 }
183 
184 bool SwServerObject::IsLinkInServer( const SwBaseLink* pChkLnk ) const
185 {
186  sal_uLong nSttNd = 0, nEndNd = 0;
187  const SwNode* pNd = nullptr;
188  const SwNodes* pNds = nullptr;
189 
190  switch( m_eType )
191  {
192  case BOOKMARK_SERVER:
193  if( m_CNTNT_TYPE.pBkmk->IsExpanded() )
194  {
195  const SwPosition* pStt = &m_CNTNT_TYPE.pBkmk->GetMarkStart(),
196  * pEnd = &m_CNTNT_TYPE.pBkmk->GetMarkEnd();
197 
198  nSttNd = pStt->nNode.GetIndex();
199  nEndNd = pEnd->nNode.GetIndex();
200  pNds = &pStt->nNode.GetNodes();
201  }
202  break;
203 
204  case TABLE_SERVER: pNd = m_CNTNT_TYPE.pTableNd; break;
205  case SECTION_SERVER: pNd = m_CNTNT_TYPE.pSectNd; break;
206 
207  case SECTION_SERVER+1:
208  return true;
209  }
210 
211  if( pNd )
212  {
213  nSttNd = pNd->GetIndex();
214  nEndNd = pNd->EndOfSectionIndex();
215  pNds = &pNd->GetNodes();
216  }
217 
218  if( nSttNd && nEndNd )
219  {
220  // Get LinkManager
221  const ::sfx2::SvBaseLinks& rLnks = pNds->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().GetLinks();
222 
223  // To avoid recursions: convert ServerType!
225  if( !pChkLnk )
226  const_cast<SwServerObject*>(this)->m_eType = NONE_SERVER;
227  for( size_t n = rLnks.size(); n; )
228  {
229  const ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]);
230  if (OBJECT_CLIENT_GRF != pLnk->GetObjType() &&
231  dynamic_cast<const SwBaseLink*>( pLnk) != nullptr &&
232  !static_cast<const SwBaseLink*>(pLnk)->IsNoDataFlag() &&
233  static_cast<const SwBaseLink*>(pLnk)->IsInRange( nSttNd, nEndNd ))
234  {
235  if( pChkLnk )
236  {
237  if( pLnk == pChkLnk ||
238  static_cast<const SwBaseLink*>(pLnk)->IsRecursion( pChkLnk ) )
239  return true;
240  }
241  else if( static_cast<const SwBaseLink*>(pLnk)->IsRecursion( static_cast<const SwBaseLink*>(pLnk) ) )
242  const_cast<SwBaseLink*>(static_cast<const SwBaseLink*>(pLnk))->SetNoDataFlag();
243  }
244  }
245  if( !pChkLnk )
246  const_cast<SwServerObject*>(this)->m_eType = eSave;
247  }
248 
249  return false;
250 }
251 
253 {
254  if(m_eType == BOOKMARK_SERVER && m_CNTNT_TYPE.pBkmk)
255  {
256  ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(m_CNTNT_TYPE.pBkmk);
257  if(pDdeBookmark)
258  {
259  m_CNTNT_TYPE.pBkmk = nullptr;
261  pDdeBookmark->SetRefObject(nullptr);
262  }
263  }
264 }
265 
267 {
268  ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(&rBookmark);
269  if(pDdeBookmark)
270  {
272  m_CNTNT_TYPE.pBkmk = &rBookmark;
273  pDdeBookmark->SetRefObject(this);
274  }
275  else
276  OSL_FAIL("SwServerObject::SetNoServer(..)"
277  " - setting a bookmark that is not DDE-capable");
278 }
279 
281  : pPam( &rPam ), pPos( nullptr ), pDoc( rPam.GetDoc() )
282 {
283  nContent = rPam.GetPoint()->nContent.GetIndex();
284 }
285 
287  : pPam( nullptr ), pPos( &rPos ), pDoc( pDc )
288 {
289  nContent = rPos.nContent.GetIndex();
290 }
291 
293 {
294  // JP 09.04.96: Only if the Layout is available (thus during input)
296  {
297  const ::sfx2::SvLinkSources& rServers = pDoc->getIDocumentLinksAdministration().GetLinkManager().GetServers();
298 
299  ::sfx2::SvLinkSources aTemp(rServers);
300  for( const auto& rpLinkSrc : aTemp )
301  {
302  ::sfx2::SvLinkSourceRef refObj( rpLinkSrc );
303  // Anyone else interested in the Object?
304  if( refObj->HasDataLinks() && dynamic_cast<const SwServerObject*>( refObj.get() ) != nullptr)
305  {
306  SwServerObject& rObj = *static_cast<SwServerObject*>( refObj.get() );
307  if( pPos )
308  rObj.SendDataChanged( *pPos );
309  else
310  rObj.SendDataChanged( *pPam );
311  }
312 
313  // We shouldn't have a connection anymore
314  if( !refObj->HasDataLinks() )
315  {
316  // Then remove from the list
318  }
319  }
320  }
321 }
322 
323 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool is() const
Starts a section of nodes in the document model.
Definition: node.hxx:303
sal_uLong GetIndex() const
Definition: node.hxx:282
virtual ~SwServerObject() override
Definition: swserv.cxx:39
const SwPosition * pPos
Definition: mvsave.hxx:130
Marks a position in the document model.
Definition: pam.hxx:35
bool IsLinkInServer(const SwBaseLink *) const
Definition: swserv.cxx:184
signed char sal_Int8
SwNodeIndex nNode
Definition: pam.hxx:37
sal_uIntPtr sal_uLong
Definition: doc.hxx:185
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:292
void GetASCWriter(const OUString &rFltNm, const OUString &, WriterRef &xRet)
Definition: wrtasc.cxx:206
ErrCode Write(WriterRef const &rxWriter, const OUString *=nullptr)
Definition: shellio.cxx:727
const SwPaM * pPam
Definition: mvsave.hxx:129
#define OBJECT_CLIENT_GRF
virtual bool GetData(css::uno::Any &rData, const OUString &rMimeType, bool bSynchron=false) override
Definition: swserv.cxx:43
SwIndex nContent
Definition: pam.hxx:38
void RemoveServer(SvLinkSource *rObj)
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
SwDataChanged(const SwPaM &rPam)
Definition: swserv.cxx:280
bool IsInRange(const sal_uInt16 *pRange, const sal_uInt16 nId)
check if ID is in range of attribute set IDs
Definition: swatrset.cxx:441
sal_Int32 nContent
Definition: mvsave.hxx:132
void SetRefObject(SwServerObject *pObj)
Definition: bookmrk.cxx:261
SwDoc * pDoc
Definition: mvsave.hxx:131
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:481
T * get() const
const SvBaseLinks & GetLinks() const
const SwPosition * GetPoint() const
Definition: pam.hxx:207
void SetNoServer()
Definition: swserv.cxx:252
void SendDataChanged(const SwPosition &rPos)
Definition: swserv.cxx:110
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:437
const SwPosition * Start() const
Definition: pam.hxx:212
SwDoc * GetDoc()
Which Doc contains the nodes-array?
Definition: ndarr.hxx:305
const SvLinkSources & GetServers() const
bool HasDataLinks() const
bool IsError() const
void GetRTFWriter(const OUString &rFltName, const OUString &rBaseURL, WriterRef &xRet)
Definition: fltini.cxx:675
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
union SwServerObject::@30 m_CNTNT_TYPE
std::set< SvLinkSource * > SvLinkSources
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
const SwNodes & GetNodes() const
Definition: ndindex.hxx:155
static SotClipboardFormatId GetFormatIdFromMimeType(const OUString &rMimeType)
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
sal_Int32 GetIndex() const
Definition: index.hxx:95
const SwPosition * End() const
Definition: pam.hxx:217
sal_uInt64 Tell() const
SvStream & WriteChar(char nChar)
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
virtual sfx2::LinkManager & GetLinkManager()=0
enum SwServerObject::ServerModes m_eType
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:455
void SetDdeBookmark(::sw::mark::IMark &rBookmark)
Definition: swserv.cxx:266
const void * GetData()
Base class of the Writer document model elements.
Definition: node.hxx:79