xref: /AOO41X/main/sc/source/ui/app/seltrans.cxx (revision a206ee714f966ac34d586aa0448e90cdf7eed74e)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 // INCLUDE ---------------------------------------------------------------
28 
29 
30 
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/beans/XPropertySetInfo.hpp>
33 #include <com/sun/star/form/FormButtonType.hpp>
34 
35 #include <tools/urlobj.hxx>
36 #include <sfx2/docfile.hxx>
37 #include <svx/fmglob.hxx>
38 #include <svx/svdograf.hxx>
39 #include <svx/svdouno.hxx>
40 
41 #include "seltrans.hxx"
42 #include "transobj.hxx"
43 #include "drwtrans.hxx"
44 #include "scmod.hxx"
45 #include "dbfunc.hxx"   // for CopyToClip
46 #include "docsh.hxx"
47 #include "drawview.hxx"
48 #include "drwlayer.hxx"
49 
50 using namespace com::sun::star;
51 
52 // -----------------------------------------------------------------------
53 
lcl_IsURLButton(SdrObject * pObject)54 sal_Bool lcl_IsURLButton( SdrObject* pObject )
55 {
56     sal_Bool bRet = sal_False;
57 
58     SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject);
59     if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
60     {
61         uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
62         DBG_ASSERT( xControlModel.is(), "uno control without model" );
63         if ( xControlModel.is() )
64         {
65             uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
66             uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
67 
68             rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" );
69             if(xInfo->hasPropertyByName( sPropButtonType ))
70             {
71                 uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
72                 form::FormButtonType eTmp;
73                 if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
74                     bRet = sal_True;
75             }
76         }
77     }
78 
79     return bRet;
80 }
81 
82 // static
83 
CreateFromView(ScTabView * pView)84 ScSelectionTransferObj* ScSelectionTransferObj::CreateFromView( ScTabView* pView )
85 {
86     ScSelectionTransferObj* pRet = NULL;
87 
88     if ( pView )
89     {
90         ScSelectionTransferMode eMode = SC_SELTRANS_INVALID;
91 
92         SdrView* pSdrView = pView->GetSdrView();
93         if ( pSdrView )
94         {
95             //  handle selection on drawing layer
96             const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
97             sal_uLong nMarkCount = rMarkList.GetMarkCount();
98             if ( nMarkCount )
99             {
100                 if ( nMarkCount == 1 )
101                 {
102                     SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
103                     sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
104 
105                     if ( nSdrObjKind == OBJ_GRAF )
106                     {
107                         if ( ((SdrGrafObj*)pObj)->GetGraphic().GetType() == GRAPHIC_BITMAP )
108                             eMode = SC_SELTRANS_DRAW_BITMAP;
109                         else
110                             eMode = SC_SELTRANS_DRAW_GRAPHIC;
111                     }
112                     else if ( nSdrObjKind == OBJ_OLE2 )
113                         eMode = SC_SELTRANS_DRAW_OLE;
114                     else if ( lcl_IsURLButton( pObj ) )
115                         eMode = SC_SELTRANS_DRAW_BOOKMARK;
116                 }
117 
118                 if ( eMode == SC_SELTRANS_INVALID )
119                     eMode = SC_SELTRANS_DRAW_OTHER;     // something selected but no special selection
120             }
121         }
122         if ( eMode == SC_SELTRANS_INVALID )             // no drawing object selected
123         {
124             ScRange aRange;
125             ScViewData* pViewData = pView->GetViewData();
126             const ScMarkData& rMark = pViewData->GetMarkData();
127             //  allow MultiMarked because GetSimpleArea may be able to merge into a simple range
128             //  (GetSimpleArea modifies a local copy of MarkData)
129             // Also allow simple filtered area.
130             ScMarkType eMarkType;
131             if ( ( rMark.IsMarked() || rMark.IsMultiMarked() ) &&
132                     (((eMarkType = pViewData->GetSimpleArea( aRange )) == SC_MARK_SIMPLE) ||
133                      (eMarkType == SC_MARK_SIMPLE_FILTERED)) )
134             {
135                 //  only for "real" selection, cursor alone isn't used
136                 if ( aRange.aStart == aRange.aEnd )
137                     eMode = SC_SELTRANS_CELL;
138                 else
139                     eMode = SC_SELTRANS_CELLS;
140             }
141         }
142 
143         if ( eMode != SC_SELTRANS_INVALID )
144             pRet = new ScSelectionTransferObj( pView, eMode );
145     }
146 
147     return pRet;
148 }
149 
150 
ScSelectionTransferObj(ScTabView * pSource,ScSelectionTransferMode eNewMode)151 ScSelectionTransferObj::ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode ) :
152     pView( pSource ),
153     eMode( eNewMode ),
154     pCellData( NULL ),
155     pDrawData( NULL )
156 {
157     //! store range for StillValid
158 }
159 
~ScSelectionTransferObj()160 ScSelectionTransferObj::~ScSelectionTransferObj()
161 {
162     ScModule* pScMod = SC_MOD();
163     if ( pScMod->GetSelectionTransfer() == this )
164     {
165         //  this is reached when the object wasn't really copied to the selection
166         //  (CopyToSelection has no effect under Windows)
167 
168         ForgetView();
169         pScMod->SetSelectionTransfer( NULL );
170     }
171 
172     DBG_ASSERT( !pView, "ScSelectionTransferObj dtor: ForgetView not called" );
173 }
174 
StillValid()175 sal_Bool ScSelectionTransferObj::StillValid()
176 {
177     //! check if view still has same cell selection
178     //! (but return sal_False if data has changed inbetween)
179     return sal_False;
180 }
181 
ForgetView()182 void ScSelectionTransferObj::ForgetView()
183 {
184     pView = NULL;
185     eMode = SC_SELTRANS_INVALID;
186 
187     if (pCellData)
188     {
189         pCellData->release();
190         pCellData = NULL;
191     }
192     if (pDrawData)
193     {
194         pDrawData->release();
195         pDrawData = NULL;
196     }
197 }
198 
AddSupportedFormats()199 void ScSelectionTransferObj::AddSupportedFormats()
200 {
201     //  AddSupportedFormats must work without actually creating the
202     //  "real" transfer object
203 
204     switch (eMode)
205     {
206         case SC_SELTRANS_CELL:
207         case SC_SELTRANS_CELLS:
208             //  same formats as in ScTransferObj::AddSupportedFormats
209             AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
210             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
211             AddFormat( SOT_FORMAT_GDIMETAFILE );
212             AddFormat( SOT_FORMATSTR_ID_PNG );
213             AddFormat( SOT_FORMAT_BITMAP );
214             AddFormat( SOT_FORMATSTR_ID_HTML );
215             AddFormat( SOT_FORMATSTR_ID_SYLK );
216             AddFormat( SOT_FORMATSTR_ID_LINK );
217             AddFormat( SOT_FORMATSTR_ID_DIF );
218             AddFormat( SOT_FORMAT_STRING );
219             AddFormat( SOT_FORMAT_RTF );
220             if ( eMode == SC_SELTRANS_CELL )
221                 AddFormat( SOT_FORMATSTR_ID_EDITENGINE );
222             break;
223 
224         // different graphic formats as in ScDrawTransferObj::AddSupportedFormats:
225 
226         case SC_SELTRANS_DRAW_BITMAP:
227             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
228             AddFormat( SOT_FORMATSTR_ID_SVXB );
229             AddFormat( SOT_FORMATSTR_ID_PNG );
230             AddFormat( SOT_FORMAT_BITMAP );
231             AddFormat( SOT_FORMAT_GDIMETAFILE );
232             break;
233 
234         case SC_SELTRANS_DRAW_GRAPHIC:
235             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
236             AddFormat( SOT_FORMATSTR_ID_SVXB );
237             AddFormat( SOT_FORMAT_GDIMETAFILE );
238             AddFormat( SOT_FORMATSTR_ID_PNG );
239             AddFormat( SOT_FORMAT_BITMAP );
240             break;
241 
242         case SC_SELTRANS_DRAW_BOOKMARK:
243             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
244             AddFormat( SOT_FORMATSTR_ID_SOLK );
245             AddFormat( SOT_FORMAT_STRING );
246             AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
247             AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
248             AddFormat( SOT_FORMATSTR_ID_DRAWING );
249             break;
250 
251         case SC_SELTRANS_DRAW_OLE:
252             AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
253             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
254             AddFormat( SOT_FORMAT_GDIMETAFILE );
255             break;
256 
257         case SC_SELTRANS_DRAW_OTHER:
258             //  other drawing objects
259             AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
260             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
261             AddFormat( SOT_FORMATSTR_ID_DRAWING );
262             AddFormat( SOT_FORMATSTR_ID_PNG );
263             AddFormat( SOT_FORMAT_BITMAP );
264             AddFormat( SOT_FORMAT_GDIMETAFILE );
265             break;
266 
267         default:
268         {
269             // added to avoid warnings
270         }
271     }
272 }
273 
CreateCellData()274 void ScSelectionTransferObj::CreateCellData()
275 {
276     DBG_ASSERT( !pCellData, "CreateCellData twice" );
277     if ( pView )
278     {
279         ScViewData* pViewData = pView->GetViewData();
280         ScMarkData aNewMark( pViewData->GetMarkData() );    // use local copy for MarkToSimple
281         aNewMark.MarkToSimple();
282 
283         //  similar to ScViewFunctionSet::BeginDrag
284         if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() )
285         {
286             ScDocShell* pDocSh = pViewData->GetDocShell();
287 
288             ScRange aSelRange;
289             aNewMark.GetMarkArea( aSelRange );
290             ScDocShellRef aDragShellRef;
291             if ( pDocSh->GetDocument()->HasOLEObjectsInArea( aSelRange, &aNewMark ) )
292             {
293                 aDragShellRef = new ScDocShell;     // DocShell needs a Ref immediately
294                 aDragShellRef->DoInitNew(NULL);
295             }
296             ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
297 
298             ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
299             // bApi = sal_True -> no error mesages
300             // #i18364# bStopEdit = sal_False -> don't end edit mode
301             // (this may be called from pasting into the edit line)
302             sal_Bool bCopied = pViewData->GetView()->CopyToClip( pClipDoc, sal_False, sal_True, sal_True, sal_False );
303 
304             ScDrawLayer::SetGlobalDrawPersist(NULL);
305 
306             if ( bCopied )
307             {
308                 TransferableObjectDescriptor aObjDesc;
309                 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
310                 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
311                 // maSize is set in ScTransferObj ctor
312 
313                 ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
314                 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
315 
316                 // SetDragHandlePos is not used - there is no mouse position
317                 //? pTransferObj->SetVisibleTab( nTab );
318 
319                 SfxObjectShellRef aPersistRef( aDragShellRef );
320                 pTransferObj->SetDrawPersist( aPersistRef );    // keep persist for ole objects alive
321 
322                 pTransferObj->SetDragSource( pDocSh, aNewMark );
323 
324                 pCellData = pTransferObj;
325                 pCellData->acquire();       // keep ref count up - released in ForgetView
326             }
327             else
328                 delete pClipDoc;
329         }
330     }
331     DBG_ASSERT( pCellData, "can't create CellData" );
332 }
333 
334 //! make static member of ScDrawView
335 extern void lcl_CheckOle( const SdrMarkList& rMarkList, sal_Bool& rAnyOle, sal_Bool& rOneOle );
336 
CreateDrawData()337 void ScSelectionTransferObj::CreateDrawData()
338 {
339     DBG_ASSERT( !pDrawData, "CreateDrawData twice" );
340     if ( pView )
341     {
342         //  similar to ScDrawView::BeginDrag
343 
344         ScDrawView* pDrawView = pView->GetScDrawView();
345         if ( pDrawView )
346         {
347             sal_Bool bAnyOle, bOneOle;
348             const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList();
349             lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
350 
351             //---------------------------------------------------------
352             ScDocShellRef aDragShellRef;
353             if (bAnyOle)
354             {
355                 aDragShellRef = new ScDocShell;     // ohne Ref lebt die DocShell nicht !!!
356                 aDragShellRef->DoInitNew(NULL);
357             }
358             //---------------------------------------------------------
359 
360             ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
361             SdrModel* pModel = pDrawView->GetAllMarkedModel();
362             ScDrawLayer::SetGlobalDrawPersist(NULL);
363 
364             ScViewData* pViewData = pView->GetViewData();
365             ScDocShell* pDocSh = pViewData->GetDocShell();
366 
367             TransferableObjectDescriptor aObjDesc;
368             pDocSh->FillTransferableObjectDescriptor( aObjDesc );
369             aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
370             // maSize is set in ScDrawTransferObj ctor
371 
372             ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
373             uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
374 
375             SfxObjectShellRef aPersistRef( aDragShellRef );
376             pTransferObj->SetDrawPersist( aPersistRef );    // keep persist for ole objects alive
377             pTransferObj->SetDragSource( pDrawView );       // copies selection
378 
379             pDrawData = pTransferObj;
380             pDrawData->acquire();       // keep ref count up - released in ForgetView
381         }
382     }
383     DBG_ASSERT( pDrawData, "can't create DrawData" );
384 }
385 
GetCellData()386 ScTransferObj* ScSelectionTransferObj::GetCellData()
387 {
388     if ( !pCellData && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) )
389         CreateCellData();
390     return pCellData;
391 }
392 
GetDrawData()393 ScDrawTransferObj* ScSelectionTransferObj::GetDrawData()
394 {
395     if ( !pDrawData && ( eMode == SC_SELTRANS_DRAW_BITMAP || eMode == SC_SELTRANS_DRAW_GRAPHIC ||
396                          eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE ||
397                          eMode == SC_SELTRANS_DRAW_OTHER ) )
398         CreateDrawData();
399     return pDrawData;
400 }
401 
GetData(const::com::sun::star::datatransfer::DataFlavor & rFlavor)402 sal_Bool ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
403 {
404     sal_Bool bOK = sal_False;
405 
406     uno::Reference<datatransfer::XTransferable> xSource;
407     switch (eMode)
408     {
409         case SC_SELTRANS_CELL:
410         case SC_SELTRANS_CELLS:
411             xSource = GetCellData();
412             break;
413         case SC_SELTRANS_DRAW_BITMAP:
414         case SC_SELTRANS_DRAW_GRAPHIC:
415         case SC_SELTRANS_DRAW_BOOKMARK:
416         case SC_SELTRANS_DRAW_OLE:
417         case SC_SELTRANS_DRAW_OTHER:
418             xSource = GetDrawData();
419             break;
420         default:
421         {
422             // added to avoid warnings
423         }
424     }
425 
426     if ( xSource.is() )
427     {
428         TransferableDataHelper aHelper( xSource );
429         uno::Any aAny = aHelper.GetAny( rFlavor );
430         bOK = SetAny( aAny, rFlavor );
431     }
432 
433     return bOK;
434 }
435 
ObjectReleased()436 void ScSelectionTransferObj::ObjectReleased()
437 {
438     //  called when another selection is set from outside
439 
440     ForgetView();
441 
442     ScModule* pScMod = SC_MOD();
443     if ( pScMod->GetSelectionTransfer() == this )
444         pScMod->SetSelectionTransfer( NULL );
445 
446     TransferableHelper::ObjectReleased();
447 }
448 
449 
450