Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/unoidl/DrawController.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 <DrawController.hxx>
21
22
#include <sdpage.hxx>
23
#include <ViewShell.hxx>
24
#include <ViewShellBase.hxx>
25
#include <ViewShellManager.hxx>
26
#include <FormShellManager.hxx>
27
#include <Window.hxx>
28
#include <ResourceId.hxx>
29
#include <framework/ConfigurationController.hxx>
30
#include <framework/ModuleController.hxx>
31
32
#include <comphelper/processfactory.hxx>
33
#include <comphelper/sequence.hxx>
34
#include <comphelper/servicehelper.hxx>
35
#include <cppuhelper/supportsservice.hxx>
36
#include <cppuhelper/typeprovider.hxx>
37
38
#include <com/sun/star/beans/PropertyAttribute.hpp>
39
#include <com/sun/star/drawing/XDrawSubController.hpp>
40
#include <com/sun/star/drawing/XLayer.hpp>
41
42
#include <slideshow.hxx>
43
44
#include <sal/log.hxx>
45
#include <svx/fmshell.hxx>
46
#include <vcl/svapp.hxx>
47
#include <vcl/EnumContext.hxx>
48
#include <svx/sidebar/ContextChangeEventMultiplexer.hxx>
49
#include <comphelper/diagnose_ex.hxx>
50
51
#include <memory>
52
53
using namespace ::cppu;
54
using namespace ::com::sun::star;
55
using namespace ::com::sun::star::uno;
56
using namespace ::com::sun::star::drawing::framework;
57
using vcl::EnumContext;
58
59
namespace sd {
60
61
DrawController::DrawController (ViewShellBase& rBase) noexcept
62
0
    : DrawControllerInterfaceBase(&rBase),
63
0
      BroadcastHelperOwner(SfxBaseController::m_aMutex),
64
0
      OPropertySetHelper(BroadcastHelperOwner::maBroadcastHelper),
65
0
      m_aSelectionTypeIdentifier(
66
0
        cppu::UnoType<view::XSelectionChangeListener>::get()),
67
0
      mpBase(&rBase),
68
0
      mpCurrentPage(nullptr),
69
0
      mbMasterPageMode(false),
70
0
      mbLayerMode(false),
71
0
      mbDisposing(false)
72
0
{
73
0
    SolarMutexGuard aGuard;
74
0
    try
75
0
    {
76
0
        mxConfigurationController = new sd::framework::ConfigurationController(this);
77
0
        mxModuleController = new sd::framework::ModuleController(this);
78
0
    }
79
0
    catch (const RuntimeException&)
80
0
    {
81
0
        mxConfigurationController = nullptr;
82
0
        mxModuleController = nullptr;
83
0
    }
84
0
}
85
86
DrawController::~DrawController() noexcept
87
0
{
88
0
}
89
90
void DrawController::SetSubController (
91
    const Reference<drawing::XDrawSubController>& rxSubController)
92
0
{
93
    // Update the internal state.
94
0
    mxSubController = rxSubController;
95
0
    mpPropertyArrayHelper.reset();
96
0
    maLastVisArea = ::tools::Rectangle();
97
98
    // Inform listeners about the changed state.
99
0
    FireSelectionChangeListener();
100
0
}
101
102
// XInterface
103
104
IMPLEMENT_FORWARD_XINTERFACE2(
105
    DrawController,
106
    DrawControllerInterfaceBase,
107
    OPropertySetHelper);
108
109
// XTypeProvider
110
111
Sequence<Type> SAL_CALL DrawController::getTypes()
112
0
{
113
0
    ThrowIfDisposed();
114
    // OPropertySetHelper does not provide getTypes, so we have to
115
    // implement this method manually and list its three interfaces.
116
0
    OTypeCollection aTypeCollection (
117
0
        cppu::UnoType<beans::XMultiPropertySet>::get(),
118
0
        cppu::UnoType<beans::XFastPropertySet>::get(),
119
0
        cppu::UnoType<beans::XPropertySet>::get());
120
121
0
    return ::comphelper::concatSequences(
122
0
        SfxBaseController::getTypes(),
123
0
        aTypeCollection.getTypes(),
124
0
        DrawControllerInterfaceBase::getTypes());
125
0
}
126
127
IMPLEMENT_GET_IMPLEMENTATION_ID(DrawController);
128
129
// XComponent
130
131
void SAL_CALL DrawController::dispose()
132
0
{
133
0
    if( mbDisposing )
134
0
        return;
135
136
0
    SolarMutexGuard aGuard;
137
138
0
    if( mbDisposing )
139
0
        return;
140
141
0
    mbDisposing = true;
142
143
0
    std::shared_ptr<ViewShell> pViewShell;
144
0
    if (mpBase)
145
0
        pViewShell = mpBase->GetMainViewShell();
146
0
    if ( pViewShell )
147
0
    {
148
0
        pViewShell->DeactivateCurrentFunction();
149
0
        auto* pView = pViewShell->GetView();
150
0
        if (pView)
151
0
            pView->getSearchContext().resetSearchFunction();
152
0
    }
153
0
    pViewShell.reset();
154
155
    // When the controller has not been detached from its view
156
    // shell, i.e. mpViewShell is not NULL, then tell PaneManager
157
    // and ViewShellManager to clear the shell stack.
158
0
    if (mxSubController.is() && mpBase!=nullptr)
159
0
    {
160
0
        mpBase->DisconnectAllClients();
161
0
        mpBase->GetViewShellManager()->Shutdown();
162
0
    }
163
164
0
    OPropertySetHelper::disposing();
165
166
0
    DisposeFrameworkControllers();
167
168
0
    SfxBaseController::dispose();
169
0
}
170
171
void SAL_CALL DrawController::addEventListener(
172
    const Reference<lang::XEventListener >& xListener)
173
0
{
174
0
    ThrowIfDisposed();
175
0
    SfxBaseController::addEventListener( xListener );
176
0
}
177
178
void SAL_CALL DrawController::removeEventListener (
179
    const Reference<lang::XEventListener >& aListener)
180
0
{
181
0
    if(!rBHelper.bDisposed && !rBHelper.bInDispose && !mbDisposing)
182
0
        SfxBaseController::removeEventListener( aListener );
183
0
}
184
185
// XController
186
sal_Bool SAL_CALL DrawController::suspend( sal_Bool Suspend )
187
0
{
188
0
    if( Suspend )
189
0
    {
190
0
        ViewShellBase* pViewShellBase = GetViewShellBase();
191
0
        if( pViewShellBase )
192
0
        {
193
            // do not allow suspend if a slideshow needs this controller!
194
0
            rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( *pViewShellBase ) );
195
0
            if (xSlideShow.is())
196
0
            {
197
0
                if (xSlideShow->IsInteractiveSlideshow())
198
0
                {
199
                    // IASS mode: If preview mode, end it
200
0
                    if (xSlideShow->isInteractiveSetup())
201
0
                        xSlideShow->endInteractivePreview();
202
203
                    // end the SlideShow
204
0
                    xSlideShow->end();
205
206
                    // use SfxBaseController::suspend( Suspend ) below
207
                    // for normal processing and return value
208
0
                }
209
0
                else
210
0
                {
211
                    // original reaction - prevent exit
212
0
                    if (xSlideShow->dependsOn(pViewShellBase))
213
0
                        return false;
214
0
                }
215
0
            }
216
0
        }
217
0
    }
218
219
0
    return SfxBaseController::suspend( Suspend );
220
0
}
221
222
// XServiceInfo
223
OUString SAL_CALL DrawController::getImplementationName(  )
224
0
{
225
    // Do not throw an exception at the moment.  This leads to a crash
226
    // under Solaris on reload.  See issue i70929 for details.
227
    //    ThrowIfDisposed();
228
0
    return u"DrawController"_ustr ;
229
0
}
230
231
constexpr OUString ssServiceName = u"com.sun.star.drawing.DrawingDocumentDrawView"_ustr;
232
233
sal_Bool SAL_CALL DrawController::supportsService (const OUString& rsServiceName)
234
0
{
235
0
    return cppu::supportsService(this, rsServiceName);
236
0
}
237
238
Sequence<OUString> SAL_CALL DrawController::getSupportedServiceNames()
239
0
{
240
0
    ThrowIfDisposed();
241
0
    Sequence<OUString> aSupportedServices { ssServiceName };
242
0
    return aSupportedServices;
243
0
}
244
245
//------ XSelectionSupplier --------------------------------------------
246
sal_Bool SAL_CALL DrawController::select (const Any& aSelection)
247
0
{
248
0
    ThrowIfDisposed();
249
0
    SolarMutexGuard aGuard;
250
251
0
    if (mxSubController.is())
252
0
        return mxSubController->select(aSelection);
253
0
    else
254
0
        return false;
255
0
}
256
257
Any SAL_CALL DrawController::getSelection()
258
0
{
259
0
    ThrowIfDisposed();
260
0
    SolarMutexGuard aGuard;
261
262
0
    if (mxSubController.is())
263
0
        return mxSubController->getSelection();
264
0
    else
265
0
        return Any();
266
0
}
267
268
void SAL_CALL DrawController::addSelectionChangeListener(
269
    const Reference< view::XSelectionChangeListener >& xListener)
270
0
{
271
0
    if( mbDisposing )
272
0
        throw lang::DisposedException();
273
274
0
    BroadcastHelperOwner::maBroadcastHelper.addListener (m_aSelectionTypeIdentifier, xListener);
275
0
}
276
277
void SAL_CALL DrawController::removeSelectionChangeListener(
278
    const Reference< view::XSelectionChangeListener >& xListener )
279
0
{
280
0
    if (rBHelper.bDisposed)
281
0
        throw lang::DisposedException();
282
283
0
    BroadcastHelperOwner::maBroadcastHelper.removeListener (m_aSelectionTypeIdentifier, xListener);
284
0
}
285
286
//=====  lang::XEventListener  ================================================
287
288
void SAL_CALL
289
    DrawController::disposing (const lang::EventObject& )
290
0
{
291
0
}
292
293
//=====  view::XSelectionChangeListener  ======================================
294
295
void  SAL_CALL
296
    DrawController::selectionChanged (const lang::EventObject& rEvent)
297
0
{
298
0
    ThrowIfDisposed();
299
    // Have to forward the event to our selection change listeners.
300
0
    OInterfaceContainerHelper* pListeners = BroadcastHelperOwner::maBroadcastHelper.getContainer(
301
0
        cppu::UnoType<view::XSelectionChangeListener>::get());
302
0
    if (!pListeners)
303
0
        return;
304
305
    // Re-send the event to all of our listeners.
306
0
    OInterfaceIteratorHelper aIterator (*pListeners);
307
0
    while (aIterator.hasMoreElements())
308
0
    {
309
0
        try
310
0
        {
311
0
            view::XSelectionChangeListener* pListener =
312
0
                static_cast<view::XSelectionChangeListener*>(
313
0
                    aIterator.next());
314
0
            if (pListener != nullptr)
315
0
                pListener->selectionChanged (rEvent);
316
0
        }
317
0
        catch (const RuntimeException&)
318
0
        {
319
0
        }
320
0
    }
321
0
}
322
323
// XDrawView
324
325
void SAL_CALL DrawController::setCurrentPage( const Reference< drawing::XDrawPage >& xPage )
326
0
{
327
0
    ThrowIfDisposed();
328
0
    SolarMutexGuard aGuard;
329
330
0
    if (mxSubController.is())
331
0
        mxSubController->setCurrentPage(xPage);
332
0
}
333
334
Reference< drawing::XDrawPage > SAL_CALL DrawController::getCurrentPage()
335
0
{
336
0
    ThrowIfDisposed();
337
0
    SolarMutexGuard aGuard;
338
0
    Reference<drawing::XDrawPage> xPage;
339
340
    // Get current page from sub controller.
341
0
    if (mxSubController.is())
342
0
        xPage = mxSubController->getCurrentPage();
343
344
    // When there is not yet a sub controller (during initialization) then fall back
345
    // to the current page in mpCurrentPage.
346
0
    if ( ! xPage.is() )
347
0
        if (rtl::Reference<SdPage> pPage = mpCurrentPage.get())
348
0
            xPage.set(pPage->getUnoPage(), UNO_QUERY);
349
350
0
    return xPage;
351
0
}
352
353
void DrawController::FireVisAreaChanged (const ::tools::Rectangle& rVisArea) noexcept
354
0
{
355
0
    if( maLastVisArea == rVisArea )
356
0
        return;
357
358
0
    Any aNewValue;
359
0
    aNewValue <<= awt::Rectangle(
360
0
        rVisArea.Left(),
361
0
        rVisArea.Top(),
362
0
        rVisArea.GetWidth(),
363
0
        rVisArea.GetHeight() );
364
365
0
    Any aOldValue;
366
0
    aOldValue <<= awt::Rectangle(
367
0
        maLastVisArea.Left(),
368
0
        maLastVisArea.Top(),
369
0
        maLastVisArea.GetWidth(),
370
0
        maLastVisArea.GetHeight() );
371
372
0
    FirePropertyChange (PROPERTY_WORKAREA, aNewValue, aOldValue);
373
374
0
    maLastVisArea = rVisArea;
375
0
}
376
377
void DrawController::FireSelectionChangeListener() noexcept
378
0
{
379
0
    OInterfaceContainerHelper * pLC = BroadcastHelperOwner::maBroadcastHelper.getContainer(
380
0
        m_aSelectionTypeIdentifier);
381
0
    if( !pLC )
382
0
        return;
383
384
0
    Reference< XInterface > xSource( static_cast<XWeak*>(this) );
385
0
    const lang::EventObject aEvent( xSource );
386
387
    // iterate over all listeners and send events
388
0
    OInterfaceIteratorHelper aIt( *pLC);
389
0
    while( aIt.hasMoreElements() )
390
0
    {
391
0
        try
392
0
        {
393
0
            view::XSelectionChangeListener * pL =
394
0
                static_cast<view::XSelectionChangeListener*>(aIt.next());
395
0
            if (pL != nullptr)
396
0
                pL->selectionChanged( aEvent );
397
0
        }
398
0
        catch (const RuntimeException&)
399
0
        {
400
0
        }
401
0
    }
402
0
}
403
404
void DrawController::FireChangeEditMode (bool bMasterPageMode) noexcept
405
0
{
406
0
    if (bMasterPageMode != mbMasterPageMode )
407
0
    {
408
0
        FirePropertyChange(
409
0
            PROPERTY_MASTERPAGEMODE,
410
0
            Any(bMasterPageMode),
411
0
            Any(mbMasterPageMode));
412
413
0
        mbMasterPageMode = bMasterPageMode;
414
0
    }
415
0
}
416
417
void DrawController::FireChangeLayerMode (bool bLayerMode) noexcept
418
0
{
419
0
    if (bLayerMode != mbLayerMode)
420
0
    {
421
0
        FirePropertyChange(
422
0
            PROPERTY_LAYERMODE,
423
0
            Any(bLayerMode),
424
0
            Any(mbLayerMode));
425
426
0
        mbLayerMode = bLayerMode;
427
0
    }
428
0
}
429
430
void DrawController::FireSwitchCurrentPage (SdPage* pNewCurrentPage) noexcept
431
0
{
432
0
    rtl::Reference<SdrPage> pCurrentPage  = mpCurrentPage.get();
433
0
    if (pNewCurrentPage == pCurrentPage.get())
434
0
        return;
435
436
0
    try
437
0
    {
438
0
        Any aNewValue (
439
0
            Any(Reference<drawing::XDrawPage>(pNewCurrentPage->getUnoPage(), UNO_QUERY)));
440
441
0
        Any aOldValue;
442
0
        if (pCurrentPage != nullptr)
443
0
        {
444
0
            Reference<drawing::XDrawPage> xOldPage (pCurrentPage->getUnoPage(), UNO_QUERY);
445
0
            aOldValue <<= xOldPage;
446
0
        }
447
448
0
        FirePropertyChange(PROPERTY_CURRENTPAGE, aNewValue, aOldValue);
449
450
0
        mpCurrentPage = pNewCurrentPage;
451
0
    }
452
0
    catch (const uno::Exception&)
453
0
    {
454
0
        TOOLS_WARN_EXCEPTION("sd", "sd::SdUnoDrawView::FireSwitchCurrentPage()");
455
0
    }
456
0
}
457
458
void DrawController::NotifyAccUpdate()
459
0
{
460
0
    sal_Int32 nHandle = PROPERTY_UPDATEACC;
461
0
    Any aNewValue, aOldValue;
462
0
    fire (&nHandle, &aNewValue, &aOldValue, 1, false);
463
0
}
464
465
void DrawController::fireChangeLayer( const css::uno::Reference< css::drawing::XLayer>& xNewLayer ) noexcept
466
0
{
467
0
    if( xNewLayer != mxCurrentLayer )
468
0
    {
469
0
        sal_Int32 nHandle = PROPERTY_ACTIVE_LAYER;
470
471
0
        Any aNewValue (xNewLayer);
472
473
0
        Any aOldValue ;
474
475
0
        fire (&nHandle, &aNewValue, &aOldValue, 1, false);
476
477
0
        mxCurrentLayer = xNewLayer;
478
0
    }
479
0
}
480
481
// This method is only called in slide show and outline view
482
//void DrawController::fireSwitchCurrentPage(String pageName ) throw()
483
void DrawController::fireSwitchCurrentPage(sal_Int32 pageIndex ) noexcept
484
0
{
485
0
        Any aNewValue;
486
0
        Any aOldValue;
487
        //OUString aPageName(  pageName );
488
        //aNewValue <<= aPageName ;
489
0
        aNewValue <<= pageIndex;
490
491
        // Use new property to handle page change event
492
0
        sal_Int32 nHandles = PROPERTY_PAGE_CHANGE;
493
0
        fire( &nHandles, &aNewValue, &aOldValue, 1, false );
494
0
}
495
496
void DrawController::FirePropertyChange (
497
    sal_Int32 nHandle,
498
    const Any& rNewValue,
499
    const Any& rOldValue)
500
0
{
501
0
    try
502
0
    {
503
0
        fire (&nHandle, &rNewValue, &rOldValue, 1, false);
504
0
    }
505
0
    catch (const RuntimeException&)
506
0
    {
507
        // Ignore this exception.  Exceptions should be handled in the
508
        // fire() function so that all listeners are called.  This is
509
        // not the case at the moment, so we simply ignore the
510
        // exception.
511
0
    }
512
513
0
}
514
515
void DrawController::BroadcastContextChange() const
516
0
{
517
0
    std::shared_ptr<ViewShell> pViewShell (mpBase->GetMainViewShell());
518
0
    if ( ! pViewShell)
519
0
        return;
520
521
0
    EnumContext::Context eContext (EnumContext::Context::Unknown);
522
0
    switch (pViewShell->GetShellType())
523
0
    {
524
0
        case ViewShell::ST_IMPRESS:
525
0
        case ViewShell::ST_DRAW:
526
0
            if (mbMasterPageMode)
527
0
                eContext = EnumContext::Context::MasterPage;
528
0
            else
529
0
                eContext = EnumContext::Context::DrawPage;
530
0
            break;
531
532
0
        case ViewShell::ST_NOTES:
533
0
            eContext = EnumContext::Context::NotesPage;
534
0
            break;
535
536
0
        case ViewShell::ST_HANDOUT:
537
0
            eContext = EnumContext::Context::HandoutPage;
538
0
            break;
539
540
0
        case ViewShell::ST_OUTLINE:
541
0
            eContext = EnumContext::Context::OutlineText;
542
0
            break;
543
544
0
        case ViewShell::ST_SLIDE_SORTER:
545
0
            eContext = EnumContext::Context::SlidesorterPage;
546
0
            break;
547
548
0
        case ViewShell::ST_PRESENTATION:
549
0
        case ViewShell::ST_NONE:
550
0
        default:
551
0
            eContext = EnumContext::Context::Empty;
552
0
            break;
553
0
    }
554
555
0
    ContextChangeEventMultiplexer::NotifyContextChange(mpBase, eContext);
556
0
}
557
558
void DrawController::ReleaseViewShellBase()
559
0
{
560
0
    DisposeFrameworkControllers();
561
0
    mpBase = nullptr;
562
0
}
563
564
const rtl::Reference<framework::ConfigurationController> &
565
    DrawController::getConfigurationController()
566
0
{
567
0
    ThrowIfDisposed();
568
569
0
    return mxConfigurationController;
570
0
}
571
572
const rtl::Reference<framework::ModuleController> & DrawController::getModuleController()
573
0
{
574
0
    ThrowIfDisposed();
575
576
0
    return mxModuleController;
577
0
}
578
//===== XSlideSorterSelectionSupplier ==============================================================
579
580
Any SAL_CALL DrawController::getSlideSorterSelection()
581
0
{
582
0
    ThrowIfDisposed();
583
584
    // * traverse Impress resources to find slide preview pane, grab selection from there
585
0
    const std::vector<rtl::Reference<framework::ResourceId>> aResIds(
586
0
        mxConfigurationController->getCurrentConfiguration()->getResources(
587
0
            {}, u"", drawing::framework::AnchorBindingMode_INDIRECT));
588
589
0
    for (const rtl::Reference<framework::ResourceId>& rResId : aResIds)
590
0
    {
591
        // can we somehow obtain the slidesorter from the Impress framework?
592
0
        if (rResId->getResourceURL() == "private:resource/view/SlideSorter")
593
0
        {
594
            // got it, grab current selection from there
595
0
            uno::Reference<view::XSelectionSupplier> xSelectionSupplier(
596
0
                cppu::getXWeak(mxConfigurationController->getResource(rResId).get()), uno::UNO_QUERY);
597
0
            if (!xSelectionSupplier)
598
0
                continue;
599
600
0
            return xSelectionSupplier->getSelection();
601
0
        }
602
0
    }
603
0
    return {};
604
0
}
605
606
//===== Properties ============================================================
607
608
void DrawController::FillPropertyTable (
609
    ::std::vector<beans::Property>& rProperties)
610
0
{
611
0
    rProperties.emplace_back("VisibleArea",
612
0
            PROPERTY_WORKAREA,
613
0
            ::cppu::UnoType< css::awt::Rectangle>::get(),
614
0
            beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY);
615
0
    rProperties.emplace_back(
616
0
            "SubController",
617
0
            PROPERTY_SUB_CONTROLLER,
618
0
            cppu::UnoType<drawing::XDrawSubController>::get(),
619
0
            beans::PropertyAttribute::BOUND);
620
0
    rProperties.emplace_back(
621
0
            "CurrentPage",
622
0
            PROPERTY_CURRENTPAGE,
623
0
            cppu::UnoType<drawing::XDrawPage>::get(),
624
0
            beans::PropertyAttribute::BOUND );
625
0
    rProperties.emplace_back("IsLayerMode",
626
0
            PROPERTY_LAYERMODE,
627
0
            cppu::UnoType<bool>::get(),
628
0
            beans::PropertyAttribute::BOUND );
629
0
    rProperties.emplace_back("IsMasterPageMode",
630
0
            PROPERTY_MASTERPAGEMODE,
631
0
            cppu::UnoType<bool>::get(),
632
0
            beans::PropertyAttribute::BOUND );
633
0
    rProperties.emplace_back("ActiveLayer",
634
0
            PROPERTY_ACTIVE_LAYER,
635
0
            cppu::UnoType<drawing::XLayer>::get(),
636
0
            beans::PropertyAttribute::BOUND );
637
0
    rProperties.emplace_back("ZoomValue",
638
0
            PROPERTY_ZOOMVALUE,
639
0
            ::cppu::UnoType<sal_Int16>::get(),
640
0
            beans::PropertyAttribute::BOUND );
641
0
    rProperties.emplace_back("ZoomType",
642
0
            PROPERTY_ZOOMTYPE,
643
0
            ::cppu::UnoType<sal_Int16>::get(),
644
0
            beans::PropertyAttribute::BOUND );
645
0
    rProperties.emplace_back("ViewOffset",
646
0
            PROPERTY_VIEWOFFSET,
647
0
            ::cppu::UnoType< css::awt::Point>::get(),
648
0
            beans::PropertyAttribute::BOUND );
649
0
    rProperties.emplace_back("DrawViewMode",
650
0
            PROPERTY_DRAWVIEWMODE,
651
0
            ::cppu::UnoType< css::awt::Point>::get(),
652
0
            beans::PropertyAttribute::BOUND|beans::PropertyAttribute::READONLY|beans::PropertyAttribute::MAYBEVOID );
653
    // add new property to update current page's acc information
654
0
    rProperties.emplace_back( "UpdateAcc",
655
0
            PROPERTY_UPDATEACC,
656
0
            ::cppu::UnoType<sal_Int16>::get(),
657
0
            beans::PropertyAttribute::BOUND );
658
0
    rProperties.emplace_back( "PageChange",
659
0
            PROPERTY_PAGE_CHANGE,
660
0
            ::cppu::UnoType<sal_Int16>::get(),
661
0
            beans::PropertyAttribute::BOUND );
662
0
}
663
664
IPropertyArrayHelper & DrawController::getInfoHelper()
665
0
{
666
0
    SolarMutexGuard aGuard;
667
668
0
    if (mpPropertyArrayHelper == nullptr)
669
0
    {
670
0
        ::std::vector<beans::Property> aProperties;
671
0
        FillPropertyTable(aProperties);
672
0
        mpPropertyArrayHelper.reset(new OPropertyArrayHelper(comphelper::containerToSequence(aProperties), false));
673
0
    }
674
675
0
    return *mpPropertyArrayHelper;
676
0
}
677
678
Reference < beans::XPropertySetInfo >  DrawController::getPropertySetInfo()
679
0
{
680
0
    SolarMutexGuard aGuard;
681
682
0
    static Reference < beans::XPropertySetInfo >  xInfo( createPropertySetInfo( getInfoHelper() ) );
683
0
    return xInfo;
684
0
}
685
686
uno::Reference< form::runtime::XFormController > SAL_CALL DrawController::getFormController( const uno::Reference< form::XForm >& Form )
687
0
{
688
0
    SolarMutexGuard aGuard;
689
690
0
    FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell();
691
0
    SdrView* pSdrView = mpBase->GetDrawView();
692
0
    std::shared_ptr<ViewShell> pViewShell = mpBase->GetMainViewShell();
693
0
    ::sd::Window* pWindow = pViewShell ? pViewShell->GetActiveWindow() : nullptr;
694
695
0
    uno::Reference< form::runtime::XFormController > xController;
696
0
    if ( pFormShell && pSdrView && pWindow )
697
0
        xController = FmFormShell::GetFormController( Form, *pSdrView, *pWindow->GetOutDev() );
698
0
    return xController;
699
0
}
700
701
sal_Bool SAL_CALL DrawController::isFormDesignMode(  )
702
0
{
703
0
    SolarMutexGuard aGuard;
704
705
0
    bool bIsDesignMode = true;
706
707
0
    FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell();
708
0
    if ( pFormShell )
709
0
        bIsDesignMode = pFormShell->IsDesignMode();
710
711
0
    return bIsDesignMode;
712
0
}
713
714
void SAL_CALL DrawController::setFormDesignMode( sal_Bool DesignMode )
715
0
{
716
0
    SolarMutexGuard aGuard;
717
718
0
    FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell();
719
0
    if ( pFormShell )
720
0
        pFormShell->SetDesignMode( DesignMode );
721
0
}
722
723
uno::Reference< awt::XControl > SAL_CALL DrawController::getControl( const uno::Reference< awt::XControlModel >& xModel )
724
0
{
725
0
    SolarMutexGuard aGuard;
726
727
0
    FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell();
728
0
    SdrView* pSdrView = mpBase->GetDrawView();
729
0
    std::shared_ptr<ViewShell> pViewShell = mpBase->GetMainViewShell();
730
0
    ::sd::Window* pWindow = pViewShell ? pViewShell->GetActiveWindow() : nullptr;
731
732
0
    uno::Reference< awt::XControl > xControl;
733
0
    if ( pFormShell && pSdrView && pWindow )
734
0
        pFormShell->GetFormControl( xModel, *pSdrView, *pWindow->GetOutDev(), xControl );
735
0
    return xControl;
736
0
}
737
738
sal_Bool DrawController::convertFastPropertyValue (
739
    Any & rConvertedValue,
740
    Any & rOldValue,
741
    sal_Int32 nHandle,
742
    const Any& rValue)
743
0
{
744
0
    bool bResult = false;
745
746
0
    if (nHandle == PROPERTY_SUB_CONTROLLER)
747
0
    {
748
0
        rOldValue <<= mxSubController;
749
0
        rConvertedValue <<= Reference<drawing::XDrawSubController>(rValue, UNO_QUERY);
750
0
        bResult = (rOldValue != rConvertedValue);
751
0
    }
752
0
    else if (mxSubController.is())
753
0
    {
754
0
        rConvertedValue = rValue;
755
0
        try
756
0
        {
757
0
            rOldValue = mxSubController->getFastPropertyValue(nHandle);
758
0
            bResult = (rOldValue != rConvertedValue);
759
0
        }
760
0
        catch (const beans::UnknownPropertyException&)
761
0
        {
762
            // The property is unknown and thus an illegal argument to this method.
763
0
            throw css::lang::IllegalArgumentException();
764
0
        }
765
0
    }
766
767
0
    return bResult;
768
0
}
769
770
void DrawController::setFastPropertyValue_NoBroadcast (
771
    sal_Int32 nHandle,
772
    const Any& rValue)
773
0
{
774
0
    SolarMutexGuard aGuard;
775
0
    if (nHandle == PROPERTY_SUB_CONTROLLER)
776
0
        SetSubController(Reference<drawing::XDrawSubController>(rValue, UNO_QUERY));
777
0
    else if (mxSubController.is())
778
0
        mxSubController->setFastPropertyValue(nHandle, rValue);
779
0
}
780
781
void DrawController::getFastPropertyValue (
782
    Any & rRet,
783
    sal_Int32 nHandle ) const
784
0
{
785
0
    SolarMutexGuard aGuard;
786
787
0
    switch( nHandle )
788
0
    {
789
0
        case PROPERTY_WORKAREA:
790
0
            rRet <<= awt::Rectangle(
791
0
                maLastVisArea.Left(),
792
0
                maLastVisArea.Top(),
793
0
                maLastVisArea.GetWidth(),
794
0
                maLastVisArea.GetHeight());
795
0
            break;
796
797
0
        case PROPERTY_SUB_CONTROLLER:
798
0
            rRet <<= mxSubController;
799
0
            break;
800
801
0
        default:
802
0
            if (mxSubController.is())
803
0
                rRet = mxSubController->getFastPropertyValue(nHandle);
804
0
            break;
805
0
    }
806
0
}
807
808
void DrawController::DisposeFrameworkControllers()
809
0
{
810
0
    if (mxModuleController.is())
811
0
        mxModuleController->dispose();
812
813
0
    if (mxConfigurationController.is())
814
0
        mxConfigurationController->dispose();
815
0
}
816
817
void DrawController::ThrowIfDisposed() const
818
0
{
819
0
    if (rBHelper.bDisposed || rBHelper.bInDispose || mbDisposing)
820
0
    {
821
0
        SAL_WARN("sd", "Calling disposed DrawController object. Throwing exception.");
822
0
        throw lang::DisposedException (
823
0
            u"DrawController object has already been disposed"_ustr,
824
0
            const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
825
0
    }
826
0
}
827
828
} // end of namespace sd
829
830
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */