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 
29 #include <seltrans.hxx>
30 #include <transobj.hxx>
31 #include <drwtrans.hxx>
32 #include <scmod.hxx>
33 #include <dbfunc.hxx>
34 #include <docsh.hxx>
35 #include <drawview.hxx>
36 #include <drwlayer.hxx>
37 #include <markdata.hxx>
38 
39 using namespace com::sun::star;
40 
41 static bool lcl_IsURLButton( SdrObject* pObject )
42 {
43  bool bRet = false;
44 
45  SdrUnoObj* pUnoCtrl = dynamic_cast<SdrUnoObj*>( pObject );
46  if (pUnoCtrl && SdrInventor::FmForm == pUnoCtrl->GetObjInventor())
47  {
48  const uno::Reference<awt::XControlModel>& xControlModel = pUnoCtrl->GetUnoControlModel();
49  OSL_ENSURE( xControlModel.is(), "uno control without model" );
50  if ( xControlModel.is() )
51  {
52  uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
53  uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
54 
55  OUString sPropButtonType( "ButtonType" );
56  if(xInfo->hasPropertyByName( sPropButtonType ))
57  {
58  uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
59  form::FormButtonType eTmp;
60  if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
61  bRet = true;
62  }
63  }
64  }
65 
66  return bRet;
67 }
68 
70 {
71  ScSelectionTransferObj* pRet = nullptr;
72 
73  try
74  {
75  if ( pView )
76  {
78 
79  SdrView* pSdrView = pView->GetScDrawView();
80  if ( pSdrView )
81  {
82  // handle selection on drawing layer
83  const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
84  const size_t nMarkCount = rMarkList.GetMarkCount();
85  if ( nMarkCount )
86  {
87  if ( nMarkCount == 1 )
88  {
89  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
90  sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
91 
92  if ( nSdrObjKind == OBJ_GRAF )
93  {
94  if ( static_cast<SdrGrafObj*>(pObj)->GetGraphic().GetType() == GraphicType::Bitmap )
96  else
98  }
99  else if ( nSdrObjKind == OBJ_OLE2 )
100  eMode = SC_SELTRANS_DRAW_OLE;
101  else if ( lcl_IsURLButton( pObj ) )
103  }
104 
105  if ( eMode == SC_SELTRANS_INVALID )
106  eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection
107  }
108  }
109  if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected
110  {
111  ScViewData& rViewData = pView->GetViewData();
112  const ScMarkData& rMark = rViewData.GetMarkData();
113  // allow MultiMarked because GetSimpleArea may be able to merge into a simple range
114  // (GetSimpleArea modifies a local copy of MarkData)
115  // Also allow simple filtered area.
116  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
117  {
118  ScRange aRange;
119  ScMarkType eMarkType = rViewData.GetSimpleArea( aRange );
120  if (eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED)
121  {
122  // only for "real" selection, cursor alone isn't used
123  if ( aRange.aStart == aRange.aEnd )
124  eMode = SC_SELTRANS_CELL;
125  else
126  eMode = SC_SELTRANS_CELLS;
127  }
128  }
129  }
130 
131  if ( eMode != SC_SELTRANS_INVALID )
132  pRet = new ScSelectionTransferObj( pView, eMode );
133  }
134  }
135  catch (...)
136  {
137  }
138 
139  return pRet;
140 }
141 
143  pView( pSource ),
144  eMode( eNewMode )
145 {
147 }
148 
150 {
151  ScModule* pScMod = SC_MOD();
152  if ( pScMod->GetSelectionTransfer() == this )
153  {
154  // this is reached when the object wasn't really copied to the selection
155  // (CopyToSelection has no effect under Windows)
156 
157  ForgetView();
158  pScMod->SetSelectionTransfer( nullptr );
159  }
160 
161  OSL_ENSURE( !pView, "ScSelectionTransferObj dtor: ForgetView not called" );
162 }
163 
165 {
166  pView = nullptr;
168 
169  mxCellData.clear();
170  mxDrawData.clear();
171 }
172 
174 {
175  // AddSupportedFormats must work without actually creating the
176  // "real" transfer object
177 
178  switch (eMode)
179  {
180  case SC_SELTRANS_CELL:
181  case SC_SELTRANS_CELLS:
182  // same formats as in ScTransferObj::AddSupportedFormats
183  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
184  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
185  AddFormat( SotClipboardFormatId::GDIMETAFILE );
186  AddFormat( SotClipboardFormatId::PNG );
187  AddFormat( SotClipboardFormatId::BITMAP );
188  AddFormat( SotClipboardFormatId::HTML );
189  AddFormat( SotClipboardFormatId::SYLK );
190  AddFormat( SotClipboardFormatId::LINK );
191  AddFormat( SotClipboardFormatId::DIF );
192  AddFormat( SotClipboardFormatId::STRING );
193  AddFormat( SotClipboardFormatId::STRING_TSVC );
194  AddFormat( SotClipboardFormatId::RTF );
195  AddFormat( SotClipboardFormatId::RICHTEXT );
196  if ( eMode == SC_SELTRANS_CELL )
197  {
198  AddFormat( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT );
199  }
200  break;
201 
202  // different graphic formats as in ScDrawTransferObj::AddSupportedFormats:
203 
205  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
206  AddFormat( SotClipboardFormatId::SVXB );
207  AddFormat( SotClipboardFormatId::PNG );
208  AddFormat( SotClipboardFormatId::BITMAP );
209  AddFormat( SotClipboardFormatId::GDIMETAFILE );
210  break;
211 
213  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
214  AddFormat( SotClipboardFormatId::SVXB );
215  AddFormat( SotClipboardFormatId::GDIMETAFILE );
216  AddFormat( SotClipboardFormatId::PNG );
217  AddFormat( SotClipboardFormatId::BITMAP );
218  break;
219 
221  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
222  AddFormat( SotClipboardFormatId::SOLK );
223  AddFormat( SotClipboardFormatId::STRING );
224  AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
225  AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
226  AddFormat( SotClipboardFormatId::DRAWING );
227  break;
228 
230  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
231  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
232  AddFormat( SotClipboardFormatId::GDIMETAFILE );
233  break;
234 
236  // other drawing objects
237  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
238  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
239  AddFormat( SotClipboardFormatId::DRAWING );
240  AddFormat( SotClipboardFormatId::PNG );
241  AddFormat( SotClipboardFormatId::BITMAP );
242  AddFormat( SotClipboardFormatId::GDIMETAFILE );
243  break;
244 
245  default:
246  {
247  // added to avoid warnings
248  }
249  }
250 }
251 
253 {
254  OSL_ENSURE( !mxCellData.is(), "CreateCellData twice" );
255  if ( pView )
256  {
257  ScViewData& rViewData = pView->GetViewData();
258  ScMarkData aNewMark( rViewData.GetMarkData() ); // use local copy for MarkToSimple
259  aNewMark.MarkToSimple();
260 
261  // similar to ScViewFunctionSet::BeginDrag
262  if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() )
263  {
264  ScDocShell* pDocSh = rViewData.GetDocShell();
265 
266  ScRange aSelRange;
267  aNewMark.GetMarkArea( aSelRange );
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:3046
virtual bool GetData(const css::datatransfer::DataFlavor &rFlavor, const OUString &rDestDoc) override
Definition: seltrans.cxx:369
virtual void AddSupportedFormats() override
Definition: seltrans.cxx:173
OBJ_GRAF
ScTransferObj * GetCellData()
Definition: seltrans.cxx:353
void MarkToSimple()
Definition: markdata.cxx:237
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScAddress aStart
Definition: address.hxx:500
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:43
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:165
OBJ_OLE2
ScDrawTransferObj * GetDrawData()
Definition: seltrans.cxx:360
ScSelectionTransferObj(ScTabView *pSource, ScSelectionTransferMode eNewMode)
Definition: seltrans.cxx:142
ScAddress aEnd
Definition: address.hxx:501
SdrMark * GetMark(size_t nNum) const
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
void AddFormat(SotClipboardFormatId nFormat)
static bool lcl_IsURLButton(SdrObject *pObject)
Definition: seltrans.cxx:41
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2335
virtual std::unique_ptr< SdrModel > CreateMarkedObjModel() const override
bool IsMultiMarked() const
Definition: markdata.hxx:83
Mode eMode
ScViewData & GetViewData()
Definition: tabview.hxx:332
static ScSelectionTransferObj * CreateFromView(ScTabView *pSource)
Definition: seltrans.cxx:69
SdrObject * GetMarkedSdrObj() const
bool HasOLEObjectsInArea(const ScRange &rRange, const ScMarkData *pTabMark=nullptr)
Definition: documen9.cxx:274
T * get() const
bool IsMarked() const
Definition: markdata.hxx:82
static void CheckOle(const SdrMarkList &rMarkList, bool &rAnyOle, bool &rOneOle)
Definition: drawvie4.cxx:327
virtual sal_uInt16 GetObjIdentifier() const
ScMarkType
States GetSimpleArea() returns for the underlying selection marks, so the caller can react if the res...
Definition: viewdata.hxx:61
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2613
#define SC_MOD()
Definition: scmod.hxx:253
Any aHelper
const SdrMarkList & GetMarkedObjectList() const
ScSelectionTransferMode
Definition: seltrans.hxx:30
unsigned char sal_Bool
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1170
ScSelectionTransferMode eMode
Definition: seltrans.hxx:46
ScSelectionTransferObj * GetSelectionTransfer() const
Definition: scmod.hxx:155
virtual SdrInventor GetObjInventor() const
ScDBFunc * GetView() const
Definition: viewdata.cxx:852
virtual void ObjectReleased() override
Definition: seltrans.cxx:404
ScDrawView * GetScDrawView()
Definition: tabview.hxx:340
rtl::Reference< ScTransferObj > mxCellData
Definition: seltrans.hxx:47
virtual sal_Bool SAL_CALL isComplex() override
Definition: seltrans.cxx:417
virtual void ObjectReleased()
bool DoInitNew(SfxMedium *pMedium=nullptr)
const INetURLObject & GetURLObject() const
const ScDocument & GetDocument() const
Definition: docsh.hxx:216
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:650
virtual ~ScSelectionTransferObj() override
Definition: seltrans.cxx:149
bool SetAny(const css::uno::Any &rAny)
rtl::Reference< ScDrawTransferObj > mxDrawData
Definition: seltrans.hxx:48
SfxMedium * GetMedium() const