Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/embeddedobj/source/general/docholder.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <com/sun/star/embed/Aspects.hpp>
21
#include <com/sun/star/frame/TaskCreator.hpp>
22
#include <com/sun/star/frame/XTitle.hpp>
23
#include <com/sun/star/frame/TerminationVetoException.hpp>
24
#include <com/sun/star/frame/XComponentLoader.hpp>
25
#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
26
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
27
#include <com/sun/star/lang/XSingleComponentFactory.hpp>
28
#include <com/sun/star/util/CloseVetoException.hpp>
29
#include <com/sun/star/util/XCloseBroadcaster.hpp>
30
#include <com/sun/star/util/XCloseable.hpp>
31
#include <com/sun/star/lang/XServiceInfo.hpp>
32
#include <com/sun/star/beans/XPropertySet.hpp>
33
#include <com/sun/star/beans/NamedValue.hpp>
34
#include <com/sun/star/frame/XModel.hpp>
35
#include <com/sun/star/frame/Desktop.hpp>
36
#include <com/sun/star/frame/XFramesSupplier.hpp>
37
#include <com/sun/star/frame/XControllerBorder.hpp>
38
#include <com/sun/star/util/XModifyBroadcaster.hpp>
39
#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
40
#include <com/sun/star/awt/Toolkit.hpp>
41
#include <com/sun/star/awt/XTopWindow.hpp>
42
#include <com/sun/star/awt/PosSize.hpp>
43
#include <com/sun/star/awt/WindowAttribute.hpp>
44
#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
45
#include <com/sun/star/embed/XHatchWindow.hpp>
46
#include <com/sun/star/embed/HatchWindowFactory.hpp>
47
#include <com/sun/star/frame/XLayoutManager.hpp>
48
#include <com/sun/star/frame/XMenuBarMergingAcceptor.hpp>
49
#include <com/sun/star/frame/ModuleManager.hpp>
50
#include <com/sun/star/ui/XDockingAreaAcceptor.hpp>
51
#include <com/sun/star/ui/XUIElementSettings.hpp>
52
#include <com/sun/star/ui/XUIConfigurationManager.hpp>
53
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
54
#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
55
#include <com/sun/star/embed/StateChangeInProgressException.hpp>
56
57
#include <com/sun/star/embed/EmbedMisc.hpp>
58
#include <com/sun/star/embed/EmbedStates.hpp>
59
#include <osl/diagnose.h>
60
#include <utility>
61
#include <tools/gen.hxx>
62
#include <vcl/svapp.hxx>
63
#include <unotools/resmgr.hxx>
64
#include <sfx2/strings.hrc>
65
66
#include <comphelper/processfactory.hxx>
67
#include <comphelper/namedvaluecollection.hxx>
68
69
#include <docholder.hxx>
70
#include <commonembobj.hxx>
71
#include <intercept.hxx>
72
73
using namespace ::com::sun::star;
74
75
namespace {
76
77
class IntCounterGuard
78
{
79
    sal_Int32& m_rFlag;
80
public:
81
    explicit IntCounterGuard(sal_Int32& rFlag)
82
0
        : m_rFlag(rFlag)
83
0
    {
84
0
        ++m_rFlag;
85
0
    }
86
87
    ~IntCounterGuard()
88
0
    {
89
0
        if (m_rFlag)
90
0
            --m_rFlag;
91
0
    }
92
};
93
94
}
95
96
static void InsertMenu_Impl( const uno::Reference< container::XIndexContainer >& xTargetMenu,
97
                            sal_Int32 nTargetIndex,
98
                            const uno::Reference< container::XIndexAccess >& xSourceMenu,
99
                            sal_Int32 nSourceIndex,
100
                            const OUString& aContModuleName,
101
                            const uno::Reference< frame::XDispatchProvider >& xSourceDisp )
102
0
{
103
0
    sal_Int32 nInd = 0;
104
0
    OUString aModuleIdentPropName( u"ModuleIdentifier"_ustr );
105
0
    OUString aDispProvPropName( u"DispatchProvider"_ustr );
106
0
    bool bModuleNameSet = false;
107
0
    bool bDispProvSet = false;
108
109
0
    uno::Sequence< beans::PropertyValue > aSourceProps;
110
0
    xSourceMenu->getByIndex( nSourceIndex ) >>= aSourceProps;
111
0
    uno::Sequence< beans::PropertyValue > aTargetProps( aSourceProps.getLength() );
112
0
    auto aTargetPropsRange = asNonConstRange(aTargetProps);
113
0
    for ( nInd = 0; nInd < aSourceProps.getLength(); nInd++ )
114
0
    {
115
0
        aTargetPropsRange[nInd].Name = aSourceProps[nInd].Name;
116
0
        if ( !aContModuleName.isEmpty() && aTargetProps[nInd].Name == aModuleIdentPropName )
117
0
        {
118
0
            aTargetPropsRange[nInd].Value <<= aContModuleName;
119
0
            bModuleNameSet = true;
120
0
        }
121
0
        else if ( aTargetProps[nInd].Name == aDispProvPropName )
122
0
        {
123
0
            aTargetPropsRange[nInd].Value <<= xSourceDisp;
124
0
            bDispProvSet = true;
125
0
        }
126
0
        else
127
0
            aTargetPropsRange[nInd].Value = aSourceProps[nInd].Value;
128
0
    }
129
130
0
    if ( !bModuleNameSet && !aContModuleName.isEmpty() )
131
0
    {
132
0
        aTargetProps.realloc( ++nInd );
133
0
        auto pTargetProps = aTargetProps.getArray();
134
0
        pTargetProps[nInd-1].Name = aModuleIdentPropName;
135
0
        pTargetProps[nInd-1].Value <<= aContModuleName;
136
0
    }
137
138
0
    if ( !bDispProvSet && xSourceDisp.is() )
139
0
    {
140
0
        aTargetProps.realloc( ++nInd );
141
0
        auto pTargetProps = aTargetProps.getArray();
142
0
        pTargetProps[nInd-1].Name = aDispProvPropName;
143
0
        pTargetProps[nInd-1].Value <<= xSourceDisp;
144
0
    }
145
146
0
    xTargetMenu->insertByIndex( nTargetIndex, uno::Any( aTargetProps ) );
147
0
}
148
149
namespace embeddedobj
150
{
151
152
DocumentHolder::DocumentHolder( uno::Reference< uno::XComponentContext > xContext,
153
                                OCommonEmbeddedObject& rEmbObj )
154
0
: m_rEmbedObj( rEmbObj ),
155
0
  m_xContext(std::move( xContext )),
156
0
  m_bReadOnly( false ),
157
0
  m_bWaitForClose( false ),
158
0
  m_bAllowClosing( false ),
159
0
  m_bDesktopTerminated( false ),
160
0
  m_nNoBorderResizeReact( 0 ),
161
0
  m_nNoResizeReact( 0 )
162
0
{
163
0
    uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext );
164
0
    osl_atomic_increment(&m_refCount);
165
0
    try
166
0
    {
167
0
        xDesktop->addTerminateListener( this );
168
0
    }
169
0
    catch ( const uno::Exception& )
170
0
    {
171
0
    }
172
0
    osl_atomic_decrement(&m_refCount);
173
174
0
    m_aOutplaceFrameProps = { uno::Any(beans::NamedValue{ u"TopWindow"_ustr, uno::Any(true) }),
175
0
                              uno::Any(beans::NamedValue{ u"MakeVisible"_ustr, uno::Any(false) }),
176
                              //TODO/LATER: should use parent document frame
177
0
                              uno::Any(beans::NamedValue{ u"ParentFrame"_ustr, uno::Any(xDesktop) }) };
178
0
}
179
180
181
DocumentHolder::~DocumentHolder()
182
0
{
183
0
    osl_atomic_increment(&m_refCount); // to allow deregistration as a listener
184
185
0
    if( m_xFrame.is() )
186
0
        CloseFrame();
187
188
0
    if ( m_xComponent.is() )
189
0
    {
190
0
        try {
191
0
            CloseDocument( true, false );
192
0
        } catch( const uno::Exception& ) {}
193
0
    }
194
195
0
    if ( m_xInterceptor.is() )
196
0
    {
197
0
        m_xInterceptor->DisconnectDocHolder();
198
0
        m_xInterceptor.clear();
199
0
    }
200
201
0
    if ( !m_bDesktopTerminated )
202
0
        FreeOffice();
203
0
}
204
205
206
void DocumentHolder::CloseFrame()
207
0
{
208
0
    uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
209
0
    if ( xCloseBroadcaster.is() )
210
0
        xCloseBroadcaster->removeCloseListener( static_cast<util::XCloseListener*>(this) );
211
212
0
    uno::Reference<util::XCloseable> xCloseable(
213
0
        m_xFrame,uno::UNO_QUERY );
214
0
    if( xCloseable.is() )
215
0
        try {
216
0
            xCloseable->close( true );
217
0
        }
218
0
        catch( const uno::Exception& ) {
219
0
        }
220
0
    else {
221
0
        if( m_xFrame.is() )
222
0
            m_xFrame->dispose();
223
0
    }
224
225
0
    if ( m_xHatchWindow.is() )
226
0
        m_xHatchWindow->dispose();
227
228
0
    m_xHatchWindow.clear();
229
0
    m_xOwnWindow.clear();
230
0
    m_xFrame.clear();
231
0
}
232
233
234
void DocumentHolder::FreeOffice()
235
0
{
236
0
    try {
237
0
        uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext );
238
0
        xDesktop->removeTerminateListener( this );
239
0
    } catch (const css::uno::DeploymentException&) {
240
        // if this happens, the desktop is already gone
241
0
    }
242
243
    // the following code is commented out since for now there is still no completely correct way to detect
244
    // whether the office can be terminated, so it is better to have unnecessary process running than
245
    // to lose any data
246
247
//      uno::Reference< frame::XFramesSupplier > xFramesSupplier( xDesktop, uno::UNO_QUERY );
248
//      if ( xFramesSupplier.is() )
249
//      {
250
//          uno::Reference< frame::XFrames > xFrames = xFramesSupplier->getFrames();
251
//          if ( xFrames.is() && !xFrames->hasElements() )
252
//          {
253
//              try
254
//              {
255
//                  xDesktop->terminate();
256
//              }
257
//              catch( uno::Exception & )
258
//              {}
259
//          }
260
//      }
261
0
}
262
263
264
void DocumentHolder::CloseDocument( bool bDeliverOwnership, bool bWaitForClose )
265
0
{
266
0
    if ( m_xComponent.is() )
267
0
    {
268
0
        uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY );
269
0
        if ( xEventBroadcaster.is() )
270
0
            xEventBroadcaster->removeEventListener( static_cast<document::XEventListener*>(this) );
271
0
        else
272
0
        {
273
            // the object does not support document::XEventBroadcaster interface
274
            // use the workaround, register for modified events
275
0
            uno::Reference< util::XModifyBroadcaster > xModifyBroadcaster( m_xComponent, uno::UNO_QUERY );
276
0
            if ( xModifyBroadcaster.is() )
277
0
                xModifyBroadcaster->removeModifyListener( static_cast<util::XModifyListener*>(this) );
278
0
        }
279
280
0
        m_bAllowClosing = true;
281
0
        m_bWaitForClose = bWaitForClose;
282
0
        m_xComponent->close( bDeliverOwnership );
283
0
    }
284
285
0
    m_xComponent = nullptr;
286
0
}
287
288
289
void DocumentHolder::PlaceFrame( const awt::Rectangle& aNewRect )
290
0
{
291
0
    OSL_ENSURE( m_xFrame.is() && m_xOwnWindow.is(),
292
0
                "The object does not have windows required for inplace mode!" );
293
294
    //TODO: may need mutex locking???
295
0
    if ( !(m_xFrame.is() && m_xOwnWindow.is()) )
296
0
        return;
297
298
    // the frame can be replaced only in inplace mode
299
0
    frame::BorderWidths aOldWidths;
300
0
    IntCounterGuard aGuard( m_nNoBorderResizeReact );
301
302
0
    do
303
0
    {
304
0
        aOldWidths = m_aBorderWidths;
305
306
0
        awt::Rectangle aHatchRect = AddBorderToArea( aNewRect );
307
308
0
        ResizeWindows_Impl( aHatchRect );
309
310
0
    } while ( aOldWidths.Left != m_aBorderWidths.Left
311
0
           || aOldWidths.Top != m_aBorderWidths.Top
312
0
           || aOldWidths.Right != m_aBorderWidths.Right
313
0
           || aOldWidths.Bottom != m_aBorderWidths.Bottom );
314
315
0
    m_aObjRect = aNewRect;
316
0
}
317
318
319
void DocumentHolder::ResizeWindows_Impl( const awt::Rectangle& aHatchRect )
320
0
{
321
0
    OSL_ENSURE( m_xFrame.is() && m_xOwnWindow.is() /*&& m_xHatchWindow.is()*/,
322
0
                "The object does not have windows required for inplace mode!" );
323
0
    sal_Int32 nHatchBorderWidth(getHatchBorderWidth());
324
0
    if ( m_xHatchWindow.is() )
325
0
    {
326
0
        m_xOwnWindow->setPosSize( nHatchBorderWidth,
327
0
                                  nHatchBorderWidth,
328
0
                                  aHatchRect.Width - 2*nHatchBorderWidth,
329
0
                                  aHatchRect.Height - 2*nHatchBorderWidth,
330
0
                                  awt::PosSize::POSSIZE );
331
332
333
0
        m_xHatchWindow->setPosSize( aHatchRect.X,
334
0
                                    aHatchRect.Y,
335
0
                                    aHatchRect.Width,
336
0
                                    aHatchRect.Height,
337
0
                                    awt::PosSize::POSSIZE );
338
0
    }
339
0
    else
340
0
        m_xOwnWindow->setPosSize( aHatchRect.X + nHatchBorderWidth,
341
0
                                  aHatchRect.Y + nHatchBorderWidth,
342
0
                                  aHatchRect.Width - 2*nHatchBorderWidth,
343
0
                                  aHatchRect.Height - 2*nHatchBorderWidth,
344
0
                                  awt::PosSize::POSSIZE );
345
0
}
346
347
348
bool DocumentHolder::SetFrameLMVisibility( const uno::Reference< frame::XFrame >& xFrame, bool bVisible )
349
0
{
350
0
    bool bResult = false;
351
352
0
    try
353
0
    {
354
0
        uno::Reference< css::frame::XLayoutManager > xLayoutManager;
355
0
        uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY_THROW );
356
0
        xPropSet->getPropertyValue(u"LayoutManager"_ustr) >>= xLayoutManager;
357
0
        if ( xLayoutManager.is() )
358
0
        {
359
0
            xLayoutManager->setVisible( bVisible );
360
361
            // MBA: locking is done only on the container LM, because it is not about hiding windows, it's about
362
            // giving up control over the component window (and stopping to listen for resize events of the container window)
363
0
            if ( bVisible )
364
0
                xLayoutManager->unlock();
365
0
            else
366
0
                xLayoutManager->lock();
367
368
0
            bResult = true;
369
0
        }
370
0
    }
371
0
    catch( const uno::Exception& )
372
0
    {}
373
374
0
    return bResult;
375
0
}
376
377
378
bool DocumentHolder::ShowInplace( const uno::Reference< awt::XWindowPeer >& xParent,
379
                                      const awt::Rectangle& aRectangleToShow,
380
                                      const uno::Reference< frame::XDispatchProvider >& xContDisp )
381
0
{
382
0
    OSL_ENSURE( !m_xFrame.is(), "A frame exists already!" );
383
384
0
    if ( !m_xFrame.is() )
385
0
    {
386
0
        uno::Reference < frame::XModel > xModel( GetComponent(), uno::UNO_QUERY );
387
0
        awt::Rectangle aHatchRectangle = AddBorderToArea( aRectangleToShow );
388
389
0
        sal_Int32 nHatchBorderWidth(getHatchBorderWidth());
390
0
        awt::Rectangle aOwnRectangle( nHatchBorderWidth,
391
0
                                    nHatchBorderWidth,
392
0
                                    aHatchRectangle.Width - 2*nHatchBorderWidth,
393
0
                                    aHatchRectangle.Height - 2*nHatchBorderWidth );
394
0
        uno::Reference< awt::XWindow > xHWindow;
395
0
        uno::Reference< awt::XWindowPeer > xMyParent( xParent );
396
397
0
        if ( xModel.is() )
398
0
        {
399
400
0
            uno::Reference< embed::XHatchWindowFactory > xHatchFactory =
401
0
                    embed::HatchWindowFactory::create(m_xContext);
402
403
0
            uno::Reference< embed::XHatchWindow > xHatchWindow =
404
0
                            xHatchFactory->createHatchWindowInstance( xParent,
405
0
                                                                      aHatchRectangle,
406
0
                                                                      awt::Size( nHatchBorderWidth, nHatchBorderWidth ) );
407
408
0
            uno::Reference< awt::XWindowPeer > xHatchWinPeer( xHatchWindow, uno::UNO_QUERY );
409
0
            xHWindow.set( xHatchWinPeer, uno::UNO_QUERY_THROW );
410
411
0
            xHatchWindow->setController( uno::Reference< embed::XHatchWindowController >(
412
0
                                                static_cast< embed::XHatchWindowController* >( this ) ) );
413
414
0
            xMyParent = std::move(xHatchWinPeer);
415
0
        }
416
0
        else
417
0
        {
418
0
            aOwnRectangle.X += aHatchRectangle.X;
419
0
            aOwnRectangle.Y += aHatchRectangle.Y;
420
0
        }
421
422
0
        awt::WindowDescriptor aOwnWinDescriptor( awt::WindowClass_TOP,
423
0
                                                u"dockingwindow"_ustr,
424
0
                                                xMyParent,
425
0
                                                0,
426
0
                                                awt::Rectangle(),//aOwnRectangle,
427
0
                                                awt::WindowAttribute::SHOW | awt::VclWindowPeerAttribute::CLIPCHILDREN );
428
429
0
        uno::Reference< awt::XToolkit2 > xToolkit = awt::Toolkit::create(m_xContext);
430
431
0
        uno::Reference< awt::XWindowPeer > xNewWinPeer = xToolkit->createWindow( aOwnWinDescriptor );
432
0
        uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer, uno::UNO_QUERY_THROW );
433
0
        uno::Reference< frame::XFrame > xContFrame( xContDisp, uno::UNO_QUERY );
434
435
        // create a frame based on the specified window
436
0
        uno::Reference< lang::XSingleServiceFactory > xFrameFact = frame::TaskCreator::create(m_xContext);
437
438
0
        uno::Sequence< uno::Any > aArgs( xContFrame.is() ? 2 : 1 );
439
0
        auto pArgs = aArgs.getArray();
440
0
        beans::NamedValue aArg;
441
442
0
        aArg.Name    = "ContainerWindow";
443
0
        aArg.Value <<= xOwnWindow;
444
0
        pArgs[0] <<= aArg;
445
446
0
        if ( xContFrame.is() )
447
0
        {
448
0
            aArg.Name    = "ParentFrame";
449
0
            aArg.Value <<= xContFrame;
450
0
            pArgs[1] <<= aArg;
451
0
        }
452
453
        // the call will create, initialize the frame, and register it in the parent
454
0
        m_xFrame.set( xFrameFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY_THROW );
455
456
0
        m_xHatchWindow = std::move(xHWindow);
457
0
        m_xOwnWindow = std::move(xOwnWindow);
458
459
0
        if ( !SetFrameLMVisibility( m_xFrame, false ) )
460
0
        {
461
0
            OSL_FAIL( "Can't deactivate LayoutManager!" );
462
            // TODO/LATER: error handling?
463
0
        }
464
465
        // m_bIsInplace = sal_True; TODO: ?
466
467
0
        uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
468
0
        if ( xCloseBroadcaster.is() )
469
0
            xCloseBroadcaster->addCloseListener( static_cast<util::XCloseListener*>(this) );
470
471
        // TODO: some listeners to the frame and the window ( resize for example )
472
0
    }
473
474
0
    if ( !m_xComponent )
475
0
        return false;
476
477
0
    if ( !LoadDocToFrame( true ) )
478
0
    {
479
0
        CloseFrame();
480
0
        return false;
481
0
    }
482
483
0
    uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY );
484
0
    if ( xControllerBorder.is() )
485
0
    {
486
0
        m_aBorderWidths = xControllerBorder->getBorder();
487
0
        xControllerBorder->addBorderResizeListener( static_cast<frame::XBorderResizeListener*>(this) );
488
0
    }
489
490
0
    PlaceFrame( aRectangleToShow );
491
492
0
    if ( m_xHatchWindow.is() )
493
0
        m_xHatchWindow->setVisible( true );
494
495
0
    return true;
496
0
}
497
498
499
uno::Reference< container::XIndexAccess > DocumentHolder::RetrieveOwnMenu_Impl()
500
0
{
501
0
    uno::Reference< container::XIndexAccess > xResult;
502
503
0
    uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUIConfSupplier(
504
0
                m_xComponent,
505
0
                uno::UNO_QUERY );
506
0
    uno::Reference< css::ui::XUIConfigurationManager > xUIConfigManager;
507
0
    if( xUIConfSupplier.is())
508
0
    {
509
0
        xUIConfigManager.set(
510
0
            xUIConfSupplier->getUIConfigurationManager(),
511
0
            uno::UNO_SET_THROW );
512
0
    }
513
514
0
    try
515
0
    {
516
0
        if( xUIConfigManager.is())
517
0
        {
518
0
            xResult = xUIConfigManager->getSettings(
519
0
                u"private:resource/menubar/menubar"_ustr,
520
0
                false );
521
0
        }
522
0
    }
523
0
    catch( const uno::Exception& )
524
0
    {}
525
526
0
    if ( !xResult.is() )
527
0
    {
528
        // no internal document configuration, use the one from the module
529
0
        uno::Reference< frame::XModuleManager2 > xModuleMan = frame::ModuleManager::create(m_xContext);
530
0
        OUString aModuleIdent =
531
0
            xModuleMan->identify( uno::Reference< uno::XInterface >( m_xComponent, uno::UNO_QUERY ) );
532
533
0
        if ( !aModuleIdent.isEmpty() )
534
0
        {
535
0
            uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModConfSupplier =
536
0
                    ui::theModuleUIConfigurationManagerSupplier::get(m_xContext);
537
0
            uno::Reference< css::ui::XUIConfigurationManager > xModUIConfMan(
538
0
                    xModConfSupplier->getUIConfigurationManager( aModuleIdent ),
539
0
                    uno::UNO_SET_THROW );
540
0
            xResult = xModUIConfMan->getSettings(
541
0
                    u"private:resource/menubar/menubar"_ustr,
542
0
                    false );
543
0
        }
544
0
    }
545
546
0
    if ( !xResult.is() )
547
0
        throw uno::RuntimeException(u"Unable to retrieve the UI configuration menu."_ustr, getXWeak());
548
549
0
    return xResult;
550
0
}
551
552
553
void DocumentHolder::FindConnectPoints(
554
        const uno::Reference< container::XIndexAccess >& xMenu,
555
        sal_Int32 nConnectPoints[2] )
556
0
{
557
0
    nConnectPoints[0] = -1;
558
0
    nConnectPoints[1] = -1;
559
0
    for ( sal_Int32 nInd = 0; nInd < xMenu->getCount(); nInd++ )
560
0
    {
561
0
        uno::Sequence< beans::PropertyValue > aProps;
562
0
        xMenu->getByIndex( nInd ) >>= aProps;
563
0
        OUString aCommand;
564
0
        for (beans::PropertyValue const& prop : aProps)
565
0
            if ( prop.Name == "CommandURL" )
566
0
            {
567
0
                prop.Value >>= aCommand;
568
0
                break;
569
0
            }
570
571
0
        if ( aCommand.isEmpty() )
572
0
            throw uno::RuntimeException("CommandURL is empty at index: " + OUString::number(nInd),  xMenu);
573
574
0
        if ( aCommand == ".uno:PickList" )
575
0
            nConnectPoints[0] = nInd;
576
0
        else if ( aCommand == ".uno:WindowList" )
577
0
            nConnectPoints[1] = nInd;
578
0
    }
579
0
}
580
581
582
uno::Reference< container::XIndexAccess > DocumentHolder::MergeMenusForInplace(
583
        const uno::Reference< container::XIndexAccess >& xContMenu,
584
        const uno::Reference< frame::XDispatchProvider >& xContDisp,
585
        const OUString& aContModuleName,
586
        const uno::Reference< container::XIndexAccess >& xOwnMenu,
587
        const uno::Reference< frame::XDispatchProvider >& xOwnDisp )
588
0
{
589
    // TODO/LATER: use dispatch providers on merge
590
591
0
    sal_Int32 nContPoints[2];
592
0
    sal_Int32 nOwnPoints[2];
593
594
0
    uno::Reference< lang::XSingleComponentFactory > xIndAccessFact( xContMenu, uno::UNO_QUERY_THROW );
595
596
0
    uno::Reference< container::XIndexContainer > xMergedMenu(
597
0
            xIndAccessFact->createInstanceWithContext(
598
0
                comphelper::getProcessComponentContext() ),
599
0
            uno::UNO_QUERY_THROW );
600
601
0
    FindConnectPoints( xContMenu, nContPoints );
602
0
    FindConnectPoints( xOwnMenu, nOwnPoints );
603
604
0
    for ( sal_Int32 nInd = 0; nInd < xOwnMenu->getCount(); nInd++ )
605
0
    {
606
0
        if ( nOwnPoints[0] == nInd )
607
0
        {
608
0
            if ( nContPoints[0] >= 0 && nContPoints[0] < xContMenu->getCount() )
609
0
            {
610
0
                InsertMenu_Impl( xMergedMenu, nInd, xContMenu, nContPoints[0], aContModuleName, xContDisp );
611
0
            }
612
0
        }
613
0
        else if ( nOwnPoints[1] == nInd )
614
0
        {
615
0
            if ( nContPoints[1] >= 0 && nContPoints[1] < xContMenu->getCount() )
616
0
            {
617
0
                InsertMenu_Impl( xMergedMenu, nInd, xContMenu, nContPoints[1], aContModuleName, xContDisp );
618
0
            }
619
0
        }
620
0
        else
621
0
            InsertMenu_Impl( xMergedMenu, nInd, xOwnMenu, nInd, OUString(), xOwnDisp );
622
0
    }
623
624
0
    return uno::Reference< container::XIndexAccess >( xMergedMenu, uno::UNO_QUERY_THROW );
625
0
}
626
627
628
bool DocumentHolder::MergeMenus_Impl( const uno::Reference< css::frame::XLayoutManager >& xOwnLM,
629
                                            const uno::Reference< css::frame::XLayoutManager >& xContLM,
630
                                            const uno::Reference< frame::XDispatchProvider >& xContDisp,
631
                                            const OUString& aContModuleName )
632
0
{
633
0
    bool bMenuMerged = false;
634
0
    try
635
0
    {
636
0
        uno::Reference< css::ui::XUIElementSettings > xUISettings(
637
0
            xContLM->getElement( u"private:resource/menubar/menubar"_ustr ),
638
0
            uno::UNO_QUERY_THROW );
639
0
        uno::Reference< container::XIndexAccess > xContMenu = xUISettings->getSettings( true );
640
0
        if ( !xContMenu.is() )
641
0
            throw uno::RuntimeException(u"Unable to merge the menu"_ustr, getXWeak());
642
643
0
        uno::Reference< container::XIndexAccess > xOwnMenu = RetrieveOwnMenu_Impl();
644
0
        uno::Reference< frame::XDispatchProvider > xOwnDisp( m_xFrame, uno::UNO_QUERY_THROW );
645
646
0
        uno::Reference< container::XIndexAccess > xMergedMenu = MergeMenusForInplace( xContMenu, xContDisp, aContModuleName, xOwnMenu, xOwnDisp );
647
0
        uno::Reference< css::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM,
648
0
                                                                                         uno::UNO_QUERY_THROW );
649
0
        bMenuMerged = xMerge->setMergedMenuBar( xMergedMenu );
650
0
    }
651
0
    catch( const uno::Exception& )
652
0
    {}
653
654
0
    return bMenuMerged;
655
0
}
656
657
bool DocumentHolder::ShowUI( const uno::Reference< css::frame::XLayoutManager >& xContainerLM,
658
                                 const uno::Reference< frame::XDispatchProvider >& xContainerDP,
659
                                 const OUString& aContModuleName )
660
0
{
661
0
    bool bResult = false;
662
0
    if ( xContainerLM.is() )
663
0
    {
664
        // the LM of the embedded frame and its current DockingAreaAcceptor
665
0
        uno::Reference< css::frame::XLayoutManager > xOwnLM;
666
0
        uno::Reference< css::ui::XDockingAreaAcceptor > xDocAreaAcc;
667
668
0
        try
669
0
        {
670
0
            uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
671
0
            xPropSet->getPropertyValue(u"LayoutManager"_ustr) >>= xOwnLM;
672
0
            xDocAreaAcc = xContainerLM->getDockingAreaAcceptor();
673
0
        }
674
0
        catch( const uno::Exception& ){}
675
676
0
        if ( xOwnLM.is() && xDocAreaAcc.is() )
677
0
        {
678
            // make sure that lock state of LM is correct even if an exception is thrown in between
679
0
            bool bUnlockContainerLM = false;
680
0
            bool bLockOwnLM = false;
681
0
            try
682
0
            {
683
                // take over the control over the containers window
684
                // as long as the LM is invisible and locked an empty tool space will be used on resizing
685
0
                xOwnLM->setDockingAreaAcceptor( xDocAreaAcc );
686
687
                // try to merge menus; don't do anything else if it fails
688
0
                if ( MergeMenus_Impl( xOwnLM, xContainerLM, xContainerDP, aContModuleName ) )
689
0
                {
690
                    // make sure that the container LM does not control the size of the containers window anymore
691
                    // this must be done after merging menus as we won't get the container menu otherwise
692
0
                    xContainerLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() );
693
694
0
                    uno::Reference< lang::XServiceInfo> xServiceInfo(m_xComponent, uno::UNO_QUERY);
695
0
                    if (!xServiceInfo.is() || !xServiceInfo->supportsService(u"com.sun.star.chart2.ChartDocument"_ustr))
696
0
                    {
697
                        // prevent further changes at this LM
698
0
                        xContainerLM->setVisible(false);
699
0
                        xContainerLM->lock();
700
0
                        bUnlockContainerLM = true;
701
0
                    }
702
703
                    // by unlocking the LM each layout change will now resize the containers window; pending layouts will be processed now
704
0
                    xOwnLM->setVisible( true );
705
706
0
                    uno::Reference< frame::XFramesSupplier > xSupp = m_xFrame->getCreator();
707
0
                    if ( xSupp.is() )
708
0
                        xSupp->setActiveFrame( m_xFrame );
709
710
0
                    xOwnLM->unlock();
711
0
                    bLockOwnLM = true;
712
0
                    bResult = true;
713
714
                    // TODO/LATER: The following action should be done only if the window is not hidden
715
                    // otherwise the activation must fail, unfortunately currently it is not possible
716
                    // to detect whether the window is hidden using UNO API
717
0
                    m_xOwnWindow->setFocus();
718
0
                }
719
0
            }
720
0
            catch( const uno::Exception& )
721
0
            {
722
                // activation failed; reestablish old state
723
0
                try
724
0
                {
725
0
                    uno::Reference< frame::XFramesSupplier > xSupp = m_xFrame->getCreator();
726
0
                    if ( xSupp.is() )
727
0
                        xSupp->setActiveFrame( nullptr );
728
729
                    // remove control about containers window from own LM
730
0
                    if (bLockOwnLM)
731
0
                        xOwnLM->lock();
732
0
                    xOwnLM->setVisible( false );
733
0
                    xOwnLM->setDockingAreaAcceptor( uno::Reference< css::ui::XDockingAreaAcceptor >() );
734
735
                    // unmerge menu
736
0
                    uno::Reference< css::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW );
737
0
                    xMerge->removeMergedMenuBar();
738
0
                }
739
0
                catch( const uno::Exception& ) {}
740
741
0
                try
742
0
                {
743
                    // reestablish control of containers window
744
0
                    xContainerLM->setDockingAreaAcceptor( xDocAreaAcc );
745
0
                    xContainerLM->setVisible( true );
746
0
                    if (bUnlockContainerLM)
747
0
                        xContainerLM->unlock();
748
0
                }
749
0
                catch( const uno::Exception& ) {}
750
0
            }
751
0
        }
752
0
    }
753
754
0
    return bResult;
755
0
}
756
757
758
bool DocumentHolder::HideUI( const uno::Reference< css::frame::XLayoutManager >& xContainerLM )
759
0
{
760
0
    bool bResult = false;
761
762
0
    if ( xContainerLM.is() )
763
0
    {
764
0
        uno::Reference< css::frame::XLayoutManager > xOwnLM;
765
766
0
        try {
767
0
            uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
768
0
            xPropSet->getPropertyValue(u"LayoutManager"_ustr) >>= xOwnLM;
769
0
        } catch( const uno::Exception& )
770
0
        {}
771
772
0
        if ( xOwnLM.is() )
773
0
        {
774
0
            try {
775
0
                uno::Reference< frame::XFramesSupplier > xSupp = m_xFrame->getCreator();
776
0
                if ( xSupp.is() )
777
0
                    xSupp->setActiveFrame( nullptr );
778
779
0
                uno::Reference< css::ui::XDockingAreaAcceptor > xDocAreaAcc = xOwnLM->getDockingAreaAcceptor();
780
781
0
                xOwnLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() );
782
0
                xOwnLM->lock();
783
0
                xOwnLM->setVisible( false );
784
785
0
                uno::Reference< css::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW );
786
0
                xMerge->removeMergedMenuBar();
787
788
0
                xContainerLM->setDockingAreaAcceptor( xDocAreaAcc );
789
0
                uno::Reference< lang::XServiceInfo> xServiceInfo(m_xComponent, uno::UNO_QUERY);
790
0
                if (!xServiceInfo.is() || !xServiceInfo->supportsService(u"com.sun.star.chart2.ChartDocument"_ustr))
791
0
                {
792
0
                    xContainerLM->setVisible(true);
793
0
                    xContainerLM->unlock();
794
0
                }
795
796
0
                xContainerLM->doLayout();
797
0
                bResult = true;
798
0
            }
799
0
            catch( const uno::Exception& )
800
0
            {
801
0
                SetFrameLMVisibility( m_xFrame, true );
802
0
            }
803
0
        }
804
0
    }
805
806
0
    return bResult;
807
0
}
808
809
810
uno::Reference< frame::XFrame > const & DocumentHolder::GetDocFrame()
811
0
{
812
    // the frame for outplace activation
813
0
    if ( !m_xFrame.is() )
814
0
    {
815
0
        uno::Reference< lang::XSingleServiceFactory > xFrameFact = frame::TaskCreator::create(m_xContext);
816
817
0
        m_xFrame.set(xFrameFact->createInstanceWithArguments( m_aOutplaceFrameProps ), uno::UNO_QUERY_THROW);
818
819
0
        uno::Reference< frame::XDispatchProviderInterception > xInterception( m_xFrame, uno::UNO_QUERY );
820
0
        if ( xInterception.is() )
821
0
        {
822
0
            if ( m_xInterceptor.is() )
823
0
            {
824
0
                m_xInterceptor->DisconnectDocHolder();
825
0
                m_xInterceptor.clear();
826
0
            }
827
828
0
            m_xInterceptor = new Interceptor( this );
829
830
0
            xInterception->registerDispatchProviderInterceptor( m_xInterceptor );
831
832
            // register interceptor from outside
833
0
            if ( m_xOutplaceInterceptor.is() )
834
0
                xInterception->registerDispatchProviderInterceptor( m_xOutplaceInterceptor );
835
0
        }
836
837
0
        uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
838
0
        if ( xCloseBroadcaster.is() )
839
0
            xCloseBroadcaster->addCloseListener( static_cast<util::XCloseListener*>(this) );
840
0
    }
841
842
0
    if ( m_xComponent.is() )
843
0
    {
844
0
        uno::Reference< css::frame::XLayoutManager > xOwnLM;
845
0
        try {
846
0
            uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
847
0
            xPropSet->getPropertyValue(u"LayoutManager"_ustr) >>= xOwnLM;
848
0
        } catch( const uno::Exception& )
849
0
        {}
850
851
0
        if ( xOwnLM.is() )
852
0
            xOwnLM->lock();
853
854
        // TODO/LATER: get it for the real aspect
855
0
        awt::Size aSize;
856
0
        LoadDocToFrame(false);
857
858
0
        if ( xOwnLM.is() )
859
0
        {
860
0
            xOwnLM->unlock();
861
0
            xOwnLM->lock();
862
0
        }
863
864
0
        GetExtent(embed::Aspects::MSOLE_CONTENT, &aSize);
865
0
        SetExtent(embed::Aspects::MSOLE_CONTENT, aSize);
866
867
0
        if ( xOwnLM.is() )
868
0
            xOwnLM->unlock();
869
0
    }
870
871
0
    try
872
0
    {
873
0
        uno::Reference< awt::XWindow > xHWindow = m_xFrame->getContainerWindow();
874
875
0
        if( xHWindow.is() )
876
0
        {
877
0
            sal_Int32 nDisplay = Application::GetDisplayBuiltInScreen();
878
879
0
            AbsoluteScreenPixelRectangle aWorkRect = Application::GetScreenPosSizePixel( nDisplay );
880
0
            awt::Rectangle aWindowRect = xHWindow->getPosSize();
881
882
0
            if (( aWindowRect.Width < aWorkRect.GetWidth()) && ( aWindowRect.Height < aWorkRect.GetHeight() ))
883
0
            {
884
0
                int OffsetX = ( aWorkRect.GetWidth() - aWindowRect.Width ) / 2 + aWorkRect.Left();
885
0
                int OffsetY = ( aWorkRect.GetHeight() - aWindowRect.Height ) /2 + aWorkRect.Top();
886
0
                xHWindow->setPosSize( OffsetX, OffsetY, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POS );
887
0
            }
888
0
            else
889
0
            {
890
0
                xHWindow->setPosSize( aWorkRect.Left(), aWorkRect.Top(), aWorkRect.GetWidth(), aWorkRect.GetHeight(), awt::PosSize::POSSIZE );
891
0
            }
892
893
0
            xHWindow->setVisible( true );
894
0
        }
895
0
    }
896
0
    catch ( const uno::Exception& )
897
0
    {
898
0
    }
899
900
0
    return m_xFrame;
901
0
}
902
903
904
void DocumentHolder::SetComponent( const uno::Reference< util::XCloseable >& xDoc, bool bReadOnly )
905
0
{
906
0
    if ( m_xComponent.is() )
907
0
    {
908
        // May be should be improved
909
0
        try {
910
0
            CloseDocument( true, false );
911
0
        } catch( const uno::Exception& )
912
0
        {}
913
0
    }
914
915
0
    m_xComponent = xDoc;
916
917
0
    m_bReadOnly = bReadOnly;
918
0
    m_bAllowClosing = false;
919
920
0
    if ( m_xComponent.is() )
921
0
        m_xComponent->addCloseListener( static_cast<util::XCloseListener*>(this) );
922
923
0
    uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY );
924
0
    if ( xEventBroadcaster.is() )
925
0
        xEventBroadcaster->addEventListener( static_cast<document::XEventListener*>(this) );
926
0
    else
927
0
    {
928
        // the object does not support document::XEventBroadcaster interface
929
        // use the workaround, register for modified events
930
0
        uno::Reference< util::XModifyBroadcaster > xModifyBroadcaster( m_xComponent, uno::UNO_QUERY );
931
0
        if ( xModifyBroadcaster.is() )
932
0
            xModifyBroadcaster->addModifyListener( static_cast<util::XModifyListener*>(this) );
933
0
    }
934
935
0
    if ( m_xFrame.is() )
936
0
        LoadDocToFrame(false);
937
0
}
938
939
940
bool DocumentHolder::LoadDocToFrame( bool bInPlace )
941
0
{
942
0
    if ( !m_xFrame || !m_xComponent )
943
0
        return true;
944
945
0
    uno::Reference < frame::XModel > xDoc( m_xComponent, uno::UNO_QUERY );
946
0
    if ( xDoc.is() )
947
0
    {
948
        // load new document into the frame
949
0
        uno::Reference< frame::XComponentLoader > xComponentLoader( m_xFrame, uno::UNO_QUERY_THROW );
950
951
0
        ::comphelper::NamedValueCollection aArgs;
952
0
        aArgs.put( u"Model"_ustr, m_xComponent );
953
0
        aArgs.put( u"ReadOnly"_ustr, m_bReadOnly );
954
955
        // set document title to show in the title bar
956
0
        css::uno::Reference< css::frame::XTitle > xModelTitle( xDoc, css::uno::UNO_QUERY );
957
0
        if( xModelTitle.is() && !m_rEmbedObj.getContainerName().isEmpty() )
958
0
        {
959
0
            std::locale aResLoc = Translate::Create("sfx");
960
0
            OUString sEmbedded = Translate::get(STR_EMBEDDED_TITLE, aResLoc);
961
0
            xModelTitle->setTitle( m_rEmbedObj.getContainerName() + sEmbedded );
962
0
            m_aContainerName = m_rEmbedObj.getContainerName();
963
            // TODO: get real m_aDocumentNamePart
964
0
            m_aDocumentNamePart = sEmbedded;
965
0
        }
966
967
0
        if ( bInPlace )
968
0
            aArgs.put( u"PluginMode"_ustr, sal_Int16(1) );
969
0
        OUString sUrl;
970
0
        uno::Reference< lang::XServiceInfo> xServiceInfo(xDoc,uno::UNO_QUERY);
971
0
        if (    xServiceInfo.is()
972
0
            &&  xServiceInfo->supportsService(u"com.sun.star.report.ReportDefinition"_ustr) )
973
0
        {
974
0
            sUrl = ".component:DB/ReportDesign";
975
0
        }
976
0
        else if( xServiceInfo.is()
977
0
            &&   xServiceInfo->supportsService(u"com.sun.star.chart2.ChartDocument"_ustr))
978
0
            sUrl = "private:factory/schart";
979
0
        else
980
0
            sUrl = "private:object";
981
982
0
        xComponentLoader->loadComponentFromURL( sUrl,
983
0
                                                    u"_self"_ustr,
984
0
                                                    0,
985
0
                                                    aArgs.getPropertyValues() );
986
987
0
        return true;
988
0
    }
989
0
    else
990
0
    {
991
0
        uno::Reference < frame::XSynchronousFrameLoader > xLoader( m_xComponent, uno::UNO_QUERY );
992
0
        if ( xLoader.is() )
993
0
            return xLoader->load( uno::Sequence < beans::PropertyValue >(), m_xFrame );
994
0
        else
995
0
            return false;
996
0
    }
997
998
0
    return true;
999
0
}
1000
1001
1002
void DocumentHolder::Show()
1003
0
{
1004
0
    if( m_xFrame.is() )
1005
0
    {
1006
0
        m_xFrame->activate();
1007
0
        uno::Reference<awt::XTopWindow> xTopWindow( m_xFrame->getContainerWindow(), uno::UNO_QUERY );
1008
0
        if( xTopWindow.is() )
1009
0
            xTopWindow->toFront();
1010
0
    }
1011
0
    else
1012
0
        GetDocFrame();
1013
0
}
1014
1015
1016
bool DocumentHolder::SetExtent( sal_Int64 nAspect, const awt::Size& aSize )
1017
0
{
1018
0
    uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY );
1019
0
    if ( xDocVis.is() )
1020
0
    {
1021
0
        try
1022
0
        {
1023
0
            xDocVis->setVisualAreaSize( nAspect, aSize );
1024
0
            return true;
1025
0
        }
1026
0
        catch( const uno::Exception& )
1027
0
        {
1028
            // TODO: Error handling
1029
0
        }
1030
0
    }
1031
1032
0
    return false;
1033
0
}
1034
1035
1036
bool DocumentHolder::GetExtent( sal_Int64 nAspect, awt::Size *pSize )
1037
0
{
1038
0
    uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY );
1039
0
    if ( pSize && xDocVis.is() )
1040
0
    {
1041
0
        try
1042
0
        {
1043
0
            *pSize = xDocVis->getVisualAreaSize( nAspect );
1044
0
            return true;
1045
0
        }
1046
0
        catch( const uno::Exception& )
1047
0
        {
1048
            // TODO: Error handling
1049
0
        }
1050
0
    }
1051
1052
0
    return false;
1053
0
}
1054
1055
1056
sal_Int32 DocumentHolder::GetMapUnit( sal_Int64 nAspect )
1057
0
{
1058
0
    uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY );
1059
0
    if ( xDocVis.is() )
1060
0
    {
1061
0
        try
1062
0
        {
1063
0
            return xDocVis->getMapUnit( nAspect );
1064
0
        }
1065
0
        catch( const uno::Exception& )
1066
0
        {
1067
            // TODO: Error handling
1068
0
        }
1069
0
    }
1070
1071
0
    return 0;
1072
0
}
1073
1074
1075
awt::Rectangle DocumentHolder::CalculateBorderedArea( const awt::Rectangle& aRect )
1076
0
{
1077
0
    sal_Int32 nHatchBorderWidth(getHatchBorderWidth());
1078
0
    return awt::Rectangle( aRect.X + m_aBorderWidths.Left + nHatchBorderWidth,
1079
0
                             aRect.Y + m_aBorderWidths.Top + nHatchBorderWidth,
1080
0
                             aRect.Width - m_aBorderWidths.Left - m_aBorderWidths.Right - 2*nHatchBorderWidth,
1081
0
                             aRect.Height - m_aBorderWidths.Top - m_aBorderWidths.Bottom - 2*nHatchBorderWidth );
1082
0
}
1083
1084
1085
awt::Rectangle DocumentHolder::AddBorderToArea( const awt::Rectangle& aRect )
1086
0
{
1087
0
    sal_Int32 nHatchBorderWidth(getHatchBorderWidth());
1088
0
    return awt::Rectangle( aRect.X - m_aBorderWidths.Left - nHatchBorderWidth,
1089
0
                             aRect.Y - m_aBorderWidths.Top - nHatchBorderWidth,
1090
0
                             aRect.Width + m_aBorderWidths.Left + m_aBorderWidths.Right + 2*nHatchBorderWidth,
1091
0
                             aRect.Height + m_aBorderWidths.Top + m_aBorderWidths.Bottom + 2*nHatchBorderWidth );
1092
0
}
1093
1094
1095
void SAL_CALL DocumentHolder::disposing( const css::lang::EventObject& aSource )
1096
0
{
1097
0
    if ( m_xComponent.is() && m_xComponent == aSource.Source )
1098
0
    {
1099
0
        m_xComponent = nullptr;
1100
0
        if ( m_bWaitForClose )
1101
0
        {
1102
0
            m_bWaitForClose = false;
1103
0
            FreeOffice();
1104
0
        }
1105
0
    }
1106
1107
0
    if( m_xFrame.is() && m_xFrame == aSource.Source )
1108
0
    {
1109
0
        m_xHatchWindow.clear();
1110
0
        m_xOwnWindow.clear();
1111
0
        m_xFrame.clear();
1112
0
    }
1113
0
}
1114
1115
1116
void SAL_CALL DocumentHolder::queryClosing( const lang::EventObject& aSource, sal_Bool /*bGetsOwnership*/ )
1117
0
{
1118
0
    if ( m_xComponent.is() && m_xComponent == aSource.Source && !m_bAllowClosing )
1119
0
        throw util::CloseVetoException(u"To close an embedded document, close the document holder (document definition), not the document itself."_ustr, static_cast< ::cppu::OWeakObject*>(this));
1120
0
}
1121
1122
1123
void SAL_CALL DocumentHolder::notifyClosing( const lang::EventObject& aSource )
1124
0
{
1125
0
    if ( m_xComponent.is() && m_xComponent == aSource.Source )
1126
0
    {
1127
0
        m_xComponent = nullptr;
1128
0
        if ( m_bWaitForClose )
1129
0
        {
1130
0
            m_bWaitForClose = false;
1131
0
            FreeOffice();
1132
0
        }
1133
0
    }
1134
1135
0
    if( m_xFrame.is() && m_xFrame == aSource.Source )
1136
0
    {
1137
0
        m_xHatchWindow.clear();
1138
0
        m_xOwnWindow.clear();
1139
0
        m_xFrame.clear();
1140
0
    }
1141
0
}
1142
1143
1144
void SAL_CALL DocumentHolder::queryTermination( const lang::EventObject& )
1145
0
{
1146
0
    if ( m_bWaitForClose )
1147
0
        throw frame::TerminationVetoException();
1148
0
}
1149
1150
1151
void SAL_CALL DocumentHolder::notifyTermination( const lang::EventObject& aSource )
1152
0
{
1153
0
    OSL_ENSURE( !m_xComponent.is(), "Just a disaster..." );
1154
1155
0
    uno::Reference< frame::XDesktop > xDesktop( aSource.Source, uno::UNO_QUERY );
1156
0
    m_bDesktopTerminated = true;
1157
0
    if ( xDesktop.is() )
1158
0
        xDesktop->removeTerminateListener( static_cast<frame::XTerminateListener*>(this) );
1159
0
}
1160
1161
1162
void SAL_CALL DocumentHolder::modified( const lang::EventObject& aEvent )
1163
0
{
1164
    // if the component does not support document::XEventBroadcaster
1165
    // the modify notifications are used as workaround, but only for running state
1166
0
    if( aEvent.Source == m_xComponent && m_rEmbedObj.getCurrentState() == embed::EmbedStates::RUNNING )
1167
0
        m_rEmbedObj.PostEvent_Impl( u"OnVisAreaChanged"_ustr );
1168
0
}
1169
1170
1171
void SAL_CALL DocumentHolder::notifyEvent( const document::EventObject& Event )
1172
0
{
1173
0
    if( Event.Source == m_xComponent )
1174
0
    {
1175
        // for now the ignored events are not forwarded, but sent by the object itself
1176
0
        if ( !Event.EventName.startsWith( "OnSave" )
1177
0
          && !Event.EventName.startsWith( "OnSaveDone" )
1178
0
          && !Event.EventName.startsWith( "OnSaveAs" )
1179
0
          && !Event.EventName.startsWith( "OnSaveAsDone" )
1180
0
          && !( Event.EventName.startsWith( "OnVisAreaChanged" ) && m_nNoResizeReact ) )
1181
0
            m_rEmbedObj.PostEvent_Impl( Event.EventName );
1182
0
    }
1183
0
}
1184
1185
1186
void SAL_CALL DocumentHolder::borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject,
1187
                                                    const frame::BorderWidths& aNewSize )
1188
0
{
1189
    // TODO: may require mutex introduction ???
1190
0
    if ( m_xFrame.is() && aObject == m_xFrame->getController() )
1191
0
    {
1192
0
        if ( m_aBorderWidths.Left != aNewSize.Left
1193
0
          || m_aBorderWidths.Right != aNewSize.Right
1194
0
          || m_aBorderWidths.Top != aNewSize.Top
1195
0
          || m_aBorderWidths.Bottom != aNewSize.Bottom )
1196
0
        {
1197
0
            m_aBorderWidths = aNewSize;
1198
0
            if ( !m_nNoBorderResizeReact )
1199
0
                PlaceFrame( m_aObjRect );
1200
0
        }
1201
0
    }
1202
0
}
1203
1204
1205
void SAL_CALL DocumentHolder::requestPositioning( const awt::Rectangle& aRect )
1206
0
{
1207
    // TODO: may require mutex introduction ???
1208
    // borders should not be counted
1209
0
    awt::Rectangle aObjRect = CalculateBorderedArea( aRect );
1210
0
    IntCounterGuard aGuard( m_nNoResizeReact );
1211
0
    m_rEmbedObj.requestPositioning( aObjRect );
1212
0
}
1213
1214
1215
awt::Rectangle SAL_CALL DocumentHolder::calcAdjustedRectangle( const awt::Rectangle& aRect )
1216
0
{
1217
    // Solar mutex should be locked already since this is a call from HatchWindow with focus
1218
0
    awt::Rectangle aResult( aRect );
1219
1220
0
    if ( m_xFrame.is() )
1221
0
    {
1222
        // borders should not be counted
1223
0
        uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY );
1224
0
        if ( xControllerBorder.is() )
1225
0
        {
1226
0
            awt::Rectangle aObjRect = CalculateBorderedArea( aRect );
1227
0
            aObjRect = xControllerBorder->queryBorderedArea( aObjRect );
1228
0
            aResult = AddBorderToArea( aObjRect );
1229
0
        }
1230
0
    }
1231
1232
0
    awt::Rectangle aMinRectangle = AddBorderToArea( awt::Rectangle() );
1233
0
    if ( aResult.Width < aMinRectangle.Width + 2 )
1234
0
        aResult.Width = aMinRectangle.Width + 2;
1235
0
    if ( aResult.Height < aMinRectangle.Height + 2 )
1236
0
        aResult.Height = aMinRectangle.Height + 2;
1237
1238
0
    return aResult;
1239
0
}
1240
1241
void SAL_CALL DocumentHolder::activated(  )
1242
0
{
1243
0
    if ( !(m_rEmbedObj.getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) )
1244
0
        return;
1245
1246
0
    if ( m_rEmbedObj.getCurrentState() != embed::EmbedStates::UI_ACTIVE &&
1247
0
    !(m_rEmbedObj.getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_NOUIACTIVATE) )
1248
0
    {
1249
0
        try
1250
0
        {
1251
0
            m_rEmbedObj.changeState( embed::EmbedStates::UI_ACTIVE );
1252
0
        }
1253
0
        catch ( const css::embed::StateChangeInProgressException& )
1254
0
        {
1255
            // must catch this exception because focus is grabbed while UI activation in doVerb()
1256
0
        }
1257
0
        catch ( const css::uno::Exception& )
1258
0
        {
1259
            // no outgoing exceptions specified here
1260
0
        }
1261
0
    }
1262
0
    else
1263
0
    {
1264
0
        uno::Reference< frame::XFramesSupplier > xSupp = m_xFrame->getCreator();
1265
0
        if ( xSupp.is() )
1266
0
            xSupp->setActiveFrame( m_xFrame );
1267
0
    }
1268
0
}
1269
1270
void DocumentHolder::ResizeHatchWindow()
1271
0
{
1272
0
    awt::Rectangle aHatchRect = AddBorderToArea( m_aObjRect );
1273
0
    ResizeWindows_Impl( aHatchRect );
1274
0
    uno::Reference< embed::XHatchWindow > xHatchWindow( m_xHatchWindow, uno::UNO_QUERY );
1275
0
    sal_Int32 nHatchBorderWidth(getHatchBorderWidth());
1276
0
    xHatchWindow->setHatchBorderSize( awt::Size( nHatchBorderWidth, nHatchBorderWidth ) );
1277
0
}
1278
1279
sal_Int32 DocumentHolder::getHatchBorderWidth()
1280
0
{
1281
0
    return m_rEmbedObj.getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE && \
1282
0
                            m_rEmbedObj.getCurrentState() != embed::EmbedStates::UI_ACTIVE ? 0 : 4;
1283
0
}
1284
1285
void SAL_CALL DocumentHolder::deactivated(  )
1286
0
{
1287
    // deactivation is too unspecific to be useful; usually we only trigger code from activation
1288
    // so UIDeactivation is actively triggered by the container
1289
0
}
1290
1291
} // namespace embeddedobj
1292
1293
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */