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