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