LibreOffice Module sc (master)  1
seltrans.cxx
Go to the documentation of this file.
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/svdograf.hxx>
27 #include <svx/svdouno.hxx>
28 #include <osl/diagnose.h>
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 static bool lcl_IsURLButton( SdrObject* pObject )
43 {
44  bool bRet = false;
45 
46  SdrUnoObj* pUnoCtrl = dynamic_cast<SdrUnoObj*>( pObject );
47  if (pUnoCtrl && SdrInventor::FmForm == pUnoCtrl->GetObjInventor())
48  {
49  const uno::Reference<awt::XControlModel>& xControlModel = pUnoCtrl->GetUnoControlModel();
50  OSL_ENSURE( xControlModel.is(), "uno control without model" );
51  if ( xControlModel.is() )
52  {
53  uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
54  uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
55 
56  OUString sPropButtonType( "ButtonType" );
57  if(xInfo->hasPropertyByName( sPropButtonType ))
58  {
59  uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
60  form::FormButtonType eTmp;
61  if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
62  bRet = true;
63  }
64  }
65  }
66 
67  return bRet;
68 }
69 
71 {
73 
74  try
75  {
76  if ( pView )
77  {
79 
80  SdrView* pSdrView = pView->GetScDrawView();
81  if ( pSdrView )
82  {
83  // handle selection on drawing layer
84  const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
85  const size_t nMarkCount = rMarkList.GetMarkCount();
86  if ( nMarkCount )
87  {
88  if ( nMarkCount == 1 )
89  {
90  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
91  sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
92 
93  if ( nSdrObjKind == OBJ_GRAF )
94  {
95  if ( static_cast<SdrGrafObj*>(pObj)->GetGraphic().GetType() == GraphicType::Bitmap )
97  else
99  }
100  else if ( nSdrObjKind == OBJ_OLE2 )
101  eMode = SC_SELTRANS_DRAW_OLE;
102  else if ( lcl_IsURLButton( pObj ) )
104  }
105 
106  if ( eMode == SC_SELTRANS_INVALID )
107  eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection
108  }
109  }
110  if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected
111  {
112  ScViewData& rViewData = pView->GetViewData();
113  const ScMarkData& rMark = rViewData.GetMarkData();
114  // allow MultiMarked because GetSimpleArea may be able to merge into a simple range
115  // (GetSimpleArea modifies a local copy of MarkData)
116  // Also allow simple filtered area.
117  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
118  {
119  ScRange aRange;
120  ScMarkType eMarkType = rViewData.GetSimpleArea( aRange );
121  if (eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED)
122  {
123  // only for "real" selection, cursor alone isn't used
124  if ( aRange.aStart == aRange.aEnd )
125  eMode = SC_SELTRANS_CELL;
126  else
127  eMode = SC_SELTRANS_CELLS;
128  }
129  }
130  }
131 
132  if ( eMode != SC_SELTRANS_INVALID )
133  pRet = new ScSelectionTransferObj( pView, eMode );
134  }
135  }
136  catch (...)
137  {
138  }
139 
140  return pRet;
141 }
142 
144  pView( pSource ),
145  eMode( eNewMode )
146 {
148 }
149 
151 {
152  ScModule* pScMod = SC_MOD();
153  if (pScMod && pScMod->GetSelectionTransfer() == this)
154  {
155  // this is reached when the object wasn't really copied to the selection
156  // (CopyToSelection has no effect under Windows)
157 
158  ForgetView();
159  pScMod->SetSelectionTransfer( nullptr );
160  }
161 
162  OSL_ENSURE( !pView, "ScSelectionTransferObj dtor: ForgetView not called" );
163 }
164 
166 {
167  pView = nullptr;
169 
170  mxCellData.clear();
171  mxDrawData.clear();
172 }
173 
175 {
176  // AddSupportedFormats must work without actually creating the
177  // "real" transfer object
178 
179  switch (eMode)
180  {
181  case SC_SELTRANS_CELL:
182  case SC_SELTRANS_CELLS:
183  // same formats as in ScTransferObj::AddSupportedFormats
184  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
185  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
186  AddFormat( SotClipboardFormatId::GDIMETAFILE );
187  AddFormat( SotClipboardFormatId::PNG );
188  AddFormat( SotClipboardFormatId::BITMAP );
189  AddFormat( SotClipboardFormatId::HTML );
190  AddFormat( SotClipboardFormatId::SYLK );
191  AddFormat( SotClipboardFormatId::LINK );
192  AddFormat( SotClipboardFormatId::DIF );
193  AddFormat( SotClipboardFormatId::STRING );
194  AddFormat( SotClipboardFormatId::STRING_TSVC );
195  AddFormat( SotClipboardFormatId::RTF );
196  AddFormat( SotClipboardFormatId::RICHTEXT );
197  if ( eMode == SC_SELTRANS_CELL )
198  {
199  AddFormat( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT );
200  }
201  break;
202 
203  // different graphic formats as in ScDrawTransferObj::AddSupportedFormats:
204 
206  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
207  AddFormat( SotClipboardFormatId::SVXB );
208  AddFormat( SotClipboardFormatId::PNG );
209  AddFormat( SotClipboardFormatId::BITMAP );
210  AddFormat( SotClipboardFormatId::GDIMETAFILE );
211  break;
212 
214  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
215  AddFormat( SotClipboardFormatId::SVXB );
216  AddFormat( SotClipboardFormatId::GDIMETAFILE );
217  AddFormat( SotClipboardFormatId::PNG );
218  AddFormat( SotClipboardFormatId::BITMAP );
219  break;
220 
222  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
223  AddFormat( SotClipboardFormatId::SOLK );
224  AddFormat( SotClipboardFormatId::STRING );
225  AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
226  AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
227  AddFormat( SotClipboardFormatId::DRAWING );
228  break;
229 
231  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
232  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
233  AddFormat( SotClipboardFormatId::GDIMETAFILE );
234  break;
235 
237  // other drawing objects
238  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
239  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
240  AddFormat( SotClipboardFormatId::DRAWING );
241  AddFormat( SotClipboardFormatId::PNG );
242  AddFormat( SotClipboardFormatId::BITMAP );
243  AddFormat( SotClipboardFormatId::GDIMETAFILE );
244  break;
245 
246  default:
247  {
248  // added to avoid warnings
249  }
250  }
251 }
252 
254 {
255  OSL_ENSURE( !mxCellData.is(), "CreateCellData twice" );
256  if ( pView )
257  {
258  ScViewData& rViewData = pView->GetViewData();
259  ScMarkData aNewMark( rViewData.GetMarkData() ); // use local copy for MarkToSimple
260  aNewMark.MarkToSimple();
261 
262  // similar to ScViewFunctionSet::BeginDrag
263  if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() )
264  {
265  ScDocShell* pDocSh = rViewData.GetDocShell();
266 
267  ScRange aSelRange;
268  aNewMark.GetMarkArea( aSelRange );
269  ScDocShellRef aDragShellRef;
270  if ( pDocSh->GetDocument().HasOLEObjectsInArea( aSelRange, &aNewMark ) )
271  {
272  aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
273  aDragShellRef->DoInitNew();
274  }
275  ScDrawLayer::SetGlobalDrawPersist( aDragShellRef.get() );
276 
278  // bApi = sal_True -> no error messages
279  // #i18364# bStopEdit = sal_False -> don't end edit mode
280  // (this may be called from pasting into the edit line)
281  bool bCopied = rViewData.GetView()->CopyToClip( pClipDoc.get(), false, true, true, false );
282 
284 
285  if ( bCopied )
286  {
288  pDocSh->FillTransferableObjectDescriptor( aObjDesc );
289  aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
290  // maSize is set in ScTransferObj ctor
291 
292  rtl::Reference<ScTransferObj> pTransferObj = new ScTransferObj( std::move(pClipDoc), aObjDesc );
293 
294  // SetDragHandlePos is not used - there is no mouse position
295  //? pTransferObj->SetVisibleTab( nTab );
296 
297  SfxObjectShellRef aPersistRef( aDragShellRef.get() );
298  pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
299 
300  pTransferObj->SetDragSource( pDocSh, aNewMark );
301 
302  mxCellData = pTransferObj;
303  }
304  }
305  }
306  OSL_ENSURE( mxCellData.is(), "can't create CellData" );
307 }
308 
310 {
311  OSL_ENSURE( !mxDrawData.is(), "CreateDrawData twice" );
312  if ( pView )
313  {
314  // similar to ScDrawView::BeginDrag
315 
316  ScDrawView* pDrawView = pView->GetScDrawView();
317  if ( pDrawView )
318  {
319  bool bAnyOle, bOneOle;
320  const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList();
321  ScDrawView::CheckOle( rMarkList, bAnyOle, bOneOle );
322 
323  ScDocShellRef aDragShellRef;
324  if (bAnyOle)
325  {
326  aDragShellRef = new ScDocShell; // Without Ref the DocShell does not live
327  aDragShellRef->DoInitNew();
328  }
329 
330  ScDrawLayer::SetGlobalDrawPersist( aDragShellRef.get() );
331  std::unique_ptr<SdrModel> pModel(pDrawView->CreateMarkedObjModel());
333 
334  ScViewData& rViewData = pView->GetViewData();
335  ScDocShell* pDocSh = rViewData.GetDocShell();
336 
338  pDocSh->FillTransferableObjectDescriptor( aObjDesc );
339  aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
340  // maSize is set in ScDrawTransferObj ctor
341 
342  rtl::Reference<ScDrawTransferObj> pTransferObj = new ScDrawTransferObj( std::move(pModel), pDocSh, aObjDesc );
343 
344  SfxObjectShellRef aPersistRef( aDragShellRef.get() );
345  pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
346  pTransferObj->SetDragSource( pDrawView ); // copies selection
347 
348  mxDrawData = pTransferObj;
349  }
350  }
351  OSL_ENSURE( mxDrawData.is(), "can't create DrawData" );
352 }
353 
355 {
356  if ( !mxCellData.is() && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) )
357  CreateCellData();
358  return mxCellData.get();
359 }
360 
362 {
366  CreateDrawData();
367  return mxDrawData.get();
368 }
369 
371  const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc )
372 {
373  bool bOK = false;
374 
375  uno::Reference<datatransfer::XTransferable> xSource;
376  switch (eMode)
377  {
378  case SC_SELTRANS_CELL:
379  case SC_SELTRANS_CELLS:
380  xSource = GetCellData();
381  break;
387  xSource = GetDrawData();
388  break;
389  default:
390  {
391  // added to avoid warnings
392  }
393  }
394 
395  if ( xSource.is() )
396  {
397  TransferableDataHelper aHelper( xSource );
398  uno::Any aAny = aHelper.GetAny(rFlavor, rDestDoc);
399  bOK = SetAny( aAny );
400  }
401 
402  return bOK;
403 }
404 
406 {
407  // called when another selection is set from outside
408 
409  ForgetView();
410 
411  ScModule* pScMod = SC_MOD();
412  if ( pScMod->GetSelectionTransfer() == this )
413  pScMod->SetSelectionTransfer( nullptr );
414 
416 }
417 
419 {
420  switch (eMode)
421  {
422  case SC_SELTRANS_CELL:
423  case SC_SELTRANS_CELLS:
424  return false;
425  default:
426  return true;
427  }
428 }
429 
430 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3109
virtual bool GetData(const css::datatransfer::DataFlavor &rFlavor, const OUString &rDestDoc) override
Definition: seltrans.cxx:370
virtual void AddSupportedFormats() override
Definition: seltrans.cxx:174
ScTransferObj * GetCellData()
Definition: seltrans.cxx:354
void MarkToSimple()
Definition: markdata.cxx:236
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:353
ScAddress aStart
Definition: address.hxx:499
size_t GetMarkCount() const
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:42
css::uno::Any GetAny(SotClipboardFormatId nFormat, const OUString &rDestDoc) const
SC_DLLPUBLIC bool CopyToClip(ScDocument *pClipDoc, bool bCut, bool bApi=false, bool bIncludeObjects=false, bool bStopEdit=true)
Definition: viewfun3.cxx:168
ScDrawTransferObj * GetDrawData()
Definition: seltrans.cxx:361
ScSelectionTransferObj(ScTabView *pSource, ScSelectionTransferMode eNewMode)
Definition: seltrans.cxx:143
ScAddress aEnd
Definition: address.hxx:500
SdrMark * GetMark(size_t nNum) const
virtual SdrObjKind GetObjIdentifier() const
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
void AddFormat(SotClipboardFormatId nFormat)
static bool lcl_IsURLButton(SdrObject *pObject)
Definition: seltrans.cxx:42
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2646
virtual std::unique_ptr< SdrModel > CreateMarkedObjModel() const override
bool IsMultiMarked() const
Definition: markdata.hxx:82
Mode eMode
ScViewData & GetViewData()
Definition: tabview.hxx:333
SdrObject * GetMarkedSdrObj() const
bool HasOLEObjectsInArea(const ScRange &rRange, const ScMarkData *pTabMark=nullptr)
Definition: documen9.cxx:276
T * get() const
bool IsMarked() const
Definition: markdata.hxx:81
static void CheckOle(const SdrMarkList &rMarkList, bool &rAnyOle, bool &rOneOle)
Definition: drawvie4.cxx:327
ScMarkType
States GetSimpleArea() returns for the underlying selection marks, so the caller can react if the res...
Definition: viewdata.hxx:60
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2622
#define SC_MOD()
Definition: scmod.hxx:250
Any aHelper
const SdrMarkList & GetMarkedObjectList() const
ScSelectionTransferMode
Definition: seltrans.hxx:29
OBJ_GRAF
unsigned char sal_Bool
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1179
ScSelectionTransferMode eMode
Definition: seltrans.hxx:45
ScSelectionTransferObj * GetSelectionTransfer() const
Definition: scmod.hxx:152
virtual SdrInventor GetObjInventor() const
ScDBFunc * GetView() const
Definition: viewdata.cxx:861
virtual void ObjectReleased() override
Definition: seltrans.cxx:405
ScDrawView * GetScDrawView()
Definition: tabview.hxx:341
rtl::Reference< ScTransferObj > mxCellData
Definition: seltrans.hxx:46
virtual sal_Bool SAL_CALL isComplex() override
Definition: seltrans.cxx:418
virtual void ObjectReleased()
bool DoInitNew(SfxMedium *pMedium=nullptr)
const INetURLObject & GetURLObject() const
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void SetSelectionTransfer(ScSelectionTransferObj *pNew)
Definition: scmod.cxx:645
virtual ~ScSelectionTransferObj() override
Definition: seltrans.cxx:150
bool SetAny(const css::uno::Any &rAny)
rtl::Reference< ScDrawTransferObj > mxDrawData
Definition: seltrans.hxx:47
OBJ_OLE2
static rtl::Reference< ScSelectionTransferObj > CreateFromView(ScTabView *pSource)
Definition: seltrans.cxx:70
SfxMedium * GetMedium() const