Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/svx/source/svdraw/svdoole2.cxx
Line
Count
Source (jump to first uncovered line)
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
    Fraction m_aScaleWidth;
117
    Fraction m_aScaleHeight;
118
119
120
public:
121
    explicit SdrLightEmbeddedClient_Impl( SdrOle2Obj* pObj );
122
    virtual ~SdrLightEmbeddedClient_Impl() override;
123
124
    void SetSizeScale( const Fraction& aScaleWidth, const Fraction& aScaleHeight )
125
0
    {
126
0
        m_aScaleWidth = aScaleWidth;
127
0
        m_aScaleHeight = aScaleHeight;
128
0
    }
129
130
0
    const Fraction& GetScaleWidth() const { return m_aScaleWidth; }
131
0
    const Fraction& 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 * Fraction( aVisArea.GetWidth() ) ),
266
0
                            static_cast< tools::Long >( m_aScaleHeight * Fraction( 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
0
    ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB ),
547
0
    m_pObj(pObject)
548
0
{
549
0
    SetSynchron( false );
550
0
}
551
552
SdrEmbedObjectLink::~SdrEmbedObjectLink()
553
0
{
554
0
}
555
556
::sfx2::SvBaseLink::UpdateResult SdrEmbedObjectLink::DataChanged(
557
    const OUString& /*rMimeType*/, const css::uno::Any & /*rValue*/ )
558
0
{
559
0
    if ( !m_pObj->UpdateLinkURL_Impl() )
560
0
    {
561
        // the link URL was not changed
562
0
        uno::Reference< embed::XEmbeddedObject > xObject = m_pObj->GetObjRef();
563
0
        OSL_ENSURE( xObject.is(), "The object must exist always!" );
564
0
        if ( xObject.is() )
565
0
        {
566
            // let the object reload the link
567
            // TODO/LATER: reload call could be used for this case
568
569
0
            try
570
0
            {
571
0
                sal_Int32 nState = xObject->getCurrentState();
572
0
                if ( nState != embed::EmbedStates::LOADED )
573
0
                {
574
                    // in some cases the linked file probably is not locked so it could be changed
575
0
                    xObject->changeState( embed::EmbedStates::LOADED );
576
0
                    xObject->changeState( nState );
577
0
                }
578
0
            }
579
0
            catch ( uno::Exception& )
580
0
            {
581
0
            }
582
0
        }
583
0
    }
584
585
0
    m_pObj->GetNewReplacement();
586
0
    m_pObj->SetChanged();
587
588
0
    return SUCCESS;
589
0
}
590
591
void SdrEmbedObjectLink::Closed()
592
0
{
593
0
    m_pObj->BreakFileLink_Impl();
594
0
    SvBaseLink::Closed();
595
0
}
596
597
SdrIFrameLink::SdrIFrameLink(SdrOle2Obj* pObject)
598
0
    : ::sfx2::SvBaseLink(::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB)
599
0
    , m_pObject(pObject)
600
0
{
601
0
    SetSynchron( false );
602
0
}
603
604
::sfx2::SvBaseLink::UpdateResult SdrIFrameLink::DataChanged(
605
    const OUString&, const uno::Any& )
606
0
{
607
0
    uno::Reference<embed::XEmbeddedObject> xObject = m_pObject->GetObjRef();
608
0
    uno::Reference<embed::XCommonEmbedPersist> xPersObj(xObject, uno::UNO_QUERY);
609
0
    if (xPersObj.is())
610
0
    {
611
        // let the IFrameObject reload the link
612
0
        try
613
0
        {
614
0
            xPersObj->reload(uno::Sequence<beans::PropertyValue>(), uno::Sequence<beans::PropertyValue>());
615
0
        }
616
0
        catch (const uno::Exception&)
617
0
        {
618
0
        }
619
620
0
        m_pObject->SetChanged();
621
0
    }
622
623
0
    return SUCCESS;
624
0
}
625
626
class SdrOle2ObjImpl
627
{
628
public:
629
    svt::EmbeddedObjectRef mxObjRef;
630
631
    std::optional<Graphic> moGraphic;
632
    OUString        maProgName;
633
    OUString        aPersistName;       // name of object in persist
634
    rtl::Reference<SdrLightEmbeddedClient_Impl> mxLightClient; // must be registered as client only using AddOwnLightClient() call
635
636
    bool mbFrame:1; // Due to compatibility at SdrTextObj for now
637
    bool mbSuppressSetVisAreaSize:1; // #i118524#
638
    mutable bool mbTypeAsked:1;
639
    mutable bool mbIsChart:1;
640
    bool mbLoadingOLEObjectFailed:1; // New local var to avoid repeated loading if load of OLE2 fails
641
    bool mbConnected:1;
642
    bool mbIgnoreOLEObjectScale : 1 = false; // See SdXMLObjectShapeContext::createFastChildContext
643
644
    sfx2::SvBaseLink* mpObjectLink;
645
    OUString maLinkURL;
646
647
    rtl::Reference<SvxUnoShapeModifyListener> mxModifyListener;
648
649
    explicit SdrOle2ObjImpl( bool bFrame ) :
650
715
        mbFrame(bFrame),
651
715
        mbSuppressSetVisAreaSize(false),
652
715
        mbTypeAsked(false),
653
715
        mbIsChart(false),
654
715
        mbLoadingOLEObjectFailed(false),
655
715
        mbConnected(false),
656
715
        mpObjectLink(nullptr)
657
715
    {
658
715
        mxObjRef.Lock();
659
715
    }
660
661
    SdrOle2ObjImpl( bool bFrame, const svt::EmbeddedObjectRef& rObjRef ) :
662
0
        mxObjRef(rObjRef),
663
0
        mbFrame(bFrame),
664
0
        mbSuppressSetVisAreaSize(false),
665
0
        mbTypeAsked(false),
666
0
        mbIsChart(false),
667
0
        mbLoadingOLEObjectFailed(false),
668
0
        mbConnected(false),
669
0
        mpObjectLink(nullptr)
670
0
    {
671
0
        mxObjRef.Lock();
672
0
    }
673
674
    ~SdrOle2ObjImpl()
675
715
    {
676
715
        moGraphic.reset();
677
678
715
        if (mxModifyListener.is())
679
0
        {
680
0
            mxModifyListener->invalidate();
681
0
        }
682
715
    }
683
};
684
685
// Predicate determining whether the given OLE is an internal math
686
// object
687
static bool ImplIsMathObj( const uno::Reference < embed::XEmbeddedObject >& rObjRef )
688
11
{
689
11
    if ( !rObjRef.is() )
690
11
        return false;
691
692
0
    SvGlobalName aClassName( rObjRef->getClassID() );
693
0
    return aClassName == SvGlobalName(SO3_SM_CLASSID_30) ||
694
0
        aClassName == SvGlobalName(SO3_SM_CLASSID_40) ||
695
0
        aClassName == SvGlobalName(SO3_SM_CLASSID_50) ||
696
0
        aClassName == SvGlobalName(SO3_SM_CLASSID_60) ||
697
0
        aClassName == SvGlobalName(SO3_SM_CLASSID);
698
11
}
699
700
// BaseProperties section
701
702
std::unique_ptr<sdr::properties::BaseProperties> SdrOle2Obj::CreateObjectSpecificProperties()
703
715
{
704
715
    return std::make_unique<sdr::properties::OleProperties>(*this);
705
715
}
706
707
// DrawContact section
708
709
std::unique_ptr<sdr::contact::ViewContact> SdrOle2Obj::CreateObjectSpecificViewContact()
710
715
{
711
715
    return std::make_unique<sdr::contact::ViewContactOfSdrOle2Obj>(*this);
712
715
}
713
714
void SdrOle2Obj::Init()
715
715
{
716
    // Stuff that was done from old SetModel:
717
    // #i43086# #i85304 redo the change for charts for the above bugfix, as #i43086# does not occur anymore
718
    // so maybe the ImpSetVisAreaSize call can be removed here completely
719
    // Nevertheless I leave it in for other objects as I am not sure about the side effects when removing now
720
715
    if(!getSdrModelFromSdrObject().isLocked() && !IsChart())
721
21
    {
722
21
        ImpSetVisAreaSize();
723
21
    }
724
725
715
    ::comphelper::IEmbeddedHelper* pDestPers(getSdrModelFromSdrObject().GetPersist());
726
715
    if(pDestPers && !IsEmptyPresObj())
727
715
    {
728
        // object wasn't connected, now it should be
729
715
        Connect_Impl();
730
715
    }
731
732
715
    AddListeners_Impl();
733
715
}
734
735
SdrOle2Obj::SdrOle2Obj(
736
    SdrModel& rSdrModel,
737
    bool bFrame_)
738
715
:   SdrRectObj(rSdrModel),
739
715
    mpImpl(new SdrOle2ObjImpl(bFrame_))
740
715
{
741
715
    Init();
742
715
}
743
744
SdrOle2Obj::SdrOle2Obj(SdrModel& rSdrModel, SdrOle2Obj const & rSource)
745
0
:   SdrRectObj(rSdrModel, rSource),
746
0
    mpImpl(new SdrOle2ObjImpl(/*bFrame*/false))
747
0
{
748
0
    Init();
749
750
    // Manually copying bClosedObj attribute
751
0
    SetClosedObj( rSource.IsClosedObj() );
752
753
0
    mpImpl->aPersistName = rSource.mpImpl->aPersistName;
754
0
    mpImpl->maProgName = rSource.mpImpl->maProgName;
755
0
    mpImpl->mbFrame = rSource.mpImpl->mbFrame;
756
757
0
    if (rSource.mpImpl->moGraphic)
758
0
    {
759
0
        mpImpl->moGraphic.emplace(*rSource.mpImpl->moGraphic);
760
0
    }
761
762
0
    if( IsEmptyPresObj() )
763
0
        return;
764
765
0
    ::comphelper::IEmbeddedHelper* pDestPers(getSdrModelFromSdrObject().GetPersist());
766
0
    ::comphelper::IEmbeddedHelper* pSrcPers(rSource.getSdrModelFromSdrObject().GetPersist());
767
0
    if( !(pDestPers && pSrcPers) )
768
0
        return;
769
770
0
    DBG_ASSERT( !mpImpl->mxObjRef.is(), "Object already existing!" );
771
0
    comphelper::EmbeddedObjectContainer& rContainer = pSrcPers->getEmbeddedObjectContainer();
772
0
    uno::Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( mpImpl->aPersistName );
773
0
    if ( xObj.is() )
774
0
    {
775
0
        OUString aTmp;
776
0
        mpImpl->mxObjRef.Assign( pDestPers->getEmbeddedObjectContainer().CopyAndGetEmbeddedObject(
777
0
            rContainer, xObj, aTmp, pSrcPers->getDocumentBaseURL(), pDestPers->getDocumentBaseURL()), rSource.GetAspect());
778
0
        mpImpl->mbTypeAsked = false;
779
0
        mpImpl->aPersistName = aTmp;
780
0
        CheckFileLink_Impl();
781
0
    }
782
783
0
    Connect();
784
0
}
785
786
SdrOle2Obj::SdrOle2Obj(
787
    SdrModel& rSdrModel,
788
    const svt::EmbeddedObjectRef& rNewObjRef,
789
    const OUString& rNewObjName,
790
    const tools::Rectangle& rNewRect)
791
0
:   SdrRectObj(rSdrModel, rNewRect),
792
0
    mpImpl(new SdrOle2ObjImpl(false/*bFrame_*/, rNewObjRef))
793
0
{
794
0
    osl_atomic_increment(&m_refCount);
795
796
0
    mpImpl->aPersistName = rNewObjName;
797
798
0
    if (mpImpl->mxObjRef.is() && (mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
799
0
        m_bSizProt = true;
800
801
    // For math objects, set closed state to transparent
802
0
    SetClosedObj(!ImplIsMathObj( mpImpl->mxObjRef.GetObject() ));
803
804
0
    Init();
805
806
0
    osl_atomic_decrement(&m_refCount);
807
0
}
808
809
OUString SdrOle2Obj::GetStyleString()
810
0
{
811
0
    OUString strStyle;
812
0
    if (mpImpl->mxObjRef.is() && mpImpl->mxObjRef.IsChart())
813
0
    {
814
0
        strStyle = mpImpl->mxObjRef.GetChartType();
815
0
    }
816
0
    return strStyle;
817
0
}
818
819
SdrOle2Obj::~SdrOle2Obj()
820
715
{
821
715
    if ( mpImpl->mbConnected )
822
0
        Disconnect();
823
824
715
    DisconnectFileLink_Impl();
825
826
715
    if (mpImpl->mxLightClient)
827
0
    {
828
0
        mpImpl->mxLightClient->disconnect();
829
0
        mpImpl->mxLightClient.clear();
830
0
    }
831
715
}
832
833
void SdrOle2Obj::SetAspect( sal_Int64 nAspect )
834
46
{
835
46
    mpImpl->mxObjRef.SetViewAspect( nAspect );
836
46
}
837
838
const svt::EmbeddedObjectRef& SdrOle2Obj::getEmbeddedObjectRef() const
839
0
{
840
0
    return mpImpl->mxObjRef;
841
0
}
842
843
sal_Int64 SdrOle2Obj::GetAspect() const
844
95
{
845
95
    return mpImpl->mxObjRef.GetViewAspect();
846
95
}
847
848
bool SdrOle2Obj::isInplaceActive() const
849
0
{
850
0
    return mpImpl->mxObjRef.is() && embed::EmbedStates::INPLACE_ACTIVE == mpImpl->mxObjRef->getCurrentState();
851
0
}
852
853
bool SdrOle2Obj::isUiActive() const
854
0
{
855
0
    return mpImpl->mxObjRef.is() && embed::EmbedStates::UI_ACTIVE == mpImpl->mxObjRef->getCurrentState();
856
0
}
857
858
void SdrOle2Obj::SetGraphic(const Graphic& rGrf)
859
118
{
860
    // only for setting a preview graphic
861
118
    mpImpl->moGraphic.emplace(rGrf);
862
863
118
    SetChanged();
864
118
    BroadcastObjectChange();
865
118
}
866
867
void SdrOle2Obj::ClearGraphic()
868
0
{
869
0
    mpImpl->moGraphic.reset();
870
871
0
    SetChanged();
872
0
    BroadcastObjectChange();
873
0
}
874
875
void SdrOle2Obj::SetProgName( const OUString& rName )
876
6
{
877
6
    mpImpl->maProgName = rName;
878
6
}
879
880
const OUString& SdrOle2Obj::GetProgName() const
881
0
{
882
0
    return mpImpl->maProgName;
883
0
}
884
885
bool SdrOle2Obj::IsEmpty() const
886
520
{
887
520
    return !mpImpl->mxObjRef.is();
888
520
}
889
890
void SdrOle2Obj::Connect(SvxOle2Shape* pCreator)
891
726
{
892
726
    if( IsEmptyPresObj() )
893
118
        return;
894
895
608
    if( mpImpl->mbConnected )
896
0
    {
897
        // currently there are situations where it seems to be unavoidable to have multiple connects
898
        // changing this would need a larger code rewrite, so for now I remove the assertion
899
        // OSL_FAIL("Connect() called on connected object!");
900
0
        return;
901
0
    }
902
903
608
    Connect_Impl(pCreator);
904
608
    AddListeners_Impl();
905
608
}
906
907
bool SdrOle2Obj::UpdateLinkURL_Impl()
908
0
{
909
0
    bool bResult = false;
910
911
0
    if ( mpImpl->mpObjectLink )
912
0
    {
913
0
        sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
914
915
0
        if ( pLinkManager )
916
0
        {
917
0
            OUString aNewLinkURL;
918
0
            sfx2::LinkManager::GetDisplayNames( mpImpl->mpObjectLink, nullptr, &aNewLinkURL );
919
0
            if ( !aNewLinkURL.equalsIgnoreAsciiCase( mpImpl->maLinkURL ) )
920
0
            {
921
0
                GetObjRef_Impl();
922
0
                uno::Reference<embed::XCommonEmbedPersist> xPersObj( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY );
923
0
                OSL_ENSURE( xPersObj.is(), "The object must exist!" );
924
0
                if ( xPersObj.is() )
925
0
                {
926
0
                    try
927
0
                    {
928
0
                        sal_Int32 nCurState = mpImpl->mxObjRef->getCurrentState();
929
0
                        if ( nCurState != embed::EmbedStates::LOADED )
930
0
                            mpImpl->mxObjRef->changeState(embed::EmbedStates::LOADED);
931
932
                        // TODO/LATER: there should be possible to get current mediadescriptor settings from the object
933
0
                        uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
934
0
                            u"URL"_ustr, aNewLinkURL) };
935
0
                        xPersObj->reload( aArgs, uno::Sequence< beans::PropertyValue >() );
936
937
0
                        mpImpl->maLinkURL = aNewLinkURL;
938
0
                        bResult = true;
939
940
0
                        if ( nCurState != embed::EmbedStates::LOADED )
941
0
                            mpImpl->mxObjRef->changeState(nCurState);
942
0
                    }
943
0
                    catch( css::uno::Exception const & )
944
0
                    {
945
0
                        TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::UpdateLinkURL_Impl()" );
946
0
                    }
947
0
                }
948
949
0
                if ( !bResult )
950
0
                {
951
                    // TODO/LATER: return the old name to the link manager, is it possible?
952
0
                }
953
0
            }
954
0
        }
955
0
    }
956
957
0
    return bResult;
958
0
}
959
960
void SdrOle2Obj::BreakFileLink_Impl()
961
0
{
962
0
    uno::Reference<document::XStorageBasedDocument> xDoc(getSdrModelFromSdrObject().getUnoModel(), uno::UNO_QUERY);
963
964
0
    if ( !xDoc.is() )
965
0
        return;
966
967
0
    uno::Reference< embed::XStorage > xStorage = xDoc->getDocumentStorage();
968
0
    if ( !xStorage.is() )
969
0
        return;
970
971
0
    try
972
0
    {
973
0
        uno::Reference< embed::XLinkageSupport > xLinkSupport( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY_THROW );
974
0
        xLinkSupport->breakLink( xStorage, mpImpl->aPersistName );
975
0
        DisconnectFileLink_Impl();
976
0
        mpImpl->maLinkURL.clear();
977
0
    }
978
0
    catch( css::uno::Exception& )
979
0
    {
980
0
        TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::BreakFileLink_Impl()" );
981
0
    }
982
0
}
983
984
void SdrOle2Obj::DisconnectFileLink_Impl()
985
715
{
986
715
    sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
987
988
715
    if ( pLinkManager && mpImpl->mpObjectLink )
989
0
    {
990
0
        pLinkManager->Remove( mpImpl->mpObjectLink );
991
0
        mpImpl->mpObjectLink = nullptr;
992
0
    }
993
715
}
994
995
void SdrOle2Obj::CheckFileLink_Impl()
996
11
{
997
11
    if (!mpImpl->mxObjRef.GetObject().is() || mpImpl->mpObjectLink)
998
11
        return;
999
1000
0
    try
1001
0
    {
1002
0
        uno::Reference<embed::XEmbeddedObject> xObject = mpImpl->mxObjRef.GetObject();
1003
0
        if (!xObject)
1004
0
            return;
1005
1006
0
        bool bIFrame = false;
1007
1008
0
        OUString aLinkURL;
1009
0
        uno::Reference<embed::XLinkageSupport> xLinkSupport(xObject, uno::UNO_QUERY);
1010
0
        if (xLinkSupport)
1011
0
        {
1012
0
            if (xLinkSupport->isLink())
1013
0
                aLinkURL = xLinkSupport->getLinkURL();
1014
0
        }
1015
0
        else
1016
0
        {
1017
            // get IFrame (Floating Frames) listed and updatable from the
1018
            // manage links dialog
1019
0
            SvGlobalName aClassId(xObject->getClassID());
1020
0
            if (aClassId == SvGlobalName(SO3_IFRAME_CLASSID))
1021
0
            {
1022
0
                uno::Reference<beans::XPropertySet> xSet(xObject->getComponent(), uno::UNO_QUERY);
1023
0
                if (xSet.is())
1024
0
                    xSet->getPropertyValue(u"FrameURL"_ustr) >>= aLinkURL;
1025
0
                bIFrame = true;
1026
0
            }
1027
0
        }
1028
1029
0
        if (!aLinkURL.isEmpty()) // this is a file link so the model link manager should handle it
1030
0
        {
1031
0
            sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
1032
1033
0
            if ( pLinkManager )
1034
0
            {
1035
0
                SdrEmbedObjectLink* pEmbedObjectLink = nullptr;
1036
0
                if (!bIFrame)
1037
0
                {
1038
0
                    pEmbedObjectLink = new SdrEmbedObjectLink(this);
1039
0
                    mpImpl->mpObjectLink = pEmbedObjectLink;
1040
0
                }
1041
0
                else
1042
0
                    mpImpl->mpObjectLink = new SdrIFrameLink(this);
1043
0
                mpImpl->maLinkURL = aLinkURL;
1044
0
                pLinkManager->InsertFileLink( *mpImpl->mpObjectLink, sfx2::SvBaseLinkObjectType::ClientOle, aLinkURL );
1045
0
                if (pEmbedObjectLink)
1046
0
                    pEmbedObjectLink->Connect();
1047
0
            }
1048
0
        }
1049
0
    }
1050
0
    catch (const css::uno::Exception&)
1051
0
    {
1052
0
        TOOLS_WARN_EXCEPTION("svx", "SdrOle2Obj::CheckFileLink_Impl()");
1053
0
    }
1054
0
}
1055
1056
void SdrOle2Obj::Connect_Impl(SvxOle2Shape* pCreator)
1057
1.32k
{
1058
1.32k
    if(mpImpl->aPersistName.isEmpty() )
1059
1.31k
        return;
1060
1061
11
    try
1062
11
    {
1063
11
        ::comphelper::IEmbeddedHelper* pPers(getSdrModelFromSdrObject().GetPersist());
1064
1065
11
        if ( pPers )
1066
11
        {
1067
11
            comphelper::EmbeddedObjectContainer& rContainer = pPers->getEmbeddedObjectContainer();
1068
1069
11
            if ( !rContainer.HasEmbeddedObject( mpImpl->aPersistName )
1070
11
              || ( mpImpl->mxObjRef.is() && !rContainer.HasEmbeddedObject( mpImpl->mxObjRef.GetObject() ) ) )
1071
0
            {
1072
                // object not known to container document
1073
                // No object -> disaster!
1074
0
                DBG_ASSERT( mpImpl->mxObjRef.is(), "No object in connect!");
1075
0
                if ( mpImpl->mxObjRef.is() )
1076
0
                {
1077
                    // object came from the outside, now add it to the container
1078
0
                    OUString aTmp;
1079
0
                    rContainer.InsertEmbeddedObject( mpImpl->mxObjRef.GetObject(), aTmp );
1080
0
                    mpImpl->aPersistName = aTmp;
1081
0
                }
1082
0
            }
1083
11
            else if ( !mpImpl->mxObjRef.is() )
1084
11
            {
1085
11
                mpImpl->mxObjRef.Assign( rContainer.GetEmbeddedObject( mpImpl->aPersistName ), mpImpl->mxObjRef.GetViewAspect() );
1086
11
                mpImpl->mbTypeAsked = false;
1087
11
            }
1088
1089
11
            if ( mpImpl->mxObjRef.GetObject().is() )
1090
0
            {
1091
0
                mpImpl->mxObjRef.AssignToContainer( &rContainer, mpImpl->aPersistName );
1092
0
                mpImpl->mbConnected = true;
1093
0
                mpImpl->mxObjRef.Lock();
1094
0
            }
1095
11
        }
1096
1097
11
        if (pCreator)
1098
11
        {
1099
11
            OUString sFrameURL(pCreator->GetAndClearInitialFrameURL());
1100
11
            if (!sFrameURL.isEmpty() && svt::EmbeddedObjectRef::TryRunningState(mpImpl->mxObjRef.GetObject()))
1101
0
            {
1102
0
                uno::Reference<beans::XPropertySet> xSet(mpImpl->mxObjRef->getComponent(), uno::UNO_QUERY);
1103
0
                if (xSet.is())
1104
0
                    xSet->setPropertyValue(u"FrameURL"_ustr, uno::Any(sFrameURL));
1105
0
            }
1106
11
        }
1107
1108
11
        if ( mpImpl->mxObjRef.is() )
1109
0
        {
1110
0
            if ( !mpImpl->mxLightClient.is() )
1111
0
                mpImpl->mxLightClient = new SdrLightEmbeddedClient_Impl( this );
1112
1113
0
            mpImpl->mxObjRef->addStateChangeListener( mpImpl->mxLightClient );
1114
0
            mpImpl->mxObjRef->addEventListener( mpImpl->mxLightClient );
1115
1116
0
            if ( mpImpl->mxObjRef->getCurrentState() != embed::EmbedStates::LOADED )
1117
0
                GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
1118
1119
0
            CheckFileLink_Impl();
1120
1121
0
            uno::Reference< container::XChild > xChild( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY );
1122
0
            if( xChild.is() )
1123
0
            {
1124
0
                uno::Reference< uno::XInterface > xParent( getSdrModelFromSdrObject().getUnoModel());
1125
0
                if( xParent.is())
1126
0
                    xChild->setParent( getSdrModelFromSdrObject().getUnoModel() );
1127
0
            }
1128
1129
0
        }
1130
11
    }
1131
11
    catch( css::uno::Exception& )
1132
11
    {
1133
0
        TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Connect_Impl()" );
1134
0
    }
1135
11
}
1136
1137
void SdrOle2Obj::ObjectLoaded()
1138
0
{
1139
0
    AddListeners_Impl();
1140
0
}
1141
1142
void SdrOle2Obj::AddListeners_Impl()
1143
1.32k
{
1144
1.32k
    if( !(mpImpl->mxObjRef.is() && mpImpl->mxObjRef->getCurrentState() != embed::EmbedStates::LOADED) )
1145
1.32k
        return;
1146
1147
    // register modify listener
1148
0
    if (!mpImpl->mxModifyListener.is())
1149
0
    {
1150
0
        mpImpl->mxModifyListener = new SvxUnoShapeModifyListener(this);
1151
0
    }
1152
1153
0
    uno::Reference< util::XModifyBroadcaster > xBC( getXModel(), uno::UNO_QUERY );
1154
0
    if (xBC.is())
1155
0
    {
1156
0
        xBC->addModifyListener( mpImpl->mxModifyListener );
1157
0
    }
1158
0
}
1159
1160
void SdrOle2Obj::Disconnect()
1161
591
{
1162
591
    if( IsEmptyPresObj() )
1163
15
        return;
1164
1165
576
    if( !mpImpl->mbConnected )
1166
576
    {
1167
576
        OSL_FAIL("Disconnect() called on disconnected object!");
1168
576
        return;
1169
576
    }
1170
1171
0
    RemoveListeners_Impl();
1172
0
    Disconnect_Impl();
1173
0
}
1174
1175
void SdrOle2Obj::RemoveListeners_Impl()
1176
0
{
1177
0
    if ( !mpImpl->mxObjRef.is() || mpImpl->aPersistName.isEmpty() )
1178
0
        return;
1179
1180
0
    try
1181
0
    {
1182
0
        sal_Int32 nState = mpImpl->mxObjRef->getCurrentState();
1183
0
        if ( nState != embed::EmbedStates::LOADED )
1184
0
        {
1185
0
            uno::Reference< util::XModifyBroadcaster > xBC( getXModel(), uno::UNO_QUERY );
1186
0
            if (xBC.is() && mpImpl->mxModifyListener.is())
1187
0
            {
1188
0
                xBC->removeModifyListener( mpImpl->mxModifyListener );
1189
0
            }
1190
0
        }
1191
0
    }
1192
0
    catch( css::uno::Exception& )
1193
0
    {
1194
0
        TOOLS_WARN_EXCEPTION( "svx",  "SdrOle2Obj::RemoveListeners_Impl()" );
1195
0
    }
1196
0
}
1197
1198
void SdrOle2Obj::Disconnect_Impl()
1199
0
{
1200
0
    try
1201
0
    {
1202
0
        if ( !mpImpl->aPersistName.isEmpty() )
1203
0
        {
1204
0
            if( getSdrModelFromSdrObject().IsInDestruction() )
1205
0
            {
1206
                // TODO/LATER: here we must assume that the destruction of the model is enough to make clear that we will not
1207
                // remove the object from the container, even if the DrawingObject itself is not destroyed (unfortunately this
1208
                // There is no real need to do the following removing of the object from the container
1209
                // in case the model has correct persistence, but in case of problems such a removing
1210
                // would make the behavior of the office more stable
1211
1212
0
                comphelper::EmbeddedObjectContainer* pContainer = mpImpl->mxObjRef.GetContainer();
1213
0
                if ( pContainer )
1214
0
                {
1215
0
                    pContainer->CloseEmbeddedObject( mpImpl->mxObjRef.GetObject() );
1216
0
                    mpImpl->mxObjRef.AssignToContainer( nullptr, mpImpl->aPersistName );
1217
0
                }
1218
1219
                // happens later than the destruction of the model, so we can't assert that).
1220
                //DBG_ASSERT( bInDestruction, "Model is destroyed, but not me?!" );
1221
                //TODO/LATER: should be make sure that the ObjectShell also forgets the object, because we will close it soon?
1222
                /*
1223
                uno::Reference < util::XCloseable > xClose( xObjRef, uno::UNO_QUERY );
1224
                if ( xClose.is() )
1225
                {
1226
                    try
1227
                    {
1228
                        xClose->close( true );
1229
                    }
1230
                    catch ( util::CloseVetoException& )
1231
                    {
1232
                        // there's still someone who needs the object!
1233
                    }
1234
                }
1235
1236
                xObjRef = NULL;*/
1237
0
            }
1238
0
            else if ( mpImpl->mxObjRef.is() )
1239
0
            {
1240
0
                if ( getSdrModelFromSdrObject().getUnoModel().is() )
1241
0
                {
1242
                    // remove object, but don't close it (that's up to someone else)
1243
0
                    comphelper::EmbeddedObjectContainer* pContainer = mpImpl->mxObjRef.GetContainer();
1244
0
                    if ( pContainer )
1245
0
                    {
1246
0
                        pContainer->RemoveEmbeddedObject( mpImpl->mxObjRef.GetObject() );
1247
1248
                        // TODO/LATER: mpImpl->aPersistName contains outdated information, to keep it updated
1249
                        // it should be returned from RemoveEmbeddedObject call. Currently it is no problem,
1250
                        // since no container is adjusted, actually the empty string could be provided as a name here
1251
0
                        mpImpl->mxObjRef.AssignToContainer( nullptr, mpImpl->aPersistName );
1252
0
                    }
1253
1254
0
                    DisconnectFileLink_Impl();
1255
0
                }
1256
0
            }
1257
0
        }
1258
1259
0
        if ( mpImpl->mxObjRef.is() && mpImpl->mxLightClient.is() )
1260
0
        {
1261
0
            mpImpl->mxObjRef->removeStateChangeListener ( mpImpl->mxLightClient );
1262
0
            mpImpl->mxObjRef->removeEventListener( mpImpl->mxLightClient );
1263
0
            mpImpl->mxObjRef->setClientSite( nullptr );
1264
1265
0
            GetSdrGlobalData().GetOLEObjCache().RemoveObj(this);
1266
0
        }
1267
0
    }
1268
0
    catch( css::uno::Exception& )
1269
0
    {
1270
0
        TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Disconnect_Impl()" );
1271
0
    }
1272
1273
0
    mpImpl->mbConnected = false;
1274
0
}
1275
1276
rtl::Reference<SdrObject> SdrOle2Obj::createSdrGrafObjReplacement(bool bAddText) const
1277
0
{
1278
0
    const Graphic* pOLEGraphic = GetGraphic();
1279
1280
0
    if(pOLEGraphic)
1281
0
    {
1282
        // #i118485# allow creating a SdrGrafObj representation
1283
0
        rtl::Reference<SdrGrafObj> pClone = new SdrGrafObj(
1284
0
            getSdrModelFromSdrObject(),
1285
0
            *pOLEGraphic);
1286
1287
        // copy transformation
1288
0
        basegfx::B2DHomMatrix aMatrix;
1289
0
        basegfx::B2DPolyPolygon aPolyPolygon;
1290
1291
0
        TRGetBaseGeometry(aMatrix, aPolyPolygon);
1292
0
        pClone->TRSetBaseGeometry(aMatrix, aPolyPolygon);
1293
1294
        // copy all attributes to support graphic styles for OLEs
1295
0
        pClone->SetStyleSheet(GetStyleSheet(), false);
1296
0
        pClone->SetMergedItemSet(GetMergedItemSet());
1297
1298
0
        if(bAddText)
1299
0
        {
1300
            // #i118485# copy text (Caution! Model needed, as guaranteed in aw080)
1301
0
            OutlinerParaObject* pOPO = GetOutlinerParaObject();
1302
1303
0
            if(pOPO)
1304
0
            {
1305
0
                pClone->NbcSetOutlinerParaObject(*pOPO);
1306
0
            }
1307
0
        }
1308
1309
0
        return rtl::Reference<SdrObject>(pClone);
1310
0
    }
1311
0
    else
1312
0
    {
1313
        // #i100710# pOLEGraphic may be zero (no visualisation available),
1314
        // so we need to use the OLE replacement graphic
1315
0
        rtl::Reference<SdrRectObj> pClone = new SdrRectObj(
1316
0
            getSdrModelFromSdrObject(),
1317
0
            GetSnapRect());
1318
1319
        // gray outline
1320
0
        pClone->SetMergedItem(XLineStyleItem(css::drawing::LineStyle_SOLID));
1321
0
        const svtools::ColorConfig aColorConfig;
1322
0
        const svtools::ColorConfigValue aColor(aColorConfig.GetColorValue(svtools::DOCBOUNDARIES));
1323
0
        pClone->SetMergedItem(XLineColorItem(OUString(), aColor.nColor));
1324
1325
        // bitmap fill
1326
0
        pClone->SetMergedItem(XFillStyleItem(drawing::FillStyle_BITMAP));
1327
0
        pClone->SetMergedItem(XFillBitmapItem(OUString(), GetEmptyOLEReplacementGraphic()));
1328
0
        pClone->SetMergedItem(XFillBmpTileItem(false));
1329
0
        pClone->SetMergedItem(XFillBmpStretchItem(false));
1330
1331
0
        return rtl::Reference<SdrObject>(pClone);
1332
0
    }
1333
0
}
1334
1335
rtl::Reference<SdrObject> SdrOle2Obj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
1336
0
{
1337
    // #i118485# missing converter added
1338
0
    rtl::Reference<SdrObject> pRetval = createSdrGrafObjReplacement(true);
1339
1340
0
    if(pRetval)
1341
0
    {
1342
0
        return pRetval->DoConvertToPolyObj(bBezier, bAddText);
1343
0
    }
1344
1345
0
    return nullptr;
1346
0
}
1347
1348
void SdrOle2Obj::handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage)
1349
839
{
1350
839
    const bool bRemove(pNewPage == nullptr && pOldPage != nullptr);
1351
839
    const bool bInsert(pNewPage != nullptr && pOldPage == nullptr);
1352
1353
839
    if (bRemove && mpImpl->mbConnected )
1354
0
    {
1355
0
        Disconnect();
1356
0
    }
1357
1358
    // call parent
1359
839
    SdrRectObj::handlePageChange(pOldPage, pNewPage);
1360
1361
839
    if (bInsert && !mpImpl->mbConnected )
1362
715
    {
1363
715
        Connect();
1364
715
    }
1365
839
}
1366
1367
void SdrOle2Obj::SetObjRef( const css::uno::Reference < css::embed::XEmbeddedObject >& rNewObjRef )
1368
0
{
1369
0
    DBG_ASSERT( !rNewObjRef.is() || !mpImpl->mxObjRef.GetObject().is(), "SetObjRef called on already initialized object!");
1370
0
    if( rNewObjRef == mpImpl->mxObjRef.GetObject() )
1371
0
        return;
1372
1373
    // the caller of the method is responsible to control the old object, it will not be closed here
1374
    // Otherwise WW8 import crashes because it transfers control to OLENode by this method
1375
0
    if ( mpImpl->mxObjRef.GetObject().is() )
1376
0
        mpImpl->mxObjRef.Lock( false );
1377
1378
    // avoid removal of object in Disconnect! It is definitely a HACK to call SetObjRef(0)!
1379
    // This call will try to close the objects; so if anybody else wants to keep it, it must be locked by a CloseListener
1380
0
    mpImpl->mxObjRef.Clear();
1381
1382
0
    if ( mpImpl->mbConnected )
1383
0
        Disconnect();
1384
1385
0
    mpImpl->mxObjRef.Assign( rNewObjRef, GetAspect() );
1386
0
    mpImpl->mbTypeAsked = false;
1387
1388
0
    if ( mpImpl->mxObjRef.is() )
1389
0
    {
1390
0
        mpImpl->moGraphic.reset();
1391
1392
0
        if ( mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE )
1393
0
            SetResizeProtect(true);
1394
1395
        // For math objects, set closed state to transparent
1396
0
        SetClosedObj(!ImplIsMathObj( rNewObjRef ));
1397
1398
0
        Connect();
1399
0
    }
1400
1401
0
    SetChanged();
1402
0
    BroadcastObjectChange();
1403
0
}
1404
1405
void SdrOle2Obj::SetClosedObj( bool bIsClosed )
1406
11
{
1407
    // TODO/LATER: do we still need this hack?
1408
    // Allow changes to the closed state of OLE objects
1409
11
    m_bClosedObj = bIsClosed;
1410
11
}
1411
1412
rtl::Reference<SdrObject> SdrOle2Obj::getFullDragClone() const
1413
0
{
1414
    // #i118485# use central replacement generator
1415
0
    return createSdrGrafObjReplacement(false);
1416
0
}
1417
1418
void SdrOle2Obj::SetPersistName( const OUString& rPersistName, SvxOle2Shape* pCreator )
1419
11
{
1420
11
    DBG_ASSERT( mpImpl->aPersistName.isEmpty(), "Persist name changed!");
1421
1422
11
    mpImpl->aPersistName = rPersistName;
1423
11
    mpImpl->mbLoadingOLEObjectFailed = false;
1424
1425
11
    Connect(pCreator);
1426
11
    SetChanged();
1427
11
}
1428
1429
void SdrOle2Obj::AbandonObject()
1430
0
{
1431
0
    mpImpl->aPersistName.clear();
1432
0
    mpImpl->mbLoadingOLEObjectFailed = false;
1433
0
    SetObjRef(nullptr);
1434
0
}
1435
1436
const OUString& SdrOle2Obj::GetPersistName() const
1437
1.01k
{
1438
1.01k
    return mpImpl->aPersistName;
1439
1.01k
}
1440
1441
void SdrOle2Obj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1442
0
{
1443
    // #i118485# Allowing much more attributes for OLEs
1444
0
    rInfo.bRotateFreeAllowed = true;
1445
0
    rInfo.bRotate90Allowed = true;
1446
0
    rInfo.bMirrorFreeAllowed = true;
1447
0
    rInfo.bMirror45Allowed = true;
1448
0
    rInfo.bMirror90Allowed = true;
1449
0
    rInfo.bTransparenceAllowed = true;
1450
0
    rInfo.bShearAllowed = true;
1451
0
    rInfo.bEdgeRadiusAllowed = false;
1452
0
    rInfo.bNoOrthoDesired = false;
1453
0
    rInfo.bCanConvToPath = true;
1454
0
    rInfo.bCanConvToPoly = true;
1455
0
    rInfo.bCanConvToPathLineToArea = false;
1456
0
    rInfo.bCanConvToPolyLineToArea = false;
1457
0
    rInfo.bCanConvToContour = true;
1458
0
}
1459
1460
SdrObjKind SdrOle2Obj::GetObjIdentifier() const
1461
8.56k
{
1462
8.56k
    return mpImpl->mbFrame ? SdrObjKind::OLEPluginFrame : SdrObjKind::OLE2;
1463
8.56k
}
1464
1465
OUString SdrOle2Obj::TakeObjNameSingul() const
1466
0
{
1467
0
    OUStringBuffer sName(SvxResId(mpImpl->mbFrame ? STR_ObjNameSingulFrame : STR_ObjNameSingulOLE2));
1468
1469
0
    const OUString aName(GetName());
1470
1471
0
    if (!aName.isEmpty())
1472
0
    {
1473
0
        sName.append(" '" + aName + "\'");
1474
0
    }
1475
1476
0
    return sName.makeStringAndClear();
1477
0
}
1478
1479
OUString SdrOle2Obj::TakeObjNamePlural() const
1480
0
{
1481
0
    return SvxResId(mpImpl->mbFrame ? STR_ObjNamePluralFrame : STR_ObjNamePluralOLE2);
1482
0
}
1483
1484
rtl::Reference<SdrObject> SdrOle2Obj::CloneSdrObject(SdrModel& rTargetModel) const
1485
0
{
1486
0
    return new SdrOle2Obj(rTargetModel, *this);
1487
0
}
1488
1489
void SdrOle2Obj::ImpSetVisAreaSize()
1490
84
{
1491
    // #i118524# do not again set VisAreaSize when the call comes from OLE client (e.g. ObjectAreaChanged)
1492
84
    if (mpImpl->mbSuppressSetVisAreaSize)
1493
0
        return;
1494
1495
    // currently there is no need to recalculate scaling for iconified objects
1496
    // TODO/LATER: it might be needed in future when it is possible to change the icon
1497
84
    if ( GetAspect() == embed::Aspects::MSOLE_ICON )
1498
0
        return;
1499
1500
    // the object area of an embedded object was changed, e.g. by user interaction an a selected object
1501
84
    GetObjRef();
1502
84
    if (!mpImpl->mxObjRef.is())
1503
84
        return;
1504
1505
0
    sal_Int64 nMiscStatus = mpImpl->mxObjRef->getStatus( GetAspect() );
1506
1507
    // the client is required to get access to scaling
1508
0
    SfxInPlaceClient* pClient(
1509
0
        SfxInPlaceClient::GetClient(
1510
0
            dynamic_cast<SfxObjectShell*>(
1511
0
                getSdrModelFromSdrObject().GetPersist()),
1512
0
                mpImpl->mxObjRef.GetObject()));
1513
0
    const bool bHasOwnClient(
1514
0
        mpImpl->mxLightClient.is() &&
1515
0
        mpImpl->mxObjRef->getClientSite() == uno::Reference< embed::XEmbeddedClient >( mpImpl->mxLightClient ) );
1516
1517
0
    if ( pClient || bHasOwnClient )
1518
0
    {
1519
        // TODO: IMHO we need to do similar things when object is UIActive or OutplaceActive?!
1520
0
        if ( ((nMiscStatus & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) &&
1521
0
                svt::EmbeddedObjectRef::TryRunningState( mpImpl->mxObjRef.GetObject() ))
1522
0
                || mpImpl->mxObjRef->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE
1523
0
                )
1524
0
        {
1525
0
            Fraction aScaleWidth;
1526
0
            Fraction aScaleHeight;
1527
0
            if ( pClient )
1528
0
            {
1529
0
                aScaleWidth = pClient->GetScaleWidth();
1530
0
                aScaleHeight = pClient->GetScaleHeight();
1531
0
            }
1532
0
            else
1533
0
            {
1534
0
                aScaleWidth = mpImpl->mxLightClient->GetScaleWidth();
1535
0
                aScaleHeight = mpImpl->mxLightClient->GetScaleHeight();
1536
0
            }
1537
1538
            // The object wants to resize itself (f.e. Chart wants to recalculate the layout)
1539
            // or object is inplace active and so has a window that must be resized also
1540
            // In these cases the change in the object area size will be reflected in a change of the
1541
            // objects' visual area. The scaling will not change, but it might exist already and must
1542
            // be used in calculations
1543
0
            MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl->mxObjRef->getMapUnit( GetAspect() ) );
1544
0
            Size aVisSize;
1545
0
            if (sal_Int32(aScaleWidth) != 0 && sal_Int32(aScaleHeight) != 0) // avoid div by zero
1546
0
                aVisSize = Size( static_cast<tools::Long>( Fraction( getRectangle().GetWidth() ) / aScaleWidth ),
1547
0
                                 static_cast<tools::Long>( Fraction( getRectangle().GetHeight() ) / aScaleHeight ) );
1548
1549
0
            aVisSize = OutputDevice::LogicToLogic(
1550
0
                aVisSize,
1551
0
                MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1552
0
                MapMode(aMapUnit));
1553
0
            awt::Size aSz;
1554
0
            aSz.Width = aVisSize.Width();
1555
0
            aSz.Height = aVisSize.Height();
1556
0
            mpImpl->mxObjRef->setVisualAreaSize( GetAspect(), aSz );
1557
1558
0
            try
1559
0
            {
1560
0
                aSz = mpImpl->mxObjRef->getVisualAreaSize( GetAspect() );
1561
0
            }
1562
0
            catch( embed::NoVisualAreaSizeException& )
1563
0
            {}
1564
1565
0
            tools::Rectangle aAcceptedVisArea;
1566
0
            aAcceptedVisArea.SetSize( Size( static_cast<tools::Long>( Fraction( tools::Long( aSz.Width ) ) * aScaleWidth ),
1567
0
                                            static_cast<tools::Long>( Fraction( tools::Long( aSz.Height ) ) * aScaleHeight ) ) );
1568
0
            if (aVisSize != aAcceptedVisArea.GetSize())
1569
0
            {
1570
                // server changed VisArea to its liking and the VisArea is different than the suggested one
1571
                // store the new value as given by the object
1572
0
                MapUnit aNewMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl->mxObjRef->getMapUnit( GetAspect() ) );
1573
0
                auto aSize = OutputDevice::LogicToLogic(aAcceptedVisArea.GetSize(), MapMode(aNewMapUnit), MapMode(getSdrModelFromSdrObject().GetScaleUnit()));
1574
0
                setRectangleSize(aSize.Width(), aSize.Height());
1575
0
            }
1576
1577
            // make the new object area known to the client
1578
            // compared to the "else" branch aRect might have been changed by the object and no additional scaling was applied
1579
            // WHY this -> OSL_ASSERT( pClient );
1580
0
            if( pClient )
1581
0
                pClient->SetObjArea(getRectangle());
1582
1583
            // we need a new replacement image as the object has resized itself
1584
1585
            //#i79578# don't request a new replacement image for charts to often
1586
            //a chart sends a modified call to the framework if it was changed
1587
            //thus the replacement update is already handled there
1588
0
            if( !IsChart() )
1589
0
                mpImpl->mxObjRef.UpdateReplacement();
1590
0
        }
1591
0
        else
1592
0
        {
1593
            // The object isn't active and does not want to resize itself so the changed object area size
1594
            // will be reflected in a changed object scaling
1595
0
            Fraction aScaleWidth;
1596
0
            Fraction aScaleHeight;
1597
0
            Size aObjAreaSize;
1598
0
            if ( CalculateNewScaling( aScaleWidth, aScaleHeight, aObjAreaSize ) )
1599
0
            {
1600
0
                if ( pClient )
1601
0
                {
1602
0
                    tools::Rectangle aScaleRect(getRectangle().TopLeft(), aObjAreaSize);
1603
0
                    pClient->SetObjAreaAndScale( aScaleRect, aScaleWidth, aScaleHeight);
1604
0
                }
1605
0
                else
1606
0
                {
1607
0
                    mpImpl->mxLightClient->SetSizeScale( aScaleWidth, aScaleHeight );
1608
0
                }
1609
0
            }
1610
0
        }
1611
0
    }
1612
0
    else if( (nMiscStatus & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) &&
1613
0
        svt::EmbeddedObjectRef::TryRunningState( mpImpl->mxObjRef.GetObject() ) )
1614
0
    {
1615
        //also handle not sfx based ole objects e.g. charts
1616
        //#i83860# resizing charts in impress distorts fonts
1617
0
        uno::Reference< embed::XVisualObject > xVisualObject( getXModel(), uno::UNO_QUERY );
1618
0
        if( xVisualObject.is() )
1619
0
        {
1620
0
            const MapUnit aMapUnit(
1621
0
                VCLUnoHelper::UnoEmbed2VCLMapUnit(
1622
0
                    mpImpl->mxObjRef->getMapUnit(GetAspect())));
1623
0
            const Point aTL( getRectangle().TopLeft() );
1624
0
            const Point aBR( getRectangle().BottomRight() );
1625
0
            const Point aTL2(
1626
0
                OutputDevice::LogicToLogic(
1627
0
                    aTL,
1628
0
                    MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1629
0
                    MapMode(aMapUnit)));
1630
0
            const Point aBR2(
1631
0
                OutputDevice::LogicToLogic(
1632
0
                    aBR,
1633
0
                    MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1634
0
                    MapMode(aMapUnit)));
1635
0
            const tools::Rectangle aNewRect(
1636
0
                aTL2,
1637
0
                aBR2);
1638
1639
0
            xVisualObject->setVisualAreaSize(
1640
0
                GetAspect(),
1641
0
                awt::Size(
1642
0
                    aNewRect.GetWidth(),
1643
0
                    aNewRect.GetHeight()));
1644
0
        }
1645
0
    }
1646
0
}
1647
1648
void SdrOle2Obj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1649
0
{
1650
0
    if(!getSdrModelFromSdrObject().isLocked())
1651
0
    {
1652
0
        GetObjRef();
1653
1654
0
        if ( mpImpl->mxObjRef.is() && ( mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) )
1655
0
        {
1656
            // if the object needs recompose on resize
1657
            // the client site should be created before the resize will take place
1658
            // check whether there is no client site and create it if necessary
1659
0
            AddOwnLightClient();
1660
0
        }
1661
0
    }
1662
1663
0
    SdrRectObj::NbcResize(rRef,xFact,yFact);
1664
1665
0
    if( !getSdrModelFromSdrObject().isLocked() )
1666
0
        ImpSetVisAreaSize();
1667
0
}
1668
1669
void SdrOle2Obj::SetGeoData(const SdrObjGeoData& rGeo)
1670
0
{
1671
0
    SdrRectObj::SetGeoData(rGeo);
1672
1673
0
    if( !getSdrModelFromSdrObject().isLocked() )
1674
0
        ImpSetVisAreaSize();
1675
0
}
1676
1677
void SdrOle2Obj::NbcSetSnapRect(const tools::Rectangle& rRect)
1678
1.18k
{
1679
1.18k
    SdrRectObj::NbcSetSnapRect(rRect);
1680
1681
1.18k
    if( !getSdrModelFromSdrObject().isLocked() )
1682
42
        ImpSetVisAreaSize();
1683
1684
1.18k
    if ( mpImpl->mxObjRef.is() && IsChart() )
1685
0
    {
1686
        //#i103460# charts do not necessarily have an own size within ODF files,
1687
        //for this case they need to use the size settings from the surrounding frame,
1688
        //which is made available with this method as there is no other way
1689
0
        mpImpl->mxObjRef.SetDefaultSizeForChart( Size( rRect.GetWidth(), rRect.GetHeight() ) );
1690
0
    }
1691
1.18k
}
1692
1693
void SdrOle2Obj::NbcSetLogicRect(const tools::Rectangle& rRect, bool bAdaptTextMinSize)
1694
965
{
1695
965
    SdrRectObj::NbcSetLogicRect(rRect, bAdaptTextMinSize);
1696
1697
965
    if( !getSdrModelFromSdrObject().isLocked() )
1698
21
        ImpSetVisAreaSize();
1699
965
}
1700
1701
const Graphic* SdrOle2Obj::GetGraphic() const
1702
0
{
1703
0
    if ( mpImpl->mxObjRef.is() )
1704
0
        return mpImpl->mxObjRef.GetGraphic();
1705
0
    return mpImpl->moGraphic ? &*mpImpl->moGraphic : nullptr;
1706
0
}
1707
1708
void SdrOle2Obj::GetNewReplacement()
1709
0
{
1710
0
    if ( mpImpl->mxObjRef.is() )
1711
0
        mpImpl->mxObjRef.UpdateReplacement();
1712
0
}
1713
1714
Size SdrOle2Obj::GetOrigObjSize( MapMode const * pTargetMapMode ) const
1715
0
{
1716
0
    return mpImpl->mxObjRef.GetSize( pTargetMapMode );
1717
0
}
1718
1719
void SdrOle2Obj::setSuppressSetVisAreaSize( bool bNew )
1720
0
{
1721
0
    mpImpl->mbSuppressSetVisAreaSize = bNew;
1722
0
}
1723
1724
void SdrOle2Obj::NbcMove(const Size& rSize)
1725
525
{
1726
525
    SdrRectObj::NbcMove(rSize);
1727
1728
525
    if( !getSdrModelFromSdrObject().isLocked() )
1729
0
        ImpSetVisAreaSize();
1730
525
}
1731
1732
bool SdrOle2Obj::CanUnloadRunningObj( const uno::Reference< embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
1733
0
{
1734
0
    uno::Reference<embed::XEmbedPersist2> xPersist(xObj, uno::UNO_QUERY);
1735
0
    if (xPersist.is())
1736
0
    {
1737
0
        if (!xPersist->isStored())
1738
            // It doesn't have persistent storage.  We can't unload this.
1739
0
            return false;
1740
0
    }
1741
1742
0
    bool bResult = false;
1743
1744
0
    sal_Int32 nState = xObj->getCurrentState();
1745
0
    if ( nState == embed::EmbedStates::LOADED )
1746
0
    {
1747
        // the object is already unloaded
1748
0
        bResult = true;
1749
0
    }
1750
0
    else
1751
0
    {
1752
0
        uno::Reference < util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
1753
0
        if ( !xModifiable.is() )
1754
0
            bResult = true;
1755
0
        else
1756
0
        {
1757
0
            sal_Int64 nMiscStatus = xObj->getStatus( nAspect );
1758
1759
0
            if ( embed::EmbedMisc::MS_EMBED_ALWAYSRUN != ( nMiscStatus & embed::EmbedMisc::MS_EMBED_ALWAYSRUN ) &&
1760
0
            embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY != ( nMiscStatus & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) &&
1761
0
            !( xModifiable.is() && xModifiable->isModified() ) &&
1762
0
            !( nState == embed::EmbedStates::INPLACE_ACTIVE || nState == embed::EmbedStates::UI_ACTIVE || nState == embed::EmbedStates::ACTIVE ) )
1763
0
            {
1764
0
                bResult = true;
1765
0
            }
1766
0
        }
1767
0
    }
1768
1769
0
    return bResult;
1770
0
}
1771
1772
bool SdrOle2Obj::Unload( const uno::Reference< embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
1773
0
{
1774
0
    bool bResult = false;
1775
1776
0
    if ( CanUnloadRunningObj( xObj, nAspect ) )
1777
0
    {
1778
0
        try
1779
0
        {
1780
0
            xObj->changeState( embed::EmbedStates::LOADED );
1781
0
            bResult = true;
1782
0
        }
1783
0
        catch( css::uno::Exception& )
1784
0
        {
1785
0
            TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Unload()" );
1786
0
        }
1787
0
    }
1788
1789
0
    return bResult;
1790
0
}
1791
1792
bool SdrOle2Obj::Unload()
1793
0
{
1794
0
    if (!mpImpl->mxObjRef.is())
1795
        // Already unloaded.
1796
0
        return true;
1797
1798
0
    return Unload(mpImpl->mxObjRef.GetObject(), GetAspect());
1799
0
}
1800
1801
void SdrOle2Obj::GetObjRef_Impl()
1802
845
{
1803
845
    if ( !mpImpl->mxObjRef.is() && !mpImpl->aPersistName.isEmpty() && getSdrModelFromSdrObject().GetPersist() )
1804
11
    {
1805
        // Only try loading if it did not went wrong up to now
1806
11
        if(!mpImpl->mbLoadingOLEObjectFailed)
1807
11
        {
1808
11
            mpImpl->mxObjRef.Assign(
1809
11
                getSdrModelFromSdrObject().GetPersist()->getEmbeddedObjectContainer().GetEmbeddedObject(mpImpl->aPersistName),
1810
11
                GetAspect());
1811
11
            mpImpl->mbTypeAsked = false;
1812
11
            CheckFileLink_Impl();
1813
1814
            // If loading of OLE object failed, remember that to not invoke an endless
1815
            // loop trying to load it again and again.
1816
11
            if( mpImpl->mxObjRef.is() )
1817
0
            {
1818
0
                mpImpl->mbLoadingOLEObjectFailed = true;
1819
0
            }
1820
1821
            // For math objects, set closed state to transparent
1822
11
            SetClosedObj(!ImplIsMathObj( mpImpl->mxObjRef.GetObject() ));
1823
11
        }
1824
1825
11
        if ( mpImpl->mxObjRef.is() )
1826
0
        {
1827
0
            if( !IsEmptyPresObj() )
1828
0
            {
1829
                // remember modified status of model
1830
0
                const bool bWasChanged(getSdrModelFromSdrObject().IsChanged());
1831
1832
                // perhaps preview not valid anymore
1833
                // This line changes the modified state of the model
1834
0
                ClearGraphic();
1835
1836
                // if status was not set before, force it back
1837
                // to not set, so that SetGraphic(0) above does not
1838
                // set the modified state of the model.
1839
0
                if(!bWasChanged && getSdrModelFromSdrObject().IsChanged())
1840
0
                {
1841
0
                    getSdrModelFromSdrObject().SetChanged( false );
1842
0
                }
1843
0
            }
1844
0
        }
1845
1846
11
        if ( mpImpl->mxObjRef.is() )
1847
0
            Connect();
1848
11
    }
1849
1850
845
    if ( mpImpl->mbConnected )
1851
0
    {
1852
        // move object to first position in cache
1853
0
        GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
1854
0
    }
1855
845
}
1856
1857
uno::Reference < embed::XEmbeddedObject > const & SdrOle2Obj::GetObjRef() const
1858
845
{
1859
845
    const_cast<SdrOle2Obj*>(this)->GetObjRef_Impl();
1860
845
    return mpImpl->mxObjRef.GetObject();
1861
845
}
1862
1863
uno::Reference < embed::XEmbeddedObject > const & SdrOle2Obj::GetObjRef_NoInit() const
1864
0
{
1865
0
    return mpImpl->mxObjRef.GetObject();
1866
0
}
1867
1868
uno::Reference< frame::XModel > SdrOle2Obj::getXModel() const
1869
0
{
1870
0
    if (svt::EmbeddedObjectRef::TryRunningState(GetObjRef()))
1871
0
        return uno::Reference< frame::XModel >( mpImpl->mxObjRef->getComponent(), uno::UNO_QUERY );
1872
0
    else
1873
0
        return uno::Reference< frame::XModel >();
1874
0
}
1875
1876
bool SdrOle2Obj::IsChart() const
1877
21
{
1878
21
    if (!mpImpl->mbTypeAsked)
1879
21
    {
1880
21
        mpImpl->mbIsChart = mpImpl->mxObjRef.IsChart();
1881
21
        mpImpl->mbTypeAsked = true;
1882
21
    }
1883
21
    return mpImpl->mbIsChart;
1884
21
}
1885
1886
void SdrOle2Obj::SetGraphicToObj( const Graphic& aGraphic )
1887
8
{
1888
8
    mpImpl->mxObjRef.SetGraphic( aGraphic, OUString() );
1889
    // if the object isn't valid, e.g. link to something that doesn't exist, set the fallback
1890
    // graphic as mxGraphic so SdrOle2Obj::GetGraphic will show the fallback
1891
8
    if (const Graphic* pObjGraphic = mpImpl->mxObjRef.is() ? nullptr : mpImpl->mxObjRef.GetGraphic())
1892
8
        mpImpl->moGraphic.emplace(*pObjGraphic);
1893
8
}
1894
1895
void SdrOle2Obj::SetGraphicToObj( const uno::Reference< io::XInputStream >& xGrStream, const OUString& aMediaType )
1896
0
{
1897
0
    mpImpl->mxObjRef.SetGraphicStream( xGrStream, aMediaType );
1898
    // if the object isn't valid, e.g. link to something that doesn't exist, set the fallback
1899
    // graphic as mxGraphic so SdrOle2Obj::GetGraphic will show the fallback
1900
0
    if (const Graphic* pObjGraphic = mpImpl->mxObjRef.is() ? nullptr : mpImpl->mxObjRef.GetGraphic())
1901
0
        mpImpl->moGraphic.emplace(*pObjGraphic);
1902
0
}
1903
1904
bool SdrOle2Obj::IsCalc() const
1905
0
{
1906
0
    if ( !mpImpl->mxObjRef.is() )
1907
0
        return false;
1908
1909
0
    SvGlobalName aObjClsId( mpImpl->mxObjRef->getClassID() );
1910
0
    return SvGlobalName(SO3_SC_CLASSID_30) == aObjClsId
1911
0
        || SvGlobalName(SO3_SC_CLASSID_40) == aObjClsId
1912
0
        || SvGlobalName(SO3_SC_CLASSID_50) == aObjClsId
1913
0
        || SvGlobalName(SO3_SC_CLASSID_60) == aObjClsId
1914
0
        || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_60) == aObjClsId
1915
0
        || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_8) == aObjClsId
1916
0
        || SvGlobalName(SO3_SC_CLASSID) == aObjClsId;
1917
0
}
1918
1919
const uno::Reference< frame::XModel > & SdrOle2Obj::GetParentXModel() const
1920
0
{
1921
0
    return getSdrModelFromSdrObject().getUnoModel();
1922
0
}
1923
1924
bool SdrOle2Obj::CalculateNewScaling( Fraction& aScaleWidth, Fraction& aScaleHeight, Size& aObjAreaSize )
1925
0
{
1926
    // TODO/LEAN: to avoid rounding errors scaling always uses the VisArea.
1927
    // If we don't cache it for own objects also we must load the object here
1928
0
    if (!mpImpl->mxObjRef.is())
1929
0
        return false;
1930
1931
0
    MapMode aMapMode(getSdrModelFromSdrObject().GetScaleUnit());
1932
0
    aObjAreaSize = mpImpl->mxObjRef.GetSize( &aMapMode );
1933
1934
0
    Size aSize = getRectangle().GetSize();
1935
0
    if (!aObjAreaSize.Width() || !aObjAreaSize.Height())
1936
0
    {
1937
        // avoid invalid fractions
1938
0
        aScaleWidth = Fraction(1,1);
1939
0
        aScaleHeight = Fraction(1,1);
1940
0
    }
1941
0
    else
1942
0
    {
1943
0
        aScaleWidth = Fraction(aSize.Width(),  aObjAreaSize.Width() );
1944
0
        aScaleHeight = Fraction(aSize.Height(), aObjAreaSize.Height() );
1945
        // reduce to 10 binary digits
1946
0
        aScaleHeight.ReduceInaccurate(10);
1947
0
        aScaleWidth.ReduceInaccurate(10);
1948
0
    }
1949
1950
0
    return true;
1951
0
}
1952
1953
0
void SdrOle2Obj::SetIgnoreOLEObjectScale(bool val) { mpImpl->mbIgnoreOLEObjectScale = val; }
1954
1955
bool SdrOle2Obj::AddOwnLightClient()
1956
0
{
1957
    // The Own Light Client must be registered in object only using this method!
1958
0
    if ( !SfxInPlaceClient::GetClient( dynamic_cast<SfxObjectShell*>(getSdrModelFromSdrObject().GetPersist()), mpImpl->mxObjRef.GetObject() )
1959
0
      && !( mpImpl->mxLightClient.is() && mpImpl->mxObjRef->getClientSite() == uno::Reference< embed::XEmbeddedClient >( mpImpl->mxLightClient ) ) )
1960
0
    {
1961
0
        Connect();
1962
1963
0
        if (!mpImpl->mbIgnoreOLEObjectScale && mpImpl->mxObjRef.is() && mpImpl->mxLightClient.is())
1964
0
        {
1965
0
            Fraction aScaleWidth;
1966
0
            Fraction aScaleHeight;
1967
0
            Size aObjAreaSize;
1968
0
            if ( CalculateNewScaling( aScaleWidth, aScaleHeight, aObjAreaSize ) )
1969
0
            {
1970
0
                mpImpl->mxLightClient->SetSizeScale( aScaleWidth, aScaleHeight );
1971
0
                try {
1972
0
                    mpImpl->mxObjRef->setClientSite( mpImpl->mxLightClient );
1973
0
                    return true;
1974
0
                } catch( uno::Exception& )
1975
0
                {}
1976
0
            }
1977
1978
0
        }
1979
1980
0
        return false;
1981
0
    }
1982
1983
0
    return true;
1984
0
}
1985
1986
Graphic SdrOle2Obj::GetEmptyOLEReplacementGraphic()
1987
0
{
1988
0
    return Graphic(BitmapEx(BMP_SVXOLEOBJ));
1989
0
}
1990
1991
void SdrOle2Obj::SetWindow(const css::uno::Reference < css::awt::XWindow >& _xWindow)
1992
0
{
1993
0
    if ( mpImpl->mxObjRef.is() && mpImpl->mxLightClient.is() )
1994
0
    {
1995
0
        mpImpl->mxLightClient->setWindow(_xWindow);
1996
0
    }
1997
0
}
1998
1999
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */