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