Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "BasicPaneFactory.hxx"
31 : :
32 : : #include "ChildWindowPane.hxx"
33 : : #include "FrameWindowPane.hxx"
34 : : #include "FullScreenPane.hxx"
35 : :
36 : : #include "framework/FrameworkHelper.hxx"
37 : : #include "ViewShellBase.hxx"
38 : : #include "PaneChildWindows.hxx"
39 : : #include "DrawController.hxx"
40 : : #include "DrawDocShell.hxx"
41 : : #include <com/sun/star/drawing/framework/XControllerManager.hpp>
42 : : #include <boost/bind.hpp>
43 : :
44 : :
45 : : using namespace ::com::sun::star;
46 : : using namespace ::com::sun::star::uno;
47 : : using namespace ::com::sun::star::lang;
48 : : using namespace ::com::sun::star::drawing::framework;
49 : :
50 : : using ::rtl::OUString;
51 : : using ::sd::framework::FrameworkHelper;
52 : :
53 : : namespace {
54 : : enum PaneId {
55 : : CenterPaneId,
56 : : FullScreenPaneId,
57 : : LeftImpressPaneId,
58 : : LeftDrawPaneId,
59 : : RightPaneId
60 : : };
61 : :
62 : : static const sal_Int32 gnConfigurationUpdateStartEvent(0);
63 : : static const sal_Int32 gnConfigurationUpdateEndEvent(1);
64 : : }
65 : :
66 : : namespace sd { namespace framework {
67 : :
68 : :
69 : : /** Store URL, XPane reference and (local) PaneId for every pane factory
70 : : that is registered at the PaneController.
71 : : */
72 : 2730 : class BasicPaneFactory::PaneDescriptor
73 : : {
74 : : public:
75 : : OUString msPaneURL;
76 : : Reference<XResource> mxPane;
77 : : PaneId mePaneId;
78 : : /** The mbReleased flag is set when the pane has been released. Some
79 : : panes are just hidden and destroyed. When the pane is reused this
80 : : flag is reset.
81 : : */
82 : : bool mbIsReleased;
83 : : bool mbIsChildWindow;
84 : :
85 : 1378 : bool CompareURL (const OUString& rsPaneURL) { return msPaneURL.equals(rsPaneURL); }
86 : 1378 : bool ComparePane (const Reference<XResource>& rxPane) { return mxPane==rxPane; }
87 : : };
88 : :
89 : :
90 : 0 : class BasicPaneFactory::PaneContainer
91 : : : public ::std::vector<PaneDescriptor>
92 : : {
93 : : public:
94 : 130 : PaneContainer (void) {}
95 : : };
96 : :
97 : :
98 : :
99 : 130 : Reference<XInterface> SAL_CALL BasicPaneFactory_createInstance (
100 : : const Reference<XComponentContext>& rxContext)
101 : : {
102 [ + - ]: 130 : return Reference<XInterface>(static_cast<XWeak*>(new BasicPaneFactory(rxContext)));
103 : : }
104 : :
105 : :
106 : :
107 : :
108 : 38 : ::rtl::OUString BasicPaneFactory_getImplementationName (void) throw(RuntimeException)
109 : : {
110 : 38 : return ::rtl::OUString("com.sun.star.comp.Draw.framework.BasicPaneFactory");
111 : : }
112 : :
113 : :
114 : :
115 : :
116 : 16 : Sequence<rtl::OUString> SAL_CALL BasicPaneFactory_getSupportedServiceNames (void)
117 : : throw (RuntimeException)
118 : : {
119 [ + - ][ + - ]: 16 : static const ::rtl::OUString sServiceName("com.sun.star.drawing.framework.BasicPaneFactory");
120 : 16 : return Sequence<rtl::OUString>(&sServiceName, 1);
121 : : }
122 : :
123 : :
124 : :
125 : :
126 : : //===== PaneFactory ===========================================================
127 : :
128 : 130 : BasicPaneFactory::BasicPaneFactory (
129 : : const Reference<XComponentContext>& rxContext)
130 : : : BasicPaneFactoryInterfaceBase(m_aMutex),
131 : : mxComponentContext(rxContext),
132 : : mxConfigurationControllerWeak(),
133 : : mpViewShellBase(NULL),
134 [ + - ][ + - ]: 130 : mpPaneContainer(new PaneContainer)
[ + - ][ + - ]
135 : : {
136 : 130 : }
137 : :
138 : :
139 : :
140 : :
141 : :
142 [ # # ][ # # ]: 0 : BasicPaneFactory::~BasicPaneFactory (void)
[ # # ][ # # ]
143 : : {
144 [ # # ]: 0 : }
145 : :
146 : :
147 : :
148 : :
149 : 0 : void SAL_CALL BasicPaneFactory::disposing (void)
150 : : {
151 [ # # ]: 0 : Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
152 [ # # ]: 0 : if (xCC.is())
153 : : {
154 [ # # ][ # # ]: 0 : xCC->removeResourceFactoryForReference(this);
[ # # ]
155 [ # # ][ # # ]: 0 : xCC->removeConfigurationChangeListener(this);
[ # # ]
156 [ # # ]: 0 : mxConfigurationControllerWeak = Reference<XConfigurationController>();
157 : : }
158 : :
159 [ # # ][ # # ]: 0 : for (PaneContainer::const_iterator iDescriptor = mpPaneContainer->begin();
[ # # ]
160 : 0 : iDescriptor != mpPaneContainer->end();
161 : : ++iDescriptor)
162 : : {
163 [ # # ]: 0 : if (iDescriptor->mbIsReleased)
164 : : {
165 [ # # ]: 0 : Reference<XComponent> xComponent (iDescriptor->mxPane, UNO_QUERY);
166 [ # # ]: 0 : if (xComponent.is())
167 : : {
168 [ # # ][ # # ]: 0 : xComponent->removeEventListener(this);
[ # # ]
169 [ # # ][ # # ]: 0 : xComponent->dispose();
170 : 0 : }
171 : : }
172 : 0 : }
173 : 0 : }
174 : :
175 : :
176 : :
177 : :
178 : 130 : void SAL_CALL BasicPaneFactory::initialize (const Sequence<Any>& aArguments)
179 : : throw (Exception, RuntimeException)
180 : : {
181 [ + - ]: 130 : if (aArguments.getLength() > 0)
182 : : {
183 : : try
184 : : {
185 : : // Get the XController from the first argument.
186 [ + - ]: 130 : Reference<frame::XController> xController (aArguments[0], UNO_QUERY_THROW);
187 [ + - ]: 130 : mxControllerWeak = xController;
188 : :
189 : : // Tunnel through the controller to obtain access to the ViewShellBase.
190 : : try
191 : : {
192 [ + - ]: 130 : Reference<lang::XUnoTunnel> xTunnel (xController, UNO_QUERY_THROW);
193 : : DrawController* pController
194 : : = reinterpret_cast<DrawController*>(
195 : : (sal::static_int_cast<sal_uIntPtr>(
196 [ + - ][ + - ]: 130 : xTunnel->getSomething(DrawController::getUnoTunnelId()))));
[ + - ]
197 [ # # ][ + - ]: 130 : mpViewShellBase = pController->GetViewShellBase();
198 : : }
199 [ # # ]: 0 : catch(RuntimeException&)
200 : : {}
201 : :
202 [ + - ]: 130 : Reference<XControllerManager> xCM (xController, UNO_QUERY_THROW);
203 [ + - ][ + - ]: 130 : Reference<XConfigurationController> xCC (xCM->getConfigurationController());
204 [ + - ]: 130 : mxConfigurationControllerWeak = xCC;
205 : :
206 : : // Add pane factories for the two left panes (one for Impress and one for
207 : : // Draw), the center pane, and the right pane.
208 [ + - ][ + - ]: 130 : if (xController.is() && xCC.is())
[ + - ]
209 : : {
210 [ + - ]: 130 : PaneDescriptor aDescriptor;
211 : 130 : aDescriptor.msPaneURL = FrameworkHelper::msCenterPaneURL;
212 : 130 : aDescriptor.mePaneId = CenterPaneId;
213 : 130 : aDescriptor.mbIsReleased = false;
214 : 130 : aDescriptor.mbIsChildWindow = false;
215 [ + - ]: 130 : mpPaneContainer->push_back(aDescriptor);
216 [ + - ][ + - ]: 130 : xCC->addResourceFactory(aDescriptor.msPaneURL, this);
[ + - ]
217 : :
218 : 130 : aDescriptor.msPaneURL = FrameworkHelper::msFullScreenPaneURL;
219 : 130 : aDescriptor.mePaneId = FullScreenPaneId;
220 [ + - ]: 130 : mpPaneContainer->push_back(aDescriptor);
221 [ + - ][ + - ]: 130 : xCC->addResourceFactory(aDescriptor.msPaneURL, this);
[ + - ]
222 : :
223 : 130 : aDescriptor.msPaneURL = FrameworkHelper::msLeftImpressPaneURL;
224 : 130 : aDescriptor.mePaneId = LeftImpressPaneId;
225 : 130 : aDescriptor.mbIsChildWindow = true;
226 [ + - ]: 130 : mpPaneContainer->push_back(aDescriptor);
227 [ + - ][ + - ]: 130 : xCC->addResourceFactory(aDescriptor.msPaneURL, this);
[ + - ]
228 : :
229 : 130 : aDescriptor.msPaneURL = FrameworkHelper::msLeftDrawPaneURL;
230 : 130 : aDescriptor.mePaneId = LeftDrawPaneId;
231 [ + - ]: 130 : mpPaneContainer->push_back(aDescriptor);
232 [ + - ][ + - ]: 130 : xCC->addResourceFactory(aDescriptor.msPaneURL, this);
[ + - ]
233 : :
234 : 130 : aDescriptor.msPaneURL = FrameworkHelper::msRightPaneURL;
235 : 130 : aDescriptor.mePaneId = RightPaneId;
236 [ + - ]: 130 : mpPaneContainer->push_back(aDescriptor);
237 [ + - ][ + - ]: 130 : xCC->addResourceFactory(aDescriptor.msPaneURL, this);
[ + - ][ + - ]
238 : : }
239 : :
240 : : // Register as configuration change listener.
241 [ + - ]: 130 : if (xCC.is())
242 : : {
243 [ + - ]: 130 : xCC->addConfigurationChangeListener(
244 : : this,
245 : : FrameworkHelper::msConfigurationUpdateStartEvent,
246 [ + - ][ + - ]: 130 : makeAny(gnConfigurationUpdateStartEvent));
[ + - ]
247 [ + - ]: 130 : xCC->addConfigurationChangeListener(
248 : : this,
249 : : FrameworkHelper::msConfigurationUpdateEndEvent,
250 [ + - ][ + - ]: 130 : makeAny(gnConfigurationUpdateEndEvent));
[ + - ]
251 : 130 : }
252 : : }
253 [ # # ]: 0 : catch (RuntimeException&)
254 : : {
255 [ # # ]: 0 : Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
256 [ # # ]: 0 : if (xCC.is())
257 [ # # # # : 0 : xCC->removeResourceFactoryForReference(this);
# # ]
258 : : }
259 : : }
260 : 130 : }
261 : :
262 : :
263 : :
264 : :
265 : : //===== XPaneFactory ==========================================================
266 : :
267 : 442 : Reference<XResource> SAL_CALL BasicPaneFactory::createResource (
268 : : const Reference<XResourceId>& rxPaneId)
269 : : throw (RuntimeException, IllegalArgumentException, WrappedTargetException)
270 : : {
271 [ + - ]: 442 : ThrowIfDisposed();
272 : :
273 : 442 : Reference<XResource> xPane;
274 : :
275 : : // Based on the ResourceURL of the given ResourceId look up the
276 : : // corresponding factory descriptor.
277 : : PaneContainer::iterator iDescriptor (
278 : : ::std::find_if (
279 : 442 : mpPaneContainer->begin(),
280 : 442 : mpPaneContainer->end(),
281 [ + - ]: 1326 : ::boost::bind(&PaneDescriptor::CompareURL, _1, rxPaneId->getResourceURL())));
[ + - + - ]
[ + - ]
282 : :
283 [ + - ][ + - ]: 442 : if (iDescriptor != mpPaneContainer->end())
284 : : {
285 [ + + ]: 442 : if (iDescriptor->mxPane.is())
286 : : {
287 : : // The pane has already been created and is still active (has
288 : : // not yet been released). This should not happen.
289 [ + - ]: 156 : xPane = iDescriptor->mxPane;
290 : : }
291 : : else
292 : : {
293 : : // Create a new pane.
294 [ + - + - ]: 286 : switch (iDescriptor->mePaneId)
295 : : {
296 : : case CenterPaneId:
297 [ + - ][ + - ]: 130 : xPane = CreateFrameWindowPane(rxPaneId);
298 : 130 : break;
299 : :
300 : : case FullScreenPaneId:
301 [ # # ][ # # ]: 0 : xPane = CreateFullScreenPane(mxComponentContext, rxPaneId);
302 : 0 : break;
303 : :
304 : : case LeftImpressPaneId:
305 : : case LeftDrawPaneId:
306 : : case RightPaneId:
307 : : xPane = CreateChildWindowPane(
308 : : rxPaneId,
309 [ + - ][ + - ]: 156 : *iDescriptor);
310 : 156 : break;
311 : : }
312 [ + - ]: 286 : iDescriptor->mxPane = xPane;
313 : :
314 : : // Listen for the pane being disposed.
315 [ + - ]: 286 : Reference<lang::XComponent> xComponent (xPane, UNO_QUERY);
316 [ + - ]: 286 : if (xComponent.is())
317 [ + - ][ + - ]: 286 : xComponent->addEventListener(this);
[ + - ]
318 : : }
319 : 442 : iDescriptor->mbIsReleased = false;
320 : : }
321 : : else
322 : : {
323 : : // The requested pane can not be created by any of the factories
324 : : // managed by the called BasicPaneFactory object.
325 : : throw lang::IllegalArgumentException("BasicPaneFactory::createPane() called for unknown resource id",
326 : : NULL,
327 [ # # ][ # # ]: 0 : 0);
328 : : }
329 : :
330 : 442 : return xPane;
331 : : }
332 : :
333 : :
334 : :
335 : :
336 : :
337 : 442 : void SAL_CALL BasicPaneFactory::releaseResource (
338 : : const Reference<XResource>& rxPane)
339 : : throw (RuntimeException)
340 : : {
341 [ + - ]: 442 : ThrowIfDisposed();
342 : :
343 : : // Based on the given XPane reference look up the corresponding factory
344 : : // descriptor.
345 : : PaneContainer::iterator iDescriptor (
346 : : ::std::find_if(
347 : 442 : mpPaneContainer->begin(),
348 : 442 : mpPaneContainer->end(),
349 [ + - + - ]: 1326 : ::boost::bind(&PaneDescriptor::ComparePane, _1, rxPane)));
[ + - ]
350 : :
351 [ + - ][ + - ]: 442 : if (iDescriptor != mpPaneContainer->end())
352 : : {
353 : : // The given pane was created by one of the factories. Child
354 : : // windows are just hidden and will be reused when requested later.
355 : : // Other windows are disposed and their reference is reset so that
356 : : // on the next createPane() call for the same pane type the pane is
357 : : // created anew.
358 [ + - ][ - + ]: 442 : ChildWindowPane* pChildWindowPane = dynamic_cast<ChildWindowPane*>(rxPane.get());
359 [ + + ]: 442 : if (pChildWindowPane != NULL)
360 : : {
361 : 312 : iDescriptor->mbIsReleased = true;
362 [ + - ]: 312 : pChildWindowPane->Hide();
363 : : }
364 : : else
365 : : {
366 [ + - ]: 130 : iDescriptor->mxPane = NULL;
367 [ + - ]: 130 : Reference<XComponent> xComponent (rxPane, UNO_QUERY);
368 [ + - ]: 130 : if (xComponent.is())
369 : : {
370 : : // We are disposing the pane and do not have to be informed of
371 : : // that.
372 [ + - ][ + - ]: 130 : xComponent->removeEventListener(this);
[ + - ]
373 [ + - ][ + - ]: 130 : xComponent->dispose();
374 : 130 : }
375 : : }
376 : : }
377 : : else
378 : : {
379 : : // The given XPane reference is either empty or the pane was not
380 : : // created by any of the factories managed by the called
381 : : // BasicPaneFactory object.
382 : : throw lang::IllegalArgumentException("BasicPaneFactory::releasePane() called for pane that that was not created by same factory.",
383 : : NULL,
384 [ # # ][ # # ]: 0 : 0);
385 : : }
386 : 442 : }
387 : :
388 : :
389 : :
390 : :
391 : : //===== XConfigurationChangeListener ==========================================
392 : :
393 : 694 : void SAL_CALL BasicPaneFactory::notifyConfigurationChange (
394 : : const ConfigurationChangeEvent& /* rEvent */ )
395 : : throw (RuntimeException)
396 : : {
397 : : // FIXME: nothing to do
398 : 694 : }
399 : :
400 : :
401 : :
402 : :
403 : : //===== lang::XEventListener ==================================================
404 : :
405 : 130 : void SAL_CALL BasicPaneFactory::disposing (
406 : : const lang::EventObject& rEventObject)
407 : : throw (RuntimeException)
408 : : {
409 [ + - ][ + - ]: 130 : if (mxConfigurationControllerWeak == rEventObject.Source)
410 : : {
411 [ + - ]: 130 : mxConfigurationControllerWeak = Reference<XConfigurationController>();
412 : : }
413 : : else
414 : : {
415 : : // Has one of the panes been disposed? If so, then release the
416 : : // reference to that pane, but not the pane descriptor.
417 [ # # ]: 0 : Reference<XResource> xPane (rEventObject.Source, UNO_QUERY);
418 : : PaneContainer::iterator iDescriptor (
419 : : ::std::find_if (
420 : 0 : mpPaneContainer->begin(),
421 : 0 : mpPaneContainer->end(),
422 [ # # # # ]: 0 : ::boost::bind(&PaneDescriptor::ComparePane, _1, xPane)));
[ # # ]
423 [ # # ][ # # ]: 0 : if (iDescriptor != mpPaneContainer->end())
424 : : {
425 [ # # ]: 0 : iDescriptor->mxPane = NULL;
426 : 0 : }
427 : : }
428 : 130 : }
429 : :
430 : :
431 : :
432 : :
433 : : //-----------------------------------------------------------------------------
434 : :
435 : 130 : Reference<XResource> BasicPaneFactory::CreateFrameWindowPane (
436 : : const Reference<XResourceId>& rxPaneId)
437 : : {
438 : 130 : Reference<XResource> xPane;
439 : :
440 [ + - ]: 130 : if (mpViewShellBase != NULL)
441 : : {
442 [ + - ][ + - ]: 130 : xPane = new FrameWindowPane(rxPaneId, mpViewShellBase->GetViewWindow());
[ + - ][ + - ]
443 : : }
444 : :
445 : 130 : return xPane;
446 : : }
447 : :
448 : :
449 : :
450 : :
451 : 0 : Reference<XResource> BasicPaneFactory::CreateFullScreenPane (
452 : : const Reference<XComponentContext>& rxComponentContext,
453 : : const Reference<XResourceId>& rxPaneId)
454 : : {
455 : : Reference<XResource> xPane (
456 : : new FullScreenPane(
457 : : rxComponentContext,
458 : : rxPaneId,
459 [ # # ][ # # ]: 0 : mpViewShellBase->GetViewWindow()));
[ # # ]
460 : :
461 : 0 : return xPane;
462 : : }
463 : :
464 : :
465 : :
466 : :
467 : 156 : Reference<XResource> BasicPaneFactory::CreateChildWindowPane (
468 : : const Reference<XResourceId>& rxPaneId,
469 : : const PaneDescriptor& rDescriptor)
470 : : {
471 : 156 : Reference<XResource> xPane;
472 : :
473 [ + - ]: 156 : if (mpViewShellBase != NULL)
474 : : {
475 : : // Create the corresponding shell and determine the id of the child window.
476 : 156 : sal_uInt16 nChildWindowId = 0;
477 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
478 : 156 : ::std::auto_ptr<SfxShell> pShell;
479 : : SAL_WNODEPRECATED_DECLARATIONS_POP
480 [ + + + - ]: 156 : switch (rDescriptor.mePaneId)
481 : : {
482 : : case LeftImpressPaneId:
483 [ + - ][ + - ]: 26 : pShell.reset(new LeftImpressPaneShell());
484 [ + - ]: 26 : nChildWindowId = ::sd::LeftPaneImpressChildWindow::GetChildWindowId();
485 : 26 : break;
486 : :
487 : : case LeftDrawPaneId:
488 [ + - ][ + - ]: 104 : pShell.reset(new LeftDrawPaneShell());
489 [ + - ]: 104 : nChildWindowId = ::sd::LeftPaneDrawChildWindow::GetChildWindowId();
490 : 104 : break;
491 : :
492 : : case RightPaneId:
493 [ + - ][ + - ]: 26 : pShell.reset(new ToolPanelPaneShell());
494 [ + - ]: 26 : nChildWindowId = ::sd::ToolPanelChildWindow::GetChildWindowId();
495 : 26 : break;
496 : :
497 : : default:
498 : 0 : break;
499 : : }
500 : :
501 : : // With shell and child window id create the ChildWindowPane
502 : : // wrapper.
503 [ + - ]: 156 : if (pShell.get() != NULL)
504 : : {
505 : : xPane = new ChildWindowPane(
506 : : rxPaneId,
507 : : nChildWindowId,
508 : : *mpViewShellBase,
509 [ + - ][ + - ]: 156 : pShell);
[ + - ][ + - ]
510 [ + - ]: 156 : }
511 : : }
512 : :
513 : 156 : return xPane;
514 : : }
515 : :
516 : 884 : void BasicPaneFactory::ThrowIfDisposed (void) const
517 : : throw (lang::DisposedException)
518 : : {
519 [ + - ][ - + ]: 884 : if (rBHelper.bDisposed || rBHelper.bInDispose)
520 : : {
521 : : throw lang::DisposedException ("BasicPaneFactory object has already been disposed",
522 [ # # ][ # # ]: 0 : const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
523 : : }
524 : 884 : }
525 : :
526 : :
527 [ + - ][ + - ]: 75 : } } // end of namespace sd::framework
528 : :
529 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|