1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
24 #include "BasicPaneFactory.hxx"
27 #include "ChildWindowPane.hxx"
28 #include "FrameWindowPane.hxx"
29 #include "FullScreenPane.hxx"
31 #include "framework/FrameworkHelper.hxx"
32 #include "ViewShellBase.hxx"
33 #include "PaneChildWindows.hxx"
34 #include "DrawController.hxx"
35 #include "DrawDocShell.hxx"
36 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
37 #include <boost/bind.hpp>
39 using namespace ::com::sun::star
;
40 using namespace ::com::sun::star::uno
;
41 using namespace ::com::sun::star::lang
;
42 using namespace ::com::sun::star::drawing::framework
;
44 using ::sd::framework::FrameworkHelper
;
54 static const sal_Int32
gnConfigurationUpdateStartEvent(0);
55 static const sal_Int32
gnConfigurationUpdateEndEvent(1);
58 namespace sd
{ namespace framework
{
60 /** Store URL, XPane reference and (local) PaneId for every pane factory
61 that is registered at the PaneController.
63 class BasicPaneFactory::PaneDescriptor
67 Reference
<XResource
> mxPane
;
69 /** The mbReleased flag is set when the pane has been released. Some
70 panes are just hidden and destroyed. When the pane is reused this
76 bool CompareURL (const OUString
& rsPaneURL
) { return msPaneURL
.equals(rsPaneURL
); }
77 bool ComparePane (const Reference
<XResource
>& rxPane
) { return mxPane
==rxPane
; }
80 class BasicPaneFactory::PaneContainer
81 : public ::std::vector
<PaneDescriptor
>
87 //===== PaneFactory ===========================================================
89 BasicPaneFactory::BasicPaneFactory (
90 const Reference
<XComponentContext
>& rxContext
)
91 : BasicPaneFactoryInterfaceBase(m_aMutex
),
92 mxComponentContext(rxContext
),
93 mxConfigurationControllerWeak(),
94 mpViewShellBase(NULL
),
95 mpPaneContainer(new PaneContainer
)
99 BasicPaneFactory::~BasicPaneFactory()
103 void SAL_CALL
BasicPaneFactory::disposing()
105 Reference
<XConfigurationController
> xCC (mxConfigurationControllerWeak
);
108 xCC
->removeResourceFactoryForReference(this);
109 xCC
->removeConfigurationChangeListener(this);
110 mxConfigurationControllerWeak
.clear();
113 for (PaneContainer::const_iterator iDescriptor
= mpPaneContainer
->begin();
114 iDescriptor
!= mpPaneContainer
->end();
117 if (iDescriptor
->mbIsReleased
)
119 Reference
<XComponent
> xComponent (iDescriptor
->mxPane
, UNO_QUERY
);
122 xComponent
->removeEventListener(this);
123 xComponent
->dispose();
129 void SAL_CALL
BasicPaneFactory::initialize (const Sequence
<Any
>& aArguments
)
130 throw (Exception
, RuntimeException
, std::exception
)
132 if (aArguments
.getLength() > 0)
136 // Get the XController from the first argument.
137 Reference
<frame::XController
> xController (aArguments
[0], UNO_QUERY_THROW
);
138 mxControllerWeak
= xController
;
140 // Tunnel through the controller to obtain access to the ViewShellBase.
143 Reference
<lang::XUnoTunnel
> xTunnel (xController
, UNO_QUERY_THROW
);
144 DrawController
* pController
145 = reinterpret_cast<DrawController
*>(
146 (sal::static_int_cast
<sal_uIntPtr
>(
147 xTunnel
->getSomething(DrawController::getUnoTunnelId()))));
148 mpViewShellBase
= pController
->GetViewShellBase();
150 catch(RuntimeException
&)
153 Reference
<XControllerManager
> xCM (xController
, UNO_QUERY_THROW
);
154 Reference
<XConfigurationController
> xCC (xCM
->getConfigurationController());
155 mxConfigurationControllerWeak
= xCC
;
157 // Add pane factories for the two left panes (one for Impress and one for
158 // Draw) and the center pane.
159 if (xController
.is() && xCC
.is())
161 PaneDescriptor aDescriptor
;
162 aDescriptor
.msPaneURL
= FrameworkHelper::msCenterPaneURL
;
163 aDescriptor
.mePaneId
= CenterPaneId
;
164 aDescriptor
.mbIsReleased
= false;
165 aDescriptor
.mbIsChildWindow
= false;
166 mpPaneContainer
->push_back(aDescriptor
);
167 xCC
->addResourceFactory(aDescriptor
.msPaneURL
, this);
169 aDescriptor
.msPaneURL
= FrameworkHelper::msFullScreenPaneURL
;
170 aDescriptor
.mePaneId
= FullScreenPaneId
;
171 mpPaneContainer
->push_back(aDescriptor
);
172 xCC
->addResourceFactory(aDescriptor
.msPaneURL
, this);
174 aDescriptor
.msPaneURL
= FrameworkHelper::msLeftImpressPaneURL
;
175 aDescriptor
.mePaneId
= LeftImpressPaneId
;
176 aDescriptor
.mbIsChildWindow
= true;
177 mpPaneContainer
->push_back(aDescriptor
);
178 xCC
->addResourceFactory(aDescriptor
.msPaneURL
, this);
180 aDescriptor
.msPaneURL
= FrameworkHelper::msLeftDrawPaneURL
;
181 aDescriptor
.mePaneId
= LeftDrawPaneId
;
182 mpPaneContainer
->push_back(aDescriptor
);
183 xCC
->addResourceFactory(aDescriptor
.msPaneURL
, this);
186 // Register as configuration change listener.
189 xCC
->addConfigurationChangeListener(
191 FrameworkHelper::msConfigurationUpdateStartEvent
,
192 makeAny(gnConfigurationUpdateStartEvent
));
193 xCC
->addConfigurationChangeListener(
195 FrameworkHelper::msConfigurationUpdateEndEvent
,
196 makeAny(gnConfigurationUpdateEndEvent
));
199 catch (RuntimeException
&)
201 Reference
<XConfigurationController
> xCC (mxConfigurationControllerWeak
);
203 xCC
->removeResourceFactoryForReference(this);
208 //===== XPaneFactory ==========================================================
210 Reference
<XResource
> SAL_CALL
BasicPaneFactory::createResource (
211 const Reference
<XResourceId
>& rxPaneId
)
212 throw (RuntimeException
, IllegalArgumentException
, WrappedTargetException
, std::exception
)
216 Reference
<XResource
> xPane
;
218 // Based on the ResourceURL of the given ResourceId look up the
219 // corresponding factory descriptor.
220 PaneContainer::iterator
iDescriptor (
222 mpPaneContainer
->begin(),
223 mpPaneContainer
->end(),
224 ::boost::bind(&PaneDescriptor::CompareURL
, _1
, rxPaneId
->getResourceURL())));
226 if (iDescriptor
!= mpPaneContainer
->end())
228 if (iDescriptor
->mxPane
.is())
230 // The pane has already been created and is still active (has
231 // not yet been released). This should not happen.
232 xPane
= iDescriptor
->mxPane
;
236 // Create a new pane.
237 switch (iDescriptor
->mePaneId
)
240 xPane
= CreateFrameWindowPane(rxPaneId
);
243 case FullScreenPaneId
:
244 xPane
= CreateFullScreenPane(mxComponentContext
, rxPaneId
);
247 case LeftImpressPaneId
:
249 xPane
= CreateChildWindowPane(
254 iDescriptor
->mxPane
= xPane
;
256 // Listen for the pane being disposed.
257 Reference
<lang::XComponent
> xComponent (xPane
, UNO_QUERY
);
259 xComponent
->addEventListener(this);
261 iDescriptor
->mbIsReleased
= false;
265 // The requested pane can not be created by any of the factories
266 // managed by the called BasicPaneFactory object.
267 throw lang::IllegalArgumentException("BasicPaneFactory::createPane() called for unknown resource id",
275 void SAL_CALL
BasicPaneFactory::releaseResource (
276 const Reference
<XResource
>& rxPane
)
277 throw (RuntimeException
, std::exception
)
281 // Based on the given XPane reference look up the corresponding factory
283 PaneContainer::iterator
iDescriptor (
285 mpPaneContainer
->begin(),
286 mpPaneContainer
->end(),
287 ::boost::bind(&PaneDescriptor::ComparePane
, _1
, rxPane
)));
289 if (iDescriptor
!= mpPaneContainer
->end())
291 // The given pane was created by one of the factories. Child
292 // windows are just hidden and will be reused when requested later.
293 // Other windows are disposed and their reference is reset so that
294 // on the next createPane() call for the same pane type the pane is
296 ChildWindowPane
* pChildWindowPane
= dynamic_cast<ChildWindowPane
*>(rxPane
.get());
297 if (pChildWindowPane
!= NULL
)
299 iDescriptor
->mbIsReleased
= true;
300 pChildWindowPane
->Hide();
304 iDescriptor
->mxPane
= NULL
;
305 Reference
<XComponent
> xComponent (rxPane
, UNO_QUERY
);
308 // We are disposing the pane and do not have to be informed of
310 xComponent
->removeEventListener(this);
311 xComponent
->dispose();
317 // The given XPane reference is either empty or the pane was not
318 // created by any of the factories managed by the called
319 // BasicPaneFactory object.
320 throw lang::IllegalArgumentException("BasicPaneFactory::releasePane() called for pane that was not created by same factory.",
326 //===== XConfigurationChangeListener ==========================================
328 void SAL_CALL
BasicPaneFactory::notifyConfigurationChange (
329 const ConfigurationChangeEvent
& /* rEvent */ )
330 throw (RuntimeException
, std::exception
)
332 // FIXME: nothing to do
335 //===== lang::XEventListener ==================================================
337 void SAL_CALL
BasicPaneFactory::disposing (
338 const lang::EventObject
& rEventObject
)
339 throw (RuntimeException
, std::exception
)
341 if (mxConfigurationControllerWeak
== rEventObject
.Source
)
343 mxConfigurationControllerWeak
.clear();
347 // Has one of the panes been disposed? If so, then release the
348 // reference to that pane, but not the pane descriptor.
349 Reference
<XResource
> xPane (rEventObject
.Source
, UNO_QUERY
);
350 PaneContainer::iterator
iDescriptor (
352 mpPaneContainer
->begin(),
353 mpPaneContainer
->end(),
354 ::boost::bind(&PaneDescriptor::ComparePane
, _1
, xPane
)));
355 if (iDescriptor
!= mpPaneContainer
->end())
357 iDescriptor
->mxPane
= NULL
;
362 Reference
<XResource
> BasicPaneFactory::CreateFrameWindowPane (
363 const Reference
<XResourceId
>& rxPaneId
)
365 Reference
<XResource
> xPane
;
367 if (mpViewShellBase
!= NULL
)
369 xPane
= new FrameWindowPane(rxPaneId
, mpViewShellBase
->GetViewWindow());
375 Reference
<XResource
> BasicPaneFactory::CreateFullScreenPane (
376 const Reference
<XComponentContext
>& rxComponentContext
,
377 const Reference
<XResourceId
>& rxPaneId
)
379 Reference
<XResource
> xPane (
383 mpViewShellBase
->GetViewWindow()));
388 Reference
<XResource
> BasicPaneFactory::CreateChildWindowPane (
389 const Reference
<XResourceId
>& rxPaneId
,
390 const PaneDescriptor
& rDescriptor
)
392 Reference
<XResource
> xPane
;
394 if (mpViewShellBase
!= NULL
)
396 // Create the corresponding shell and determine the id of the child window.
397 sal_uInt16 nChildWindowId
= 0;
398 ::std::unique_ptr
<SfxShell
> pShell
;
399 switch (rDescriptor
.mePaneId
)
401 case LeftImpressPaneId
:
402 pShell
.reset(new LeftImpressPaneShell());
403 nChildWindowId
= ::sd::LeftPaneImpressChildWindow::GetChildWindowId();
407 pShell
.reset(new LeftDrawPaneShell());
408 nChildWindowId
= ::sd::LeftPaneDrawChildWindow::GetChildWindowId();
415 // With shell and child window id create the ChildWindowPane
417 if (pShell
.get() != NULL
)
419 xPane
= new ChildWindowPane(
430 void BasicPaneFactory::ThrowIfDisposed() const
431 throw (lang::DisposedException
)
433 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
435 throw lang::DisposedException ("BasicPaneFactory object has already been disposed",
436 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
440 } } // end of namespace sd::framework
443 extern "C" SAL_DLLPUBLIC_EXPORT ::com::sun::star::uno::XInterface
* SAL_CALL
444 com_sun_star_comp_Draw_framework_BasicPaneFactory_get_implementation(::com::sun::star::uno::XComponentContext
* context
,
445 ::com::sun::star::uno::Sequence
<css::uno::Any
> const &)
447 return cppu::acquire(new sd::framework::BasicPaneFactory(context
));
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */