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
40using namespace com::sun::star;
41
42static 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 )
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 )
126 else
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:
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), std::move(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, std::move(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 ) )
357 return mxCellData.get();
358}
359
361{
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:
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 {
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:
423 return false;
424 default:
425 return true;
426 }
427}
428
429/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual std::unique_ptr< SdrModel > CreateMarkedObjModel() const override
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
bool HasOLEObjectsInArea(const ScRange &rRange, const ScMarkData *pTabMark=nullptr)
Definition: documen9.cxx:276
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2657
static void CheckOle(const SdrMarkList &rMarkList, bool &rAnyOle, bool &rOneOle)
Definition: drawvie4.cxx:327
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
const ScRange & GetMarkArea() const
Definition: markdata.hxx:83
bool IsMultiMarked() const
Definition: markdata.hxx:81
bool IsMarked() const
Definition: markdata.hxx:80
void MarkToSimple()
Definition: markdata.cxx:222
void SetSelectionTransfer(ScSelectionTransferObj *pNew)
Definition: scmod.cxx:692
ScSelectionTransferObj * GetSelectionTransfer() const
Definition: scmod.hxx:151
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
virtual void AddSupportedFormats() override
Definition: seltrans.cxx:174
ScDrawTransferObj * GetDrawData()
Definition: seltrans.cxx:360
ScSelectionTransferObj(ScTabView *pSource, ScSelectionTransferMode eNewMode)
Definition: seltrans.cxx:143
ScTransferObj * GetCellData()
Definition: seltrans.cxx:353
virtual bool GetData(const css::datatransfer::DataFlavor &rFlavor, const OUString &rDestDoc) override
Definition: seltrans.cxx:369
ScSelectionTransferMode eMode
Definition: seltrans.hxx:45
rtl::Reference< ScDrawTransferObj > mxDrawData
Definition: seltrans.hxx:47
virtual ~ScSelectionTransferObj() override
Definition: seltrans.cxx:150
virtual sal_Bool SAL_CALL isComplex() override
Definition: seltrans.cxx:417
rtl::Reference< ScTransferObj > mxCellData
Definition: seltrans.hxx:46
virtual void ObjectReleased() override
Definition: seltrans.cxx:404
static rtl::Reference< ScSelectionTransferObj > CreateFromView(ScTabView *pSource)
Definition: seltrans.cxx:70
ScViewData & GetViewData()
Definition: tabview.hxx:335
ScDrawView * GetScDrawView()
Definition: tabview.hxx:343
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3141
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1181
ScDBFunc * GetView() const
Definition: viewdata.cxx:863
SC_DLLPUBLIC bool CopyToClip(ScDocument *pClipDoc, bool bCut, bool bApi=false, bool bIncludeObjects=false, bool bStopEdit=true)
Definition: viewfun3.cxx:168
size_t GetMarkCount() const
SdrMark * GetMark(size_t nNum) const
const SdrMarkList & GetMarkedObjectList() const
SdrObject * GetMarkedSdrObj() const
virtual SdrInventor GetObjInventor() const
virtual SdrObjKind GetObjIdentifier() const
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
const INetURLObject & GetURLObject() const
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
SfxMedium * GetMedium() const
bool SetAny(const css::uno::Any &rAny)
void AddFormat(SotClipboardFormatId nFormat)
virtual void ObjectReleased()
T * get() const
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2717
@ SCDOCMODE_CLIP
Definition: document.hxx:256
EmbeddedObjectRef * pObject
Any aHelper
Mode eMode
#define SC_MOD()
Definition: scmod.hxx:249
static bool lcl_IsURLButton(SdrObject *pObject)
Definition: seltrans.cxx:42
ScSelectionTransferMode
Definition: seltrans.hxx:30
@ SC_SELTRANS_DRAW_OLE
Definition: seltrans.hxx:37
@ SC_SELTRANS_DRAW_BOOKMARK
Definition: seltrans.hxx:36
@ SC_SELTRANS_INVALID
Definition: seltrans.hxx:31
@ SC_SELTRANS_CELL
Definition: seltrans.hxx:32
@ SC_SELTRANS_DRAW_BITMAP
Definition: seltrans.hxx:34
@ SC_SELTRANS_CELLS
Definition: seltrans.hxx:33
@ SC_SELTRANS_DRAW_GRAPHIC
Definition: seltrans.hxx:35
@ SC_SELTRANS_DRAW_OTHER
Definition: seltrans.hxx:38
SdrObjKind
unsigned char sal_Bool
ScMarkType
States GetSimpleArea() returns for the underlying selection marks, so the caller can react if the res...
Definition: viewdata.hxx:61
@ SC_MARK_SIMPLE
Definition: viewdata.hxx:65
@ SC_MARK_SIMPLE_FILTERED
Definition: viewdata.hxx:67