update dev300-m58
[ooovba.git] / svx / source / form / fmexch.cxx
blob55d92e07a0c7663f7ef530c8f9fc9a944a2eabbf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fmexch.cxx,v $
10 * $Revision: 1.19 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include "fmexch.hxx"
35 #include <sot/storage.hxx>
36 #include <svtools/itempool.hxx>
38 #ifndef _SVX_DBEXCH_HRC
39 #include <dbexch.hrc>
40 #endif
41 #include <sot/formats.hxx>
42 #include <svtools/svtreebx.hxx>
43 #include <tools/diagnose_ex.h>
45 #define _SVSTDARR_ULONGS
46 #include <svtools/svstdarr.hxx>
48 //........................................................................
49 namespace svxform
51 //........................................................................
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::datatransfer;
56 //====================================================================
57 //= OLocalExchange
58 //====================================================================
59 //--------------------------------------------------------------------
60 OLocalExchange::OLocalExchange( )
61 :m_bDragging( sal_False )
62 ,m_bClipboardOwner( sal_False )
66 //--------------------------------------------------------------------
67 void OLocalExchange::copyToClipboard( Window* _pWindow, const GrantAccess& )
69 if ( m_bClipboardOwner )
70 { // simulate a lostOwnership to notify parties interested in
71 if ( m_aClipboardListener.IsSet() )
72 m_aClipboardListener.Call( this );
75 m_bClipboardOwner = sal_True;
76 CopyToClipboard( _pWindow );
79 //--------------------------------------------------------------------
80 void OLocalExchange::clear()
82 if ( isClipboardOwner() )
84 try
86 Reference< clipboard::XClipboard > xClipBoard( getOwnClipboard() );
87 if ( xClipBoard.is() )
88 xClipBoard->setContents( NULL, NULL );
90 catch( const Exception& )
92 DBG_UNHANDLED_EXCEPTION();
94 m_bClipboardOwner = sal_False;
98 //--------------------------------------------------------------------
99 void SAL_CALL OLocalExchange::lostOwnership( const Reference< clipboard::XClipboard >& _rxClipboard, const Reference< XTransferable >& _rxTrans ) throw(RuntimeException)
101 TransferableHelper::implCallOwnLostOwnership( _rxClipboard, _rxTrans );
102 m_bClipboardOwner = sal_False;
104 if ( m_aClipboardListener.IsSet() )
105 m_aClipboardListener.Call( this );
108 //--------------------------------------------------------------------
109 void OLocalExchange::startDrag( Window* _pWindow, sal_Int8 _nDragSourceActions, const GrantAccess& )
111 m_bDragging = sal_True;
112 StartDrag( _pWindow, _nDragSourceActions );
115 //--------------------------------------------------------------------
116 void OLocalExchange::DragFinished( sal_Int8 nDropAction )
118 TransferableHelper::DragFinished( nDropAction );
119 m_bDragging = sal_False;
122 //--------------------------------------------------------------------
123 sal_Bool OLocalExchange::hasFormat( const DataFlavorExVector& _rFormats, sal_uInt32 _nFormatId )
125 DataFlavorExVector::const_iterator aSearch;
127 for ( aSearch = _rFormats.begin(); aSearch != _rFormats.end(); ++aSearch )
128 if ( aSearch->mnSotId == _nFormatId )
129 break;
131 return aSearch != _rFormats.end();
134 //--------------------------------------------------------------------
135 sal_Bool OLocalExchange::GetData( const ::com::sun::star::datatransfer::DataFlavor& /*_rFlavor*/ )
137 return sal_False; // do not have any formats by default
140 //====================================================================
141 //= OControlTransferData
142 //====================================================================
143 //--------------------------------------------------------------------
144 OControlTransferData::OControlTransferData( )
145 :m_pFocusEntry( NULL )
149 //--------------------------------------------------------------------
150 OControlTransferData::OControlTransferData( const Reference< XTransferable >& _rxTransferable )
151 :m_pFocusEntry( NULL )
153 TransferableDataHelper aExchangedData( _rxTransferable );
155 // try the formats we know
156 if ( OControlExchange::hasControlPathFormat( aExchangedData.GetDataFlavorExVector() ) )
157 { // paths to the controls, relative to a root
158 Sequence< Any > aControlPathData;
159 if ( aExchangedData.GetAny( OControlExchange::getControlPathFormatId() ) >>= aControlPathData )
161 DBG_ASSERT( aControlPathData.getLength() >= 2, "OControlTransferData::OControlTransferData: invalid data for the control path format!" );
162 if ( aControlPathData.getLength() >= 2 )
164 aControlPathData[0] >>= m_xFormsRoot;
165 aControlPathData[1] >>= m_aControlPaths;
168 else
170 DBG_ERROR( "OControlTransferData::OControlTransferData: invalid data for the control path format (2)!" );
173 if ( OControlExchange::hasHiddenControlModelsFormat( aExchangedData.GetDataFlavorExVector() ) )
174 { // sequence of models of hidden controls
175 aExchangedData.GetAny( OControlExchange::getHiddenControlModelsFormatId() ) >>= m_aHiddenControlModels;
178 updateFormats( );
181 //--------------------------------------------------------------------
182 static sal_Bool lcl_fillDataFlavorEx( SotFormatStringId nId, DataFlavorEx& _rFlavor )
184 _rFlavor.mnSotId = nId;
185 return SotExchange::GetFormatDataFlavor( _rFlavor.mnSotId, _rFlavor );
188 //--------------------------------------------------------------------
189 void OControlTransferData::updateFormats( )
191 m_aCurrentFormats.clear();
192 m_aCurrentFormats.reserve( 3 );
194 DataFlavorEx aFlavor;
196 if ( m_aHiddenControlModels.getLength() )
198 if ( lcl_fillDataFlavorEx( OControlExchange::getHiddenControlModelsFormatId(), aFlavor ) )
199 m_aCurrentFormats.push_back( aFlavor );
202 if ( m_xFormsRoot.is() && m_aControlPaths.getLength() )
204 if ( lcl_fillDataFlavorEx( OControlExchange::getControlPathFormatId(), aFlavor ) )
205 m_aCurrentFormats.push_back( aFlavor );
208 if ( !m_aSelectedEntries.empty() )
210 if ( lcl_fillDataFlavorEx( OControlExchange::getFieldExchangeFormatId(), aFlavor ) )
211 m_aCurrentFormats.push_back( aFlavor );
215 //--------------------------------------------------------------------
216 size_t OControlTransferData::onEntryRemoved( SvLBoxEntry* _pEntry )
218 m_aSelectedEntries.erase( _pEntry );
219 return m_aSelectedEntries.size();
222 //--------------------------------------------------------------------
223 void OControlTransferData::addSelectedEntry( SvLBoxEntry* _pEntry )
225 m_aSelectedEntries.insert( _pEntry );
228 //--------------------------------------------------------------------
229 void OControlTransferData::setFocusEntry( SvLBoxEntry* _pFocusEntry )
231 m_pFocusEntry = _pFocusEntry;
234 //------------------------------------------------------------------------
235 void OControlTransferData::addHiddenControlsFormat(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > seqInterfaces)
237 m_aHiddenControlModels = seqInterfaces;
240 //------------------------------------------------------------------------
241 void OControlTransferData::buildPathFormat(SvTreeListBox* pTreeBox, SvLBoxEntry* pRoot)
243 m_aControlPaths.realloc(0);
245 sal_Int32 nEntryCount = m_aSelectedEntries.size();
246 if (nEntryCount == 0)
247 return;
249 m_aControlPaths.realloc(nEntryCount);
250 ::com::sun::star::uno::Sequence<sal_uInt32>* pAllPaths = m_aControlPaths.getArray();
251 for ( ListBoxEntrySet::const_iterator loop = m_aSelectedEntries.begin();
252 loop != m_aSelectedEntries.end();
253 ++loop, ++pAllPaths
256 // erst mal sammeln wir den Pfad in einem Array ein
257 ::std::vector< sal_uInt32 > aCurrentPath;
258 SvLBoxEntry* pCurrentEntry = *loop;
260 SvLBoxEntry* pLoop = pCurrentEntry;
261 while (pLoop != pRoot)
263 aCurrentPath.push_back(pLoop->GetChildListPos());
264 pLoop = pTreeBox->GetParent(pLoop);
265 DBG_ASSERT((pLoop != NULL) || (pRoot == 0), "OControlTransferData::buildPathFormat: invalid root or entry !");
266 // pLoop == NULL heisst, dass ich am oberen Ende angelangt bin, dann sollte das Ganze abbrechen, was nur bei pRoot == NULL der Fall sein wird
269 // dann koennen wir ihn in die ::com::sun::star::uno::Sequence uebertragen
270 Sequence<sal_uInt32>& rCurrentPath = *pAllPaths;
271 sal_Int32 nDepth = aCurrentPath.size();
273 rCurrentPath.realloc(nDepth);
274 sal_uInt32* pSeq = rCurrentPath.getArray();
275 sal_Int32 j,k;
276 for (j = nDepth - 1, k = 0; k<nDepth; --j, ++k)
277 pSeq[j] = aCurrentPath[k];
281 //------------------------------------------------------------------------
282 void OControlTransferData::buildListFromPath(SvTreeListBox* pTreeBox, SvLBoxEntry* pRoot)
284 ListBoxEntrySet aEmpty;
285 m_aSelectedEntries.swap( aEmpty );
287 sal_Int32 nControls = m_aControlPaths.getLength();
288 const ::com::sun::star::uno::Sequence<sal_uInt32>* pPaths = m_aControlPaths.getConstArray();
289 for (sal_Int32 i=0; i<nControls; ++i)
291 sal_Int32 nThisPatLength = pPaths[i].getLength();
292 const sal_uInt32* pThisPath = pPaths[i].getConstArray();
293 SvLBoxEntry* pSearch = pRoot;
294 for (sal_Int32 j=0; j<nThisPatLength; ++j)
295 pSearch = pTreeBox->GetEntry(pSearch, pThisPath[j]);
297 m_aSelectedEntries.insert( pSearch );
301 //====================================================================
302 //= OControlExchange
303 //====================================================================
304 //--------------------------------------------------------------------
305 OControlExchange::OControlExchange( )
309 //--------------------------------------------------------------------
310 sal_Bool OControlExchange::GetData( const DataFlavor& _rFlavor )
312 const sal_uInt32 nFormatId = SotExchange::GetFormat( _rFlavor );
314 if ( getControlPathFormatId( ) == nFormatId )
316 // ugly. We have to pack all the info into one object
317 Sequence< Any > aCompleteInfo( 2 );
318 OSL_ENSURE( m_xFormsRoot.is(), "OLocalExchange::GetData: invalid forms root for this format!" );
319 aCompleteInfo.getArray()[ 0 ] <<= m_xFormsRoot;
320 aCompleteInfo.getArray()[ 1 ] <<= m_aControlPaths;
322 SetAny( makeAny( aCompleteInfo ), _rFlavor );
324 else if ( getHiddenControlModelsFormatId() == nFormatId )
326 // just need to transfer the models
327 SetAny( makeAny( m_aHiddenControlModels ), _rFlavor );
329 else
330 return OLocalExchange::GetData( _rFlavor );
332 return sal_True;
335 //--------------------------------------------------------------------
336 void OControlExchange::AddSupportedFormats()
338 if (m_pFocusEntry && !m_aSelectedEntries.empty())
339 AddFormat(getFieldExchangeFormatId());
341 if (m_aControlPaths.getLength())
342 AddFormat(getControlPathFormatId());
344 if (m_aHiddenControlModels.getLength())
345 AddFormat(getHiddenControlModelsFormatId());
348 //--------------------------------------------------------------------
349 sal_uInt32 OControlExchange::getControlPathFormatId()
351 static sal_uInt32 s_nFormat = (sal_uInt32)-1;
352 if ((sal_uInt32)-1 == s_nFormat)
354 s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"svxform.ControlPathExchange\""));
355 DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OControlExchange::getControlPathFormatId: bad exchange id!");
357 return s_nFormat;
360 //--------------------------------------------------------------------
361 sal_uInt32 OControlExchange::getHiddenControlModelsFormatId()
363 static sal_uInt32 s_nFormat = (sal_uInt32)-1;
364 if ((sal_uInt32)-1 == s_nFormat)
366 s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"svxform.HiddenControlModelsExchange\""));
367 DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OControlExchange::getHiddenControlModelsFormatId: bad exchange id!");
369 return s_nFormat;
372 //--------------------------------------------------------------------
373 sal_uInt32 OControlExchange::getFieldExchangeFormatId()
375 static sal_uInt32 s_nFormat = (sal_uInt32)-1;
376 if ((sal_uInt32)-1 == s_nFormat)
378 s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"svxform.FieldNameExchange\""));
379 DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OControlExchange::getFieldExchangeFormatId: bad exchange id!");
381 return s_nFormat;
384 //====================================================================
385 //= OControlExchangeHelper
386 //====================================================================
387 OLocalExchange* OControlExchangeHelper::createExchange() const
389 return new OControlExchange;
392 //====================================================================
393 //= OLocalExchangeHelper
394 //====================================================================
395 //--------------------------------------------------------------------
396 OLocalExchangeHelper::OLocalExchangeHelper(Window* _pDragSource)
397 :m_pDragSource(_pDragSource)
398 ,m_pTransferable(NULL)
402 //--------------------------------------------------------------------
403 OLocalExchangeHelper::~OLocalExchangeHelper()
405 implReset();
408 //--------------------------------------------------------------------
409 void OLocalExchangeHelper::startDrag( sal_Int8 nDragSourceActions )
411 DBG_ASSERT(m_pTransferable, "OLocalExchangeHelper::startDrag: not prepared!");
412 m_pTransferable->startDrag( m_pDragSource, nDragSourceActions, OLocalExchange::GrantAccess() );
415 //--------------------------------------------------------------------
416 void OLocalExchangeHelper::copyToClipboard( ) const
418 DBG_ASSERT( m_pTransferable, "OLocalExchangeHelper::copyToClipboard: not prepared!" );
419 m_pTransferable->copyToClipboard( m_pDragSource, OLocalExchange::GrantAccess() );
422 //--------------------------------------------------------------------
423 void OLocalExchangeHelper::implReset()
425 if (m_pTransferable)
427 m_pTransferable->setClipboardListener( Link() );
428 m_pTransferable->release();
429 m_pTransferable = NULL;
433 //--------------------------------------------------------------------
434 void OLocalExchangeHelper::prepareDrag( )
436 DBG_ASSERT(!m_pTransferable || !m_pTransferable->isDragging(), "OLocalExchangeHelper::prepareDrag: recursive DnD?");
438 implReset();
439 m_pTransferable = createExchange();
440 m_pTransferable->acquire();
443 //........................................................................
445 //........................................................................