cid#1640468 Dereference after null check
[LibreOffice.git] / reportdesign / source / ui / report / propbrw.cxx
blob31b94c79a924916a4ae294c36596ea1fd2d55b91
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #include <memory>
20 #include <propbrw.hxx>
21 #include <RptObject.hxx>
22 #include <ReportController.hxx>
23 #include <cppuhelper/component_context.hxx>
24 #include <strings.hrc>
25 #include <rptui_slotid.hrc>
26 #include <comphelper/diagnose_ex.hxx>
27 #include <com/sun/star/awt/XLayoutConstrains.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/frame/Frame.hpp>
30 #include <com/sun/star/inspection/ObjectInspector.hpp>
31 #include <com/sun/star/inspection/DefaultHelpProvider.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <com/sun/star/report/inspection/DefaultComponentInspectorModel.hpp>
34 #include <vcl/stdtext.hxx>
35 #include <vcl/weld.hxx>
36 #include <svx/svditer.hxx>
38 #include <toolkit/helper/vclunohelper.hxx>
39 #include <comphelper/namecontainer.hxx>
40 #include <comphelper/types.hxx>
41 #include <comphelper/sequence.hxx>
42 #include <core_resource.hxx>
43 #include <SectionView.hxx>
44 #include <ReportSection.hxx>
45 #include <strings.hxx>
46 #include <DesignView.hxx>
47 #include <ViewsWindow.hxx>
48 #include <UITools.hxx>
49 #include <unotools/confignode.hxx>
51 namespace rptui
53 #define STD_WIN_SIZE_X 300
54 #define STD_WIN_SIZE_Y 350
56 using namespace ::com::sun::star;
57 using namespace uno;
58 using namespace lang;
59 using namespace frame;
60 using namespace beans;
61 using namespace container;
62 using namespace ::comphelper;
65 namespace
67 bool lcl_shouldEnableHelpSection( const Reference< XComponentContext >& _rxContext )
69 ::utl::OConfigurationTreeRoot aConfiguration(
70 ::utl::OConfigurationTreeRoot::createWithComponentContext(
71 _rxContext, u"/org.openoffice.Office.ReportDesign/PropertyBrowser/"_ustr ) );
73 bool bEnabled = false;
74 OSL_VERIFY( aConfiguration.getNodeValue( u"DirectHelp"_ustr ) >>= bEnabled );
75 return bEnabled;
80 // PropBrw
83 PropBrw::PropBrw(const Reference< XComponentContext >& _xORB, vcl::Window* pParent, ODesignView* _pDesignView)
84 : DockingWindow(pParent,WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK))
85 , m_xContentArea(VclPtr<VclVBox>::Create(this))
86 , m_xORB(_xORB)
87 , m_pDesignView(_pDesignView)
88 , m_pView( nullptr )
89 , m_bInitialStateChange(true)
92 Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
93 SetOutputSizePixel(aPropWinSize);
95 // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
96 // transparent children of the widget
97 m_xContentArea->SetControlBackground(m_xContentArea->GetSettings().GetStyleSettings().GetWindowColor());
98 m_xContentArea->SetBackground(m_xContentArea->GetControlBackground());
99 m_xContentArea->SetStyle(m_xContentArea->GetStyle() & ~WB_CLIPCHILDREN);
100 m_xContentArea->Show();
104 // create a frame wrapper for myself
105 m_xMeAsFrame = Frame::create( m_xORB );
106 m_xMeAsFrame->initialize(VCLUnoHelper::GetInterface(m_xContentArea));
107 m_xMeAsFrame->setName(u"report property browser"_ustr); // change name!
109 catch (Exception&)
111 DBG_UNHANDLED_EXCEPTION("reportdesign");
112 OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!");
113 m_xMeAsFrame.clear();
116 if (m_xMeAsFrame.is())
120 ::cppu::ContextEntry_Init aHandlerContextInfo[] =
122 ::cppu::ContextEntry_Init( u"ContextDocument"_ustr, Any( m_pDesignView->getController().getModel() )),
123 ::cppu::ContextEntry_Init( u"DialogParentWindow"_ustr, Any( VCLUnoHelper::GetInterface ( this ) )),
124 ::cppu::ContextEntry_Init( u"ActiveConnection"_ustr, Any( m_pDesignView->getController().getConnection() ) ),
126 m_xInspectorContext.set(
127 ::cppu::createComponentContext( aHandlerContextInfo, SAL_N_ELEMENTS( aHandlerContextInfo ),
128 m_xORB ) );
129 // create a property browser controller
130 bool bEnableHelpSection = lcl_shouldEnableHelpSection( m_xORB );
131 Reference< inspection::XObjectInspectorModel> xInspectorModel( bEnableHelpSection
132 ? report::inspection::DefaultComponentInspectorModel::createWithHelpSection( m_xInspectorContext, 3, 8 )
133 : report::inspection::DefaultComponentInspectorModel::createDefault( m_xInspectorContext ) );
135 m_xBrowserController = inspection::ObjectInspector::createWithModel(m_xInspectorContext, xInspectorModel);
136 if ( !m_xBrowserController.is() )
138 ShowServiceNotAvailableError(pParent ? pParent->GetFrameWeld() : nullptr, u"com.sun.star.inspection.ObjectInspector", true);
140 else
142 m_xBrowserController->attachFrame( Reference<XFrame>(m_xMeAsFrame, UNO_QUERY_THROW));
143 if ( bEnableHelpSection )
145 uno::Reference< inspection::XObjectInspector > xInspector( m_xBrowserController, uno::UNO_SET_THROW );
146 uno::Reference< inspection::XObjectInspectorUI > xInspectorUI( xInspector->getInspectorUI() );
147 inspection::DefaultHelpProvider::create( m_xInspectorContext, xInspectorUI );
151 catch (Exception&)
153 DBG_UNHANDLED_EXCEPTION("reportdesign");
154 OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!");
157 ::comphelper::disposeComponent(m_xBrowserController);
159 catch(Exception&) { }
160 m_xBrowserController.clear();
164 VclContainer::setLayoutAllocation(*m_xContentArea, Point(0, 0), aPropWinSize);
165 m_xContentArea->Show();
167 ::rptui::notifySystemWindow(pParent,this,::comphelper::mem_fun(&TaskPaneList::AddWindow));
171 PropBrw::~PropBrw()
173 disposeOnce();
176 void PropBrw::dispose()
178 if (m_xBrowserController.is())
179 implDetachController();
183 uno::Reference<container::XNameContainer> xName(m_xInspectorContext,uno::UNO_QUERY);
184 if ( xName.is() )
186 const OUString pProps[] = { u"ContextDocument"_ustr
187 , u"DialogParentWindow"_ustr
188 , u"ActiveConnection"_ustr};
189 for (const auto & i : pProps)
190 xName->removeByName(i);
193 catch(Exception&)
196 ::rptui::notifySystemWindow(this,this,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
197 m_pDesignView.clear();
198 m_xContentArea.disposeAndClear();
199 DockingWindow::dispose();
202 void PropBrw::setCurrentPage(const OUString& _sLastActivePage)
204 m_sLastActivePage = _sLastActivePage;
208 void PropBrw::implDetachController()
210 m_sLastActivePage = getCurrentPage();
211 implSetNewObject( );
213 if ( m_xMeAsFrame.is() )
214 m_xMeAsFrame->setComponent( nullptr, nullptr );
216 if ( m_xBrowserController.is() )
217 m_xBrowserController->attachFrame( nullptr );
219 m_xMeAsFrame.clear();
220 m_xBrowserController.clear();
223 OUString PropBrw::getCurrentPage() const
225 OUString sCurrentPage;
228 if ( m_xBrowserController.is() )
230 OSL_VERIFY( m_xBrowserController->getViewData() >>= sCurrentPage );
233 if ( sCurrentPage.isEmpty() )
234 sCurrentPage = m_sLastActivePage;
236 catch( const Exception& )
238 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::getCurrentPage: caught an exception while retrieving the current page!" );
240 return sCurrentPage;
243 bool PropBrw::Close()
245 m_xLastSection.clear();
246 // suspend the controller (it is allowed to veto)
247 if ( m_xMeAsFrame.is() )
251 Reference< XController > xController( m_xMeAsFrame->getController() );
252 if ( xController.is() && !xController->suspend( true ) )
253 return false;
255 catch( const Exception& )
257 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::Close: caught an exception while asking the controller!" );
260 implDetachController();
262 m_pDesignView->getController().executeUnChecked(SID_PROPERTYBROWSER_LAST_PAGE,uno::Sequence< beans::PropertyValue>());
264 return true;
267 uno::Sequence< Reference<uno::XInterface> > PropBrw::CreateCompPropSet(const SdrMarkList& _rMarkList)
269 const size_t nMarkCount = _rMarkList.GetMarkCount();
270 ::std::vector< uno::Reference< uno::XInterface> > aSets;
271 aSets.reserve(nMarkCount);
273 for(size_t i=0; i<nMarkCount; ++i)
275 SdrObject* pCurrent = _rMarkList.GetMark(i)->GetMarkedSdrObj();
276 assert(pCurrent);
278 ::std::optional<SdrObjListIter> oGroupIterator;
279 if (pCurrent->IsGroupObject())
281 oGroupIterator.emplace(pCurrent->GetSubList());
282 pCurrent = oGroupIterator->IsMore() ? oGroupIterator->Next() : nullptr;
285 while (pCurrent)
287 OObjectBase* pObj = dynamic_cast<OObjectBase*>(pCurrent);
288 if ( pObj )
289 aSets.push_back(CreateComponentPair(pObj));
291 // next element
292 pCurrent = oGroupIterator && oGroupIterator->IsMore() ? oGroupIterator->Next() : nullptr;
295 return uno::Sequence< Reference<uno::XInterface> >(aSets.data(), aSets.size());
298 void PropBrw::implSetNewObject( const uno::Sequence< Reference<uno::XInterface> >& _aObjects )
300 if ( m_xBrowserController.is() )
304 m_xBrowserController->inspect(uno::Sequence< Reference<uno::XInterface> >());
305 m_xBrowserController->inspect(_aObjects);
307 catch( const Exception& )
309 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
312 SetText( GetHeadlineName(_aObjects) );
316 OUString PropBrw::GetHeadlineName( const uno::Sequence< Reference<uno::XInterface> >& _aObjects )
318 OUString aName;
319 if ( !_aObjects.hasElements() )
321 aName = RptResId(RID_STR_BRWTITLE_NO_PROPERTIES);
323 else if ( _aObjects.getLength() == 1 ) // single selection
325 aName = RptResId(RID_STR_BRWTITLE_PROPERTIES);
327 uno::Reference< container::XNameContainer > xNameCont(_aObjects[0],uno::UNO_QUERY);
328 Reference< lang::XServiceInfo > xServiceInfo( xNameCont->getByName(u"ReportComponent"_ustr), UNO_QUERY );
329 if ( xServiceInfo.is() )
331 TranslateId pResId;
332 if ( xServiceInfo->supportsService( SERVICE_FIXEDTEXT ) )
334 pResId = RID_STR_PROPTITLE_FIXEDTEXT;
336 else if ( xServiceInfo->supportsService( SERVICE_IMAGECONTROL ) )
338 pResId = RID_STR_PROPTITLE_IMAGECONTROL;
340 else if ( xServiceInfo->supportsService( SERVICE_FORMATTEDFIELD ) )
342 pResId = RID_STR_PROPTITLE_FORMATTED;
344 else if ( xServiceInfo->supportsService( SERVICE_SHAPE ) )
346 pResId = RID_STR_PROPTITLE_SHAPE;
348 else if ( xServiceInfo->supportsService( SERVICE_REPORTDEFINITION ) )
350 pResId = RID_STR_PROPTITLE_REPORT;
352 else if ( xServiceInfo->supportsService( SERVICE_SECTION ) )
354 pResId = RID_STR_PROPTITLE_SECTION;
356 else if ( xServiceInfo->supportsService( SERVICE_FUNCTION ) )
358 pResId = RID_STR_PROPTITLE_FUNCTION;
360 else if ( xServiceInfo->supportsService( SERVICE_GROUP ) )
362 pResId = RID_STR_PROPTITLE_GROUP;
364 else if ( xServiceInfo->supportsService( SERVICE_FIXEDLINE ) )
366 pResId = RID_STR_PROPTITLE_FIXEDLINE;
368 else
370 OSL_FAIL("Unknown service name!");
371 aName += RID_STR_CLASS_FORMATTEDFIELD;
372 return aName;
375 aName += RptResId(pResId);
378 else // multiselection
380 aName = RptResId(RID_STR_BRWTITLE_PROPERTIES)
381 + RptResId(RID_STR_BRWTITLE_MULTISELECT);
384 return aName;
387 uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(OObjectBase* _pObj)
389 _pObj->initializeOle();
390 return CreateComponentPair(_pObj->getAwtComponent(),_pObj->getReportComponent());
393 uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(const uno::Reference< uno::XInterface>& _xFormComponent
394 ,const uno::Reference< uno::XInterface>& _xReportComponent)
396 uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get());
397 xNameCont->insertByName(u"FormComponent"_ustr,uno::Any(_xFormComponent));
398 xNameCont->insertByName(u"ReportComponent"_ustr,uno::Any(_xReportComponent));
399 xNameCont->insertByName(u"RowSet"_ustr,uno::Any(uno::Reference< uno::XInterface>(m_pDesignView->getController().getRowSet())));
401 return xNameCont;
404 ::Size PropBrw::getMinimumSize() const
406 ::Size aSize;
407 Reference< awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY );
408 if( xLayoutConstrains.is() )
410 awt::Size aMinSize = xLayoutConstrains->getMinimumSize();
411 aMinSize.Height += 4;
412 aMinSize.Width += 4;
413 aSize.setHeight( aMinSize.Height );
414 aSize.setWidth( aMinSize.Width );
416 return aSize;
419 void PropBrw::Update( OSectionView* pNewView )
423 if ( m_pView )
425 EndListening(m_pView->GetModel());
426 m_pView = nullptr;
429 // set focus on initialization
430 if ( m_bInitialStateChange )
432 // if we're just newly created, we want to have the focus
433 PostUserEvent( LINK( this, PropBrw, OnAsyncGetFocus ), nullptr, true );
434 m_bInitialStateChange = false;
435 // and additionally, we want to show the page which was active during
436 // our previous incarnation
437 if ( !m_sLastActivePage.isEmpty() && m_xBrowserController.is() )
441 m_xBrowserController->restoreViewData( Any( m_sLastActivePage ) );
443 catch( const Exception& )
445 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
450 if ( !pNewView )
451 return;
452 else
453 m_pView = pNewView;
455 uno::Sequence< Reference<uno::XInterface> > aMarkedObjects;
456 OViewsWindow* pViews = m_pView->getReportSection()->getSectionWindow()->getViewsWindow();
457 const sal_uInt16 nSectionCount = pViews->getSectionCount();
458 for (sal_uInt16 i = 0; i < nSectionCount; ++i)
460 OSectionWindow* pSectionWindow = pViews->getSectionWindow(i);
461 if ( pSectionWindow )
463 const SdrMarkList& rMarkList = pSectionWindow->getReportSection().getSectionView().GetMarkedObjectList();
464 aMarkedObjects = ::comphelper::concatSequences(aMarkedObjects,CreateCompPropSet( rMarkList ));
468 if ( aMarkedObjects.hasElements() ) // multiple selection
470 m_xLastSection.clear();
471 implSetNewObject( aMarkedObjects );
473 else if ( m_xLastSection != m_pView->getReportSection()->getSection() )
475 uno::Reference< uno::XInterface> xTemp(m_pView->getReportSection()->getSection());
476 m_xLastSection = xTemp;
477 uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get() );
478 xNameCont->insertByName(u"ReportComponent"_ustr,uno::Any(xTemp));
479 xTemp = xNameCont;
481 implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) );
484 StartListening(m_pView->GetModel());
486 catch ( Exception& )
488 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update" );
492 void PropBrw::Update( const uno::Reference< uno::XInterface>& _xReportComponent)
494 if ( m_xLastSection == _xReportComponent )
495 return;
497 m_xLastSection = _xReportComponent;
500 if ( m_pView )
502 EndListening(m_pView->GetModel());
503 m_pView = nullptr;
506 uno::Reference< uno::XInterface> xTemp(CreateComponentPair(_xReportComponent,_xReportComponent));
507 implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) );
509 catch ( Exception& )
511 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update: Exception occurred!" );
515 IMPL_LINK_NOARG( PropBrw, OnAsyncGetFocus, void*, void )
517 m_xContentArea->GrabFocus();
520 void PropBrw::LoseFocus()
522 DockingWindow::LoseFocus();
523 if (m_pDesignView)
524 m_pDesignView->getController().InvalidateAll();
529 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */