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