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  return;
112 
113  bool bCall = false;
114  const SwStartNode* pNd = nullptr;
115  switch( m_eType )
116  {
117  case BOOKMARK_SERVER:
118  if( m_CNTNT_TYPE.pBkmk->IsExpanded() )
119  {
120  bCall = m_CNTNT_TYPE.pBkmk->GetMarkStart() <= rPos
121  && rPos < m_CNTNT_TYPE.pBkmk->GetMarkEnd();
122  }
123  break;
124 
125  case TABLE_SERVER: pNd = m_CNTNT_TYPE.pTableNd; break;
126  case SECTION_SERVER: pNd = m_CNTNT_TYPE.pSectNd; break;
127  case NONE_SERVER: break;
128  }
129  if( pNd )
130  {
131  sal_uLong nNd = rPos.nNode.GetIndex();
132  bCall = pNd->GetIndex() < nNd && nNd < pNd->EndOfSectionIndex();
133  }
134 
135  if( bCall )
136  {
137  // Recognize recursions and flag them
138  IsLinkInServer( nullptr );
139  SvLinkSource::NotifyDataChanged();
140  }
141 }
142 
144 {
145  // Is someone interested in our changes?
146  if( !HasDataLinks() )
147  return;
148 
149  bool bCall = false;
150  const SwStartNode* pNd = nullptr;
151  const SwPosition* pStt = rRange.Start(), *pEnd = rRange.End();
152  switch( m_eType )
153  {
154  case BOOKMARK_SERVER:
155  if(m_CNTNT_TYPE.pBkmk->IsExpanded())
156  {
157  bCall = *pStt <= m_CNTNT_TYPE.pBkmk->GetMarkEnd()
158  && *pEnd > m_CNTNT_TYPE.pBkmk->GetMarkStart();
159  }
160  break;
161 
162  case TABLE_SERVER: pNd = m_CNTNT_TYPE.pTableNd; break;
163  case SECTION_SERVER: pNd = m_CNTNT_TYPE.pSectNd; break;
164  case NONE_SERVER: break;
165  }
166  if( pNd )
167  {
168  // Is the start area within the node area?
169  bCall = pStt->nNode.GetIndex() < pNd->EndOfSectionIndex() &&
170  pEnd->nNode.GetIndex() >= pNd->GetIndex();
171  }
172 
173  if( bCall )
174  {
175  // Recognize recursions and flag them
176  IsLinkInServer( nullptr );
177  SvLinkSource::NotifyDataChanged();
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 (sfx2::SvBaseLinkObjectType::ClientGraphic != 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  : m_pPam( &rPam ), m_pPos( nullptr ), m_rDoc( rPam.GetDoc() )
279 {
280  m_nContent = rPam.GetPoint()->nContent.GetIndex();
281 }
282 
284  : m_pPam( nullptr ), m_pPos( &rPos ), m_rDoc( rDc )
285 {
286  m_nContent = rPos.nContent.GetIndex();
287 }
288 
290 {
291  // JP 09.04.96: Only if the Layout is available (thus during input)
293  return;
294 
295  const ::sfx2::SvLinkSources& rServers = m_rDoc.getIDocumentLinksAdministration().GetLinkManager().GetServers();
296 
297  ::sfx2::SvLinkSources aTemp(rServers);
298  for( const auto& rpLinkSrc : aTemp )
299  {
300  ::sfx2::SvLinkSourceRef refObj( rpLinkSrc );
301  // Anyone else interested in the Object?
302  if( refObj->HasDataLinks() && dynamic_cast<const SwServerObject*>( refObj.get() ) != nullptr)
303  {
304  SwServerObject& rObj = *static_cast<SwServerObject*>( refObj.get() );
305  if( m_pPos )
306  rObj.SendDataChanged( *m_pPos );
307  else
308  rObj.SendDataChanged( *m_pPam );
309  }
310 
311  // We shouldn't have a connection anymore
312  if( !refObj->HasDataLinks() )
313  {
314  // Then remove from the list
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:311
sal_uLong GetIndex() const
Definition: node.hxx:290
virtual ~SwServerObject() override
Definition: swserv.cxx:36
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
SwDoc & GetDoc()
Which Doc contains the nodes-array?
Definition: ndarr.hxx:302
sal_uIntPtr sal_uLong
sal_Int64 n
Definition: doc.hxx:186
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:260
ErrCode Write(WriterRef const &rxWriter, const OUString *=nullptr)
Definition: shellio.cxx:730
SwDoc & m_rDoc
Definition: docbm.cxx:1205
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:470
void SetRefObject(SwServerObject *pObj)
Definition: bookmrk.cxx:368
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:502
T * get() const
const SvBaseLinks & GetLinks() const
const SwPosition * GetPoint() const
Definition: pam.hxx:207
sal_Int32 m_nContent
Definition: mvsave.hxx:134
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:696
SwDoc & m_rDoc
Definition: mvsave.hxx:133
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
const SwPosition * Start() const
Definition: pam.hxx:212
void GetASCWriter(const OUString &rFltNm, [[maybe_unused]] const OUString &, WriterRef &xRet)
Definition: wrtasc.cxx:205
const SvLinkSources & GetServers() const
bool HasDataLinks() const
const SwPaM * m_pPam
Definition: mvsave.hxx:131
bool IsError() const
void GetRTFWriter(const OUString &rFltName, const OUString &rBaseURL, WriterRef &xRet)
Definition: fltini.cxx:641
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:680
const SwPosition * m_pPos
Definition: mvsave.hxx:132
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:91
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:476
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
union SwServerObject::@29 m_CNTNT_TYPE