xref: /trunk/main/sc/source/ui/app/seltrans.cxx (revision a206ee71)
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