1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 
27 #include "DrawController.hxx"
28 #include "DrawDocShell.hxx"
29 
30 #include "DrawSubController.hxx"
31 #include "sdpage.hxx"
32 #include "ViewShellBase.hxx"
33 #include "ViewShellManager.hxx"
34 #include "FormShellManager.hxx"
35 #include "Window.hxx"
36 
37 #include <comphelper/anytostring.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/sequence.hxx>
40 #include <comphelper/stl_types.hxx>
41 #include <cppuhelper/exc_hlp.hxx>
42 #include <cppuhelper/bootstrap.hxx>
43 
44 #include <com/sun/star/beans/PropertyAttribute.hpp>
45 #include <com/sun/star/drawing/framework/ConfigurationController.hpp>
46 #include <com/sun/star/drawing/framework/ModuleController.hpp>
47 #include <com/sun/star/lang/XInitialization.hpp>
48 
49 #include "slideshow.hxx"
50 
51 #include <svx/fmshell.hxx>
52 #include <vos/mutex.hxx>
53 #include <vcl/svapp.hxx>
54 #include <boost/shared_ptr.hpp>
55 
56 using namespace ::std;
57 using ::rtl::OUString;
58 using namespace ::cppu;
59 using namespace ::vos;
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::drawing::framework;
63 
64 namespace {
65 static const ::com::sun::star::uno::Type saComponentTypeIdentifier (
66     ::getCppuType( (Reference<lang::XEventListener > *)0 ));
67 static const ::com::sun::star::uno::Type saSelectionTypeIdentifier (
68     ::getCppuType( (Reference<view::XSelectionChangeListener > *)0 ));
69 
70 } // end of anonymous namespace
71 
72 namespace sd {
73 
74 DrawController::DrawController (ViewShellBase& rBase) throw()
75     : DrawControllerInterfaceBase(&rBase),
76       BroadcastHelperOwner(SfxBaseController::m_aMutex),
77       OPropertySetHelper( static_cast<OBroadcastHelperVar<
78           OMultiTypeInterfaceContainerHelper,
79           OMultiTypeInterfaceContainerHelper::keyType>& >(
80               BroadcastHelperOwner::maBroadcastHelper)),
81       mpBase(&rBase),
82       maLastVisArea(),
83       mpCurrentPage(NULL),
84       mbMasterPageMode(false),
85       mbLayerMode(false),
86       mbDisposing(false),
87       mpPropertyArrayHelper(NULL),
88       mxSubController(),
89       mxConfigurationController(),
90       mxModuleController()
91 {
92     ProvideFrameworkControllers();
93 }
94 
95 
96 
97 
98 DrawController::~DrawController (void) throw()
99 {
100 }
101 
102 
103 
104 
105 void DrawController::SetSubController (
106     const Reference<drawing::XDrawSubController>& rxSubController)
107 {
108     // Update the internal state.
109     mxSubController = rxSubController;
110     mpPropertyArrayHelper.reset();
111     maLastVisArea = Rectangle();
112 
113     // Inform listeners about the changed state.
114     FireSelectionChangeListener();
115 }
116 
117 
118 
119 
120 // XInterface
121 
122 IMPLEMENT_FORWARD_XINTERFACE2(
123     DrawController,
124     DrawControllerInterfaceBase,
125     OPropertySetHelper);
126 
127 
128 // XTypeProvider
129 
130 Sequence<Type> SAL_CALL DrawController::getTypes (void)
131     throw (::com::sun::star::uno::RuntimeException)
132 {
133     ThrowIfDisposed();
134     // OPropertySetHelper does not provide getTypes, so we have to
135     // implement this method manually and list its three interfaces.
136     OTypeCollection aTypeCollection (
137         ::getCppuType (( const Reference<beans::XMultiPropertySet>*)NULL),
138         ::getCppuType (( const Reference<beans::XFastPropertySet>*)NULL),
139         ::getCppuType (( const Reference<beans::XPropertySet>*)NULL));
140 
141     return ::comphelper::concatSequences(
142         SfxBaseController::getTypes(),
143         aTypeCollection.getTypes(),
144         DrawControllerInterfaceBase::getTypes());
145 }
146 
147 IMPLEMENT_GET_IMPLEMENTATION_ID(DrawController);
148 
149 
150 
151 // XComponent
152 
153 
154 void SAL_CALL DrawController::dispose (void)
155 	throw( RuntimeException )
156 {
157 	if( !mbDisposing )
158 	{
159 		OGuard aGuard( Application::GetSolarMutex() );
160 
161 		if( !mbDisposing )
162 		{
163 			mbDisposing = true;
164 
165             boost::shared_ptr<ViewShell> pViewShell = mpBase->GetMainViewShell();
166             if ( pViewShell )
167             {
168                 pViewShell->DeactivateCurrentFunction();
169                 DrawDocShell* pDocShell = pViewShell->GetDocSh();
170                 if ( pDocShell != NULL )
171                     pDocShell->SetDocShellFunction(0);
172             }
173             pViewShell.reset();
174 
175             // When the controller has not been detached from its view
176             // shell, i.e. mpViewShell is not NULL, then tell PaneManager
177             // and ViewShellManager to clear the shell stack.
178             if (mxSubController.is() && mpBase!=NULL)
179             {
180                 mpBase->DisconnectAllClients();
181                 mpBase->GetViewShellManager()->Shutdown();
182             }
183 
184             OPropertySetHelper::disposing();
185 
186             DisposeFrameworkControllers();
187 
188 			SfxBaseController::dispose();
189 		}
190 	}
191 }
192 
193 
194 
195 
196 void SAL_CALL DrawController::addEventListener(
197     const Reference<lang::XEventListener >& xListener)
198     throw (RuntimeException)
199 {
200     ThrowIfDisposed();
201 	SfxBaseController::addEventListener( xListener );
202 }
203 
204 
205 
206 
207 void SAL_CALL DrawController::removeEventListener (
208     const Reference<lang::XEventListener >& aListener)
209     throw (RuntimeException)
210 {
211 	if(!rBHelper.bDisposed && !rBHelper.bInDispose && !mbDisposing)
212 		SfxBaseController::removeEventListener( aListener );
213 }
214 
215 // XController
216 ::sal_Bool SAL_CALL DrawController::suspend( ::sal_Bool Suspend ) throw (::com::sun::star::uno::RuntimeException)
217 {
218 	if( Suspend )
219 	{
220 		ViewShellBase* pViewShellBase = GetViewShellBase();
221 		if( pViewShellBase )
222 		{
223 			// do not allow suspend if a slideshow needs this controller!
224 			rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( *pViewShellBase ) );
225 			if( xSlideShow.is() && xSlideShow->dependsOn(pViewShellBase) )
226 				return sal_False;
227 		}
228 	}
229 
230 	return SfxBaseController::suspend( Suspend );
231 }
232 
233 
234 // XServiceInfo
235 
236 OUString SAL_CALL DrawController::getImplementationName(  ) throw(RuntimeException)
237 {
238     // Do not throw an excepetion at the moment.  This leads to a crash
239     // under Solaris on relead.  See issue i70929 for details.
240     //    ThrowIfDisposed();
241 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "DrawController" ) );
242 }
243 
244 
245 
246 static OUString ssServiceName (OUString::createFromAscii(
247     "com.sun.star.drawing.DrawingDocumentDrawView"));
248 
249 sal_Bool SAL_CALL DrawController::supportsService (
250     const OUString& rsServiceName)
251     throw(RuntimeException)
252 {
253     // Do not throw an excepetion at the moment.  This leads to a crash
254     // under Solaris on relead.  See issue i70929 for details.
255     //    ThrowIfDisposed();
256     return rsServiceName.equals(ssServiceName);
257 }
258 
259 
260 
261 
262 Sequence<OUString> SAL_CALL DrawController::getSupportedServiceNames (void)
263     throw(RuntimeException)
264 {
265     ThrowIfDisposed();
266 	Sequence<OUString> aSupportedServices (1);
267 	OUString* pServices = aSupportedServices.getArray();
268     pServices[0] = ssServiceName;
269 	return aSupportedServices;
270 }
271 
272 
273 
274 
275 //------ XSelectionSupplier --------------------------------------------
276 
277 sal_Bool SAL_CALL DrawController::select (const Any& aSelection)
278 	throw(lang::IllegalArgumentException, RuntimeException)
279 {
280     ThrowIfDisposed();
281 	::vos::OGuard aGuard (Application::GetSolarMutex());
282 
283     if (mxSubController.is())
284         return mxSubController->select(aSelection);
285     else
286         return false;
287 }
288 
289 
290 
291 
292 Any SAL_CALL DrawController::getSelection()
293 	throw(RuntimeException)
294 {
295     ThrowIfDisposed();
296 	::vos::OGuard aGuard (Application::GetSolarMutex());
297 
298     if (mxSubController.is())
299         return mxSubController->getSelection();
300     else
301         return Any();
302 }
303 
304 
305 
306 
307 void SAL_CALL DrawController::addSelectionChangeListener(
308     const Reference< view::XSelectionChangeListener >& xListener)
309 	throw(RuntimeException)
310 {
311 	if( mbDisposing )
312 		throw lang::DisposedException();
313 
314     BroadcastHelperOwner::maBroadcastHelper.addListener (saSelectionTypeIdentifier, xListener);
315 }
316 
317 
318 
319 
320 void SAL_CALL DrawController::removeSelectionChangeListener(
321     const Reference< view::XSelectionChangeListener >& xListener )
322     throw(RuntimeException)
323 {
324     if (rBHelper.bDisposed)
325         throw lang::DisposedException();
326 
327 	BroadcastHelperOwner::maBroadcastHelper.removeListener (saSelectionTypeIdentifier, xListener);
328 }
329 
330 
331 
332 
333 
334 //=====  lang::XEventListener  ================================================
335 
336 void SAL_CALL
337     DrawController::disposing (const lang::EventObject& )
338     throw (uno::RuntimeException)
339 {
340 }
341 
342 
343 
344 
345 //=====  view::XSelectionChangeListener  ======================================
346 
347 void  SAL_CALL
348     DrawController::selectionChanged (const lang::EventObject& rEvent)
349         throw (uno::RuntimeException)
350 {
351     ThrowIfDisposed();
352     // Have to forward the event to our selection change listeners.
353 	OInterfaceContainerHelper* pListeners = BroadcastHelperOwner::maBroadcastHelper.getContainer(
354         ::getCppuType((Reference<view::XSelectionChangeListener>*)0));
355 	if (pListeners)
356 	{
357 		// Re-send the event to all of our listeners.
358 		OInterfaceIteratorHelper aIterator (*pListeners);
359 		while (aIterator.hasMoreElements())
360 		{
361             try
362             {
363                 view::XSelectionChangeListener* pListener =
364                     static_cast<view::XSelectionChangeListener*>(
365                         aIterator.next());
366                 if (pListener != NULL)
367                     pListener->selectionChanged (rEvent);
368             }
369             catch (RuntimeException aException)
370             {
371             }
372 		}
373 	}
374 }
375 
376 
377 
378 
379 // XDrawView
380 
381 void SAL_CALL DrawController::setCurrentPage( const Reference< drawing::XDrawPage >& xPage )
382 	throw(RuntimeException)
383 {
384     ThrowIfDisposed();
385     ::vos::OGuard aGuard (Application::GetSolarMutex());
386 
387     if (mxSubController.is())
388         mxSubController->setCurrentPage(xPage);
389 }
390 
391 
392 
393 
394 Reference< drawing::XDrawPage > SAL_CALL DrawController::getCurrentPage (void)
395 	throw(RuntimeException)
396 {
397     ThrowIfDisposed();
398 	::vos::OGuard aGuard( Application::GetSolarMutex() );
399     Reference<drawing::XDrawPage> xPage;
400 
401     // Get current page from sub controller.
402     if (mxSubController.is())
403         xPage = mxSubController->getCurrentPage();
404 
405     // When there is not yet a sub controller (during initialization) then fall back
406     // to the current page in mpCurrentPage.
407     if ( ! xPage.is() && mpCurrentPage.is())
408         xPage = Reference<drawing::XDrawPage>(mpCurrentPage->getUnoPage(), UNO_QUERY);
409 
410 	return xPage;
411 }
412 
413 
414 
415 
416 void DrawController::FireVisAreaChanged (const Rectangle& rVisArea) throw()
417 {
418 	if( maLastVisArea != rVisArea )
419 	{
420 		Any aNewValue;
421 		aNewValue <<= awt::Rectangle(
422             rVisArea.Left(),
423             rVisArea.Top(),
424             rVisArea.GetWidth(),
425             rVisArea.GetHeight() );
426 
427 		Any aOldValue;
428 		aOldValue <<= awt::Rectangle(
429             maLastVisArea.Left(),
430             maLastVisArea.Top(),
431             maLastVisArea.GetWidth(),
432             maLastVisArea.GetHeight() );
433 
434         FirePropertyChange (PROPERTY_WORKAREA, aNewValue, aOldValue);
435 
436 		maLastVisArea = rVisArea;
437 	}
438 }
439 
440 
441 
442 
443 void DrawController::FireSelectionChangeListener() throw()
444 {
445 	OInterfaceContainerHelper * pLC = BroadcastHelperOwner::maBroadcastHelper.getContainer(
446         saSelectionTypeIdentifier);
447 	if( pLC )
448 	{
449 		Reference< XInterface > xSource( (XWeak*)this );
450 		const lang::EventObject aEvent( xSource );
451 
452 		// Ueber alle Listener iterieren und Events senden
453 		OInterfaceIteratorHelper aIt( *pLC);
454 		while( aIt.hasMoreElements() )
455 		{
456             try
457             {
458                 view::XSelectionChangeListener * pL =
459                     static_cast<view::XSelectionChangeListener*>(aIt.next());
460                 if (pL != NULL)
461                     pL->selectionChanged( aEvent );
462             }
463             catch (RuntimeException aException)
464             {
465             }
466 		}
467 	}
468 }
469 
470 
471 
472 
473 void DrawController::FireChangeEditMode (bool bMasterPageMode) throw()
474 {
475 	if (bMasterPageMode != mbMasterPageMode )
476 	{
477         FirePropertyChange(
478             PROPERTY_MASTERPAGEMODE,
479             makeAny(bMasterPageMode),
480             makeAny(mbMasterPageMode));
481 
482 		mbMasterPageMode = bMasterPageMode;
483 	}
484 }
485 
486 
487 
488 
489 void DrawController::FireChangeLayerMode (bool bLayerMode) throw()
490 {
491 	if (bLayerMode != mbLayerMode)
492 	{
493         FirePropertyChange(
494             PROPERTY_LAYERMODE,
495             makeAny(bLayerMode),
496             makeAny(mbLayerMode));
497 
498 		mbLayerMode = bLayerMode;
499 	}
500 }
501 
502 
503 
504 
505 void DrawController::FireSwitchCurrentPage (SdPage* pNewCurrentPage) throw()
506 {
507     SdrPage* pCurrentPage  = mpCurrentPage.get();
508     if (pNewCurrentPage != pCurrentPage)
509     {
510         try
511         {
512             Any aNewValue (
513                 makeAny(Reference<drawing::XDrawPage>(pNewCurrentPage->getUnoPage(), UNO_QUERY)));
514 
515             Any aOldValue;
516             if (pCurrentPage != NULL)
517             {
518                 Reference<drawing::XDrawPage> xOldPage (pCurrentPage->getUnoPage(), UNO_QUERY);
519                 aOldValue <<= xOldPage;
520             }
521 
522             FirePropertyChange(PROPERTY_CURRENTPAGE, aNewValue, aOldValue);
523 
524             mpCurrentPage.reset(pNewCurrentPage);
525         }
526         catch( uno::Exception& e )
527         {
528             (void)e;
529             DBG_ERROR(
530                 (::rtl::OString("sd::SdUnoDrawView::FireSwitchCurrentPage(), "
531                     "exception caught: ") +
532                     ::rtl::OUStringToOString(
533                         comphelper::anyToString( cppu::getCaughtException() ),
534                         RTL_TEXTENCODING_UTF8 )).getStr() );
535         }
536     }
537 }
538 
539 
540 
541 
542 void DrawController::FirePropertyChange (
543     sal_Int32 nHandle,
544     const Any& rNewValue,
545     const Any& rOldValue)
546 {
547     try
548     {
549         fire (&nHandle, &rNewValue, &rOldValue, 1, sal_False);
550     }
551     catch (RuntimeException aException)
552     {
553         // Ignore this exception.  Exceptions should be handled in the
554         // fire() function so that all listeners are called.  This is
555         // not the case at the moment, so we simply ignore the
556         // exception.
557     }
558 
559 }
560 
561 
562 
563 
564 ViewShellBase* DrawController::GetViewShellBase (void)
565 {
566     return mpBase;
567 }
568 
569 
570 
571 
572 void DrawController::ReleaseViewShellBase (void)
573 {
574     DisposeFrameworkControllers();
575     mpBase = NULL;
576 }
577 
578 
579 
580 
581 //===== XControllerManager ==============================================================
582 
583 Reference<XConfigurationController> SAL_CALL
584     DrawController::getConfigurationController (void)
585     throw (RuntimeException)
586 {
587     ThrowIfDisposed();
588 
589     return mxConfigurationController;
590 }
591 
592 
593 
594 
595 Reference<XModuleController> SAL_CALL
596     DrawController::getModuleController (void)
597     throw (RuntimeException)
598 {
599     ThrowIfDisposed();
600 
601     return mxModuleController;
602 }
603 
604 
605 
606 
607 //===== XUnoTunnel ============================================================
608 
609 const Sequence<sal_Int8>& DrawController::getUnoTunnelId (void)
610 {
611 	static ::com::sun::star::uno::Sequence<sal_Int8>* pSequence = NULL;
612 	if (pSequence == NULL)
613 	{
614 		::osl::Guard< ::osl::Mutex > aGuard (::osl::Mutex::getGlobalMutex());
615 		if (pSequence == NULL)
616 		{
617 			static ::com::sun::star::uno::Sequence<sal_Int8> aSequence (16);
618 			rtl_createUuid((sal_uInt8*)aSequence.getArray(), 0, sal_True);
619 			pSequence = &aSequence;
620 		}
621 	}
622 	return *pSequence;
623 }
624 
625 
626 
627 
628 sal_Int64 SAL_CALL DrawController::getSomething (const Sequence<sal_Int8>& rId)
629     throw (RuntimeException)
630 {
631     sal_Int64 nResult = 0;
632 
633     if (rId.getLength() == 16
634         && rtl_compareMemory(getUnoTunnelId().getConstArray(), rId.getConstArray(), 16) == 0)
635 	{
636 		nResult = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
637 	}
638 
639     return nResult;
640 }
641 
642 
643 
644 
645 //===== Properties ============================================================
646 
647 void DrawController::FillPropertyTable (
648     ::std::vector<beans::Property>& rProperties)
649 {
650     rProperties.push_back(
651         beans::Property(
652             OUString( RTL_CONSTASCII_USTRINGPARAM("VisibleArea") ),
653             PROPERTY_WORKAREA,
654             ::getCppuType((const ::com::sun::star::awt::Rectangle*)0),
655             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY));
656     rProperties.push_back(
657         beans::Property(
658             OUString( RTL_CONSTASCII_USTRINGPARAM("SubController") ),
659             PROPERTY_SUB_CONTROLLER,
660             ::getCppuType((const Reference<drawing::XDrawSubController>*)0),
661             beans::PropertyAttribute::BOUND));
662     rProperties.push_back(
663         beans::Property(
664             OUString( RTL_CONSTASCII_USTRINGPARAM("CurrentPage") ),
665             PROPERTY_CURRENTPAGE,
666             ::getCppuType((const Reference< drawing::XDrawPage > *)0),
667             beans::PropertyAttribute::BOUND ));
668     rProperties.push_back(
669         beans::Property( OUString( RTL_CONSTASCII_USTRINGPARAM("IsLayerMode") ),
670             PROPERTY_LAYERMODE,
671             ::getCppuBooleanType(),
672             beans::PropertyAttribute::BOUND ));
673     rProperties.push_back(
674         beans::Property( OUString( RTL_CONSTASCII_USTRINGPARAM("IsMasterPageMode") ),
675             PROPERTY_MASTERPAGEMODE,
676             ::getCppuBooleanType(),
677             beans::PropertyAttribute::BOUND ));
678     rProperties.push_back(
679         beans::Property( OUString( RTL_CONSTASCII_USTRINGPARAM("ActiveLayer") ),
680             PROPERTY_ACTIVE_LAYER,
681             ::getCppuBooleanType(),
682             beans::PropertyAttribute::BOUND ));
683     rProperties.push_back(
684         beans::Property( OUString( RTL_CONSTASCII_USTRINGPARAM("ZoomValue") ),
685 			PROPERTY_ZOOMVALUE,
686             ::getCppuType((const sal_Int16*)0),
687             beans::PropertyAttribute::BOUND ));
688     rProperties.push_back(
689         beans::Property( OUString( RTL_CONSTASCII_USTRINGPARAM("ZoomType") ),
690 			PROPERTY_ZOOMTYPE,
691             ::getCppuType((const sal_Int16*)0),
692             beans::PropertyAttribute::BOUND ));
693     rProperties.push_back(
694         beans::Property( OUString( RTL_CONSTASCII_USTRINGPARAM("ViewOffset") ),
695 			PROPERTY_VIEWOFFSET,
696             ::getCppuType((const ::com::sun::star::awt::Point*)0),
697             beans::PropertyAttribute::BOUND ));
698     rProperties.push_back(
699         beans::Property( OUString( RTL_CONSTASCII_USTRINGPARAM("DrawViewMode") ),
700 			PROPERTY_DRAWVIEWMODE,
701             ::getCppuType((const ::com::sun::star::awt::Point*)0),
702             beans::PropertyAttribute::BOUND|beans::PropertyAttribute::READONLY|beans::PropertyAttribute::MAYBEVOID ));
703 }
704 
705 
706 
707 
708 IPropertyArrayHelper & DrawController::getInfoHelper()
709 {
710 	OGuard aGuard( Application::GetSolarMutex() );
711 
712     if (mpPropertyArrayHelper.get() == NULL)
713     {
714         ::std::vector<beans::Property> aProperties;
715         FillPropertyTable (aProperties);
716         Sequence<beans::Property> aPropertySequence (aProperties.size());
717         for (unsigned int i=0; i<aProperties.size(); i++)
718             aPropertySequence[i] = aProperties[i];
719         mpPropertyArrayHelper.reset(new OPropertyArrayHelper(aPropertySequence, sal_False));
720     }
721 
722 	return *mpPropertyArrayHelper.get();
723 }
724 
725 
726 
727 
728 Reference < beans::XPropertySetInfo >  DrawController::getPropertySetInfo()
729 		throw ( ::com::sun::star::uno::RuntimeException)
730 {
731 	::vos::OGuard aGuard( Application::GetSolarMutex() );
732 
733 	static Reference < beans::XPropertySetInfo >  xInfo( createPropertySetInfo( getInfoHelper() ) );
734 	return xInfo;
735 }
736 
737 
738 uno::Reference< form::runtime::XFormController > SAL_CALL DrawController::getFormController( const uno::Reference< form::XForm >& Form ) throw (uno::RuntimeException)
739 {
740     OGuard aGuard( Application::GetSolarMutex() );
741 
742     FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell();
743     SdrView* pSdrView = mpBase->GetDrawView();
744     ::boost::shared_ptr<ViewShell> pViewShell = mpBase->GetMainViewShell();
745     ::sd::Window* pWindow = pViewShell ? pViewShell->GetActiveWindow() : NULL;
746 
747     uno::Reference< form::runtime::XFormController > xController( NULL );
748     if ( pFormShell && pSdrView && pWindow )
749         xController = pFormShell->GetFormController( Form, *pSdrView, *pWindow );
750     return xController;
751 }
752 
753 ::sal_Bool SAL_CALL DrawController::isFormDesignMode(  ) throw (uno::RuntimeException)
754 {
755     OGuard aGuard( Application::GetSolarMutex() );
756 
757     sal_Bool bIsDesignMode = sal_True;
758 
759     FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell();
760     if ( pFormShell )
761         bIsDesignMode = pFormShell->IsDesignMode();
762 
763     return bIsDesignMode;
764 }
765 
766 void SAL_CALL DrawController::setFormDesignMode( ::sal_Bool _DesignMode ) throw (uno::RuntimeException)
767 {
768     OGuard aGuard( Application::GetSolarMutex() );
769 
770     FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell();
771     if ( pFormShell )
772         pFormShell->SetDesignMode( _DesignMode );
773 }
774 
775 uno::Reference< awt::XControl > SAL_CALL DrawController::getControl( const uno::Reference< awt::XControlModel >& xModel ) throw (container::NoSuchElementException, uno::RuntimeException)
776 {
777     OGuard aGuard( Application::GetSolarMutex() );
778 
779     FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell();
780     SdrView* pSdrView = mpBase->GetDrawView();
781     ::boost::shared_ptr<ViewShell> pViewShell = mpBase->GetMainViewShell();
782     ::sd::Window* pWindow = pViewShell ? pViewShell->GetActiveWindow() : NULL;
783 
784     uno::Reference< awt::XControl > xControl( NULL );
785     if ( pFormShell && pSdrView && pWindow )
786         pFormShell->GetFormControl( xModel, *pSdrView, *pWindow, xControl );
787     return xControl;
788 }
789 
790 
791 
792 
793 sal_Bool DrawController::convertFastPropertyValue (
794     Any & rConvertedValue,
795 	Any & rOldValue,
796 	sal_Int32 nHandle,
797 	const Any& rValue)
798     throw ( com::sun::star::lang::IllegalArgumentException)
799 {
800     sal_Bool bResult = sal_False;
801 
802     if (nHandle == PROPERTY_SUB_CONTROLLER)
803     {
804         rOldValue <<= mxSubController;
805         rConvertedValue <<= Reference<drawing::XDrawSubController>(rValue, UNO_QUERY);
806         bResult = (rOldValue != rConvertedValue);
807     }
808     else if (mxSubController.is())
809     {
810         rConvertedValue = rValue;
811         try
812         {
813             rOldValue = mxSubController->getFastPropertyValue(nHandle);
814             bResult = (rOldValue != rConvertedValue);
815         }
816         catch(beans::UnknownPropertyException aException)
817         {
818             // The prperty is unknown and thus an illegal argument to this method.
819             throw com::sun::star::lang::IllegalArgumentException();
820         }
821     }
822 
823     return bResult;
824 }
825 
826 
827 
828 
829 void DrawController::setFastPropertyValue_NoBroadcast (
830 	sal_Int32 nHandle,
831 	const Any& rValue)
832     throw ( com::sun::star::uno::Exception)
833 {
834     OGuard aGuard( Application::GetSolarMutex() );
835     if (nHandle == PROPERTY_SUB_CONTROLLER)
836         SetSubController(Reference<drawing::XDrawSubController>(rValue, UNO_QUERY));
837     else if (mxSubController.is())
838         mxSubController->setFastPropertyValue(nHandle, rValue);
839 }
840 
841 
842 
843 
844 void DrawController::getFastPropertyValue (
845     Any & rRet,
846     sal_Int32 nHandle ) const
847 {
848 	OGuard aGuard( Application::GetSolarMutex() );
849 
850 	switch( nHandle )
851 	{
852 		case PROPERTY_WORKAREA:
853 			rRet <<= awt::Rectangle(
854                 maLastVisArea.Left(),
855                 maLastVisArea.Top(),
856                 maLastVisArea.GetWidth(),
857                 maLastVisArea.GetHeight());
858 			break;
859 
860         case PROPERTY_SUB_CONTROLLER:
861             rRet <<= mxSubController;
862             break;
863 
864         default:
865             if (mxSubController.is())
866                 rRet = mxSubController->getFastPropertyValue(nHandle);
867             break;
868     }
869 }
870 
871 
872 
873 
874 //-----------------------------------------------------------------------------
875 
876 void DrawController::ProvideFrameworkControllers (void)
877 {
878 	::vos::OGuard aGuard (Application::GetSolarMutex());
879     try
880     {
881         Reference<XController> xController (this);
882         const Reference<XComponentContext> xContext (
883             ::comphelper::getProcessComponentContext() );
884         mxConfigurationController = ConfigurationController::create(
885             xContext,
886             xController);
887         mxModuleController = ModuleController::create(
888             xContext,
889             xController);
890     }
891     catch (RuntimeException&)
892     {
893         mxConfigurationController = NULL;
894         mxModuleController = NULL;
895     }
896 }
897 
898 
899 
900 
901 void DrawController::DisposeFrameworkControllers (void)
902 {
903     Reference<XComponent> xComponent (mxModuleController, UNO_QUERY);
904     if (xComponent.is())
905         xComponent->dispose();
906 
907     xComponent = Reference<XComponent>(mxConfigurationController, UNO_QUERY);
908     if (xComponent.is())
909         xComponent->dispose();
910 }
911 
912 
913 
914 
915 void DrawController::ThrowIfDisposed (void) const
916     throw (::com::sun::star::lang::DisposedException)
917 {
918 	if (rBHelper.bDisposed || rBHelper.bInDispose || mbDisposing)
919 	{
920         OSL_TRACE ("Calling disposed DrawController object. Throwing exception:");
921         throw lang::DisposedException (
922             OUString(RTL_CONSTASCII_USTRINGPARAM(
923                 "DrawController object has already been disposed")),
924             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
925     }
926 }
927 
928 
929 
930 
931 
932 } // end of namespace sd
933 
934 
935