1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: seltrans.cxx,v $
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"
52 #include "dbfunc.hxx" // for CopyToClip
54 #include "drawview.hxx"
55 #include "drwlayer.hxx"
57 using namespace com::sun::star
;
59 // -----------------------------------------------------------------------
61 BOOL
lcl_IsURLButton( SdrObject
* pObject
)
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
)
91 ScSelectionTransferObj
* ScSelectionTransferObj::CreateFromView( ScTabView
* pView
)
93 ScSelectionTransferObj
* pRet
= NULL
;
97 ScSelectionTransferMode eMode
= SC_SELTRANS_INVALID
;
99 SdrView
* pSdrView
= pView
->GetSdrView();
102 // handle selection on drawing layer
103 const SdrMarkList
& rMarkList
= pSdrView
->GetMarkedObjectList();
104 ULONG nMarkCount
= rMarkList
.GetMarkCount();
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
;
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
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
;
146 eMode
= SC_SELTRANS_CELLS
;
150 if ( eMode
!= SC_SELTRANS_INVALID
)
151 pRet
= new ScSelectionTransferObj( pView
, eMode
);
158 ScSelectionTransferObj::ScSelectionTransferObj( ScTabView
* pSource
, ScSelectionTransferMode eNewMode
) :
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)
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)
189 void ScSelectionTransferObj::ForgetView()
192 eMode
= SC_SELTRANS_INVALID
;
196 pCellData
->release();
201 pDrawData
->release();
206 void ScSelectionTransferObj::AddSupportedFormats()
208 // AddSupportedFormats must work without actually creating the
209 // "real" transfer object
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
);
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
);
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
);
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
);
255 case SC_SELTRANS_DRAW_OLE
:
256 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
);
257 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
);
258 AddFormat( SOT_FORMAT_GDIMETAFILE
);
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
);
272 // added to avoid warnings
277 void ScSelectionTransferObj::CreateCellData()
279 DBG_ASSERT( !pCellData
, "CreateCellData twice" );
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();
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
);
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
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" );
345 // similar to ScDrawView::BeginDrag
347 ScDrawView
* pDrawView
= pView
->GetScDrawView();
350 BOOL bAnyOle
, bOneOle
;
351 const SdrMarkList
& rMarkList
= pDrawView
->GetMarkedObjectList();
352 lcl_CheckOle( rMarkList
, bAnyOle
, bOneOle
);
354 //---------------------------------------------------------
355 ScDocShellRef aDragShellRef
;
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
) )
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
) )
405 sal_Bool
ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
)
407 sal_Bool bOK
= sal_False
;
409 uno::Reference
<datatransfer::XTransferable
> xSource
;
412 case SC_SELTRANS_CELL
:
413 case SC_SELTRANS_CELLS
:
414 xSource
= GetCellData();
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();
425 // added to avoid warnings
431 TransferableDataHelper
aHelper( xSource
);
432 uno::Any aAny
= aHelper
.GetAny( rFlavor
);
433 bOK
= SetAny( aAny
, rFlavor
);
439 void ScSelectionTransferObj::ObjectReleased()
441 // called when another selection is set from outside
445 ScModule
* pScMod
= SC_MOD();
446 if ( pScMod
->GetSelectionTransfer() == this )
447 pScMod
->SetSelectionTransfer( NULL
);
449 TransferableHelper::ObjectReleased();