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 <bookmark.hxx>
31#include <pam.hxx>
32#include <shellio.hxx>
33
34using 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( std::u16string_view(), OUString(), xWrt );
49 break;
50
51 case SotClipboardFormatId::RTF:
52 case SotClipboardFormatId::RICHTEXT:
53 // mba: no BaseURL for data exchange
54 ::GetRTFWriter( std::u16string_view(), 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()->Assign( *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 SwNodeOffset nNd = rPos.GetNodeIndex();
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 auto [pStt, pEnd] = rRange.StartEnd(); // SwPosition*
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->GetNodeIndex() < pNd->EndOfSectionIndex() &&
170 pEnd->GetNodeIndex() >= pNd->GetIndex();
171 }
172
173 if( bCall )
174 {
175 // Recognize recursions and flag them
176 IsLinkInServer( nullptr );
177 SvLinkSource::NotifyDataChanged();
178 }
179}
180
181bool SwServerObject::IsLinkInServer( const SwBaseLink* pChkLnk ) const
182{
183 SwNodeOffset 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->GetNodeIndex();
196 nEndNd = pEnd->GetNodeIndex();
197 pNds = &pStt->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{
281}
282
284 : m_pPam( nullptr ), m_pPos( &rPos ), m_rDoc( rDc )
285{
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())
303 if (auto pServerObj = dynamic_cast<SwServerObject*>( refObj.get() ))
304 {
305 if( m_pPos )
306 pServerObj->SendDataChanged( *m_pPos );
307 else
308 pServerObj->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 IsError() const
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
virtual sfx2::LinkManager & GetLinkManager()=0
static SotClipboardFormatId GetFormatIdFromMimeType(std::u16string_view rMimeType)
const void * GetData()
sal_uInt64 Tell() const
SvStream & WriteChar(char nChar)
const SwPaM * m_pPam
Definition: mvsave.hxx:132
SwDataChanged(const SwPaM &rPam)
Definition: swserv.cxx:277
sal_Int32 m_nContent
Definition: mvsave.hxx:135
const SwPosition * m_pPos
Definition: mvsave.hxx:133
SwDoc & m_rDoc
Definition: mvsave.hxx:134
Definition: doc.hxx:197
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:274
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:419
Base class of the Writer document model elements.
Definition: node.hxx:98
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:706
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:691
SwDoc & GetDoc()
Which Doc contains the nodes-array?
Definition: ndarr.hxx:307
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:643
std::pair< const SwPosition *, const SwPosition * > StartEnd() const
Because sometimes the cost of the operator<= can add up.
Definition: pam.hxx:269
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:657
const SwPosition * GetPoint() const
Definition: pam.hxx:253
void SetDdeBookmark(::sw::mark::IMark &rBookmark)
Definition: swserv.cxx:263
bool IsLinkInServer(const SwBaseLink *) const
Definition: swserv.cxx:181
virtual ~SwServerObject() override
Definition: swserv.cxx:36
void SetNoServer()
Definition: swserv.cxx:249
union SwServerObject::@26 m_CNTNT_TYPE
enum SwServerObject::ServerModes m_eType
virtual bool GetData(css::uno::Any &rData, const OUString &rMimeType, bool bSynchron=false) override
Definition: swserv.cxx:40
Starts a section of nodes in the document model.
Definition: node.hxx:348
ErrCode Write(WriterRef const &rxWriter, const OUString *=nullptr)
Definition: shellio.cxx:745
const SvLinkSources & GetServers() const
void RemoveServer(SvLinkSource *rObj)
const SvBaseLinks & GetLinks() const
bool HasDataLinks() const
void SetRefObject(SwServerObject *pObj)
T * get() const
bool is() const
SwDoc & m_rDoc
Definition: docbm.cxx:1228
void GetRTFWriter(std::u16string_view rFltName, const OUString &rBaseURL, WriterRef &xRet)
Definition: fltini.cxx:642
sal_Int64 n
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:60
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:61
Marks a position in the document model.
Definition: pam.hxx:38
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:231
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:78
const SwNodes & GetNodes() const
Definition: pam.hxx:79
sal_Int32 GetContentIndex() const
Definition: pam.hxx:85
bool IsInRange(const WhichRangesContainer &pRange, const sal_uInt16 nId)
check if ID is in range of attribute set IDs
Definition: swatrset.cxx:451
signed char sal_Int8
void GetASCWriter(std::u16string_view rFltNm, const OUString &, WriterRef &xRet)
Definition: wrtasc.cxx:224