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  SdrObjKind nSdrObjKind = pObj->GetObjIdentifier();
92 
93  if ( nSdrObjKind == SdrObjKind::Graphic )
94  {
95  if ( static_cast<SdrGrafObj*>(pObj)->GetGraphic().GetType() == GraphicType::Bitmap )
97  else
99  }
100  else if ( nSdrObjKind == SdrObjKind::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  const ScRange& aSelRange = aNewMark.GetMarkArea();
268  ScDocShellRef aDragShellRef;
269  if ( pDocSh->GetDocument().HasOLEObjectsInArea( aSelRange, &aNewMark ) )
270  {
271  aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
272  aDragShellRef->DoInitNew();
273  }
274  ScDrawLayer::SetGlobalDrawPersist( aDragShellRef.get() );
275 
277  // bApi = sal_True -> no error messages
278  // #i18364# bStopEdit = sal_False -> don't end edit mode
279  // (this may be called from pasting into the edit line)
280  bool bCopied = rViewData.GetView()->CopyToClip( pClipDoc.get(), false, true, true, false );
281 
283 
284  if ( bCopied )
285  {
287  pDocSh->FillTransferableObjectDescriptor( aObjDesc );
288  aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
289  // maSize is set in ScTransferObj ctor
290 
291  rtl::Reference<ScTransferObj> pTransferObj = new ScTransferObj( std::move(pClipDoc), aObjDesc );
292 
293  // SetDragHandlePos is not used - there is no mouse position
294  //? pTransferObj->SetVisibleTab( nTab );
295 
296  SfxObjectShellRef aPersistRef( aDragShellRef.get() );
297  pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
298 
299  pTransferObj->SetDragSource( pDocSh, aNewMark );
300 
301  mxCellData = pTransferObj;
302  }
303  }
304  }
305  OSL_ENSURE( mxCellData.is(), "can't create CellData" );
306 }
307 
309 {
310  OSL_ENSURE( !mxDrawData.is(), "CreateDrawData twice" );
311  if ( pView )
312  {
313  // similar to ScDrawView::BeginDrag
314 
315  ScDrawView* pDrawView = pView->GetScDrawView();
316  if ( pDrawView )
317  {
318  bool bAnyOle, bOneOle;
319  const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList();
320  ScDrawView::CheckOle( rMarkList, bAnyOle, bOneOle );
321 
322  ScDocShellRef aDragShellRef;
323  if (bAnyOle)
324  {
325  aDragShellRef = new ScDocShell; // Without Ref the DocShell does not live
326  aDragShellRef->DoInitNew();
327  }
328 
329  ScDrawLayer::SetGlobalDrawPersist( aDragShellRef.get() );
330  std::unique_ptr<SdrModel> pModel(pDrawView->CreateMarkedObjModel());
332 
333  ScViewData& rViewData = pView->GetViewData();
334  ScDocShell* pDocSh = rViewData.GetDocShell();
335 
337  pDocSh->FillTransferableObjectDescriptor( aObjDesc );
338  aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
339  // maSize is set in ScDrawTransferObj ctor
340 
341  rtl::Reference<ScDrawTransferObj> pTransferObj = new ScDrawTransferObj( std::move(pModel), pDocSh, aObjDesc );
342 
343  SfxObjectShellRef aPersistRef( aDragShellRef.get() );
344  pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
345  pTransferObj->SetDragSource( pDrawView ); // copies selection
346 
347  mxDrawData = pTransferObj;
348  }
349  }
350  OSL_ENSURE( mxDrawData.is(), "can't create DrawData" );
351 }
352 
354 {
355  if ( !mxCellData.is() && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) )
356  CreateCellData();
357  return mxCellData.get();
358 }
359 
361 {
365  CreateDrawData();
366  return mxDrawData.get();
367 }
368 
370  const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc )
371 {
372  bool bOK = false;
373 
374  uno::Reference<datatransfer::XTransferable> xSource;
375  switch (eMode)
376  {
377  case SC_SELTRANS_CELL:
378  case SC_SELTRANS_CELLS:
379  xSource = GetCellData();
380  break;
386  xSource = GetDrawData();
387  break;
388  default:
389  {
390  // added to avoid warnings
391  }
392  }
393 
394  if ( xSource.is() )
395  {
396  TransferableDataHelper aHelper( xSource );
397  uno::Any aAny = aHelper.GetAny(rFlavor, rDestDoc);
398  bOK = SetAny( aAny );
399  }
400 
401  return bOK;
402 }
403 
405 {
406  // called when another selection is set from outside
407 
408  ForgetView();
409 
410  ScModule* pScMod = SC_MOD();
411  if ( pScMod->GetSelectionTransfer() == this )
412  pScMod->SetSelectionTransfer( nullptr );
413 
415 }
416 
418 {
419  switch (eMode)
420  {
421  case SC_SELTRANS_CELL:
422  case SC_SELTRANS_CELLS:
423  return false;
424  default:
425  return true;
426  }
427 }
428 
429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3135
virtual bool GetData(const css::datatransfer::DataFlavor &rFlavor, const OUString &rDestDoc) override
Definition: seltrans.cxx:369
virtual void AddSupportedFormats() override
Definition: seltrans.cxx:174
ScTransferObj * GetCellData()
Definition: seltrans.cxx:353
void MarkToSimple()
Definition: markdata.cxx:222
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScAddress aStart
Definition: address.hxx:497
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:360
ScSelectionTransferObj(ScTabView *pSource, ScSelectionTransferMode eNewMode)
Definition: seltrans.cxx:143
ScAddress aEnd
Definition: address.hxx:498
SdrMark * GetMark(size_t nNum) const
virtual SdrObjKind GetObjIdentifier() const
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
SdrObjKind
void AddFormat(SotClipboardFormatId nFormat)
static bool lcl_IsURLButton(SdrObject *pObject)
Definition: seltrans.cxx:42
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2655
virtual std::unique_ptr< SdrModel > CreateMarkedObjModel() const override
bool IsMultiMarked() const
Definition: markdata.hxx:81
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:80
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:2711
#define SC_MOD()
Definition: scmod.hxx:249
Any aHelper
const SdrMarkList & GetMarkedObjectList() const
ScSelectionTransferMode
Definition: seltrans.hxx:29
unsigned char sal_Bool
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1181
ScSelectionTransferMode eMode
Definition: seltrans.hxx:45
ScSelectionTransferObj * GetSelectionTransfer() const
Definition: scmod.hxx:151
virtual SdrInventor GetObjInventor() const
ScDBFunc * GetView() const
Definition: viewdata.cxx:863
virtual void ObjectReleased() override
Definition: seltrans.cxx:404
ScDrawView * GetScDrawView()
Definition: tabview.hxx:341
rtl::Reference< ScTransferObj > mxCellData
Definition: seltrans.hxx:46
virtual sal_Bool SAL_CALL isComplex() override
Definition: seltrans.cxx:417
virtual void ObjectReleased()
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:692
virtual ~ScSelectionTransferObj() override
Definition: seltrans.cxx:150
bool SetAny(const css::uno::Any &rAny)
rtl::Reference< ScDrawTransferObj > mxDrawData
Definition: seltrans.hxx:47
static rtl::Reference< ScSelectionTransferObj > CreateFromView(ScTabView *pSource)
Definition: seltrans.cxx:70
bool m_bDetectedRangeSegmentation false
SfxMedium * GetMedium() const