Update ooo320-m1
[ooovba.git] / sc / source / ui / app / seltrans.cxx
blob8d9ec9ec9ee1898f008363f1a0c67e66839b7a89
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: seltrans.cxx,v $
10 * $Revision: 1.15 $
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_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/XPropertySetInfo.hpp>
40 #include <com/sun/star/form/FormButtonType.hpp>
42 #include <tools/urlobj.hxx>
43 #include <sfx2/docfile.hxx>
44 #include <svx/fmglob.hxx>
45 #include <svx/svdograf.hxx>
46 #include <svx/svdouno.hxx>
48 #include "seltrans.hxx"
49 #include "transobj.hxx"
50 #include "drwtrans.hxx"
51 #include "scmod.hxx"
52 #include "dbfunc.hxx" // for CopyToClip
53 #include "docsh.hxx"
54 #include "drawview.hxx"
55 #include "drwlayer.hxx"
57 using namespace com::sun::star;
59 // -----------------------------------------------------------------------
61 BOOL lcl_IsURLButton( SdrObject* pObject )
63 BOOL bRet = FALSE;
65 SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject);
66 if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
68 uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
69 DBG_ASSERT( xControlModel.is(), "uno control without model" );
70 if ( xControlModel.is() )
72 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
73 uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
75 rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" );
76 if(xInfo->hasPropertyByName( sPropButtonType ))
78 uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
79 form::FormButtonType eTmp;
80 if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
81 bRet = TRUE;
86 return bRet;
89 // static
91 ScSelectionTransferObj* ScSelectionTransferObj::CreateFromView( ScTabView* pView )
93 ScSelectionTransferObj* pRet = NULL;
95 if ( pView )
97 ScSelectionTransferMode eMode = SC_SELTRANS_INVALID;
99 SdrView* pSdrView = pView->GetSdrView();
100 if ( pSdrView )
102 // handle selection on drawing layer
103 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
104 ULONG nMarkCount = rMarkList.GetMarkCount();
105 if ( nMarkCount )
107 if ( nMarkCount == 1 )
109 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
110 UINT16 nSdrObjKind = pObj->GetObjIdentifier();
112 if ( nSdrObjKind == OBJ_GRAF )
114 if ( ((SdrGrafObj*)pObj)->GetGraphic().GetType() == GRAPHIC_BITMAP )
115 eMode = SC_SELTRANS_DRAW_BITMAP;
116 else
117 eMode = SC_SELTRANS_DRAW_GRAPHIC;
119 else if ( nSdrObjKind == OBJ_OLE2 )
120 eMode = SC_SELTRANS_DRAW_OLE;
121 else if ( lcl_IsURLButton( pObj ) )
122 eMode = SC_SELTRANS_DRAW_BOOKMARK;
125 if ( eMode == SC_SELTRANS_INVALID )
126 eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection
129 if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected
131 ScRange aRange;
132 ScViewData* pViewData = pView->GetViewData();
133 const ScMarkData& rMark = pViewData->GetMarkData();
134 // allow MultiMarked because GetSimpleArea may be able to merge into a simple range
135 // (GetSimpleArea modifies a local copy of MarkData)
136 // Also allow simple filtered area.
137 ScMarkType eMarkType;
138 if ( ( rMark.IsMarked() || rMark.IsMultiMarked() ) &&
139 (((eMarkType = pViewData->GetSimpleArea( aRange )) == SC_MARK_SIMPLE) ||
140 (eMarkType == SC_MARK_SIMPLE_FILTERED)) )
142 // only for "real" selection, cursor alone isn't used
143 if ( aRange.aStart == aRange.aEnd )
144 eMode = SC_SELTRANS_CELL;
145 else
146 eMode = SC_SELTRANS_CELLS;
150 if ( eMode != SC_SELTRANS_INVALID )
151 pRet = new ScSelectionTransferObj( pView, eMode );
154 return pRet;
158 ScSelectionTransferObj::ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode ) :
159 pView( pSource ),
160 eMode( eNewMode ),
161 pCellData( NULL ),
162 pDrawData( NULL )
164 //! store range for StillValid
167 ScSelectionTransferObj::~ScSelectionTransferObj()
169 ScModule* pScMod = SC_MOD();
170 if ( pScMod->GetSelectionTransfer() == this )
172 // this is reached when the object wasn't really copied to the selection
173 // (CopyToSelection has no effect under Windows)
175 ForgetView();
176 pScMod->SetSelectionTransfer( NULL );
179 DBG_ASSERT( !pView, "ScSelectionTransferObj dtor: ForgetView not called" );
182 BOOL ScSelectionTransferObj::StillValid()
184 //! check if view still has same cell selection
185 //! (but return FALSE if data has changed inbetween)
186 return FALSE;
189 void ScSelectionTransferObj::ForgetView()
191 pView = NULL;
192 eMode = SC_SELTRANS_INVALID;
194 if (pCellData)
196 pCellData->release();
197 pCellData = NULL;
199 if (pDrawData)
201 pDrawData->release();
202 pDrawData = NULL;
206 void ScSelectionTransferObj::AddSupportedFormats()
208 // AddSupportedFormats must work without actually creating the
209 // "real" transfer object
211 switch (eMode)
213 case SC_SELTRANS_CELL:
214 case SC_SELTRANS_CELLS:
215 // same formats as in ScTransferObj::AddSupportedFormats
216 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
217 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
218 AddFormat( SOT_FORMAT_GDIMETAFILE );
219 AddFormat( SOT_FORMAT_BITMAP );
220 AddFormat( SOT_FORMATSTR_ID_HTML );
221 AddFormat( SOT_FORMATSTR_ID_SYLK );
222 AddFormat( SOT_FORMATSTR_ID_LINK );
223 AddFormat( SOT_FORMATSTR_ID_DIF );
224 AddFormat( SOT_FORMAT_STRING );
225 AddFormat( SOT_FORMAT_RTF );
226 if ( eMode == SC_SELTRANS_CELL )
227 AddFormat( SOT_FORMATSTR_ID_EDITENGINE );
228 break;
230 // different graphic formats as in ScDrawTransferObj::AddSupportedFormats:
232 case SC_SELTRANS_DRAW_BITMAP:
233 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
234 AddFormat( SOT_FORMATSTR_ID_SVXB );
235 AddFormat( SOT_FORMAT_BITMAP );
236 AddFormat( SOT_FORMAT_GDIMETAFILE );
237 break;
239 case SC_SELTRANS_DRAW_GRAPHIC:
240 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
241 AddFormat( SOT_FORMATSTR_ID_SVXB );
242 AddFormat( SOT_FORMAT_GDIMETAFILE );
243 AddFormat( SOT_FORMAT_BITMAP );
244 break;
246 case SC_SELTRANS_DRAW_BOOKMARK:
247 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
248 AddFormat( SOT_FORMATSTR_ID_SOLK );
249 AddFormat( SOT_FORMAT_STRING );
250 AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
251 AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
252 AddFormat( SOT_FORMATSTR_ID_DRAWING );
253 break;
255 case SC_SELTRANS_DRAW_OLE:
256 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
257 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
258 AddFormat( SOT_FORMAT_GDIMETAFILE );
259 break;
261 case SC_SELTRANS_DRAW_OTHER:
262 // other drawing objects
263 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
264 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
265 AddFormat( SOT_FORMATSTR_ID_DRAWING );
266 AddFormat( SOT_FORMAT_BITMAP );
267 AddFormat( SOT_FORMAT_GDIMETAFILE );
268 break;
270 default:
272 // added to avoid warnings
277 void ScSelectionTransferObj::CreateCellData()
279 DBG_ASSERT( !pCellData, "CreateCellData twice" );
280 if ( pView )
282 ScViewData* pViewData = pView->GetViewData();
283 ScMarkData aNewMark( pViewData->GetMarkData() ); // use local copy for MarkToSimple
284 aNewMark.MarkToSimple();
286 // similar to ScViewFunctionSet::BeginDrag
287 if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() )
289 ScDocShell* pDocSh = pViewData->GetDocShell();
291 ScRange aSelRange;
292 aNewMark.GetMarkArea( aSelRange );
293 ScDocShellRef aDragShellRef;
294 if ( pDocSh->GetDocument()->HasOLEObjectsInArea( aSelRange, &aNewMark ) )
296 aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
297 aDragShellRef->DoInitNew(NULL);
299 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
301 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
302 // bApi = TRUE -> no error mesages
303 // #i18364# bStopEdit = FALSE -> don't end edit mode
304 // (this may be called from pasting into the edit line)
305 BOOL bCopied = pViewData->GetView()->CopyToClip( pClipDoc, FALSE, TRUE, TRUE, FALSE );
307 ScDrawLayer::SetGlobalDrawPersist(NULL);
309 if ( bCopied )
311 TransferableObjectDescriptor aObjDesc;
312 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
313 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
314 // maSize is set in ScTransferObj ctor
316 ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
317 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
319 // SetDragHandlePos is not used - there is no mouse position
320 //? pTransferObj->SetVisibleTab( nTab );
322 SfxObjectShellRef aPersistRef( aDragShellRef );
323 pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
325 pTransferObj->SetDragSource( pDocSh, aNewMark );
327 pCellData = pTransferObj;
328 pCellData->acquire(); // keep ref count up - released in ForgetView
330 else
331 delete pClipDoc;
334 DBG_ASSERT( pCellData, "can't create CellData" );
337 //! make static member of ScDrawView
338 extern void lcl_CheckOle( const SdrMarkList& rMarkList, BOOL& rAnyOle, BOOL& rOneOle );
340 void ScSelectionTransferObj::CreateDrawData()
342 DBG_ASSERT( !pDrawData, "CreateDrawData twice" );
343 if ( pView )
345 // similar to ScDrawView::BeginDrag
347 ScDrawView* pDrawView = pView->GetScDrawView();
348 if ( pDrawView )
350 BOOL bAnyOle, bOneOle;
351 const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList();
352 lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
354 //---------------------------------------------------------
355 ScDocShellRef aDragShellRef;
356 if (bAnyOle)
358 aDragShellRef = new ScDocShell; // ohne Ref lebt die DocShell nicht !!!
359 aDragShellRef->DoInitNew(NULL);
361 //---------------------------------------------------------
363 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
364 SdrModel* pModel = pDrawView->GetAllMarkedModel();
365 ScDrawLayer::SetGlobalDrawPersist(NULL);
367 ScViewData* pViewData = pView->GetViewData();
368 ScDocShell* pDocSh = pViewData->GetDocShell();
370 TransferableObjectDescriptor aObjDesc;
371 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
372 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
373 // maSize is set in ScDrawTransferObj ctor
375 ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
376 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
378 SfxObjectShellRef aPersistRef( aDragShellRef );
379 pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
380 pTransferObj->SetDragSource( pDrawView ); // copies selection
382 pDrawData = pTransferObj;
383 pDrawData->acquire(); // keep ref count up - released in ForgetView
386 DBG_ASSERT( pDrawData, "can't create DrawData" );
389 ScTransferObj* ScSelectionTransferObj::GetCellData()
391 if ( !pCellData && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) )
392 CreateCellData();
393 return pCellData;
396 ScDrawTransferObj* ScSelectionTransferObj::GetDrawData()
398 if ( !pDrawData && ( eMode == SC_SELTRANS_DRAW_BITMAP || eMode == SC_SELTRANS_DRAW_GRAPHIC ||
399 eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE ||
400 eMode == SC_SELTRANS_DRAW_OTHER ) )
401 CreateDrawData();
402 return pDrawData;
405 sal_Bool ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
407 sal_Bool bOK = sal_False;
409 uno::Reference<datatransfer::XTransferable> xSource;
410 switch (eMode)
412 case SC_SELTRANS_CELL:
413 case SC_SELTRANS_CELLS:
414 xSource = GetCellData();
415 break;
416 case SC_SELTRANS_DRAW_BITMAP:
417 case SC_SELTRANS_DRAW_GRAPHIC:
418 case SC_SELTRANS_DRAW_BOOKMARK:
419 case SC_SELTRANS_DRAW_OLE:
420 case SC_SELTRANS_DRAW_OTHER:
421 xSource = GetDrawData();
422 break;
423 default:
425 // added to avoid warnings
429 if ( xSource.is() )
431 TransferableDataHelper aHelper( xSource );
432 uno::Any aAny = aHelper.GetAny( rFlavor );
433 bOK = SetAny( aAny, rFlavor );
436 return bOK;
439 void ScSelectionTransferObj::ObjectReleased()
441 // called when another selection is set from outside
443 ForgetView();
445 ScModule* pScMod = SC_MOD();
446 if ( pScMod->GetSelectionTransfer() == this )
447 pScMod->SetSelectionTransfer( NULL );
449 TransferableHelper::ObjectReleased();