Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/embeddedobj/source/inc/oleembobj.hxx
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
#pragma once
21
22
#include <com/sun/star/uno/Sequence.hxx>
23
#include <com/sun/star/uno/Reference.hxx>
24
#include <com/sun/star/embed/XEmbeddedObject.hpp>
25
#include <com/sun/star/embed/XEmbeddedOleObject.hpp>
26
#include <com/sun/star/embed/XInplaceObject.hpp>
27
#include <com/sun/star/embed/XEmbedPersist.hpp>
28
#include <com/sun/star/embed/XLinkageSupport.hpp>
29
#include <com/sun/star/container/XChild.hpp>
30
#include <com/sun/star/util/XCloseListener.hpp>
31
#include <com/sun/star/io/XActiveDataStreamer.hpp>
32
#include <com/sun/star/lang/XInitialization.hpp>
33
#include <com/sun/star/lang/XServiceInfo.hpp>
34
#include <com/sun/star/uno/XComponentContext.hpp>
35
#include <cppuhelper/implbase.hxx>
36
#include <rtl/ref.hxx>
37
38
#include <osl/thread.h>
39
#include <memory>
40
41
namespace comphelper {
42
    class OMultiTypeInterfaceContainerHelper2;
43
}
44
45
class VerbExecutionController
46
{
47
    // the following mutex is allowed to be locked only for variables initialization, so no deadlock can be caused
48
    ::osl::Mutex    m_aVerbExecutionMutex;
49
50
    sal_Int32 m_nNotificationLock;
51
52
#ifdef _WIN32
53
    bool m_bWasEverActive;
54
    bool m_bVerbExecutionInProgress;
55
    oslThreadIdentifier m_nVerbExecutionThreadIdentifier;
56
    bool m_bChangedOnVerbExecution;
57
#endif
58
59
public:
60
61
    VerbExecutionController()
62
51
    : m_nNotificationLock( 0 )
63
#ifdef _WIN32
64
    , m_bWasEverActive( false )
65
    , m_bVerbExecutionInProgress( false )
66
    , m_nVerbExecutionThreadIdentifier( 0 )
67
    , m_bChangedOnVerbExecution( false )
68
#endif
69
51
    {}
70
71
#ifdef _WIN32
72
    void StartControlExecution();
73
    bool EndControlExecution_WasModified();
74
    void ModificationNotificationIsDone();
75
    // no need to lock anything to check the value of the numeric members
76
    bool CanDoNotification() { return ( !m_bVerbExecutionInProgress && !m_bWasEverActive && !m_nNotificationLock ); }
77
    // ... or to change it
78
    void ObjectIsActive() { m_bWasEverActive = true; }
79
#endif
80
    void LockNotification();
81
    void UnlockNotification();
82
};
83
84
class VerbExecutionControllerGuard
85
{
86
    VerbExecutionController& m_rController;
87
public:
88
89
    VerbExecutionControllerGuard( VerbExecutionController& rController )
90
0
    : m_rController( rController )
91
0
    {
92
0
        m_rController.LockNotification();
93
0
    }
94
95
    ~VerbExecutionControllerGuard()
96
0
    {
97
0
        m_rController.UnlockNotification();
98
0
    }
99
};
100
101
102
class OleComponent;
103
class OwnView_Impl;
104
/**
105
 * Represents an OLE object that has native data and we try to let an external
106
 * application handle that data.
107
 */
108
class OleEmbeddedObject : public ::cppu::WeakImplHelper
109
                        < css::embed::XEmbeddedObject
110
                        , css::embed::XEmbeddedOleObject
111
                        , css::embed::XEmbedPersist
112
                        , css::embed::XLinkageSupport
113
                        , css::embed::XInplaceObject
114
                        , css::container::XChild
115
                        , css::io::XActiveDataStreamer
116
                        , css::lang::XInitialization
117
                        , css::lang::XServiceInfo >
118
{
119
    friend class OleComponent;
120
121
    ::osl::Mutex    m_aMutex;
122
123
    rtl::Reference<OleComponent> m_pOleComponent;
124
125
    std::unique_ptr<::comphelper::OMultiTypeInterfaceContainerHelper2> m_pInterfaceContainer;
126
127
    bool m_bReadOnly;
128
129
    bool m_bDisposed;
130
    sal_Int32 m_nObjectState;
131
    sal_Int32 m_nTargetState;
132
    sal_Int32 m_nUpdateMode;
133
134
    css::uno::Reference< css::uno::XComponentContext > m_xContext;
135
136
    css::uno::Sequence< sal_Int8 > m_aClassID;
137
    OUString m_aClassName;
138
139
    css::uno::Reference< css::embed::XEmbeddedClient > m_xClientSite;
140
141
    OUString m_aContainerName;
142
143
    css::uno::Reference< css::util::XCloseListener > m_xClosePreventer;
144
145
    bool m_bWaitSaveCompleted;
146
    bool m_bNewVisReplInStream;
147
    css::uno::Reference< css::io::XStream > m_xNewCachedVisRepl;
148
    OUString m_aNewEntryName;
149
    css::uno::Reference< css::embed::XStorage > m_xNewParentStorage;
150
    css::uno::Reference< css::io::XStream > m_xNewObjectStream;
151
    bool m_bStoreLoaded;
152
153
    css::uno::Reference< css::io::XStream > m_xCachedVisualRepresentation;
154
    bool m_bVisReplInitialized;
155
    bool m_bVisReplInStream;
156
    bool m_bStoreVisRepl;
157
158
    bool m_bIsLink;
159
160
    // TODO/LATER: may need to cache more than one aspect in future
161
    bool m_bHasCachedSize; // the object has cached size
162
    css::awt::Size m_aCachedSize;
163
    sal_Int64 m_nCachedAspect;
164
165
    bool m_bHasSizeToSet;  // the object has cached size that should be set to OLE component
166
    css::awt::Size m_aSizeToSet; // this size might be different from the cached one ( scaling is applied )
167
    sal_Int64 m_nAspectToSet;
168
169
170
    // cache the status of the object
171
    // TODO/LATER: may need to cache more than one aspect in future
172
    bool m_bGotStatus;
173
    sal_Int64 m_nStatus;
174
    sal_Int64 m_nStatusAspect;
175
176
    // embedded object related stuff
177
    OUString m_aEntryName;
178
    css::uno::Reference< css::embed::XStorage > m_xParentStorage;
179
    css::uno::Reference< css::io::XStream > m_xObjectStream;
180
181
    // link related stuff
182
    OUString m_aLinkURL; // ???
183
184
    // points to own view provider if the object has no server
185
    rtl::Reference<OwnView_Impl> m_xOwnView;
186
187
    // whether the object should be initialized from clipboard in case of default initialization
188
    bool m_bFromClipboard;
189
190
    OUString m_aTempURL;
191
192
    OUString m_aTempDumpURL;
193
194
    // STAMPIT solution
195
    // the following member is used during verb execution to detect whether the verb execution modifies the object
196
    VerbExecutionController m_aVerbExecutionController;
197
198
    // if the following member is set, the object works in wrapper mode
199
    css::uno::Reference< css::embed::XEmbeddedObject > m_xWrappedObject;
200
    bool m_bTriedConversion;
201
    OUString m_aFilterName; // if m_bTriedConversion, then the filter detected by that
202
203
    css::uno::Reference< css::uno::XInterface > m_xParent;
204
205
    /// If it is allowed to modify entries in the stream of the OLE storage.
206
    bool m_bStreamReadOnly = false;
207
208
protected:
209
    /// @throws css::uno::Exception
210
    css::uno::Reference< css::io::XStream > TryToGetAcceptableFormat_Impl(
211
                                    const css::uno::Reference< css::io::XStream >& xStream );
212
213
    /// @throws css::io::IOException
214
    /// @throws css::uno::RuntimeException
215
    css::uno::Reference< css::io::XStream > GetNewFilledTempStream_Impl(
216
                                    const css::uno::Reference< css::io::XInputStream >& xInStream );
217
#ifdef _WIN32
218
    void SwitchComponentToRunningState_Impl(osl::ResettableMutexGuard& guard);
219
#endif
220
    void MakeEventListenerNotification_Impl( const OUString& aEventName, osl::ResettableMutexGuard& guard );
221
#ifdef _WIN32
222
    void StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState, osl::ResettableMutexGuard& guard );
223
    css::uno::Reference< css::io::XOutputStream > GetStreamForSaving();
224
225
226
    css::uno::Sequence< sal_Int32 > GetIntermediateVerbsSequence_Impl( sal_Int32 nNewState );
227
228
    static css::uno::Sequence< sal_Int32 > GetReachableStatesList_Impl(
229
                        const css::uno::Sequence< css::embed::VerbDescriptor >& aVerbList );
230
#endif
231
232
    void Dispose(osl::ResettableMutexGuard* guard = nullptr);
233
234
    void SwitchOwnPersistence(
235
                const css::uno::Reference< css::embed::XStorage >& xNewParentStorage,
236
                const css::uno::Reference< css::io::XStream >& xNewObjectStream,
237
                const OUString& aNewName );
238
239
    void SwitchOwnPersistence(
240
                const css::uno::Reference< css::embed::XStorage >& xNewParentStorage,
241
                const OUString& aNewName );
242
243
    void GetRidOfComponent(osl::ResettableMutexGuard* guard);
244
245
    /// @throws css::uno::Exception
246
    void StoreToLocation_Impl(
247
                            const css::uno::Reference< css::embed::XStorage >& xStorage,
248
                            const OUString& sEntName,
249
                            const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs,
250
                            bool bSaveAs,
251
                            osl::ResettableMutexGuard& rGuard);
252
#ifdef _WIN32
253
    /// @throws css::uno::Exception
254
    void StoreObjectToStream(css::uno::Reference<css::io::XOutputStream> const& xOutStream,
255
                             osl::ResettableMutexGuard& rGuard);
256
#endif
257
    /// @throws css::uno::Exception
258
    void InsertVisualCache_Impl(
259
            const css::uno::Reference< css::io::XStream >& xTargetStream,
260
            const css::uno::Reference< css::io::XStream >& xCachedVisualRepresentation,
261
            osl::ResettableMutexGuard& rGuard);
262
263
    /// @throws css::uno::Exception
264
    void RemoveVisualCache_Impl( const css::uno::Reference< css::io::XStream >& xTargetStream );
265
266
    void SetVisReplInStream( bool bExists );
267
    bool HasVisReplInStream();
268
269
    /// @throws css::uno::Exception
270
    css::embed::VisualRepresentation GetVisualRepresentationInNativeFormat_Impl(
271
                    const css::uno::Reference< css::io::XStream >& xCachedVisRepr );
272
273
    css::uno::Reference< css::io::XStream > TryToRetrieveCachedVisualRepresentation_Impl(
274
                    const css::uno::Reference< css::io::XStream >& xStream,
275
                    osl::ResettableMutexGuard& rGuard,
276
                    bool bAllowRepair50 = false )
277
        noexcept;
278
#ifdef _WIN32
279
    bool SaveObject_Impl();
280
    bool OnShowWindow_Impl( bool bShow );
281
    void CreateOleComponent_Impl( rtl::Reference<OleComponent> const & pOleComponent = {} );
282
    void CreateOleComponentAndLoad_Impl( rtl::Reference<OleComponent> const & pOleComponent = {} );
283
    void CreateOleComponentFromClipboard_Impl( OleComponent* pOleComponent = nullptr );
284
    OUString CreateTempURLEmpty_Impl();
285
    OUString GetTempURL_Impl();
286
    void SetObjectIsLink_Impl( bool bIsLink ) { m_bIsLink = bIsLink; }
287
#endif
288
289
    // the following 4 methods are related to switch to wrapping mode
290
    void MoveListeners();
291
    css::uno::Reference< css::embed::XStorage > CreateTemporarySubstorage( OUString& o_aStorageName );
292
    OUString MoveToTemporarySubstream();
293
    bool TryToConvertToOOo( const css::uno::Reference< css::io::XStream >& xStream );
294
295
public:
296
    // in case a new object must be created the class ID must be specified
297
    OleEmbeddedObject( css::uno::Reference< css::uno::XComponentContext > xContext,
298
                        const css::uno::Sequence< sal_Int8 >& aClassID,
299
                        OUString  aClassName );
300
301
    // in case object will be loaded from a persistent entry or from a file the class ID will be detected on loading
302
    // factory can do it for OOo objects, but for OLE objects OS dependent code is required
303
    OleEmbeddedObject( css::uno::Reference< css::uno::XComponentContext > xContext,
304
                        bool bLink );
305
#ifdef _WIN32
306
    // this constructor let object be initialized from clipboard
307
    OleEmbeddedObject( const css::uno::Reference< css::uno::XComponentContext >& xContext );
308
#endif
309
310
    virtual ~OleEmbeddedObject() override;
311
312
#ifdef _WIN32
313
    static void OnIconChanged_Impl();
314
    void OnViewChanged_Impl();
315
    void OnClosed_Impl();
316
#endif
317
318
// XEmbeddedObject
319
320
    virtual void SAL_CALL changeState( sal_Int32 nNewState ) override;
321
322
    virtual css::uno::Sequence< sal_Int32 > SAL_CALL getReachableStates() override;
323
324
    virtual sal_Int32 SAL_CALL getCurrentState() override;
325
326
    virtual void SAL_CALL doVerb( sal_Int32 nVerbID ) override;
327
328
    virtual css::uno::Sequence< css::embed::VerbDescriptor > SAL_CALL getSupportedVerbs() override;
329
330
    virtual void SAL_CALL setClientSite(
331
                const css::uno::Reference< css::embed::XEmbeddedClient >& xClient ) override;
332
333
    virtual css::uno::Reference< css::embed::XEmbeddedClient > SAL_CALL getClientSite() override;
334
335
    virtual void SAL_CALL update() override;
336
337
    virtual void SAL_CALL setUpdateMode( sal_Int32 nMode ) override;
338
339
    virtual sal_Int64 SAL_CALL getStatus( sal_Int64 nAspect ) override;
340
341
    virtual void SAL_CALL setContainerName( const OUString& sName ) override;
342
343
344
// XVisualObject
345
346
    virtual void SAL_CALL setVisualAreaSize( sal_Int64 nAspect, const css::awt::Size& aSize ) override;
347
348
    virtual css::awt::Size SAL_CALL getVisualAreaSize( sal_Int64 nAspect ) override;
349
350
    virtual css::embed::VisualRepresentation SAL_CALL getPreferredVisualRepresentation( ::sal_Int64 nAspect ) override;
351
352
    virtual sal_Int32 SAL_CALL getMapUnit( sal_Int64 nAspect ) override;
353
354
355
// XEmbedPersist
356
357
    virtual void SAL_CALL setPersistentEntry(
358
                    const css::uno::Reference< css::embed::XStorage >& xStorage,
359
                    const OUString& sEntName,
360
                    sal_Int32 nEntryConnectionMode,
361
                    const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
362
                    const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs ) override;
363
364
    virtual void SAL_CALL storeToEntry( const css::uno::Reference< css::embed::XStorage >& xStorage, const OUString& sEntName, const css::uno::Sequence< css::beans::PropertyValue >& lArguments, const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs ) override;
365
366
    virtual void SAL_CALL storeAsEntry(
367
                const css::uno::Reference< css::embed::XStorage >& xStorage,
368
                const OUString& sEntName,
369
                const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
370
                const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs ) override;
371
372
    virtual void SAL_CALL saveCompleted( sal_Bool bUseNew ) override;
373
374
    virtual sal_Bool SAL_CALL hasEntry() override;
375
376
    virtual OUString SAL_CALL getEntryName() override;
377
378
// XLinkageSupport
379
380
    virtual void SAL_CALL breakLink( const css::uno::Reference< css::embed::XStorage >& xStorage,
381
                                     const OUString& sEntName ) override;
382
383
    virtual sal_Bool SAL_CALL isLink() override;
384
385
    virtual OUString SAL_CALL getLinkURL() override;
386
387
// XCommonEmbedPersist
388
    virtual void SAL_CALL storeOwn() override;
389
390
    virtual sal_Bool SAL_CALL isReadonly() override;
391
392
    virtual void SAL_CALL reload(
393
                const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
394
                const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs ) override;
395
396
// XClassifiedObject
397
398
    virtual css::uno::Sequence< sal_Int8 > SAL_CALL getClassID() override;
399
400
    virtual OUString SAL_CALL getClassName() override;
401
402
    virtual void SAL_CALL setClassInfo(
403
                const css::uno::Sequence< sal_Int8 >& aClassID, const OUString& aClassName ) override;
404
405
// XStateChangeBroadcaster
406
    virtual void SAL_CALL addStateChangeListener( const css::uno::Reference< css::embed::XStateChangeListener >& xListener ) override;
407
    virtual void SAL_CALL removeStateChangeListener( const css::uno::Reference< css::embed::XStateChangeListener >& xListener ) override;
408
409
410
// XComponentSupplier
411
412
    virtual css::uno::Reference< css::util::XCloseable > SAL_CALL getComponent() override;
413
414
// XCloseable
415
416
    virtual void SAL_CALL close( sal_Bool DeliverOwnership ) override;
417
418
    virtual void SAL_CALL addCloseListener(
419
                const css::uno::Reference< css::util::XCloseListener >& Listener ) override;
420
421
    virtual void SAL_CALL removeCloseListener(
422
                const css::uno::Reference< css::util::XCloseListener >& Listener ) override;
423
424
// XEventBroadcaster
425
    virtual void SAL_CALL addEventListener(
426
                const css::uno::Reference< css::document::XEventListener >& Listener ) override;
427
428
    virtual void SAL_CALL removeEventListener(
429
                const css::uno::Reference< css::document::XEventListener >& Listener ) override;
430
431
// XInplaceObject ( only for wrapping scenario here )
432
433
    virtual void SAL_CALL setObjectRectangles( const css::awt::Rectangle& aPosRect,
434
                                          const css::awt::Rectangle& aClipRect ) override;
435
436
    virtual void SAL_CALL enableModeless( sal_Bool bEnable ) override;
437
438
    virtual void SAL_CALL translateAccelerators(
439
                    const css::uno::Sequence< css::awt::KeyEvent >& aKeys ) override;
440
441
    // XChild ( only for wrapping scenario here )
442
    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent(  ) override;
443
    virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override;
444
445
    // XActiveDataStreamer
446
    void SAL_CALL setStream(const css::uno::Reference<css::io::XStream>& xStream) override;
447
    css::uno::Reference<css::io::XStream> SAL_CALL getStream() override;
448
449
    // XInitialization
450
    void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override;
451
452
    // XServiceInfo
453
    OUString SAL_CALL getImplementationName() override;
454
    sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
455
    css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
456
457
private:
458
    css::awt::Size getVisualAreaSize_impl(sal_Int64 nAspect, osl::ResettableMutexGuard& guard);
459
};
460
461
namespace
462
{
463
#if defined(_WIN32)
464
template <class Proc> auto ExecUnlocked(Proc proc, osl::ResettableMutexGuard& guard)
465
{
466
    osl::ResettableMutexGuardScopedReleaser area(guard);
467
    return proc();
468
}
469
#endif
470
}
471
472
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */