xref: /aoo41x/main/svx/source/form/fmPropBrw.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include "fmhelp.hrc"
32 #include "fmprop.hrc"
33 #include "fmPropBrw.hxx"
34 #include "svx/fmresids.hrc"
35 #include "fmservs.hxx"
36 #include "fmshimp.hxx"
37 #include "fmpgeimp.hxx"
38 
39 #include "svx/dialmgr.hxx"
40 #include "svx/fmpage.hxx"
41 #include "svx/fmshell.hxx"
42 #include "svx/sdrpagewindow.hxx"
43 #include "svx/svdpagv.hxx"
44 #include "svx/svxids.hrc"
45 
46 /** === begin UNO includes === **/
47 #include <com/sun/star/beans/PropertyValue.hpp>
48 #include <com/sun/star/awt/PosSize.hpp>
49 #include <com/sun/star/form/XForm.hpp>
50 #include <com/sun/star/form/FormComponentType.hpp>
51 #include <com/sun/star/awt/XLayoutConstrains.hpp>
52 #include <com/sun/star/awt/XControlContainer.hpp>
53 #include <com/sun/star/container/XChild.hpp>
54 #include <com/sun/star/awt/PosSize.hpp>
55 #include <com/sun/star/inspection/ObjectInspector.hpp>
56 #include <com/sun/star/inspection/ObjectInspectorModel.hpp>
57 #include <com/sun/star/form/inspection/DefaultFormComponentInspectorModel.hpp>
58 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
59 #include <com/sun/star/inspection/DefaultHelpProvider.hpp>
60 /** === end UNO includes === **/
61 
62 #include <comphelper/processfactory.hxx>
63 #include <comphelper/property.hxx>
64 #include <cppuhelper/component_context.hxx>
65 #include <sfx2/bindings.hxx>
66 #include <sfx2/childwin.hxx>
67 #include <sfx2/dispatch.hxx>
68 #include <sfx2/objitem.hxx>
69 #include <sfx2/objsh.hxx>
70 #include <sfx2/viewfrm.hxx>
71 #include <toolkit/unohlp.hxx>
72 #include <tools/debug.hxx>
73 #include <tools/diagnose_ex.h>
74 #include <tools/shl.hxx>
75 #include <unotools/confignode.hxx>
76 #include <vcl/stdtext.hxx>
77 
78 #include <algorithm>
79 
80 using namespace ::com::sun::star;
81 using namespace ::com::sun::star::uno;
82 using namespace ::com::sun::star::util;
83 using namespace ::com::sun::star::inspection;
84 using namespace ::com::sun::star::form::inspection;
85 using ::com::sun::star::awt::XWindow;
86 
87 /*************************************************************************/
88 //========================================================================
89 //= FmPropBrwMgr
90 //========================================================================
91 //-----------------------------------------------------------------------
92 SFX_IMPL_FLOATINGWINDOW(FmPropBrwMgr, SID_FM_SHOW_PROPERTIES)
93 
94 //-----------------------------------------------------------------------
95 FmPropBrwMgr::FmPropBrwMgr(	Window* _pParent, sal_uInt16 _nId,
96 							SfxBindings* _pBindings, SfxChildWinInfo* _pInfo)
97 			  :SfxChildWindow(_pParent, _nId)
98 {
99 	pWindow = new FmPropBrw( ::comphelper::getProcessServiceFactory(), _pBindings, this, _pParent, _pInfo );
100 	eChildAlignment = SFX_ALIGN_NOALIGNMENT;
101 	((SfxFloatingWindow*)pWindow)->Initialize( _pInfo );
102 }
103 
104 //========================================================================
105 //========================================================================
106 const long STD_WIN_SIZE_X = 300;
107 const long STD_WIN_SIZE_Y = 350;
108 
109 const long STD_MIN_SIZE_X = 250;
110 const long STD_MIN_SIZE_Y = 250;
111 
112 const long STD_WIN_POS_X = 50;
113 const long STD_WIN_POS_Y = 50;
114 const long WIN_BORDER = 2;
115 const long MIN_WIN_SIZE_X = 50;
116 const long MIN_WIN_SIZE_Y = 50;
117 
118 using namespace ::com::sun::star::uno;
119 using namespace ::com::sun::star::lang;
120 using namespace ::com::sun::star::form;
121 using namespace ::com::sun::star::frame;
122 using namespace ::com::sun::star::beans;
123 using namespace ::com::sun::star::container;
124 using namespace ::svxform;
125 
126 ::rtl::OUString GetUIHeadlineName(sal_Int16 nClassId, const Any& aUnoObj)
127 {
128     sal_uInt16 nClassNameResourceId = 0;
129 
130     switch ( nClassId )
131 	{
132 		case FormComponentType::TEXTFIELD:
133 		{
134 			Reference< XInterface >  xIFace;
135 			aUnoObj >>= xIFace;
136 			nClassNameResourceId = RID_STR_PROPTITLE_EDIT;
137 			if (xIFace.is())
138 			{	// we have a chance to check if it's a formatted field model
139 				Reference< XServiceInfo >  xInfo(xIFace, UNO_QUERY);
140 				if (xInfo.is() && (xInfo->supportsService(FM_SUN_COMPONENT_FORMATTEDFIELD)))
141                     nClassNameResourceId = RID_STR_PROPTITLE_FORMATTED;
142 				else if (!xInfo.is())
143 				{
144 					// couldn't distinguish between formatted and edit with the service name, so try with the properties
145 					Reference< XPropertySet >  xProps(xIFace, UNO_QUERY);
146 					if (xProps.is())
147 					{
148 						Reference< XPropertySetInfo >  xPropsInfo = xProps->getPropertySetInfo();
149 						if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(FM_PROP_FORMATSSUPPLIER))
150 							nClassNameResourceId = RID_STR_PROPTITLE_FORMATTED;
151 					}
152 				}
153 			}
154 		}
155 		break;
156 
157 		case FormComponentType::COMMANDBUTTON:
158 			nClassNameResourceId = RID_STR_PROPTITLE_PUSHBUTTON; break;
159 		case FormComponentType::RADIOBUTTON:
160 			nClassNameResourceId = RID_STR_PROPTITLE_RADIOBUTTON; break;
161 		case FormComponentType::CHECKBOX:
162 			nClassNameResourceId = RID_STR_PROPTITLE_CHECKBOX; break;
163 		case FormComponentType::LISTBOX:
164 			nClassNameResourceId = RID_STR_PROPTITLE_LISTBOX; break;
165 		case FormComponentType::COMBOBOX:
166 			nClassNameResourceId = RID_STR_PROPTITLE_COMBOBOX; break;
167 		case FormComponentType::GROUPBOX:
168 			nClassNameResourceId = RID_STR_PROPTITLE_GROUPBOX; break;
169 		case FormComponentType::IMAGEBUTTON:
170 			nClassNameResourceId = RID_STR_PROPTITLE_IMAGEBUTTON; break;
171 		case FormComponentType::FIXEDTEXT:
172 			nClassNameResourceId = RID_STR_PROPTITLE_FIXEDTEXT; break;
173 		case FormComponentType::GRIDCONTROL:
174 			nClassNameResourceId = RID_STR_PROPTITLE_DBGRID; break;
175 		case FormComponentType::FILECONTROL:
176 			nClassNameResourceId = RID_STR_PROPTITLE_FILECONTROL; break;
177 		case FormComponentType::DATEFIELD:
178 			nClassNameResourceId = RID_STR_PROPTITLE_DATEFIELD; break;
179 		case FormComponentType::TIMEFIELD:
180 			nClassNameResourceId = RID_STR_PROPTITLE_TIMEFIELD; break;
181 		case FormComponentType::NUMERICFIELD:
182 			nClassNameResourceId = RID_STR_PROPTITLE_NUMERICFIELD; break;
183 		case FormComponentType::CURRENCYFIELD:
184 			nClassNameResourceId = RID_STR_PROPTITLE_CURRENCYFIELD; break;
185 		case FormComponentType::PATTERNFIELD:
186 			nClassNameResourceId = RID_STR_PROPTITLE_PATTERNFIELD; break;
187 		case FormComponentType::IMAGECONTROL:
188 			nClassNameResourceId = RID_STR_PROPTITLE_IMAGECONTROL; break;
189 		case FormComponentType::HIDDENCONTROL:
190 			nClassNameResourceId = RID_STR_PROPTITLE_HIDDEN; break;
191 		case FormComponentType::SCROLLBAR:
192 			nClassNameResourceId = RID_STR_PROPTITLE_SCROLLBAR; break;
193 		case FormComponentType::SPINBUTTON:
194 			nClassNameResourceId = RID_STR_PROPTITLE_SPINBUTTON; break;
195 		case FormComponentType::NAVIGATIONBAR:
196 			nClassNameResourceId = RID_STR_PROPTITLE_NAVBAR; break;
197 		case FormComponentType::CONTROL:
198 		default:
199 			nClassNameResourceId = RID_STR_CONTROL; break;
200 	}
201 
202     if ( !nClassNameResourceId )
203         return ::rtl::OUString();
204 
205     return ::rtl::OUString( String( SVX_RES( nClassNameResourceId ) ) );
206 }
207 
208 //========================================================================
209 // class FmPropBrw
210 //========================================================================
211 DBG_NAME(FmPropBrw);
212 //------------------------------------------------------------------------
213 FmPropBrw::FmPropBrw( const Reference< XMultiServiceFactory >& _xORB, SfxBindings* _pBindings,
214             SfxChildWindow* _pMgr, Window* _pParent, const SfxChildWinInfo* _pInfo )
215     :SfxFloatingWindow(_pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK|WB_ROLLABLE) )
216     ,SfxControllerItem(SID_FM_PROPERTY_CONTROL, *_pBindings)
217     ,m_bInitialStateChange(sal_True)
218     ,m_bInStateChange( false )
219     ,m_xORB(_xORB)
220 {
221 	DBG_CTOR(FmPropBrw,NULL);
222 
223     ::Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
224     SetMinOutputSizePixel(::Size(STD_MIN_SIZE_X,STD_MIN_SIZE_Y));
225 	SetOutputSizePixel(aPropWinSize);
226 	SetUniqueId(UID_FORMPROPBROWSER_FRAME);
227 
228 	try
229 	{
230 		// create a frame wrapper for myself
231 		m_xMeAsFrame = Reference< XFrame >(m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Frame")), UNO_QUERY);
232 		if (m_xMeAsFrame.is())
233 		{
234             // create an intermediate window, which is to be the container window of the frame
235             // Do *not* use |this| as container window for the frame, this would result in undefined
236             // responsiblity for this window (as soon as we initialize a frame with a window, the frame
237             // is responsible for it's life time, but |this| is controlled by the belonging SfxChildWindow)
238             // #i34249# - 2004-09-27 - fs@openoffice.org
239             Window* pContainerWindow = new Window( this );
240             pContainerWindow->Show();
241             m_xFrameContainerWindow = VCLUnoHelper::GetInterface ( pContainerWindow );
242 
243 			m_xMeAsFrame->initialize( m_xFrameContainerWindow );
244 			m_xMeAsFrame->setName(::rtl::OUString::createFromAscii("form property browser"));
245             if ( _pBindings->GetDispatcher() )
246             {
247                 ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFramesSupplier >
248                         xSupp ( _pBindings->GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface(), ::com::sun::star::uno::UNO_QUERY );
249 //                if ( xSupp.is() )
250 //                    xSupp->getFrames()->append( m_xMeAsFrame );
251                 // Don't append frame to frame hierachy to prevent UI_DEACTIVATE messages
252                 // #i31834# - 2004-07-27 - cd@openoffice.org
253             }
254 		}
255 	}
256 	catch (Exception&)
257 	{
258 		DBG_ERROR("FmPropBrw::FmPropBrw: could not create/initialize my frame!");
259 		m_xMeAsFrame.clear();
260 	}
261 
262 	if (m_xMeAsFrame.is())
263 		_pMgr->SetFrame( m_xMeAsFrame );
264 
265 
266 	if ( m_xBrowserComponentWindow.is() )
267 		m_xBrowserComponentWindow->setVisible( sal_True );
268 
269     if ( _pInfo )
270         m_sLastActivePage = _pInfo->aExtraString;
271 }
272 
273 //------------------------------------------------------------------------
274 void FmPropBrw::Resize()
275 {
276     SfxFloatingWindow::Resize();
277 
278     if ( m_xFrameContainerWindow.is() )
279     {
280         try
281         {
282 			::Size aOutputSize( GetOutputSizePixel() );
283             m_xFrameContainerWindow->setPosSize( 0, 0, aOutputSize.Width(), aOutputSize.Height(), awt::PosSize::POSSIZE );
284         }
285         catch( const Exception& )
286         {
287         	OSL_ENSURE( sal_False, "FmPropBrw::Resize: caught an exception!" );
288         }
289     }
290 }
291 
292 //------------------------------------------------------------------------
293 FmPropBrw::~FmPropBrw()
294 {
295 	if (m_xBrowserController.is())
296 		implDetachController();
297     try
298     {
299         // remove our own properties from the component context. We cannot ensure that the component context
300         // is freed (there might be refcount problems :-\), so at least ensure the context itself
301         // does hold the objects anymore
302         Reference<XNameContainer> xName(m_xInspectorContext,uno::UNO_QUERY);
303         if ( xName.is() )
304         {
305             const ::rtl::OUString pProps[] = { ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContextDocument" ) )
306                                              , ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogParentWindow" ) )
307                                              , ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlContext" ) )
308                                              , ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlShapeAccess" ) ) };
309             for ( size_t i = 0; i < sizeof(pProps)/sizeof(pProps[0]); ++i )
310                 xName->removeByName( pProps[i] );
311         }
312     }
313     catch (const Exception& )
314     {
315         DBG_UNHANDLED_EXCEPTION();
316     }
317 	DBG_DTOR(FmPropBrw,NULL);
318 }
319 
320 //-----------------------------------------------------------------------
321 ::rtl::OUString FmPropBrw::getCurrentPage() const
322 {
323     ::rtl::OUString sCurrentPage;
324     try
325     {
326         if ( m_xBrowserController.is() )
327         {
328             OSL_VERIFY( m_xBrowserController->getViewData() >>= sCurrentPage );
329         }
330 
331         if ( !sCurrentPage.getLength() )
332             sCurrentPage = m_sLastActivePage;
333     }
334     catch( const Exception& )
335     {
336     	OSL_ENSURE( sal_False, "FmPropBrw::getCurrentPage: caught an exception while retrieving the current page!" );
337     }
338     return sCurrentPage;
339 }
340 
341 //-----------------------------------------------------------------------
342 void FmPropBrw::implDetachController()
343 {
344     m_sLastActivePage = getCurrentPage();
345 
346 	implSetNewSelection( InterfaceBag() );
347 
348     if ( m_xMeAsFrame.is() )
349     {
350         try
351         {
352 		    m_xMeAsFrame->setComponent(NULL, NULL);
353         }
354         catch( const Exception& )
355         {
356         	OSL_ENSURE( sal_False, "FmPropBrw::implDetachController: caught an exception while resetting the component!" );
357         }
358     }
359 
360 	// we attached a frame to the controller manually, so we need to manually tell it that it's detached, too
361 	// 96068 - 09.01.2002 - fs@openoffice.org
362 	if ( m_xBrowserController.is() )
363 		m_xBrowserController->attachFrame( NULL );
364 
365 	m_xBrowserController.clear();
366     m_xInspectorModel.clear();
367 	m_xMeAsFrame.clear();
368 }
369 
370 //-----------------------------------------------------------------------
371 sal_Bool FmPropBrw::Close()
372 {
373     // suspend the controller (it is allowed to veto)
374     if ( m_xMeAsFrame.is() )
375     {
376         try
377         {
378             Reference< XController > xController( m_xMeAsFrame->getController() );
379             if ( xController.is() && !xController->suspend( sal_True ) )
380                 return sal_False;
381         }
382         catch( const Exception& )
383         {
384         	OSL_ENSURE( sal_False, "FmPropBrw::Close: caught an exception while asking the controller!" );
385         }
386     }
387 
388 	implDetachController();
389 
390 	if( IsRollUp() )
391 		RollDown();
392 
393 	// remember our bindings: while we're closed, we're deleted, too, so accessing the bindings after this
394 	// would be deadly
395 	// 10/19/00 - 79321 - FS
396 	SfxBindings& rBindings = SfxControllerItem::GetBindings();
397 
398 	sal_Bool bClose = SfxFloatingWindow::Close();
399 
400 	if (bClose)
401 	{
402 		rBindings.Invalidate(SID_FM_CTL_PROPERTIES);
403 		rBindings.Invalidate(SID_FM_PROPERTIES);
404 	}
405 
406 	return bClose;
407 }
408 
409 //-----------------------------------------------------------------------
410 bool FmPropBrw::implIsReadOnlyModel() const
411 {
412     try
413     {
414         if ( m_xInspectorModel.is() )
415             return m_xInspectorModel->getIsReadOnly();
416         return false;
417     }
418     catch( const Exception& )
419     {
420     	DBG_UNHANDLED_EXCEPTION();
421     }
422     return true;
423 }
424 
425 //-----------------------------------------------------------------------
426 void FmPropBrw::implSetNewSelection( const InterfaceBag& _rSelection )
427 {
428 	if ( m_xBrowserController.is() )
429 	{
430         try
431         {
432             Reference< XObjectInspector > xInspector( m_xBrowserController, UNO_QUERY_THROW );
433 
434             // tell it the objects to inspect
435             Sequence< Reference< XInterface > > aSelection( _rSelection.size() );
436             ::std::copy( _rSelection.begin(), _rSelection.end(), aSelection.getArray() );
437 
438             xInspector->inspect( aSelection );
439         }
440         catch( const VetoException& )
441         {
442             return;
443         }
444         catch( const Exception& )
445         {
446         	OSL_ENSURE( sal_False, "FmPropBrw::implSetNewSelection: caught an unexpected exception!" );
447             return;
448         }
449 
450 		// set the new title according to the selected object
451 		String sTitle;
452 
453         if ( _rSelection.empty() )
454         {
455 			sTitle = String( SVX_RES( RID_STR_NO_PROPERTIES ) );
456         }
457         else if ( _rSelection.size() > 1 )
458 		{
459 			// no form component and (no form or no name) -> Multiselection
460 			sTitle = String( SVX_RES( RID_STR_PROPERTIES_CONTROL ) );
461 			sTitle += String( SVX_RES( RID_STR_PROPTITLE_MULTISELECT ) );
462 		}
463         else
464         {
465             Reference< XPropertySet > xSingleSelection( *_rSelection.begin(), UNO_QUERY);
466             if  ( ::comphelper::hasProperty( FM_PROP_CLASSID, xSingleSelection ) )
467 		    {
468                 sal_Int16 nClassID = FormComponentType::CONTROL;
469 			    xSingleSelection->getPropertyValue( FM_PROP_CLASSID ) >>= nClassID;
470 
471                 sTitle = String( SVX_RES( RID_STR_PROPERTIES_CONTROL ) );
472 				sTitle += String( GetUIHeadlineName( nClassID, makeAny( xSingleSelection ) ) );
473 		    }
474 		    else if ( Reference< XForm >( xSingleSelection, UNO_QUERY ).is() )
475 			    sTitle = String( SVX_RES( RID_STR_PROPERTIES_FORM ) );
476         }
477 
478         if ( implIsReadOnlyModel() )
479             sTitle += String( SVX_RES( RID_STR_READONLY_VIEW ) );
480 
481 		SetText( sTitle );
482 
483 		// #95343# ---------------------------------
484 		Reference< ::com::sun::star::awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY );
485 		if( xLayoutConstrains.is() )
486 		{
487 			::Size aConstrainedSize;
488 			::com::sun::star::awt::Size aMinSize = xLayoutConstrains->getMinimumSize();
489 
490             sal_Int32 nLeft(0), nTop(0), nRight(0), nBottom(0);
491             GetBorder( nLeft, nTop, nRight, nBottom );
492 			aMinSize.Width += nLeft + nRight + 8;
493 			aMinSize.Height += nTop + nBottom + 8;
494 
495             aConstrainedSize.setHeight( aMinSize.Height );
496 			aConstrainedSize.setWidth( aMinSize.Width );
497 			SetMinOutputSizePixel( aConstrainedSize );
498 			aConstrainedSize = GetOutputSizePixel();
499 			sal_Bool bResize = sal_False;
500 			if( aConstrainedSize.Width() < aMinSize.Width )
501 			{
502 				aConstrainedSize.setWidth( aMinSize.Width );
503 				bResize = sal_True;
504 			}
505 			if( aConstrainedSize.Height() < aMinSize.Height )
506 			{
507 				aConstrainedSize.setHeight( aMinSize.Height );
508 				bResize = sal_True;
509 			}
510 			if( bResize )
511 				SetOutputSizePixel( aConstrainedSize );
512 		}
513 	}
514 }
515 
516 //-----------------------------------------------------------------------
517 void FmPropBrw::FillInfo( SfxChildWinInfo& rInfo ) const
518 {
519 	rInfo.bVisible = sal_False;
520     rInfo.aExtraString = getCurrentPage();
521 }
522 
523 //-----------------------------------------------------------------------
524 IMPL_LINK( FmPropBrw, OnAsyncGetFocus, void*, /*NOTINTERESTEDIN*/ )
525 {
526 	if (m_xBrowserComponentWindow.is())
527 		m_xBrowserComponentWindow->setFocus();
528 	return 0L;
529 }
530 
531 //-----------------------------------------------------------------------
532 namespace
533 {
534     static bool lcl_shouldEnableHelpSection( const Reference< XMultiServiceFactory >& _rxFactory )
535     {
536         const ::rtl::OUString sConfigName( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Forms/PropertyBrowser/" ) );
537         const ::rtl::OUString sPropertyName( RTL_CONSTASCII_USTRINGPARAM( "DirectHelp" ) );
538 
539         ::utl::OConfigurationTreeRoot aConfiguration(
540             ::utl::OConfigurationTreeRoot::createWithServiceFactory( _rxFactory, sConfigName ) );
541 
542         bool bEnabled = false;
543         OSL_VERIFY( aConfiguration.getNodeValue( sPropertyName ) >>= bEnabled );
544         return bEnabled;
545     }
546 }
547 //-----------------------------------------------------------------------
548 void FmPropBrw::impl_createPropertyBrowser_throw( FmFormShell* _pFormShell )
549 {
550     // the document in which we live
551     Reference< XInterface > xDocument;
552     if ( _pFormShell && _pFormShell->GetObjectShell() )
553         xDocument = _pFormShell->GetObjectShell()->GetModel();
554 
555     // the context of the controls in our document
556     Reference< awt::XControlContainer > xControlContext;
557     if ( _pFormShell && _pFormShell->GetFormView() )
558     {
559         SdrPageView* pPageView = _pFormShell->GetFormView()->GetSdrPageView();
560 
561 		if(pPageView)
562 		{
563 			SdrPageWindow* pPageWindow = pPageView->GetPageWindow(0L);
564 
565 			if(pPageWindow)
566 			{
567 			    xControlContext = pPageWindow->GetControlContainer();
568 			}
569 		}
570     }
571 
572     // the default parent window for message boxes
573     Reference< XWindow > xParentWindow( VCLUnoHelper::GetInterface ( this ) );
574 
575     // the mapping from control models to control shapes
576     Reference< XMap > xControlMap;
577     FmFormPage* pFormPage = _pFormShell ? _pFormShell->GetCurPage() : NULL;
578     if ( pFormPage )
579         xControlMap = pFormPage->GetImpl().getControlToShapeMap();
580 
581     // our own component context
582     Reference< XPropertySet > xFactoryProperties( m_xORB, UNO_QUERY_THROW );
583     Reference< XComponentContext > xOwnContext(
584         xFactoryProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ),
585         UNO_QUERY_THROW );
586 
587     // a ComponentContext for the
588     ::cppu::ContextEntry_Init aHandlerContextInfo[] =
589     {
590         ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContextDocument" ) ), makeAny( xDocument ) ),
591         ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogParentWindow" ) ), makeAny( xParentWindow ) ),
592         ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlContext" ) ), makeAny( xControlContext ) ),
593         ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlShapeAccess" ) ), makeAny( xControlMap ) )
594     };
595     m_xInspectorContext.set(
596         ::cppu::createComponentContext( aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ),
597         xOwnContext ) );
598 
599     bool bEnableHelpSection = lcl_shouldEnableHelpSection( m_xORB );
600 
601     // an object inspector model
602     m_xInspectorModel =
603             bEnableHelpSection
604         ?   DefaultFormComponentInspectorModel::createWithHelpSection( m_xInspectorContext, 3, 5 )
605         :   DefaultFormComponentInspectorModel::createDefault( m_xInspectorContext );
606 
607     // an object inspector
608     m_xBrowserController = m_xBrowserController.query(
609         ObjectInspector::createWithModel(
610             m_xInspectorContext, m_xInspectorModel
611         ) );
612 
613     if ( !m_xBrowserController.is() )
614 	{
615         ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.inspection.ObjectInspector" ) );
616 		ShowServiceNotAvailableError( GetParent(), sServiceName, sal_True );
617 	}
618 	else
619 	{
620 		m_xBrowserController->attachFrame( m_xMeAsFrame );
621 		m_xBrowserComponentWindow = m_xMeAsFrame->getComponentWindow();
622 		DBG_ASSERT( m_xBrowserComponentWindow.is(), "FmPropBrw::impl_createPropertyBrowser_throw: attached the controller, but have no component window!" );
623 	}
624 
625     if ( bEnableHelpSection )
626     {
627         Reference< XObjectInspector > xInspector( m_xBrowserController, UNO_QUERY_THROW );
628         Reference< XObjectInspectorUI > xInspectorUI( xInspector->getInspectorUI() );
629         Reference< XInterface > xDefaultHelpProvider( DefaultHelpProvider::create( m_xInspectorContext, xInspectorUI ) );
630     }
631 }
632 
633 //-----------------------------------------------------------------------
634 void FmPropBrw::impl_ensurePropertyBrowser_nothrow( FmFormShell* _pFormShell )
635 {
636     // the document in which we live
637     Reference< XInterface > xDocument;
638     SfxObjectShell* pObjectShell = _pFormShell ? _pFormShell->GetObjectShell() : NULL;
639     if ( pObjectShell )
640         xDocument = pObjectShell->GetModel();
641     if ( ( xDocument == m_xLastKnownDocument ) && m_xBrowserController.is() )
642         // nothing to do
643         return;
644 
645     try
646     {
647         // clean up any previous instances of the object inspector
648         if ( m_xMeAsFrame.is() )
649             m_xMeAsFrame->setComponent( NULL, NULL );
650         else
651     	    ::comphelper::disposeComponent( m_xBrowserController );
652         m_xBrowserController.clear();
653         m_xInspectorModel.clear();
654         m_xBrowserComponentWindow.clear();
655 
656         // and create a new one
657         impl_createPropertyBrowser_throw( _pFormShell );
658     }
659     catch( const Exception& )
660     {
661         DBG_UNHANDLED_EXCEPTION();
662     }
663     m_xLastKnownDocument = xDocument;
664 }
665 
666 //-----------------------------------------------------------------------
667 void FmPropBrw::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
668 {
669 	if (!pState  || SID_FM_PROPERTY_CONTROL != nSID)
670 		return;
671 
672     m_bInStateChange = true;
673 	try
674 	{
675 		if (eState >= SFX_ITEM_AVAILABLE)
676 		{
677 			FmFormShell* pShell = PTR_CAST(FmFormShell,((SfxObjectItem*)pState)->GetShell());
678             InterfaceBag aSelection;
679 			if ( pShell )
680                 pShell->GetImpl()->getCurrentSelection( aSelection );
681 
682             impl_ensurePropertyBrowser_nothrow( pShell );
683 
684             // set the new object to inspect
685             implSetNewSelection( aSelection );
686 
687             // if this is the first time we're here, some additional things need to be done ...
688 			if ( m_bInitialStateChange )
689 			{
690                 // if we're just newly created, we want to have the focus
691 				PostUserEvent( LINK( this, FmPropBrw, OnAsyncGetFocus ) );
692 
693                 // and additionally, we want to show the page which was active during
694                 // our previous incarnation
695                 if ( m_sLastActivePage.getLength() )
696                 {
697                     try
698                     {
699                         if ( m_xBrowserController.is() )
700                             m_xBrowserController->restoreViewData( makeAny( m_sLastActivePage ) );
701                     }
702                     catch( const Exception& )
703                     {
704                         OSL_ENSURE( sal_False, "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
705                     }
706                 }
707 
708 				m_bInitialStateChange = sal_False;
709 			}
710 
711 		}
712 		else
713 		{
714 			implSetNewSelection( InterfaceBag() );
715 		}
716 	}
717 	catch (Exception&)
718 	{
719 		DBG_ERROR("FmPropBrw::StateChanged: Exception occured!");
720 	}
721     m_bInStateChange = false;
722 }
723