Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/svdraw/svdoole2.cxx
Line
Count
Source
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 <svx/svdoole2.hxx>
21
22
#include <com/sun/star/beans/XPropertySet.hpp>
23
#include <com/sun/star/util/XModifyBroadcaster.hpp>
24
#include <com/sun/star/util/XModifiable.hpp>
25
#include <com/sun/star/embed/EmbedStates.hpp>
26
#include <com/sun/star/embed/EmbedMisc.hpp>
27
#include <com/sun/star/embed/Aspects.hpp>
28
#include <com/sun/star/embed/ObjectSaveVetoException.hpp>
29
#include <com/sun/star/embed/XEmbeddedObject.hpp>
30
#include <com/sun/star/embed/XEmbedPersist2.hpp>
31
#include <com/sun/star/embed/XInplaceClient.hpp>
32
#include <com/sun/star/embed/XInplaceObject.hpp>
33
#include <com/sun/star/embed/XLinkageSupport.hpp>
34
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
35
#include <com/sun/star/embed/XWindowSupplier.hpp>
36
#include <com/sun/star/document/XEventListener.hpp>
37
#include <com/sun/star/container/XChild.hpp>
38
#include <com/sun/star/document/XStorageBasedDocument.hpp>
39
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
40
41
#include <cppuhelper/exc_hlp.hxx>
42
43
#include <toolkit/helper/vclunohelper.hxx>
44
45
#include <svtools/colorcfg.hxx>
46
#include <svtools/embedhlp.hxx>
47
48
#include <sfx2/objsh.hxx>
49
#include <sfx2/ipclient.hxx>
50
#include <sfx2/lnkbase.hxx>
51
#include <sfx2/linkmgr.hxx>
52
#include <tools/debug.hxx>
53
#include <tools/globname.hxx>
54
#include <comphelper/diagnose_ex.hxx>
55
#include <comphelper/classids.hxx>
56
#include <comphelper/propertyvalue.hxx>
57
58
#include <sot/formats.hxx>
59
#include <cppuhelper/implbase.hxx>
60
61
#include <vcl/svapp.hxx>
62
#include <vcl/unohelp.hxx>
63
64
#include <svx/svdmodel.hxx>
65
#include <svx/dialmgr.hxx>
66
#include <svx/strings.hrc>
67
#include <svx/svdetc.hxx>
68
#include <unomlstr.hxx>
69
#include <sdr/contact/viewcontactofsdrole2obj.hxx>
70
#include <svx/svdograf.hxx>
71
#include <sdr/properties/oleproperties.hxx>
72
#include <svx/unoshape.hxx>
73
#include <svx/xlineit0.hxx>
74
#include <svx/xlnclit.hxx>
75
#include <svx/xbtmpit.hxx>
76
#include <svx/xfillit0.hxx>
77
#include <svx/xflbmtit.hxx>
78
#include <svx/xflbstit.hxx>
79
#include <basegfx/matrix/b2dhommatrix.hxx>
80
#include <basegfx/polygon/b2dpolypolygon.hxx>
81
#include <editeng/outlobj.hxx>
82
#include <svx/svdpage.hxx>
83
#include <rtl/ustrbuf.hxx>
84
#include <rtl/ref.hxx>
85
#include <bitmaps.hlst>
86
87
using namespace ::com::sun::star;
88
89
static uno::Reference < beans::XPropertySet > lcl_getFrame_throw(const SdrOle2Obj* _pObject)
90
0
{
91
0
    uno::Reference < beans::XPropertySet > xFrame;
92
0
    if ( _pObject )
93
0
    {
94
0
        uno::Reference< frame::XController> xController = _pObject->GetParentXModel()->getCurrentController();
95
0
        if ( xController.is() )
96
0
        {
97
0
            xFrame.set( xController->getFrame(),uno::UNO_QUERY_THROW);
98
0
        }
99
0
    } // if ( _pObject )
100
0
    return xFrame;
101
0
}
102
103
namespace {
104
105
class SdrLightEmbeddedClient_Impl : public ::cppu::WeakImplHelper
106
                                                            < embed::XStateChangeListener
107
                                                            , document::XEventListener
108
                                                            , embed::XInplaceClient
109
                                                            , embed::XEmbeddedClient
110
                                                            , embed::XWindowSupplier
111
                                                            >
112
{
113
    uno::Reference< awt::XWindow > m_xWindow;
114
    SdrOle2Obj* mpObj;
115
116
    double m_aScaleWidth { 0.0 };
117
    double m_aScaleHeight { 0.0 };
118
119
120
public:
121
    explicit SdrLightEmbeddedClient_Impl( SdrOle2Obj* pObj );
122
    virtual ~SdrLightEmbeddedClient_Impl() override;
123
124
    void SetSizeScale( double aScaleWidth, double aScaleHeight )
125
0
    {
126
0
        m_aScaleWidth = aScaleWidth;
127
0
        m_aScaleHeight = aScaleHeight;
128
0
    }
129
130
0
    double GetScaleWidth() const { return m_aScaleWidth; }
131
0
    double GetScaleHeight() const { return m_aScaleHeight; }
132
133
    void setWindow(const uno::Reference< awt::XWindow >& _xWindow);
134
135
    void disconnect();
136
private:
137
138
    tools::Rectangle impl_getScaledRect_nothrow() const;
139
    // XStateChangeListener
140
    virtual void SAL_CALL changingState( const css::lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) override;
141
    virtual void SAL_CALL stateChanged( const css::lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) override;
142
    virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) override;
143
144
    // document::XEventListener
145
    virtual void SAL_CALL       notifyEvent( const document::EventObject& aEvent ) override;
146
147
    // XEmbeddedClient
148
    virtual void SAL_CALL saveObject() override;
149
    virtual void SAL_CALL visibilityChanged( sal_Bool bVisible ) override;
150
151
    // XComponentSupplier
152
    virtual uno::Reference< util::XCloseable > SAL_CALL getComponent() override;
153
154
    // XInplaceClient
155
    virtual sal_Bool SAL_CALL canInplaceActivate() override;
156
    virtual void SAL_CALL activatingInplace() override;
157
    virtual void SAL_CALL activatingUI() override;
158
    virtual void SAL_CALL deactivatedInplace() override;
159
    virtual void SAL_CALL deactivatedUI() override;
160
    virtual uno::Reference< css::frame::XLayoutManager > SAL_CALL getLayoutManager() override;
161
    virtual uno::Reference< frame::XDispatchProvider > SAL_CALL getInplaceDispatchProvider() override;
162
    virtual awt::Rectangle SAL_CALL getPlacement() override;
163
    virtual awt::Rectangle SAL_CALL getClipRectangle() override;
164
    virtual void SAL_CALL translateAccelerators( const uno::Sequence< awt::KeyEvent >& aKeys ) override;
165
    virtual void SAL_CALL scrollObject( const awt::Size& aOffset ) override;
166
    virtual void SAL_CALL changedPlacement( const awt::Rectangle& aPosRect ) override;
167
168
    // XWindowSupplier
169
    virtual uno::Reference< awt::XWindow > SAL_CALL getWindow() override;
170
};
171
172
}
173
174
SdrLightEmbeddedClient_Impl::SdrLightEmbeddedClient_Impl( SdrOle2Obj* pObj )
175
0
: mpObj( pObj )
176
0
{
177
0
}
178
SdrLightEmbeddedClient_Impl::~SdrLightEmbeddedClient_Impl()
179
0
{
180
0
    assert(!mpObj);
181
0
}
182
tools::Rectangle SdrLightEmbeddedClient_Impl::impl_getScaledRect_nothrow() const
183
0
{
184
0
    tools::Rectangle aLogicRect( mpObj->GetLogicRect() );
185
    // apply scaling to object area and convert to pixels
186
0
    aLogicRect.SetSize( Size( tools::Long( aLogicRect.GetWidth() * m_aScaleWidth),
187
0
                              tools::Long( aLogicRect.GetHeight() * m_aScaleHeight) ) );
188
0
    return aLogicRect;
189
0
}
190
191
void SAL_CALL SdrLightEmbeddedClient_Impl::changingState( const css::lang::EventObject& /*aEvent*/, ::sal_Int32 /*nOldState*/, ::sal_Int32 /*nNewState*/ )
192
0
{
193
0
}
194
195
void SAL_CALL SdrLightEmbeddedClient_Impl::stateChanged( const css::lang::EventObject& /*aEvent*/, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
196
0
{
197
0
    SolarMutexGuard aGuard;
198
199
0
    if ( mpObj && nOldState == embed::EmbedStates::LOADED && nNewState == embed::EmbedStates::RUNNING )
200
0
    {
201
0
        mpObj->ObjectLoaded();
202
0
        GetSdrGlobalData().GetOLEObjCache().InsertObj(mpObj);
203
0
    }
204
0
    else if ( mpObj && nNewState == embed::EmbedStates::LOADED && nOldState == embed::EmbedStates::RUNNING )
205
0
    {
206
0
        GetSdrGlobalData().GetOLEObjCache().RemoveObj(mpObj);
207
0
    }
208
0
}
209
210
void SdrLightEmbeddedClient_Impl::disconnect()
211
0
{
212
0
    SolarMutexGuard aGuard;
213
0
    if (!mpObj)
214
0
        return;
215
0
    GetSdrGlobalData().GetOLEObjCache().RemoveObj(mpObj);
216
0
    mpObj = nullptr;
217
0
}
218
219
void SAL_CALL SdrLightEmbeddedClient_Impl::disposing( const css::lang::EventObject& /*aEvent*/ )
220
0
{
221
0
    disconnect();
222
0
}
223
224
void SAL_CALL SdrLightEmbeddedClient_Impl::notifyEvent( const document::EventObject& aEvent )
225
0
{
226
    // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
227
228
0
    SolarMutexGuard aGuard;
229
230
    // the code currently makes sense only in case there is no other client
231
0
    if ( !(mpObj && mpObj->GetAspect() != embed::Aspects::MSOLE_ICON && aEvent.EventName == "OnVisAreaChanged"
232
0
      && mpObj->GetObjRef().is() && mpObj->GetObjRef()->getClientSite() == uno::Reference< embed::XEmbeddedClient >( this )) )
233
0
        return;
234
235
0
    try
236
0
    {
237
0
        MapUnit aContainerMapUnit( MapUnit::Map100thMM );
238
0
        uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
239
0
        if ( xParentVis.is() )
240
0
            aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
241
242
0
        MapUnit aObjMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpObj->GetObjRef()->getMapUnit( mpObj->GetAspect() ) );
243
244
0
        tools::Rectangle          aVisArea;
245
0
        awt::Size aSz;
246
0
        try
247
0
        {
248
0
            aSz = mpObj->GetObjRef()->getVisualAreaSize( mpObj->GetAspect() );
249
0
        }
250
0
        catch( embed::NoVisualAreaSizeException& )
251
0
        {
252
0
            TOOLS_WARN_EXCEPTION("svx.svdraw", "No visual area size!");
253
0
            aSz.Width = 5000;
254
0
            aSz.Height = 5000;
255
0
        }
256
0
        catch( uno::Exception& )
257
0
        {
258
0
            TOOLS_WARN_EXCEPTION("svx.svdraw", "");
259
0
            aSz.Width = 5000;
260
0
            aSz.Height = 5000;
261
0
        }
262
263
0
        aVisArea.SetSize( Size( aSz.Width, aSz.Height ) );
264
0
        aVisArea = OutputDevice::LogicToLogic(aVisArea, MapMode(aObjMapUnit), MapMode(aContainerMapUnit));
265
0
        Size aScaledSize( static_cast< tools::Long >( m_aScaleWidth * aVisArea.GetWidth() ),
266
0
                            static_cast< tools::Long >( m_aScaleHeight * aVisArea.GetHeight() ) );
267
0
        tools::Rectangle aLogicRect( mpObj->GetLogicRect() );
268
269
        // react to the change if the difference is bigger than one pixel
270
0
        Size aPixelDiff =
271
0
            Application::GetDefaultDevice()->LogicToPixel(
272
0
                Size( aLogicRect.GetWidth() - aScaledSize.Width(),
273
0
                      aLogicRect.GetHeight() - aScaledSize.Height() ),
274
0
                MapMode(aContainerMapUnit));
275
0
        if( aPixelDiff.Width() || aPixelDiff.Height() )
276
0
        {
277
0
            mpObj->SetLogicRect( tools::Rectangle( aLogicRect.TopLeft(), aScaledSize ) );
278
0
            mpObj->BroadcastObjectChange();
279
0
        }
280
0
        else
281
0
            mpObj->ActionChanged();
282
0
    }
283
0
    catch( uno::Exception& )
284
0
    {
285
0
        TOOLS_WARN_EXCEPTION("svx.svdraw", "");
286
0
    }
287
0
}
288
289
void SAL_CALL SdrLightEmbeddedClient_Impl::saveObject()
290
0
{
291
    // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
292
0
    uno::Reference< embed::XCommonEmbedPersist > xPersist;
293
0
    uno::Reference< util::XModifiable > xModifiable;
294
295
0
    {
296
0
        SolarMutexGuard aGuard;
297
298
0
        if ( !mpObj )
299
0
            throw embed::ObjectSaveVetoException();
300
301
        // the common persistence is supported by objects and links
302
0
        xPersist.set( mpObj->GetObjRef(), uno::UNO_QUERY_THROW );
303
0
        xModifiable.set( mpObj->GetParentXModel(), uno::UNO_QUERY );
304
0
    }
305
306
0
    xPersist->storeOwn();
307
308
0
    if ( xModifiable.is() )
309
0
        xModifiable->setModified( true );
310
0
}
311
312
void SAL_CALL SdrLightEmbeddedClient_Impl::visibilityChanged( sal_Bool /*bVisible*/ )
313
0
{
314
    // nothing to do currently
315
    // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
316
0
    if ( mpObj )
317
0
    {
318
0
        tools::Rectangle aLogicRect( mpObj->GetLogicRect() );
319
0
        Size aLogicSize( aLogicRect.GetWidth(), aLogicRect.GetHeight() );
320
321
0
        if( mpObj->IsChart() )
322
0
        {
323
            //charts never should be stretched see #i84323# for example
324
0
            mpObj->SetLogicRect( tools::Rectangle( aLogicRect.TopLeft(), aLogicSize ) );
325
0
            mpObj->BroadcastObjectChange();
326
0
        } // if( mpObj->IsChart() )
327
0
    }
328
0
}
329
330
uno::Reference< util::XCloseable > SAL_CALL SdrLightEmbeddedClient_Impl::getComponent()
331
0
{
332
0
    uno::Reference< util::XCloseable > xResult;
333
334
0
    SolarMutexGuard aGuard;
335
0
    if ( mpObj )
336
0
        xResult.set( mpObj->GetParentXModel(), uno::UNO_QUERY );
337
338
0
    return xResult;
339
0
}
340
// XInplaceClient
341
342
sal_Bool SAL_CALL SdrLightEmbeddedClient_Impl::canInplaceActivate()
343
0
{
344
0
    bool bRet = false;
345
0
    SolarMutexGuard aGuard;
346
0
    if ( mpObj )
347
0
    {
348
0
        uno::Reference< embed::XEmbeddedObject > xObject = mpObj->GetObjRef();
349
0
        if ( !xObject.is() )
350
0
            throw uno::RuntimeException();
351
        // we don't want to switch directly from outplace to inplace mode
352
0
        bRet = ( xObject->getCurrentState() != embed::EmbedStates::ACTIVE && mpObj->GetAspect() != embed::Aspects::MSOLE_ICON );
353
0
    } // if ( mpObj )
354
0
    return bRet;
355
0
}
356
357
void SAL_CALL SdrLightEmbeddedClient_Impl::activatingInplace()
358
0
{
359
0
}
360
361
void SAL_CALL SdrLightEmbeddedClient_Impl::activatingUI()
362
0
{
363
0
    SolarMutexGuard aGuard;
364
365
0
    uno::Reference < beans::XPropertySet > xFrame( lcl_getFrame_throw(mpObj));
366
0
    uno::Reference < frame::XFrame > xOwnFrame( xFrame,uno::UNO_QUERY);
367
0
    uno::Reference < frame::XFramesSupplier > xParentFrame = xOwnFrame->getCreator();
368
0
    if ( xParentFrame.is() )
369
0
        xParentFrame->setActiveFrame( xOwnFrame );
370
371
0
    OLEObjCache& rObjCache = GetSdrGlobalData().GetOLEObjCache();
372
0
    const size_t nCount = rObjCache.size();
373
0
    for(sal_Int32 i = nCount-1 ; i >= 0;--i)
374
0
    {
375
0
        SdrOle2Obj* pObj = rObjCache[i];
376
0
        if ( pObj != mpObj )
377
0
        {
378
            // only deactivate ole objects which belongs to the same frame
379
0
            if ( xFrame == lcl_getFrame_throw(pObj) )
380
0
            {
381
0
                const uno::Reference< embed::XEmbeddedObject >& xObject = pObj->GetObjRef();
382
0
                try
383
0
                {
384
0
                    if ( xObject->getStatus( pObj->GetAspect() ) & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE )
385
0
                        xObject->changeState( embed::EmbedStates::INPLACE_ACTIVE );
386
0
                    else
387
0
                    {
388
                        // the links should not stay in running state for long time because of locking
389
0
                        uno::Reference< embed::XLinkageSupport > xLink( xObject, uno::UNO_QUERY );
390
0
                        if ( xLink.is() && xLink->isLink() )
391
0
                            xObject->changeState( embed::EmbedStates::LOADED );
392
0
                        else
393
0
                            xObject->changeState( embed::EmbedStates::RUNNING );
394
0
                    }
395
0
                }
396
0
                catch (css::uno::Exception& )
397
0
                {}
398
0
            }
399
0
        }
400
0
    } // for(sal_Int32 i = nCount-1 ; i >= 0;--i)
401
0
}
402
403
void SAL_CALL SdrLightEmbeddedClient_Impl::deactivatedInplace()
404
0
{
405
0
}
406
407
void SAL_CALL SdrLightEmbeddedClient_Impl::deactivatedUI()
408
0
{
409
0
    SolarMutexGuard aGuard;
410
0
    css::uno::Reference< css::frame::XLayoutManager > xLayoutManager(getLayoutManager());
411
0
    if ( xLayoutManager.is() )
412
0
    {
413
0
        static constexpr OUString aMenuBarURL = u"private:resource/menubar/menubar"_ustr;
414
0
        if ( !xLayoutManager->isElementVisible( aMenuBarURL ) )
415
0
            xLayoutManager->createElement( aMenuBarURL );
416
0
    }
417
0
}
418
419
uno::Reference< css::frame::XLayoutManager > SAL_CALL SdrLightEmbeddedClient_Impl::getLayoutManager()
420
0
{
421
0
    uno::Reference< css::frame::XLayoutManager > xMan;
422
0
    SolarMutexGuard aGuard;
423
0
    uno::Reference < beans::XPropertySet > xFrame( lcl_getFrame_throw(mpObj));
424
0
    try
425
0
    {
426
0
        xMan.set(xFrame->getPropertyValue(u"LayoutManager"_ustr),uno::UNO_QUERY);
427
0
    }
428
0
    catch ( uno::Exception& ex )
429
0
    {
430
0
        css::uno::Any anyEx = cppu::getCaughtException();
431
0
        throw css::lang::WrappedTargetRuntimeException( ex.Message,
432
0
                        nullptr, anyEx );
433
0
    }
434
435
0
    return xMan;
436
0
}
437
438
uno::Reference< frame::XDispatchProvider > SAL_CALL SdrLightEmbeddedClient_Impl::getInplaceDispatchProvider()
439
0
{
440
0
    SolarMutexGuard aGuard;
441
0
    return uno::Reference < frame::XDispatchProvider >( lcl_getFrame_throw(mpObj), uno::UNO_QUERY_THROW );
442
0
}
443
444
awt::Rectangle SAL_CALL SdrLightEmbeddedClient_Impl::getPlacement()
445
0
{
446
0
    SolarMutexGuard aGuard;
447
0
    if ( !mpObj )
448
0
        throw uno::RuntimeException();
449
450
0
    tools::Rectangle aLogicRect = impl_getScaledRect_nothrow();
451
0
    MapUnit aContainerMapUnit( MapUnit::Map100thMM );
452
0
    uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
453
0
    if ( xParentVis.is() )
454
0
        aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
455
456
0
    aLogicRect = Application::GetDefaultDevice()->LogicToPixel(aLogicRect, MapMode(aContainerMapUnit));
457
0
    return vcl::unohelper::ConvertToAWTRect(aLogicRect);
458
0
}
459
460
awt::Rectangle SAL_CALL SdrLightEmbeddedClient_Impl::getClipRectangle()
461
0
{
462
0
    return getPlacement();
463
0
}
464
465
void SAL_CALL SdrLightEmbeddedClient_Impl::translateAccelerators( const uno::Sequence< awt::KeyEvent >& /*aKeys*/ )
466
0
{
467
0
}
468
469
void SAL_CALL SdrLightEmbeddedClient_Impl::scrollObject( const awt::Size& /*aOffset*/ )
470
0
{
471
0
}
472
473
void SAL_CALL SdrLightEmbeddedClient_Impl::changedPlacement( const awt::Rectangle& aPosRect )
474
0
{
475
0
    SolarMutexGuard aGuard;
476
0
    if ( !mpObj )
477
0
        throw uno::RuntimeException();
478
479
0
    uno::Reference< embed::XInplaceObject > xInplace( mpObj->GetObjRef(), uno::UNO_QUERY_THROW );
480
481
    // check if the change is at least one pixel in size
482
0
    awt::Rectangle aOldRect = getPlacement();
483
0
    tools::Rectangle aNewPixelRect = vcl::unohelper::ConvertToVCLRect(aPosRect);
484
0
    tools::Rectangle aOldPixelRect = vcl::unohelper::ConvertToVCLRect(aOldRect);
485
0
    if ( aOldPixelRect == aNewPixelRect )
486
        // nothing has changed
487
0
        return;
488
489
    // new scaled object area
490
0
    MapUnit aContainerMapUnit( MapUnit::Map100thMM );
491
0
    uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
492
0
    if ( xParentVis.is() )
493
0
        aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
494
495
0
    tools::Rectangle aNewLogicRect = Application::GetDefaultDevice()->PixelToLogic(aNewPixelRect, MapMode(aContainerMapUnit));
496
0
    tools::Rectangle aLogicRect = impl_getScaledRect_nothrow();
497
498
0
    if ( aNewLogicRect == aLogicRect )
499
0
        return;
500
501
    // the calculation of the object area has not changed the object size
502
    // it should be done here then
503
    //SfxBooleanFlagGuard aGuard( m_bResizeNoScale, true );
504
505
    // new size of the object area without scaling
506
0
    Size aNewObjSize( tools::Long( aNewLogicRect.GetWidth() / m_aScaleWidth ),
507
0
                      tools::Long( aNewLogicRect.GetHeight() / m_aScaleHeight ) );
508
509
    // now remove scaling from new placement and keep this at the new object area
510
0
    aNewLogicRect.SetSize( aNewObjSize );
511
    // react to the change if the difference is bigger than one pixel
512
0
    Size aPixelDiff =
513
0
        Application::GetDefaultDevice()->LogicToPixel(
514
0
            Size( aLogicRect.GetWidth() - aNewObjSize.Width(),
515
0
                  aLogicRect.GetHeight() - aNewObjSize.Height() ),
516
0
            MapMode(aContainerMapUnit));
517
0
    if( aPixelDiff.Width() || aPixelDiff.Height() )
518
0
    {
519
0
        mpObj->SetLogicRect( tools::Rectangle( aLogicRect.TopLeft(), aNewObjSize ) );
520
0
        mpObj->BroadcastObjectChange();
521
0
    }
522
0
    else
523
0
        mpObj->ActionChanged();
524
0
}
525
// XWindowSupplier
526
527
uno::Reference< awt::XWindow > SAL_CALL SdrLightEmbeddedClient_Impl::getWindow()
528
0
{
529
0
    SolarMutexGuard aGuard;
530
0
    uno::Reference< awt::XWindow > xCurrent = m_xWindow;
531
0
    if ( !xCurrent.is() )
532
0
    {
533
0
        if ( !mpObj )
534
0
            throw uno::RuntimeException();
535
0
        uno::Reference< frame::XFrame> xFrame(lcl_getFrame_throw(mpObj),uno::UNO_QUERY_THROW);
536
0
        xCurrent = xFrame->getComponentWindow();
537
0
    } // if ( !xCurrent.is() )
538
0
    return xCurrent;
539
0
}
540
void SdrLightEmbeddedClient_Impl::setWindow(const uno::Reference< awt::XWindow >& _xWindow)
541
0
{
542
0
    m_xWindow = _xWindow;
543
0
}
544
545
SdrEmbedObjectLink::SdrEmbedObjectLink(SdrOle2Obj* pObject):
546
4
    ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB ),
547
4
    m_pObj(pObject)
548
4
{
549
4
    SetSynchron( false );
550
4
}
551
552
SdrEmbedObjectLink::~SdrEmbedObjectLink()
553
4
{
554
4
}
555
556
::sfx2::SvBaseLink::UpdateResult SdrEmbedObjectLink::DataChanged(
557
    const OUString& /*rMimeType*/, const css::uno::Any & /*rValue*/ )
558
0
{
559
    // Deferred link: the object was not created during import because link
560
    // updates were not yet allowed, complete the creation now.
561
0
    if (m_pObj->CompleteDeferredLink())
562
0
    {
563
0
        m_pObj->GetNewReplacement();
564
0
        m_pObj->SetChanged();
565
0
        return SUCCESS;
566
0
    }
567
568
0
    if ( !m_pObj->UpdateLinkURL_Impl() )
569
0
    {
570
        // the link URL was not changed
571
0
        uno::Reference< embed::XEmbeddedObject > xObject = m_pObj->GetObjRef();
572
0
        OSL_ENSURE( xObject.is(), "The object must exist always!" );
573
0
        if ( xObject.is() )
574
0
        {
575
            // let the object reload the link
576
            // TODO/LATER: reload call could be used for this case
577
578
0
            try
579
0
            {
580
0
                sal_Int32 nState = xObject->getCurrentState();
581
0
                if ( nState != embed::EmbedStates::LOADED )
582
0
                {
583
                    // in some cases the linked file probably is not locked so it could be changed
584
0
                    xObject->changeState( embed::EmbedStates::LOADED );
585
0
                    xObject->changeState( nState );
586
0
                }
587
0
            }
588
0
            catch ( uno::Exception& )
589
0
            {
590
0
            }
591
0
        }
592
0
    }
593
594
0
    m_pObj->GetNewReplacement();
595
0
    m_pObj->SetChanged();
596
597
0
    return SUCCESS;
598
0
}
599
600
void SdrEmbedObjectLink::Closed()
601
0
{
602
0
    m_pObj->BreakFileLink_Impl();
603
0
    SvBaseLink::Closed();
604
0
}
605
606
SdrIFrameLink::SdrIFrameLink(SdrOle2Obj* pObject)
607
0
    : ::sfx2::SvBaseLink(::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB)
608
0
    , m_pObject(pObject)
609
0
{
610
0
    SetSynchron( false );
611
0
}
612
613
::sfx2::SvBaseLink::UpdateResult SdrIFrameLink::DataChanged(
614
    const OUString&, const uno::Any& )
615
0
{
616
0
    uno::Reference<embed::XEmbeddedObject> xObject = m_pObject->GetObjRef();
617
0
    uno::Reference<embed::XCommonEmbedPersist> xPersObj(xObject, uno::UNO_QUERY);
618
0
    if (xPersObj.is())
619
0
    {
620
        // let the IFrameObject reload the link
621
0
        try
622
0
        {
623
0
            xPersObj->reload(uno::Sequence<beans::PropertyValue>(), uno::Sequence<beans::PropertyValue>());
624
0
        }
625
0
        catch (const uno::Exception&)
626
0
        {
627
0
        }
628
629
0
        m_pObject->SetChanged();
630
0
    }
631
632
0
    return SUCCESS;
633
0
}
634
635
class SdrOle2ObjImpl
636
{
637
public:
638
    svt::EmbeddedObjectRef mxObjRef;
639
640
    std::optional<Graphic> moGraphic;
641
    OUString        maProgName;
642
    OUString        aPersistName;       // name of object in persist
643
    rtl::Reference<SdrLightEmbeddedClient_Impl> mxLightClient; // must be registered as client only using AddOwnLightClient() call
644
645
    bool mbFrame:1; // Due to compatibility at SdrTextObj for now
646
    bool mbSuppressSetVisAreaSize:1; // #i118524#
647
    mutable bool mbTypeAsked:1;
648
    mutable bool mbIsChart:1;
649
    bool mbLoadingOLEObjectFailed:1; // New local var to avoid repeated loading if load of OLE2 fails
650
    bool mbConnected:1;
651
    bool mbIgnoreOLEObjectScale : 1 = false; // See SdXMLObjectShapeContext::createFastChildContext
652
653
    sfx2::SvBaseLink* mpObjectLink;
654
    OUString maLinkURL;
655
656
    // Stored when a linked OLE object is deferred during import because
657
    // link updates are not yet allowed, used to complete creation later.
658
    css::uno::Sequence<css::beans::PropertyValue> maDeferredMediaDescriptor;
659
660
    rtl::Reference<SvxUnoShapeModifyListener> mxModifyListener;
661
662
    explicit SdrOle2ObjImpl( bool bFrame ) :
663
520
        mbFrame(bFrame),
664
520
        mbSuppressSetVisAreaSize(false),
665
520
        mbTypeAsked(false),
666
520
        mbIsChart(false),
667
520
        mbLoadingOLEObjectFailed(false),
668
520
        mbConnected(false),
669
520
        mpObjectLink(nullptr)
670
520
    {
671
520
        mxObjRef.Lock();
672
520
    }
673
674
    SdrOle2ObjImpl( bool bFrame, const svt::EmbeddedObjectRef& rObjRef ) :
675
0
        mxObjRef(rObjRef),
676
0
        mbFrame(bFrame),
677
0
        mbSuppressSetVisAreaSize(false),
678
0
        mbTypeAsked(false),
679
0
        mbIsChart(false),
680
0
        mbLoadingOLEObjectFailed(false),
681
0
        mbConnected(false),
682
0
        mpObjectLink(nullptr)
683
0
    {
684
0
        mxObjRef.Lock();
685
0
    }
686
687
    ~SdrOle2ObjImpl()
688
520
    {
689
520
        moGraphic.reset();
690
691
520
        if (mxModifyListener.is())
692
0
        {
693
0
            mxModifyListener->invalidate();
694
0
        }
695
520
    }
696
};
697
698
// Predicate determining whether the given OLE is an internal math
699
// object
700
static bool ImplIsMathObj( const uno::Reference < embed::XEmbeddedObject >& rObjRef )
701
12
{
702
12
    if ( !rObjRef.is() )
703
12
        return false;
704
705
0
    SvGlobalName aClassName( rObjRef->getClassID() );
706
0
    return aClassName == SvGlobalName(SO3_SM_CLASSID_30) ||
707
0
        aClassName == SvGlobalName(SO3_SM_CLASSID_40) ||
708
0
        aClassName == SvGlobalName(SO3_SM_CLASSID_50) ||
709
0
        aClassName == SvGlobalName(SO3_SM_CLASSID_60) ||
710
0
        aClassName == SvGlobalName(SO3_SM_CLASSID);
711
12
}
712
713
// BaseProperties section
714
715
std::unique_ptr<sdr::properties::BaseProperties> SdrOle2Obj::CreateObjectSpecificProperties()
716
520
{
717
520
    return std::make_unique<sdr::properties::OleProperties>(*this);
718
520
}
719
720
// DrawContact section
721
722
std::unique_ptr<sdr::contact::ViewContact> SdrOle2Obj::CreateObjectSpecificViewContact()
723
520
{
724
520
    return std::make_unique<sdr::contact::ViewContactOfSdrOle2Obj>(*this);
725
520
}
726
727
void SdrOle2Obj::Init()
728
520
{
729
    // Stuff that was done from old SetModel:
730
    // #i43086# #i85304 redo the change for charts for the above bugfix, as #i43086# does not occur anymore
731
    // so maybe the ImpSetVisAreaSize call can be removed here completely
732
    // Nevertheless I leave it in for other objects as I am not sure about the side effects when removing now
733
520
    if(!getSdrModelFromSdrObject().isLocked() && !IsChart())
734
16
    {
735
16
        ImpSetVisAreaSize();
736
16
    }
737
738
520
    ::comphelper::IEmbeddedHelper* pDestPers(getSdrModelFromSdrObject().GetPersist());
739
520
    if(pDestPers && !IsEmptyPresObj())
740
520
    {
741
        // object wasn't connected, now it should be
742
520
        Connect_Impl();
743
520
    }
744
745
520
    AddListeners_Impl();
746
520
}
747
748
SdrOle2Obj::SdrOle2Obj(
749
    SdrModel& rSdrModel,
750
    bool bFrame_)
751
520
:   SdrRectObj(rSdrModel),
752
520
    mpImpl(new SdrOle2ObjImpl(bFrame_))
753
520
{
754
520
    Init();
755
520
}
756
757
SdrOle2Obj::SdrOle2Obj(SdrModel& rSdrModel, SdrOle2Obj const & rSource)
758
0
:   SdrRectObj(rSdrModel, rSource),
759
0
    mpImpl(new SdrOle2ObjImpl(/*bFrame*/false))
760
0
{
761
0
    Init();
762
763
    // Manually copying bClosedObj attribute
764
0
    SetClosedObj( rSource.IsClosedObj() );
765
766
0
    mpImpl->aPersistName = rSource.mpImpl->aPersistName;
767
0
    mpImpl->maProgName = rSource.mpImpl->maProgName;
768
0
    mpImpl->mbFrame = rSource.mpImpl->mbFrame;
769
770
0
    if (rSource.mpImpl->moGraphic)
771
0
    {
772
0
        mpImpl->moGraphic.emplace(*rSource.mpImpl->moGraphic);
773
0
    }
774
775
0
    if( IsEmptyPresObj() )
776
0
        return;
777
778
0
    ::comphelper::IEmbeddedHelper* pDestPers(getSdrModelFromSdrObject().GetPersist());
779
0
    ::comphelper::IEmbeddedHelper* pSrcPers(rSource.getSdrModelFromSdrObject().GetPersist());
780
0
    if( !(pDestPers && pSrcPers) )
781
0
        return;
782
783
0
    DBG_ASSERT( !mpImpl->mxObjRef.is(), "Object already existing!" );
784
0
    comphelper::EmbeddedObjectContainer& rContainer = pSrcPers->getEmbeddedObjectContainer();
785
0
    uno::Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( mpImpl->aPersistName );
786
0
    if ( xObj.is() )
787
0
    {
788
0
        OUString aTmp;
789
0
        mpImpl->mxObjRef.Assign( pDestPers->getEmbeddedObjectContainer().CopyAndGetEmbeddedObject(
790
0
            rContainer, xObj, aTmp, pSrcPers->getDocumentBaseURL(), pDestPers->getDocumentBaseURL()), rSource.GetAspect());
791
0
        mpImpl->mbTypeAsked = false;
792
0
        mpImpl->aPersistName = aTmp;
793
0
        CheckFileLink_Impl();
794
0
    }
795
796
0
    Connect();
797
0
}
798
799
SdrOle2Obj::SdrOle2Obj(
800
    SdrModel& rSdrModel,
801
    const svt::EmbeddedObjectRef& rNewObjRef,
802
    const OUString& rNewObjName,
803
    const tools::Rectangle& rNewRect)
804
0
:   SdrRectObj(rSdrModel, rNewRect),
805
0
    mpImpl(new SdrOle2ObjImpl(false/*bFrame_*/, rNewObjRef))
806
0
{
807
0
    osl_atomic_increment(&m_refCount);
808
809
0
    mpImpl->aPersistName = rNewObjName;
810
811
0
    if (mpImpl->mxObjRef.is() && (mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
812
0
        m_bSizProt = true;
813
814
    // For math objects, set closed state to transparent
815
0
    SetClosedObj(!ImplIsMathObj( mpImpl->mxObjRef.GetObject() ));
816
817
0
    Init();
818
819
0
    osl_atomic_decrement(&m_refCount);
820
0
}
821
822
OUString SdrOle2Obj::GetStyleString()
823
0
{
824
0
    OUString strStyle;
825
0
    if (mpImpl->mxObjRef.is() && mpImpl->mxObjRef.IsChart())
826
0
    {
827
0
        strStyle = mpImpl->mxObjRef.GetChartType();
828
0
    }
829
0
    return strStyle;
830
0
}
831
832
SdrOle2Obj::~SdrOle2Obj()
833
520
{
834
520
    if ( mpImpl->mbConnected )
835
0
        Disconnect();
836
837
520
    DisconnectFileLink_Impl();
838
839
520
    if (mpImpl->mxLightClient)
840
0
    {
841
0
        mpImpl->mxLightClient->disconnect();
842
0
        mpImpl->mxLightClient.clear();
843
0
    }
844
520
}
845
846
void SdrOle2Obj::SetAspect( sal_Int64 nAspect )
847
16
{
848
16
    mpImpl->mxObjRef.SetViewAspect( nAspect );
849
16
}
850
851
const svt::EmbeddedObjectRef& SdrOle2Obj::getEmbeddedObjectRef() const
852
0
{
853
0
    return mpImpl->mxObjRef;
854
0
}
855
856
sal_Int64 SdrOle2Obj::GetAspect() const
857
76
{
858
76
    return mpImpl->mxObjRef.GetViewAspect();
859
76
}
860
861
bool SdrOle2Obj::isInplaceActive() const
862
0
{
863
0
    return mpImpl->mxObjRef.is() && embed::EmbedStates::INPLACE_ACTIVE == mpImpl->mxObjRef->getCurrentState();
864
0
}
865
866
bool SdrOle2Obj::isUiActive() const
867
0
{
868
0
    return mpImpl->mxObjRef.is() && embed::EmbedStates::UI_ACTIVE == mpImpl->mxObjRef->getCurrentState();
869
0
}
870
871
void SdrOle2Obj::SetGraphic(const Graphic& rGrf)
872
113
{
873
    // only for setting a preview graphic
874
113
    mpImpl->moGraphic.emplace(rGrf);
875
876
113
    SetChanged();
877
113
    BroadcastObjectChange();
878
113
}
879
880
void SdrOle2Obj::ClearGraphic()
881
0
{
882
0
    mpImpl->moGraphic.reset();
883
884
0
    SetChanged();
885
0
    BroadcastObjectChange();
886
0
}
887
888
void SdrOle2Obj::SetProgName( const OUString& rName )
889
0
{
890
0
    mpImpl->maProgName = rName;
891
0
}
892
893
const OUString& SdrOle2Obj::GetProgName() const
894
0
{
895
0
    return mpImpl->maProgName;
896
0
}
897
898
bool SdrOle2Obj::IsEmpty() const
899
366
{
900
366
    return !mpImpl->mxObjRef.is();
901
366
}
902
903
void SdrOle2Obj::Connect(SvxOle2Shape* pCreator)
904
532
{
905
532
    if( IsEmptyPresObj() )
906
113
        return;
907
908
419
    if( mpImpl->mbConnected )
909
0
    {
910
        // currently there are situations where it seems to be unavoidable to have multiple connects
911
        // changing this would need a larger code rewrite, so for now I remove the assertion
912
        // OSL_FAIL("Connect() called on connected object!");
913
0
        return;
914
0
    }
915
916
419
    Connect_Impl(pCreator);
917
419
    AddListeners_Impl();
918
419
}
919
920
bool SdrOle2Obj::UpdateLinkURL_Impl()
921
0
{
922
0
    bool bResult = false;
923
924
0
    if ( mpImpl->mpObjectLink )
925
0
    {
926
0
        sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
927
928
0
        if ( pLinkManager )
929
0
        {
930
0
            OUString aNewLinkURL;
931
0
            sfx2::LinkManager::GetDisplayNames( mpImpl->mpObjectLink, nullptr, &aNewLinkURL );
932
0
            if ( !aNewLinkURL.equalsIgnoreAsciiCase( mpImpl->maLinkURL ) )
933
0
            {
934
0
                GetObjRef_Impl();
935
0
                uno::Reference<embed::XCommonEmbedPersist> xPersObj( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY );
936
0
                OSL_ENSURE( xPersObj.is(), "The object must exist!" );
937
0
                if ( xPersObj.is() )
938
0
                {
939
0
                    try
940
0
                    {
941
0
                        sal_Int32 nCurState = mpImpl->mxObjRef->getCurrentState();
942
0
                        if ( nCurState != embed::EmbedStates::LOADED )
943
0
                            mpImpl->mxObjRef->changeState(embed::EmbedStates::LOADED);
944
945
                        // TODO/LATER: there should be possible to get current mediadescriptor settings from the object
946
0
                        uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
947
0
                            u"URL"_ustr, aNewLinkURL) };
948
0
                        xPersObj->reload( aArgs, uno::Sequence< beans::PropertyValue >() );
949
950
0
                        mpImpl->maLinkURL = aNewLinkURL;
951
0
                        bResult = true;
952
953
0
                        if ( nCurState != embed::EmbedStates::LOADED )
954
0
                            mpImpl->mxObjRef->changeState(nCurState);
955
0
                    }
956
0
                    catch( css::uno::Exception const & )
957
0
                    {
958
0
                        TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::UpdateLinkURL_Impl()" );
959
0
                    }
960
0
                }
961
962
0
                if ( !bResult )
963
0
                {
964
                    // TODO/LATER: return the old name to the link manager, is it possible?
965
0
                }
966
0
            }
967
0
        }
968
0
    }
969
970
0
    return bResult;
971
0
}
972
973
void SdrOle2Obj::BreakFileLink_Impl()
974
0
{
975
0
    uno::Reference<document::XStorageBasedDocument> xDoc(getSdrModelFromSdrObject().getUnoModel(), uno::UNO_QUERY);
976
977
0
    if ( !xDoc.is() )
978
0
        return;
979
980
0
    uno::Reference< embed::XStorage > xStorage = xDoc->getDocumentStorage();
981
0
    if ( !xStorage.is() )
982
0
        return;
983
984
0
    try
985
0
    {
986
0
        uno::Reference< embed::XLinkageSupport > xLinkSupport( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY_THROW );
987
0
        xLinkSupport->breakLink( xStorage, mpImpl->aPersistName );
988
0
        DisconnectFileLink_Impl();
989
0
        mpImpl->maLinkURL.clear();
990
0
    }
991
0
    catch( css::uno::Exception& )
992
0
    {
993
0
        TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::BreakFileLink_Impl()" );
994
0
    }
995
0
}
996
997
void SdrOle2Obj::DisconnectFileLink_Impl()
998
520
{
999
520
    sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
1000
1001
520
    if ( pLinkManager && mpImpl->mpObjectLink )
1002
4
    {
1003
4
        pLinkManager->Remove( mpImpl->mpObjectLink );
1004
4
        mpImpl->mpObjectLink = nullptr;
1005
4
    }
1006
520
}
1007
1008
void SdrOle2Obj::CheckFileLink_Impl()
1009
12
{
1010
12
    if (!mpImpl->mxObjRef.GetObject().is() || mpImpl->mpObjectLink)
1011
12
        return;
1012
1013
0
    try
1014
0
    {
1015
0
        uno::Reference<embed::XEmbeddedObject> xObject = mpImpl->mxObjRef.GetObject();
1016
0
        if (!xObject)
1017
0
            return;
1018
1019
0
        bool bIFrame = false;
1020
1021
0
        OUString aLinkURL;
1022
0
        uno::Reference<embed::XLinkageSupport> xLinkSupport(xObject, uno::UNO_QUERY);
1023
0
        if (xLinkSupport)
1024
0
        {
1025
0
            if (xLinkSupport->isLink())
1026
0
                aLinkURL = xLinkSupport->getLinkURL();
1027
0
        }
1028
0
        else
1029
0
        {
1030
            // get IFrame (Floating Frames) listed and updatable from the
1031
            // manage links dialog
1032
0
            SvGlobalName aClassId(xObject->getClassID());
1033
0
            if (aClassId == SvGlobalName(SO3_IFRAME_CLASSID))
1034
0
            {
1035
0
                uno::Reference<beans::XPropertySet> xSet(xObject->getComponent(), uno::UNO_QUERY);
1036
0
                if (xSet.is())
1037
0
                    xSet->getPropertyValue(u"FrameURL"_ustr) >>= aLinkURL;
1038
0
                bIFrame = true;
1039
0
            }
1040
0
        }
1041
1042
0
        if (!aLinkURL.isEmpty()) // this is a file link so the model link manager should handle it
1043
0
        {
1044
0
            sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
1045
1046
0
            if ( pLinkManager )
1047
0
            {
1048
0
                SdrEmbedObjectLink* pEmbedObjectLink = nullptr;
1049
0
                if (!bIFrame)
1050
0
                {
1051
0
                    pEmbedObjectLink = new SdrEmbedObjectLink(this);
1052
0
                    mpImpl->mpObjectLink = pEmbedObjectLink;
1053
0
                }
1054
0
                else
1055
0
                    mpImpl->mpObjectLink = new SdrIFrameLink(this);
1056
0
                mpImpl->maLinkURL = aLinkURL;
1057
0
                pLinkManager->InsertFileLink( *mpImpl->mpObjectLink, sfx2::SvBaseLinkObjectType::ClientOle, aLinkURL );
1058
0
                if (pEmbedObjectLink)
1059
0
                    pEmbedObjectLink->Connect();
1060
0
            }
1061
0
        }
1062
0
    }
1063
0
    catch (const css::uno::Exception&)
1064
0
    {
1065
0
        TOOLS_WARN_EXCEPTION("svx", "SdrOle2Obj::CheckFileLink_Impl()");
1066
0
    }
1067
0
}
1068
1069
void SdrOle2Obj::SetDeferredLink(const OUString& rLinkURL,
1070
                                 const uno::Sequence<beans::PropertyValue>& rMediaDescriptor)
1071
4
{
1072
4
    if (mpImpl->mpObjectLink)
1073
0
        return;
1074
1075
4
    mpImpl->maLinkURL = rLinkURL;
1076
4
    mpImpl->maDeferredMediaDescriptor = rMediaDescriptor;
1077
1078
4
    sfx2::LinkManager* pLinkManager = getSdrModelFromSdrObject().GetLinkManager();
1079
4
    if (!pLinkManager)
1080
0
        return;
1081
1082
4
    mpImpl->mpObjectLink = new SdrEmbedObjectLink(this);
1083
4
    pLinkManager->InsertFileLink(*mpImpl->mpObjectLink,
1084
4
        sfx2::SvBaseLinkObjectType::ClientOle, mpImpl->maLinkURL);
1085
4
}
1086
1087
bool SdrOle2Obj::CompleteDeferredLink()
1088
0
{
1089
0
    if (!mpImpl->maDeferredMediaDescriptor.hasElements())
1090
0
        return false;
1091
1092
    // take ownership of the descriptor and clear it so we don't retry
1093
0
    uno::Sequence<beans::PropertyValue> aMediaDescriptor;
1094
0
    std::swap(aMediaDescriptor, mpImpl->maDeferredMediaDescriptor);
1095
1096
0
    ::comphelper::IEmbeddedHelper* pPersist = getSdrModelFromSdrObject().GetPersist();
1097
0
    if (!pPersist)
1098
0
        return false;
1099
1100
0
    OUString aPersistName;
1101
0
    uno::Reference<embed::XEmbeddedObject> xObj =
1102
0
        pPersist->getEmbeddedObjectContainer().InsertEmbeddedLink(
1103
0
            aMediaDescriptor, aPersistName);
1104
0
    if (!xObj.is())
1105
0
        return false;
1106
1107
0
    SyncObjVisualArea(xObj);
1108
1109
0
    SetObjRef(xObj);
1110
0
    SetPersistName(aPersistName);
1111
0
    SetChanged();
1112
0
    return true;
1113
0
}
1114
1115
void SdrOle2Obj::SyncObjVisualArea(const uno::Reference<embed::XEmbeddedObject>& xObj)
1116
0
{
1117
0
    tools::Rectangle aRect = GetLogicRect();
1118
0
    if (aRect.GetWidth() == 101 && aRect.GetHeight() == 101)
1119
0
    {
1120
        // default size, take it from the OLE
1121
0
        try
1122
0
        {
1123
0
            awt::Size aSz = xObj->getVisualAreaSize(GetAspect());
1124
0
            aRect.SetSize(Size(aSz.Width, aSz.Height));
1125
0
        }
1126
0
        catch (const uno::Exception&)
1127
0
        {
1128
0
            TOOLS_WARN_EXCEPTION("svx.svdraw", "");
1129
0
        }
1130
0
        SetLogicRect(aRect);
1131
0
    }
1132
0
    else
1133
0
    {
1134
0
        Size aSize = aRect.GetSize();
1135
0
        awt::Size aSz(aSize.Width(), aSize.Height());
1136
0
        try
1137
0
        {
1138
0
            xObj->setVisualAreaSize(GetAspect(), aSz);
1139
0
        }
1140
0
        catch (const uno::Exception&)
1141
0
        {
1142
0
            TOOLS_WARN_EXCEPTION("svx.svdraw", "");
1143
0
        }
1144
0
    }
1145
0
}
1146
1147
bool SdrOle2Obj::HasDeferredLink() const
1148
0
{
1149
0
    return mpImpl->maDeferredMediaDescriptor.hasElements();
1150
0
}
1151
1152
void SdrOle2Obj::Connect_Impl(SvxOle2Shape* pCreator)
1153
939
{
1154
939
    if(mpImpl->aPersistName.isEmpty() )
1155
927
        return;
1156
1157
12
    try
1158
12
    {
1159
12
        ::comphelper::IEmbeddedHelper* pPers(getSdrModelFromSdrObject().GetPersist());
1160
1161
12
        if ( pPers )
1162
12
        {
1163
12
            comphelper::EmbeddedObjectContainer& rContainer = pPers->getEmbeddedObjectContainer();
1164
1165
12
            if ( !rContainer.HasEmbeddedObject( mpImpl->aPersistName )
1166
12
              || ( mpImpl->mxObjRef.is() && !rContainer.HasEmbeddedObject( mpImpl->mxObjRef.GetObject() ) ) )
1167
0
            {
1168
                // object not known to container document
1169
                // No object -> disaster!
1170
0
                DBG_ASSERT( mpImpl->mxObjRef.is(), "No object in connect!");
1171
0
                if ( mpImpl->mxObjRef.is() )
1172
0
                {
1173
                    // object came from the outside, now add it to the container
1174
0
                    OUString aTmp;
1175
0
                    rContainer.InsertEmbeddedObject( mpImpl->mxObjRef.GetObject(), aTmp );
1176
0
                    mpImpl->aPersistName = aTmp;
1177
0
                }
1178
0
            }
1179
12
            else if ( !mpImpl->mxObjRef.is() )
1180
12
            {
1181
12
                mpImpl->mxObjRef.Assign( rContainer.GetEmbeddedObject( mpImpl->aPersistName ), mpImpl->mxObjRef.GetViewAspect() );
1182
12
                mpImpl->mbTypeAsked = false;
1183
12
            }
1184
1185
12
            if ( mpImpl->mxObjRef.GetObject().is() )
1186
0
            {
1187
0
                mpImpl->mxObjRef.AssignToContainer( &rContainer, mpImpl->aPersistName );
1188
0
                mpImpl->mbConnected = true;
1189
0
                mpImpl->mxObjRef.Lock();
1190
0
            }
1191
12
        }
1192
1193
12
        if (pCreator)
1194
12
        {
1195
12
            OUString sFrameURL(pCreator->GetAndClearInitialFrameURL());
1196
12
            if (!sFrameURL.isEmpty() && svt::EmbeddedObjectRef::TryRunningState(mpImpl->mxObjRef.GetObject()))
1197
0
            {
1198
0
                uno::Reference<beans::XPropertySet> xSet(mpImpl->mxObjRef->getComponent(), uno::UNO_QUERY);
1199
0
                if (xSet.is())
1200
0
                    xSet->setPropertyValue(u"FrameURL"_ustr, uno::Any(sFrameURL));
1201
0
            }
1202
12
        }
1203
1204
12
        if ( mpImpl->mxObjRef.is() )
1205
0
        {
1206
0
            if ( !mpImpl->mxLightClient.is() )
1207
0
                mpImpl->mxLightClient = new SdrLightEmbeddedClient_Impl( this );
1208
1209
0
            mpImpl->mxObjRef->addStateChangeListener( mpImpl->mxLightClient );
1210
0
            mpImpl->mxObjRef->addEventListener( mpImpl->mxLightClient );
1211
1212
0
            if ( mpImpl->mxObjRef->getCurrentState() != embed::EmbedStates::LOADED )
1213
0
                GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
1214
1215
0
            CheckFileLink_Impl();
1216
1217
0
            uno::Reference< container::XChild > xChild( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY );
1218
0
            if( xChild.is() )
1219
0
            {
1220
0
                uno::Reference< uno::XInterface > xParent( getSdrModelFromSdrObject().getUnoModel());
1221
0
                if( xParent.is())
1222
0
                    xChild->setParent( getSdrModelFromSdrObject().getUnoModel() );
1223
0
            }
1224
1225
0
        }
1226
12
    }
1227
12
    catch( css::uno::Exception& )
1228
12
    {
1229
0
        TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Connect_Impl()" );
1230
0
    }
1231
12
}
1232
1233
void SdrOle2Obj::ObjectLoaded()
1234
0
{
1235
0
    AddListeners_Impl();
1236
0
}
1237
1238
void SdrOle2Obj::AddListeners_Impl()
1239
939
{
1240
939
    if( !(mpImpl->mxObjRef.is() && mpImpl->mxObjRef->getCurrentState() != embed::EmbedStates::LOADED) )
1241
939
        return;
1242
1243
    // register modify listener
1244
0
    if (!mpImpl->mxModifyListener.is())
1245
0
    {
1246
0
        mpImpl->mxModifyListener = new SvxUnoShapeModifyListener(this);
1247
0
    }
1248
1249
0
    uno::Reference< util::XModifyBroadcaster > xBC( getXModel(), uno::UNO_QUERY );
1250
0
    if (xBC.is())
1251
0
    {
1252
0
        xBC->addModifyListener( mpImpl->mxModifyListener );
1253
0
    }
1254
0
}
1255
1256
void SdrOle2Obj::Disconnect()
1257
391
{
1258
391
    if( IsEmptyPresObj() )
1259
0
        return;
1260
1261
391
    if( !mpImpl->mbConnected )
1262
391
    {
1263
391
        OSL_FAIL("Disconnect() called on disconnected object!");
1264
391
        return;
1265
391
    }
1266
1267
0
    RemoveListeners_Impl();
1268
0
    Disconnect_Impl();
1269
0
}
1270
1271
void SdrOle2Obj::RemoveListeners_Impl()
1272
0
{
1273
0
    if ( !mpImpl->mxObjRef.is() || mpImpl->aPersistName.isEmpty() )
1274
0
        return;
1275
1276
0
    try
1277
0
    {
1278
0
        sal_Int32 nState = mpImpl->mxObjRef->getCurrentState();
1279
0
        if ( nState != embed::EmbedStates::LOADED )
1280
0
        {
1281
0
            uno::Reference< util::XModifyBroadcaster > xBC( getXModel(), uno::UNO_QUERY );
1282
0
            if (xBC.is() && mpImpl->mxModifyListener.is())
1283
0
            {
1284
0
                xBC->removeModifyListener( mpImpl->mxModifyListener );
1285
0
            }
1286
0
        }
1287
0
    }
1288
0
    catch( css::uno::Exception& )
1289
0
    {
1290
0
        TOOLS_WARN_EXCEPTION( "svx",  "SdrOle2Obj::RemoveListeners_Impl()" );
1291
0
    }
1292
0
}
1293
1294
void SdrOle2Obj::Disconnect_Impl()
1295
0
{
1296
0
    try
1297
0
    {
1298
0
        if ( !mpImpl->aPersistName.isEmpty() )
1299
0
        {
1300
0
            if( getSdrModelFromSdrObject().IsInDestruction() )
1301
0
            {
1302
                // TODO/LATER: here we must assume that the destruction of the model is enough to make clear that we will not
1303
                // remove the object from the container, even if the DrawingObject itself is not destroyed (unfortunately this
1304
                // There is no real need to do the following removing of the object from the container
1305
                // in case the model has correct persistence, but in case of problems such a removing
1306
                // would make the behavior of the office more stable
1307
1308
0
                comphelper::EmbeddedObjectContainer* pContainer = mpImpl->mxObjRef.GetContainer();
1309
0
                if ( pContainer )
1310
0
                {
1311
0
                    pContainer->CloseEmbeddedObject( mpImpl->mxObjRef.GetObject() );
1312
0
                    mpImpl->mxObjRef.AssignToContainer( nullptr, mpImpl->aPersistName );
1313
0
                }
1314
1315
                // happens later than the destruction of the model, so we can't assert that).
1316
                //DBG_ASSERT( bInDestruction, "Model is destroyed, but not me?!" );
1317
                //TODO/LATER: should be make sure that the ObjectShell also forgets the object, because we will close it soon?
1318
                /*
1319
                uno::Reference < util::XCloseable > xClose( xObjRef, uno::UNO_QUERY );
1320
                if ( xClose.is() )
1321
                {
1322
                    try
1323
                    {
1324
                        xClose->close( true );
1325
                    }
1326
                    catch ( util::CloseVetoException& )
1327
                    {
1328
                        // there's still someone who needs the object!
1329
                    }
1330
                }
1331
1332
                xObjRef = NULL;*/
1333
0
            }
1334
0
            else if ( mpImpl->mxObjRef.is() )
1335
0
            {
1336
0
                if ( getSdrModelFromSdrObject().getUnoModel().is() )
1337
0
                {
1338
                    // remove object, but don't close it (that's up to someone else)
1339
0
                    comphelper::EmbeddedObjectContainer* pContainer = mpImpl->mxObjRef.GetContainer();
1340
0
                    if ( pContainer )
1341
0
                    {
1342
0
                        pContainer->RemoveEmbeddedObject( mpImpl->mxObjRef.GetObject() );
1343
1344
                        // TODO/LATER: mpImpl->aPersistName contains outdated information, to keep it updated
1345
                        // it should be returned from RemoveEmbeddedObject call. Currently it is no problem,
1346
                        // since no container is adjusted, actually the empty string could be provided as a name here
1347
0
                        mpImpl->mxObjRef.AssignToContainer( nullptr, mpImpl->aPersistName );
1348
0
                    }
1349
1350
0
                    DisconnectFileLink_Impl();
1351
0
                }
1352
0
            }
1353
0
        }
1354
1355
0
        if ( mpImpl->mxObjRef.is() && mpImpl->mxLightClient.is() )
1356
0
        {
1357
0
            mpImpl->mxObjRef->removeStateChangeListener ( mpImpl->mxLightClient );
1358
0
            mpImpl->mxObjRef->removeEventListener( mpImpl->mxLightClient );
1359
0
            mpImpl->mxObjRef->setClientSite( nullptr );
1360
1361
0
            GetSdrGlobalData().GetOLEObjCache().RemoveObj(this);
1362
0
        }
1363
0
    }
1364
0
    catch( css::uno::Exception& )
1365
0
    {
1366
0
        TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Disconnect_Impl()" );
1367
0
    }
1368
1369
0
    mpImpl->mbConnected = false;
1370
0
}
1371
1372
rtl::Reference<SdrObject> SdrOle2Obj::createSdrGrafObjReplacement(bool bAddText) const
1373
0
{
1374
0
    const Graphic* pOLEGraphic = GetGraphic();
1375
1376
0
    if(pOLEGraphic)
1377
0
    {
1378
        // #i118485# allow creating a SdrGrafObj representation
1379
0
        rtl::Reference<SdrGrafObj> pClone = new SdrGrafObj(
1380
0
            getSdrModelFromSdrObject(),
1381
0
            *pOLEGraphic);
1382
1383
        // copy transformation
1384
0
        basegfx::B2DHomMatrix aMatrix;
1385
0
        basegfx::B2DPolyPolygon aPolyPolygon;
1386
1387
0
        TRGetBaseGeometry(aMatrix, aPolyPolygon);
1388
0
        pClone->TRSetBaseGeometry(aMatrix, aPolyPolygon);
1389
1390
        // copy all attributes to support graphic styles for OLEs
1391
0
        pClone->SetStyleSheet(GetStyleSheet(), false);
1392
0
        pClone->SetMergedItemSet(GetMergedItemSet());
1393
1394
0
        if(bAddText)
1395
0
        {
1396
            // #i118485# copy text (Caution! Model needed, as guaranteed in aw080)
1397
0
            OutlinerParaObject* pOPO = GetOutlinerParaObject();
1398
1399
0
            if(pOPO)
1400
0
            {
1401
0
                pClone->NbcSetOutlinerParaObject(*pOPO);
1402
0
            }
1403
0
        }
1404
1405
0
        return rtl::Reference<SdrObject>(pClone);
1406
0
    }
1407
0
    else
1408
0
    {
1409
        // #i100710# pOLEGraphic may be zero (no visualisation available),
1410
        // so we need to use the OLE replacement graphic
1411
0
        rtl::Reference<SdrRectObj> pClone = new SdrRectObj(
1412
0
            getSdrModelFromSdrObject(),
1413
0
            GetSnapRect());
1414
1415
        // gray outline
1416
0
        pClone->SetMergedItem(XLineStyleItem(css::drawing::LineStyle_SOLID));
1417
0
        const svtools::ColorConfig aColorConfig;
1418
0
        const svtools::ColorConfigValue aColor(aColorConfig.GetColorValue(svtools::DOCBOUNDARIES));
1419
0
        pClone->SetMergedItem(XLineColorItem(OUString(), aColor.nColor));
1420
1421
        // bitmap fill
1422
0
        pClone->SetMergedItem(XFillStyleItem(drawing::FillStyle_BITMAP));
1423
0
        pClone->SetMergedItem(XFillBitmapItem(OUString(), GetEmptyOLEReplacementGraphic()));
1424
0
        pClone->SetMergedItem(XFillBmpTileItem(false));
1425
0
        pClone->SetMergedItem(XFillBmpStretchItem(false));
1426
1427
0
        return rtl::Reference<SdrObject>(pClone);
1428
0
    }
1429
0
}
1430
1431
rtl::Reference<SdrObject> SdrOle2Obj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
1432
0
{
1433
    // #i118485# missing converter added
1434
0
    rtl::Reference<SdrObject> pRetval = createSdrGrafObjReplacement(true);
1435
1436
0
    if(pRetval)
1437
0
    {
1438
0
        return pRetval->DoConvertToPolyObj(bBezier, bAddText);
1439
0
    }
1440
1441
0
    return nullptr;
1442
0
}
1443
1444
void SdrOle2Obj::handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage)
1445
649
{
1446
649
    const bool bRemove(pNewPage == nullptr && pOldPage != nullptr);
1447
649
    const bool bInsert(pNewPage != nullptr && pOldPage == nullptr);
1448
1449
649
    if (bRemove && mpImpl->mbConnected )
1450
0
    {
1451
0
        Disconnect();
1452
0
    }
1453
1454
    // call parent
1455
649
    SdrRectObj::handlePageChange(pOldPage, pNewPage);
1456
1457
649
    if (bInsert && !mpImpl->mbConnected )
1458
520
    {
1459
520
        Connect();
1460
520
    }
1461
649
}
1462
1463
void SdrOle2Obj::SetObjRef( const css::uno::Reference < css::embed::XEmbeddedObject >& rNewObjRef )
1464
0
{
1465
0
    DBG_ASSERT( !rNewObjRef.is() || !mpImpl->mxObjRef.GetObject().is(), "SetObjRef called on already initialized object!");
1466
0
    if( rNewObjRef == mpImpl->mxObjRef.GetObject() )
1467
0
        return;
1468
1469
    // the caller of the method is responsible to control the old object, it will not be closed here
1470
    // Otherwise WW8 import crashes because it transfers control to OLENode by this method
1471
0
    if ( mpImpl->mxObjRef.GetObject().is() )
1472
0
        mpImpl->mxObjRef.Lock( false );
1473
1474
    // avoid removal of object in Disconnect! It is definitely a HACK to call SetObjRef(0)!
1475
    // This call will try to close the objects; so if anybody else wants to keep it, it must be locked by a CloseListener
1476
0
    mpImpl->mxObjRef.Clear();
1477
1478
0
    if ( mpImpl->mbConnected )
1479
0
        Disconnect();
1480
1481
0
    mpImpl->mxObjRef.Assign( rNewObjRef, GetAspect() );
1482
0
    mpImpl->mbTypeAsked = false;
1483
1484
0
    if ( mpImpl->mxObjRef.is() )
1485
0
    {
1486
0
        mpImpl->moGraphic.reset();
1487
1488
0
        if ( mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE )
1489
0
            SetResizeProtect(true);
1490
1491
        // For math objects, set closed state to transparent
1492
0
        SetClosedObj(!ImplIsMathObj( rNewObjRef ));
1493
1494
0
        Connect();
1495
0
    }
1496
1497
0
    SetChanged();
1498
0
    BroadcastObjectChange();
1499
0
}
1500
1501
void SdrOle2Obj::SetClosedObj( bool bIsClosed )
1502
12
{
1503
    // TODO/LATER: do we still need this hack?
1504
    // Allow changes to the closed state of OLE objects
1505
12
    m_bClosedObj = bIsClosed;
1506
12
}
1507
1508
rtl::Reference<SdrObject> SdrOle2Obj::getFullDragClone() const
1509
0
{
1510
    // #i118485# use central replacement generator
1511
0
    return createSdrGrafObjReplacement(false);
1512
0
}
1513
1514
void SdrOle2Obj::SetPersistName( const OUString& rPersistName, SvxOle2Shape* pCreator )
1515
12
{
1516
12
    DBG_ASSERT( mpImpl->aPersistName.isEmpty(), "Persist name changed!");
1517
1518
12
    mpImpl->aPersistName = rPersistName;
1519
12
    mpImpl->mbLoadingOLEObjectFailed = false;
1520
1521
12
    Connect(pCreator);
1522
12
    SetChanged();
1523
12
}
1524
1525
void SdrOle2Obj::AbandonObject()
1526
0
{
1527
0
    mpImpl->aPersistName.clear();
1528
0
    mpImpl->mbLoadingOLEObjectFailed = false;
1529
0
    SetObjRef(nullptr);
1530
0
}
1531
1532
const OUString& SdrOle2Obj::GetPersistName() const
1533
773
{
1534
773
    return mpImpl->aPersistName;
1535
773
}
1536
1537
void SdrOle2Obj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1538
0
{
1539
    // #i118485# Allowing much more attributes for OLEs
1540
0
    rInfo.bRotateFreeAllowed = true;
1541
0
    rInfo.bRotate90Allowed = true;
1542
0
    rInfo.bMirrorFreeAllowed = true;
1543
0
    rInfo.bMirror45Allowed = true;
1544
0
    rInfo.bMirror90Allowed = true;
1545
0
    rInfo.bTransparenceAllowed = true;
1546
0
    rInfo.bShearAllowed = true;
1547
0
    rInfo.bEdgeRadiusAllowed = false;
1548
0
    rInfo.bNoOrthoDesired = false;
1549
0
    rInfo.bCanConvToPath = true;
1550
0
    rInfo.bCanConvToPoly = true;
1551
0
    rInfo.bCanConvToPathLineToArea = false;
1552
0
    rInfo.bCanConvToPolyLineToArea = false;
1553
0
    rInfo.bCanConvToContour = true;
1554
0
}
1555
1556
SdrObjKind SdrOle2Obj::GetObjIdentifier() const
1557
6.56k
{
1558
6.56k
    return mpImpl->mbFrame ? SdrObjKind::OLEPluginFrame : SdrObjKind::OLE2;
1559
6.56k
}
1560
1561
OUString SdrOle2Obj::TakeObjNameSingul() const
1562
0
{
1563
0
    OUStringBuffer sName(SvxResId(mpImpl->mbFrame ? STR_ObjNameSingulFrame : STR_ObjNameSingulOLE2));
1564
1565
0
    const OUString aName(GetName());
1566
1567
0
    if (!aName.isEmpty())
1568
0
    {
1569
0
        sName.append(" '" + aName + "\'");
1570
0
    }
1571
1572
0
    return sName.makeStringAndClear();
1573
0
}
1574
1575
OUString SdrOle2Obj::TakeObjNamePlural() const
1576
0
{
1577
0
    return SvxResId(mpImpl->mbFrame ? STR_ObjNamePluralFrame : STR_ObjNamePluralOLE2);
1578
0
}
1579
1580
rtl::Reference<SdrObject> SdrOle2Obj::implCloneSdrObject(SdrModel& rTargetModel) const
1581
0
{
1582
0
    return new SdrOle2Obj(rTargetModel, *this);
1583
0
}
1584
1585
void SdrOle2Obj::ImpSetVisAreaSize()
1586
64
{
1587
    // #i118524# do not again set VisAreaSize when the call comes from OLE client (e.g. ObjectAreaChanged)
1588
64
    if (mpImpl->mbSuppressSetVisAreaSize)
1589
0
        return;
1590
1591
    // currently there is no need to recalculate scaling for iconified objects
1592
    // TODO/LATER: it might be needed in future when it is possible to change the icon
1593
64
    if ( GetAspect() == embed::Aspects::MSOLE_ICON )
1594
0
        return;
1595
1596
    // the object area of an embedded object was changed, e.g. by user interaction an a selected object
1597
64
    GetObjRef();
1598
64
    if (!mpImpl->mxObjRef.is())
1599
64
        return;
1600
1601
0
    sal_Int64 nMiscStatus = mpImpl->mxObjRef->getStatus( GetAspect() );
1602
1603
    // the client is required to get access to scaling
1604
0
    SfxInPlaceClient* pClient(
1605
0
        SfxInPlaceClient::GetClient(
1606
0
            dynamic_cast<SfxObjectShell*>(
1607
0
                getSdrModelFromSdrObject().GetPersist()),
1608
0
                mpImpl->mxObjRef.GetObject()));
1609
0
    const bool bHasOwnClient(
1610
0
        mpImpl->mxLightClient.is() &&
1611
0
        mpImpl->mxObjRef->getClientSite() == uno::Reference< embed::XEmbeddedClient >( mpImpl->mxLightClient ) );
1612
1613
0
    if ( pClient || bHasOwnClient )
1614
0
    {
1615
        // TODO: IMHO we need to do similar things when object is UIActive or OutplaceActive?!
1616
0
        if ( ((nMiscStatus & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) &&
1617
0
                svt::EmbeddedObjectRef::TryRunningState( mpImpl->mxObjRef.GetObject() ))
1618
0
                || mpImpl->mxObjRef->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE
1619
0
                )
1620
0
        {
1621
0
            double fScaleWidth;
1622
0
            double fScaleHeight;
1623
0
            if ( pClient )
1624
0
            {
1625
0
                fScaleWidth = pClient->GetScaleWidth();
1626
0
                fScaleHeight = pClient->GetScaleHeight();
1627
0
            }
1628
0
            else
1629
0
            {
1630
0
                fScaleWidth = mpImpl->mxLightClient->GetScaleWidth();
1631
0
                fScaleHeight = mpImpl->mxLightClient->GetScaleHeight();
1632
0
            }
1633
1634
            // The object wants to resize itself (f.e. Chart wants to recalculate the layout)
1635
            // or object is inplace active and so has a window that must be resized also
1636
            // In these cases the change in the object area size will be reflected in a change of the
1637
            // objects' visual area. The scaling will not change, but it might exist already and must
1638
            // be used in calculations
1639
0
            MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl->mxObjRef->getMapUnit( GetAspect() ) );
1640
0
            Size aVisSize;
1641
0
            if (sal_Int32(fScaleWidth) != 0 && sal_Int32(fScaleHeight) != 0) // avoid div by zero
1642
0
                aVisSize = Size( static_cast<tools::Long>( getRectangle().GetWidth() / fScaleWidth ),
1643
0
                                 static_cast<tools::Long>( getRectangle().GetHeight() / fScaleHeight ) );
1644
1645
0
            aVisSize = OutputDevice::LogicToLogic(
1646
0
                aVisSize,
1647
0
                MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1648
0
                MapMode(aMapUnit));
1649
0
            awt::Size aSz;
1650
0
            aSz.Width = aVisSize.Width();
1651
0
            aSz.Height = aVisSize.Height();
1652
0
            mpImpl->mxObjRef->setVisualAreaSize( GetAspect(), aSz );
1653
1654
0
            try
1655
0
            {
1656
0
                aSz = mpImpl->mxObjRef->getVisualAreaSize( GetAspect() );
1657
0
            }
1658
0
            catch( embed::NoVisualAreaSizeException& )
1659
0
            {}
1660
1661
0
            tools::Rectangle aAcceptedVisArea;
1662
0
            aAcceptedVisArea.SetSize( Size( static_cast<tools::Long>( aSz.Width * fScaleWidth ),
1663
0
                                            static_cast<tools::Long>( aSz.Height * fScaleHeight ) ) );
1664
0
            if (aVisSize != aAcceptedVisArea.GetSize())
1665
0
            {
1666
                // server changed VisArea to its liking and the VisArea is different than the suggested one
1667
                // store the new value as given by the object
1668
0
                MapUnit aNewMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl->mxObjRef->getMapUnit( GetAspect() ) );
1669
0
                auto aSize = OutputDevice::LogicToLogic(aAcceptedVisArea.GetSize(), MapMode(aNewMapUnit), MapMode(getSdrModelFromSdrObject().GetScaleUnit()));
1670
0
                setRectangleSize(aSize.Width(), aSize.Height());
1671
0
            }
1672
1673
            // make the new object area known to the client
1674
            // compared to the "else" branch aRect might have been changed by the object and no additional scaling was applied
1675
            // WHY this -> OSL_ASSERT( pClient );
1676
0
            if( pClient )
1677
0
                pClient->SetObjArea(getRectangle());
1678
1679
            // we need a new replacement image as the object has resized itself
1680
1681
            //#i79578# don't request a new replacement image for charts to often
1682
            //a chart sends a modified call to the framework if it was changed
1683
            //thus the replacement update is already handled there
1684
0
            if( !IsChart() )
1685
0
                mpImpl->mxObjRef.UpdateReplacement();
1686
0
        }
1687
0
        else
1688
0
        {
1689
            // The object isn't active and does not want to resize itself so the changed object area size
1690
            // will be reflected in a changed object scaling
1691
0
            double aScaleWidth;
1692
0
            double aScaleHeight;
1693
0
            Size aObjAreaSize;
1694
0
            if ( CalculateNewScaling( aScaleWidth, aScaleHeight, aObjAreaSize ) )
1695
0
            {
1696
0
                if ( pClient )
1697
0
                {
1698
0
                    tools::Rectangle aScaleRect(getRectangle().TopLeft(), aObjAreaSize);
1699
0
                    pClient->SetObjAreaAndScale( aScaleRect, aScaleWidth, aScaleHeight);
1700
0
                }
1701
0
                else
1702
0
                {
1703
0
                    mpImpl->mxLightClient->SetSizeScale( aScaleWidth, aScaleHeight );
1704
0
                }
1705
0
            }
1706
0
        }
1707
0
    }
1708
0
    else if( (nMiscStatus & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) &&
1709
0
        svt::EmbeddedObjectRef::TryRunningState( mpImpl->mxObjRef.GetObject() ) )
1710
0
    {
1711
        //also handle not sfx based ole objects e.g. charts
1712
        //#i83860# resizing charts in impress distorts fonts
1713
0
        uno::Reference< embed::XVisualObject > xVisualObject( getXModel(), uno::UNO_QUERY );
1714
0
        if( xVisualObject.is() )
1715
0
        {
1716
0
            const MapUnit aMapUnit(
1717
0
                VCLUnoHelper::UnoEmbed2VCLMapUnit(
1718
0
                    mpImpl->mxObjRef->getMapUnit(GetAspect())));
1719
0
            const Point aTL( getRectangle().TopLeft() );
1720
0
            const Point aBR( getRectangle().BottomRight() );
1721
0
            const Point aTL2(
1722
0
                OutputDevice::LogicToLogic(
1723
0
                    aTL,
1724
0
                    MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1725
0
                    MapMode(aMapUnit)));
1726
0
            const Point aBR2(
1727
0
                OutputDevice::LogicToLogic(
1728
0
                    aBR,
1729
0
                    MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1730
0
                    MapMode(aMapUnit)));
1731
0
            const tools::Rectangle aNewRect(
1732
0
                aTL2,
1733
0
                aBR2);
1734
1735
0
            xVisualObject->setVisualAreaSize(
1736
0
                GetAspect(),
1737
0
                awt::Size(
1738
0
                    aNewRect.GetWidth(),
1739
0
                    aNewRect.GetHeight()));
1740
0
        }
1741
0
    }
1742
0
}
1743
1744
void SdrOle2Obj::NbcResize(const Point& rRef, double xFact, double yFact)
1745
0
{
1746
0
    if(!getSdrModelFromSdrObject().isLocked())
1747
0
    {
1748
0
        GetObjRef();
1749
1750
0
        if ( mpImpl->mxObjRef.is() && ( mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) )
1751
0
        {
1752
            // if the object needs recompose on resize
1753
            // the client site should be created before the resize will take place
1754
            // check whether there is no client site and create it if necessary
1755
0
            AddOwnLightClient();
1756
0
        }
1757
0
    }
1758
1759
0
    SdrRectObj::NbcResize(rRef,xFact,yFact);
1760
1761
0
    if( !getSdrModelFromSdrObject().isLocked() )
1762
0
        ImpSetVisAreaSize();
1763
0
}
1764
1765
void SdrOle2Obj::SetGeoData(const SdrObjGeoData& rGeo)
1766
0
{
1767
0
    SdrRectObj::SetGeoData(rGeo);
1768
1769
0
    if( !getSdrModelFromSdrObject().isLocked() )
1770
0
        ImpSetVisAreaSize();
1771
0
}
1772
1773
void SdrOle2Obj::NbcSetSnapRect(const tools::Rectangle& rRect)
1774
853
{
1775
853
    SdrRectObj::NbcSetSnapRect(rRect);
1776
1777
853
    if( !getSdrModelFromSdrObject().isLocked() )
1778
32
        ImpSetVisAreaSize();
1779
1780
853
    if ( mpImpl->mxObjRef.is() && IsChart() )
1781
0
    {
1782
        //#i103460# charts do not necessarily have an own size within ODF files,
1783
        //for this case they need to use the size settings from the surrounding frame,
1784
        //which is made available with this method as there is no other way
1785
0
        mpImpl->mxObjRef.SetDefaultSizeForChart( Size( rRect.GetWidth(), rRect.GetHeight() ) );
1786
0
    }
1787
853
}
1788
1789
void SdrOle2Obj::NbcSetLogicRect(const tools::Rectangle& rRect, bool bAdaptTextMinSize)
1790
762
{
1791
762
    SdrRectObj::NbcSetLogicRect(rRect, bAdaptTextMinSize);
1792
1793
762
    if( !getSdrModelFromSdrObject().isLocked() )
1794
16
        ImpSetVisAreaSize();
1795
762
}
1796
1797
const Graphic* SdrOle2Obj::GetGraphic() const
1798
0
{
1799
0
    if ( mpImpl->mxObjRef.is() )
1800
0
        return mpImpl->mxObjRef.GetGraphic();
1801
0
    return mpImpl->moGraphic ? &*mpImpl->moGraphic : nullptr;
1802
0
}
1803
1804
void SdrOle2Obj::GetNewReplacement()
1805
0
{
1806
0
    if ( mpImpl->mxObjRef.is() )
1807
0
        mpImpl->mxObjRef.UpdateReplacement();
1808
0
}
1809
1810
Size SdrOle2Obj::GetOrigObjSize( MapMode const * pTargetMapMode ) const
1811
0
{
1812
0
    return mpImpl->mxObjRef.GetSize( pTargetMapMode );
1813
0
}
1814
1815
void SdrOle2Obj::setSuppressSetVisAreaSize( bool bNew )
1816
0
{
1817
0
    mpImpl->mbSuppressSetVisAreaSize = bNew;
1818
0
}
1819
1820
void SdrOle2Obj::NbcMove(const Size& rSize)
1821
382
{
1822
382
    SdrRectObj::NbcMove(rSize);
1823
1824
382
    if( !getSdrModelFromSdrObject().isLocked() )
1825
0
        ImpSetVisAreaSize();
1826
382
}
1827
1828
bool SdrOle2Obj::CanUnloadRunningObj( const uno::Reference< embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
1829
0
{
1830
0
    uno::Reference<embed::XEmbedPersist2> xPersist(xObj, uno::UNO_QUERY);
1831
0
    if (xPersist.is())
1832
0
    {
1833
0
        if (!xPersist->isStored())
1834
            // It doesn't have persistent storage.  We can't unload this.
1835
0
            return false;
1836
0
    }
1837
1838
0
    bool bResult = false;
1839
1840
0
    sal_Int32 nState = xObj->getCurrentState();
1841
0
    if ( nState == embed::EmbedStates::LOADED )
1842
0
    {
1843
        // the object is already unloaded
1844
0
        bResult = true;
1845
0
    }
1846
0
    else
1847
0
    {
1848
0
        uno::Reference < util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
1849
0
        if ( !xModifiable.is() )
1850
0
            bResult = true;
1851
0
        else
1852
0
        {
1853
0
            sal_Int64 nMiscStatus = xObj->getStatus( nAspect );
1854
1855
0
            if ( embed::EmbedMisc::MS_EMBED_ALWAYSRUN != ( nMiscStatus & embed::EmbedMisc::MS_EMBED_ALWAYSRUN ) &&
1856
0
            embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY != ( nMiscStatus & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) &&
1857
0
            !( xModifiable.is() && xModifiable->isModified() ) &&
1858
0
            !( nState == embed::EmbedStates::INPLACE_ACTIVE || nState == embed::EmbedStates::UI_ACTIVE || nState == embed::EmbedStates::ACTIVE ) )
1859
0
            {
1860
0
                bResult = true;
1861
0
            }
1862
0
        }
1863
0
    }
1864
1865
0
    return bResult;
1866
0
}
1867
1868
bool SdrOle2Obj::Unload( const uno::Reference< embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
1869
0
{
1870
0
    bool bResult = false;
1871
1872
0
    if ( CanUnloadRunningObj( xObj, nAspect ) )
1873
0
    {
1874
0
        try
1875
0
        {
1876
0
            xObj->changeState( embed::EmbedStates::LOADED );
1877
0
            bResult = true;
1878
0
        }
1879
0
        catch( css::uno::Exception& )
1880
0
        {
1881
0
            TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Unload()" );
1882
0
        }
1883
0
    }
1884
1885
0
    return bResult;
1886
0
}
1887
1888
bool SdrOle2Obj::Unload()
1889
0
{
1890
0
    if (!mpImpl->mxObjRef.is())
1891
        // Already unloaded.
1892
0
        return true;
1893
1894
0
    return Unload(mpImpl->mxObjRef.GetObject(), GetAspect());
1895
0
}
1896
1897
void SdrOle2Obj::GetObjRef_Impl()
1898
631
{
1899
631
    if ( !mpImpl->mxObjRef.is() && !mpImpl->aPersistName.isEmpty() && getSdrModelFromSdrObject().GetPersist() )
1900
12
    {
1901
        // Only try loading if it did not went wrong up to now
1902
12
        if(!mpImpl->mbLoadingOLEObjectFailed)
1903
12
        {
1904
12
            mpImpl->mxObjRef.Assign(
1905
12
                getSdrModelFromSdrObject().GetPersist()->getEmbeddedObjectContainer().GetEmbeddedObject(mpImpl->aPersistName),
1906
12
                GetAspect());
1907
12
            mpImpl->mbTypeAsked = false;
1908
12
            CheckFileLink_Impl();
1909
1910
            // If loading of OLE object failed, remember that to not invoke an endless
1911
            // loop trying to load it again and again.
1912
12
            if( mpImpl->mxObjRef.is() )
1913
0
            {
1914
0
                mpImpl->mbLoadingOLEObjectFailed = true;
1915
0
            }
1916
1917
            // For math objects, set closed state to transparent
1918
12
            SetClosedObj(!ImplIsMathObj( mpImpl->mxObjRef.GetObject() ));
1919
12
        }
1920
1921
12
        if ( mpImpl->mxObjRef.is() )
1922
0
        {
1923
0
            if( !IsEmptyPresObj() )
1924
0
            {
1925
                // remember modified status of model
1926
0
                const bool bWasChanged(getSdrModelFromSdrObject().IsChanged());
1927
1928
                // perhaps preview not valid anymore
1929
                // This line changes the modified state of the model
1930
0
                ClearGraphic();
1931
1932
                // if status was not set before, force it back
1933
                // to not set, so that SetGraphic(0) above does not
1934
                // set the modified state of the model.
1935
0
                if(!bWasChanged && getSdrModelFromSdrObject().IsChanged())
1936
0
                {
1937
0
                    getSdrModelFromSdrObject().SetChanged( false );
1938
0
                }
1939
0
            }
1940
0
        }
1941
1942
12
        if ( mpImpl->mxObjRef.is() )
1943
0
            Connect();
1944
12
    }
1945
1946
631
    if ( mpImpl->mbConnected )
1947
0
    {
1948
        // move object to first position in cache
1949
0
        GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
1950
0
    }
1951
631
}
1952
1953
uno::Reference < embed::XEmbeddedObject > const & SdrOle2Obj::GetObjRef() const
1954
631
{
1955
631
    const_cast<SdrOle2Obj*>(this)->GetObjRef_Impl();
1956
631
    return mpImpl->mxObjRef.GetObject();
1957
631
}
1958
1959
uno::Reference < embed::XEmbeddedObject > const & SdrOle2Obj::GetObjRef_NoInit() const
1960
0
{
1961
0
    return mpImpl->mxObjRef.GetObject();
1962
0
}
1963
1964
uno::Reference< frame::XModel > SdrOle2Obj::getXModel() const
1965
0
{
1966
0
    if (svt::EmbeddedObjectRef::TryRunningState(GetObjRef()))
1967
0
        return uno::Reference< frame::XModel >( mpImpl->mxObjRef->getComponent(), uno::UNO_QUERY );
1968
0
    else
1969
0
        return uno::Reference< frame::XModel >();
1970
0
}
1971
1972
bool SdrOle2Obj::IsChart() const
1973
16
{
1974
16
    if (!mpImpl->mbTypeAsked)
1975
16
    {
1976
16
        mpImpl->mbIsChart = mpImpl->mxObjRef.IsChart();
1977
16
        mpImpl->mbTypeAsked = true;
1978
16
    }
1979
16
    return mpImpl->mbIsChart;
1980
16
}
1981
1982
void SdrOle2Obj::SetGraphicToObj( const Graphic& aGraphic )
1983
10
{
1984
10
    mpImpl->mxObjRef.SetGraphic( aGraphic, OUString() );
1985
    // if the object isn't valid, e.g. link to something that doesn't exist, set the fallback
1986
    // graphic as mxGraphic so SdrOle2Obj::GetGraphic will show the fallback
1987
10
    if (const Graphic* pObjGraphic = mpImpl->mxObjRef.is() ? nullptr : mpImpl->mxObjRef.GetGraphic())
1988
10
        mpImpl->moGraphic.emplace(*pObjGraphic);
1989
10
}
1990
1991
void SdrOle2Obj::SetGraphicToObj( const uno::Reference< io::XInputStream >& xGrStream, const OUString& aMediaType )
1992
0
{
1993
0
    mpImpl->mxObjRef.SetGraphicStream( xGrStream, aMediaType );
1994
    // if the object isn't valid, e.g. link to something that doesn't exist, set the fallback
1995
    // graphic as mxGraphic so SdrOle2Obj::GetGraphic will show the fallback
1996
0
    if (const Graphic* pObjGraphic = mpImpl->mxObjRef.is() ? nullptr : mpImpl->mxObjRef.GetGraphic())
1997
0
        mpImpl->moGraphic.emplace(*pObjGraphic);
1998
0
}
1999
2000
bool SdrOle2Obj::IsCalc() const
2001
0
{
2002
0
    if ( !mpImpl->mxObjRef.is() )
2003
0
        return false;
2004
2005
0
    SvGlobalName aObjClsId( mpImpl->mxObjRef->getClassID() );
2006
0
    return SvGlobalName(SO3_SC_CLASSID_30) == aObjClsId
2007
0
        || SvGlobalName(SO3_SC_CLASSID_40) == aObjClsId
2008
0
        || SvGlobalName(SO3_SC_CLASSID_50) == aObjClsId
2009
0
        || SvGlobalName(SO3_SC_CLASSID_60) == aObjClsId
2010
0
        || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_60) == aObjClsId
2011
0
        || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_8) == aObjClsId
2012
0
        || SvGlobalName(SO3_SC_CLASSID) == aObjClsId;
2013
0
}
2014
2015
const uno::Reference< frame::XModel > & SdrOle2Obj::GetParentXModel() const
2016
0
{
2017
0
    return getSdrModelFromSdrObject().getUnoModel();
2018
0
}
2019
2020
bool SdrOle2Obj::CalculateNewScaling( double& aScaleWidth, double& aScaleHeight, Size& aObjAreaSize )
2021
0
{
2022
    // TODO/LEAN: to avoid rounding errors scaling always uses the VisArea.
2023
    // If we don't cache it for own objects also we must load the object here
2024
0
    if (!mpImpl->mxObjRef.is())
2025
0
        return false;
2026
2027
0
    MapMode aMapMode(getSdrModelFromSdrObject().GetScaleUnit());
2028
0
    aObjAreaSize = mpImpl->mxObjRef.GetSize( &aMapMode );
2029
2030
0
    Size aSize = getRectangle().GetSize();
2031
0
    if (!aObjAreaSize.Width() || !aObjAreaSize.Height())
2032
0
    {
2033
        // avoid invalid fractions
2034
0
        aScaleWidth = 1.0;
2035
0
        aScaleHeight = 1.0;
2036
0
    }
2037
0
    else
2038
0
    {
2039
0
        aScaleWidth = double(aSize.Width()) / aObjAreaSize.Width();
2040
0
        aScaleHeight = double(aSize.Height()) / aObjAreaSize.Height();
2041
0
    }
2042
2043
0
    return true;
2044
0
}
2045
2046
0
void SdrOle2Obj::SetIgnoreOLEObjectScale(bool val) { mpImpl->mbIgnoreOLEObjectScale = val; }
2047
2048
bool SdrOle2Obj::AddOwnLightClient()
2049
0
{
2050
    // The Own Light Client must be registered in object only using this method!
2051
0
    if ( !SfxInPlaceClient::GetClient( dynamic_cast<SfxObjectShell*>(getSdrModelFromSdrObject().GetPersist()), mpImpl->mxObjRef.GetObject() )
2052
0
      && !( mpImpl->mxLightClient.is() && mpImpl->mxObjRef->getClientSite() == uno::Reference< embed::XEmbeddedClient >( mpImpl->mxLightClient ) ) )
2053
0
    {
2054
0
        Connect();
2055
2056
0
        if (!mpImpl->mbIgnoreOLEObjectScale && mpImpl->mxObjRef.is() && mpImpl->mxLightClient.is())
2057
0
        {
2058
0
            double aScaleWidth;
2059
0
            double aScaleHeight;
2060
0
            Size aObjAreaSize;
2061
0
            if ( CalculateNewScaling( aScaleWidth, aScaleHeight, aObjAreaSize ) )
2062
0
            {
2063
0
                mpImpl->mxLightClient->SetSizeScale( aScaleWidth, aScaleHeight );
2064
0
                try {
2065
0
                    mpImpl->mxObjRef->setClientSite( mpImpl->mxLightClient );
2066
0
                    return true;
2067
0
                } catch( uno::Exception& )
2068
0
                {}
2069
0
            }
2070
2071
0
        }
2072
2073
0
        return false;
2074
0
    }
2075
2076
0
    return true;
2077
0
}
2078
2079
Graphic SdrOle2Obj::GetEmptyOLEReplacementGraphic()
2080
0
{
2081
0
    return Graphic(Bitmap(BMP_SVXOLEOBJ));
2082
0
}
2083
2084
void SdrOle2Obj::SetWindow(const css::uno::Reference < css::awt::XWindow >& _xWindow)
2085
0
{
2086
0
    if ( mpImpl->mxObjRef.is() && mpImpl->mxLightClient.is() )
2087
0
    {
2088
0
        mpImpl->mxLightClient->setWindow(_xWindow);
2089
0
    }
2090
0
}
2091
2092
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */