1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: BasicViewFactory.cxx,v $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 #include "precompiled_sd.hxx"
34 #include "BasicViewFactory.hxx"
36 #include "framework/ViewShellWrapper.hxx"
37 #include "framework/FrameworkHelper.hxx"
38 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
39 #include <com/sun/star/lang/IllegalArgumentException.hpp>
40 #include "framework/Pane.hxx"
41 #include "DrawController.hxx"
42 #include "DrawSubController.hxx"
43 #include "ViewShellBase.hxx"
44 #include "ViewShellManager.hxx"
45 #include "DrawDocShell.hxx"
46 #include "DrawViewShell.hxx"
47 #include "GraphicViewShell.hxx"
48 #include "OutlineViewShell.hxx"
49 #include "TaskPaneViewShell.hxx"
50 #include "PresentationViewShell.hxx"
51 #include "SlideSorterViewShell.hxx"
52 #include "FrameView.hxx"
54 #include <sfx2/viewfrm.hxx>
55 #include <vcl/wrkwin.hxx>
56 #include <toolkit/helper/vclunohelper.hxx>
58 #include <boost/bind.hpp>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star::drawing::framework
;
64 using ::rtl::OUString
;
65 using ::sd::framework::FrameworkHelper
;
68 namespace sd
{ namespace framework
{
71 Reference
<XInterface
> SAL_CALL
BasicViewFactory_createInstance (
72 const Reference
<XComponentContext
>& rxContext
)
74 return Reference
<XInterface
>(static_cast<XWeak
*>(new BasicViewFactory(rxContext
)));
80 ::rtl::OUString
BasicViewFactory_getImplementationName (void) throw(RuntimeException
)
82 return ::rtl::OUString(
83 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.BasicViewFactory"));
89 Sequence
<rtl::OUString
> SAL_CALL
BasicViewFactory_getSupportedServiceNames (void)
90 throw (RuntimeException
)
92 static const ::rtl::OUString
sServiceName(
93 ::rtl::OUString::createFromAscii("com.sun.star.drawing.framework.BasicViewFactory"));
94 return Sequence
<rtl::OUString
>(&sServiceName
, 1);
100 //===== ViewDescriptor ========================================================
102 class BasicViewFactory::ViewDescriptor
105 Reference
<XResource
> mxView
;
106 ::boost::shared_ptr
<sd::ViewShell
> mpViewShell
;
107 ViewShellWrapper
* mpWrapper
;
108 Reference
<XResourceId
> mxViewId
;
109 static bool CompareView (const ::boost::shared_ptr
<ViewDescriptor
>& rpDescriptor
,
110 const Reference
<XResource
>& rxView
)
111 { return rpDescriptor
->mxView
.get() == rxView
.get(); }
118 //===== BasicViewFactory::ViewShellContainer ==================================
120 class BasicViewFactory::ViewShellContainer
121 : public ::std::vector
<boost::shared_ptr
<ViewDescriptor
> >
124 ViewShellContainer (void) {};
128 class BasicViewFactory::ViewCache
129 : public ::std::vector
<boost::shared_ptr
<ViewDescriptor
> >
138 //===== ViewFactory ===========================================================
140 BasicViewFactory::BasicViewFactory (
141 const Reference
<XComponentContext
>& rxContext
)
142 : BasicViewFactoryInterfaceBase(MutexOwner::maMutex
),
143 mxConfigurationController(),
144 mpViewShellContainer(new ViewShellContainer()),
147 mpViewCache(new ViewCache()),
148 mxLocalPane(new Pane(Reference
<XResourceId
>(), new WorkWindow(NULL
,WB_STDWORK
)))
156 BasicViewFactory::~BasicViewFactory (void)
163 void SAL_CALL
BasicViewFactory::disposing (void)
165 // Disconnect from the frame view.
166 if (mpFrameView
!= NULL
)
168 mpFrameView
->Disconnect();
172 // Relase the view cache.
173 ViewShellContainer::const_iterator iView
;
174 for (iView
=mpViewCache
->begin(); iView
!=mpViewCache
->end(); ++iView
)
176 ReleaseView(*iView
, true);
179 // Release the view shell container. At this point no one other than us
180 // should hold references to the view shells (at the moment this is a
181 // trivial requirement, because no one other then us holds a shared
183 // ViewShellContainer::const_iterator iView;
184 for (iView
=mpViewShellContainer
->begin(); iView
!=mpViewShellContainer
->end(); ++iView
)
186 OSL_ASSERT((*iView
)->mpViewShell
.unique());
188 mpViewShellContainer
.reset();
194 Reference
<XResource
> SAL_CALL
BasicViewFactory::createResource (
195 const Reference
<XResourceId
>& rxViewId
)
196 throw(RuntimeException
)
198 Reference
<XResource
> xView
;
199 const bool bIsCenterPane (
200 rxViewId
->isBoundToURL(FrameworkHelper::msCenterPaneURL
, AnchorBindingMode_DIRECT
));
202 // Get the pane for the anchor URL.
203 Reference
<XPane
> xPane
;
204 if (mxConfigurationController
.is())
205 xPane
= Reference
<XPane
>(mxConfigurationController
->getResource(rxViewId
->getAnchor()),
208 // For main views use the frame view of the last main view.
209 ::sd::FrameView
* pFrameView
= NULL
;
210 if (xPane
.is() && bIsCenterPane
)
212 pFrameView
= mpFrameView
;
215 // Get Window pointer for XWindow of the pane.
216 ::Window
* pWindow
= NULL
;
218 pWindow
= VCLUnoHelper::GetWindow(xPane
->getWindow());
220 // Get the view frame.
221 SfxViewFrame
* pFrame
= NULL
;
223 pFrame
= mpBase
->GetViewFrame();
225 if (pFrame
!= NULL
&& mpBase
!=NULL
&& pWindow
!=NULL
)
227 // Try to get the view from the cache.
228 ::boost::shared_ptr
<ViewDescriptor
> pDescriptor (GetViewFromCache(rxViewId
, xPane
));
230 // When the requested view is not in the cache then create a new view.
231 if (pDescriptor
.get() == NULL
)
233 pDescriptor
= CreateView(rxViewId
, *pFrame
, *pWindow
, xPane
, pFrameView
);
236 if (pDescriptor
.get() != NULL
)
237 xView
= pDescriptor
->mxView
;
239 mpViewShellContainer
->push_back(pDescriptor
);
242 ActivateCenterView(pDescriptor
);
253 void SAL_CALL
BasicViewFactory::releaseResource (const Reference
<XResource
>& rxView
)
254 throw(RuntimeException
)
257 throw lang::IllegalArgumentException();
259 if (rxView
.is() && mpBase
!=NULL
)
261 ViewShellContainer::iterator
iViewShell (
263 mpViewShellContainer
->begin(),
264 mpViewShellContainer
->end(),
265 ::boost::bind(&ViewDescriptor::CompareView
, _1
, rxView
)));
266 if (iViewShell
!= mpViewShellContainer
->end())
268 ::boost::shared_ptr
<ViewShell
> pViewShell ((*iViewShell
)->mpViewShell
);
270 if ((*iViewShell
)->mxViewId
->isBoundToURL(
271 FrameworkHelper::msCenterPaneURL
, AnchorBindingMode_DIRECT
))
273 // Obtain a pointer to and connect to the frame view of the
274 // view. The next view, that is created, will be
275 // initialized with this frame view.
276 if (mpFrameView
== NULL
)
278 mpFrameView
= pViewShell
->GetFrameView();
280 mpFrameView
->Connect();
283 // With the view in the center pane the sub controller is
285 mpBase
->GetDrawController().SetSubController(
286 Reference
<drawing::XDrawSubController
>());
288 SfxViewShell
* pSfxViewShell
= pViewShell
->GetViewShell();
289 if (pSfxViewShell
!= NULL
)
290 pSfxViewShell
->DisconnectAllClients();
293 ReleaseView(*iViewShell
);
295 mpViewShellContainer
->erase(iViewShell
);
299 throw lang::IllegalArgumentException();
307 void SAL_CALL
BasicViewFactory::initialize (const Sequence
<Any
>& aArguments
)
308 throw (Exception
, RuntimeException
)
310 if (aArguments
.getLength() > 0)
312 Reference
<XConfigurationController
> xCC
;
315 // Get the XController from the first argument.
316 Reference
<frame::XController
> xController (aArguments
[0], UNO_QUERY_THROW
);
318 // Tunnel through the controller to obtain a ViewShellBase.
319 Reference
<lang::XUnoTunnel
> xTunnel (xController
, UNO_QUERY_THROW
);
320 ::sd::DrawController
* pController
= reinterpret_cast<sd::DrawController
*>(
321 xTunnel
->getSomething(sd::DrawController::getUnoTunnelId()));
322 if (pController
!= NULL
)
323 mpBase
= pController
->GetViewShellBase();
325 // Register the factory for its supported views.
326 Reference
<XControllerManager
> xCM (xController
,UNO_QUERY_THROW
);
327 mxConfigurationController
= xCM
->getConfigurationController();
328 if ( ! mxConfigurationController
.is())
329 throw RuntimeException();
330 mxConfigurationController
->addResourceFactory(FrameworkHelper::msImpressViewURL
, this);
331 mxConfigurationController
->addResourceFactory(FrameworkHelper::msDrawViewURL
, this);
332 mxConfigurationController
->addResourceFactory(FrameworkHelper::msOutlineViewURL
, this);
333 mxConfigurationController
->addResourceFactory(FrameworkHelper::msNotesViewURL
, this);
334 mxConfigurationController
->addResourceFactory(FrameworkHelper::msHandoutViewURL
, this);
335 mxConfigurationController
->addResourceFactory(FrameworkHelper::msPresentationViewURL
, this);
336 mxConfigurationController
->addResourceFactory(FrameworkHelper::msTaskPaneURL
, this);
337 mxConfigurationController
->addResourceFactory(FrameworkHelper::msSlideSorterURL
, this);
339 catch (RuntimeException
&)
342 if (mxConfigurationController
.is())
343 mxConfigurationController
->removeResourceFactoryForReference(this);
352 ::boost::shared_ptr
<BasicViewFactory::ViewDescriptor
> BasicViewFactory::CreateView (
353 const Reference
<XResourceId
>& rxViewId
,
354 SfxViewFrame
& rFrame
,
356 const Reference
<XPane
>& rxPane
,
357 FrameView
* pFrameView
)
359 ::boost::shared_ptr
<ViewDescriptor
> pDescriptor (new ViewDescriptor());
361 pDescriptor
->mpViewShell
= CreateViewShell(
366 pDescriptor
->mxViewId
= rxViewId
;
368 if (pDescriptor
->mpViewShell
.get() != NULL
)
370 const bool bIsCenterPane (
371 rxViewId
->isBoundToURL(FrameworkHelper::msCenterPaneURL
, AnchorBindingMode_DIRECT
));
372 pDescriptor
->mpViewShell
->Init(bIsCenterPane
);
373 mpBase
->GetViewShellManager()->ActivateViewShell(pDescriptor
->mpViewShell
.get());
375 pDescriptor
->mpWrapper
= new ViewShellWrapper(
376 pDescriptor
->mpViewShell
,
378 rxPane
->getWindow());
379 pDescriptor
->mxView
= Reference
<XResource
>(pDescriptor
->mpWrapper
);
388 ::boost::shared_ptr
<ViewShell
> BasicViewFactory::CreateViewShell (
389 const Reference
<XResourceId
>& rxViewId
,
390 SfxViewFrame
& rFrame
,
392 FrameView
* pFrameView
)
394 ::boost::shared_ptr
<ViewShell
> pViewShell
;
395 const OUString
& rsViewURL (rxViewId
->getResourceURL());
396 if (rsViewURL
.equals(FrameworkHelper::msImpressViewURL
))
406 else if (rsViewURL
.equals(FrameworkHelper::msDrawViewURL
))
409 new GraphicViewShell (
415 else if (rsViewURL
.equals(FrameworkHelper::msOutlineViewURL
))
418 new OutlineViewShell (
424 else if (rsViewURL
.equals(FrameworkHelper::msNotesViewURL
))
434 else if (rsViewURL
.equals(FrameworkHelper::msHandoutViewURL
))
444 else if (rsViewURL
.equals(FrameworkHelper::msPresentationViewURL
))
447 new PresentationViewShell(
453 else if (rsViewURL
.equals(FrameworkHelper::msTaskPaneURL
))
456 new ::sd::toolpanel::TaskPaneViewShell (
462 else if (rsViewURL
.equals(FrameworkHelper::msSlideSorterURL
))
464 pViewShell
= ::sd::slidesorter::SlideSorterViewShell::Create (
477 void BasicViewFactory::ReleaseView (
478 const ::boost::shared_ptr
<ViewDescriptor
>& rpDescriptor
,
481 bool bIsCacheable (!bDoNotCache
&& IsCacheable(rpDescriptor
));
485 Reference
<XRelocatableResource
> xResource (rpDescriptor
->mxView
, UNO_QUERY
);
488 Reference
<XResource
> xNewAnchor (mxLocalPane
, UNO_QUERY
);
490 if (xResource
->relocateToAnchor(xNewAnchor
))
491 mpViewCache
->push_back(rpDescriptor
);
493 bIsCacheable
= false;
495 bIsCacheable
= false;
499 bIsCacheable
= false;
505 // Shut down the current view shell.
506 rpDescriptor
->mpViewShell
->Shutdown ();
507 mpBase
->GetDocShell()->Disconnect(rpDescriptor
->mpViewShell
.get());
508 mpBase
->GetViewShellManager()->DeactivateViewShell(rpDescriptor
->mpViewShell
.get());
510 Reference
<XComponent
> xComponent (rpDescriptor
->mxView
, UNO_QUERY
);
512 xComponent
->dispose();
519 bool BasicViewFactory::IsCacheable (const ::boost::shared_ptr
<ViewDescriptor
>& rpDescriptor
)
521 bool bIsCacheable (false);
523 Reference
<XRelocatableResource
> xResource (rpDescriptor
->mxView
, UNO_QUERY
);
526 static ::std::vector
<Reference
<XResourceId
> > maCacheableResources
;
527 if (maCacheableResources
.size() == 0)
529 ::boost::shared_ptr
<FrameworkHelper
> pHelper (FrameworkHelper::Instance(*mpBase
));
531 // The slide sorter and the task panel are cacheable and relocatable.
532 maCacheableResources
.push_back(pHelper
->CreateResourceId(
533 FrameworkHelper::msSlideSorterURL
, FrameworkHelper::msLeftDrawPaneURL
));
534 maCacheableResources
.push_back(pHelper
->CreateResourceId(
535 FrameworkHelper::msSlideSorterURL
, FrameworkHelper::msLeftImpressPaneURL
));
536 maCacheableResources
.push_back(pHelper
->CreateResourceId(
537 FrameworkHelper::msTaskPaneURL
, FrameworkHelper::msRightPaneURL
));
540 ::std::vector
<Reference
<XResourceId
> >::const_iterator iId
;
541 for (iId
=maCacheableResources
.begin(); iId
!=maCacheableResources
.end(); ++iId
)
543 if ((*iId
)->compareTo(rpDescriptor
->mxViewId
) == 0)
557 ::boost::shared_ptr
<BasicViewFactory::ViewDescriptor
> BasicViewFactory::GetViewFromCache (
558 const Reference
<XResourceId
>& rxViewId
,
559 const Reference
<XPane
>& rxPane
)
561 ::boost::shared_ptr
<ViewDescriptor
> pDescriptor
;
563 // Search for the requested view in the cache.
564 ViewCache::iterator iEntry
;
565 for (iEntry
=mpViewCache
->begin(); iEntry
!=mpViewCache
->end(); ++iEntry
)
567 if ((*iEntry
)->mxViewId
->compareTo(rxViewId
) == 0)
569 pDescriptor
= *iEntry
;
570 mpViewCache
->erase(iEntry
);
575 // When the view has been found then relocate it to the given pane and
576 // remove it from the cache.
577 if (pDescriptor
.get() != NULL
)
579 bool bRelocationSuccessfull (false);
580 Reference
<XRelocatableResource
> xResource (pDescriptor
->mxView
, UNO_QUERY
);
581 Reference
<XResource
> xNewAnchor (rxPane
, UNO_QUERY
);
582 if (xResource
.is() && xNewAnchor
.is())
584 if (xResource
->relocateToAnchor(xNewAnchor
))
585 bRelocationSuccessfull
= true;
588 if ( ! bRelocationSuccessfull
)
590 ReleaseView(pDescriptor
, true);
601 void BasicViewFactory::ActivateCenterView (
602 const ::boost::shared_ptr
<ViewDescriptor
>& rpDescriptor
)
604 mpBase
->GetDocShell()->Connect(rpDescriptor
->mpViewShell
.get());
606 // During the creation of the new sub-shell, resize requests were not
607 // forwarded to it because it was not yet registered. Therefore, we
608 // have to request a resize now.
609 rpDescriptor
->mpViewShell
->UIFeatureChanged();
610 if (mpBase
->GetDocShell()->IsInPlaceActive())
611 mpBase
->GetViewFrame()->Resize(TRUE
);
613 mpBase
->GetDrawController().SetSubController(
614 rpDescriptor
->mpViewShell
->CreateSubController());
617 } } // end of namespace sd::framework