xref: /AOO41X/main/sc/source/ui/app/seltrans.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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 
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 
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 
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 
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 
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 
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 
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_FORMAT_BITMAP );
213             AddFormat( SOT_FORMATSTR_ID_HTML );
214             AddFormat( SOT_FORMATSTR_ID_SYLK );
215             AddFormat( SOT_FORMATSTR_ID_LINK );
216             AddFormat( SOT_FORMATSTR_ID_DIF );
217             AddFormat( SOT_FORMAT_STRING );
218             AddFormat( SOT_FORMAT_RTF );
219             if ( eMode == SC_SELTRANS_CELL )
220                 AddFormat( SOT_FORMATSTR_ID_EDITENGINE );
221             break;
222 
223         // different graphic formats as in ScDrawTransferObj::AddSupportedFormats:
224 
225         case SC_SELTRANS_DRAW_BITMAP:
226             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
227             AddFormat( SOT_FORMATSTR_ID_SVXB );
228             AddFormat( SOT_FORMAT_BITMAP );
229             AddFormat( SOT_FORMAT_GDIMETAFILE );
230             break;
231 
232         case SC_SELTRANS_DRAW_GRAPHIC:
233             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
234             AddFormat( SOT_FORMATSTR_ID_SVXB );
235             AddFormat( SOT_FORMAT_GDIMETAFILE );
236             AddFormat( SOT_FORMAT_BITMAP );
237             break;
238 
239         case SC_SELTRANS_DRAW_BOOKMARK:
240             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
241             AddFormat( SOT_FORMATSTR_ID_SOLK );
242             AddFormat( SOT_FORMAT_STRING );
243             AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
244             AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
245             AddFormat( SOT_FORMATSTR_ID_DRAWING );
246             break;
247 
248         case SC_SELTRANS_DRAW_OLE:
249             AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
250             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
251             AddFormat( SOT_FORMAT_GDIMETAFILE );
252             break;
253 
254         case SC_SELTRANS_DRAW_OTHER:
255             //  other drawing objects
256             AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
257             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
258             AddFormat( SOT_FORMATSTR_ID_DRAWING );
259             AddFormat( SOT_FORMAT_BITMAP );
260             AddFormat( SOT_FORMAT_GDIMETAFILE );
261             break;
262 
263         default:
264         {
265             // added to avoid warnings
266         }
267     }
268 }
269 
270 void ScSelectionTransferObj::CreateCellData()
271 {
272     DBG_ASSERT( !pCellData, "CreateCellData twice" );
273     if ( pView )
274     {
275         ScViewData* pViewData = pView->GetViewData();
276         ScMarkData aNewMark( pViewData->GetMarkData() );    // use local copy for MarkToSimple
277         aNewMark.MarkToSimple();
278 
279         //  similar to ScViewFunctionSet::BeginDrag
280         if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() )
281         {
282             ScDocShell* pDocSh = pViewData->GetDocShell();
283 
284             ScRange aSelRange;
285             aNewMark.GetMarkArea( aSelRange );
286             ScDocShellRef aDragShellRef;
287             if ( pDocSh->GetDocument()->HasOLEObjectsInArea( aSelRange, &aNewMark ) )
288             {
289                 aDragShellRef = new ScDocShell;     // DocShell needs a Ref immediately
290                 aDragShellRef->DoInitNew(NULL);
291             }
292             ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
293 
294             ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
295             // bApi = sal_True -> no error mesages
296             // #i18364# bStopEdit = sal_False -> don't end edit mode
297             // (this may be called from pasting into the edit line)
298             sal_Bool bCopied = pViewData->GetView()->CopyToClip( pClipDoc, sal_False, sal_True, sal_True, sal_False );
299 
300             ScDrawLayer::SetGlobalDrawPersist(NULL);
301 
302             if ( bCopied )
303             {
304                 TransferableObjectDescriptor aObjDesc;
305                 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
306                 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
307                 // maSize is set in ScTransferObj ctor
308 
309                 ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
310                 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
311 
312                 // SetDragHandlePos is not used - there is no mouse position
313                 //? pTransferObj->SetVisibleTab( nTab );
314 
315                 SfxObjectShellRef aPersistRef( aDragShellRef );
316                 pTransferObj->SetDrawPersist( aPersistRef );    // keep persist for ole objects alive
317 
318                 pTransferObj->SetDragSource( pDocSh, aNewMark );
319 
320                 pCellData = pTransferObj;
321                 pCellData->acquire();       // keep ref count up - released in ForgetView
322             }
323             else
324                 delete pClipDoc;
325         }
326     }
327     DBG_ASSERT( pCellData, "can't create CellData" );
328 }
329 
330 //! make static member of ScDrawView
331 extern void lcl_CheckOle( const SdrMarkList& rMarkList, sal_Bool& rAnyOle, sal_Bool& rOneOle );
332 
333 void ScSelectionTransferObj::CreateDrawData()
334 {
335     DBG_ASSERT( !pDrawData, "CreateDrawData twice" );
336     if ( pView )
337     {
338         //  similar to ScDrawView::BeginDrag
339 
340         ScDrawView* pDrawView = pView->GetScDrawView();
341         if ( pDrawView )
342         {
343             sal_Bool bAnyOle, bOneOle;
344             const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList();
345             lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
346 
347             //---------------------------------------------------------
348             ScDocShellRef aDragShellRef;
349             if (bAnyOle)
350             {
351                 aDragShellRef = new ScDocShell;     // ohne Ref lebt die DocShell nicht !!!
352                 aDragShellRef->DoInitNew(NULL);
353             }
354             //---------------------------------------------------------
355 
356             ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
357             SdrModel* pModel = pDrawView->GetAllMarkedModel();
358             ScDrawLayer::SetGlobalDrawPersist(NULL);
359 
360             ScViewData* pViewData = pView->GetViewData();
361             ScDocShell* pDocSh = pViewData->GetDocShell();
362 
363             TransferableObjectDescriptor aObjDesc;
364             pDocSh->FillTransferableObjectDescriptor( aObjDesc );
365             aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
366             // maSize is set in ScDrawTransferObj ctor
367 
368             ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
369             uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
370 
371             SfxObjectShellRef aPersistRef( aDragShellRef );
372             pTransferObj->SetDrawPersist( aPersistRef );    // keep persist for ole objects alive
373             pTransferObj->SetDragSource( pDrawView );       // copies selection
374 
375             pDrawData = pTransferObj;
376             pDrawData->acquire();       // keep ref count up - released in ForgetView
377         }
378     }
379     DBG_ASSERT( pDrawData, "can't create DrawData" );
380 }
381 
382 ScTransferObj* ScSelectionTransferObj::GetCellData()
383 {
384     if ( !pCellData && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) )
385         CreateCellData();
386     return pCellData;
387 }
388 
389 ScDrawTransferObj* ScSelectionTransferObj::GetDrawData()
390 {
391     if ( !pDrawData && ( eMode == SC_SELTRANS_DRAW_BITMAP || eMode == SC_SELTRANS_DRAW_GRAPHIC ||
392                          eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE ||
393                          eMode == SC_SELTRANS_DRAW_OTHER ) )
394         CreateDrawData();
395     return pDrawData;
396 }
397 
398 sal_Bool ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
399 {
400     sal_Bool bOK = sal_False;
401 
402     uno::Reference<datatransfer::XTransferable> xSource;
403     switch (eMode)
404     {
405         case SC_SELTRANS_CELL:
406         case SC_SELTRANS_CELLS:
407             xSource = GetCellData();
408             break;
409         case SC_SELTRANS_DRAW_BITMAP:
410         case SC_SELTRANS_DRAW_GRAPHIC:
411         case SC_SELTRANS_DRAW_BOOKMARK:
412         case SC_SELTRANS_DRAW_OLE:
413         case SC_SELTRANS_DRAW_OTHER:
414             xSource = GetDrawData();
415             break;
416         default:
417         {
418             // added to avoid warnings
419         }
420     }
421 
422     if ( xSource.is() )
423     {
424         TransferableDataHelper aHelper( xSource );
425         uno::Any aAny = aHelper.GetAny( rFlavor );
426         bOK = SetAny( aAny, rFlavor );
427     }
428 
429     return bOK;
430 }
431 
432 void ScSelectionTransferObj::ObjectReleased()
433 {
434     //  called when another selection is set from outside
435 
436     ForgetView();
437 
438     ScModule* pScMod = SC_MOD();
439     if ( pScMod->GetSelectionTransfer() == this )
440         pScMod->SetSelectionTransfer( NULL );
441 
442     TransferableHelper::ObjectReleased();
443 }
444 
445 
446