android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / doc / swserv.cxx
blobb12ab6b6c15c2f6aaacfa8ca3e038eb985c8e45f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sot/exchange.hxx>
21 #include <sfx2/linkmgr.hxx>
22 #include <com/sun/star/uno/Sequence.h>
23 #include <doc.hxx>
24 #include <IDocumentLinksAdministration.hxx>
25 #include <IDocumentLayoutAccess.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>
34 using namespace ::com::sun::star;
36 SwServerObject::~SwServerObject()
40 bool SwServerObject::GetData( uno::Any & rData,
41 const OUString & rMimeType, bool )
43 bool bRet = false;
44 WriterRef xWrt;
45 switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
47 case SotClipboardFormatId::STRING:
48 ::GetASCWriter( std::u16string_view(), OUString(), xWrt );
49 break;
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;
59 if( xWrt.is() )
61 SwPaM* pPam = nullptr;
62 switch( m_eType )
64 case BOOKMARK_SERVER:
65 if( m_CNTNT_TYPE.pBkmk->IsExpanded() )
67 // Span area
68 pPam = new SwPaM( m_CNTNT_TYPE.pBkmk->GetMarkPos(),
69 m_CNTNT_TYPE.pBkmk->GetOtherMarkPos() );
71 break;
73 case TABLE_SERVER:
74 pPam = new SwPaM( *m_CNTNT_TYPE.pTableNd,
75 *m_CNTNT_TYPE.pTableNd->EndOfSectionNode() );
76 break;
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;
88 if( pPam )
90 // Create stream
91 SvMemoryStream aMemStm( 65535, 65535 );
92 SwWriter aWrt( aMemStm, *pPam, false );
93 if( !aWrt.Write( xWrt ).IsError() )
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;
101 delete pPam;
104 return bRet;
107 void SwServerObject::SendDataChanged( const SwPosition& rPos )
109 // Is someone interested in our changes?
110 if( !HasDataLinks() )
111 return;
113 bool bCall = false;
114 const SwStartNode* pNd = nullptr;
115 switch( m_eType )
117 case BOOKMARK_SERVER:
118 if( m_CNTNT_TYPE.pBkmk->IsExpanded() )
120 bCall = m_CNTNT_TYPE.pBkmk->GetMarkStart() <= rPos
121 && rPos < m_CNTNT_TYPE.pBkmk->GetMarkEnd();
123 break;
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;
129 if( pNd )
131 SwNodeOffset nNd = rPos.GetNodeIndex();
132 bCall = pNd->GetIndex() < nNd && nNd < pNd->EndOfSectionIndex();
135 if( bCall )
137 // Recognize recursions and flag them
138 IsLinkInServer( nullptr );
139 SvLinkSource::NotifyDataChanged();
143 void SwServerObject::SendDataChanged( const SwPaM& rRange )
145 // Is someone interested in our changes?
146 if( !HasDataLinks() )
147 return;
149 bool bCall = false;
150 const SwStartNode* pNd = nullptr;
151 auto [pStt, pEnd] = rRange.StartEnd(); // SwPosition*
152 switch( m_eType )
154 case BOOKMARK_SERVER:
155 if(m_CNTNT_TYPE.pBkmk->IsExpanded())
157 bCall = *pStt <= m_CNTNT_TYPE.pBkmk->GetMarkEnd()
158 && *pEnd > m_CNTNT_TYPE.pBkmk->GetMarkStart();
160 break;
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;
166 if( pNd )
168 // Is the start area within the node area?
169 bCall = pStt->GetNodeIndex() < pNd->EndOfSectionIndex() &&
170 pEnd->GetNodeIndex() >= pNd->GetIndex();
173 if( bCall )
175 // Recognize recursions and flag them
176 IsLinkInServer( nullptr );
177 SvLinkSource::NotifyDataChanged();
181 bool SwServerObject::IsLinkInServer( const SwBaseLink* pChkLnk ) const
183 SwNodeOffset nSttNd(0), nEndNd(0);
184 const SwNode* pNd = nullptr;
185 const SwNodes* pNds = nullptr;
187 switch( m_eType )
189 case BOOKMARK_SERVER:
190 if( m_CNTNT_TYPE.pBkmk->IsExpanded() )
192 const SwPosition* pStt = &m_CNTNT_TYPE.pBkmk->GetMarkStart(),
193 * pEnd = &m_CNTNT_TYPE.pBkmk->GetMarkEnd();
195 nSttNd = pStt->GetNodeIndex();
196 nEndNd = pEnd->GetNodeIndex();
197 pNds = &pStt->GetNodes();
199 break;
201 case TABLE_SERVER: pNd = m_CNTNT_TYPE.pTableNd; break;
202 case SECTION_SERVER: pNd = m_CNTNT_TYPE.pSectNd; break;
204 case SECTION_SERVER+1:
205 return true;
208 if( pNd )
210 nSttNd = pNd->GetIndex();
211 nEndNd = pNd->EndOfSectionIndex();
212 pNds = &pNd->GetNodes();
215 if( nSttNd && nEndNd )
217 // Get LinkManager
218 const ::sfx2::SvBaseLinks& rLnks = pNds->GetDoc().getIDocumentLinksAdministration().GetLinkManager().GetLinks();
220 // To avoid recursions: convert ServerType!
221 SwServerObject::ServerModes eSave = m_eType;
222 if( !pChkLnk )
223 const_cast<SwServerObject*>(this)->m_eType = NONE_SERVER;
224 for( size_t n = rLnks.size(); n; )
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 ))
232 if( pChkLnk )
234 if( pLnk == pChkLnk ||
235 static_cast<const SwBaseLink*>(pLnk)->IsRecursion( pChkLnk ) )
236 return true;
238 else if( static_cast<const SwBaseLink*>(pLnk)->IsRecursion( static_cast<const SwBaseLink*>(pLnk) ) )
239 const_cast<SwBaseLink*>(static_cast<const SwBaseLink*>(pLnk))->SetNoDataFlag();
242 if( !pChkLnk )
243 const_cast<SwServerObject*>(this)->m_eType = eSave;
246 return false;
249 void SwServerObject::SetNoServer()
251 if(m_eType == BOOKMARK_SERVER && m_CNTNT_TYPE.pBkmk)
253 ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(m_CNTNT_TYPE.pBkmk);
254 if(pDdeBookmark)
256 m_CNTNT_TYPE.pBkmk = nullptr;
257 m_eType = NONE_SERVER;
258 pDdeBookmark->SetRefObject(nullptr);
263 void SwServerObject::SetDdeBookmark( ::sw::mark::IMark& rBookmark)
265 ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(&rBookmark);
266 if(pDdeBookmark)
268 m_eType = BOOKMARK_SERVER;
269 m_CNTNT_TYPE.pBkmk = &rBookmark;
270 pDdeBookmark->SetRefObject(this);
272 else
273 OSL_FAIL("SwServerObject::SetNoServer(..)"
274 " - setting a bookmark that is not DDE-capable");
277 SwDataChanged::SwDataChanged( const SwPaM& rPam )
278 : m_pPam( &rPam ), m_pPos( nullptr ), m_rDoc( rPam.GetDoc() )
280 m_nContent = rPam.GetPoint()->GetContentIndex();
283 SwDataChanged::SwDataChanged( SwDoc& rDc, const SwPosition& rPos )
284 : m_pPam( nullptr ), m_pPos( &rPos ), m_rDoc( rDc )
286 m_nContent = rPos.GetContentIndex();
289 SwDataChanged::~SwDataChanged()
291 // JP 09.04.96: Only if the Layout is available (thus during input)
292 if( !m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell() )
293 return;
295 const ::sfx2::SvLinkSources& rServers = m_rDoc.getIDocumentLinksAdministration().GetLinkManager().GetServers();
297 ::sfx2::SvLinkSources aTemp(rServers);
298 for( const auto& rpLinkSrc : aTemp )
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() ))
305 if( m_pPos )
306 pServerObj->SendDataChanged( *m_pPos );
307 else
308 pServerObj->SendDataChanged( *m_pPam );
311 // We shouldn't have a connection anymore
312 if( !refObj->HasDataLinks() )
314 // Then remove from the list
315 m_rDoc.getIDocumentLinksAdministration().GetLinkManager().RemoveServer( rpLinkSrc );
320 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */