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