merge the formfield patch from ooo-build
[ooovba.git] / sd / source / ui / framework / factories / BasicViewFactory.cxx
blob519580f47fe71b2b893fa1708c1243f344524405
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: BasicViewFactory.cxx,v $
11 * $Revision: 1.4 $
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
104 public:
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> >
123 public:
124 ViewShellContainer (void) {};
128 class BasicViewFactory::ViewCache
129 : public ::std::vector<boost::shared_ptr<ViewDescriptor> >
131 public:
132 ViewCache (void) {};
138 //===== ViewFactory ===========================================================
140 BasicViewFactory::BasicViewFactory (
141 const Reference<XComponentContext>& rxContext)
142 : BasicViewFactoryInterfaceBase(MutexOwner::maMutex),
143 mxConfigurationController(),
144 mpViewShellContainer(new ViewShellContainer()),
145 mpBase(NULL),
146 mpFrameView(NULL),
147 mpViewCache(new ViewCache()),
148 mxLocalPane(new Pane(Reference<XResourceId>(), new WorkWindow(NULL,WB_STDWORK)))
150 (void)rxContext;
156 BasicViewFactory::~BasicViewFactory (void)
163 void SAL_CALL BasicViewFactory::disposing (void)
165 // Disconnect from the frame view.
166 if (mpFrameView != NULL)
168 mpFrameView->Disconnect();
169 mpFrameView = NULL;
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
182 // pointer).
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()),
206 UNO_QUERY);
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;
217 if (xPane.is())
218 pWindow = VCLUnoHelper::GetWindow(xPane->getWindow());
220 // Get the view frame.
221 SfxViewFrame* pFrame = NULL;
222 if (mpBase != 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);
241 if (bIsCenterPane)
242 ActivateCenterView(pDescriptor);
243 else
244 pWindow->Resize();
247 return xView;
253 void SAL_CALL BasicViewFactory::releaseResource (const Reference<XResource>& rxView)
254 throw(RuntimeException)
256 if ( ! rxView.is())
257 throw lang::IllegalArgumentException();
259 if (rxView.is() && mpBase!=NULL)
261 ViewShellContainer::iterator iViewShell (
262 ::std::find_if(
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();
279 if (mpFrameView)
280 mpFrameView->Connect();
283 // With the view in the center pane the sub controller is
284 // released, too.
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);
297 else
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&)
341 mpBase = NULL;
342 if (mxConfigurationController.is())
343 mxConfigurationController->removeResourceFactoryForReference(this);
344 throw;
352 ::boost::shared_ptr<BasicViewFactory::ViewDescriptor> BasicViewFactory::CreateView (
353 const Reference<XResourceId>& rxViewId,
354 SfxViewFrame& rFrame,
355 ::Window& rWindow,
356 const Reference<XPane>& rxPane,
357 FrameView* pFrameView)
359 ::boost::shared_ptr<ViewDescriptor> pDescriptor (new ViewDescriptor());
361 pDescriptor->mpViewShell = CreateViewShell(
362 rxViewId,
363 rFrame,
364 rWindow,
365 pFrameView);
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,
377 rxViewId,
378 rxPane->getWindow());
379 pDescriptor->mxView = Reference<XResource>(pDescriptor->mpWrapper);
382 return pDescriptor;
388 ::boost::shared_ptr<ViewShell> BasicViewFactory::CreateViewShell (
389 const Reference<XResourceId>& rxViewId,
390 SfxViewFrame& rFrame,
391 ::Window& rWindow,
392 FrameView* pFrameView)
394 ::boost::shared_ptr<ViewShell> pViewShell;
395 const OUString& rsViewURL (rxViewId->getResourceURL());
396 if (rsViewURL.equals(FrameworkHelper::msImpressViewURL))
398 pViewShell.reset(
399 new DrawViewShell(
400 &rFrame,
401 *mpBase,
402 &rWindow,
403 PK_STANDARD,
404 pFrameView));
406 else if (rsViewURL.equals(FrameworkHelper::msDrawViewURL))
408 pViewShell.reset(
409 new GraphicViewShell (
410 &rFrame,
411 *mpBase,
412 &rWindow,
413 pFrameView));
415 else if (rsViewURL.equals(FrameworkHelper::msOutlineViewURL))
417 pViewShell.reset(
418 new OutlineViewShell (
419 &rFrame,
420 *mpBase,
421 &rWindow,
422 pFrameView));
424 else if (rsViewURL.equals(FrameworkHelper::msNotesViewURL))
426 pViewShell.reset(
427 new DrawViewShell(
428 &rFrame,
429 *mpBase,
430 &rWindow,
431 PK_NOTES,
432 pFrameView));
434 else if (rsViewURL.equals(FrameworkHelper::msHandoutViewURL))
436 pViewShell.reset(
437 new DrawViewShell(
438 &rFrame,
439 *mpBase,
440 &rWindow,
441 PK_HANDOUT,
442 pFrameView));
444 else if (rsViewURL.equals(FrameworkHelper::msPresentationViewURL))
446 pViewShell.reset(
447 new PresentationViewShell(
448 &rFrame,
449 *mpBase,
450 &rWindow,
451 pFrameView));
453 else if (rsViewURL.equals(FrameworkHelper::msTaskPaneURL))
455 pViewShell.reset(
456 new ::sd::toolpanel::TaskPaneViewShell (
457 &rFrame,
458 *mpBase,
459 &rWindow,
460 pFrameView));
462 else if (rsViewURL.equals(FrameworkHelper::msSlideSorterURL))
464 pViewShell = ::sd::slidesorter::SlideSorterViewShell::Create (
465 &rFrame,
466 *mpBase,
467 &rWindow,
468 pFrameView);
471 return pViewShell;
477 void BasicViewFactory::ReleaseView (
478 const ::boost::shared_ptr<ViewDescriptor>& rpDescriptor,
479 bool bDoNotCache)
481 bool bIsCacheable (!bDoNotCache && IsCacheable(rpDescriptor));
483 if (bIsCacheable)
485 Reference<XRelocatableResource> xResource (rpDescriptor->mxView, UNO_QUERY);
486 if (xResource.is())
488 Reference<XResource> xNewAnchor (mxLocalPane, UNO_QUERY);
489 if (xNewAnchor.is())
490 if (xResource->relocateToAnchor(xNewAnchor))
491 mpViewCache->push_back(rpDescriptor);
492 else
493 bIsCacheable = false;
494 else
495 bIsCacheable = false;
497 else
499 bIsCacheable = false;
503 if ( ! bIsCacheable)
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);
511 if (xComponent.is())
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);
524 if (xResource.is())
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)
545 bIsCacheable = true;
546 break;
551 return bIsCacheable;
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);
571 break;
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);
591 pDescriptor.reset();
595 return pDescriptor;
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